2011-01-10 Jer Noble <jer.noble@apple.com>
[WebKit-https.git] / Source / WebCore / dom / Document.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2001 Dirk Mueller (mueller@kde.org)
5  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  * Copyright (C) 2008, 2009 Google Inc. All rights reserved.
9  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public License
22  * along with this library; see the file COPYING.LIB.  If not, write to
23  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA 02110-1301, USA.
25  */
26
27 #include "config.h"
28 #include "Document.h"
29
30 #include "AXObjectCache.h"
31 #include "AnimationController.h"
32 #include "AsyncScriptRunner.h"
33 #include "Attr.h"
34 #include "Attribute.h"
35 #include "CDATASection.h"
36 #include "CSSStyleSelector.h"
37 #include "CSSStyleSheet.h"
38 #include "CSSValueKeywords.h"
39 #include "CachedCSSStyleSheet.h"
40 #include "CachedResourceLoader.h"
41 #include "Chrome.h"
42 #include "ChromeClient.h"
43 #include "Comment.h"
44 #include "Console.h"
45 #include "CookieJar.h"
46 #include "CustomEvent.h"
47 #include "DateComponents.h"
48 #include "DOMImplementation.h"
49 #include "DOMWindow.h"
50 #include "DeviceMotionEvent.h"
51 #include "DeviceOrientationEvent.h"
52 #include "DocumentFragment.h"
53 #include "DocumentLoader.h"
54 #include "DocumentMarkerController.h"
55 #include "DocumentType.h"
56 #include "EditingText.h"
57 #include "Editor.h"
58 #include "EntityReference.h"
59 #include "Event.h"
60 #include "EventHandler.h"
61 #include "EventListener.h"
62 #include "EventNames.h"
63 #include "EventQueue.h"
64 #include "ExceptionCode.h"
65 #include "FocusController.h"
66 #include "FormAssociatedElement.h"
67 #include "Frame.h"
68 #include "FrameLoader.h"
69 #include "FrameLoaderClient.h"
70 #include "FrameTree.h"
71 #include "FrameView.h"
72 #include "HashChangeEvent.h"
73 #include "HTMLAllCollection.h"
74 #include "HTMLAnchorElement.h"
75 #include "HTMLBodyElement.h"
76 #include "HTMLCanvasElement.h"
77 #include "HTMLCollection.h"
78 #include "HTMLDocument.h"
79 #include "HTMLElementFactory.h"
80 #include "HTMLFrameOwnerElement.h"
81 #include "HTMLHeadElement.h"
82 #include "HTMLIFrameElement.h"
83 #include "HTMLInputElement.h"
84 #include "HTMLLinkElement.h"
85 #include "HTMLMapElement.h"
86 #include "HTMLNameCollection.h"
87 #include "HTMLNames.h"
88 #include "HTMLParserIdioms.h"
89 #include "HTMLStyleElement.h"
90 #include "HTMLTitleElement.h"
91 #include "HTTPParsers.h"
92 #include "HitTestRequest.h"
93 #include "HitTestResult.h"
94 #include "ImageLoader.h"
95 #include "InspectorController.h"
96 #include "InspectorInstrumentation.h"
97 #include "KeyboardEvent.h"
98 #include "Logging.h"
99 #include "MediaQueryList.h"
100 #include "MediaQueryMatcher.h"
101 #include "MessageEvent.h"
102 #include "MouseEvent.h"
103 #include "MouseEventWithHitTestResults.h"
104 #include "MutationEvent.h"
105 #include "NameNodeList.h"
106 #include "NodeFilter.h"
107 #include "NodeIterator.h"
108 #include "NodeWithIndex.h"
109 #include "OverflowEvent.h"
110 #include "Page.h"
111 #include "PageGroup.h"
112 #include "PageTransitionEvent.h"
113 #include "PlatformKeyboardEvent.h"
114 #include "PopStateEvent.h"
115 #include "ProcessingInstruction.h"
116 #include "ProgressEvent.h"
117 #include "RegisteredEventListener.h"
118 #include "RenderArena.h"
119 #include "RenderLayer.h"
120 #include "RenderTextControl.h"
121 #include "RenderView.h"
122 #include "RenderWidget.h"
123 #include "ScriptController.h"
124 #include "ScriptElement.h"
125 #include "ScriptEventListener.h"
126 #include "SecurityOrigin.h"
127 #include "SegmentedString.h"
128 #include "SelectionController.h"
129 #include "Settings.h"
130 #include "StaticHashSetNodeList.h"
131 #include "StyleSheetList.h"
132 #include "TextEvent.h"
133 #include "TextResourceDecoder.h"
134 #include "Timer.h"
135 #include "TransformSource.h"
136 #include "TreeWalker.h"
137 #include "UIEvent.h"
138 #include "UserContentURLPattern.h"
139 #include "WebKitAnimationEvent.h"
140 #include "WebKitTransitionEvent.h"
141 #include "WheelEvent.h"
142 #include "XMLDocumentParser.h"
143 #include "XMLHttpRequest.h"
144 #include "XMLNSNames.h"
145 #include "XMLNames.h"
146 #include "XSSAuditor.h"
147 #include "htmlediting.h"
148 #include <wtf/CurrentTime.h>
149 #include <wtf/HashFunctions.h>
150 #include <wtf/MainThread.h>
151 #include <wtf/PassRefPtr.h>
152 #include <wtf/StdLibExtras.h>
153 #include <wtf/text/StringBuffer.h>
154
155 #if ENABLE(SHARED_WORKERS)
156 #include "SharedWorkerRepository.h"
157 #endif
158
159 #if ENABLE(DOM_STORAGE)
160 #include "StorageEvent.h"
161 #endif
162
163 #if ENABLE(XPATH)
164 #include "XPathEvaluator.h"
165 #include "XPathExpression.h"
166 #include "XPathNSResolver.h"
167 #include "XPathResult.h"
168 #endif
169
170 #if ENABLE(XSLT)
171 #include "XSLTProcessor.h"
172 #endif
173
174 #if ENABLE(SVG)
175 #include "SVGDocumentExtensions.h"
176 #include "SVGElementFactory.h"
177 #include "SVGNames.h"
178 #include "SVGStyleElement.h"
179 #include "SVGZoomEvent.h"
180 #endif
181
182 #if ENABLE(TOUCH_EVENTS)
183 #if USE(V8)
184 #include "RuntimeEnabledFeatures.h"
185 #endif
186 #include "TouchEvent.h"
187 #endif
188
189 #if ENABLE(WML)
190 #include "WMLDocument.h"
191 #include "WMLElement.h"
192 #include "WMLElementFactory.h"
193 #include "WMLNames.h"
194 #endif
195
196 #if ENABLE(MATHML)
197 #include "MathMLElement.h"
198 #include "MathMLElementFactory.h"
199 #include "MathMLNames.h"
200 #endif
201
202 #if ENABLE(XHTMLMP)
203 #include "HTMLNoScriptElement.h"
204 #endif
205
206 #if ENABLE(FULLSCREEN_API)
207 #include "RenderFullScreen.h"
208 #endif
209
210 using namespace std;
211 using namespace WTF;
212 using namespace Unicode;
213
214 namespace WebCore {
215
216 using namespace HTMLNames;
217
218 // #define INSTRUMENT_LAYOUT_SCHEDULING 1
219
220 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
221 // FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
222 // for dual G5s. :)
223 static const int cLayoutScheduleThreshold = 250;
224
225 // These functions can't have internal linkage because they are used as template arguments.
226 bool keyMatchesId(AtomicStringImpl*, Element*);
227 bool keyMatchesMapName(AtomicStringImpl*, Element*);
228 bool keyMatchesLowercasedMapName(AtomicStringImpl*, Element*);
229
230 // DOM Level 2 says (letters added):
231 //
232 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl.
233 // b) Name characters other than Name-start characters must have one of the categories Mc, Me, Mn, Lm, or Nd.
234 // c) Characters in the compatibility area (i.e. with character code greater than #xF900 and less than #xFFFE) are not allowed in XML names.
235 // d) Characters which have a font or compatibility decomposition (i.e. those with a "compatibility formatting tag" in field 5 of the database -- marked by field 5 beginning with a "<") are not allowed.
236 // e) The following characters are treated as name-start characters rather than name characters, because the property file classifies them as Alphabetic: [#x02BB-#x02C1], #x0559, #x06E5, #x06E6.
237 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section 5.14).
238 // g) Character #x00B7 is classified as an extender, because the property list so identifies it.
239 // h) Character #x0387 is added as a name character, because #x00B7 is its canonical equivalent.
240 // i) Characters ':' and '_' are allowed as name-start characters.
241 // j) Characters '-' and '.' are allowed as name characters.
242 //
243 // It also contains complete tables. If we decide it's better, we could include those instead of the following code.
244
245 static inline bool isValidNameStart(UChar32 c)
246 {
247     // rule (e) above
248     if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
249         return true;
250
251     // rule (i) above
252     if (c == ':' || c == '_')
253         return true;
254
255     // rules (a) and (f) above
256     const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
257     if (!(Unicode::category(c) & nameStartMask))
258         return false;
259
260     // rule (c) above
261     if (c >= 0xF900 && c < 0xFFFE)
262         return false;
263
264     // rule (d) above
265     DecompositionType decompType = decompositionType(c);
266     if (decompType == DecompositionFont || decompType == DecompositionCompat)
267         return false;
268
269     return true;
270 }
271
272 static inline bool isValidNamePart(UChar32 c)
273 {
274     // rules (a), (e), and (i) above
275     if (isValidNameStart(c))
276         return true;
277
278     // rules (g) and (h) above
279     if (c == 0x00B7 || c == 0x0387)
280         return true;
281
282     // rule (j) above
283     if (c == '-' || c == '.')
284         return true;
285
286     // rules (b) and (f) above
287     const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
288     if (!(Unicode::category(c) & otherNamePartMask))
289         return false;
290
291     // rule (c) above
292     if (c >= 0xF900 && c < 0xFFFE)
293         return false;
294
295     // rule (d) above
296     DecompositionType decompType = decompositionType(c);
297     if (decompType == DecompositionFont || decompType == DecompositionCompat)
298         return false;
299
300     return true;
301 }
302
303 static Widget* widgetForNode(Node* focusedNode)
304 {
305     if (!focusedNode)
306         return 0;
307     RenderObject* renderer = focusedNode->renderer();
308     if (!renderer || !renderer->isWidget())
309         return 0;
310     return toRenderWidget(renderer)->widget();
311 }
312
313 static bool acceptsEditingFocus(Node* node)
314 {
315     ASSERT(node);
316     ASSERT(node->isContentEditable());
317
318     Node* root = node->rootEditableElement();
319     Frame* frame = node->document()->frame();
320     if (!frame || !root)
321         return false;
322
323     return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
324 }
325
326 static bool disableRangeMutation(Page* page)
327 {
328 #if PLATFORM(MAC)
329     // Disable Range mutation on document modifications in Tiger and Leopard Mail
330     // See <rdar://problem/5865171>
331     return page && (page->settings()->needsLeopardMailQuirks() || page->settings()->needsTigerMailQuirks());
332 #else
333     return false;
334 #endif
335 }
336
337 static HashSet<Document*>* documentsThatNeedStyleRecalc = 0;
338
339 class DocumentWeakReference : public ThreadSafeShared<DocumentWeakReference> {
340 public:
341     static PassRefPtr<DocumentWeakReference> create(Document* document)
342     {
343         return adoptRef(new DocumentWeakReference(document));
344     }
345
346     Document* document()
347     {
348         ASSERT(isMainThread());
349         return m_document;
350     }
351
352     void clear()
353     {
354         ASSERT(isMainThread());
355         m_document = 0;
356     }
357
358 private:
359     DocumentWeakReference(Document* document)
360         : m_document(document)
361     {
362         ASSERT(isMainThread());
363     }
364
365     Document* m_document;
366 };
367
368 Document::Document(Frame* frame, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL)
369     : ContainerNode(0)
370     , m_compatibilityMode(NoQuirksMode)
371     , m_compatibilityModeLocked(false)
372     , m_domTreeVersion(0)
373     , m_styleSheets(StyleSheetList::create(this))
374     , m_readyState(Complete)
375     , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
376     , m_pendingStyleRecalcShouldForce(false)
377     , m_frameElementsShouldIgnoreScrolling(false)
378     , m_containsValidityStyleRules(false)
379     , m_updateFocusAppearanceRestoresSelection(false)
380     , m_ignoreDestructiveWriteCount(0)
381     , m_title("")
382     , m_rawTitle("")
383     , m_titleSetExplicitly(false)
384     , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
385     , m_startTime(currentTime())
386     , m_overMinimumLayoutThreshold(false)
387     , m_extraLayoutDelay(0)
388     , m_asyncScriptRunner(AsyncScriptRunner::create(this))
389     , m_xmlVersion("1.0")
390     , m_xmlStandalone(false)
391     , m_savedRenderer(0)
392     , m_designMode(inherit)
393     , m_selfOnlyRefCount(0)
394 #if ENABLE(SVG)
395     , m_svgExtensions(0)
396 #endif
397 #if ENABLE(DASHBOARD_SUPPORT)
398     , m_hasDashboardRegions(false)
399     , m_dashboardRegionsDirty(false)
400 #endif
401     , m_accessKeyMapValid(false)
402     , m_createRenderers(true)
403     , m_inPageCache(false)
404     , m_useSecureKeyboardEntryWhenActive(false)
405     , m_isXHTML(isXHTML)
406     , m_isHTML(isHTML)
407     , m_numNodeListCaches(0)
408 #if USE(JSC)
409     , m_normalWorldWrapperCache(0)
410 #endif
411     , m_usingGeolocation(false)
412     , m_eventQueue(adoptPtr(new EventQueue))
413 #if ENABLE(WML)
414     , m_containsWMLContent(false)
415 #endif
416     , m_weakReference(DocumentWeakReference::create(this))
417     , m_idAttributeName(idAttr)
418 #if ENABLE(FULLSCREEN_API)
419     , m_isFullScreen(0)
420     , m_areKeysEnabledInFullScreen(0)
421     , m_fullScreenRenderer(0)
422     , m_fullScreenChangeDelayTimer(this, &Document::fullScreenChangeDelayTimerFired)
423 #endif
424     , m_loadEventDelayCount(0)
425     , m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
426     , m_directionSetOnDocumentElement(false)
427     , m_writingModeSetOnDocumentElement(false)
428 {
429     m_document = this;
430
431     m_pageGroupUserSheetCacheValid = false;
432
433     m_printing = false;
434     m_paginatedForScreen = false;
435
436     m_ignoreAutofocus = false;
437
438     m_frame = frame;
439
440     if (frame || !url.isEmpty())
441         setURL(url);
442
443     // Setting of m_baseURL needs to happen after the setURL call, since that
444     // calls updateBaseURL, which would clobber the passed in value.
445     if (!baseURL.isNull())
446         m_baseURL = baseURL;
447
448     m_axObjectCache = 0;
449
450     m_markers = new DocumentMarkerController();
451
452     m_cachedResourceLoader = new CachedResourceLoader(this);
453
454     m_visuallyOrdered = false;
455     m_bParsing = false;
456     m_wellFormed = false;
457
458     m_textColor = Color::black;
459     m_listenerTypes = 0;
460     setInDocument();
461     m_inStyleRecalc = false;
462     m_closeAfterStyleRecalc = false;
463
464     m_usesDescendantRules = false;
465     m_usesSiblingRules = false;
466     m_usesFirstLineRules = false;
467     m_usesFirstLetterRules = false;
468     m_usesBeforeAfterRules = false;
469     m_usesRemUnits = false;
470     m_usesLinkRules = false;
471
472     m_gotoAnchorNeededAfterStylesheetsLoad = false;
473  
474     m_didCalculateStyleSelector = false;
475     m_pendingStylesheets = 0;
476     m_ignorePendingStylesheets = false;
477     m_hasNodesWithPlaceholderStyle = false;
478     m_pendingSheetLayout = NoLayoutWithPendingSheets;
479
480     m_cssTarget = 0;
481
482     resetLinkColor();
483     resetVisitedLinkColor();
484     resetActiveLinkColor();
485
486     m_processingLoadEvent = false;
487     
488     initSecurityContext();
489     initDNSPrefetch();
490
491     static int docID = 0;
492     m_docID = docID++;
493 #if ENABLE(XHTMLMP)
494     m_shouldProcessNoScriptElement = !(m_frame && m_frame->script()->canExecuteScripts(NotAboutToExecuteScript));
495 #endif
496 }
497
498 inline void Document::DocumentOrderedMap::clear()
499 {
500     m_map.clear();
501     m_duplicateCounts.clear();
502 }
503
504 void Document::removedLastRef()
505 {
506     ASSERT(!m_deletionHasBegun);
507     if (m_selfOnlyRefCount) {
508         // If removing a child removes the last self-only ref, we don't
509         // want the document to be destructed until after
510         // removeAllChildren returns, so we guard ourselves with an
511         // extra self-only ref.
512         selfOnlyRef();
513
514         // We must make sure not to be retaining any of our children through
515         // these extra pointers or we will create a reference cycle.
516         m_docType = 0;
517         m_focusedNode = 0;
518         m_hoverNode = 0;
519         m_activeNode = 0;
520         m_titleElement = 0;
521         m_documentElement = 0;
522 #if ENABLE(FULLSCREEN_API)
523         m_fullScreenElement = 0;
524 #endif
525
526         // removeAllChildren() doesn't always unregister IDs, do it upfront to avoid having stale references in the map.
527         m_elementsById.clear();
528
529         removeAllChildren();
530
531         m_markers->detach();
532
533         detachParser();
534
535         m_cssCanvasElements.clear();
536
537 #ifndef NDEBUG
538         m_inRemovedLastRefFunction = false;
539 #endif
540
541         selfOnlyDeref();
542     } else {
543 #ifndef NDEBUG
544         m_deletionHasBegun = true;
545 #endif
546         delete this;
547     }
548 }
549
550 Document::~Document()
551 {
552     ASSERT(!renderer());
553     ASSERT(!m_inPageCache);
554     ASSERT(!m_savedRenderer);
555     ASSERT(m_ranges.isEmpty());
556     ASSERT(!m_styleRecalcTimer.isActive());
557
558     m_asyncScriptRunner.clear();
559
560     removeAllEventListeners();
561
562 #if USE(JSC)
563     destroyAllWrapperCaches();
564 #endif
565
566     // Currently we believe that Document can never outlive the parser.
567     // Although the Document may be replaced synchronously, DocumentParsers
568     // generally keep at least one reference to an Element which would in turn
569     // has a reference to the Document.  If you hit this ASSERT, then that
570     // assumption is wrong.  DocumentParser::detach() should ensure that even
571     // if the DocumentParser outlives the Document it won't cause badness.
572     ASSERT(!m_parser || m_parser->refCount() == 1);
573     detachParser();
574     m_document = 0;
575     m_cachedResourceLoader.clear();
576
577     m_renderArena.clear();
578
579     clearAXObjectCache();
580
581     m_decoder = 0;
582
583     for (size_t i = 0; i < m_nameCollectionInfo.size(); ++i)
584         deleteAllValues(m_nameCollectionInfo[i]);
585
586     if (m_styleSheets)
587         m_styleSheets->documentDestroyed();
588
589     if (m_elemSheet)
590         m_elemSheet->clearOwnerNode();
591     if (m_mappedElementSheet)
592         m_mappedElementSheet->clearOwnerNode();
593     if (m_pageUserSheet)
594         m_pageUserSheet->clearOwnerNode();
595     if (m_pageGroupUserSheets) {
596         for (size_t i = 0; i < m_pageGroupUserSheets->size(); ++i)
597             (*m_pageGroupUserSheets)[i]->clearOwnerNode();
598     }
599
600     m_weakReference->clear();
601
602     if (m_mediaQueryMatcher)
603         m_mediaQueryMatcher->documentDestroyed();
604 }
605
606 MediaQueryMatcher* Document::mediaQueryMatcher()
607 {
608     if (!m_mediaQueryMatcher)
609         m_mediaQueryMatcher = MediaQueryMatcher::create(this);
610     return m_mediaQueryMatcher.get();
611 }
612
613 #if USE(JSC)
614 Document::JSWrapperCache* Document::createWrapperCache(DOMWrapperWorld* world)
615 {
616     JSWrapperCache* wrapperCache = new JSWrapperCache;
617     m_wrapperCacheMap.set(world, wrapperCache);
618     if (world->isNormal()) {
619         ASSERT(!m_normalWorldWrapperCache);
620         m_normalWorldWrapperCache = wrapperCache;
621     }
622     world->didCreateWrapperCache(this);
623     return wrapperCache;
624 }
625
626 void Document::destroyWrapperCache(DOMWrapperWorld* world)
627 {
628     Document::JSWrapperCache* wrappers = wrapperCacheMap().take(world);
629     ASSERT(wrappers);
630     delete wrappers;
631     world->didDestroyWrapperCache(this);
632 }
633
634 void Document::destroyAllWrapperCaches()
635 {
636     JSWrapperCacheMap& wrapperCacheMap = this->wrapperCacheMap();
637     while (!wrapperCacheMap.isEmpty())
638         destroyWrapperCache(wrapperCacheMap.begin()->first);
639 }
640 #endif
641
642 void Document::setCompatibilityMode(CompatibilityMode mode)
643 {
644     if (m_compatibilityModeLocked || mode == m_compatibilityMode)
645         return;
646     ASSERT(!documentElement() && !m_styleSheets->length());
647     bool wasInQuirksMode = inQuirksMode();
648     m_compatibilityMode = mode;
649     if (inQuirksMode() != wasInQuirksMode) {
650         // All user stylesheets have to reparse using the different mode.
651         clearPageUserSheet();
652         clearPageGroupUserSheets();
653     }
654 }
655
656 String Document::compatMode() const
657 {
658     return inQuirksMode() ? "BackCompat" : "CSS1Compat";
659 }
660
661 void Document::resetLinkColor()
662 {
663     m_linkColor = Color(0, 0, 238);
664 }
665
666 void Document::resetVisitedLinkColor()
667 {
668     m_visitedLinkColor = Color(85, 26, 139);    
669 }
670
671 void Document::resetActiveLinkColor()
672 {
673     m_activeLinkColor.setNamedColor("red");
674 }
675
676 void Document::setDocType(PassRefPtr<DocumentType> docType)
677 {
678     // This should never be called more than once.
679     ASSERT(!m_docType || !docType);
680     m_docType = docType;
681     if (m_docType)
682         m_docType->setDocument(this);
683 }
684
685 DOMImplementation* Document::implementation() const
686 {
687     if (!m_implementation)
688         m_implementation = DOMImplementation::create();
689     return m_implementation.get();
690 }
691
692 void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
693 {
694     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
695     
696     // Invalidate the document element we have cached in case it was replaced.
697     m_documentElement = 0;
698 }
699
700 void Document::cacheDocumentElement() const
701 {
702     ASSERT(!m_documentElement);
703     Node* n = firstChild();
704     while (n && !n->isElementNode())
705         n = n->nextSibling();
706     m_documentElement = static_cast<Element*>(n);
707 }
708
709 PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec)
710 {
711     if (!isValidName(name)) {
712         ec = INVALID_CHARACTER_ERR;
713         return 0;
714     }
715
716     if (m_isXHTML)
717         return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), this, 0, false);
718
719     return createElement(QualifiedName(nullAtom, name, nullAtom), false);
720 }
721
722 PassRefPtr<DocumentFragment> Document::createDocumentFragment()
723 {
724     return DocumentFragment::create(document());
725 }
726
727 PassRefPtr<Text> Document::createTextNode(const String& data)
728 {
729     return Text::create(this, data);
730 }
731
732 PassRefPtr<Comment> Document::createComment(const String& data)
733 {
734     return Comment::create(this, data);
735 }
736
737 PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec)
738 {
739     if (isHTMLDocument()) {
740         ec = NOT_SUPPORTED_ERR;
741         return 0;
742     }
743     return CDATASection::create(this, data);
744 }
745
746 PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec)
747 {
748     if (!isValidName(target)) {
749         ec = INVALID_CHARACTER_ERR;
750         return 0;
751     }
752     if (isHTMLDocument()) {
753         ec = NOT_SUPPORTED_ERR;
754         return 0;
755     }
756     return ProcessingInstruction::create(this, target, data);
757 }
758
759 PassRefPtr<EntityReference> Document::createEntityReference(const String& name, ExceptionCode& ec)
760 {
761     if (!isValidName(name)) {
762         ec = INVALID_CHARACTER_ERR;
763         return 0;
764     }
765     if (isHTMLDocument()) {
766         ec = NOT_SUPPORTED_ERR;
767         return 0;
768     }
769     return EntityReference::create(this, name);
770 }
771
772 PassRefPtr<EditingText> Document::createEditingTextNode(const String& text)
773 {
774     return EditingText::create(this, text);
775 }
776
777 PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
778 {
779     return CSSMutableStyleDeclaration::create();
780 }
781
782 PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCode& ec)
783 {
784     ec = 0;
785     
786     if (!importedNode
787 #if ENABLE(SVG) && ENABLE(DASHBOARD_SUPPORT)
788         || (importedNode->isSVGElement() && page() && page()->settings()->usesDashboardBackwardCompatibilityMode())
789 #endif
790         ) {
791         ec = NOT_SUPPORTED_ERR;
792         return 0;
793     }
794
795     switch (importedNode->nodeType()) {
796     case TEXT_NODE:
797         return createTextNode(importedNode->nodeValue());
798     case CDATA_SECTION_NODE:
799         return createCDATASection(importedNode->nodeValue(), ec);
800     case ENTITY_REFERENCE_NODE:
801         return createEntityReference(importedNode->nodeName(), ec);
802     case PROCESSING_INSTRUCTION_NODE:
803         return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), ec);
804     case COMMENT_NODE:
805         return createComment(importedNode->nodeValue());
806     case ELEMENT_NODE: {
807         Element* oldElement = static_cast<Element*>(importedNode);
808         RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec);
809                     
810         if (ec)
811             return 0;
812
813         NamedNodeMap* attrs = oldElement->attributes(true);
814         if (attrs) {
815             unsigned length = attrs->length();
816             for (unsigned i = 0; i < length; i++) {
817                 Attribute* attr = attrs->attributeItem(i);
818                 newElement->setAttribute(attr->name(), attr->value().impl(), ec);
819                 if (ec)
820                     return 0;
821             }
822         }
823
824         newElement->copyNonAttributeProperties(oldElement);
825
826         if (deep) {
827             for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
828                 RefPtr<Node> newChild = importNode(oldChild, true, ec);
829                 if (ec)
830                     return 0;
831                 newElement->appendChild(newChild.release(), ec);
832                 if (ec)
833                     return 0;
834             }
835         }
836
837         return newElement.release();
838     }
839     case ATTRIBUTE_NODE:
840         return Attr::create(0, this, static_cast<Attr*>(importedNode)->attr()->clone());
841     case DOCUMENT_FRAGMENT_NODE: {
842         DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
843         RefPtr<DocumentFragment> newFragment = createDocumentFragment();
844         if (deep) {
845             for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
846                 RefPtr<Node> newChild = importNode(oldChild, true, ec);
847                 if (ec)
848                     return 0;
849                 newFragment->appendChild(newChild.release(), ec);
850                 if (ec)
851                     return 0;
852             }
853         }
854         
855         return newFragment.release();
856     }
857     case ENTITY_NODE:
858     case NOTATION_NODE:
859         // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that.
860         // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
861     case DOCUMENT_NODE:
862     case DOCUMENT_TYPE_NODE:
863     case XPATH_NAMESPACE_NODE:
864         break;
865     }
866
867     ec = NOT_SUPPORTED_ERR;
868     return 0;
869 }
870
871
872 PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec)
873 {
874     if (!source) {
875         ec = NOT_SUPPORTED_ERR;
876         return 0;
877     }
878
879     if (source->isReadOnlyNode()) {
880         ec = NO_MODIFICATION_ALLOWED_ERR;
881         return 0;
882     }
883
884     switch (source->nodeType()) {
885     case ENTITY_NODE:
886     case NOTATION_NODE:
887     case DOCUMENT_NODE:
888     case DOCUMENT_TYPE_NODE:
889     case XPATH_NAMESPACE_NODE:
890         ec = NOT_SUPPORTED_ERR;
891         return 0;            
892     case ATTRIBUTE_NODE: {                   
893         Attr* attr = static_cast<Attr*>(source.get());
894         if (attr->ownerElement())
895             attr->ownerElement()->removeAttributeNode(attr, ec);
896         attr->setSpecified(true);
897         break;
898     }       
899     default:
900         if (source->hasTagName(iframeTag)) {
901             HTMLIFrameElement* iframe = static_cast<HTMLIFrameElement*>(source.get());
902             if (frame() && frame()->tree()->isDescendantOf(iframe->contentFrame())) {
903                 ec = HIERARCHY_REQUEST_ERR;
904                 return 0;
905             }
906             iframe->setRemainsAliveOnRemovalFromTree(attached() && source->attached());
907         }
908
909         if (source->parentNode())
910             source->parentNode()->removeChild(source.get(), ec);
911     }
912                 
913     for (Node* node = source.get(); node; node = node->traverseNextNode(source.get()))
914         node->setDocument(this);
915
916     return source;
917 }
918
919 bool Document::hasPrefixNamespaceMismatch(const QualifiedName& qName)
920 {
921     // These checks are from DOM Core Level 2, createElementNS
922     // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS
923     if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) // createElementNS(null, "html:div")
924         return true;
925     if (qName.prefix() == xmlAtom && qName.namespaceURI() != XMLNames::xmlNamespaceURI) // createElementNS("http://www.example.com", "xml:lang")
926         return true;
927
928     // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core:
929     // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
930     // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar")
931     if ((qName.prefix() == xmlnsAtom && qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI) || (qName.prefix() != xmlnsAtom && qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI))
932         return true;
933
934     return false;
935 }
936
937 // FIXME: This should really be in a possible ElementFactory class
938 PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
939 {
940     RefPtr<Element> e;
941
942     // FIXME: Use registered namespaces and look up in a hash to find the right factory.
943     if (qName.namespaceURI() == xhtmlNamespaceURI)
944         e = HTMLElementFactory::createHTMLElement(qName, this, 0, createdByParser);
945 #if ENABLE(SVG)
946     else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
947         e = SVGElementFactory::createSVGElement(qName, this, createdByParser);
948 #endif
949 #if ENABLE(WML)
950     else if (qName.namespaceURI() == WMLNames::wmlNamespaceURI)
951         e = WMLElementFactory::createWMLElement(qName, this, createdByParser);
952     else if (isWMLDocument())
953         e = WMLElementFactory::createWMLElement(QualifiedName(nullAtom, qName.localName(), WMLNames::wmlNamespaceURI), this, createdByParser);
954 #endif
955 #if ENABLE(MATHML)
956     else if (qName.namespaceURI() == MathMLNames::mathmlNamespaceURI)
957         e = MathMLElementFactory::createMathMLElement(qName, this, createdByParser);
958 #endif
959
960     if (!e)
961         e = Element::create(qName, document());
962
963     // <image> uses imgTag so we need a special rule.
964 #if ENABLE(WML)
965     if (!isWMLDocument())
966 #endif
967     ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
968
969     return e.release();
970 }
971
972 PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode& ec)
973 {
974     String prefix, localName;
975     if (!parseQualifiedName(qualifiedName, prefix, localName, ec))
976         return 0;
977
978     QualifiedName qName(prefix, localName, namespaceURI);
979     if (hasPrefixNamespaceMismatch(qName)) {
980         ec = NAMESPACE_ERR;
981         return 0;
982     }
983
984     return createElement(qName, false);
985 }
986
987 inline void Document::DocumentOrderedMap::add(AtomicStringImpl* key, Element* element)
988 {
989     ASSERT(key);
990     ASSERT(element);
991
992     if (!m_duplicateCounts.contains(key)) {
993         // Fast path. The key is not already in m_duplicateCounts, so we assume that it's
994         // also not already in m_map and try to add it. If that add succeeds, we're done.
995         pair<Map::iterator, bool> addResult = m_map.add(key, element);
996         if (addResult.second)
997             return;
998
999         // The add failed, so this key was already cached in m_map.
1000         // There are multiple elements with this key. Remove the m_map
1001         // cache for this key so get searches for it next time it is called.
1002         m_map.remove(addResult.first);
1003         m_duplicateCounts.add(key);
1004     } else {
1005         // There are multiple elements with this key. Remove the m_map
1006         // cache for this key so get will search for it next time it is called.
1007         Map::iterator cachedItem = m_map.find(key);
1008         if (cachedItem != m_map.end()) {
1009             m_map.remove(cachedItem);
1010             m_duplicateCounts.add(key);
1011         }
1012     }
1013
1014     m_duplicateCounts.add(key);
1015 }
1016
1017 inline void Document::DocumentOrderedMap::remove(AtomicStringImpl* key, Element* element)
1018 {
1019     ASSERT(key);
1020     ASSERT(element);
1021
1022     m_map.checkConsistency();
1023     Map::iterator cachedItem = m_map.find(key);
1024     if (cachedItem != m_map.end() && cachedItem->second == element)
1025         m_map.remove(cachedItem);
1026     else
1027         m_duplicateCounts.remove(key);
1028 }
1029
1030 template<bool keyMatches(AtomicStringImpl*, Element*)> inline Element* Document::DocumentOrderedMap::get(AtomicStringImpl* key, const Document* document) const
1031 {
1032     ASSERT(key);
1033
1034     m_map.checkConsistency();
1035
1036     Element* element = m_map.get(key);
1037     if (element)
1038         return element;
1039
1040     if (m_duplicateCounts.contains(key)) {
1041         // We know there's at least one node that matches; iterate to find the first one.
1042         for (Node* node = document->firstChild(); node; node = node->traverseNextNode()) {
1043             if (!node->isElementNode())
1044                 continue;
1045             element = static_cast<Element*>(node);
1046             if (!keyMatches(key, element))
1047                 continue;
1048             m_duplicateCounts.remove(key);
1049             m_map.set(key, element);
1050             return element;
1051         }
1052         ASSERT_NOT_REACHED();
1053     }
1054
1055     return 0;
1056 }
1057
1058 inline bool keyMatchesId(AtomicStringImpl* key, Element* element)
1059 {
1060     return element->hasID() && element->getIdAttribute().impl() == key;
1061 }
1062
1063 Element* Document::getElementById(const AtomicString& elementId) const
1064 {
1065     if (elementId.isEmpty())
1066         return 0;
1067     return m_elementsById.get<keyMatchesId>(elementId.impl(), this);
1068 }
1069
1070 String Document::readyState() const
1071 {
1072     DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
1073     DEFINE_STATIC_LOCAL(const String, interactive, ("interactive"));
1074     DEFINE_STATIC_LOCAL(const String, complete, ("complete"));
1075
1076     switch (m_readyState) {
1077     case Loading:
1078         return loading;
1079     case Interactive:
1080         return interactive;
1081     case Complete:
1082         return complete;
1083     }
1084
1085     ASSERT_NOT_REACHED();
1086     return String();
1087 }
1088
1089 void Document::setReadyState(ReadyState readyState)
1090 {
1091     if (readyState == m_readyState)
1092         return;
1093
1094     switch (readyState) {
1095     case Loading:
1096         if (!m_documentTiming.domLoading)
1097             m_documentTiming.domLoading = currentTime();
1098         break;
1099     case Interactive:
1100         if (!m_documentTiming.domInteractive)
1101             m_documentTiming.domInteractive = currentTime();
1102         break;
1103     case Complete:
1104         if (!m_documentTiming.domComplete)
1105             m_documentTiming.domComplete = currentTime();
1106         break;
1107     }
1108
1109     m_readyState = readyState;
1110     dispatchEvent(Event::create(eventNames().readystatechangeEvent, false, false));
1111 }
1112
1113 String Document::encoding() const
1114 {
1115     if (TextResourceDecoder* d = decoder())
1116         return d->encoding().domName();
1117     return String();
1118 }
1119
1120 String Document::defaultCharset() const
1121 {
1122     if (Settings* settings = this->settings())
1123         return settings->defaultTextEncodingName();
1124     return String();
1125 }
1126
1127 void Document::setCharset(const String& charset)
1128 {
1129     if (!decoder())
1130         return;
1131     decoder()->setEncoding(charset, TextResourceDecoder::UserChosenEncoding);
1132 }
1133
1134 void Document::setXMLVersion(const String& version, ExceptionCode& ec)
1135 {
1136     if (!implementation()->hasFeature("XML", String())) {
1137         ec = NOT_SUPPORTED_ERR;
1138         return;
1139     }
1140
1141     if (!XMLDocumentParser::supportsXMLVersion(version)) {
1142         ec = NOT_SUPPORTED_ERR;
1143         return;
1144     }
1145
1146     m_xmlVersion = version;
1147 }
1148
1149 void Document::setXMLStandalone(bool standalone, ExceptionCode& ec)
1150 {
1151     if (!implementation()->hasFeature("XML", String())) {
1152         ec = NOT_SUPPORTED_ERR;
1153         return;
1154     }
1155
1156     m_xmlStandalone = standalone;
1157 }
1158
1159 void Document::setDocumentURI(const String& uri)
1160 {
1161     m_documentURI = uri;
1162     updateBaseURL();
1163 }
1164
1165 KURL Document::baseURI() const
1166 {
1167     return m_baseURL;
1168 }
1169
1170 // FIXME: We need to discuss the DOM API here at some point. Ideas:
1171 // * making it receive a rect as parameter, i.e. nodesFromRect(x, y, w, h);
1172 // * making it receive the expading size of each direction separately,
1173 //   i.e. nodesFromRect(x, y, topSize, rightSize, bottomSize, leftSize);
1174 PassRefPtr<NodeList> Document::nodesFromRect(int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping) const
1175 {
1176     // FIXME: Share code between this, elementFromPoint and caretRangeFromPoint.
1177     if (!renderer())
1178         return 0;
1179     Frame* frame = this->frame();
1180     if (!frame)
1181         return 0;
1182     FrameView* frameView = frame->view();
1183     if (!frameView)
1184         return 0;
1185
1186     float zoomFactor = frame->pageZoomFactor();
1187     IntPoint point = roundedIntPoint(FloatPoint(centerX * zoomFactor + view()->scrollX(), centerY * zoomFactor + view()->scrollY()));
1188
1189     int type = HitTestRequest::ReadOnly | HitTestRequest::Active;
1190
1191     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1192     if (ignoreClipping)
1193         type |= HitTestRequest::IgnoreClipping;
1194     else if (!frameView->visibleContentRect().intersects(HitTestResult::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1195         return 0;
1196
1197     HitTestRequest request(type);
1198
1199     // Passing a zero padding will trigger a rect hit test, however for the purposes of nodesFromRect,
1200     // we special handle this case in order to return a valid NodeList.
1201     if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1202         HitTestResult result(point);
1203         return handleZeroPadding(request, result);
1204     }
1205
1206     HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
1207     renderView()->layer()->hitTest(request, result);
1208
1209     return StaticHashSetNodeList::adopt(result.rectBasedTestResult());
1210 }
1211
1212 PassRefPtr<NodeList> Document::handleZeroPadding(const HitTestRequest& request, HitTestResult& result) const
1213 {
1214     renderView()->layer()->hitTest(request, result);
1215
1216     Node* node = result.innerNode();
1217     if (!node)
1218         return 0;
1219
1220     node = node->shadowAncestorNode();
1221     ListHashSet<RefPtr<Node> > list;
1222     list.add(node);
1223     return StaticHashSetNodeList::adopt(list);
1224 }
1225
1226 Element* Document::elementFromPoint(int x, int y) const
1227 {
1228     // FIXME: Share code between this and caretRangeFromPoint.
1229     if (!renderer())
1230         return 0;
1231     Frame* frame = this->frame();
1232     if (!frame)
1233         return 0;
1234     FrameView* frameView = frame->view();
1235     if (!frameView)
1236         return 0;
1237
1238     float zoomFactor = frame->pageZoomFactor();
1239     IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor  + view()->scrollX(), y * zoomFactor + view()->scrollY()));
1240
1241     if (!frameView->visibleContentRect().contains(point))
1242         return 0;
1243
1244     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
1245     HitTestResult result(point);
1246     renderView()->layer()->hitTest(request, result);
1247
1248     Node* n = result.innerNode();
1249     while (n && !n->isElementNode())
1250         n = n->parentNode();
1251     if (n)
1252         n = n->shadowAncestorNode();
1253     return static_cast<Element*>(n);
1254 }
1255
1256 PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
1257 {
1258     // FIXME: Share code between this and elementFromPoint.
1259     if (!renderer())
1260         return 0;
1261     Frame* frame = this->frame();
1262     if (!frame)
1263         return 0;
1264     FrameView* frameView = frame->view();
1265     if (!frameView)
1266         return 0;
1267
1268     float zoomFactor = frame->pageZoomFactor();
1269     IntPoint point = roundedIntPoint(FloatPoint(x * zoomFactor + view()->scrollX(), y * zoomFactor + view()->scrollY()));
1270
1271     if (!frameView->visibleContentRect().contains(point))
1272         return 0;
1273
1274     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
1275     HitTestResult result(point);
1276     renderView()->layer()->hitTest(request, result);
1277
1278     Node* node = result.innerNode();
1279     if (!node)
1280         return 0;
1281
1282     Node* shadowAncestorNode = node->shadowAncestorNode();
1283     if (shadowAncestorNode != node) {
1284         unsigned offset = shadowAncestorNode->nodeIndex();
1285         ContainerNode* container = shadowAncestorNode->parentNode();
1286         return Range::create(this, container, offset, container, offset);
1287     }
1288
1289     RenderObject* renderer = node->renderer();
1290     if (!renderer)
1291         return 0;
1292     VisiblePosition visiblePosition = renderer->positionForPoint(result.localPoint());
1293     if (visiblePosition.isNull())
1294         return 0;
1295
1296     Position rangeCompliantPosition = rangeCompliantEquivalent(visiblePosition);
1297     return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
1298 }
1299
1300 void Document::addElementById(const AtomicString& elementId, Element* element)
1301 {
1302     m_elementsById.add(elementId.impl(), element);
1303 }
1304
1305 void Document::removeElementById(const AtomicString& elementId, Element* element)
1306 {
1307     m_elementsById.remove(elementId.impl(), element);
1308 }
1309
1310 Element* Document::getElementByAccessKey(const String& key) const
1311 {
1312     if (key.isEmpty())
1313         return 0;
1314     if (!m_accessKeyMapValid) {
1315         for (Node* n = firstChild(); n; n = n->traverseNextNode()) {
1316             if (!n->isElementNode())
1317                 continue;
1318             Element* element = static_cast<Element*>(n);
1319             const AtomicString& accessKey = element->getAttribute(accesskeyAttr);
1320             if (!accessKey.isEmpty())
1321                 m_elementsByAccessKey.set(accessKey.impl(), element);
1322         }
1323         m_accessKeyMapValid = true;
1324     }
1325     return m_elementsByAccessKey.get(key.impl());
1326 }
1327
1328 /*
1329  * Performs three operations:
1330  *  1. Convert control characters to spaces
1331  *  2. Trim leading and trailing spaces
1332  *  3. Collapse internal whitespace.
1333  */
1334 static inline String canonicalizedTitle(Document* document, const String& title)
1335 {
1336     const UChar* characters = title.characters();
1337     unsigned length = title.length();
1338     unsigned i;
1339
1340     StringBuffer buffer(length);
1341     unsigned builderIndex = 0;
1342
1343     // Skip leading spaces and leading characters that would convert to spaces
1344     for (i = 0; i < length; ++i) {
1345         UChar c = characters[i];
1346         if (!(c <= 0x20 || c == 0x7F))
1347             break;
1348     }
1349
1350     if (i == length)
1351         return "";
1352
1353     // Replace control characters with spaces, and backslashes with currency symbols, and collapse whitespace.
1354     bool previousCharWasWS = false;
1355     for (; i < length; ++i) {
1356         UChar c = characters[i];
1357         if (c <= 0x20 || c == 0x7F || (WTF::Unicode::category(c) & (WTF::Unicode::Separator_Line | WTF::Unicode::Separator_Paragraph))) {
1358             if (previousCharWasWS)
1359                 continue;
1360             buffer[builderIndex++] = ' ';
1361             previousCharWasWS = true;
1362         } else {
1363             buffer[builderIndex++] = c;
1364             previousCharWasWS = false;
1365         }
1366     }
1367
1368     // Strip trailing spaces
1369     while (builderIndex > 0) {
1370         --builderIndex;
1371         if (buffer[builderIndex] != ' ')
1372             break;
1373     }
1374
1375     if (!builderIndex && buffer[builderIndex] == ' ')
1376         return "";
1377
1378     buffer.shrink(builderIndex + 1);
1379
1380     // Replace the backslashes with currency symbols if the encoding requires it.
1381     document->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
1382     
1383     return String::adopt(buffer);
1384 }
1385
1386 void Document::updateTitle()
1387 {
1388     m_title = canonicalizedTitle(this, m_rawTitle);
1389     if (Frame* f = frame())
1390         f->loader()->setTitle(m_title);
1391 }
1392
1393 void Document::setTitle(const String& title, Element* titleElement)
1394 {
1395     if (!titleElement) {
1396         // Title set by JavaScript -- overrides any title elements.
1397         m_titleSetExplicitly = true;
1398         if (!isHTMLDocument())
1399             m_titleElement = 0;
1400         else if (!m_titleElement) {
1401             if (HTMLElement* headElement = head()) {
1402                 m_titleElement = createElement(titleTag, false);
1403                 ExceptionCode ec = 0;
1404                 headElement->appendChild(m_titleElement, ec);
1405                 ASSERT(!ec);
1406             }
1407         }
1408     } else if (titleElement != m_titleElement) {
1409         if (m_titleElement || m_titleSetExplicitly)
1410             // Only allow the first title element to change the title -- others have no effect.
1411             return;
1412         m_titleElement = titleElement;
1413     }
1414
1415     if (m_rawTitle == title)
1416         return;
1417
1418     m_rawTitle = title;
1419     updateTitle();
1420
1421     if (m_titleSetExplicitly && m_titleElement && m_titleElement->hasTagName(titleTag) && !titleElement)
1422         static_cast<HTMLTitleElement*>(m_titleElement.get())->setText(m_title);
1423 }
1424
1425 void Document::removeTitle(Element* titleElement)
1426 {
1427     if (m_titleElement != titleElement)
1428         return;
1429
1430     m_titleElement = 0;
1431     m_titleSetExplicitly = false;
1432
1433     // Update title based on first title element in the head, if one exists.
1434     if (HTMLElement* headElement = head()) {
1435         for (Node* e = headElement->firstChild(); e; e = e->nextSibling())
1436             if (e->hasTagName(titleTag)) {
1437                 HTMLTitleElement* titleElement = static_cast<HTMLTitleElement*>(e);
1438                 setTitle(titleElement->text(), titleElement);
1439                 break;
1440             }
1441     }
1442
1443     if (!m_titleElement && !m_rawTitle.isEmpty()) {
1444         m_rawTitle = "";
1445         updateTitle();
1446     }
1447 }
1448
1449 String Document::nodeName() const
1450 {
1451     return "#document";
1452 }
1453
1454 Node::NodeType Document::nodeType() const
1455 {
1456     return DOCUMENT_NODE;
1457 }
1458
1459 FrameView* Document::view() const
1460 {
1461     return m_frame ? m_frame->view() : 0;
1462 }
1463
1464 Page* Document::page() const
1465 {
1466     return m_frame ? m_frame->page() : 0;    
1467 }
1468
1469 Settings* Document::settings() const
1470 {
1471     return m_frame ? m_frame->settings() : 0;
1472 }
1473
1474 PassRefPtr<Range> Document::createRange()
1475 {
1476     return Range::create(this);
1477 }
1478
1479 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, 
1480     PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
1481 {
1482     if (!root) {
1483         ec = NOT_SUPPORTED_ERR;
1484         return 0;
1485     }
1486     return NodeIterator::create(root, whatToShow, filter, expandEntityReferences);
1487 }
1488
1489 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, 
1490     PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionCode& ec)
1491 {
1492     if (!root) {
1493         ec = NOT_SUPPORTED_ERR;
1494         return 0;
1495     }
1496     return TreeWalker::create(root, whatToShow, filter, expandEntityReferences);
1497 }
1498
1499 void Document::scheduleForcedStyleRecalc()
1500 {
1501     m_pendingStyleRecalcShouldForce = true;
1502     scheduleStyleRecalc();
1503 }
1504
1505 void Document::scheduleStyleRecalc()
1506 {
1507     if (m_styleRecalcTimer.isActive() || inPageCache())
1508         return;
1509
1510     ASSERT(childNeedsStyleRecalc() || m_pendingStyleRecalcShouldForce);
1511
1512     if (!documentsThatNeedStyleRecalc)
1513         documentsThatNeedStyleRecalc = new HashSet<Document*>;
1514     documentsThatNeedStyleRecalc->add(this);
1515     
1516     // FIXME: Why on earth is this here? This is clearly misplaced.
1517     if (m_accessKeyMapValid) {
1518         m_accessKeyMapValid = false;
1519         m_elementsByAccessKey.clear();
1520     }
1521     
1522     m_styleRecalcTimer.startOneShot(0);
1523 }
1524
1525 void Document::unscheduleStyleRecalc()
1526 {
1527     ASSERT(!childNeedsStyleRecalc());
1528
1529     if (documentsThatNeedStyleRecalc)
1530         documentsThatNeedStyleRecalc->remove(this);
1531
1532     m_styleRecalcTimer.stop();
1533     m_pendingStyleRecalcShouldForce = false;
1534 }
1535
1536 bool Document::isPendingStyleRecalc() const
1537 {
1538     return m_styleRecalcTimer.isActive() && !m_inStyleRecalc;
1539 }
1540
1541 void Document::styleRecalcTimerFired(Timer<Document>*)
1542 {
1543     updateStyleIfNeeded();
1544 }
1545
1546 bool Document::childNeedsAndNotInStyleRecalc()
1547 {
1548     return childNeedsStyleRecalc() && !m_inStyleRecalc;
1549 }
1550
1551 void Document::recalcStyle(StyleChange change)
1552 {
1553     // we should not enter style recalc while painting
1554     if (view() && view()->isPainting()) {
1555         ASSERT(!view()->isPainting());
1556         return;
1557     }
1558     
1559     if (m_inStyleRecalc)
1560         return; // Guard against re-entrancy. -dwh
1561
1562     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
1563
1564     m_inStyleRecalc = true;
1565     suspendPostAttachCallbacks();
1566     RenderWidget::suspendWidgetHierarchyUpdates();
1567     if (view())
1568         view()->pauseScheduledEvents();
1569     
1570     ASSERT(!renderer() || renderArena());
1571     if (!renderer() || !renderArena())
1572         goto bail_out;
1573     
1574     if (m_pendingStyleRecalcShouldForce)
1575         change = Force;
1576
1577     if (change == Force) {
1578         // style selector may set this again during recalc
1579         m_hasNodesWithPlaceholderStyle = false;
1580         
1581         RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(this);
1582         StyleChange ch = diff(documentStyle.get(), renderer()->style());
1583         if (renderer() && ch != NoChange)
1584             renderer()->setStyle(documentStyle.release());
1585     }
1586
1587     for (Node* n = firstChild(); n; n = n->nextSibling())
1588         if (change >= Inherit || n->childNeedsStyleRecalc() || n->needsStyleRecalc())
1589             n->recalcStyle(change);
1590
1591 #if USE(ACCELERATED_COMPOSITING)
1592     if (view()) {
1593         bool layoutPending = view()->layoutPending() || renderer()->needsLayout();
1594         // If we didn't update compositing layers because of layout(), we need to do so here.
1595         if (!layoutPending)
1596             view()->updateCompositingLayers();
1597     }
1598 #endif
1599
1600 bail_out:
1601     clearNeedsStyleRecalc();
1602     clearChildNeedsStyleRecalc();
1603     unscheduleStyleRecalc();
1604
1605     if (view())
1606         view()->resumeScheduledEvents();
1607     RenderWidget::resumeWidgetHierarchyUpdates();
1608     resumePostAttachCallbacks();
1609     m_inStyleRecalc = false;
1610
1611     // If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
1612     if (m_closeAfterStyleRecalc) {
1613         m_closeAfterStyleRecalc = false;
1614         implicitClose();
1615     }
1616
1617     InspectorInstrumentation::didRecalculateStyle(cookie);
1618 }
1619
1620 void Document::updateStyleIfNeeded()
1621 {
1622     ASSERT(isMainThread());
1623     ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
1624     
1625     if ((!m_pendingStyleRecalcShouldForce && !childNeedsStyleRecalc()) || inPageCache())
1626         return;
1627
1628     if (m_frame)
1629         m_frame->animation()->beginAnimationUpdate();
1630         
1631     recalcStyle(NoChange);
1632
1633     // Tell the animation controller that updateStyleIfNeeded is finished and it can do any post-processing
1634     if (m_frame)
1635         m_frame->animation()->endAnimationUpdate();
1636 }
1637
1638 void Document::updateStyleForAllDocuments()
1639 {
1640     ASSERT(isMainThread());
1641     if (!documentsThatNeedStyleRecalc)
1642         return;
1643
1644     while (documentsThatNeedStyleRecalc->size()) {
1645         HashSet<Document*>::iterator it = documentsThatNeedStyleRecalc->begin();
1646         Document* doc = *it;
1647         documentsThatNeedStyleRecalc->remove(doc);
1648         doc->updateStyleIfNeeded();
1649     }
1650 }
1651
1652 void Document::updateLayout()
1653 {
1654     ASSERT(isMainThread());
1655     if (Element* oe = ownerElement())
1656         oe->document()->updateLayout();
1657
1658     updateStyleIfNeeded();
1659
1660     // Only do a layout if changes have occurred that make it necessary.      
1661     FrameView* v = view();
1662     if (v && renderer() && (v->layoutPending() || renderer()->needsLayout()))
1663         v->layout();
1664 }
1665
1666 // FIXME: This is a bad idea and needs to be removed eventually.
1667 // Other browsers load stylesheets before they continue parsing the web page.
1668 // Since we don't, we can run JavaScript code that needs answers before the
1669 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets
1670 // lets us get reasonable answers. The long term solution to this problem is
1671 // to instead suspend JavaScript execution.
1672 void Document::updateLayoutIgnorePendingStylesheets()
1673 {
1674     bool oldIgnore = m_ignorePendingStylesheets;
1675     
1676     if (!haveStylesheetsLoaded()) {
1677         m_ignorePendingStylesheets = true;
1678         // FIXME: We are willing to attempt to suppress painting with outdated style info only once.  Our assumption is that it would be
1679         // dangerous to try to stop it a second time, after page content has already been loaded and displayed
1680         // with accurate style information.  (Our suppression involves blanking the whole page at the
1681         // moment.  If it were more refined, we might be able to do something better.)
1682         // It's worth noting though that this entire method is a hack, since what we really want to do is
1683         // suspend JS instead of doing a layout with inaccurate information.
1684         if (body() && !body()->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
1685             m_pendingSheetLayout = DidLayoutWithPendingSheets;
1686             styleSelectorChanged(RecalcStyleImmediately);
1687         } else if (m_hasNodesWithPlaceholderStyle)
1688             // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes 
1689             // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive 
1690             // but here we need up-to-date style immediately.
1691             recalcStyle(Force);
1692     }
1693
1694     updateLayout();
1695
1696     m_ignorePendingStylesheets = oldIgnore;
1697 }
1698
1699 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
1700 {
1701     ASSERT_ARG(element, element->document() == this);
1702
1703     bool oldIgnore = m_ignorePendingStylesheets;
1704     m_ignorePendingStylesheets = true;
1705     RefPtr<RenderStyle> style = styleSelector()->styleForElement(element, element->parentNode() ? element->parentNode()->computedStyle() : 0);
1706     m_ignorePendingStylesheets = oldIgnore;
1707     return style.release();
1708 }
1709
1710 PassRefPtr<RenderStyle> Document::styleForPage(int pageIndex)
1711 {
1712     RefPtr<RenderStyle> style = styleSelector()->styleForPage(pageIndex);
1713     return style.release();
1714 }
1715
1716 bool Document::isPageBoxVisible(int pageIndex)
1717 {
1718     RefPtr<RenderStyle> style = styleForPage(pageIndex);
1719     return style->visibility() != HIDDEN; // display property doesn't apply to @page.
1720 }
1721
1722 void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
1723 {
1724     RefPtr<RenderStyle> style = styleForPage(pageIndex);
1725
1726     int width = pageSize.width();
1727     int height = pageSize.height();
1728     switch (style->pageSizeType()) {
1729     case PAGE_SIZE_AUTO:
1730         break;
1731     case PAGE_SIZE_AUTO_LANDSCAPE:
1732         if (width < height)
1733             std::swap(width, height);
1734         break;
1735     case PAGE_SIZE_AUTO_PORTRAIT:
1736         if (width > height)
1737             std::swap(width, height);
1738         break;
1739     case PAGE_SIZE_RESOLVED: {
1740         LengthSize size = style->pageSize();
1741         ASSERT(size.width().isFixed());
1742         ASSERT(size.height().isFixed());
1743         width = size.width().calcValue(0);
1744         height = size.height().calcValue(0);
1745         break;
1746     }
1747     default:
1748         ASSERT_NOT_REACHED();
1749     }
1750     pageSize = IntSize(width, height);
1751
1752     // The percentage is calculated with respect to the width even for margin top and bottom.
1753     // http://www.w3.org/TR/CSS2/box.html#margin-properties
1754     marginTop = style->marginTop().isAuto() ? marginTop : style->marginTop().calcValue(width);
1755     marginRight = style->marginRight().isAuto() ? marginRight : style->marginRight().calcValue(width);
1756     marginBottom = style->marginBottom().isAuto() ? marginBottom : style->marginBottom().calcValue(width);
1757     marginLeft = style->marginLeft().isAuto() ? marginLeft : style->marginLeft().calcValue(width);
1758 }
1759
1760 void Document::createStyleSelector()
1761 {
1762     bool matchAuthorAndUserStyles = true;
1763     if (Settings* docSettings = settings())
1764         matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
1765     m_styleSelector.set(new CSSStyleSelector(this, m_styleSheets.get(), m_mappedElementSheet.get(), pageUserSheet(), pageGroupUserSheets(), 
1766                                              !inQuirksMode(), matchAuthorAndUserStyles));
1767 }
1768
1769 void Document::attach()
1770 {
1771     ASSERT(!attached());
1772     ASSERT(!m_inPageCache);
1773     ASSERT(!m_axObjectCache);
1774
1775     if (!m_renderArena)
1776         m_renderArena = new RenderArena();
1777     
1778     // Create the rendering tree
1779     setRenderer(new (m_renderArena.get()) RenderView(this, view()));
1780 #if USE(ACCELERATED_COMPOSITING)
1781     renderView()->didMoveOnscreen();
1782 #endif
1783
1784     recalcStyle(Force);
1785
1786     RenderObject* render = renderer();
1787     setRenderer(0);
1788
1789     ContainerNode::attach();
1790
1791     setRenderer(render);
1792 }
1793
1794 void Document::detach()
1795 {
1796     ASSERT(attached());
1797     ASSERT(!m_inPageCache);
1798
1799     clearAXObjectCache();
1800     stopActiveDOMObjects();
1801     
1802     RenderObject* render = renderer();
1803
1804     // Send out documentWillBecomeInactive() notifications to registered elements,
1805     // in order to stop media elements
1806     documentWillBecomeInactive();
1807
1808 #if ENABLE(SHARED_WORKERS)
1809     SharedWorkerRepository::documentDetached(this);
1810 #endif
1811
1812     if (m_frame) {
1813         FrameView* view = m_frame->view();
1814         if (view)
1815             view->detachCustomScrollbars();
1816
1817 #if ENABLE(TOUCH_EVENTS)
1818         Page* ownerPage = page();
1819         if (ownerPage && (m_frame == ownerPage->mainFrame())) {
1820             // Inform the Chrome Client that it no longer needs to
1821             // foward touch events to WebCore as the document is being
1822             // destroyed. It may start again if a subsequent page
1823             // registers a touch event listener.
1824             ownerPage->chrome()->client()->needTouchEvents(false);
1825         }
1826 #endif
1827     }
1828
1829     // indicate destruction mode,  i.e. attached() but renderer == 0
1830     setRenderer(0);
1831     
1832 #if ENABLE(FULLSCREEN_API)
1833     if (m_fullScreenRenderer)
1834         setFullScreenRenderer(0);
1835 #endif
1836
1837     m_hoverNode = 0;
1838     m_focusedNode = 0;
1839     m_activeNode = 0;
1840
1841     ContainerNode::detach();
1842
1843     unscheduleStyleRecalc();
1844
1845     if (render)
1846         render->destroy();
1847     
1848     // This is required, as our Frame might delete itself as soon as it detaches
1849     // us. However, this violates Node::detach() semantics, as it's never
1850     // possible to re-attach. Eventually Document::detach() should be renamed,
1851     // or this setting of the frame to 0 could be made explicit in each of the
1852     // callers of Document::detach().
1853     m_frame = 0;
1854     m_renderArena.clear();
1855 }
1856
1857 void Document::removeAllEventListeners()
1858 {
1859     EventTarget::removeAllEventListeners();
1860
1861     if (DOMWindow* domWindow = this->domWindow())
1862         domWindow->removeAllEventListeners();
1863     for (Node* node = firstChild(); node; node = node->traverseNextNode())
1864         node->removeAllEventListeners();
1865 }
1866
1867 RenderView* Document::renderView() const
1868 {
1869     return toRenderView(renderer());
1870 }
1871
1872 void Document::clearAXObjectCache()
1873 {
1874     // clear cache in top document
1875     if (m_axObjectCache) {
1876         // Clear the cache member variable before calling delete because attempts
1877         // are made to access it during destruction.
1878         AXObjectCache* axObjectCache = m_axObjectCache;
1879         m_axObjectCache = 0;
1880         delete axObjectCache;
1881         return;
1882     }
1883     
1884     // ask the top-level document to clear its cache
1885     Document* doc = topDocument();
1886     if (doc != this)
1887         doc->clearAXObjectCache();
1888 }
1889
1890 bool Document::axObjectCacheExists() const
1891 {
1892     if (m_axObjectCache)
1893         return true;
1894     
1895     Document* doc = topDocument();
1896     if (doc != this)
1897         return doc->axObjectCacheExists();
1898     
1899     return false;
1900 }
1901     
1902 AXObjectCache* Document::axObjectCache() const
1903 {
1904     // The only document that actually has a AXObjectCache is the top-level
1905     // document.  This is because we need to be able to get from any WebCoreAXObject
1906     // to any other WebCoreAXObject on the same page.  Using a single cache allows
1907     // lookups across nested webareas (i.e. multiple documents).
1908     
1909     if (m_axObjectCache) {
1910         // return already known top-level cache
1911         if (!ownerElement())
1912             return m_axObjectCache;
1913         
1914         // In some pages with frames, the cache is created before the sub-webarea is
1915         // inserted into the tree.  Here, we catch that case and just toss the old
1916         // cache and start over.
1917         // NOTE: This recovery may no longer be needed. I have been unable to trigger
1918         // it again. See rdar://5794454
1919         // FIXME: Can this be fixed when inserting the subframe instead of now?
1920         // FIXME: If this function was called to get the cache in order to remove
1921         // an AXObject, we are now deleting the cache as a whole and returning a
1922         // new empty cache that does not contain the AXObject! That should actually
1923         // be OK. I am concerned about other cases like this where accessing the
1924         // cache blows away the AXObject being operated on.
1925         delete m_axObjectCache;
1926         m_axObjectCache = 0;
1927     }
1928
1929     // ask the top-level document for its cache
1930     Document* doc = topDocument();
1931     if (doc != this)
1932         return doc->axObjectCache();
1933     
1934     // this is the top-level document, so install a new cache
1935     m_axObjectCache = new AXObjectCache(this);
1936     return m_axObjectCache;
1937 }
1938
1939 void Document::setVisuallyOrdered()
1940 {
1941     m_visuallyOrdered = true;
1942     if (renderer())
1943         renderer()->style()->setVisuallyOrdered(true);
1944 }
1945
1946 PassRefPtr<DocumentParser> Document::createParser()
1947 {
1948     // FIXME: this should probably pass the frame instead
1949     return XMLDocumentParser::create(this, view());
1950 }
1951
1952 ScriptableDocumentParser* Document::scriptableDocumentParser() const
1953 {
1954     return parser() ? parser()->asScriptableDocumentParser() : 0;
1955 }
1956
1957 void Document::open(Document* ownerDocument)
1958 {
1959     if (ownerDocument) {
1960         setURL(ownerDocument->url());
1961         m_cookieURL = ownerDocument->cookieURL();
1962         ScriptExecutionContext::setSecurityOrigin(ownerDocument->securityOrigin());
1963     }
1964
1965     if (m_frame) {
1966         ScriptableDocumentParser* parser = scriptableDocumentParser();
1967         if (m_frame->loader()->isLoadingMainResource() || (parser && parser->isParsing() && parser->isExecutingScript()))
1968             return;
1969
1970         if (m_frame->loader()->state() == FrameStateProvisional)
1971             m_frame->loader()->stopAllLoaders();
1972     }
1973
1974     removeAllEventListeners();
1975     implicitOpen();
1976
1977     if (DOMWindow* domWindow = this->domWindow())
1978         domWindow->removeAllEventListeners();
1979
1980     if (m_frame)
1981         m_frame->loader()->didExplicitOpen();
1982 }
1983
1984 void Document::detachParser()
1985 {
1986     if (!m_parser)
1987         return;
1988     m_parser->detach();
1989     m_parser.clear();
1990 }
1991
1992 void Document::cancelParsing()
1993 {
1994     if (m_parser) {
1995         // We have to clear the parser to avoid possibly triggering
1996         // the onload handler when closing as a side effect of a cancel-style
1997         // change, such as opening a new document or closing the window while
1998         // still parsing
1999         detachParser();
2000         close();
2001     }
2002 }
2003
2004 void Document::implicitOpen()
2005 {
2006     cancelParsing();
2007
2008     removeChildren();
2009
2010     setCompatibilityMode(NoQuirksMode);
2011
2012     m_parser = createParser();
2013     setParsing(true);
2014     setReadyState(Loading);
2015
2016     ScriptableDocumentParser* parser = scriptableDocumentParser();
2017     if (m_frame && parser)
2018         parser->setXSSAuditor(m_frame->script()->xssAuditor());
2019
2020     // If we reload, the animation controller sticks around and has
2021     // a stale animation time. We need to update it here.
2022     if (m_frame && m_frame->animation())
2023         m_frame->animation()->beginAnimationUpdate();
2024 }
2025
2026 HTMLElement* Document::body() const
2027 {
2028     Node* de = documentElement();
2029     if (!de)
2030         return 0;
2031     
2032     // try to prefer a FRAMESET element over BODY
2033     Node* body = 0;
2034     for (Node* i = de->firstChild(); i; i = i->nextSibling()) {
2035         if (i->hasTagName(framesetTag))
2036             return static_cast<HTMLElement*>(i);
2037         
2038         if (i->hasTagName(bodyTag) && !body)
2039             body = i;
2040     }
2041     return static_cast<HTMLElement*>(body);
2042 }
2043
2044 void Document::setBody(PassRefPtr<HTMLElement> newBody, ExceptionCode& ec)
2045 {
2046     if (!newBody || !documentElement()) { 
2047         ec = HIERARCHY_REQUEST_ERR;
2048         return;
2049     }
2050
2051     HTMLElement* b = body();
2052     if (!b)
2053         documentElement()->appendChild(newBody, ec);
2054     else
2055         documentElement()->replaceChild(newBody, b, ec);
2056 }
2057
2058 HTMLHeadElement* Document::head()
2059 {
2060     Node* de = documentElement();
2061     if (!de)
2062         return 0;
2063
2064     for (Node* e = de->firstChild(); e; e = e->nextSibling())
2065         if (e->hasTagName(headTag))
2066             return static_cast<HTMLHeadElement*>(e);
2067
2068     return 0;
2069 }
2070
2071 void Document::close()
2072 {
2073     Frame* frame = this->frame();
2074     if (frame) {
2075         // This code calls implicitClose() if all loading has completed.
2076         FrameLoader* frameLoader = frame->loader();
2077         frameLoader->writer()->endIfNotLoadingMainResource();
2078         frameLoader->checkCompleted();
2079     } else {
2080         // Because we have no frame, we don't know if all loading has completed,
2081         // so we just call implicitClose() immediately. FIXME: This might fire
2082         // the load event prematurely <http://bugs.webkit.org/show_bug.cgi?id=14568>.
2083         implicitClose();
2084     }
2085 }
2086
2087 void Document::implicitClose()
2088 {
2089     // If we're in the middle of recalcStyle, we need to defer the close until the style information is accurate and all elements are re-attached.
2090     if (m_inStyleRecalc) {
2091         m_closeAfterStyleRecalc = true;
2092         return;
2093     }
2094
2095     bool wasLocationChangePending = frame() && frame()->navigationScheduler()->locationChangePending();
2096     bool doload = !parsing() && m_parser && !m_processingLoadEvent && !wasLocationChangePending;
2097     
2098     if (!doload)
2099         return;
2100
2101     m_processingLoadEvent = true;
2102
2103     ScriptableDocumentParser* parser = scriptableDocumentParser();
2104     m_wellFormed = parser && parser->wellFormed();
2105
2106     // We have to clear the parser, in case someone document.write()s from the
2107     // onLoad event handler, as in Radar 3206524.
2108     detachParser();
2109
2110     // Parser should have picked up all preloads by now
2111     m_cachedResourceLoader->clearPreloads();
2112
2113     // FIXME: We kick off the icon loader when the Document is done parsing.
2114     // There are earlier opportunities we could start it:
2115     //  -When the <head> finishes parsing
2116     //  -When any new HTMLLinkElement is inserted into the document
2117     // But those add a dynamic component to the favicon that has UI 
2118     // ramifications, and we need to decide what is the Right Thing To Do(tm)
2119     Frame* f = frame();
2120     if (f)
2121         f->loader()->startIconLoader();
2122
2123     // Resume the animations (or start them)
2124     if (f)
2125         f->animation()->resumeAnimationsForDocument(this);
2126
2127     ImageLoader::dispatchPendingBeforeLoadEvents();
2128     ImageLoader::dispatchPendingLoadEvents();
2129     dispatchWindowLoadEvent();
2130     enqueuePageshowEvent(PageshowEventNotPersisted);
2131     enqueuePopstateEvent(m_pendingStateObject ? m_pendingStateObject.release() : SerializedScriptValue::nullValue());
2132     
2133     if (f)
2134         f->loader()->handledOnloadEvents();
2135 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2136     if (!ownerElement())
2137         printf("onload fired at %d\n", elapsedTime());
2138 #endif
2139
2140     m_processingLoadEvent = false;
2141
2142     // An event handler may have removed the frame
2143     if (!frame())
2144         return;
2145
2146     // Make sure both the initial layout and reflow happen after the onload
2147     // fires. This will improve onload scores, and other browsers do it.
2148     // If they wanna cheat, we can too. -dwh
2149
2150     if (frame()->navigationScheduler()->locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
2151         // Just bail out. Before or during the onload we were shifted to another page.
2152         // The old i-Bench suite does this. When this happens don't bother painting or laying out.        
2153         view()->unscheduleRelayout();
2154         return;
2155     }
2156
2157     frame()->loader()->checkCallImplicitClose();
2158     RenderObject* renderObject = renderer();
2159     
2160     // We used to force a synchronous display and flush here.  This really isn't
2161     // necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
2162     // (if your platform is syncing flushes and limiting them to 60fps).
2163     m_overMinimumLayoutThreshold = true;
2164     if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
2165         updateStyleIfNeeded();
2166         
2167         // Always do a layout after loading if needed.
2168         if (view() && renderObject && (!renderObject->firstChild() || renderObject->needsLayout()))
2169             view()->layout();
2170     }
2171
2172 #if PLATFORM(MAC) || PLATFORM(CHROMIUM)
2173     if (f && renderObject && this == topDocument() && AXObjectCache::accessibilityEnabled()) {
2174         // The AX cache may have been cleared at this point, but we need to make sure it contains an
2175         // AX object to send the notification to. getOrCreate will make sure that an valid AX object
2176         // exists in the cache (we ignore the return value because we don't need it here). This is 
2177         // only safe to call when a layout is not in progress, so it can not be used in postNotification.    
2178         axObjectCache()->getOrCreate(renderObject);
2179         axObjectCache()->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
2180     }
2181 #endif
2182
2183 #if ENABLE(SVG)
2184     // FIXME: Officially, time 0 is when the outermost <svg> receives its
2185     // SVGLoad event, but we don't implement those yet.  This is close enough
2186     // for now.  In some cases we should have fired earlier.
2187     if (svgExtensions())
2188         accessSVGExtensions()->startAnimations();
2189 #endif
2190 }
2191
2192 void Document::setParsing(bool b)
2193 {
2194     m_bParsing = b;
2195     if (!m_bParsing && view())
2196         view()->scheduleRelayout();
2197
2198 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2199     if (!ownerElement() && !m_bParsing)
2200         printf("Parsing finished at %d\n", elapsedTime());
2201 #endif
2202 }
2203
2204 bool Document::shouldScheduleLayout()
2205 {
2206     // This function will only be called when FrameView thinks a layout is needed.
2207     // This enforces a couple extra rules.
2208     //
2209     //    (a) Only schedule a layout once the stylesheets are loaded.
2210     //    (b) Only schedule layout once we have a body element.
2211
2212     return (haveStylesheetsLoaded() && body())
2213         || (documentElement() && !documentElement()->hasTagName(htmlTag));
2214 }
2215
2216 int Document::minimumLayoutDelay()
2217 {
2218     if (m_overMinimumLayoutThreshold)
2219         return m_extraLayoutDelay;
2220     
2221     int elapsed = elapsedTime();
2222     m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
2223     
2224     // We'll want to schedule the timer to fire at the minimum layout threshold.
2225     return max(0, cLayoutScheduleThreshold - elapsed) + m_extraLayoutDelay;
2226 }
2227
2228 int Document::elapsedTime() const
2229 {
2230     return static_cast<int>((currentTime() - m_startTime) * 1000);
2231 }
2232
2233 void Document::write(const SegmentedString& text, Document* ownerDocument)
2234 {
2235 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2236     if (!ownerElement())
2237         printf("Beginning a document.write at %d\n", elapsedTime());
2238 #endif
2239
2240     bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
2241     if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)
2242         return;
2243
2244     if (!hasInsertionPoint)
2245         open(ownerDocument);
2246
2247     ASSERT(m_parser);
2248     m_parser->insert(text);
2249
2250 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2251     if (!ownerElement())
2252         printf("Ending a document.write at %d\n", elapsedTime());
2253 #endif    
2254 }
2255
2256 void Document::write(const String& text, Document* ownerDocument)
2257 {
2258     write(SegmentedString(text), ownerDocument);
2259 }
2260
2261 void Document::writeln(const String& text, Document* ownerDocument)
2262 {
2263     write(text, ownerDocument);
2264     write("\n", ownerDocument);
2265 }
2266
2267 void Document::finishParsing()
2268 {
2269 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2270     if (!ownerElement())
2271         printf("Received all data at %d\n", elapsedTime());
2272 #endif
2273     
2274     // Let the parser go through as much data as it can.  There will be three possible outcomes after
2275     // finish() is called:
2276     // (1) All remaining data is parsed, document isn't loaded yet
2277     // (2) All remaining data is parsed, document is loaded, parser gets deleted
2278     // (3) Data is still remaining to be parsed.
2279     if (m_parser)
2280         m_parser->finish();
2281 }
2282
2283 const KURL& Document::virtualURL() const
2284 {
2285     return m_url;
2286 }
2287
2288 KURL Document::virtualCompleteURL(const String& url) const
2289 {
2290     return completeURL(url);
2291 }
2292
2293 void Document::setURL(const KURL& url)
2294 {
2295     const KURL& newURL = url.isEmpty() ? blankURL() : url;
2296     if (newURL == m_url)
2297         return;
2298
2299     m_url = newURL;
2300     m_documentURI = m_url.string();
2301     updateBaseURL();
2302 }
2303
2304 void Document::updateBaseURL()
2305 {
2306     // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML], the base URI is computed using
2307     // first the value of the href attribute of the HTML BASE element if any, and the value of the documentURI attribute
2308     // from the Document interface otherwise.
2309     if (m_baseElementURL.isEmpty()) {
2310         // The documentURI attribute is an arbitrary string. DOM 3 Core does not specify how it should be resolved,
2311         // so we use a null base URL.
2312         m_baseURL = KURL(KURL(), documentURI());
2313     } else
2314         m_baseURL = m_baseElementURL;
2315     if (!m_baseURL.isValid())
2316         m_baseURL = KURL();
2317
2318     if (m_elemSheet)
2319         m_elemSheet->setFinalURL(m_baseURL);
2320     if (m_mappedElementSheet)
2321         m_mappedElementSheet->setFinalURL(m_baseURL);
2322 }
2323
2324 void Document::processBaseElement()
2325 {
2326     // Find the first href attribute in a base element and the first target attribute in a base element.
2327     const AtomicString* href = 0;
2328     const AtomicString* target = 0;
2329     for (Node* node = document()->firstChild(); node && (!href || !target); node = node->traverseNextNode()) {
2330         if (node->hasTagName(baseTag)) {
2331             if (!href) {
2332                 const AtomicString& value = static_cast<Element*>(node)->fastGetAttribute(hrefAttr);
2333                 if (!value.isNull())
2334                     href = &value;
2335             }
2336             if (!target) {
2337                 const AtomicString& value = static_cast<Element*>(node)->fastGetAttribute(targetAttr);
2338                 if (!value.isNull())
2339                     target = &value;
2340             }
2341         }
2342     }
2343
2344     // FIXME: Since this doesn't share code with completeURL it may not handle encodings correctly.
2345     KURL baseElementURL;
2346     if (href) {
2347         String strippedHref = stripLeadingAndTrailingHTMLSpaces(*href);
2348         if (!strippedHref.isEmpty() && (!frame() || frame()->script()->xssAuditor()->canSetBaseElementURL(*href)))
2349             baseElementURL = KURL(url(), strippedHref);
2350     }
2351     if (m_baseElementURL != baseElementURL) {
2352         m_baseElementURL = baseElementURL;
2353         updateBaseURL();
2354     }
2355
2356     m_baseTarget = target ? *target : nullAtom;
2357 }
2358
2359 String Document::userAgent(const KURL& url) const
2360 {
2361     return frame() ? frame()->loader()->userAgent(url) : String();
2362 }
2363
2364 CSSStyleSheet* Document::pageUserSheet()
2365 {
2366     if (m_pageUserSheet)
2367         return m_pageUserSheet.get();
2368     
2369     Page* owningPage = page();
2370     if (!owningPage)
2371         return 0;
2372     
2373     String userSheetText = owningPage->userStyleSheet();
2374     if (userSheetText.isEmpty())
2375         return 0;
2376     
2377     // Parse the sheet and cache it.
2378     m_pageUserSheet = CSSStyleSheet::createInline(this, settings()->userStyleSheetLocation());
2379     m_pageUserSheet->setIsUserStyleSheet(true);
2380     m_pageUserSheet->parseString(userSheetText, !inQuirksMode());
2381     return m_pageUserSheet.get();
2382 }
2383
2384 void Document::clearPageUserSheet()
2385 {
2386     if (m_pageUserSheet) {
2387         m_pageUserSheet = 0;
2388         styleSelectorChanged(DeferRecalcStyle);
2389     }
2390 }
2391
2392 void Document::updatePageUserSheet()
2393 {
2394     clearPageUserSheet();
2395     if (pageUserSheet())
2396         styleSelectorChanged(RecalcStyleImmediately);
2397 }
2398
2399 const Vector<RefPtr<CSSStyleSheet> >* Document::pageGroupUserSheets() const
2400 {
2401     if (m_pageGroupUserSheetCacheValid)
2402         return m_pageGroupUserSheets.get();
2403     
2404     m_pageGroupUserSheetCacheValid = true;
2405     
2406     Page* owningPage = page();
2407     if (!owningPage)
2408         return 0;
2409         
2410     const PageGroup& pageGroup = owningPage->group();
2411     const UserStyleSheetMap* sheetsMap = pageGroup.userStyleSheets();
2412     if (!sheetsMap)
2413         return 0;
2414
2415     UserStyleSheetMap::const_iterator end = sheetsMap->end();
2416     for (UserStyleSheetMap::const_iterator it = sheetsMap->begin(); it != end; ++it) {
2417         const UserStyleSheetVector* sheets = it->second;
2418         for (unsigned i = 0; i < sheets->size(); ++i) {
2419             const UserStyleSheet* sheet = sheets->at(i).get();
2420             if (sheet->injectedFrames() == InjectInTopFrameOnly && ownerElement())
2421                 continue;
2422             if (!UserContentURLPattern::matchesPatterns(url(), sheet->whitelist(), sheet->blacklist()))
2423                 continue;
2424             RefPtr<CSSStyleSheet> parsedSheet = CSSStyleSheet::createInline(const_cast<Document*>(this), sheet->url());
2425             parsedSheet->setIsUserStyleSheet(sheet->level() == UserStyleUserLevel);
2426             parsedSheet->parseString(sheet->source(), !inQuirksMode());
2427             if (!m_pageGroupUserSheets)
2428                 m_pageGroupUserSheets.set(new Vector<RefPtr<CSSStyleSheet> >);
2429             m_pageGroupUserSheets->append(parsedSheet.release());
2430         }
2431     }
2432
2433     return m_pageGroupUserSheets.get();
2434 }
2435
2436 void Document::clearPageGroupUserSheets()
2437 {
2438     m_pageGroupUserSheetCacheValid = false;
2439     if (m_pageGroupUserSheets && m_pageGroupUserSheets->size()) {
2440         m_pageGroupUserSheets->clear();
2441         styleSelectorChanged(DeferRecalcStyle);
2442     }
2443 }
2444
2445 void Document::updatePageGroupUserSheets()
2446 {
2447     clearPageGroupUserSheets();
2448     if (pageGroupUserSheets() && pageGroupUserSheets()->size())
2449         styleSelectorChanged(RecalcStyleImmediately);
2450 }
2451
2452 CSSStyleSheet* Document::elementSheet()
2453 {
2454     if (!m_elemSheet)
2455         m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
2456     return m_elemSheet.get();
2457 }
2458
2459 CSSStyleSheet* Document::mappedElementSheet()
2460 {
2461     if (!m_mappedElementSheet)
2462         m_mappedElementSheet = CSSStyleSheet::createInline(this, m_baseURL);
2463     return m_mappedElementSheet.get();
2464 }
2465
2466 static Node* nextNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
2467 {
2468     // Search is inclusive of start
2469     for (Node* n = start; n; n = n->traverseNextNode())
2470         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
2471             return n;
2472     
2473     return 0;
2474 }
2475
2476 static Node* previousNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
2477 {
2478     // Search is inclusive of start
2479     for (Node* n = start; n; n = n->traversePreviousNode())
2480         if (n->isKeyboardFocusable(event) && n->tabIndex() == tabIndex)
2481             return n;
2482     
2483     return 0;
2484 }
2485
2486 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
2487 {
2488     // Search is inclusive of start
2489     int winningTabIndex = SHRT_MAX + 1;
2490     Node* winner = 0;
2491     for (Node* n = start; n; n = n->traverseNextNode())
2492         if (n->isKeyboardFocusable(event) && n->tabIndex() > tabIndex && n->tabIndex() < winningTabIndex) {
2493             winner = n;
2494             winningTabIndex = n->tabIndex();
2495         }
2496     
2497     return winner;
2498 }
2499
2500 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
2501 {
2502     // Search is inclusive of start
2503     int winningTabIndex = 0;
2504     Node* winner = 0;
2505     for (Node* n = start; n; n = n->traversePreviousNode())
2506         if (n->isKeyboardFocusable(event) && n->tabIndex() < tabIndex && n->tabIndex() > winningTabIndex) {
2507             winner = n;
2508             winningTabIndex = n->tabIndex();
2509         }
2510     
2511     return winner;
2512 }
2513
2514 Node* Document::nextFocusableNode(Node* start, KeyboardEvent* event)
2515 {
2516     if (start) {
2517         // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
2518         if (start->tabIndex() < 0) {
2519             for (Node* n = start->traverseNextNode(); n; n = n->traverseNextNode())
2520                 if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
2521                     return n;
2522         }
2523     
2524         // First try to find a node with the same tabindex as start that comes after start in the document.
2525         if (Node* winner = nextNodeWithExactTabIndex(start->traverseNextNode(), start->tabIndex(), event))
2526             return winner;
2527
2528         if (!start->tabIndex())
2529             // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
2530             return 0;
2531     }
2532
2533     // Look for the first node in the document that:
2534     // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
2535     // 2) comes first in the document, if there's a tie.
2536     if (Node* winner = nextNodeWithGreaterTabIndex(this, start ? start->tabIndex() : 0, event))
2537         return winner;
2538
2539     // There are no nodes with a tabindex greater than start's tabindex,
2540     // so find the first node with a tabindex of 0.
2541     return nextNodeWithExactTabIndex(this, 0, event);
2542 }
2543
2544 Node* Document::previousFocusableNode(Node* start, KeyboardEvent* event)
2545 {
2546     Node* last;
2547     for (last = this; last->lastChild(); last = last->lastChild()) { }
2548
2549     // First try to find the last node in the document that comes before start and has the same tabindex as start.
2550     // If start is null, find the last node in the document with a tabindex of 0.
2551     Node* startingNode;
2552     int startingTabIndex;
2553     if (start) {
2554         startingNode = start->traversePreviousNode();
2555         startingTabIndex = start->tabIndex();
2556     } else {
2557         startingNode = last;
2558         startingTabIndex = 0;
2559     }
2560     
2561     // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
2562     if (startingTabIndex < 0) {
2563         for (Node* n = startingNode; n; n = n->traversePreviousNode())
2564             if (n->isKeyboardFocusable(event) && n->tabIndex() >= 0)
2565                 return n;        
2566     }
2567
2568     if (Node* winner = previousNodeWithExactTabIndex(startingNode, startingTabIndex, event))
2569         return winner;
2570
2571     // There are no nodes before start with the same tabindex as start, so look for a node that:
2572     // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
2573     // 2) comes last in the document, if there's a tie.
2574     startingTabIndex = (start && start->tabIndex()) ? start->tabIndex() : SHRT_MAX;
2575     return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
2576 }
2577
2578 int Document::nodeAbsIndex(Node *node)
2579 {
2580     ASSERT(node->document() == this);
2581
2582     int absIndex = 0;
2583     for (Node* n = node; n && n != this; n = n->traversePreviousNode())
2584         absIndex++;
2585     return absIndex;
2586 }
2587
2588 Node* Document::nodeWithAbsIndex(int absIndex)
2589 {
2590     Node* n = this;
2591     for (int i = 0; n && (i < absIndex); i++)
2592         n = n->traverseNextNode();
2593     return n;
2594 }
2595
2596 void Document::processHttpEquiv(const String& equiv, const String& content)
2597 {
2598     ASSERT(!equiv.isNull() && !content.isNull());
2599
2600     Frame* frame = this->frame();
2601
2602     if (equalIgnoringCase(equiv, "default-style")) {
2603         // The preferred style set has been overridden as per section 
2604         // 14.3.2 of the HTML4.0 specification.  We need to update the
2605         // sheet used variable and then update our style selector. 
2606         // For more info, see the test at:
2607         // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
2608         // -dwh
2609         m_selectedStylesheetSet = content;
2610         m_preferredStylesheetSet = content;
2611         styleSelectorChanged(DeferRecalcStyle);
2612     } else if (equalIgnoringCase(equiv, "refresh")) {
2613         double delay;
2614         String url;
2615         if (frame && parseHTTPRefresh(content, true, delay, url)) {
2616             if (url.isEmpty())
2617                 url = frame->loader()->url().string();
2618             else
2619                 url = completeURL(url).string();
2620             frame->navigationScheduler()->scheduleRedirect(delay, url);
2621         }
2622     } else if (equalIgnoringCase(equiv, "set-cookie")) {
2623         // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
2624         if (isHTMLDocument()) {
2625             ExceptionCode ec; // Exception (for sandboxed documents) ignored.
2626             static_cast<HTMLDocument*>(this)->setCookie(content, ec);
2627         }
2628     } else if (equalIgnoringCase(equiv, "content-language"))
2629         setContentLanguage(content);
2630     else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
2631         parseDNSPrefetchControlHeader(content);
2632     else if (equalIgnoringCase(equiv, "x-frame-options")) {
2633         if (frame) {
2634             FrameLoader* frameLoader = frame->loader();
2635             if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url())) {
2636                 frameLoader->stopAllLoaders();
2637                 frame->navigationScheduler()->scheduleLocationChange(securityOrigin(), blankURL(), String());
2638
2639                 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to display document because display forbidden by X-Frame-Options.\n"));
2640                 frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
2641             }
2642         }
2643     }
2644 }
2645
2646 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
2647 static bool isSeparator(UChar c)
2648 {
2649     return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
2650 }
2651
2652 void Document::processArguments(const String& features, void* data, ArgumentsCallback callback)
2653 {
2654     // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
2655     int keyBegin, keyEnd;
2656     int valueBegin, valueEnd;
2657
2658     int i = 0;
2659     int length = features.length();
2660     String buffer = features.lower();
2661     while (i < length) {
2662         // skip to first non-separator, but don't skip past the end of the string
2663         while (isSeparator(buffer[i])) {
2664             if (i >= length)
2665                 break;
2666             i++;
2667         }
2668         keyBegin = i;
2669
2670         // skip to first separator
2671         while (!isSeparator(buffer[i]))
2672             i++;
2673         keyEnd = i;
2674
2675         // skip to first '=', but don't skip past a ',' or the end of the string
2676         while (buffer[i] != '=') {
2677             if (buffer[i] == ',' || i >= length)
2678                 break;
2679             i++;
2680         }
2681
2682         // skip to first non-separator, but don't skip past a ',' or the end of the string
2683         while (isSeparator(buffer[i])) {
2684             if (buffer[i] == ',' || i >= length)
2685                 break;
2686             i++;
2687         }
2688         valueBegin = i;
2689
2690         // skip to first separator
2691         while (!isSeparator(buffer[i]))
2692             i++;
2693         valueEnd = i;
2694
2695         ASSERT(i <= length);
2696
2697         String keyString = buffer.substring(keyBegin, keyEnd - keyBegin);
2698         String valueString = buffer.substring(valueBegin, valueEnd - valueBegin);
2699         callback(keyString, valueString, this, data);
2700     }
2701 }
2702
2703 void Document::processViewport(const String& features)
2704 {
2705     ASSERT(!features.isNull());
2706
2707     m_viewportArguments = ViewportArguments();
2708     processArguments(features, (void*)&m_viewportArguments, &setViewportFeature);
2709
2710     Frame* frame = this->frame();
2711     if (!frame || !frame->page())
2712         return;
2713
2714     frame->page()->updateViewportArguments();
2715 }
2716
2717 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const IntPoint& documentPoint, const PlatformMouseEvent& event)
2718 {
2719     ASSERT(!renderer() || renderer()->isRenderView());
2720
2721     if (!renderer())
2722         return MouseEventWithHitTestResults(event, HitTestResult(IntPoint()));
2723
2724     HitTestResult result(documentPoint);
2725     renderView()->layer()->hitTest(request, result);
2726
2727     if (!request.readOnly())
2728         updateStyleIfNeeded();
2729
2730     return MouseEventWithHitTestResults(event, result);
2731 }
2732
2733 // DOM Section 1.1.1
2734 bool Document::childTypeAllowed(NodeType type)
2735 {
2736     switch (type) {
2737     case ATTRIBUTE_NODE:
2738     case CDATA_SECTION_NODE:
2739     case DOCUMENT_FRAGMENT_NODE:
2740     case DOCUMENT_NODE:
2741     case ENTITY_NODE:
2742     case ENTITY_REFERENCE_NODE:
2743     case NOTATION_NODE:
2744     case TEXT_NODE:
2745     case XPATH_NAMESPACE_NODE:
2746         return false;
2747     case COMMENT_NODE:
2748     case PROCESSING_INSTRUCTION_NODE:
2749         return true;
2750     case DOCUMENT_TYPE_NODE:
2751     case ELEMENT_NODE:
2752         // Documents may contain no more than one of each of these.
2753         // (One Element and one DocumentType.)
2754         for (Node* c = firstChild(); c; c = c->nextSibling())
2755             if (c->nodeType() == type)
2756                 return false;
2757         return true;
2758     }
2759     return false;
2760 }
2761
2762 bool Document::canReplaceChild(Node* newChild, Node* oldChild)
2763 {
2764     if (!oldChild)
2765         // ContainerNode::replaceChild will raise a NOT_FOUND_ERR.
2766         return true;
2767
2768     if (oldChild->nodeType() == newChild->nodeType())
2769         return true;
2770
2771     int numDoctypes = 0;
2772     int numElements = 0;
2773
2774     // First, check how many doctypes and elements we have, not counting
2775     // the child we're about to remove.
2776     for (Node* c = firstChild(); c; c = c->nextSibling()) {
2777         if (c == oldChild)
2778             continue;
2779         
2780         switch (c->nodeType()) {
2781         case DOCUMENT_TYPE_NODE:
2782             numDoctypes++;
2783             break;
2784         case ELEMENT_NODE:
2785             numElements++;
2786             break;
2787         default:
2788             break;
2789         }
2790     }
2791     
2792     // Then, see how many doctypes and elements might be added by the new child.
2793     if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
2794         for (Node* c = firstChild(); c; c = c->nextSibling()) {
2795             switch (c->nodeType()) {
2796             case ATTRIBUTE_NODE:
2797             case CDATA_SECTION_NODE:
2798             case DOCUMENT_FRAGMENT_NODE:
2799             case DOCUMENT_NODE:
2800             case ENTITY_NODE:
2801             case ENTITY_REFERENCE_NODE:
2802             case NOTATION_NODE:
2803             case TEXT_NODE:
2804             case XPATH_NAMESPACE_NODE:
2805                 return false;
2806             case COMMENT_NODE:
2807             case PROCESSING_INSTRUCTION_NODE:
2808                 break;
2809             case DOCUMENT_TYPE_NODE:
2810                 numDoctypes++;
2811                 break;
2812             case ELEMENT_NODE:
2813                 numElements++;
2814                 break;
2815             }
2816         }
2817     } else {
2818         switch (newChild->nodeType()) {
2819         case ATTRIBUTE_NODE:
2820         case CDATA_SECTION_NODE:
2821         case DOCUMENT_FRAGMENT_NODE:
2822         case DOCUMENT_NODE:
2823         case ENTITY_NODE:
2824         case ENTITY_REFERENCE_NODE:
2825         case NOTATION_NODE:
2826         case TEXT_NODE:
2827         case XPATH_NAMESPACE_NODE:
2828             return false;
2829         case COMMENT_NODE:
2830         case PROCESSING_INSTRUCTION_NODE:
2831             return true;
2832         case DOCUMENT_TYPE_NODE:
2833             numDoctypes++;
2834             break;
2835         case ELEMENT_NODE:
2836             numElements++;
2837             break;
2838         }                
2839     }
2840         
2841     if (numElements > 1 || numDoctypes > 1)
2842         return false;
2843     
2844     return true;
2845 }
2846
2847 PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
2848 {
2849     // Spec says cloning Document nodes is "implementation dependent"
2850     // so we do not support it...
2851     return 0;
2852 }
2853
2854 StyleSheetList* Document::styleSheets()
2855 {
2856     return m_styleSheets.get();
2857 }
2858
2859 String Document::preferredStylesheetSet() const
2860 {
2861     return m_preferredStylesheetSet;
2862 }
2863
2864 String Document::selectedStylesheetSet() const
2865 {
2866     return m_selectedStylesheetSet;
2867 }
2868
2869 void Document::setSelectedStylesheetSet(const String& aString)
2870 {
2871     m_selectedStylesheetSet = aString;
2872     styleSelectorChanged(DeferRecalcStyle);
2873 }
2874
2875 // This method is called whenever a top-level stylesheet has finished loading.
2876 void Document::removePendingSheet()
2877 {
2878     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
2879     ASSERT(m_pendingStylesheets > 0);
2880
2881     m_pendingStylesheets--;
2882     
2883 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2884     if (!ownerElement())
2885         printf("Stylesheet loaded at time %d. %d stylesheets still remain.\n", elapsedTime(), m_pendingStylesheets);
2886 #endif
2887
2888     if (m_pendingStylesheets)
2889         return;
2890
2891     styleSelectorChanged(RecalcStyleImmediately);
2892
2893     ScriptableDocumentParser* parser = scriptableDocumentParser();
2894     if (parser)
2895         parser->executeScriptsWaitingForStylesheets();
2896
2897     if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
2898         view()->scrollToFragment(m_frame->loader()->url());
2899 }
2900
2901 void Document::styleSelectorChanged(StyleSelectorUpdateFlag updateFlag)
2902 {
2903     // Don't bother updating, since we haven't loaded all our style info yet
2904     // and haven't calculated the style selector for the first time.
2905     if (!attached() || (!m_didCalculateStyleSelector && !haveStylesheetsLoaded()))
2906         return;
2907
2908 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2909     if (!ownerElement())
2910         printf("Beginning update of style selector at time %d.\n", elapsedTime());
2911 #endif
2912
2913     recalcStyleSelector();
2914     
2915     if (updateFlag == DeferRecalcStyle) {
2916         scheduleForcedStyleRecalc();
2917         return;
2918     }
2919     
2920     if (didLayoutWithPendingStylesheets() && m_pendingStylesheets <= 0) {
2921         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
2922         if (renderer())
2923             renderer()->repaint();
2924     }
2925
2926     // This recalcStyle initiates a new recalc cycle. We need to bracket it to
2927     // make sure animations get the correct update time
2928     if (m_frame)
2929         m_frame->animation()->beginAnimationUpdate();
2930     recalcStyle(Force);
2931     if (m_frame)
2932         m_frame->animation()->endAnimationUpdate();
2933
2934 #ifdef INSTRUMENT_LAYOUT_SCHEDULING
2935     if (!ownerElement())
2936         printf("Finished update of style selector at time %d\n", elapsedTime());
2937 #endif
2938
2939     if (renderer()) {
2940         renderer()->setNeedsLayoutAndPrefWidthsRecalc();
2941         if (view())
2942             view()->scheduleRelayout();
2943     }
2944
2945     if (m_mediaQueryMatcher)
2946         m_mediaQueryMatcher->styleSelectorChanged();
2947 }
2948
2949 void Document::addStyleSheetCandidateNode(Node* node, bool createdByParser)
2950 {
2951     // Until the <body> exists, we have no choice but to compare document positions,
2952     // since styles outside of the body and head continue to be shunted into the head
2953     // (and thus can shift to end up before dynamically added DOM content that is also
2954     // outside the body).
2955     if ((createdByParser && body()) || m_styleSheetCandidateNodes.isEmpty()) {
2956         m_styleSheetCandidateNodes.add(node);
2957         return;
2958     }
2959
2960     // Determine an appropriate insertion point.
2961     StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
2962     StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
2963     StyleSheetCandidateListHashSet::iterator it = end;
2964     Node* followingNode = 0;
2965     do {
2966         --it;
2967         Node* n = *it;
2968         unsigned short position = n->compareDocumentPosition(node);
2969         if (position == DOCUMENT_POSITION_FOLLOWING) {
2970             m_styleSheetCandidateNodes.insertBefore(followingNode, node);
2971             return;
2972         }
2973         followingNode = n;
2974     } while (it != begin);
2975     
2976     m_styleSheetCandidateNodes.insertBefore(followingNode, node);
2977 }
2978
2979 void Document::removeStyleSheetCandidateNode(Node* node)
2980 {
2981     m_styleSheetCandidateNodes.remove(node);
2982 }
2983
2984 void Document::recalcStyleSelector()
2985 {
2986     if (!renderer() || !attached())
2987         return;
2988
2989     StyleSheetVector sheets;
2990
2991     bool matchAuthorAndUserStyles = true;
2992     if (Settings* settings = this->settings())
2993         matchAuthorAndUserStyles = settings->authorAndUserStylesEnabled();
2994
2995     StyleSheetCandidateListHashSet::iterator begin = m_styleSheetCandidateNodes.begin();
2996     StyleSheetCandidateListHashSet::iterator end = m_styleSheetCandidateNodes.end();
2997     if (!matchAuthorAndUserStyles)
2998         end = begin;
2999     for (StyleSheetCandidateListHashSet::iterator it = begin; it != end; ++it) {
3000         Node* n = *it;
3001
3002         StyleSheet* sheet = 0;
3003
3004         if (n->nodeType() == PROCESSING_INSTRUCTION_NODE) {
3005             // Processing instruction (XML documents only).
3006             // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
3007             ProcessingInstruction* pi = static_cast<ProcessingInstruction*>(n);
3008             sheet = pi->sheet();
3009 #if ENABLE(XSLT)
3010             // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
3011             if (pi->isXSL() && !transformSourceDocument()) {
3012                 // Don't apply XSL transforms until loading is finished.
3013                 if (!parsing())
3014                     applyXSLTransform(pi);
3015                 return;
3016             }
3017 #endif
3018         } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag)))
3019 #if ENABLE(SVG)
3020             ||  (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
3021 #endif
3022         ) {
3023             Element* e = static_cast<Element*>(n);
3024             AtomicString title = e->getAttribute(titleAttr);
3025             bool enabledViaScript = false;
3026             if (e->hasLocalName(linkTag)) {
3027                 // <LINK> element
3028                 HTMLLinkElement* linkElement = static_cast<HTMLLinkElement*>(n);
3029                 if (linkElement->isDisabled())
3030                     continue;
3031                 enabledViaScript = linkElement->isEnabledViaScript();
3032                 if (linkElement->isLoading()) {
3033                     // it is loading but we should still decide which style sheet set to use
3034                     if (!enabledViaScript && !title.isEmpty() && m_preferredStylesheetSet.isEmpty()) {
3035                         const AtomicString& rel = e->getAttribute(relAttr);
3036                         if (!rel.contains("alternate")) {
3037                             m_preferredStylesheetSet = title;
3038                             m_selectedStylesheetSet = title;
3039                         }
3040                     }
3041                     continue;
3042                 }
3043                 if (!linkElement->sheet())
3044                     title = nullAtom;
3045             }
3046
3047             // Get the current preferred styleset.  This is the
3048             // set of sheets that will be enabled.
3049 #if ENABLE(SVG)
3050             if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))
3051                 sheet = static_cast<SVGStyleElement*>(n)->sheet();
3052             else
3053 #endif
3054             if (e->hasLocalName(linkTag))
3055                 sheet = static_cast<HTMLLinkElement*>(n)->sheet();
3056             else
3057                 // <STYLE> element
3058                 sheet = static_cast<HTMLStyleElement*>(n)->sheet();
3059
3060             // Check to see if this sheet belongs to a styleset
3061             // (thus making it PREFERRED or ALTERNATE rather than
3062             // PERSISTENT).
3063             if (!enabledViaScript && !title.isEmpty()) {
3064                 // Yes, we have a title.
3065                 if (m_preferredStylesheetSet.isEmpty()) {
3066                     // No preferred set has been established.  If
3067                     // we are NOT an alternate sheet, then establish
3068                     // us as the preferred set.  Otherwise, just ignore
3069                     // this sheet.
3070                     AtomicString rel = e->getAttribute(relAttr);
3071                     if (e->hasLocalName(styleTag) || !rel.contains("alternate"))
3072                         m_preferredStylesheetSet = m_selectedStylesheetSet = title;
3073                 }
3074
3075                 if (title != m_preferredStylesheetSet)
3076                     sheet = 0;
3077             }
3078         }
3079
3080         if (sheet)
3081             sheets.append(sheet);
3082     }
3083
3084     m_styleSheets->swap(sheets);
3085
3086     m_styleSelector.clear();
3087     m_didCalculateStyleSelector = true;
3088 }
3089
3090 void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
3091 {
3092     m_hoverNode = newHoverNode;
3093 }
3094
3095 void Document::setActiveNode(PassRefPtr<Node> newActiveNode)
3096 {
3097     m_activeNode = newActiveNode;
3098 }
3099
3100 void Document::focusedNodeRemoved()
3101 {
3102     setFocusedNode(0);
3103 }
3104
3105 void Document::removeFocusedNodeOfSubtree(Node* node, bool amongChildrenOnly)
3106 {
3107     if (!m_focusedNode || this->inPageCache()) // If the document is in the page cache, then we don't need to clear out the focused node.
3108         return;
3109         
3110     bool nodeInSubtree = false;
3111     if (amongChildrenOnly)
3112         nodeInSubtree = m_focusedNode->isDescendantOf(node);
3113     else
3114         nodeInSubtree = (m_focusedNode == node) || m_focusedNode->isDescendantOf(node);
3115     
3116     if (nodeInSubtree)
3117         document()->focusedNodeRemoved();
3118 }
3119
3120 void Document::hoveredNodeDetached(Node* node)
3121 {
3122     if (!m_hoverNode || (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != m_hoverNode->parentNode())))
3123         return;
3124
3125     m_hoverNode = node->parentNode();
3126     while (m_hoverNode && !m_hoverNode->renderer())
3127         m_hoverNode = m_hoverNode->parentNode();
3128     if (frame())
3129         frame()->eventHandler()->scheduleHoverStateUpdate();
3130 }
3131
3132 void Document::activeChainNodeDetached(Node* node)
3133 {
3134     if (!m_activeNode || (node != m_activeNode && (!m_activeNode->isTextNode() || node != m_activeNode->parentNode())))
3135         return;
3136
3137     m_activeNode = node->parentNode();
3138     while (m_activeNode && !m_activeNode->renderer())
3139         m_activeNode = m_activeNode->parentNode();
3140 }
3141
3142 #if ENABLE(DASHBOARD_SUPPORT)
3143 const Vector<DashboardRegionValue>& Document::dashboardRegions() const
3144 {
3145     return m_dashboardRegions;
3146 }
3147
3148 void Document::setDashboardRegions(const Vector<DashboardRegionValue>& regions)
3149 {
3150     m_dashboardRegions = regions;
3151     setDashboardRegionsDirty(false);
3152 }
3153 #endif
3154
3155 bool Document::setFocusedNode(PassRefPtr<Node> newFocusedNode)
3156 {    
3157     // Make sure newFocusedNode is actually in this document
3158     if (newFocusedNode && (newFocusedNode->document() != this))
3159         return true;
3160
3161     if (m_focusedNode == newFocusedNode)
3162         return true;
3163
3164     if (m_inPageCache)
3165         return false;
3166
3167     bool focusChangeBlocked = false;
3168     RefPtr<Node> oldFocusedNode = m_focusedNode;
3169     m_focusedNode = 0;
3170
3171     // Remove focus from the existing focus node (if any)
3172     if (oldFocusedNode && !oldFocusedNode->inDetach()) { 
3173         if (oldFocusedNode->active())
3174             oldFocusedNode->setActive(false);
3175
3176         oldFocusedNode->setFocus(false);
3177
3178         // Dispatch a change event for text fields or textareas that have been edited
3179         RenderObject* r = oldFocusedNode->renderer();
3180         if (r && r->isTextControl() && toRenderTextControl(r)->wasChangedSinceLastChangeEvent()) {
3181             static_cast<Element*>(oldFocusedNode.get())->dispatchFormControlChangeEvent();
3182             r = oldFocusedNode->renderer();
3183             if (r && r->isTextControl())
3184                 toRenderTextControl(r)->setChangedSinceLastChangeEvent(false);
3185         }
3186
3187         // Dispatch the blur event and let the node do any other blur related activities (important for text fields)
3188         oldFocusedNode->dispatchBlurEvent();
3189
3190         if (m_focusedNode) {
3191             // handler shifted focus
3192             focusChangeBlocked = true;
3193             newFocusedNode = 0;
3194         }
3195         
3196         oldFocusedNode->dispatchUIEvent(eventNames().focusoutEvent, 0, 0); // DOM level 3 name for the bubbling blur event.
3197         // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
3198         // on it, probably when <rdar://problem/8503958> is resolved.
3199         oldFocusedNode->dispatchUIEvent(eventNames().DOMFocusOutEvent, 0, 0); // DOM level 2 name for compatibility.
3200
3201         if (m_focusedNode) {
3202             // handler shifted focus
3203             focusChangeBlocked = true;
3204             newFocusedNode = 0;
3205         }
3206         if (oldFocusedNode == this && oldFocusedNode->hasOneRef())
3207             return true;
3208             
3209         if (oldFocusedNode == oldFocusedNode->rootEditableElement())
3210             frame()->editor()->didEndEditing();
3211
3212         if (view()) {
3213             Widget* oldWidget = widgetForNode(oldFocusedNode.get());
3214             if (oldWidget)
3215                 oldWidget->setFocus(false);
3216             else
3217                 view()->setFocus(false);
3218         }
3219     }
3220
3221     if (newFocusedNode) {
3222         if (newFocusedNode == newFocusedNode->rootEditableElement() && !acceptsEditingFocus(newFocusedNode.get())) {
3223             // delegate blocks focus change
3224             focusChangeBlocked = true;
3225             goto SetFocusedNodeDone;
3226         }
3227         // Set focus on the new node
3228         m_focusedNode = newFocusedNode.get();
3229
3230         // Dispatch the focus event and let the node do any other focus related activities (important for text fields)
3231         m_focusedNode->dispatchFocusEvent();
3232
3233         if (m_focusedNode != newFocusedNode) {
3234             // handler shifted focus
3235             focusChangeBlocked = true;
3236             goto SetFocusedNodeDone;
3237         }
3238
3239         m_focusedNode->dispatchUIEvent(eventNames().focusinEvent, 0, 0); // DOM level 3 bubbling focus event.
3240         // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
3241         // on it, probably when <rdar://problem/8503958> is resolved.
3242         m_focusedNode->dispatchUIEvent(eventNames().DOMFocusInEvent, 0, 0); // DOM level 2 for compatibility.
3243
3244         if (m_focusedNode != newFocusedNode) { 
3245             // handler shifted focus
3246             focusChangeBlocked = true;
3247             goto SetFocusedNodeDone;
3248         }
3249         m_focusedNode->setFocus(true);
3250
3251         if (m_focusedNode == m_focusedNode->rootEditableElement())
3252             frame()->editor()->didBeginEditing();
3253
3254         // eww, I suck. set the qt focus correctly
3255         // ### find a better place in the code for this
3256         if (view()) {
3257             Widget* focusWidget = widgetForNode(m_focusedNode.get());
3258             if (focusWidget) {
3259                 // Make sure a widget has the right size before giving it focus.
3260                 // Otherwise, we are testing edge cases of the Widget code.
3261                 // Specifically, in WebCore this does not work well for text fields.
3262                 updateLayout();
3263                 // Re-get the widget in case updating the layout changed things.
3264                 focusWidget = widgetForNode(m_focusedNode.get());
3265             }
3266             if (focusWidget)
3267                 focusWidget->setFocus(true);
3268             else
3269                 view()->setFocus(true);
3270         }
3271     }
3272
3273 #if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
3274     if (!focusChangeBlocked && m_focusedNode && AXObjectCache::accessibilityEnabled()) {
3275         RenderObject* oldFocusedRenderer = 0;
3276         RenderObject* newFocusedRenderer = 0;
3277
3278         if (oldFocusedNode)
3279             oldFocusedRenderer = oldFocusedNode->renderer();
3280         if (newFocusedNode)
3281             newFocusedRenderer = newFocusedNode->renderer();
3282
3283         axObjectCache()->handleFocusedUIElementChanged(oldFocusedRenderer, newFocusedRenderer);
3284     }
3285 #endif
3286     if (!focusChangeBlocked)
3287         page()->chrome()->focusedNodeChanged(m_focusedNode.get());
3288
3289 SetFocusedNodeDone:
3290     updateStyleIfNeeded();
3291     return !focusChangeBlocked;
3292 }
3293     
3294 void Document::getFocusableNodes(Vector<RefPtr<Node> >& nodes)
3295 {
3296     updateLayout();
3297
3298     for (Node* node = firstChild(); node; node = node->traverseNextNode()) {
3299         if (node->isFocusable())
3300             nodes.append(node);
3301     }
3302 }
3303   
3304 void Document::setCSSTarget(Element* n)
3305 {
3306     if (m_cssTarget)
3307         m_cssTarget->setNeedsStyleRecalc();
3308     m_cssTarget = n;
3309     if (n)
3310         n->setNeedsStyleRecalc();
3311 }
3312
3313 void Document::attachNodeIterator(NodeIterator* ni)
3314 {
3315     m_nodeIterators.add(ni);
3316 }
3317
3318 void Document::detachNodeIterator(NodeIterator* ni)
3319 {
3320     // The node iterator can be detached without having been attached if its root node didn't have a document
3321     // when the iterator was created, but has it now.
3322     m_nodeIterators.remove(ni);
3323 }
3324
3325 void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
3326 {
3327     HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
3328     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
3329     for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
3330         if ((*it)->root() == node) {
3331             detachNodeIterator(*it);
3332             newDocument->attachNodeIterator(*it);
3333         }
3334     }
3335 }
3336
3337 void Document::nodeChildrenChanged(ContainerNode* container)
3338 {
3339     if (!disableRangeMutation(page())) {
3340         HashSet<Range*>::const_iterator end = m_ranges.end();
3341         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3342             (*it)->nodeChildrenChanged(container);
3343     }
3344 }
3345
3346 void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
3347 {
3348     if (!disableRangeMutation(page())) {
3349         HashSet<Range*>::const_iterator end = m_ranges.end();
3350         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3351             (*it)->nodeChildrenWillBeRemoved(container);
3352     }
3353
3354     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
3355     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
3356         for (Node* n = container->firstChild(); n; n = n->nextSibling())
3357             (*it)->nodeWillBeRemoved(n);
3358     }
3359
3360     if (Frame* frame = this->frame()) {
3361         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
3362             frame->selection()->nodeWillBeRemoved(n);
3363             frame->page()->dragCaretController()->nodeWillBeRemoved(n);
3364         }
3365     }
3366 }
3367
3368 void Document::nodeWillBeRemoved(Node* n)
3369 {
3370     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
3371     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
3372         (*it)->nodeWillBeRemoved(n);
3373
3374     if (!disableRangeMutation(page())) {
3375         HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
3376         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
3377             (*it)->nodeWillBeRemoved(n);
3378     }
3379
3380     if (Frame* frame = this->frame()) {
3381         frame->selection()->nodeWillBeRemoved(n);
3382         frame->page()->dragCaretController()->nodeWillBeRemoved(n);
3383     }
3384     
3385 #if ENABLE(FULLSCREEN_API)
3386     // If the current full screen element or any of its ancestors is removed, set the current
3387     // full screen element to the document root, and fire a fullscreenchange event to inform 
3388     // clients of the DOM.
3389     ASSERT(n);
3390     if (n->contains(m_fullScreenElement.get())) {
3391         ASSERT(n != documentElement());
3392         
3393         if (m_fullScreenRenderer)
3394             m_fullScreenRenderer->remove();
3395
3396         setFullScreenRenderer(0);
3397         m_fullScreenElement = documentElement();
3398         recalcStyle(Force);
3399         m_fullScreenChangeDelayTimer.startOneShot(0);
3400     }
3401 #endif
3402 }
3403
3404 void Document::textInserted(Node* text, unsigned offset, unsigned length)
3405 {
3406     if (!disableRangeMutation(page())) {
3407         HashSet<Range*>::const_iterator end = m_ranges.end();
3408         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3409             (*it)->textInserted(text, offset, length);
3410     }
3411
3412     // Update the markers for spelling and grammar checking.
3413     m_markers->shiftMarkers(text, offset, length);
3414 }
3415
3416 void Document::textRemoved(Node* text, unsigned offset, unsigned length)
3417 {
3418     if (!disableRangeMutation(page())) {
3419         HashSet<Range*>::const_iterator end = m_ranges.end();
3420         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3421             (*it)->textRemoved(text, offset, length);
3422     }
3423
3424     // Update the markers for spelling and grammar checking.
3425     m_markers->removeMarkers(text, offset, length);
3426     m_markers->shiftMarkers(text, offset + length, 0 - length);
3427 }
3428
3429 void Document::textNodesMerged(Text* oldNode, unsigned offset)
3430 {
3431     if (!disableRangeMutation(page())) {
3432         NodeWithIndex oldNodeWithIndex(oldNode);
3433         HashSet<Range*>::const_iterator end = m_ranges.end();
3434         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3435             (*it)->textNodesMerged(oldNodeWithIndex, offset);
3436     }
3437
3438     // FIXME: This should update markers for spelling and grammar checking.
3439 }
3440
3441 void Document::textNodeSplit(Text* oldNode)
3442 {
3443     if (!disableRangeMutation(page())) {
3444         HashSet<Range*>::const_iterator end = m_ranges.end();
3445         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
3446             (*it)->textNodeSplit(oldNode);
3447     }
3448
3449     // FIXME: This should update markers for spelling and grammar checking.
3450 }
3451
3452 // FIXME: eventually, this should return a DOMWindow stored in the document.
3453 DOMWindow* Document::domWindow() const
3454 {
3455     if (!frame())
3456         return 0;
3457
3458     // The m_frame pointer is not (not always?) zeroed out when the document is put into b/f cache, so the frame can hold an unrelated document/window pair.
3459     // FIXME: We should always zero out the frame pointer on navigation to avoid accidentally accessing the new frame content.
3460     if (m_frame->document() != this)
3461         return 0;
3462
3463     return frame()->domWindow();
3464 }
3465
3466 void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
3467 {
3468     DOMWindow* domWindow = this->domWindow();
3469     if (!domWindow)
3470         return;
3471     domWindow->setAttributeEventListener(eventType, listener);
3472 }
3473
3474 EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
3475 {
3476     DOMWindow* domWindow = this->domWindow();
3477     if (!domWindow)
3478         return 0;
3479     return domWindow->getAttributeEventListener(eventType);
3480 }
3481
3482 void Document::dispatchWindowEvent(PassRefPtr<Event> event,  PassRefPtr<EventTarget> target)
3483 {
3484     ASSERT(!eventDispatchForbidden());
3485     DOMWindow* domWindow = this->domWindow();
3486     if (!domWindow)
3487         return;
3488     domWindow->dispatchEvent(event, target);
3489 }
3490
3491 void Document::dispatchWindowLoadEvent()
3492 {
3493     ASSERT(!eventDispatchForbidden());
3494     DOMWindow* domWindow = this->domWindow();
3495     if (!domWindow)
3496         return;
3497     domWindow->dispatchLoadEvent();
3498 }
3499
3500 void Document::enqueueWindowEvent(PassRefPtr<Event> event)
3501 {
3502     event->setTarget(domWindow());
3503     m_eventQueue->enqueueEvent(event);
3504 }
3505
3506 PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode& ec)
3507 {
3508     RefPtr<Event> event;
3509     if (eventType == "Event" || eventType == "Events" || eventType == "HTMLEvents")
3510         event = Event::create();
3511     else if (eventType == "CustomEvent")
3512         event = CustomEvent::create();
3513     else if (eventType == "KeyboardEvent" || eventType == "KeyboardEvents")
3514         event = KeyboardEvent::create();
3515     else if (eventType == "MessageEvent")
3516         event = MessageEvent::create();
3517     else if (eventType == "MouseEvent" || eventType == "MouseEvents")
3518         event = MouseEvent::create();
3519     else if (eventType == "MutationEvent" || eventType == "MutationEvents")
3520         event = MutationEvent::create();
3521     else if (eventType == "OverflowEvent")
3522         event = OverflowEvent::create();
3523     else if (eventType == "PageTransitionEvent")
3524         event = PageTransitionEvent::create();
3525     else if (eventType == "ProgressEvent")
3526         event = ProgressEvent::create();
3527 #if ENABLE(DOM_STORAGE)
3528     else if (eventType == "StorageEvent")
3529         event = StorageEvent::create();
3530 #endif
3531     else if (eventType == "TextEvent")
3532         event = TextEvent::create();
3533     else if (eventType == "UIEvent" || eventType == "UIEvents")
3534         event = UIEvent::create();
3535     else if (eventType == "WebKitAnimationEvent")
3536         event = WebKitAnimationEvent::create();
3537     else if (eventType == "WebKitTransitionEvent")
3538         event = WebKitTransitionEvent::create();
3539     else if (eventType == "WheelEvent")
3540         event = WheelEvent::create();
3541 #if ENABLE(SVG)
3542     else if (eventType == "SVGEvents")
3543         event = Event::create();
3544     else if (eventType == "SVGZoomEvents")
3545         event = SVGZoomEvent::create();
3546 #endif
3547 #if ENABLE(TOUCH_EVENTS)
3548 #if USE(V8)
3549     else if (eventType == "TouchEvent" && RuntimeEnabledFeatures::touchEnabled())
3550 #else
3551     else if (eventType == "TouchEvent")
3552 #endif
3553         event = TouchEvent::create();
3554 #endif
3555 #if ENABLE(DEVICE_ORIENTATION)
3556     else if (eventType == "DeviceMotionEvent")
3557         event = DeviceMotionEvent::create();
3558     else if (eventType == "DeviceOrientationEvent")
3559         event = DeviceOrientationEvent::create();
3560 #endif
3561 #if ENABLE(ORIENTATION_EVENTS)
3562     else if (eventType == "OrientationEvent")
3563         event = Event::create();
3564 #endif
3565     if (event)
3566         return event.release();
3567
3568     ec = NOT_SUPPORTED_ERR;
3569     return 0;
3570 }
3571
3572 void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
3573 {
3574     if (eventType == eventNames().DOMSubtreeModifiedEvent)
3575         addListenerType(DOMSUBTREEMODIFIED_LISTENER);
3576     else if (eventType == eventNames().DOMNodeInsertedEvent)
3577         addListenerType(DOMNODEINSERTED_LISTENER);
3578     else if (eventType == eventNames().DOMNodeRemovedEvent)
3579         addListenerType(DOMNODEREMOVED_LISTENER);
3580     else if (eventType == eventNames().DOMNodeRemovedFromDocumentEvent)
3581         addListenerType(DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
3582     else if (eventType == eventNames().DOMNodeInsertedIntoDocumentEvent)
3583         addListenerType(DOMNODEINSERTEDINTODOCUMENT_LISTENER);
3584     else if (eventType == eventNames().DOMAttrModifiedEvent)
3585         addListenerType(DOMATTRMODIFIED_LISTENER);
3586     else if (eventType == eventNames().DOMCharacterDataModifiedEvent)
3587         addListenerType(DOMCHARACTERDATAMODIFIED_LISTENER);
3588     else if (eventType == eventNames().overflowchangedEvent)
3589         addListenerType(OVERFLOWCHANGED_LISTENER);
3590     else if (eventType == eventNames().webkitAnimationStartEvent)
3591         addListenerType(ANIMATIONSTART_LISTENER);
3592     else if (eventType == eventNames().webkitAnimationEndEvent)
3593         addListenerType(ANIMATIONEND_LISTENER);
3594     else if (eventType == eventNames().webkitAnimationIterationEvent)
3595         addListenerType(ANIMATIONITERATION_LISTENER);
3596     else if (eventType == eventNames().webkitTransitionEndEvent)
3597         addListenerType(TRANSITIONEND_LISTENER);
3598     else if (eventType == eventNames().beforeloadEvent)
3599         addListenerType(BEFORELOAD_LISTENER);
3600     else if (eventType == eventNames().beforeprocessEvent)
3601         addListenerType(BEFOREPROCESS_LISTENER);
3602 #if ENABLE(TOUCH_EVENTS)
3603     else if (eventType == eventNames().touchstartEvent
3604              || eventType == eventNames().touchmoveEvent
3605              || eventType == eventNames().touchendEvent
3606              || eventType == eventNames().touchcancelEvent) {
3607         addListenerType(TOUCH_LISTENER);
3608         if (Page* page = this->page())
3609             page->chrome()->client()->needTouchEvents(true);
3610     }
3611 #endif
3612 }
3613
3614 CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)
3615 {
3616     return 0;
3617 }
3618
3619 HTMLFrameOwnerElement* Document::ownerElement() const
3620 {
3621     if (!frame())
3622         return 0;</