root/trunk/WebCore/dom/Document.cpp

Revision 50523, 145.8 KB (checked in by eric@webkit.org, 3 days ago)

2009-11-04 Eric Z. Ayers < zundel@google.com>

Reviewed by Pavel Feldman.

Followon to bug 31080, which protects Timeline
instrumentation in the case where InspectorTimelineAgent
is enabled or disabled during an event dispatch.

 https://bugs.webkit.org/show_bug.cgi?id=31121

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