Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      4  *           (C) 2001 Dirk Mueller (mueller (at) kde.org)
      5  *           (C) 2006 Alexey Proskuryakov (ap (at) webkit.org)
      6  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 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, 2011, 2012 Google Inc. All rights reserved.
      9  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
     10  * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
     11  *
     12  * This library is free software; you can redistribute it and/or
     13  * modify it under the terms of the GNU Library General Public
     14  * License as published by the Free Software Foundation; either
     15  * version 2 of the License, or (at your option) any later version.
     16  *
     17  * This library is distributed in the hope that it will be useful,
     18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     20  * Library General Public License for more details.
     21  *
     22  * You should have received a copy of the GNU Library General Public License
     23  * along with this library; see the file COPYING.LIB.  If not, write to
     24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     25  * Boston, MA 02110-1301, USA.
     26  */
     27 
     28 #include "config.h"
     29 #include "core/dom/Document.h"
     30 
     31 #include "HTMLElementFactory.h"
     32 #include "HTMLNames.h"
     33 #include "RuntimeEnabledFeatures.h"
     34 #include "SVGElementFactory.h"
     35 #include "SVGNames.h"
     36 #include "XMLNSNames.h"
     37 #include "XMLNames.h"
     38 #include "bindings/v8/CustomElementConstructorBuilder.h"
     39 #include "bindings/v8/Dictionary.h"
     40 #include "bindings/v8/ExceptionState.h"
     41 #include "bindings/v8/ExceptionStatePlaceholder.h"
     42 #include "bindings/v8/ScriptController.h"
     43 #include "core/accessibility/AXObjectCache.h"
     44 #include "core/animation/DocumentTimeline.h"
     45 #include "core/css/CSSStyleDeclaration.h"
     46 #include "core/css/CSSStyleSheet.h"
     47 #include "core/css/FontLoader.h"
     48 #include "core/css/MediaQueryMatcher.h"
     49 #include "core/css/StylePropertySet.h"
     50 #include "core/css/StyleSheetContents.h"
     51 #include "core/css/StyleSheetList.h"
     52 #include "core/css/resolver/StyleResolver.h"
     53 #include "core/dom/Attr.h"
     54 #include "core/dom/CDATASection.h"
     55 #include "core/dom/Comment.h"
     56 #include "core/dom/ContextFeatures.h"
     57 #include "core/dom/CustomElementRegistrationContext.h"
     58 #include "core/dom/DOMImplementation.h"
     59 #include "core/dom/DOMNamedFlowCollection.h"
     60 #include "core/dom/DocumentEventQueue.h"
     61 #include "core/dom/DocumentFragment.h"
     62 #include "core/dom/DocumentLifecycleObserver.h"
     63 #include "core/dom/DocumentMarkerController.h"
     64 #include "core/dom/DocumentSharedObjectPool.h"
     65 #include "core/dom/DocumentStyleSheetCollection.h"
     66 #include "core/dom/DocumentType.h"
     67 #include "core/dom/Element.h"
     68 #include "core/dom/Event.h"
     69 #include "core/dom/EventFactory.h"
     70 #include "core/dom/EventListener.h"
     71 #include "core/dom/EventNames.h"
     72 #include "core/dom/ExceptionCode.h"
     73 #include "core/dom/HashChangeEvent.h"
     74 #include "core/dom/NamedFlowCollection.h"
     75 #include "core/dom/NodeFilter.h"
     76 #include "core/dom/NodeIterator.h"
     77 #include "core/dom/NodeRareData.h"
     78 #include "core/dom/NodeRenderingTraversal.h"
     79 #include "core/dom/NodeTraversal.h"
     80 #include "core/dom/NodeWithIndex.h"
     81 #include "core/dom/PageTransitionEvent.h"
     82 #include "core/dom/PopStateEvent.h"
     83 #include "core/dom/ProcessingInstruction.h"
     84 #include "core/dom/QualifiedName.h"
     85 #include "core/dom/RequestAnimationFrameCallback.h"
     86 #include "core/dom/ScopedEventQueue.h"
     87 #include "core/dom/ScriptRunner.h"
     88 #include "core/dom/ScriptedAnimationController.h"
     89 #include "core/dom/SelectorQuery.h"
     90 #include "core/dom/TouchList.h"
     91 #include "core/dom/TransformSource.h"
     92 #include "core/dom/TreeWalker.h"
     93 #include "core/dom/UserActionElementSet.h"
     94 #include "core/dom/VisitedLinkState.h"
     95 #include "core/dom/shadow/ElementShadow.h"
     96 #include "core/dom/shadow/ShadowRoot.h"
     97 #include "core/editing/Editor.h"
     98 #include "core/editing/FrameSelection.h"
     99 #include "core/html/FormController.h"
    100 #include "core/html/HTMLAllCollection.h"
    101 #include "core/html/HTMLAnchorElement.h"
    102 #include "core/html/HTMLCanvasElement.h"
    103 #include "core/html/HTMLCollection.h"
    104 #include "core/html/HTMLDocument.h"
    105 #include "core/html/HTMLFrameOwnerElement.h"
    106 #include "core/html/HTMLHeadElement.h"
    107 #include "core/html/HTMLHtmlElement.h"
    108 #include "core/html/HTMLIFrameElement.h"
    109 #include "core/html/HTMLImport.h"
    110 #include "core/html/HTMLLinkElement.h"
    111 #include "core/html/HTMLNameCollection.h"
    112 #include "core/html/HTMLScriptElement.h"
    113 #include "core/html/HTMLStyleElement.h"
    114 #include "core/html/HTMLTitleElement.h"
    115 #include "core/html/PluginDocument.h"
    116 #include "core/html/parser/HTMLDocumentParser.h"
    117 #include "core/html/parser/HTMLParserIdioms.h"
    118 #include "core/html/parser/NestingLevelIncrementer.h"
    119 #include "core/inspector/InspectorCounters.h"
    120 #include "core/inspector/InspectorInstrumentation.h"
    121 #include "core/inspector/ScriptCallStack.h"
    122 #include "core/loader/CookieJar.h"
    123 #include "core/loader/DocumentLoader.h"
    124 #include "core/loader/FrameLoader.h"
    125 #include "core/loader/FrameLoaderClient.h"
    126 #include "core/loader/ImageLoader.h"
    127 #include "core/loader/Prerenderer.h"
    128 #include "core/loader/TextResourceDecoder.h"
    129 #include "core/loader/appcache/ApplicationCacheHost.h"
    130 #include "core/loader/cache/ResourceFetcher.h"
    131 #include "core/page/Chrome.h"
    132 #include "core/page/ChromeClient.h"
    133 #include "core/page/ContentSecurityPolicy.h"
    134 #include "core/page/DOMSecurityPolicy.h"
    135 #include "core/page/DOMWindow.h"
    136 #include "core/page/EventHandler.h"
    137 #include "core/page/Frame.h"
    138 #include "core/page/FrameTree.h"
    139 #include "core/page/FrameView.h"
    140 #include "core/page/History.h"
    141 #include "core/page/MouseEventWithHitTestResults.h"
    142 #include "core/page/Page.h"
    143 #include "core/page/PageConsole.h"
    144 #include "core/page/PointerLockController.h"
    145 #include "core/page/Settings.h"
    146 #include "core/page/ValidationMessageClient.h"
    147 #include "core/page/animation/AnimationController.h"
    148 #include "core/page/scrolling/ScrollingCoordinator.h"
    149 #include "core/platform/DateComponents.h"
    150 #include "core/platform/HistogramSupport.h"
    151 #include "core/platform/Language.h"
    152 #include "core/platform/Timer.h"
    153 #include "core/platform/chromium/TraceEvent.h"
    154 #include "core/platform/network/HTTPParsers.h"
    155 #include "core/platform/text/PlatformLocale.h"
    156 #include "core/platform/text/SegmentedString.h"
    157 #include "core/rendering/HitTestRequest.h"
    158 #include "core/rendering/HitTestResult.h"
    159 #include "core/rendering/RenderView.h"
    160 #include "core/rendering/RenderWidget.h"
    161 #include "core/rendering/TextAutosizer.h"
    162 #include "core/svg/SVGDocumentExtensions.h"
    163 #include "core/svg/SVGStyleElement.h"
    164 #include "core/workers/SharedWorkerRepository.h"
    165 #include "core/xml/XSLTProcessor.h"
    166 #include "core/xml/parser/XMLDocumentParser.h"
    167 #include "weborigin/SchemeRegistry.h"
    168 #include "weborigin/SecurityOrigin.h"
    169 #include "wtf/CurrentTime.h"
    170 #include "wtf/HashFunctions.h"
    171 #include "wtf/MainThread.h"
    172 #include "wtf/PassRefPtr.h"
    173 #include "wtf/StdLibExtras.h"
    174 #include "wtf/UnusedParam.h"
    175 #include "wtf/text/StringBuffer.h"
    176 
    177 using namespace std;
    178 using namespace WTF;
    179 using namespace Unicode;
    180 
    181 namespace WebCore {
    182 
    183 using namespace HTMLNames;
    184 
    185 static const double cDefaultIncrementalRenderingSuppressionTimeoutInSeconds = 5;
    186 
    187 static const unsigned cMaxWriteRecursionDepth = 21;
    188 
    189 // This amount of time must have elapsed before we will even consider scheduling a layout without a delay.
    190 // FIXME: For faster machines this value can really be lowered to 200.  250 is adequate, but a little high
    191 // for dual G5s. :)
    192 static const int cLayoutScheduleThreshold = 250;
    193 
    194 // DOM Level 2 says (letters added):
    195 //
    196 // a) Name start characters must have one of the categories Ll, Lu, Lo, Lt, Nl.
    197 // b) Name characters other than Name-start characters must have one of the categories Mc, Me, Mn, Lm, or Nd.
    198 // c) Characters in the compatibility area (i.e. with character code greater than #xF900 and less than #xFFFE) are not allowed in XML names.
    199 // 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.
    200 // 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.
    201 // f) Characters #x20DD-#x20E0 are excluded (in accordance with Unicode, section 5.14).
    202 // g) Character #x00B7 is classified as an extender, because the property list so identifies it.
    203 // h) Character #x0387 is added as a name character, because #x00B7 is its canonical equivalent.
    204 // i) Characters ':' and '_' are allowed as name-start characters.
    205 // j) Characters '-' and '.' are allowed as name characters.
    206 //
    207 // It also contains complete tables. If we decide it's better, we could include those instead of the following code.
    208 
    209 static inline bool isValidNameStart(UChar32 c)
    210 {
    211     // rule (e) above
    212     if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
    213         return true;
    214 
    215     // rule (i) above
    216     if (c == ':' || c == '_')
    217         return true;
    218 
    219     // rules (a) and (f) above
    220     const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
    221     if (!(Unicode::category(c) & nameStartMask))
    222         return false;
    223 
    224     // rule (c) above
    225     if (c >= 0xF900 && c < 0xFFFE)
    226         return false;
    227 
    228     // rule (d) above
    229     DecompositionType decompType = decompositionType(c);
    230     if (decompType == DecompositionFont || decompType == DecompositionCompat)
    231         return false;
    232 
    233     return true;
    234 }
    235 
    236 static inline bool isValidNamePart(UChar32 c)
    237 {
    238     // rules (a), (e), and (i) above
    239     if (isValidNameStart(c))
    240         return true;
    241 
    242     // rules (g) and (h) above
    243     if (c == 0x00B7 || c == 0x0387)
    244         return true;
    245 
    246     // rule (j) above
    247     if (c == '-' || c == '.')
    248         return true;
    249 
    250     // rules (b) and (f) above
    251     const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
    252     if (!(Unicode::category(c) & otherNamePartMask))
    253         return false;
    254 
    255     // rule (c) above
    256     if (c >= 0xF900 && c < 0xFFFE)
    257         return false;
    258 
    259     // rule (d) above
    260     DecompositionType decompType = decompositionType(c);
    261     if (decompType == DecompositionFont || decompType == DecompositionCompat)
    262         return false;
    263 
    264     return true;
    265 }
    266 
    267 static bool shouldInheritSecurityOriginFromOwner(const KURL& url)
    268 {
    269     // http://www.whatwg.org/specs/web-apps/current-work/#origin-0
    270     //
    271     // If a Document has the address "about:blank"
    272     //     The origin of the Document is the origin it was assigned when its browsing context was created.
    273     //
    274     // Note: We generalize this to all "blank" URLs and invalid URLs because we
    275     // treat all of these URLs as about:blank.
    276     //
    277     return url.isEmpty() || url.isBlankURL();
    278 }
    279 
    280 static Widget* widgetForElement(Element* focusedElement)
    281 {
    282     if (!focusedElement)
    283         return 0;
    284     RenderObject* renderer = focusedElement->renderer();
    285     if (!renderer || !renderer->isWidget())
    286         return 0;
    287     return toRenderWidget(renderer)->widget();
    288 }
    289 
    290 static bool acceptsEditingFocus(Element* element)
    291 {
    292     ASSERT(element);
    293     ASSERT(element->rendererIsEditable());
    294 
    295     Element* root = element->rootEditableElement();
    296     Frame* frame = element->document()->frame();
    297     if (!frame || !root)
    298         return false;
    299 
    300     return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
    301 }
    302 
    303 static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
    304 {
    305     // targetFrame can be 0 when we're trying to navigate a top-level frame
    306     // that has a 0 opener.
    307     if (!targetFrame)
    308         return false;
    309 
    310     const bool isLocalActiveOrigin = activeSecurityOrigin->isLocal();
    311     for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) {
    312         Document* ancestorDocument = ancestorFrame->document();
    313         // FIXME: Should be an ASSERT? Frames should alway have documents.
    314         if (!ancestorDocument)
    315             return true;
    316 
    317         const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin();
    318         if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin))
    319             return true;
    320 
    321         // Allow file URL descendant navigation even when allowFileAccessFromFileURLs is false.
    322         // FIXME: It's a bit strange to special-case local origins here. Should we be doing
    323         // something more general instead?
    324         if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal())
    325             return true;
    326     }
    327 
    328     return false;
    329 }
    330 
    331 static void printNavigationErrorMessage(Frame* frame, const KURL& activeURL, const char* reason)
    332 {
    333     String message = "Unsafe JavaScript attempt to initiate navigation for frame with URL '" + frame->document()->url().string() + "' from frame with URL '" + activeURL.string() + "'. " + reason + "\n";
    334 
    335     // FIXME: should we print to the console of the document performing the navigation instead?
    336     frame->domWindow()->printErrorMessage(message);
    337 }
    338 
    339 uint64_t Document::s_globalTreeVersion = 0;
    340 
    341 // This class should be passed only to Document::postTask.
    342 class CheckFocusedElementTask FINAL : public ScriptExecutionContext::Task {
    343 public:
    344     static PassOwnPtr<CheckFocusedElementTask> create()
    345     {
    346         return adoptPtr(new CheckFocusedElementTask());
    347     }
    348     virtual ~CheckFocusedElementTask() { }
    349 
    350 private:
    351     CheckFocusedElementTask() { }
    352     virtual void performTask(ScriptExecutionContext* context) OVERRIDE
    353     {
    354         ASSERT(context->isDocument());
    355         Document* document = toDocument(context);
    356         document->didRunCheckFocusedElementTask();
    357         Element* element = document->focusedElement();
    358         if (!element)
    359             return;
    360         if (document->childNeedsStyleRecalc()) {
    361             document->setNeedsFocusedElementCheck();
    362             return;
    363         }
    364         if (element->renderer() && element->renderer()->needsLayout())
    365             return;
    366         if (!element->isFocusable())
    367             document->setFocusedElement(0);
    368     }
    369 };
    370 
    371 Document::Document(const DocumentInit& initializer, DocumentClassFlags documentClasses)
    372     : ContainerNode(0, CreateDocument)
    373     , TreeScope(this)
    374     , m_styleResolverThrowawayTimer(this, &Document::styleResolverThrowawayTimerFired)
    375     , m_lastStyleResolverAccessTime(0)
    376     , m_didCalculateStyleResolver(false)
    377     , m_ignorePendingStylesheets(false)
    378     , m_needsNotifyRemoveAllPendingStylesheet(false)
    379     , m_hasNodesWithPlaceholderStyle(false)
    380     , m_pendingSheetLayout(NoLayoutWithPendingSheets)
    381     , m_frame(initializer.frame())
    382     , m_domWindow(0)
    383     , m_import(initializer.import())
    384     , m_activeParserCount(0)
    385     , m_contextFeatures(ContextFeatures::defaultSwitch())
    386     , m_wellFormed(false)
    387     , m_printing(false)
    388     , m_paginatedForScreen(false)
    389     , m_ignoreAutofocus(false)
    390     , m_compatibilityMode(NoQuirksMode)
    391     , m_compatibilityModeLocked(false)
    392     , m_didPostCheckFocusedElementTask(false)
    393     , m_domTreeVersion(++s_globalTreeVersion)
    394     , m_listenerTypes(0)
    395     , m_mutationObserverTypes(0)
    396     , m_styleSheetCollection(DocumentStyleSheetCollection::create(this))
    397     , m_visitedLinkState(VisitedLinkState::create(this))
    398     , m_visuallyOrdered(false)
    399     , m_readyState(Complete)
    400     , m_bParsing(false)
    401     , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
    402     , m_inStyleRecalc(false)
    403     , m_closeAfterStyleRecalc(false)
    404     , m_gotoAnchorNeededAfterStylesheetsLoad(false)
    405     , m_containsValidityStyleRules(false)
    406     , m_updateFocusAppearanceRestoresSelection(false)
    407     , m_ignoreDestructiveWriteCount(0)
    408     , m_titleSetExplicitly(false)
    409     , m_markers(adoptPtr(new DocumentMarkerController))
    410     , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
    411     , m_cssTarget(0)
    412     , m_loadEventProgress(LoadEventNotRun)
    413     , m_startTime(currentTime())
    414     , m_overMinimumLayoutThreshold(false)
    415     , m_scriptRunner(ScriptRunner::create(this))
    416     , m_xmlVersion("1.0")
    417     , m_xmlStandalone(StandaloneUnspecified)
    418     , m_hasXMLDeclaration(0)
    419     , m_designMode(inherit)
    420     , m_hasAnnotatedRegions(false)
    421     , m_annotatedRegionsDirty(false)
    422     , m_useSecureKeyboardEntryWhenActive(false)
    423     , m_documentClasses(documentClasses)
    424     , m_isViewSource(false)
    425     , m_sawElementsInKnownNamespaces(false)
    426     , m_isSrcdocDocument(false)
    427     , m_renderer(0)
    428     , m_eventQueue(DocumentEventQueue::create(this))
    429     , m_weakFactory(this)
    430     , m_idAttributeName(idAttr)
    431     , m_hasFullscreenElementStack(false)
    432     , m_loadEventDelayCount(0)
    433     , m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
    434     , m_referrerPolicy(ReferrerPolicyDefault)
    435     , m_directionSetOnDocumentElement(false)
    436     , m_writingModeSetOnDocumentElement(false)
    437     , m_writeRecursionIsTooDeep(false)
    438     , m_writeRecursionDepth(0)
    439     , m_wheelEventHandlerCount(0)
    440     , m_lastHandledUserGestureTimestamp(0)
    441     , m_prerenderer(Prerenderer::create(this))
    442     , m_textAutosizer(TextAutosizer::create(this))
    443     , m_registrationContext(initializer.registrationContext(this))
    444     , m_pendingTasksTimer(this, &Document::pendingTasksTimerFired)
    445     , m_scheduledTasksAreSuspended(false)
    446     , m_sharedObjectPoolClearTimer(this, &Document::sharedObjectPoolClearTimerFired)
    447 #ifndef NDEBUG
    448     , m_didDispatchViewportPropertiesChanged(false)
    449 #endif
    450     , m_timeline(DocumentTimeline::create(this))
    451     , m_templateDocumentHost(0)
    452     , m_fontloader(0)
    453     , m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
    454 {
    455     ScriptWrappable::init(this);
    456 
    457     if (m_frame) {
    458         provideContextFeaturesToDocumentFrom(this, m_frame->page());
    459 
    460         m_fetcher = m_frame->loader()->activeDocumentLoader()->fetcher();
    461     }
    462 
    463     if (!m_fetcher)
    464         m_fetcher = ResourceFetcher::create(0);
    465     m_fetcher->setDocument(this);
    466 
    467     // We depend on the url getting immediately set in subframes, but we
    468     // also depend on the url NOT getting immediately set in opened windows.
    469     // See fast/dom/early-frame-url.html
    470     // and fast/dom/location-new-window-no-crash.html, respectively.
    471     // FIXME: Can/should we unify this behavior?
    472     if (initializer.shouldSetURL())
    473         setURL(initializer.url());
    474 
    475     initSecurityContext(initializer);
    476     initDNSPrefetch();
    477 
    478     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
    479         m_nodeListCounts[i] = 0;
    480 
    481     InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
    482 }
    483 
    484 static void histogramMutationEventUsage(const unsigned short& listenerTypes)
    485 {
    486     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMSubtreeModified", static_cast<bool>(listenerTypes & Document::DOMSUBTREEMODIFIED_LISTENER), 2);
    487     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeInserted", static_cast<bool>(listenerTypes & Document::DOMNODEINSERTED_LISTENER), 2);
    488     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeRemoved", static_cast<bool>(listenerTypes & Document::DOMNODEREMOVED_LISTENER), 2);
    489     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeRemovedFromDocument", static_cast<bool>(listenerTypes & Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER), 2);
    490     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMNodeInsertedIntoDocument", static_cast<bool>(listenerTypes & Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER), 2);
    491     HistogramSupport::histogramEnumeration("DOMAPI.PerDocumentMutationEventUsage.DOMCharacterDataModified", static_cast<bool>(listenerTypes & Document::DOMCHARACTERDATAMODIFIED_LISTENER), 2);
    492 }
    493 
    494 static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, const WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner)
    495 {
    496     if (!owner)
    497         return true;
    498     do {
    499         if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
    500             return false;
    501     } while ((owner = owner->document()->ownerElement()));
    502     return true;
    503 }
    504 
    505 Document::~Document()
    506 {
    507     ASSERT(!renderer());
    508     ASSERT(m_ranges.isEmpty());
    509     ASSERT(!m_parentTreeScope);
    510     ASSERT(!hasGuardRefCount());
    511 
    512     if (m_templateDocument)
    513         m_templateDocument->setTemplateDocumentHost(0); // balanced in templateDocument().
    514 
    515     if (Document* ownerDocument = this->ownerDocument())
    516         ownerDocument->didRemoveEventTargetNode(this);
    517 
    518     m_scriptRunner.clear();
    519 
    520     histogramMutationEventUsage(m_listenerTypes);
    521 
    522     removeAllEventListeners();
    523 
    524     // Currently we believe that Document can never outlive the parser.
    525     // Although the Document may be replaced synchronously, DocumentParsers
    526     // generally keep at least one reference to an Element which would in turn
    527     // has a reference to the Document.  If you hit this ASSERT, then that
    528     // assumption is wrong.  DocumentParser::detach() should ensure that even
    529     // if the DocumentParser outlives the Document it won't cause badness.
    530     ASSERT(!m_parser || m_parser->refCount() == 1);
    531     detachParser();
    532 
    533     if (this == topDocument())
    534         clearAXObjectCache();
    535 
    536     m_decoder = 0;
    537 
    538     if (m_styleSheetList)
    539         m_styleSheetList->detachFromDocument();
    540 
    541     if (m_import) {
    542         m_import->wasDetachedFromDocument();
    543         m_import = 0;
    544     }
    545 
    546     m_styleSheetCollection.clear();
    547 
    548     if (m_elemSheet)
    549         m_elemSheet->clearOwnerNode();
    550 
    551     clearStyleResolver(); // We need to destory CSSFontSelector before destroying m_fetcher.
    552 
    553     // It's possible for multiple Documents to end up referencing the same ResourceFetcher (e.g., SVGImages
    554     // load the initial empty document and the SVGDocument with the same DocumentLoader).
    555     if (m_fetcher->document() == this)
    556         m_fetcher->setDocument(0);
    557     m_fetcher.clear();
    558 
    559     // We must call clearRareData() here since a Document class inherits TreeScope
    560     // as well as Node. See a comment on TreeScope.h for the reason.
    561     if (hasRareData())
    562         clearRareData();
    563 
    564     ASSERT(!m_listsInvalidatedAtDocument.size());
    565 
    566     for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
    567         ASSERT(!m_nodeListCounts[i]);
    568 
    569     clearDocumentScope();
    570 
    571     InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
    572 }
    573 
    574 void Document::dispose()
    575 {
    576     ASSERT(!m_deletionHasBegun);
    577     // We must make sure not to be retaining any of our children through
    578     // these extra pointers or we will create a reference cycle.
    579     m_docType = 0;
    580     m_focusedElement = 0;
    581     m_hoverNode = 0;
    582     m_activeElement = 0;
    583     m_titleElement = 0;
    584     m_documentElement = 0;
    585     m_contextFeatures = ContextFeatures::defaultSwitch();
    586     m_userActionElements.documentDidRemoveLastRef();
    587 
    588     detachParser();
    589 
    590     m_registrationContext.clear();
    591 
    592     if (m_import) {
    593         m_import->wasDetachedFromDocument();
    594         m_import = 0;
    595     }
    596 
    597     // removeDetachedChildren() doesn't always unregister IDs,
    598     // so tear down scope information upfront to avoid having stale references in the map.
    599     destroyTreeScopeData();
    600     removeDetachedChildren();
    601     // removeDetachedChildren() can access FormController.
    602     m_formController.clear();
    603 
    604     m_markers->detach();
    605 
    606     m_cssCanvasElements.clear();
    607 
    608     // FIXME: consider using ActiveDOMObject.
    609     if (m_scriptedAnimationController)
    610         m_scriptedAnimationController->clearDocumentPointer();
    611     m_scriptedAnimationController.clear();
    612 
    613     if (svgExtensions())
    614         accessSVGExtensions()->pauseAnimations();
    615 
    616     lifecycleNotifier()->notifyDocumentWasDisposed();
    617 }
    618 
    619 Element* Document::getElementById(const AtomicString& id) const
    620 {
    621     return TreeScope::getElementById(id);
    622 }
    623 
    624 SelectorQueryCache* Document::selectorQueryCache()
    625 {
    626     if (!m_selectorQueryCache)
    627         m_selectorQueryCache = adoptPtr(new SelectorQueryCache());
    628     return m_selectorQueryCache.get();
    629 }
    630 
    631 MediaQueryMatcher* Document::mediaQueryMatcher()
    632 {
    633     if (!m_mediaQueryMatcher)
    634         m_mediaQueryMatcher = MediaQueryMatcher::create(this);
    635     return m_mediaQueryMatcher.get();
    636 }
    637 
    638 void Document::setCompatibilityMode(CompatibilityMode mode)
    639 {
    640     if (m_compatibilityModeLocked || mode == m_compatibilityMode)
    641         return;
    642     bool wasInQuirksMode = inQuirksMode();
    643     m_compatibilityMode = mode;
    644     selectorQueryCache()->invalidate();
    645     if (inQuirksMode() != wasInQuirksMode) {
    646         // All user stylesheets have to reparse using the different mode.
    647         m_styleSheetCollection->clearPageUserSheet();
    648         m_styleSheetCollection->invalidateInjectedStyleSheetCache();
    649     }
    650 }
    651 
    652 String Document::compatMode() const
    653 {
    654     return inQuirksMode() ? "BackCompat" : "CSS1Compat";
    655 }
    656 
    657 void Document::setDocType(PassRefPtr<DocumentType> docType)
    658 {
    659     // This should never be called more than once.
    660     ASSERT(!m_docType || !docType);
    661     m_docType = docType;
    662     if (m_docType) {
    663         this->adoptIfNeeded(m_docType.get());
    664         if (m_docType->publicId().startsWith("-//wapforum//dtd xhtml mobile 1.", /* caseSensitive */ false))
    665             processViewport("width=device-width, height=device-height", ViewportArguments::XHTMLMobileProfile);
    666     }
    667     // Doctype affects the interpretation of the stylesheets.
    668     clearStyleResolver();
    669 }
    670 
    671 DOMImplementation* Document::implementation()
    672 {
    673     if (!m_implementation)
    674         m_implementation = DOMImplementation::create(this);
    675     return m_implementation.get();
    676 }
    677 
    678 bool Document::hasManifest() const
    679 {
    680     return documentElement() && isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
    681 }
    682 
    683 void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
    684 {
    685     ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    686 
    687     Element* newDocumentElement = ElementTraversal::firstWithin(this);
    688     if (newDocumentElement == m_documentElement)
    689         return;
    690     m_documentElement = newDocumentElement;
    691     // The root style used for media query matching depends on the document element.
    692     clearStyleResolver();
    693 }
    694 
    695 PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& es)
    696 {
    697     if (!isValidName(name)) {
    698         es.throwDOMException(InvalidCharacterError);
    699         return 0;
    700     }
    701 
    702     if (isXHTMLDocument() || isHTMLDocument())
    703         return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, isHTMLDocument() ? name.lower() : name, xhtmlNamespaceURI), this, 0, false);
    704 
    705     return createElement(QualifiedName(nullAtom, name, nullAtom), false);
    706 }
    707 
    708 PassRefPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState& es)
    709 {
    710     if (!isValidName(localName)) {
    711         es.throwDOMException(InvalidCharacterError);
    712         return 0;
    713     }
    714 
    715     RefPtr<Element> element;
    716 
    717     if (CustomElement::isValidName(localName) && registrationContext())
    718         element = registrationContext()->createCustomTagElement(this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
    719     else
    720         element = createElement(localName, es);
    721 
    722     if (!typeExtension.isNull() && !typeExtension.isEmpty())
    723         CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);
    724 
    725     return element;
    726 }
    727 
    728 PassRefPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const String& qualifiedName, const AtomicString& typeExtension, ExceptionState& es)
    729 {
    730     String prefix, localName;
    731     if (!parseQualifiedName(qualifiedName, prefix, localName, es))
    732         return 0;
    733 
    734     QualifiedName qName(prefix, localName, namespaceURI);
    735     if (!hasValidNamespaceForElements(qName)) {
    736         es.throwDOMException(NamespaceError);
    737         return 0;
    738     }
    739 
    740     RefPtr<Element> element;
    741     if (CustomElement::isValidName(qName.localName()) && registrationContext())
    742         element = registrationContext()->createCustomTagElement(this, qName);
    743     else
    744         element = createElementNS(namespaceURI, qualifiedName, es);
    745 
    746     if (!typeExtension.isNull() && !typeExtension.isEmpty())
    747         CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);
    748 
    749     return element;
    750 }
    751 
    752 ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, ExceptionState& es)
    753 {
    754     return registerElement(state, name, Dictionary(), es);
    755 }
    756 
    757 ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, const Dictionary& options, ExceptionState& es, CustomElement::NameSet validNames)
    758 {
    759     if (!registrationContext()) {
    760         es.throwDOMException(NotSupportedError);
    761         return ScriptValue();
    762     }
    763 
    764     CustomElementConstructorBuilder constructorBuilder(state, &options);
    765     registrationContext()->registerElement(this, &constructorBuilder, name, validNames, es);
    766     return constructorBuilder.bindingsReturnValue();
    767 }
    768 
    769 void Document::setImport(HTMLImport* import)
    770 {
    771     ASSERT(!m_import || !import);
    772     m_import = import;
    773 }
    774 
    775 void Document::didLoadAllImports()
    776 {
    777     executeScriptsWaitingForResourcesIfNeeded();
    778 }
    779 
    780 bool Document::haveImportsLoaded() const
    781 {
    782     return !m_import || !m_import->isBlocked();
    783 }
    784 
    785 PassRefPtr<DocumentFragment> Document::createDocumentFragment()
    786 {
    787     return DocumentFragment::create(document());
    788 }
    789 
    790 PassRefPtr<Text> Document::createTextNode(const String& data)
    791 {
    792     return Text::create(this, data);
    793 }
    794 
    795 PassRefPtr<Comment> Document::createComment(const String& data)
    796 {
    797     return Comment::create(this, data);
    798 }
    799 
    800 PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& es)
    801 {
    802     if (isHTMLDocument()) {
    803         es.throwDOMException(NotSupportedError);
    804         return 0;
    805     }
    806     return CDATASection::create(this, data);
    807 }
    808 
    809 PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& es)
    810 {
    811     if (!isValidName(target)) {
    812         es.throwDOMException(InvalidCharacterError);
    813         return 0;
    814     }
    815     if (isHTMLDocument()) {
    816         es.throwDOMException(NotSupportedError);
    817         return 0;
    818     }
    819     return ProcessingInstruction::create(this, target, data);
    820 }
    821 
    822 PassRefPtr<Text> Document::createEditingTextNode(const String& text)
    823 {
    824     return Text::createEditingText(this, text);
    825 }
    826 
    827 PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
    828 {
    829     return MutableStylePropertySet::create()->ensureCSSStyleDeclaration();
    830 }
    831 
    832 PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& es)
    833 {
    834     if (!importedNode) {
    835         es.throwDOMException(NotSupportedError);
    836         return 0;
    837     }
    838 
    839     switch (importedNode->nodeType()) {
    840     case TEXT_NODE:
    841         return createTextNode(importedNode->nodeValue());
    842     case CDATA_SECTION_NODE:
    843         return createCDATASection(importedNode->nodeValue(), es);
    844     case PROCESSING_INSTRUCTION_NODE:
    845         return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), es);
    846     case COMMENT_NODE:
    847         return createComment(importedNode->nodeValue());
    848     case ELEMENT_NODE: {
    849         Element* oldElement = toElement(importedNode);
    850         // FIXME: The following check might be unnecessary. Is it possible that
    851         // oldElement has mismatched prefix/namespace?
    852         if (!hasValidNamespaceForElements(oldElement->tagQName())) {
    853             es.throwDOMException(NamespaceError);
    854             return 0;
    855         }
    856         RefPtr<Element> newElement = createElement(oldElement->tagQName(), false);
    857 
    858         newElement->cloneDataFromElement(*oldElement);
    859 
    860         if (deep) {
    861             for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
    862                 RefPtr<Node> newChild = importNode(oldChild, true, es);
    863                 if (es.hadException())
    864                     return 0;
    865                 newElement->appendChild(newChild.release(), es);
    866                 if (es.hadException())
    867                     return 0;
    868             }
    869         }
    870 
    871         return newElement.release();
    872     }
    873     case ATTRIBUTE_NODE:
    874         return Attr::create(this, QualifiedName(nullAtom, toAttr(importedNode)->name(), nullAtom), toAttr(importedNode)->value());
    875     case DOCUMENT_FRAGMENT_NODE: {
    876         if (importedNode->isShadowRoot()) {
    877             // ShadowRoot nodes should not be explicitly importable.
    878             // Either they are imported along with their host node, or created implicitly.
    879             break;
    880         }
    881         DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode);
    882         RefPtr<DocumentFragment> newFragment = createDocumentFragment();
    883         if (deep) {
    884             for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
    885                 RefPtr<Node> newChild = importNode(oldChild, true, es);
    886                 if (es.hadException())
    887                     return 0;
    888                 newFragment->appendChild(newChild.release(), es);
    889                 if (es.hadException())
    890                     return 0;
    891             }
    892         }
    893 
    894         return newFragment.release();
    895     }
    896     case ENTITY_NODE:
    897     case NOTATION_NODE:
    898         // 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.
    899         // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
    900     case DOCUMENT_NODE:
    901     case DOCUMENT_TYPE_NODE:
    902     case XPATH_NAMESPACE_NODE:
    903         break;
    904     }
    905     es.throwDOMException(NotSupportedError);
    906     return 0;
    907 }
    908 
    909 PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionState& es)
    910 {
    911     if (!source) {
    912         es.throwDOMException(NotSupportedError);
    913         return 0;
    914     }
    915 
    916     EventQueueScope scope;
    917 
    918     switch (source->nodeType()) {
    919     case ENTITY_NODE:
    920     case NOTATION_NODE:
    921     case DOCUMENT_NODE:
    922     case DOCUMENT_TYPE_NODE:
    923     case XPATH_NAMESPACE_NODE:
    924         es.throwDOMException(NotSupportedError);
    925         return 0;
    926     case ATTRIBUTE_NODE: {
    927         Attr* attr = toAttr(source.get());
    928         if (attr->ownerElement())
    929             attr->ownerElement()->removeAttributeNode(attr, es);
    930         attr->setSpecified(true);
    931         break;
    932     }
    933     default:
    934         if (source->isShadowRoot()) {
    935             // ShadowRoot cannot disconnect itself from the host node.
    936             es.throwDOMException(HierarchyRequestError);
    937             return 0;
    938         }
    939 
    940         if (source->isFrameOwnerElement()) {
    941             HTMLFrameOwnerElement* frameOwnerElement = toFrameOwnerElement(source.get());
    942             if (frame() && frame()->tree()->isDescendantOf(frameOwnerElement->contentFrame())) {
    943                 es.throwDOMException(HierarchyRequestError);
    944                 return 0;
    945             }
    946         }
    947         if (source->parentNode()) {
    948             source->parentNode()->removeChild(source.get(), es);
    949             if (es.hadException())
    950                 return 0;
    951         }
    952     }
    953 
    954     this->adoptIfNeeded(source.get());
    955 
    956     return source;
    957 }
    958 
    959 bool Document::hasValidNamespaceForElements(const QualifiedName& qName)
    960 {
    961     // These checks are from DOM Core Level 2, createElementNS
    962     // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS
    963     if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) // createElementNS(null, "html:div")
    964         return false;
    965     if (qName.prefix() == xmlAtom && qName.namespaceURI() != XMLNames::xmlNamespaceURI) // createElementNS("http://www.example.com", "xml:lang")
    966         return false;
    967 
    968     // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core:
    969     // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
    970     // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar")
    971     if ((qName.prefix() == xmlnsAtom && qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI) || (qName.prefix() != xmlnsAtom && qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI))
    972         return false;
    973 
    974     return true;
    975 }
    976 
    977 bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName)
    978 {
    979     // Spec: DOM Level 2 Core: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-ElSetAttrNS
    980     if (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom) {
    981         // Note: The case of an "xmlns" qualified name with a namespace of
    982         // xmlnsNamespaceURI is specifically allowed (See <http://www.w3.org/2000/xmlns/>).
    983         return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
    984     }
    985     return hasValidNamespaceForElements(qName);
    986 }
    987 
    988 // FIXME: This should really be in a possible ElementFactory class
    989 PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
    990 {
    991     RefPtr<Element> e;
    992 
    993     // FIXME: Use registered namespaces and look up in a hash to find the right factory.
    994     if (qName.namespaceURI() == xhtmlNamespaceURI)
    995         e = HTMLElementFactory::createHTMLElement(qName, this, 0, createdByParser);
    996     else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
    997         e = SVGElementFactory::createSVGElement(qName, this, createdByParser);
    998 
    999     if (e)
   1000         m_sawElementsInKnownNamespaces = true;
   1001     else
   1002         e = Element::create(qName, document());
   1003 
   1004     // <image> uses imgTag so we need a special rule.
   1005     ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName());
   1006 
   1007     return e.release();
   1008 }
   1009 
   1010 bool Document::regionBasedColumnsEnabled() const
   1011 {
   1012     return settings() && settings()->regionBasedColumnsEnabled();
   1013 }
   1014 
   1015 bool Document::cssStickyPositionEnabled() const
   1016 {
   1017     return settings() && settings()->cssStickyPositionEnabled();
   1018 }
   1019 
   1020 bool Document::cssCompositingEnabled() const
   1021 {
   1022     return RuntimeEnabledFeatures::cssCompositingEnabled();
   1023 }
   1024 
   1025 PassRefPtr<DOMNamedFlowCollection> Document::webkitGetNamedFlows()
   1026 {
   1027     if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderer())
   1028         return 0;
   1029 
   1030     updateStyleIfNeeded();
   1031 
   1032     return namedFlows()->createCSSOMSnapshot();
   1033 }
   1034 
   1035 NamedFlowCollection* Document::namedFlows()
   1036 {
   1037     if (!m_namedFlows)
   1038         m_namedFlows = NamedFlowCollection::create(this);
   1039 
   1040     return m_namedFlows.get();
   1041 }
   1042 
   1043 PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionState& es)
   1044 {
   1045     String prefix, localName;
   1046     if (!parseQualifiedName(qualifiedName, prefix, localName, es))
   1047         return 0;
   1048 
   1049     QualifiedName qName(prefix, localName, namespaceURI);
   1050     if (!hasValidNamespaceForElements(qName)) {
   1051         es.throwDOMException(NamespaceError);
   1052         return 0;
   1053     }
   1054 
   1055     return createElement(qName, false);
   1056 }
   1057 
   1058 String Document::readyState() const
   1059 {
   1060     DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
   1061     DEFINE_STATIC_LOCAL(const String, interactive, ("interactive"));
   1062     DEFINE_STATIC_LOCAL(const String, complete, ("complete"));
   1063 
   1064     switch (m_readyState) {
   1065     case Loading:
   1066         return loading;
   1067     case Interactive:
   1068         return interactive;
   1069     case Complete:
   1070         return complete;
   1071     }
   1072 
   1073     ASSERT_NOT_REACHED();
   1074     return String();
   1075 }
   1076 
   1077 void Document::setReadyState(ReadyState readyState)
   1078 {
   1079     if (readyState == m_readyState)
   1080         return;
   1081 
   1082     switch (readyState) {
   1083     case Loading:
   1084         if (!m_documentTiming.domLoading)
   1085             m_documentTiming.domLoading = monotonicallyIncreasingTime();
   1086         break;
   1087     case Interactive:
   1088         if (!m_documentTiming.domInteractive)
   1089             m_documentTiming.domInteractive = monotonicallyIncreasingTime();
   1090         break;
   1091     case Complete:
   1092         if (!m_documentTiming.domComplete)
   1093             m_documentTiming.domComplete = monotonicallyIncreasingTime();
   1094         break;
   1095     }
   1096 
   1097     m_readyState = readyState;
   1098     dispatchEvent(Event::create(eventNames().readystatechangeEvent, false, false));
   1099 }
   1100 
   1101 String Document::encoding() const
   1102 {
   1103     // TextEncoding::domName() returns a char*, no need to allocate a new
   1104     // String for it each time.
   1105     // FIXME: We should fix TextEncoding to speak AtomicString anyway.
   1106     if (TextResourceDecoder* d = decoder())
   1107         return AtomicString(d->encoding().domName());
   1108     return String();
   1109 }
   1110 
   1111 String Document::defaultCharset() const
   1112 {
   1113     if (Settings* settings = this->settings())
   1114         return settings->defaultTextEncodingName();
   1115     return String();
   1116 }
   1117 
   1118 void Document::setCharset(const String& charset)
   1119 {
   1120     if (!decoder())
   1121         return;
   1122     decoder()->setEncoding(charset, TextResourceDecoder::UserChosenEncoding);
   1123 }
   1124 
   1125 void Document::setContentLanguage(const String& language)
   1126 {
   1127     if (m_contentLanguage == language)
   1128         return;
   1129     m_contentLanguage = language;
   1130 
   1131     // Document's style depends on the content language.
   1132     setNeedsStyleRecalc();
   1133 }
   1134 
   1135 void Document::setXMLVersion(const String& version, ExceptionState& es)
   1136 {
   1137     if (!implementation()->hasFeature("XML", String())) {
   1138         es.throwDOMException(NotSupportedError);
   1139         return;
   1140     }
   1141 
   1142     if (!XMLDocumentParser::supportsXMLVersion(version)) {
   1143         es.throwDOMException(NotSupportedError);
   1144         return;
   1145     }
   1146 
   1147     m_xmlVersion = version;
   1148 }
   1149 
   1150 void Document::setXMLStandalone(bool standalone, ExceptionState& es)
   1151 {
   1152     if (!implementation()->hasFeature("XML", String())) {
   1153         es.throwDOMException(NotSupportedError);
   1154         return;
   1155     }
   1156 
   1157     m_xmlStandalone = standalone ? Standalone : NotStandalone;
   1158 }
   1159 
   1160 KURL Document::baseURI() const
   1161 {
   1162     return m_baseURL;
   1163 }
   1164 
   1165 void Document::setContent(const String& content)
   1166 {
   1167     open();
   1168     // FIXME: This should probably use insert(), but that's (intentionally)
   1169     // not implemented for the XML parser as it's normally synonymous with
   1170     // document.write(). append() will end up yielding, but close() will
   1171     // pump the tokenizer syncrhonously and finish the parse.
   1172     m_parser->pinToMainThread();
   1173     m_parser->append(content.impl());
   1174     close();
   1175 }
   1176 
   1177 String Document::suggestedMIMEType() const
   1178 {
   1179     if (isXHTMLDocument())
   1180         return "application/xhtml+xml";
   1181     if (isSVGDocument())
   1182         return "image/svg+xml";
   1183     if (xmlStandalone())
   1184         return "text/xml";
   1185     if (isHTMLDocument())
   1186         return "text/html";
   1187 
   1188     if (DocumentLoader* documentLoader = loader())
   1189         return documentLoader->responseMIMEType();
   1190     return String();
   1191 }
   1192 
   1193 Element* Document::elementFromPoint(int x, int y) const
   1194 {
   1195     if (!renderer())
   1196         return 0;
   1197 
   1198     return TreeScope::elementFromPoint(x, y);
   1199 }
   1200 
   1201 PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
   1202 {
   1203     if (!renderer())
   1204         return 0;
   1205     LayoutPoint localPoint;
   1206     Node* node = nodeFromPoint(this, x, y, &localPoint);
   1207     if (!node)
   1208         return 0;
   1209 
   1210     Node* shadowAncestorNode = ancestorInThisScope(node);
   1211     if (shadowAncestorNode != node) {
   1212         unsigned offset = shadowAncestorNode->nodeIndex();
   1213         ContainerNode* container = shadowAncestorNode->parentNode();
   1214         return Range::create(this, container, offset, container, offset);
   1215     }
   1216 
   1217     RenderObject* renderer = node->renderer();
   1218     if (!renderer)
   1219         return 0;
   1220     PositionWithAffinity positionWithAffinity = renderer->positionForPoint(localPoint);
   1221     if (positionWithAffinity.position().isNull())
   1222         return 0;
   1223 
   1224     Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
   1225     return Range::create(this, rangeCompliantPosition, rangeCompliantPosition);
   1226 }
   1227 
   1228 /*
   1229  * Performs three operations:
   1230  *  1. Convert control characters to spaces
   1231  *  2. Trim leading and trailing spaces
   1232  *  3. Collapse internal whitespace.
   1233  */
   1234 template <typename CharacterType>
   1235 static inline StringWithDirection canonicalizedTitle(Document* document, const StringWithDirection& titleWithDirection)
   1236 {
   1237     const String& title = titleWithDirection.string();
   1238     const CharacterType* characters = title.getCharacters<CharacterType>();
   1239     unsigned length = title.length();
   1240     unsigned i;
   1241 
   1242     StringBuffer<CharacterType> buffer(length);
   1243     unsigned builderIndex = 0;
   1244 
   1245     // Skip leading spaces and leading characters that would convert to spaces
   1246     for (i = 0; i < length; ++i) {
   1247         CharacterType c = characters[i];
   1248         if (!(c <= 0x20 || c == 0x7F))
   1249             break;
   1250     }
   1251 
   1252     if (i == length)
   1253         return StringWithDirection();
   1254 
   1255     // Replace control characters with spaces, and backslashes with currency symbols, and collapse whitespace.
   1256     bool previousCharWasWS = false;
   1257     for (; i < length; ++i) {
   1258         CharacterType c = characters[i];
   1259         if (c <= 0x20 || c == 0x7F || (WTF::Unicode::category(c) & (WTF::Unicode::Separator_Line | WTF::Unicode::Separator_Paragraph))) {
   1260             if (previousCharWasWS)
   1261                 continue;
   1262             buffer[builderIndex++] = ' ';
   1263             previousCharWasWS = true;
   1264         } else {
   1265             buffer[builderIndex++] = c;
   1266             previousCharWasWS = false;
   1267         }
   1268     }
   1269 
   1270     // Strip trailing spaces
   1271     while (builderIndex > 0) {
   1272         --builderIndex;
   1273         if (buffer[builderIndex] != ' ')
   1274             break;
   1275     }
   1276 
   1277     if (!builderIndex && buffer[builderIndex] == ' ')
   1278         return StringWithDirection();
   1279 
   1280     buffer.shrink(builderIndex + 1);
   1281 
   1282     // Replace the backslashes with currency symbols if the encoding requires it.
   1283     document->displayBufferModifiedByEncoding(buffer.characters(), buffer.length());
   1284 
   1285     return StringWithDirection(String::adopt(buffer), titleWithDirection.direction());
   1286 }
   1287 
   1288 void Document::updateTitle(const StringWithDirection& title)
   1289 {
   1290     if (m_rawTitle == title)
   1291         return;
   1292 
   1293     m_rawTitle = title;
   1294 
   1295     if (m_rawTitle.string().isEmpty())
   1296         m_title = StringWithDirection();
   1297     else {
   1298         if (m_rawTitle.string().is8Bit())
   1299             m_title = canonicalizedTitle<LChar>(this, m_rawTitle);
   1300         else
   1301             m_title = canonicalizedTitle<UChar>(this, m_rawTitle);
   1302     }
   1303     if (Frame* f = frame())
   1304         f->loader()->setTitle(m_title);
   1305 }
   1306 
   1307 void Document::setTitle(const String& title)
   1308 {
   1309     // Title set by JavaScript -- overrides any title elements.
   1310     m_titleSetExplicitly = true;
   1311     if (!isHTMLDocument() && !isXHTMLDocument())
   1312         m_titleElement = 0;
   1313     else if (!m_titleElement) {
   1314         if (HTMLElement* headElement = head()) {
   1315             m_titleElement = createElement(titleTag, false);
   1316             headElement->appendChild(m_titleElement, ASSERT_NO_EXCEPTION, AttachLazily);
   1317         }
   1318     }
   1319 
   1320     // The DOM API has no method of specifying direction, so assume LTR.
   1321     updateTitle(StringWithDirection(title, LTR));
   1322 
   1323     if (m_titleElement) {
   1324         ASSERT(isHTMLTitleElement(m_titleElement.get()));
   1325         if (isHTMLTitleElement(m_titleElement.get()))
   1326             toHTMLTitleElement(m_titleElement.get())->setText(title);
   1327     }
   1328 }
   1329 
   1330 void Document::setTitleElement(const StringWithDirection& title, Element* titleElement)
   1331 {
   1332     if (titleElement != m_titleElement) {
   1333         if (m_titleElement || m_titleSetExplicitly)
   1334             // Only allow the first title element to change the title -- others have no effect.
   1335             return;
   1336         m_titleElement = titleElement;
   1337     }
   1338 
   1339     updateTitle(title);
   1340 }
   1341 
   1342 void Document::removeTitle(Element* titleElement)
   1343 {
   1344     if (m_titleElement != titleElement)
   1345         return;
   1346 
   1347     m_titleElement = 0;
   1348     m_titleSetExplicitly = false;
   1349 
   1350     // Update title based on first title element in the head, if one exists.
   1351     if (HTMLElement* headElement = head()) {
   1352         for (Node* e = headElement->firstChild(); e; e = e->nextSibling()) {
   1353             if (isHTMLTitleElement(e)) {
   1354                 HTMLTitleElement* titleElement = toHTMLTitleElement(e);
   1355                 setTitleElement(titleElement->textWithDirection(), titleElement);
   1356                 break;
   1357             }
   1358         }
   1359     }
   1360 
   1361     if (!m_titleElement)
   1362         updateTitle(StringWithDirection());
   1363 }
   1364 
   1365 PageVisibilityState Document::visibilityState() const
   1366 {
   1367     // The visibility of the document is inherited from the visibility of the
   1368     // page. If there is no page associated with the document, we will assume
   1369     // that the page is hidden, as specified by the spec:
   1370     // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PageVisibility/Overview.html#dom-document-hidden
   1371     if (!m_frame || !m_frame->page())
   1372         return PageVisibilityStateHidden;
   1373     return m_frame->page()->visibilityState();
   1374 }
   1375 
   1376 String Document::webkitVisibilityState() const
   1377 {
   1378     return pageVisibilityStateString(visibilityState());
   1379 }
   1380 
   1381 bool Document::webkitHidden() const
   1382 {
   1383     return visibilityState() != PageVisibilityStateVisible;
   1384 }
   1385 
   1386 void Document::dispatchVisibilityStateChangeEvent()
   1387 {
   1388     dispatchEvent(Event::create(eventNames().webkitvisibilitychangeEvent, false, false));
   1389 }
   1390 
   1391 DOMSecurityPolicy* Document::securityPolicy()
   1392 {
   1393     if (!m_domSecurityPolicy)
   1394         m_domSecurityPolicy = DOMSecurityPolicy::create(this);
   1395     return m_domSecurityPolicy.get();
   1396 }
   1397 
   1398 String Document::nodeName() const
   1399 {
   1400     return "#document";
   1401 }
   1402 
   1403 Node::NodeType Document::nodeType() const
   1404 {
   1405     return DOCUMENT_NODE;
   1406 }
   1407 
   1408 FormController* Document::formController()
   1409 {
   1410     if (!m_formController)
   1411         m_formController = FormController::create();
   1412     return m_formController.get();
   1413 }
   1414 
   1415 Vector<String> Document::formElementsState() const
   1416 {
   1417     if (!m_formController)
   1418         return Vector<String>();
   1419     return m_formController->formElementsState();
   1420 }
   1421 
   1422 void Document::setStateForNewFormElements(const Vector<String>& stateVector)
   1423 {
   1424     if (!stateVector.size() && !m_formController)
   1425         return;
   1426     formController()->setStateForNewFormElements(stateVector);
   1427 }
   1428 
   1429 FrameView* Document::view() const
   1430 {
   1431     return m_frame ? m_frame->view() : 0;
   1432 }
   1433 
   1434 Page* Document::page() const
   1435 {
   1436     return m_frame ? m_frame->page() : 0;
   1437 }
   1438 
   1439 Settings* Document::settings() const
   1440 {
   1441     return m_frame ? m_frame->settings() : 0;
   1442 }
   1443 
   1444 PassRefPtr<Range> Document::createRange()
   1445 {
   1446     return Range::create(this);
   1447 }
   1448 
   1449 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& es)
   1450 {
   1451     // FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
   1452     if (!root) {
   1453         es.throwDOMException(NotSupportedError);
   1454         return 0;
   1455     }
   1456     return NodeIterator::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
   1457 }
   1458 
   1459 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& es)
   1460 {
   1461     if (!root) {
   1462         es.throwDOMException(NotSupportedError);
   1463         return 0;
   1464     }
   1465     // FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
   1466     // NodeFilter.
   1467     return NodeIterator::create(root, whatToShow, PassRefPtr<NodeFilter>());
   1468 }
   1469 
   1470 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& es)
   1471 {
   1472     if (!root) {
   1473         es.throwDOMException(NotSupportedError);
   1474         return 0;
   1475     }
   1476     // FIXME: Ditto.
   1477     return NodeIterator::create(root, whatToShow, filter);
   1478 }
   1479 
   1480 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionState& es)
   1481 {
   1482     if (!root) {
   1483         es.throwDOMException(NotSupportedError);
   1484         return 0;
   1485     }
   1486     // FIXME: Warn if |expandEntityReferences| is specified. This optional argument is deprecated in DOM4.
   1487     UNUSED_PARAM(expandEntityReferences);
   1488     return NodeIterator::create(root, whatToShow, filter);
   1489 }
   1490 
   1491 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& es)
   1492 {
   1493     if (!root) {
   1494         es.throwDOMException(NotSupportedError);
   1495         return 0;
   1496     }
   1497     return TreeWalker::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
   1498 }
   1499 
   1500 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& es)
   1501 {
   1502     if (!root) {
   1503         es.throwDOMException(NotSupportedError);
   1504         return 0;
   1505     }
   1506     return TreeWalker::create(root, whatToShow, PassRefPtr<NodeFilter>());
   1507 }
   1508 
   1509 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& es)
   1510 {
   1511     if (!root) {
   1512         es.throwDOMException(NotSupportedError);
   1513         return 0;
   1514     }
   1515     return TreeWalker::create(root, whatToShow, filter);
   1516 }
   1517 
   1518 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, bool expandEntityReferences, ExceptionState& es)
   1519 {
   1520     UNUSED_PARAM(expandEntityReferences);
   1521     if (!root) {
   1522         es.throwDOMException(NotSupportedError);
   1523         return 0;
   1524     }
   1525     return TreeWalker::create(root, whatToShow, filter);
   1526 }
   1527 
   1528 void Document::scheduleStyleRecalc()
   1529 {
   1530     if (shouldDisplaySeamlesslyWithParent()) {
   1531         // When we're seamless, our parent document manages our style recalcs.
   1532         ownerElement()->setNeedsStyleRecalc();
   1533         ownerElement()->document()->scheduleStyleRecalc();
   1534         return;
   1535     }
   1536 
   1537     if (m_styleRecalcTimer.isActive())
   1538         return;
   1539 
   1540     ASSERT(needsStyleRecalc() || childNeedsStyleRecalc() || childNeedsDistributionRecalc());
   1541 
   1542     m_styleRecalcTimer.startOneShot(0);
   1543 
   1544     InspectorInstrumentation::didScheduleStyleRecalculation(this);
   1545 }
   1546 
   1547 void Document::unscheduleStyleRecalc()
   1548 {
   1549     ASSERT(!attached() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
   1550     m_styleRecalcTimer.stop();
   1551 }
   1552 
   1553 bool Document::hasPendingStyleRecalc() const
   1554 {
   1555     return m_styleRecalcTimer.isActive() && !m_inStyleRecalc;
   1556 }
   1557 
   1558 bool Document::hasPendingForcedStyleRecalc() const
   1559 {
   1560     return hasPendingStyleRecalc() && styleChangeType() >= SubtreeStyleChange;
   1561 }
   1562 
   1563 void Document::styleRecalcTimerFired(Timer<Document>*)
   1564 {
   1565     updateStyleIfNeeded();
   1566 }
   1567 
   1568 void Document::updateDistributionIfNeeded()
   1569 {
   1570     if (!childNeedsDistributionRecalc())
   1571         return;
   1572     TRACE_EVENT0("webkit", "Document::recalcDistribution");
   1573     recalcDistribution();
   1574 }
   1575 
   1576 void Document::updateDistributionForNodeIfNeeded(Node* node)
   1577 {
   1578     if (node->inDocument()) {
   1579         updateDistributionIfNeeded();
   1580         return;
   1581     }
   1582     Node* root = node;
   1583     while (Node* host = root->shadowHost())
   1584         root = host;
   1585     while (Node* ancestor = root->parentOrShadowHostNode())
   1586         root = ancestor;
   1587     if (root->childNeedsDistributionRecalc())
   1588         root->recalcDistribution();
   1589 }
   1590 
   1591 void Document::recalcStyle(StyleChange change)
   1592 {
   1593     // we should not enter style recalc while painting
   1594     ASSERT(!view() || !view()->isPainting());
   1595     if (view() && view()->isPainting())
   1596         return;
   1597 
   1598     if (m_inStyleRecalc)
   1599         return; // Guard against re-entrancy. -dwh
   1600 
   1601     TRACE_EVENT0("webkit", "Document::recalcStyle");
   1602     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle");
   1603 
   1604     updateDistributionIfNeeded();
   1605 
   1606     // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
   1607     // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
   1608     // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
   1609     // resolves style (here) and then when we resolve style on the parent chain, we may end up
   1610     // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
   1611     // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
   1612 
   1613     if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
   1614         m_styleSheetCollection->updateActiveStyleSheets(FullStyleUpdate);
   1615 
   1616     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
   1617 
   1618     if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
   1619         m_styleSheetCollection->setUsesRemUnit(true);
   1620 
   1621     m_inStyleRecalc = true;
   1622     {
   1623         PostAttachCallbackDisabler disabler(this);
   1624         WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
   1625 
   1626         RefPtr<FrameView> frameView = view();
   1627         if (frameView) {
   1628             frameView->pauseScheduledEvents();
   1629             frameView->beginDeferredRepaints();
   1630         }
   1631 
   1632         if (!renderer())
   1633             goto bailOut;
   1634 
   1635         if (styleChangeType() >= SubtreeStyleChange)
   1636             change = Force;
   1637 
   1638         // Recalculating the root style (on the document) is not needed in the common case.
   1639         if ((change == Force) || (shouldDisplaySeamlesslyWithParent() && (change >= Inherit))) {
   1640             // style selector may set this again during recalc
   1641             m_hasNodesWithPlaceholderStyle = false;
   1642 
   1643             RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(this, m_styleResolver ? m_styleResolver->fontSelector() : 0);
   1644             StyleChange ch = Node::diff(documentStyle.get(), renderer()->style(), this);
   1645             if (ch != NoChange)
   1646                 renderer()->setStyle(documentStyle.release());
   1647         }
   1648 
   1649         for (Node* n = firstChild(); n; n = n->nextSibling()) {
   1650             if (!n->isElementNode())
   1651                 continue;
   1652             Element* element = toElement(n);
   1653             if (shouldRecalcStyle(change, element))
   1654                 element->recalcStyle(change);
   1655         }
   1656 
   1657         if (view())
   1658             view()->updateCompositingLayersAfterStyleChange();
   1659 
   1660     bailOut:
   1661         clearNeedsStyleRecalc();
   1662         clearChildNeedsStyleRecalc();
   1663         unscheduleStyleRecalc();
   1664 
   1665         // FIXME: SVG <use> element can schedule a recalc in the middle of an already running one.
   1666         // See DocumentStyleSheetCollection::updateActiveStyleSheets.
   1667         if (m_styleSheetCollection->needsUpdateActiveStylesheetsOnStyleRecalc())
   1668             setNeedsStyleRecalc();
   1669 
   1670         m_inStyleRecalc = false;
   1671 
   1672         // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
   1673         if (m_styleResolver)
   1674             m_styleSheetCollection->resetCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
   1675 
   1676         if (frameView) {
   1677             frameView->resumeScheduledEvents();
   1678             frameView->endDeferredRepaints();
   1679         }
   1680     }
   1681 
   1682     // If we wanted to call implicitClose() during recalcStyle, do so now that we're finished.
   1683     if (m_closeAfterStyleRecalc) {
   1684         m_closeAfterStyleRecalc = false;
   1685         implicitClose();
   1686     }
   1687 
   1688     STYLE_STATS_PRINT();
   1689     STYLE_STATS_CLEAR();
   1690 
   1691     InspectorInstrumentation::didRecalculateStyle(cookie);
   1692 
   1693     // As a result of the style recalculation, the currently hovered element might have been
   1694     // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
   1695     // to check if any other elements ended up under the mouse pointer due to re-layout.
   1696     if (hoverNode() && !hoverNode()->renderer() && frame())
   1697         frame()->eventHandler()->dispatchFakeMouseMoveEventSoon();
   1698 }
   1699 
   1700 void Document::updateStyleIfNeeded()
   1701 {
   1702     ASSERT(isMainThread());
   1703     ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
   1704 
   1705     if (!needsStyleRecalc() && !childNeedsStyleRecalc() && !childNeedsDistributionRecalc())
   1706         return;
   1707 
   1708     AnimationUpdateBlock animationUpdateBlock(m_frame ? m_frame->animation() : 0);
   1709     recalcStyle(NoChange);
   1710 }
   1711 
   1712 void Document::updateStyleForNodeIfNeeded(Node* node)
   1713 {
   1714     if (!hasPendingForcedStyleRecalc() && !childNeedsStyleRecalc() && !needsStyleRecalc())
   1715         return;
   1716 
   1717     bool needsStyleRecalc = hasPendingForcedStyleRecalc();
   1718     for (Node* ancestor = node; ancestor && !needsStyleRecalc; ancestor = ancestor->parentOrShadowHostNode())
   1719         needsStyleRecalc = ancestor->needsStyleRecalc();
   1720     if (needsStyleRecalc)
   1721         updateStyleIfNeeded();
   1722 }
   1723 
   1724 void Document::updateLayout()
   1725 {
   1726     ASSERT(isMainThread());
   1727 
   1728     FrameView* frameView = view();
   1729     if (frameView && frameView->isInLayout()) {
   1730         // View layout should not be re-entrant.
   1731         ASSERT_NOT_REACHED();
   1732         return;
   1733     }
   1734 
   1735     if (Element* oe = ownerElement())
   1736         oe->document()->updateLayout();
   1737 
   1738     updateStyleIfNeeded();
   1739 
   1740     StackStats::LayoutCheckPoint layoutCheckPoint;
   1741 
   1742     // Only do a layout if changes have occurred that make it necessary.
   1743     if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
   1744         frameView->layout();
   1745 
   1746     setNeedsFocusedElementCheck();
   1747 }
   1748 
   1749 void Document::setNeedsFocusedElementCheck()
   1750 {
   1751     // FIXME: Using a Task doesn't look a good idea.
   1752     if (!m_focusedElement || m_didPostCheckFocusedElementTask)
   1753         return;
   1754     postTask(CheckFocusedElementTask::create());
   1755     m_didPostCheckFocusedElementTask = true;
   1756 }
   1757 
   1758 // FIXME: This is a bad idea and needs to be removed eventually.
   1759 // Other browsers load stylesheets before they continue parsing the web page.
   1760 // Since we don't, we can run JavaScript code that needs answers before the
   1761 // stylesheets are loaded. Doing a layout ignoring the pending stylesheets
   1762 // lets us get reasonable answers. The long term solution to this problem is
   1763 // to instead suspend JavaScript execution.
   1764 void Document::updateLayoutIgnorePendingStylesheets()
   1765 {
   1766     bool oldIgnore = m_ignorePendingStylesheets;
   1767 
   1768     if (!haveStylesheetsLoaded()) {
   1769         m_ignorePendingStylesheets = true;
   1770         // FIXME: We are willing to attempt to suppress painting with outdated style info only once.  Our assumption is that it would be
   1771         // dangerous to try to stop it a second time, after page content has already been loaded and displayed
   1772         // with accurate style information.  (Our suppression involves blanking the whole page at the
   1773         // moment.  If it were more refined, we might be able to do something better.)
   1774         // It's worth noting though that this entire method is a hack, since what we really want to do is
   1775         // suspend JS instead of doing a layout with inaccurate information.
   1776         HTMLElement* bodyElement = body();
   1777         if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
   1778             m_pendingSheetLayout = DidLayoutWithPendingSheets;
   1779             styleResolverChanged(RecalcStyleImmediately);
   1780         } else if (m_hasNodesWithPlaceholderStyle)
   1781             // If new nodes have been added or style recalc has been done with style sheets still pending, some nodes
   1782             // may not have had their real style calculated yet. Normally this gets cleaned when style sheets arrive
   1783             // but here we need up-to-date style immediately.
   1784             recalcStyle(Force);
   1785     }
   1786 
   1787     updateLayout();
   1788 
   1789     m_ignorePendingStylesheets = oldIgnore;
   1790 }
   1791 
   1792 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
   1793 {
   1794     ASSERT_ARG(element, element->document() == this);
   1795     TemporaryChange<bool> ignoreStyleSheets(m_ignorePendingStylesheets, true);
   1796     return styleResolver()->styleForElement(element, element->parentNode() ? element->parentNode()->computedStyle() : 0);
   1797 }
   1798 
   1799 PassRefPtr<RenderStyle> Document::styleForPage(int pageIndex)
   1800 {
   1801     return styleResolver()->styleForPage(pageIndex);
   1802 }
   1803 
   1804 bool Document::isPageBoxVisible(int pageIndex)
   1805 {
   1806     return styleForPage(pageIndex)->visibility() != HIDDEN; // display property doesn't apply to @page.
   1807 }
   1808 
   1809 void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
   1810 {
   1811     RefPtr<RenderStyle> style = styleForPage(pageIndex);
   1812     RenderView* view = renderView();
   1813 
   1814     int width = pageSize.width();
   1815     int height = pageSize.height();
   1816     switch (style->pageSizeType()) {
   1817     case PAGE_SIZE_AUTO:
   1818         break;
   1819     case PAGE_SIZE_AUTO_LANDSCAPE:
   1820         if (width < height)
   1821             std::swap(width, height);
   1822         break;
   1823     case PAGE_SIZE_AUTO_PORTRAIT:
   1824         if (width > height)
   1825             std::swap(width, height);
   1826         break;
   1827     case PAGE_SIZE_RESOLVED: {
   1828         LengthSize size = style->pageSize();
   1829         ASSERT(size.width().isFixed());
   1830         ASSERT(size.height().isFixed());
   1831         width = valueForLength(size.width(), 0, view);
   1832         height = valueForLength(size.height(), 0, view);
   1833         break;
   1834     }
   1835     default:
   1836         ASSERT_NOT_REACHED();
   1837     }
   1838     pageSize = IntSize(width, height);
   1839 
   1840     // The percentage is calculated with respect to the width even for margin top and bottom.
   1841     // http://www.w3.org/TR/CSS2/box.html#margin-properties
   1842     marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width, view);
   1843     marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width, view);
   1844     marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width, view);
   1845     marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width, view);
   1846 }
   1847 
   1848 void Document::setIsViewSource(bool isViewSource)
   1849 {
   1850     m_isViewSource = isViewSource;
   1851     if (!m_isViewSource)
   1852         return;
   1853 
   1854     setSecurityOrigin(SecurityOrigin::createUnique());
   1855     didUpdateSecurityOrigin();
   1856 }
   1857 
   1858 void Document::createStyleResolver()
   1859 {
   1860     bool matchAuthorAndUserStyles = true;
   1861     if (Settings* docSettings = settings())
   1862         matchAuthorAndUserStyles = docSettings->authorAndUserStylesEnabled();
   1863     m_styleResolver = adoptPtr(new StyleResolver(this, matchAuthorAndUserStyles));
   1864     m_styleSheetCollection->combineCSSFeatureFlags(m_styleResolver->ruleFeatureSet());
   1865 }
   1866 
   1867 void Document::clearStyleResolver()
   1868 {
   1869     m_styleResolver.clear();
   1870 }
   1871 
   1872 void Document::attach(const AttachContext& context)
   1873 {
   1874     ASSERT(!attached());
   1875     ASSERT(!m_axObjectCache || this != topDocument());
   1876 
   1877     // Create the rendering tree
   1878     setRenderer(new RenderView(this));
   1879     renderView()->setIsInWindow(true);
   1880 
   1881     recalcStyle(Force);
   1882 
   1883     ContainerNode::attach(context);
   1884 }
   1885 
   1886 void Document::detach(const AttachContext& context)
   1887 {
   1888     ASSERT(attached());
   1889 
   1890     if (page()) {
   1891         page()->pointerLockController()->documentDetached(this);
   1892         if (ValidationMessageClient* client = page()->validationMessageClient())
   1893             client->documentDetached(*this);
   1894     }
   1895 
   1896     if (this == topDocument())
   1897         clearAXObjectCache();
   1898 
   1899     stopActiveDOMObjects();
   1900     m_eventQueue->close();
   1901 
   1902     // FIXME: consider using ActiveDOMObject.
   1903     if (m_scriptedAnimationController)
   1904         m_scriptedAnimationController->clearDocumentPointer();
   1905     m_scriptedAnimationController.clear();
   1906 
   1907     if (svgExtensions())
   1908         accessSVGExtensions()->pauseAnimations();
   1909 
   1910     RenderObject* render = renderer();
   1911 
   1912     documentWillBecomeInactive();
   1913 
   1914     SharedWorkerRepository::documentDetached(this);
   1915 
   1916     if (m_frame) {
   1917         FrameView* view = m_frame->view();
   1918         if (view)
   1919             view->detachCustomScrollbars();
   1920     }
   1921 
   1922     // indicate destruction mode,  i.e. attached() but renderer == 0
   1923     setRenderer(0);
   1924 
   1925     m_hoverNode = 0;
   1926     m_focusedElement = 0;
   1927     m_activeElement = 0;
   1928 
   1929     ContainerNode::detach(context);
   1930 
   1931     unscheduleStyleRecalc();
   1932 
   1933     if (render)
   1934         render->destroy();
   1935 
   1936     if (m_touchEventTargets && m_touchEventTargets->size() && parentDocument())
   1937         parentDocument()->didRemoveEventTargetNode(this);
   1938 
   1939     // This is required, as our Frame might delete itself as soon as it detaches
   1940     // us. However, this violates Node::detach() semantics, as it's never
   1941     // possible to re-attach. Eventually Document::detach() should be renamed,
   1942     // or this setting of the frame to 0 could be made explicit in each of the
   1943     // callers of Document::detach().
   1944     m_frame = 0;
   1945 
   1946     if (m_mediaQueryMatcher)
   1947         m_mediaQueryMatcher->documentDestroyed();
   1948 
   1949     lifecycleNotifier()->notifyDocumentWasDetached();
   1950 }
   1951 
   1952 void Document::prepareForDestruction()
   1953 {
   1954     disconnectDescendantFrames();
   1955 
   1956     // The process of disconnecting descendant frames could have already
   1957     // detached us.
   1958     if (!attached())
   1959         return;
   1960 
   1961     if (DOMWindow* window = this->domWindow())
   1962         window->willDetachDocumentFromFrame();
   1963     detach();
   1964 }
   1965 
   1966 void Document::removeAllEventListeners()
   1967 {
   1968     EventTarget::removeAllEventListeners();
   1969 
   1970     if (DOMWindow* domWindow = this->domWindow())
   1971         domWindow->removeAllEventListeners();
   1972     for (Node* node = firstChild(); node; node = NodeTraversal::next(node))
   1973         node->removeAllEventListeners();
   1974 }
   1975 
   1976 void Document::suspendActiveDOMObjects(ActiveDOMObject::ReasonForSuspension why)
   1977 {
   1978     ScriptExecutionContext::suspendActiveDOMObjects(why);
   1979 }
   1980 
   1981 void Document::resumeActiveDOMObjects()
   1982 {
   1983     ScriptExecutionContext::resumeActiveDOMObjects();
   1984 }
   1985 
   1986 void Document::clearAXObjectCache()
   1987 {
   1988     ASSERT(topDocument() == this);
   1989     // Clear the cache member variable before calling delete because attempts
   1990     // are made to access it during destruction.
   1991     m_axObjectCache.clear();
   1992 }
   1993 
   1994 AXObjectCache* Document::existingAXObjectCache() const
   1995 {
   1996     if (!AXObjectCache::accessibilityEnabled())
   1997         return 0;
   1998 
   1999     // If the renderer is gone then we are in the process of destruction.
   2000     // This method will be called before m_frame = 0.
   2001     if (!topDocument()->renderer())
   2002         return 0;
   2003 
   2004     return topDocument()->m_axObjectCache.get();
   2005 }
   2006 
   2007 AXObjectCache* Document::axObjectCache() const
   2008 {
   2009     if (!AXObjectCache::accessibilityEnabled())
   2010         return 0;
   2011 
   2012     // The only document that actually has a AXObjectCache is the top-level
   2013     // document.  This is because we need to be able to get from any WebCoreAXObject
   2014     // to any other WebCoreAXObject on the same page.  Using a single cache allows
   2015     // lookups across nested webareas (i.e. multiple documents).
   2016     Document* topDocument = this->topDocument();
   2017 
   2018     // If the document has already been detached, do not make a new axObjectCache.
   2019     if (!topDocument->renderer())
   2020         return 0;
   2021 
   2022     ASSERT(topDocument == this || !m_axObjectCache);
   2023     if (!topDocument->m_axObjectCache)
   2024         topDocument->m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
   2025     return topDocument->m_axObjectCache.get();
   2026 }
   2027 
   2028 void Document::setVisuallyOrdered()
   2029 {
   2030     m_visuallyOrdered = true;
   2031     // FIXME: How is possible to not have a renderer here?
   2032     if (renderer())
   2033         renderer()->style()->setRTLOrdering(VisualOrder);
   2034     setNeedsStyleRecalc();
   2035 }
   2036 
   2037 PassRefPtr<DocumentParser> Document::createParser()
   2038 {
   2039     if (isHTMLDocument() || (RuntimeEnabledFeatures::parseSVGAsHTMLEnabled() && isSVGDocument())) {
   2040         bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(this->page());
   2041         return HTMLDocumentParser::create(this, reportErrors);
   2042     }
   2043     // FIXME: this should probably pass the frame instead
   2044     return XMLDocumentParser::create(this, view());
   2045 }
   2046 
   2047 bool Document::isFrameSet() const
   2048 {
   2049     if (!isHTMLDocument())
   2050         return false;
   2051     HTMLElement* bodyElement = body();
   2052     return bodyElement && bodyElement->hasTagName(framesetTag);
   2053 }
   2054 
   2055 ScriptableDocumentParser* Document::scriptableDocumentParser() const
   2056 {
   2057     return parser() ? parser()->asScriptableDocumentParser() : 0;
   2058 }
   2059 
   2060 void Document::open(Document* ownerDocument)
   2061 {
   2062     if (ownerDocument) {
   2063         setURL(ownerDocument->url());
   2064         m_cookieURL = ownerDocument->cookieURL();
   2065         setSecurityOrigin(ownerDocument->securityOrigin());
   2066         InspectorInstrumentation::childDocumentOpened(this);
   2067     }
   2068 
   2069     if (m_frame) {
   2070         if (ScriptableDocumentParser* parser = scriptableDocumentParser()) {
   2071             if (parser->isParsing()) {
   2072                 // FIXME: HTML5 doesn't tell us to check this, it might not be correct.
   2073                 if (parser->isExecutingScript())
   2074                     return;
   2075 
   2076                 if (!parser->wasCreatedByScript() && parser->hasInsertionPoint())
   2077                     return;
   2078             }
   2079         }
   2080 
   2081         if (m_frame->loader()->state() == FrameStateProvisional)
   2082             m_frame->loader()->stopAllLoaders();
   2083     }
   2084 
   2085     removeAllEventListeners();
   2086     implicitOpen();
   2087     if (ScriptableDocumentParser* parser = scriptableDocumentParser())
   2088         parser->setWasCreatedByScript(true);
   2089 
   2090     if (m_frame)
   2091         m_frame->loader()->didExplicitOpen();
   2092     if (m_loadEventProgress != LoadEventInProgress && m_loadEventProgress != UnloadEventInProgress)
   2093         m_loadEventProgress = LoadEventNotRun;
   2094 }
   2095 
   2096 void Document::detachParser()
   2097 {
   2098     if (!m_parser)
   2099         return;
   2100     m_parser->detach();
   2101     m_parser.clear();
   2102 }
   2103 
   2104 void Document::cancelParsing()
   2105 {
   2106     if (!m_parser)
   2107         return;
   2108 
   2109     // We have to clear the parser to avoid possibly triggering
   2110     // the onload handler when closing as a side effect of a cancel-style
   2111     // change, such as opening a new document or closing the window while
   2112     // still parsing
   2113     detachParser();
   2114     explicitClose();
   2115 }
   2116 
   2117 PassRefPtr<DocumentParser> Document::implicitOpen()
   2118 {
   2119     cancelParsing();
   2120 
   2121     removeChildren();
   2122     ASSERT(!m_focusedElement);
   2123 
   2124     setCompatibilityMode(NoQuirksMode);
   2125 
   2126     // Documents rendered seamlessly should start out requiring a stylesheet
   2127     // collection update in order to ensure they inherit all the relevant data
   2128     // from their parent.
   2129     if (shouldDisplaySeamlesslyWithParent())
   2130         styleResolverChanged(DeferRecalcStyle);
   2131 
   2132     m_parser = createParser();
   2133     setParsing(true);
   2134     setReadyState(Loading);
   2135 
   2136     return m_parser;
   2137 }
   2138 
   2139 HTMLElement* Document::body() const
   2140 {
   2141     if (!documentElement())
   2142         return 0;
   2143 
   2144     for (Node* child = documentElement()->firstChild(); child; child = child->nextSibling()) {
   2145         if (child->hasTagName(framesetTag) || child->hasTagName(bodyTag))
   2146             return toHTMLElement(child);
   2147     }
   2148 
   2149     return 0;
   2150 }
   2151 
   2152 void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionState& es)
   2153 {
   2154     RefPtr<HTMLElement> newBody = prpNewBody;
   2155 
   2156     if (!newBody || !documentElement()) {
   2157         es.throwDOMException(HierarchyRequestError);
   2158         return;
   2159     }
   2160 
   2161     if (!newBody->hasTagName(bodyTag) && !newBody->hasTagName(framesetTag)) {
   2162         es.throwDOMException(HierarchyRequestError);
   2163         return;
   2164     }
   2165 
   2166     HTMLElement* oldBody = body();
   2167     if (oldBody == newBody)
   2168         return;
   2169 
   2170     if (oldBody)
   2171         documentElement()->replaceChild(newBody.release(), oldBody, es, AttachLazily);
   2172     else
   2173         documentElement()->appendChild(newBody.release(), es, AttachLazily);
   2174 }
   2175 
   2176 HTMLHeadElement* Document::head()
   2177 {
   2178     Node* de = documentElement();
   2179     if (!de)
   2180         return 0;
   2181 
   2182     for (Node* e = de->firstChild(); e; e = e->nextSibling())
   2183         if (e->hasTagName(headTag))
   2184             return static_cast<HTMLHeadElement*>(e);
   2185 
   2186     return 0;
   2187 }
   2188 
   2189 void Document::close()
   2190 {
   2191     // FIXME: We should follow the specification more closely:
   2192     //        http://www.whatwg.org/specs/web-apps/current-work/#dom-document-close
   2193 
   2194     if (!scriptableDocumentParser() || !scriptableDocumentParser()->wasCreatedByScript() || !scriptableDocumentParser()->isParsing())
   2195         return;
   2196 
   2197     explicitClose();
   2198 }
   2199 
   2200 void Document::explicitClose()
   2201 {
   2202     if (RefPtr<DocumentParser> parser = m_parser)
   2203         parser->finish();
   2204 
   2205     if (!m_frame) {
   2206         // Because we have no frame, we don't know if all loading has completed,
   2207         // so we just call implicitClose() immediately. FIXME: This might fire
   2208         // the load event prematurely <http://bugs.webkit.org/show_bug.cgi?id=14568>.
   2209         implicitClose();
   2210         return;
   2211     }
   2212 
   2213     m_frame->loader()->checkCompleted();
   2214 }
   2215 
   2216 void Document::implicitClose()
   2217 {
   2218     // 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.
   2219     if (m_inStyleRecalc) {
   2220         m_closeAfterStyleRecalc = true;
   2221         return;
   2222     }
   2223 
   2224     bool wasLocationChangePending = frame() && frame()->navigationScheduler()->locationChangePending();
   2225     bool doload = !parsing() && m_parser && !processingLoadEvent() && !wasLocationChangePending;
   2226 
   2227     // If the load was blocked because of a pending location change and the location change triggers a same document
   2228     // navigation, don't fire load events after the same document navigation completes (unless there's an explicit open).
   2229     m_loadEventProgress = LoadEventTried;
   2230 
   2231     if (!doload)
   2232         return;
   2233 
   2234     // The call to dispatchWindowLoadEvent can detach the DOMWindow and cause it (and its
   2235     // attached Document) to be destroyed.
   2236     RefPtr<DOMWindow> protect(this->domWindow());
   2237 
   2238     m_loadEventProgress = LoadEventInProgress;
   2239 
   2240     ScriptableDocumentParser* parser = scriptableDocumentParser();
   2241     m_wellFormed = parser && parser->wellFormed();
   2242 
   2243     // We have to clear the parser, in case someone document.write()s from the
   2244     // onLoad event handler, as in Radar 3206524.
   2245     detachParser();
   2246 
   2247     Frame* f = frame();
   2248     if (f && !RuntimeEnabledFeatures::webAnimationsCSSEnabled())
   2249         f->animation()->resumeAnimationsForDocument(this);
   2250 
   2251     if (f && f->script()->canExecuteScripts(NotAboutToExecuteScript)) {
   2252         ImageLoader::dispatchPendingBeforeLoadEvents();
   2253         ImageLoader::dispatchPendingLoadEvents();
   2254         ImageLoader::dispatchPendingErrorEvents();
   2255 
   2256         HTMLLinkElement::dispatchPendingLoadEvents();
   2257         HTMLStyleElement::dispatchPendingLoadEvents();
   2258     }
   2259 
   2260     // To align the HTML load event and the SVGLoad event for the outermost <svg> element, fire it from
   2261     // here, instead of doing it from SVGElement::finishedParsingChildren (if externalResourcesRequired="false",
   2262     // which is the default, for ='true' its fired at a later time, once all external resources finished loading).
   2263     if (svgExtensions())
   2264         accessSVGExtensions()->dispatchSVGLoadEventToOutermostSVGElements();
   2265 
   2266     dispatchWindowLoadEvent();
   2267     enqueuePageshowEvent(PageshowEventNotPersisted);
   2268     enqueuePopstateEvent(m_pendingStateObject ? m_pendingStateObject.release() : SerializedScriptValue::nullValue());
   2269 
   2270     if (frame()) {
   2271         frame()->loader()->client()->dispatchDidHandleOnloadEvents();
   2272         loader()->applicationCacheHost()->stopDeferringEvents();
   2273     }
   2274 
   2275     // An event handler may have removed the frame
   2276     if (!frame()) {
   2277         m_loadEventProgress = LoadEventCompleted;
   2278         return;
   2279     }
   2280 
   2281     // Make sure both the initial layout and reflow happen after the onload
   2282     // fires. This will improve onload scores, and other browsers do it.
   2283     // If they wanna cheat, we can too. -dwh
   2284 
   2285     if (frame()->navigationScheduler()->locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
   2286         // Just bail out. Before or during the onload we were shifted to another page.
   2287         // The old i-Bench suite does this. When this happens don't bother painting or laying out.
   2288         m_loadEventProgress = LoadEventCompleted;
   2289         view()->unscheduleRelayout();
   2290         return;
   2291     }
   2292 
   2293     RenderObject* renderObject = renderer();
   2294 
   2295     // We used to force a synchronous display and flush here.  This really isn't
   2296     // necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
   2297     // (if your platform is syncing flushes and limiting them to 60fps).
   2298     m_overMinimumLayoutThreshold = true;
   2299     if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
   2300         updateStyleIfNeeded();
   2301 
   2302         // Always do a layout after loading if needed.
   2303         if (view() && renderObject && (!renderObject->firstChild() || renderObject->needsLayout()))
   2304             view()->layout();
   2305     }
   2306 
   2307     m_loadEventProgress = LoadEventCompleted;
   2308 
   2309     if (f && renderObject && AXObjectCache::accessibilityEnabled()) {
   2310         // The AX cache may have been cleared at this point, but we need to make sure it contains an
   2311         // AX object to send the notification to. getOrCreate will make sure that an valid AX object
   2312         // exists in the cache (we ignore the return value because we don't need it here). This is
   2313         // only safe to call when a layout is not in progress, so it can not be used in postNotification.
   2314         if (AXObjectCache* cache = axObjectCache()) {
   2315             cache->getOrCreate(renderObject);
   2316             if (this == topDocument()) {
   2317                 cache->postNotification(renderObject, AXObjectCache::AXLoadComplete, true);
   2318             } else {
   2319                 // AXLoadComplete can only be posted on the top document, so if it's a document
   2320                 // in an iframe that just finished loading, post AXLayoutComplete instead.
   2321                 cache->postNotification(renderObject, AXObjectCache::AXLayoutComplete, true);
   2322             }
   2323         }
   2324     }
   2325 
   2326     if (svgExtensions())
   2327         accessSVGExtensions()->startAnimations();
   2328 }
   2329 
   2330 void Document::setParsing(bool b)
   2331 {
   2332     m_bParsing = b;
   2333 
   2334     if (m_bParsing && !m_sharedObjectPool)
   2335         m_sharedObjectPool = DocumentSharedObjectPool::create();
   2336 
   2337     if (!m_bParsing && view())
   2338         view()->scheduleRelayout();
   2339 }
   2340 
   2341 bool Document::shouldScheduleLayout()
   2342 {
   2343     // This function will only be called when FrameView thinks a layout is needed.
   2344     // This enforces a couple extra rules.
   2345     //
   2346     //    (a) Only schedule a layout once the stylesheets are loaded.
   2347     //    (b) Only schedule layout once we have a body element.
   2348 
   2349     return (haveStylesheetsLoaded() && body())
   2350         || (documentElement() && !isHTMLHtmlElement(documentElement()));
   2351 }
   2352 
   2353 bool Document::shouldParserYieldAgressivelyBeforeScriptExecution()
   2354 {
   2355     return view() && view()->layoutPending() && !minimumLayoutDelay();
   2356 }
   2357 
   2358 int Document::minimumLayoutDelay()
   2359 {
   2360     if (m_overMinimumLayoutThreshold)
   2361         return 0;
   2362 
   2363     int elapsed = elapsedTime();
   2364     m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
   2365 
   2366     // We'll want to schedule the timer to fire at the minimum layout threshold.
   2367     return max(0, cLayoutScheduleThreshold - elapsed);
   2368 }
   2369 
   2370 int Document::elapsedTime() const
   2371 {
   2372     return static_cast<int>((currentTime() - m_startTime) * 1000);
   2373 }
   2374 
   2375 void Document::write(const SegmentedString& text, Document* ownerDocument)
   2376 {
   2377     NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);
   2378 
   2379     m_writeRecursionIsTooDeep = (m_writeRecursionDepth > 1) && m_writeRecursionIsTooDeep;
   2380     m_writeRecursionIsTooDeep = (m_writeRecursionDepth > cMaxWriteRecursionDepth) || m_writeRecursionIsTooDeep;
   2381 
   2382     if (m_writeRecursionIsTooDeep)
   2383        return;
   2384 
   2385     bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
   2386     if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)
   2387         return;
   2388 
   2389     if (!hasInsertionPoint)
   2390         open(ownerDocument);
   2391 
   2392     ASSERT(m_parser);
   2393     m_parser->insert(text);
   2394 }
   2395 
   2396 void Document::write(const String& text, Document* ownerDocument)
   2397 {
   2398     write(SegmentedString(text), ownerDocument);
   2399 }
   2400 
   2401 void Document::writeln(const String& text, Document* ownerDocument)
   2402 {
   2403     write(text, ownerDocument);
   2404     write("\n", ownerDocument);
   2405 }
   2406 
   2407 const KURL& Document::virtualURL() const
   2408 {
   2409     return m_url;
   2410 }
   2411 
   2412 KURL Document::virtualCompleteURL(const String& url) const
   2413 {
   2414     return completeURL(url);
   2415 }
   2416 
   2417 double Document::timerAlignmentInterval() const
   2418 {
   2419     Page* p = page();
   2420     if (!p)
   2421         return ScriptExecutionContext::timerAlignmentInterval();
   2422     return p->timerAlignmentInterval();
   2423 }
   2424 
   2425 EventTarget* Document::errorEventTarget()
   2426 {
   2427     return domWindow();
   2428 }
   2429 
   2430 void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
   2431 {
   2432     addMessage(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack);
   2433 }
   2434 
   2435 void Document::setURL(const KURL& url)
   2436 {
   2437     const KURL& newURL = url.isEmpty() ? blankURL() : url;
   2438     if (newURL == m_url)
   2439         return;
   2440 
   2441     m_url = newURL;
   2442     m_documentURI = m_url.string();
   2443     updateBaseURL();
   2444     contextFeatures()->urlDidChange(this);
   2445 }
   2446 
   2447 void Document::updateBaseURL()
   2448 {
   2449     KURL oldBaseURL = m_baseURL;
   2450     // DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML], the base URI is computed using
   2451     // first the value of the href attribute of the HTML BASE element if any, and the value of the documentURI attribute
   2452     // from the Document interface otherwise.
   2453     if (!m_baseElementURL.isEmpty())
   2454         m_baseURL = m_baseElementURL;
   2455     else if (!m_baseURLOverride.isEmpty())
   2456         m_baseURL = m_baseURLOverride;
   2457     else {
   2458         // The documentURI attribute is read-only from JavaScript, but writable from Objective C, so we need to retain
   2459         // this fallback behavior. We use a null base URL, since the documentURI attribute is an arbitrary string
   2460         // and DOM 3 Core does not specify how it should be resolved.
   2461         // FIXME: Now that we don't support Objective-C this can probably be removed.
   2462         m_baseURL = KURL(ParsedURLString, documentURI());
   2463     }
   2464     selectorQueryCache()->invalidate();
   2465 
   2466     if (!m_baseURL.isValid())
   2467         m_baseURL = KURL();
   2468 
   2469     if (m_elemSheet) {
   2470         // Element sheet is silly. It never contains anything.
   2471         ASSERT(!m_elemSheet->contents()->ruleCount());
   2472         bool usesRemUnits = m_elemSheet->contents()->usesRemUnits();
   2473         m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
   2474         // FIXME: So we are not really the parser. The right fix is to eliminate the element sheet completely.
   2475         m_elemSheet->contents()->parserSetUsesRemUnits(usesRemUnits);
   2476     }
   2477 
   2478     if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) {
   2479         // Base URL change changes any relative visited links.
   2480         // FIXME: There are other URLs in the tree that would need to be re-evaluated on dynamic base URL change. Style should be invalidated too.
   2481         for (Element* element = ElementTraversal::firstWithin(this); element; element = ElementTraversal::next(element)) {
   2482             if (isHTMLAnchorElement(element))
   2483                 toHTMLAnchorElement(element)->invalidateCachedVisitedLinkHash();
   2484         }
   2485     }
   2486 }
   2487 
   2488 void Document::setBaseURLOverride(const KURL& url)
   2489 {
   2490     m_baseURLOverride = url;
   2491     updateBaseURL();
   2492 }
   2493 
   2494 void Document::processBaseElement()
   2495 {
   2496     // Find the first href attribute in a base element and the first target attribute in a base element.
   2497     const AtomicString* href = 0;
   2498     const AtomicString* target = 0;
   2499     for (Element* element = ElementTraversal::firstWithin(this); element && (!href || !target); element = ElementTraversal::next(element)) {
   2500         if (element->hasTagName(baseTag)) {
   2501             if (!href) {
   2502                 const AtomicString& value = element->fastGetAttribute(hrefAttr);
   2503                 if (!value.isNull())
   2504                     href = &value;
   2505             }
   2506             if (!target) {
   2507                 const AtomicString& value = element->fastGetAttribute(targetAttr);
   2508                 if (!value.isNull())
   2509                     target = &value;
   2510             }
   2511             if (contentSecurityPolicy()->isActive())
   2512                 UseCounter::count(this, UseCounter::ContentSecurityPolicyWithBaseElement);
   2513         }
   2514     }
   2515 
   2516     // FIXME: Since this doesn't share code with completeURL it may not handle encodings correctly.
   2517     KURL baseElementURL;
   2518     if (href) {
   2519         String strippedHref = stripLeadingAndTrailingHTMLSpaces(*href);
   2520         if (!strippedHref.isEmpty())
   2521             baseElementURL = KURL(url(), strippedHref);
   2522     }
   2523     if (m_baseElementURL != baseElementURL && contentSecurityPolicy()->allowBaseURI(baseElementURL)) {
   2524         m_baseElementURL = baseElementURL;
   2525         updateBaseURL();
   2526     }
   2527 
   2528     m_baseTarget = target ? *target : nullAtom;
   2529 }
   2530 
   2531 String Document::userAgent(const KURL& url) const
   2532 {
   2533     return frame() ? frame()->loader()->userAgent(url) : String();
   2534 }
   2535 
   2536 void Document::disableEval(const String& errorMessage)
   2537 {
   2538     if (!frame())
   2539         return;
   2540 
   2541     frame()->script()->disableEval(errorMessage);
   2542 }
   2543 
   2544 bool Document::canNavigate(Frame* targetFrame)
   2545 {
   2546     if (!m_frame)
   2547         return false;
   2548 
   2549     // FIXME: We shouldn't call this function without a target frame, but
   2550     // fast/forms/submit-to-blank-multiple-times.html depends on this function
   2551     // returning true when supplied with a 0 targetFrame.
   2552     if (!targetFrame)
   2553         return true;
   2554 
   2555     // Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
   2556     if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree()->top())
   2557         return true;
   2558 
   2559     if (isSandboxed(SandboxNavigation)) {
   2560         if (targetFrame->tree()->isDescendantOf(m_frame))
   2561             return true;
   2562 
   2563         const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
   2564         if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree()->top())
   2565             reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
   2566 
   2567         printNavigationErrorMessage(targetFrame, url(), reason);
   2568         return false;
   2569     }
   2570 
   2571     // This is the normal case. A document can navigate its decendant frames,
   2572     // or, more generally, a document can navigate a frame if the document is
   2573     // in the same origin as any of that frame's ancestors (in the frame
   2574     // hierarchy).
   2575     //
   2576     // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
   2577     // historical information about this security check.
   2578     if (canAccessAncestor(securityOrigin(), targetFrame))
   2579         return true;
   2580 
   2581     // Top-level frames are easier to navigate than other frames because they
   2582     // display their URLs in the address bar (in most browsers). However, there
   2583     // are still some restrictions on navigation to avoid nuisance attacks.
   2584     // Specifically, a document can navigate a top-level frame if that frame
   2585     // opened the document or if the document is the same-origin with any of
   2586     // the top-level frame's opener's ancestors (in the frame hierarchy).
   2587     //
   2588     // In both of these cases, the document performing the navigation is in
   2589     // some way related to the frame being navigate (e.g., by the "opener"
   2590     // and/or "parent" relation). Requiring some sort of relation prevents a
   2591     // document from navigating arbitrary, unrelated top-level frames.
   2592     if (!targetFrame->tree()->parent()) {
   2593         if (targetFrame == m_frame->loader()->opener())
   2594             return true;
   2595 
   2596         if (canAccessAncestor(securityOrigin(), targetFrame->loader()->opener()))
   2597             return true;
   2598     }
   2599 
   2600     printNavigationErrorMessage(targetFrame, url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
   2601     return false;
   2602 }
   2603 
   2604 Frame* Document::findUnsafeParentScrollPropagationBoundary()
   2605 {
   2606     Frame* currentFrame = m_frame;
   2607     Frame* ancestorFrame = currentFrame->tree()->parent();
   2608 
   2609     while (ancestorFrame) {
   2610         if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrigin()))
   2611             return currentFrame;
   2612         currentFrame = ancestorFrame;
   2613         ancestorFrame = ancestorFrame->tree()->parent();
   2614     }
   2615     return 0;
   2616 }
   2617 
   2618 
   2619 void Document::seamlessParentUpdatedStylesheets()
   2620 {
   2621     styleResolverChanged(RecalcStyleImmediately);
   2622 }
   2623 
   2624 void Document::didRemoveAllPendingStylesheet()
   2625 {
   2626     m_needsNotifyRemoveAllPendingStylesheet = false;
   2627 
   2628     styleResolverChanged(RecalcStyleImmediately, AnalyzedStyleUpdate);
   2629     executeScriptsWaitingForResourcesIfNeeded();
   2630 
   2631     if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
   2632         view()->scrollToFragment(m_url);
   2633 }
   2634 
   2635 void Document::executeScriptsWaitingForResourcesIfNeeded()
   2636 {
   2637     if (!haveStylesheetsAndImportsLoaded())
   2638         return;
   2639     if (ScriptableDocumentParser* parser = scriptableDocumentParser())
   2640         parser->executeScriptsWaitingForResources();
   2641 }
   2642 
   2643 
   2644 CSSStyleSheet* Document::elementSheet()
   2645 {
   2646     if (!m_elemSheet)
   2647         m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
   2648     return m_elemSheet.get();
   2649 }
   2650 
   2651 void Document::processHttpEquiv(const String& equiv, const String& content)
   2652 {
   2653     ASSERT(!equiv.isNull() && !content.isNull());
   2654 
   2655     if (equalIgnoringCase(equiv, "default-style"))
   2656         processHttpEquivDefaultStyle(content);
   2657     else if (equalIgnoringCase(equiv, "refresh"))
   2658         processHttpEquivRefresh(content);
   2659     else if (equalIgnoringCase(equiv, "set-cookie"))
   2660         processHttpEquivSetCookie(content);
   2661     else if (equalIgnoringCase(equiv, "content-language"))
   2662         setContentLanguage(content);
   2663     else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
   2664         parseDNSPrefetchControlHeader(content);
   2665     else if (equalIgnoringCase(equiv, "x-frame-options"))
   2666         processHttpEquivXFrameOptions(content);
   2667     else if (equalIgnoringCase(equiv, "content-security-policy")
   2668         || equalIgnoringCase(equiv, "content-security-policy-report-only")
   2669         || equalIgnoringCase(equiv, "x-webkit-csp")
   2670         || equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
   2671         processHttpEquivContentSecurityPolicy(equiv, content);
   2672 }
   2673 
   2674 void Document::processHttpEquivContentSecurityPolicy(const String& equiv, const String& content)
   2675 {
   2676     if (equalIgnoringCase(equiv, "content-security-policy"))
   2677         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce);
   2678     else if (equalIgnoringCase(equiv, "content-security-policy-report-only"))
   2679         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report);
   2680     else if (equalIgnoringCase(equiv, "x-webkit-csp"))
   2681         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedEnforce);
   2682     else if (equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
   2683         contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::PrefixedReport);
   2684     else
   2685         ASSERT_NOT_REACHED();
   2686 }
   2687 
   2688 void Document::processHttpEquivDefaultStyle(const String& content)
   2689 {
   2690     // The preferred style set has been overridden as per section
   2691     // 14.3.2 of the HTML4.0 specification. We need to update the
   2692     // sheet used variable and then update our style selector.
   2693     // For more info, see the test at:
   2694     // http://www.hixie.ch/tests/evil/css/import/main/preferred.html
   2695     // -dwh
   2696     m_styleSheetCollection->setSelectedStylesheetSetName(content);
   2697     m_styleSheetCollection->setPreferredStylesheetSetName(content);
   2698     styleResolverChanged(DeferRecalcStyle);
   2699 }
   2700 
   2701 void Document::processHttpEquivRefresh(const String& content)
   2702 {
   2703     maybeHandleHttpRefresh(content, HttpRefreshFromMetaTag);
   2704 }
   2705 
   2706 void Document::maybeHandleHttpRefresh(const String& content, HttpRefreshType httpRefreshType)
   2707 {
   2708     if (m_isViewSource || !m_frame)
   2709         return;
   2710 
   2711     double delay;
   2712     String refreshURL;
   2713     if (!parseHTTPRefresh(content, httpRefreshType == HttpRefreshFromMetaTag, delay, refreshURL))
   2714         return;
   2715     if (refreshURL.isEmpty())
   2716         refreshURL = url().string();
   2717     else
   2718         refreshURL = completeURL(refreshURL).string();
   2719 
   2720     if (protocolIsJavaScript(refreshURL)) {
   2721         String message = "Refused to refresh " + m_url.elidedString() + " to a javascript: URL";
   2722         addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
   2723         return;
   2724     }
   2725 
   2726     if (httpRefreshType == HttpRefreshFromMetaTag && isSandboxed(SandboxAutomaticFeatures)) {
   2727         String message = "Refused to execute the redirect specified via '<meta http-equiv='refresh' content='...'>'. The document is sandboxed, and the 'allow-scripts' keyword is not set.";
   2728         addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
   2729         return;
   2730     }
   2731     m_frame->navigationScheduler()->scheduleRedirect(delay, refreshURL);
   2732 }
   2733 
   2734 void Document::processHttpEquivSetCookie(const String& content)
   2735 {
   2736     // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
   2737     if (!isHTMLDocument())
   2738         return;
   2739 
   2740     // Exception (for sandboxed documents) ignored.
   2741     toHTMLDocument(this)->setCookie(content, IGNORE_EXCEPTION);
   2742 }
   2743 
   2744 void Document::processHttpEquivXFrameOptions(const String& content)
   2745 {
   2746     Frame* frame = this->frame();
   2747     if (!frame)
   2748         return;
   2749 
   2750     FrameLoader* frameLoader = frame->loader();
   2751     unsigned long requestIdentifier = loader()->mainResourceIdentifier();
   2752     if (frameLoader->shouldInterruptLoadForXFrameOptions(content, url(), requestIdentifier)) {
   2753         String message = "Refused to display '" + url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
   2754         frameLoader->stopAllLoaders();
   2755         // Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
   2756         // intent, we must navigate away from the possibly partially-rendered document to a location that
   2757         // doesn't inherit the parent's SecurityOrigin.
   2758         frame->navigationScheduler()->scheduleLocationChange(securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
   2759         addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
   2760     }
   2761 }
   2762 
   2763 // Though isspace() considers \t and \v to be whitespace, Win IE doesn't.
   2764 static bool isSeparator(UChar c)
   2765 {
   2766     return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' || c == ',' || c == '\0';
   2767 }
   2768 
   2769 void Document::processArguments(const String& features, void* data, ArgumentsCallback callback)
   2770 {
   2771     // Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
   2772     int keyBegin, keyEnd;
   2773     int valueBegin, valueEnd;
   2774 
   2775     int i = 0;
   2776     int length = features.length();
   2777     String buffer = features.lower();
   2778     while (i < length) {
   2779         // skip to first non-separator, but don't skip past the end of the string
   2780         while (isSeparator(buffer[i])) {
   2781             if (i >= length)
   2782                 break;
   2783             i++;
   2784         }
   2785         keyBegin = i;
   2786 
   2787         // skip to first separator
   2788         while (!isSeparator(buffer[i]))
   2789             i++;
   2790         keyEnd = i;
   2791 
   2792         // skip to first '=', but don't skip past a ',' or the end of the string
   2793         while (buffer[i] != '=') {
   2794             if (buffer[i] == ',' || i >= length)
   2795                 break;
   2796             i++;
   2797         }
   2798 
   2799         // skip to first non-separator, but don't skip past a ',' or the end of the string
   2800         while (isSeparator(buffer[i])) {
   2801             if (buffer[i] == ',' || i >= length)
   2802                 break;
   2803             i++;
   2804         }
   2805         valueBegin = i;
   2806 
   2807         // skip to first separator
   2808         while (!isSeparator(buffer[i]))
   2809             i++;
   2810         valueEnd = i;
   2811 
   2812         ASSERT_WITH_SECURITY_IMPLICATION(i <= length);
   2813 
   2814         String keyString = buffer.substring(keyBegin, keyEnd - keyBegin);
   2815         String valueString = buffer.substring(valueBegin, valueEnd - valueBegin);
   2816         callback(keyString, valueString, this, data);
   2817     }
   2818 }
   2819 
   2820 void Document::processViewport(const String& features, ViewportArguments::Type origin)
   2821 {
   2822     ASSERT(!features.isNull());
   2823 
   2824     if (origin < m_viewportArguments.type)
   2825         return;
   2826 
   2827     if (origin != m_viewportArguments.type || !(page() && page()->settings()->viewportMetaMergeQuirk()))
   2828         m_viewportArguments = ViewportArguments(origin);
   2829     processArguments(features, (void*)&m_viewportArguments, &setViewportFeature);
   2830 
   2831     updateViewportArguments();
   2832 }
   2833 
   2834 void Document::updateViewportArguments()
   2835 {
   2836     if (page() && page()->mainFrame() == frame()) {
   2837 #ifndef NDEBUG
   2838         m_didDispatchViewportPropertiesChanged = true;
   2839 #endif
   2840         page()->chrome().dispatchViewportPropertiesDidChange(m_viewportArguments);
   2841     }
   2842 }
   2843 
   2844 void Document::processReferrerPolicy(const String& policy)
   2845 {
   2846     ASSERT(!policy.isNull());
   2847 
   2848     m_referrerPolicy = ReferrerPolicyDefault;
   2849 
   2850     if (equalIgnoringCase(policy, "never"))
   2851         m_referrerPolicy = ReferrerPolicyNever;
   2852     else if (equalIgnoringCase(policy, "always"))
   2853         m_referrerPolicy = ReferrerPolicyAlways;
   2854     else if (equalIgnoringCase(policy, "origin"))
   2855         m_referrerPolicy = ReferrerPolicyOrigin;
   2856 }
   2857 
   2858 MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
   2859 {
   2860     ASSERT(!renderer() || renderer()->isRenderView());
   2861 
   2862     // RenderView::hitTest causes a layout, and we don't want to hit that until the first
   2863     // layout because until then, there is nothing shown on the screen - the user can't
   2864     // have intentionally clicked on something belonging to this page. Furthermore,
   2865     // mousemove events before the first layout should not lead to a premature layout()
   2866     // happening, which could show a flash of white.
   2867     // See also the similar code in EventHandler::hitTestResultAtPoint.
   2868     if (!renderer() || !view() || !view()->didFirstLayout())
   2869         return MouseEventWithHitTestResults(event, HitTestResult(LayoutPoint()));
   2870 
   2871     HitTestResult result(documentPoint);
   2872     renderView()->hitTest(request, result);
   2873 
   2874     if (!request.readOnly())
   2875         updateHoverActiveState(request, result.innerElement(), &event);
   2876 
   2877     return MouseEventWithHitTestResults(event, result);
   2878 }
   2879 
   2880 // DOM Section 1.1.1
   2881 bool Document::childTypeAllowed(NodeType type) const
   2882 {
   2883     switch (type) {
   2884     case ATTRIBUTE_NODE:
   2885     case CDATA_SECTION_NODE:
   2886     case DOCUMENT_FRAGMENT_NODE:
   2887     case DOCUMENT_NODE:
   2888     case ENTITY_NODE:
   2889     case NOTATION_NODE:
   2890     case TEXT_NODE:
   2891     case XPATH_NAMESPACE_NODE:
   2892         return false;
   2893     case COMMENT_NODE:
   2894     case PROCESSING_INSTRUCTION_NODE:
   2895         return true;
   2896     case DOCUMENT_TYPE_NODE:
   2897     case ELEMENT_NODE:
   2898         // Documents may contain no more than one of each of these.
   2899         // (One Element and one DocumentType.)
   2900         for (Node* c = firstChild(); c; c = c->nextSibling())
   2901             if (c->nodeType() == type)
   2902                 return false;
   2903         return true;
   2904     }
   2905     return false;
   2906 }
   2907 
   2908 bool Document::canReplaceChild(Node* newChild, Node* oldChild)
   2909 {
   2910     if (!oldChild)
   2911         // ContainerNode::replaceChild will raise a NotFoundError.
   2912         return true;
   2913 
   2914     if (oldChild->nodeType() == newChild->nodeType())
   2915         return true;
   2916 
   2917     int numDoctypes = 0;
   2918     int numElements = 0;
   2919 
   2920     // First, check how many doctypes and elements we have, not counting
   2921     // the child we're about to remove.
   2922     for (Node* c = firstChild(); c; c = c->nextSibling()) {
   2923         if (c == oldChild)
   2924             continue;
   2925 
   2926         switch (c->nodeType()) {
   2927         case DOCUMENT_TYPE_NODE:
   2928             numDoctypes++;
   2929             break;
   2930         case ELEMENT_NODE:
   2931             numElements++;
   2932             break;
   2933         default:
   2934             break;
   2935         }
   2936     }
   2937 
   2938     // Then, see how many doctypes and elements might be added by the new child.
   2939     if (newChild->nodeType() == DOCUMENT_FRAGMENT_NODE) {
   2940         for (Node* c = newChild->firstChild(); c; c = c->nextSibling()) {
   2941             switch (c->nodeType()) {
   2942             case ATTRIBUTE_NODE:
   2943             case CDATA_SECTION_NODE:
   2944             case DOCUMENT_FRAGMENT_NODE:
   2945             case DOCUMENT_NODE:
   2946             case ENTITY_NODE:
   2947             case NOTATION_NODE:
   2948             case TEXT_NODE:
   2949             case XPATH_NAMESPACE_NODE:
   2950                 return false;
   2951             case COMMENT_NODE:
   2952             case PROCESSING_INSTRUCTION_NODE:
   2953                 break;
   2954             case DOCUMENT_TYPE_NODE:
   2955                 numDoctypes++;
   2956                 break;
   2957             case ELEMENT_NODE:
   2958                 numElements++;
   2959                 break;
   2960             }
   2961         }
   2962     } else {
   2963         switch (newChild->nodeType()) {
   2964         case ATTRIBUTE_NODE:
   2965         case CDATA_SECTION_NODE:
   2966         case DOCUMENT_FRAGMENT_NODE:
   2967         case DOCUMENT_NODE:
   2968         case ENTITY_NODE:
   2969         case NOTATION_NODE:
   2970         case TEXT_NODE:
   2971         case XPATH_NAMESPACE_NODE:
   2972             return false;
   2973         case COMMENT_NODE:
   2974         case PROCESSING_INSTRUCTION_NODE:
   2975             return true;
   2976         case DOCUMENT_TYPE_NODE:
   2977             numDoctypes++;
   2978             break;
   2979         case ELEMENT_NODE:
   2980             numElements++;
   2981             break;
   2982         }
   2983     }
   2984 
   2985     if (numElements > 1 || numDoctypes > 1)
   2986         return false;
   2987 
   2988     return true;
   2989 }
   2990 
   2991 PassRefPtr<Node> Document::cloneNode(bool /*deep*/)
   2992 {
   2993     // Spec says cloning Document nodes is "implementation dependent"
   2994     // so we do not support it...
   2995     return 0;
   2996 }
   2997 
   2998 StyleSheetList* Document::styleSheets()
   2999 {
   3000     if (!m_styleSheetList)
   3001         m_styleSheetList = StyleSheetList::create(this);
   3002     return m_styleSheetList.get();
   3003 }
   3004 
   3005 String Document::preferredStylesheetSet() const
   3006 {
   3007     return m_styleSheetCollection->preferredStylesheetSetName();
   3008 }
   3009 
   3010 String Document::selectedStylesheetSet() const
   3011 {
   3012     return m_styleSheetCollection->selectedStylesheetSetName();
   3013 }
   3014 
   3015 void Document::setSelectedStylesheetSet(const String& aString)
   3016 {
   3017     m_styleSheetCollection->setSelectedStylesheetSetName(aString);
   3018     styleResolverChanged(DeferRecalcStyle);
   3019 }
   3020 
   3021 void Document::evaluateMediaQueryList()
   3022 {
   3023     if (m_mediaQueryMatcher)
   3024         m_mediaQueryMatcher->styleResolverChanged();
   3025 }
   3026 
   3027 void Document::styleResolverChanged(StyleResolverUpdateType updateType, StyleResolverUpdateMode updateMode)
   3028 {
   3029     // Don't bother updating, since we haven't loaded all our style info yet
   3030     // and haven't calculated the style selector for the first time.
   3031     if (!attached() || (!m_didCalculateStyleResolver && !haveStylesheetsLoaded())) {
   3032         m_styleResolver.clear();
   3033         return;
   3034     }
   3035     m_didCalculateStyleResolver = true;
   3036 
   3037     bool needsRecalc = m_styleSheetCollection->updateActiveStyleSheets(updateMode);
   3038 
   3039     if (updateType >= DeferRecalcStyle) {
   3040         setNeedsStyleRecalc();
   3041         return;
   3042     }
   3043 
   3044     if (didLayoutWithPendingStylesheets() && !m_styleSheetCollection->hasPendingSheets()) {
   3045         m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
   3046         if (renderer())
   3047             renderView()->repaintViewAndCompositedLayers();
   3048     }
   3049 
   3050     if (!needsRecalc)
   3051         return;
   3052 
   3053     // This recalcStyle initiates a new recalc cycle. We need to bracket it to
   3054     // make sure animations get the correct update time
   3055     {
   3056         AnimationUpdateBlock animationUpdateBlock(m_frame ? m_frame->animation() : 0);
   3057         recalcStyle(Force);
   3058     }
   3059 
   3060     if (renderer()) {
   3061         renderer()->setNeedsLayoutAndPrefWidthsRecalc();
   3062         if (view())
   3063             view()->scheduleRelayout();
   3064     }
   3065 
   3066     evaluateMediaQueryList();
   3067 }
   3068 
   3069 void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
   3070 {
   3071     // If we're not in a frame yet any potential child documents won't have a StyleResolver to update.
   3072     if (!frame())
   3073         return;
   3074 
   3075     // Seamless child frames are expected to notify their seamless children recursively, so we only do direct children.
   3076     for (Frame* child = frame()->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
   3077         Document* childDocument = child->document();
   3078         if (childDocument->shouldDisplaySeamlesslyWithParent()) {
   3079             ASSERT(childDocument->seamlessParentIFrame()->document() == this);
   3080             childDocument->seamlessParentUpdatedStylesheets();
   3081         }
   3082     }
   3083 }
   3084 
   3085 void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
   3086 {
   3087     m_hoverNode = newHoverNode;
   3088 }
   3089 
   3090 void Document::setActiveElement(PassRefPtr<Element> newActiveElement)
   3091 {
   3092     if (!newActiveElement) {
   3093         m_activeElement.clear();
   3094         return;
   3095     }
   3096 
   3097     m_activeElement = newActiveElement;
   3098 }
   3099 
   3100 void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
   3101 {
   3102     if (!m_focusedElement)
   3103         return;
   3104 
   3105     Element* focusedElement = node->treeScope()->adjustedFocusedElement();
   3106     if (!focusedElement)
   3107         return;
   3108 
   3109     bool nodeInSubtree = false;
   3110     if (amongChildrenOnly)
   3111         nodeInSubtree = focusedElement->isDescendantOf(node);
   3112     else
   3113         nodeInSubtree = (focusedElement == node) || focusedElement->isDescendantOf(node);
   3114 
   3115     if (nodeInSubtree)
   3116         setFocusedElement(0);
   3117 }
   3118 
   3119 void Document::hoveredNodeDetached(Node* node)
   3120 {
   3121     if (!m_hoverNode)
   3122         return;
   3123 
   3124     if (node != m_hoverNode && (!m_hoverNode->isTextNode() || node != NodeRenderingTraversal::parent(m_hoverNode.get())))
   3125         return;
   3126 
   3127     m_hoverNode = NodeRenderingTraversal::parent(node);
   3128     while (m_hoverNode && !m_hoverNode->renderer())
   3129         m_hoverNode = NodeRenderingTraversal::parent(m_hoverNode.get());
   3130 
   3131     // If the mouse cursor is not visible, do not clear existing
   3132     // hover effects on the ancestors of |node| and do not invoke
   3133     // new hover effects on any other element.
   3134     if (!page()->isCursorVisible())
   3135         return;
   3136 
   3137     if (frame())
   3138         frame()->eventHandler()->scheduleHoverStateUpdate();
   3139 }
   3140 
   3141 void Document::activeChainNodeDetached(Node* node)
   3142 {
   3143     if (!m_activeElement)
   3144         return;
   3145 
   3146     if (node != m_activeElement && (!m_activeElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeElement.get())))
   3147         return;
   3148 
   3149     Node* activeNode = NodeRenderingTraversal::parent(node);
   3150     while (activeNode && activeNode->isElementNode() && !activeNode->renderer())
   3151         activeNode = NodeRenderingTraversal::parent(activeNode);
   3152 
   3153     m_activeElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
   3154 }
   3155 
   3156 const Vector<AnnotatedRegionValue>& Document::annotatedRegions() const
   3157 {
   3158     return m_annotatedRegions;
   3159 }
   3160 
   3161 void Document::setAnnotatedRegions(const Vector<AnnotatedRegionValue>& regions)
   3162 {
   3163     m_annotatedRegions = regions;
   3164     setAnnotatedRegionsDirty(false);
   3165 }
   3166 
   3167 bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, FocusDirection direction)
   3168 {
   3169     RefPtr<Element> newFocusedElement = prpNewFocusedElement;
   3170 
   3171     // Make sure newFocusedNode is actually in this document
   3172     if (newFocusedElement && (newFocusedElement->document() != this))
   3173         return true;
   3174 
   3175     if (m_focusedElement == newFocusedElement)
   3176         return true;
   3177 
   3178     bool focusChangeBlocked = false;
   3179     RefPtr<Element> oldFocusedElement = m_focusedElement;
   3180     m_focusedElement = 0;
   3181 
   3182     // Remove focus from the existing focus node (if any)
   3183     if (oldFocusedElement) {
   3184         ASSERT(!oldFocusedElement->inDetach());
   3185 
   3186         if (oldFocusedElement->active())
   3187             oldFocusedElement->setActive(false);
   3188 
   3189         oldFocusedElement->setFocus(false);
   3190 
   3191         // Dispatch a change event for text fields or textareas that have been edited
   3192         if (oldFocusedElement->wasChangedSinceLastFormControlChangeEvent())
   3193             oldFocusedElement->dispatchFormControlChangeEvent();
   3194 
   3195         // Dispatch the blur event and let the node do any other blur related activities (important for text fields)
   3196         oldFocusedElement->dispatchBlurEvent(newFocusedElement.get());
   3197 
   3198         if (m_focusedElement) {
   3199             // handler shifted focus
   3200             focusChangeBlocked = true;
   3201             newFocusedElement = 0;
   3202         }
   3203 
   3204         oldFocusedElement->dispatchFocusOutEvent(eventNames().focusoutEvent, newFocusedElement.get()); // DOM level 3 name for the bubbling blur event.
   3205         // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
   3206         // on it, probably when <rdar://problem/8503958> is resolved.
   3207         oldFocusedElement->dispatchFocusOutEvent(eventNames().DOMFocusOutEvent, newFocusedElement.get()); // DOM level 2 name for compatibility.
   3208 
   3209         if (m_focusedElement) {
   3210             // handler shifted focus
   3211             focusChangeBlocked = true;
   3212             newFocusedElement = 0;
   3213         }
   3214 
   3215         if (oldFocusedElement->isRootEditableElement())
   3216             frame()->editor()->didEndEditing();
   3217 
   3218         if (view()) {
   3219             Widget* oldWidget = widgetForElement(oldFocusedElement.get());
   3220             if (oldWidget)
   3221                 oldWidget->setFocus(false);
   3222             else
   3223                 view()->setFocus(false);
   3224         }
   3225     }
   3226 
   3227     if (newFocusedElement && newFocusedElement->isFocusable()) {
   3228         if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(newFocusedElement.get())) {
   3229             // delegate blocks focus change
   3230             focusChangeBlocked = true;
   3231             goto SetFocusedElementDone;
   3232         }
   3233         // Set focus on the new node
   3234         m_focusedElement = newFocusedElement;
   3235 
   3236         // Dispatch the focus event and let the node do any other focus related activities (important for text fields)
   3237         m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), direction);
   3238 
   3239         if (m_focusedElement != newFocusedElement) {
   3240             // handler shifted focus
   3241             focusChangeBlocked = true;
   3242             goto SetFocusedElementDone;
   3243         }
   3244 
   3245         m_focusedElement->dispatchFocusInEvent(eventNames().focusinEvent, oldFocusedElement.get()); // DOM level 3 bubbling focus event.
   3246 
   3247         if (m_focusedElement != newFocusedElement) {
   3248             // handler shifted focus
   3249             focusChangeBlocked = true;
   3250             goto SetFocusedElementDone;
   3251         }
   3252 
   3253         // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
   3254         // on it, probably when <rdar://problem/8503958> is m.
   3255         m_focusedElement->dispatchFocusInEvent(eventNames().DOMFocusInEvent, oldFocusedElement.get()); // DOM level 2 for compatibility.
   3256 
   3257         if (m_focusedElement != newFocusedElement) {
   3258             // handler shifted focus
   3259             focusChangeBlocked = true;
   3260             goto SetFocusedElementDone;
   3261         }
   3262         m_focusedElement->setFocus(true);
   3263 
   3264         if (m_focusedElement->isRootEditableElement())
   3265             frame()->editor()->didBeginEditing();
   3266 
   3267         // eww, I suck. set the qt focus correctly
   3268         // ### find a better place in the code for this
   3269         if (view()) {
   3270             Widget* focusWidget = widgetForElement(m_focusedElement.get());
   3271             if (focusWidget) {
   3272                 // Make sure a widget has the right size before giving it focus.
   3273                 // Otherwise, we are testing edge cases of the Widget code.
   3274                 // Specifically, in WebCore this does not work well for text fields.
   3275                 updateLayout();
   3276                 // Re-get the widget in case updating the layout changed things.
   3277                 focusWidget = widgetForElement(m_focusedElement.get());
   3278             }
   3279             if (focusWidget)
   3280                 focusWidget->setFocus(true);
   3281             else
   3282                 view()->setFocus(true);
   3283         }
   3284     }
   3285 
   3286     if (!focusChangeBlocked && m_focusedElement) {
   3287         // Create the AXObject cache in a focus change because Chromium relies on it.
   3288         if (AXObjectCache* cache = axObjectCache())
   3289             cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFocusedElement.get());
   3290     }
   3291 
   3292     if (!focusChangeBlocked)
   3293         page()->chrome().focusedNodeChanged(m_focusedElement.get());
   3294 
   3295 SetFocusedElementDone:
   3296     updateStyleIfNeeded();
   3297     if (Frame* frame = this->frame())
   3298         frame->selection()->didChangeFocus();
   3299     return !focusChangeBlocked;
   3300 }
   3301 
   3302 void Document::setCSSTarget(Element* n)
   3303 {
   3304     if (m_cssTarget)
   3305         m_cssTarget->didAffectSelector(AffectedSelectorTarget);
   3306     m_cssTarget = n;
   3307     if (n)
   3308         n->didAffectSelector(AffectedSelectorTarget);
   3309 }
   3310 
   3311 void Document::registerNodeList(LiveNodeListBase* list)
   3312 {
   3313     if (list->hasIdNameCache())
   3314         m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
   3315     m_nodeListCounts[list->invalidationType()]++;
   3316     if (list->isRootedAtDocument())
   3317         m_listsInvalidatedAtDocument.add(list);
   3318 }
   3319 
   3320 void Document::unregisterNodeList(LiveNodeListBase* list)
   3321 {
   3322     if (list->hasIdNameCache())
   3323         m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
   3324     m_nodeListCounts[list->invalidationType()]--;
   3325     if (list->isRootedAtDocument()) {
   3326         ASSERT(m_listsInvalidatedAtDocument.contains(list));
   3327         m_listsInvalidatedAtDocument.remove(list);
   3328     }
   3329 }
   3330 
   3331 void Document::attachNodeIterator(NodeIterator* ni)
   3332 {
   3333     m_nodeIterators.add(ni);
   3334 }
   3335 
   3336 void Document::detachNodeIterator(NodeIterator* ni)
   3337 {
   3338     // The node iterator can be detached without having been attached if its root node didn't have a document
   3339     // when the iterator was created, but has it now.
   3340     m_nodeIterators.remove(ni);
   3341 }
   3342 
   3343 void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
   3344 {
   3345     HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
   3346     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
   3347     for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
   3348         if ((*it)->root() == node) {
   3349             detachNodeIterator(*it);
   3350             newDocument->attachNodeIterator(*it);
   3351         }
   3352     }
   3353 }
   3354 
   3355 void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
   3356 {
   3357     if (!m_ranges.isEmpty()) {
   3358         HashSet<Range*>::const_iterator end = m_ranges.end();
   3359         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
   3360             (*it)->nodeChildrenChanged(container);
   3361     }
   3362 }
   3363 
   3364 void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
   3365 {
   3366     if (!m_ranges.isEmpty()) {
   3367         HashSet<Range*>::const_iterator end = m_ranges.end();
   3368         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
   3369             (*it)->nodeChildrenWillBeRemoved(container);
   3370     }
   3371 
   3372     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
   3373     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
   3374         for (Node* n = container->firstChild(); n; n = n->nextSibling())
   3375             (*it)->nodeWillBeRemoved(n);
   3376     }
   3377 
   3378     if (Frame* frame = this->frame()) {
   3379         for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
   3380             frame->eventHandler()->nodeWillBeRemoved(n);
   3381             frame->selection()->nodeWillBeRemoved(n);
   3382             frame->page()->dragCaretController().nodeWillBeRemoved(n);
   3383         }
   3384     }
   3385 }
   3386 
   3387 void Document::nodeWillBeRemoved(Node* n)
   3388 {
   3389     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
   3390     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
   3391         (*it)->nodeWillBeRemoved(n);
   3392 
   3393     if (!m_ranges.isEmpty()) {
   3394         HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
   3395         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
   3396             (*it)->nodeWillBeRemoved(n);
   3397     }
   3398 
   3399     if (Frame* frame = this->frame()) {
   3400         frame->eventHandler()->nodeWillBeRemoved(n);
   3401         frame->selection()->nodeWillBeRemoved(n);
   3402         frame->page()->dragCaretController().nodeWillBeRemoved(n);
   3403     }
   3404 }
   3405 
   3406 void Document::textInserted(Node* text, unsigned offset, unsigned length)
   3407 {
   3408     if (!m_ranges.isEmpty()) {
   3409         HashSet<Range*>::const_iterator end = m_ranges.end();
   3410         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
   3411             (*it)->textInserted(text, offset, length);
   3412     }
   3413 
   3414     // Update the markers for spelling and grammar checking.
   3415     m_markers->shiftMarkers(text, offset, length);
   3416 }
   3417 
   3418 void Document::textRemoved(Node* text, unsigned offset, unsigned length)
   3419 {
   3420     if (!m_ranges.isEmpty()) {
   3421         HashSet<Range*>::const_iterator end = m_ranges.end();
   3422         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
   3423             (*it)->textRemoved(text, offset, length);
   3424     }
   3425 
   3426     // Update the markers for spelling and grammar checking.
   3427     m_markers->removeMarkers(text, offset, length);
   3428     m_markers->shiftMarkers(text, offset + length, 0 - length);
   3429 }
   3430 
   3431 void Document::textNodesMerged(Text* oldNode, unsigned offset)
   3432 {
   3433     if (!m_ranges.isEmpty()) {
   3434         NodeWithIndex oldNodeWithIndex(oldNode);
   3435         HashSet<Range*>::const_iterator end = m_ranges.end();
   3436         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
   3437             (*it)->textNodesMerged(oldNodeWithIndex, offset);
   3438     }
   3439 
   3440     // FIXME: This should update markers for spelling and grammar checking.
   3441 }
   3442 
   3443 void Document::textNodeSplit(Text* oldNode)
   3444 {
   3445     if (!m_ranges.isEmpty()) {
   3446         HashSet<Range*>::const_iterator end = m_ranges.end();
   3447         for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
   3448             (*it)->textNodeSplit(oldNode);
   3449     }
   3450 
   3451     // FIXME: This should update markers for spelling and grammar checking.
   3452 }
   3453 
   3454 void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
   3455 {
   3456     DOMWindow* domWindow = this->domWindow();
   3457     if (!domWindow)
   3458         return;
   3459     domWindow->setAttributeEventListener(eventType, listener, isolatedWorld);
   3460 }
   3461 
   3462 EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
   3463 {
   3464     DOMWindow* domWindow = this->domWindow();
   3465     if (!domWindow)
   3466         return 0;
   3467     return domWindow->getAttributeEventListener(eventType, isolatedWorld);
   3468 }
   3469 
   3470 void Document::dispatchWindowEvent(PassRefPtr<Event> event,  PassRefPtr<EventTarget> target)
   3471 {
   3472     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
   3473     DOMWindow* domWindow = this->domWindow();
   3474     if (!domWindow)
   3475         return;
   3476     domWindow->dispatchEvent(event, target);
   3477 }
   3478 
   3479 void Document::enqueueWindowEvent(PassRefPtr<Event> event)
   3480 {
   3481     event->setTarget(domWindow());
   3482     m_eventQueue->enqueueEvent(event);
   3483 }
   3484 
   3485 void Document::enqueueDocumentEvent(PassRefPtr<Event> event)
   3486 {
   3487     event->setTarget(this);
   3488     m_eventQueue->enqueueEvent(event);
   3489 }
   3490 
   3491 PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionState& es)
   3492 {
   3493     RefPtr<Event> event = EventFactory::create(eventType);
   3494     if (event)
   3495         return event.release();
   3496 
   3497     es.throwDOMException(NotSupportedError);
   3498     return 0;
   3499 }
   3500 
   3501 void Document::dispatchWindowLoadEvent()
   3502 {
   3503     ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
   3504     DOMWindow* domWindow = this->domWindow();
   3505     if (!domWindow)
   3506         return;
   3507     domWindow->dispatchLoadEvent();
   3508 }
   3509 
   3510 void Document::addMutationEventListenerTypeIfEnabled(ListenerType listenerType)
   3511 {
   3512     if (ContextFeatures::mutationEventsEnabled(this))
   3513         addListenerType(listenerType);
   3514 }
   3515 
   3516 void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
   3517 {
   3518     if (eventType == eventNames().DOMSubtreeModifiedEvent)
   3519         addMutationEventListenerTypeIfEnabled(DOMSUBTREEMODIFIED_LISTENER);
   3520     else if (eventType == eventNames().DOMNodeInsertedEvent)
   3521         addMutationEventListenerTypeIfEnabled(DOMNODEINSERTED_LISTENER);
   3522     else if (eventType == eventNames().DOMNodeRemovedEvent)
   3523         addMutationEventListenerTypeIfEnabled(DOMNODEREMOVED_LISTENER);
   3524     else if (eventType == eventNames().DOMNodeRemovedFromDocumentEvent)
   3525         addMutationEventListenerTypeIfEnabled(DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
   3526     else if (eventType == eventNames().DOMNodeInsertedIntoDocumentEvent)
   3527         addMutationEventListenerTypeIfEnabled(DOMNODEINSERTEDINTODOCUMENT_LISTENER);
   3528     else if (eventType == eventNames().DOMCharacterDataModifiedEvent)
   3529         addMutationEventListenerTypeIfEnabled(DOMCHARACTERDATAMODIFIED_LISTENER);
   3530     else if (eventType == eventNames().overflowchangedEvent)
   3531         addListenerType(OVERFLOWCHANGED_LISTENER);
   3532     else if (eventType == eventNames().webkitAnimationStartEvent)
   3533         addListenerType(ANIMATIONSTART_LISTENER);
   3534     else if (eventType == eventNames().webkitAnimationEndEvent)
   3535         addListenerType(ANIMATIONEND_LISTENER);
   3536     else if (eventType == eventNames().webkitAnimationIterationEvent)
   3537         addListenerType(ANIMATIONITERATION_LISTENER);
   3538     else if (eventType == eventNames().webkitTransitionEndEvent || eventType == eventNames().transitionendEvent)
   3539         addListenerType(TRANSITIONEND_LISTENER);
   3540     else if (eventType == eventNames().beforeloadEvent)
   3541         addListenerType(BEFORELOAD_LISTENER);
   3542     else if (eventType == eventNames().scrollEvent)
   3543         addListenerType(SCROLL_LISTENER);
   3544 }
   3545 
   3546 CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)
   3547 {
   3548     return 0;
   3549 }
   3550 
   3551 HTMLFrameOwnerElement* Document::ownerElement() const
   3552 {
   3553     if (!frame())
   3554         return 0;
   3555     return frame()->ownerElement();
   3556 }
   3557 
   3558 String Document::cookie(ExceptionState& es) const
   3559 {
   3560     if (page() && !page()->settings()->cookieEnabled())
   3561         return String();
   3562 
   3563     // FIXME: The HTML5 DOM spec states that this attribute can raise an
   3564     // InvalidStateError exception on getting if the Document has no
   3565     // browsing context.
   3566 
   3567     if (!securityOrigin()->canAccessCookies()) {
   3568         es.throwDOMException(SecurityError);
   3569         return String();
   3570     }
   3571 
   3572     KURL cookieURL = this->cookieURL();
   3573     if (cookieURL.isEmpty())
   3574         return String();
   3575 
   3576     return cookies(this, cookieURL);
   3577 }
   3578 
   3579 void Document::setCookie(const String& value, ExceptionState& es)
   3580 {
   3581     if (page() && !page()->settings()->cookieEnabled())
   3582         return;
   3583 
   3584     // FIXME: The HTML5 DOM spec states that this attribute can raise an
   3585     // InvalidStateError exception on setting if the Document has no
   3586     // browsing context.
   3587 
   3588     if (!securityOrigin()->canAccessCookies()) {
   3589         es.throwDOMException(SecurityError);
   3590         return;
   3591     }
   3592 
   3593     KURL cookieURL = this->cookieURL();
   3594     if (cookieURL.isEmpty())
   3595         return;
   3596 
   3597     setCookies(this, cookieURL, value);
   3598 }
   3599 
   3600 String Document::referrer() const
   3601 {
   3602     if (frame())
   3603         return frame()->loader()->referrer();
   3604     return String();
   3605 }
   3606 
   3607 String Document::domain() const
   3608 {
   3609     return securityOrigin()->domain();
   3610 }
   3611 
   3612 void Document::setDomain(const String& newDomain, ExceptionState& es)
   3613 {
   3614     if (SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(securityOrigin()->protocol())) {
   3615         es.throwDOMException(SecurityError, "'document.domain' assignment is forbidden for the '" + securityOrigin()->protocol() + "' scheme.");
   3616         return;
   3617     }
   3618 
   3619     // Both NS and IE specify that changing the domain is only allowed when
   3620     // the new domain is a suffix of the old domain.
   3621 
   3622     // If the new domain is the same as the old domain, still call
   3623     // securityOrigin()->setDomainForDOM. This will change the
   3624     // security check behavior. For example, if a page loaded on port 8000
   3625     // assigns its current domain using document.domain, the page will
   3626     // allow other pages loaded on different ports in the same domain that
   3627     // have also assigned to access this page.
   3628     if (equalIgnoringCase(domain(), newDomain)) {
   3629         securityOrigin()->setDomainFromDOM(newDomain);
   3630         if (m_frame)
   3631             m_frame->script()->updateSecurityOrigin();
   3632         return;
   3633     }
   3634 
   3635     int oldLength = domain().length();
   3636     int newLength = newDomain.length();
   3637     String exceptionMessage =  "'document.domain' assignment failed: '" + newDomain + "' is not a suffix of '" + domain() + "'.";
   3638     // e.g. newDomain = subdomain.www.example.com (25) and domain() = www.example.com (15)
   3639     if (newLength >= oldLength) {
   3640         es.throwDOMException(SecurityError, exceptionMessage);
   3641         return;
   3642     }
   3643 
   3644     String test = domain();
   3645     // Check that it's a complete suffix, not e.g. "ample.com"
   3646     if (test[oldLength - newLength - 1] != '.') {
   3647         es.throwDOMException(SecurityError, exceptionMessage);
   3648         return;
   3649     }
   3650 
   3651     // Now test is "example.com" from domain()
   3652     // and we check that it's the same thing as newDomain
   3653     test.remove(0, oldLength - newLength);
   3654     if (test != newDomain) {
   3655         es.throwDOMException(SecurityError, exceptionMessage);
   3656         return;
   3657     }
   3658 
   3659     securityOrigin()->setDomainFromDOM(newDomain);
   3660     if (m_frame)
   3661         m_frame->script()->updateSecurityOrigin();
   3662 }
   3663 
   3664 // http://www.whatwg.org/specs/web-apps/current-work/#dom-document-lastmodified
   3665 String Document::lastModified() const
   3666 {
   3667     DateComponents date;
   3668     bool foundDate = false;
   3669     if (m_frame) {
   3670         String httpLastModified;
   3671         if (DocumentLoader* documentLoader = loader())
   3672             httpLastModified = documentLoader->response().httpHeaderField("Last-Modified");
   3673         if (!httpLastModified.isEmpty()) {
   3674             date.setMillisecondsSinceEpochForDateTime(parseDate(httpLastModified));
   3675             foundDate = true;
   3676         }
   3677     }
   3678     // FIXME: If this document came from the file system, the HTML5
   3679     // specificiation tells us to read the last modification date from the file
   3680     // system.
   3681     if (!foundDate)
   3682         date.setMillisecondsSinceEpochForDateTime(currentTimeMS());
   3683     return String::format("%02d/%02d/%04d %02d:%02d:%02d", date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
   3684 }
   3685 
   3686 const KURL& Document::firstPartyForCookies() const
   3687 {
   3688     return topDocument()->url();
   3689 }
   3690 
   3691 static bool isValidNameNonASCII(const LChar* characters, unsigned length)
   3692 {
   3693     if (!isValidNameStart(characters[0]))
   3694         return false;
   3695 
   3696     for (unsigned i = 1; i < length; ++i) {
   3697         if (!isValidNamePart(characters[i]))
   3698             return false;
   3699     }
   3700 
   3701     return true;
   3702 }
   3703 
   3704 static bool isValidNameNonASCII(const UChar* characters, unsigned length)
   3705 {
   3706     unsigned i = 0;
   3707 
   3708     UChar32 c;
   3709     U16_NEXT(characters, i, length, c)
   3710     if (!isValidNameStart(c))
   3711         return false;
   3712 
   3713     while (i < length) {
   3714         U16_NEXT(characters, i, length, c)
   3715         if (!isValidNamePart(c))
   3716             return false;
   3717     }
   3718 
   3719     return true;
   3720 }
   3721 
   3722 template<typename CharType>
   3723 static inline bool isValidNameASCII(const CharType* characters, unsigned length)
   3724 {
   3725     CharType c = characters[0];
   3726     if (!(isASCIIAlpha(c) || c == ':' || c == '_'))
   3727         return false;
   3728 
   3729     for (unsigned i = 1; i < length; ++i) {
   3730         c = characters[i];
   3731         if (!(isASCIIAlphanumeric(c) || c == ':' || c == '_' || c == '-' || c == '.'))
   3732             return false;
   3733     }
   3734 
   3735     return true;
   3736 }
   3737 
   3738 bool Document::isValidName(const String& name)
   3739 {
   3740     unsigned length = name.length();
   3741     if (!length)
   3742         return false;
   3743 
   3744     if (name.is8Bit()) {
   3745         const LChar* characters = name.characters8();
   3746 
   3747         if (isValidNameASCII(characters, length))
   3748             return true;
   3749 
   3750         return isValidNameNonASCII(characters, length);
   3751     }
   3752 
   3753     const UChar* characters = name.characters16();
   3754 
   3755     if (isValidNameASCII(characters, length))
   3756         return true;
   3757 
   3758     return isValidNameNonASCII(characters, length);
   3759 }
   3760 
   3761 template<typename CharType>
   3762 static bool parseQualifiedNameInternal(const String& qualifiedName, const CharType* characters, unsigned length, String& prefix, String& localName, ExceptionState& es)
   3763 {
   3764     bool nameStart = true;
   3765     bool sawColon = false;
   3766     int colonPos = 0;
   3767 
   3768     for (unsigned i = 0; i < length;) {
   3769         UChar32 c;
   3770         U16_NEXT(characters, i, length, c)
   3771         if (c == ':') {
   3772             if (sawColon) {
   3773                 es.throwDOMException(NamespaceError);
   3774                 return false; // multiple colons: not allowed
   3775             }
   3776             nameStart = true;
   3777             sawColon = true;
   3778             colonPos = i - 1;
   3779         } else if (nameStart) {
   3780             if (!isValidNameStart(c)) {
   3781                 es.throwDOMException(InvalidCharacterError);
   3782                 return false;
   3783             }
   3784             nameStart = false;
   3785         } else {
   3786             if (!isValidNamePart(c)) {
   3787                 es.throwDOMException(InvalidCharacterError);
   3788                 return false;
   3789             }
   3790         }
   3791     }
   3792 
   3793     if (!sawColon) {
   3794         prefix = String();
   3795         localName = qualifiedName;
   3796     } else {
   3797         prefix = qualifiedName.substring(0, colonPos);
   3798         if (prefix.isEmpty()) {
   3799             es.throwDOMException(NamespaceError);
   3800             return false;
   3801         }
   3802         localName = qualifiedName.substring(colonPos + 1);
   3803     }
   3804 
   3805     if (localName.isEmpty()) {
   3806         es.throwDOMException(NamespaceError);
   3807         return false;
   3808     }
   3809 
   3810     return true;
   3811 }
   3812 
   3813 bool Document::parseQualifiedName(const String& qualifiedName, String& prefix, String& localName, ExceptionState& es)
   3814 {
   3815     unsigned length = qualifiedName.length();
   3816 
   3817     if (!length) {
   3818         es.throwDOMException(InvalidCharacterError);
   3819         return false;
   3820     }
   3821 
   3822     if (qualifiedName.is8Bit())
   3823         return parseQualifiedNameInternal(qualifiedName, qualifiedName.characters8(), length, prefix, localName, es);
   3824     return parseQualifiedNameInternal(qualifiedName, qualifiedName.characters16(), length, prefix, localName, es);
   3825 }
   3826 
   3827 void Document::setDecoder(PassRefPtr<TextResourceDecoder> decoder)
   3828 {
   3829     m_decoder = decoder;
   3830 }
   3831 
   3832 KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
   3833 {
   3834     // Always return a null URL when passed a null string.
   3835     // FIXME: Should we change the KURL constructor to have this behavior?
   3836     // See also [CSS]StyleSheet::completeURL(const String&)
   3837     if (url.isNull())
   3838         return KURL();
   3839     const KURL& baseURL = ((baseURLOverride.isEmpty() || baseURLOverride == blankURL()) && parentDocument()) ? parentDocument()->baseURL() : baseURLOverride;
   3840     if (!m_decoder)
   3841         return KURL(baseURL, url);
   3842     return KURL(baseURL, url, m_decoder->encoding());
   3843 }
   3844 
   3845 KURL Document::completeURL(const String& url) const
   3846 {
   3847     return completeURL(url, m_baseURL);
   3848 }
   3849 
   3850 void Document::documentWillBecomeInactive()
   3851 {
   3852     if (renderer())
   3853         renderView()->setIsInWindow(false);
   3854 }
   3855 
   3856 // Support for Javascript execCommand, and related methods
   3857 
   3858 static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
   3859 {
   3860     Frame* frame = document->frame();
   3861     if (!frame || frame->document() != document)
   3862         return Editor::Command();
   3863 
   3864     document->updateStyleIfNeeded();
   3865 
   3866     return frame->editor()->command(commandName,
   3867         userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
   3868 }
   3869 
   3870 bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
   3871 {
   3872     return command(this, commandName, userInterface).execute(value);
   3873 }
   3874 
   3875 bool Document::queryCommandEnabled(const String& commandName)
   3876 {
   3877     return command(this, commandName).isEnabled();
   3878 }
   3879 
   3880 bool Document::queryCommandIndeterm(const String& commandName)
   3881 {
   3882     return command(this, commandName).state() == MixedTriState;
   3883 }
   3884 
   3885 bool Document::queryCommandState(const String& commandName)
   3886 {
   3887     return command(this, commandName).state() == TrueTriState;
   3888 }
   3889 
   3890 bool Document::queryCommandSupported(const String& commandName)
   3891 {
   3892     return command(this, commandName).isSupported();
   3893 }
   3894 
   3895 String Document::queryCommandValue(const String& commandName)
   3896 {
   3897     return command(this, commandName).value();
   3898 }
   3899 
   3900 KURL Document::openSearchDescriptionURL()
   3901 {
   3902     static const char* const openSearchMIMEType = "application/opensearchdescription+xml";
   3903     static const char* const openSearchRelation = "search";
   3904 
   3905     // FIXME: Why do only top-level frames have openSearchDescriptionURLs?
   3906     if (!frame() || frame()->tree()->parent())
   3907         return KURL();
   3908 
   3909     // FIXME: Why do we need to wait for FrameStateComplete?
   3910     if (frame()->loader()->state() != FrameStateComplete)
   3911         return KURL();
   3912 
   3913     if (!head())
   3914         return KURL();
   3915 
   3916     RefPtr<HTMLCollection> children = head()->children();
   3917     for (unsigned i = 0; Node* child = children->item(i); i++) {
   3918         if (!child->hasTagName(linkTag))
   3919             continue;
   3920         HTMLLinkElement* linkElement = toHTMLLinkElement(child);
   3921         if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
   3922             continue;
   3923         if (linkElement->href().isEmpty())
   3924             continue;
   3925         return linkElement->href();
   3926     }
   3927 
   3928     return KURL();
   3929 }
   3930 
   3931 void Document::pushCurrentScript(PassRefPtr<HTMLScriptElement> newCurrentScript)
   3932 {
   3933     ASSERT(newCurrentScript);
   3934     m_currentScriptStack.append(newCurrentScript);
   3935 }
   3936 
   3937 void Document::popCurrentScript()
   3938 {
   3939     ASSERT(!m_currentScriptStack.isEmpty());
   3940     m_currentScriptStack.removeLast();
   3941 }
   3942 
   3943 void Document::applyXSLTransform(ProcessingInstruction* pi)
   3944 {
   3945     ASSERT(!pi->isLoading());
   3946     UseCounter::count(this, UseCounter::XSLProcessingInstruction);
   3947     RefPtr<XSLTProcessor> processor = XSLTProcessor::create();
   3948     processor->setXSLStyleSheet(static_cast<XSLStyleSheet*>(pi->sheet()));
   3949     String resultMIMEType;
   3950     String newSource;
   3951     String resultEncoding;
   3952     if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
   3953         return;
   3954     // FIXME: If the transform failed we should probably report an error (like Mozilla does).
   3955     Frame* ownerFrame = frame();
   3956     processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, ownerFrame);
   3957     InspectorInstrumentation::frameDocumentUpdated(ownerFrame);
   3958 }
   3959 
   3960 void Document::setTransformSource(PassOwnPtr<TransformSource> source)
   3961 {
   3962     m_transformSource = source;
   3963 }
   3964 
   3965 void Document::setDesignMode(InheritedBool value)
   3966 {
   3967     m_designMode = value;
   3968     for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree()->traverseNext(m_frame))
   3969         frame->document()->setNeedsStyleRecalc();
   3970 }
   3971 
   3972 Document::InheritedBool Document::getDesignMode() const
   3973 {
   3974     return m_designMode;
   3975 }
   3976 
   3977 bool Document::inDesignMode() const
   3978 {
   3979     for (const Document* d = this; d; d = d->parentDocument()) {
   3980         if (d->m_designMode != inherit)
   3981             return d->m_designMode;
   3982     }
   3983     return false;
   3984 }
   3985 
   3986 Document* Document::parentDocument() const
   3987 {
   3988     if (!m_frame)
   3989         return 0;
   3990     Frame* parent = m_frame->tree()->parent();
   3991     if (!parent)
   3992         return 0;
   3993     return parent->document();
   3994 }
   3995 
   3996 Document* Document::topDocument() const
   3997 {
   3998     Document* doc = const_cast<Document *>(this);
   3999     Element* element;
   4000     while ((element = doc->ownerElement()))
   4001         doc = element->document();
   4002 
   4003     return doc;
   4004 }
   4005 
   4006 PassRefPtr<Attr> Document::createAttribute(const String& name, ExceptionState& es)
   4007 {
   4008     return createAttributeNS(String(), name, es, true);
   4009 }
   4010 
   4011 PassRefPtr<Attr> Document::createAttributeNS(const String& namespaceURI, const String& qualifiedName, ExceptionState& es, bool shouldIgnoreNamespaceChecks)
   4012 {
   4013     String prefix, localName;
   4014     if (!parseQualifiedName(qualifiedName, prefix, localName, es))
   4015         return 0;
   4016 
   4017     QualifiedName qName(prefix, localName, namespaceURI);
   4018 
   4019     if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(qName)) {
   4020         es.throwDOMException(NamespaceError);
   4021         return 0;
   4022     }
   4023 
   4024     return Attr::create(this, qName, emptyString());
   4025 }
   4026 
   4027 const SVGDocumentExtensions* Document::svgExtensions()
   4028 {
   4029     return m_svgExtensions.get();
   4030 }
   4031 
   4032 SVGDocumentExtensions* Document::accessSVGExtensions()
   4033 {
   4034     if (!m_svgExtensions)
   4035         m_svgExtensions = adoptPtr(new SVGDocumentExtensions(this));
   4036     return m_svgExtensions.get();
   4037 }
   4038 
   4039 bool Document::hasSVGRootNode() const
   4040 {
   4041     return documentElement() && documentElement()->hasTagName(SVGNames::svgTag);
   4042 }
   4043 
   4044 PassRefPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
   4045 {
   4046     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type);
   4047 }
   4048 
   4049 PassRefPtr<HTMLCollection> Document::images()
   4050 {
   4051     return ensureCachedCollection(DocImages);
   4052 }
   4053 
   4054 PassRefPtr<HTMLCollection> Document::applets()
   4055 {
   4056     return ensureCachedCollection(DocApplets);
   4057 }
   4058 
   4059 PassRefPtr<HTMLCollection> Document::embeds()
   4060 {
   4061     return ensureCachedCollection(DocEmbeds);
   4062 }
   4063 
   4064 PassRefPtr<HTMLCollection> Document::plugins()
   4065 {
   4066     // This is an alias for embeds() required for the JS DOM bindings.
   4067     return ensureCachedCollection(DocEmbeds);
   4068 }
   4069 
   4070 PassRefPtr<HTMLCollection> Document::scripts()
   4071 {
   4072     return ensureCachedCollection(DocScripts);
   4073 }
   4074 
   4075 PassRefPtr<HTMLCollection> Document::links()
   4076 {
   4077     return ensureCachedCollection(DocLinks);
   4078 }
   4079 
   4080 PassRefPtr<HTMLCollection> Document::forms()
   4081 {
   4082     return ensureCachedCollection(DocForms);
   4083 }
   4084 
   4085 PassRefPtr<HTMLCollection> Document::anchors()
   4086 {
   4087     return ensureCachedCollection(DocAnchors);
   4088 }
   4089 
   4090 PassRefPtr<HTMLCollection> Document::allForBinding()
   4091 {
   4092     UseCounter::count(this, UseCounter::DocumentAll);
   4093     return all();
   4094 }
   4095 
   4096 PassRefPtr<HTMLCollection> Document::all()
   4097 {
   4098     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLAllCollection>(this, DocAll);
   4099 }
   4100 
   4101 PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
   4102 {
   4103     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLNameCollection>(this, WindowNamedItems, name);
   4104 }
   4105 
   4106 PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
   4107 {
   4108     return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLNameCollection>(this, DocumentNamedItems, name);
   4109 }
   4110 
   4111 void Document::finishedParsing()
   4112 {
   4113     ASSERT(!scriptableDocumentParser() || !m_parser->isParsing());
   4114     ASSERT(!scriptableDocumentParser() || m_readyState != Loading);
   4115     setParsing(false);
   4116     if (!m_documentTiming.domContentLoadedEventStart)
   4117         m_documentTiming.domContentLoadedEventStart = monotonicallyIncreasingTime();
   4118     dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
   4119     if (!m_documentTiming.domContentLoadedEventEnd)
   4120         m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
   4121 
   4122     // The loader's finishedParsing() method may invoke script that causes this object to
   4123     // be dereferenced (when this document is in an iframe and the onload causes the iframe's src to change).
   4124     // Keep it alive until we are done.
   4125     RefPtr<Document> protect(this);
   4126 
   4127     if (RefPtr<Frame> f = frame()) {
   4128         // FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all
   4129         // resource loads are complete. HTMLObjectElements can start loading their resources from
   4130         // post attach callbacks triggered by recalcStyle().  This means if we parse out an <object>
   4131         // tag and then reach the end of the document without updating styles, we might not have yet
   4132         // started the resource load and might fire the window load event too early.  To avoid this
   4133         // we force the styles to be up to date before calling FrameLoader::finishedParsing().
   4134         // See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment 35.
   4135         updateStyleIfNeeded();
   4136 
   4137         f->loader()->finishedParsing();
   4138 
   4139         InspectorInstrumentation::domContentLoadedEventFired(f.get());
   4140     }
   4141 
   4142     // Schedule dropping of the DocumentSharedObjectPool. We keep it alive for a while after parsing finishes
   4143     // so that dynamically inserted content can also benefit from sharing optimizations.
   4144     // Note that we don't refresh the timer on pool access since that could lead to huge caches being kept
   4145     // alive indefinitely by something innocuous like JS setting .innerHTML repeatedly on a timer.
   4146     static const int timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds = 10;
   4147     m_sharedObjectPoolClearTimer.startOneShot(timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds);
   4148 
   4149     // Parser should have picked up all preloads by now
   4150     m_fetcher->clearPreloads();
   4151 
   4152     if (m_import)
   4153         m_import->didFinishParsing();
   4154 }
   4155 
   4156 void Document::sharedObjectPoolClearTimerFired(Timer<Document>*)
   4157 {
   4158     m_sharedObjectPool.clear();
   4159 }
   4160 
   4161 void Document::didAccessStyleResolver()
   4162 {
   4163     static const int timeBeforeThrowingAwayStyleResolverAfterLastUseInSeconds = 60;
   4164     static const int holdOffTimeBeforeReschedulingTimerInSeconds = 5;
   4165 
   4166     double currentTime = WTF::currentTime();
   4167 
   4168     if (currentTime > m_lastStyleResolverAccessTime + holdOffTimeBeforeReschedulingTimerInSeconds) {
   4169         m_styleResolverThrowawayTimer.startOneShot(timeBeforeThrowingAwayStyleResolverAfterLastUseInSeconds);
   4170         m_lastStyleResolverAccessTime = currentTime;
   4171     }
   4172 }
   4173 
   4174 void Document::styleResolverThrowawayTimerFired(Timer<Document>*)
   4175 {
   4176     ASSERT(!m_inStyleRecalc);
   4177     clearStyleResolver();
   4178 }
   4179 
   4180 const Vector<IconURL>& Document::shortcutIconURLs()
   4181 {
   4182     // Include any icons where type = link, rel = "shortcut icon".
   4183     return iconURLs(Favicon);
   4184 }
   4185 
   4186 const Vector<IconURL>& Document::iconURLs(int iconTypesMask)
   4187 {
   4188     m_iconURLs.clear();
   4189 
   4190     if (!head() || !(head()->children()))
   4191         return m_iconURLs;
   4192 
   4193     RefPtr<HTMLCollection> children = head()->children();
   4194     unsigned int length = children->length();
   4195     for (unsigned int i = 0; i < length; ++i) {
   4196         Node* child = children->item(i);
   4197         if (!child->hasTagName(linkTag))
   4198             continue;
   4199         HTMLLinkElement* linkElement = toHTMLLinkElement(child);
   4200         if (!(linkElement->iconType() & iconTypesMask))
   4201             continue;
   4202         if (linkElement->href().isEmpty())
   4203             continue;
   4204 
   4205         // Put it at the front to ensure that icons seen later take precedence as required by the spec.
   4206         IconURL newURL(linkElement->href(), linkElement->iconSizes(), linkElement->type(), linkElement->iconType());
   4207         m_iconURLs.prepend(newURL);
   4208     }
   4209 
   4210     return m_iconURLs;
   4211 }
   4212 
   4213 void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
   4214 {
   4215     if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
   4216         return;
   4217 
   4218     m_useSecureKeyboardEntryWhenActive = usesSecureKeyboard;
   4219     m_frame->selection()->updateSecureKeyboardEntryIfActive();
   4220 }
   4221 
   4222 bool Document::useSecureKeyboardEntryWhenActive() const
   4223 {
   4224     return m_useSecureKeyboardEntryWhenActive;
   4225 }
   4226 
   4227 static bool isEligibleForSeamless(Document* parent, Document* child)
   4228 {
   4229     // It should not matter what we return for the top-most document.
   4230     if (!parent)
   4231         return false;
   4232     if (parent->isSandboxed(SandboxSeamlessIframes))
   4233         return false;
   4234     if (child->isSrcdocDocument())
   4235         return true;
   4236     if (parent->securityOrigin()->canAccess(child->securityOrigin()))
   4237         return true;
   4238     return parent->securityOrigin()->canRequest(child->url());
   4239 }
   4240 
   4241 void Document::initSecurityContext()
   4242 {
   4243     initSecurityContext(DocumentInit(m_url, m_frame, m_import));
   4244 }
   4245 
   4246 void Document::initSecurityContext(const DocumentInit& initializer)
   4247 {
   4248     if (haveInitializedSecurityOrigin()) {
   4249         ASSERT(securityOrigin());
   4250         return;
   4251     }
   4252 
   4253     if (!initializer.hasSecurityContext()) {
   4254         // No source for a security context.
   4255         // This can occur via document.implementation.createDocument().
   4256         m_cookieURL = KURL(ParsedURLString, emptyString());
   4257         setSecurityOrigin(SecurityOrigin::createUnique());
   4258         setContentSecurityPolicy(ContentSecurityPolicy::create(this));
   4259         return;
   4260     }
   4261 
   4262     // In the common case, create the security context from the currently
   4263     // loading URL with a fresh content security policy.
   4264     m_cookieURL = m_url;
   4265     enforceSandboxFlags(initializer.sandboxFlags());
   4266     setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));
   4267     setContentSecurityPolicy(ContentSecurityPolicy::create(this));
   4268 
   4269     if (Settings* settings = initializer.settings()) {
   4270         if (!settings->webSecurityEnabled()) {
   4271             // Web security is turned off. We should let this document access every other document. This is used primary by testing
   4272             // harnesses for web sites.
   4273             securityOrigin()->grantUniversalAccess();
   4274         } else if (securityOrigin()->isLocal()) {
   4275             if (settings->allowUniversalAccessFromFileURLs()) {
   4276                 // Some clients want local URLs to have universal access, but that setting is dangerous for other clients.
   4277                 securityOrigin()->grantUniversalAccess();
   4278             } else if (!settings->allowFileAccessFromFileURLs()) {
   4279                 // Some clients want local URLs to have even tighter restrictions by default, and not be able to access other local files.
   4280                 // FIXME 81578: The naming of this is confusing. Files with restricted access to other local files
   4281                 // still can have other privileges that can be remembered, thereby not making them unique origins.
   4282                 securityOrigin()->enforceFilePathSeparation();
   4283             }
   4284         }
   4285     }
   4286 
   4287     Document* parentDocument = ownerElement() ? ownerElement()->document() : 0;
   4288     if (parentDocument && initializer.shouldTreatURLAsSrcdocDocument()) {
   4289         m_isSrcdocDocument = true;
   4290         setBaseURLOverride(parentDocument->baseURL());
   4291     }
   4292 
   4293     // FIXME: What happens if we inherit the security origin? This check may need to be later.
   4294     // <iframe seamless src="about:blank"> likely won't work as-is.
   4295     m_mayDisplaySeamlesslyWithParent = isEligibleForSeamless(parentDocument, this);
   4296 
   4297     if (!shouldInheritSecurityOriginFromOwner(m_url))
   4298         return;
   4299 
   4300     // If we do not obtain a meaningful origin from the URL, then we try to
   4301     // find one via the frame hierarchy.
   4302 
   4303     Frame* ownerFrame = initializer.ownerFrame();
   4304     if (!ownerFrame) {
   4305         didFailToInitializeSecurityOrigin();
   4306         return;
   4307     }
   4308 
   4309     if (isSandboxed(SandboxOrigin)) {
   4310         // If we're supposed to inherit our security origin from our owner,
   4311         // but we're also sandboxed, the only thing we inherit is the ability
   4312         // to load local resources. This lets about:blank iframes in file://
   4313         // URL documents load images and other resources from the file system.
   4314         if (ownerFrame->document()->securityOrigin()->canLoadLocalResources())
   4315             securityOrigin()->grantLoadLocalResources();
   4316         return;
   4317     }
   4318 
   4319     m_cookieURL = ownerFrame->document()->cookieURL();
   4320     // We alias the SecurityOrigins to match Firefox, see Bug 15313
   4321     // https://bugs.webkit.org/show_bug.cgi?id=15313
   4322     setSecurityOrigin(ownerFrame->document()->securityOrigin());
   4323 }
   4324 
   4325 void Document::initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders& headers)
   4326 {
   4327     if (m_frame && m_frame->tree()->parent() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
   4328         contentSecurityPolicy()->copyStateFrom(m_frame->tree()->parent()->document()->contentSecurityPolicy());
   4329     contentSecurityPolicy()->didReceiveHeaders(headers);
   4330 }
   4331 
   4332 void Document::didUpdateSecurityOrigin()
   4333 {
   4334     if (!m_frame)
   4335         return;
   4336     m_frame->script()->updateSecurityOrigin();
   4337 }
   4338 
   4339 bool Document::isContextThread() const
   4340 {
   4341     return isMainThread();
   4342 }
   4343 
   4344 void Document::statePopped(PassRefPtr<SerializedScriptValue> stateObject)
   4345 {
   4346     if (!frame())
   4347         return;
   4348 
   4349     // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we
   4350     // defer firing of popstate until we're in the complete state.
   4351     if (m_readyState == Complete)
   4352         enqueuePopstateEvent(stateObject);
   4353     else
   4354         m_pendingStateObject = stateObject;
   4355 }
   4356 
   4357 void Document::updateFocusAppearanceSoon(bool restorePreviousSelection)
   4358 {
   4359     m_updateFocusAppearanceRestoresSelection = restorePreviousSelection;
   4360     if (!m_updateFocusAppearanceTimer.isActive())
   4361         m_updateFocusAppearanceTimer.startOneShot(0);
   4362 }
   4363 
   4364 void Document::cancelFocusAppearanceUpdate()
   4365 {
   4366     m_updateFocusAppearanceTimer.stop();
   4367 }
   4368 
   4369 void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
   4370 {
   4371     Element* element = focusedElement();
   4372     if (!element)
   4373         return;
   4374     updateLayout();
   4375     if (element->isFocusable())
   4376         element->updateFocusAppearance(m_updateFocusAppearanceRestoresSelection);
   4377 }
   4378 
   4379 void Document::attachRange(Range* range)
   4380 {
   4381     ASSERT(!m_ranges.contains(range));
   4382     m_ranges.add(range);
   4383 }
   4384 
   4385 void Document::detachRange(Range* range)
   4386 {
   4387     // We don't ASSERT m_ranges.contains(range) to allow us to call this
   4388     // unconditionally to fix: https://bugs.webkit.org/show_bug.cgi?id=26044
   4389     m_ranges.remove(range);
   4390 }
   4391 
   4392 CanvasRenderingContext* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
   4393 {
   4394     HTMLCanvasElement* element = getCSSCanvasElement(name);
   4395     if (!element)
   4396         return 0;
   4397     element->setSize(IntSize(width, height));
   4398     return element->getContext(type);
   4399 }
   4400 
   4401 HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
   4402 {
   4403     RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, 0).iterator->value;
   4404     if (!element) {
   4405         element = HTMLCanvasElement::create(this);
   4406         element->setAccelerationDisabled(true);
   4407     }
   4408     return element.get();
   4409 }
   4410 
   4411 void Document::initDNSPrefetch()
   4412 {
   4413     Settings* settings = this->settings();
   4414 
   4415     m_haveExplicitlyDisabledDNSPrefetch = false;
   4416     m_isDNSPrefetchEnabled = settings && settings->dnsPrefetchingEnabled() && securityOrigin()->protocol() == "http";
   4417 
   4418     // Inherit DNS prefetch opt-out from parent frame
   4419     if (Document* parent = parentDocument()) {
   4420         if (!parent->isDNSPrefetchEnabled())
   4421             m_isDNSPrefetchEnabled = false;
   4422     }
   4423 }
   4424 
   4425 void Document::parseDNSPrefetchControlHeader(const String& dnsPrefetchControl)
   4426 {
   4427     if (equalIgnoringCase(dnsPrefetchControl, "on") && !m_haveExplicitlyDisabledDNSPrefetch) {
   4428         m_isDNSPrefetchEnabled = true;
   4429         return;
   4430     }
   4431 
   4432     m_isDNSPrefetchEnabled = false;
   4433     m_haveExplicitlyDisabledDNSPrefetch = true;
   4434 }
   4435 
   4436 void Document::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier)
   4437 {
   4438     if (!isContextThread()) {
   4439         postTask(AddConsoleMessageTask::create(source, level, message));
   4440         return;
   4441     }
   4442 
   4443     if (Page* page = this->page())
   4444         page->console()->addMessage(source, level, message, requestIdentifier, this);
   4445 }
   4446 
   4447 void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state, unsigned long requestIdentifier)
   4448 {
   4449     if (!isContextThread()) {
   4450         postTask(AddConsoleMessageTask::create(source, level, message));
   4451         return;
   4452     }
   4453 
   4454     if (Page* page = this->page())
   4455         page->console()->addMessage(source, level, message, sourceURL, lineNumber, 0, callStack, state, requestIdentifier);
   4456 }
   4457 
   4458 struct PerformTaskContext {
   4459     WTF_MAKE_NONCOPYABLE(PerformTaskContext); WTF_MAKE_FAST_ALLOCATED;
   4460 public:
   4461     PerformTaskContext(WeakPtr<Document> document, PassOwnPtr<ScriptExecutionContext::Task> task)
   4462         : documentReference(document)
   4463         , task(task)
   4464     {
   4465     }
   4466 
   4467     WeakPtr<Document> documentReference;
   4468     OwnPtr<ScriptExecutionContext::Task> task;
   4469 };
   4470 
   4471 void Document::didReceiveTask(void* untypedContext)
   4472 {
   4473     ASSERT(isMainThread());
   4474 
   4475     OwnPtr<PerformTaskContext> context = adoptPtr(static_cast<PerformTaskContext*>(untypedContext));
   4476     ASSERT(context);
   4477 
   4478     Document* document = context->documentReference.get();
   4479     if (!document)
   4480         return;
   4481 
   4482     Page* page = document->page();
   4483     if ((page && page->defersLoading()) || !document->m_pendingTasks.isEmpty()) {
   4484         document->m_pendingTasks.append(context->task.release());
   4485         return;
   4486     }
   4487 
   4488     context->task->performTask(document);
   4489 }
   4490 
   4491 void Document::postTask(PassOwnPtr<Task> task)
   4492 {
   4493     callOnMainThread(didReceiveTask, new PerformTaskContext(m_weakFactory.createWeakPtr(), task));
   4494 }
   4495 
   4496 void Document::pendingTasksTimerFired(Timer<Document>*)
   4497 {
   4498     while (!m_pendingTasks.isEmpty()) {
   4499         OwnPtr<Task> task = m_pendingTasks[0].release();
   4500         m_pendingTasks.remove(0);
   4501         task->performTask(this);
   4502     }
   4503 }
   4504 
   4505 void Document::suspendScheduledTasks(ActiveDOMObject::ReasonForSuspension reason)
   4506 {
   4507     ASSERT(!m_scheduledTasksAreSuspended);
   4508 
   4509     suspendScriptedAnimationControllerCallbacks();
   4510     suspendActiveDOMObjects(reason);
   4511     scriptRunner()->suspend();
   4512     m_pendingTasksTimer.stop();
   4513     if (m_parser)
   4514         m_parser->suspendScheduledTasks();
   4515 
   4516     m_scheduledTasksAreSuspended = true;
   4517 }
   4518 
   4519 void Document::resumeScheduledTasks()
   4520 {
   4521     ASSERT(m_scheduledTasksAreSuspended);
   4522 
   4523     if (m_parser)
   4524         m_parser->resumeScheduledTasks();
   4525     if (!m_pendingTasks.isEmpty())
   4526         m_pendingTasksTimer.startOneShot(0);
   4527     scriptRunner()->resume();
   4528     resumeActiveDOMObjects();
   4529     resumeScriptedAnimationControllerCallbacks();
   4530 
   4531     m_scheduledTasksAreSuspended = false;
   4532 }
   4533 
   4534 void Document::suspendScriptedAnimationControllerCallbacks()
   4535 {
   4536     if (m_scriptedAnimationController)
   4537         m_scriptedAnimationController->suspend();
   4538 }
   4539 
   4540 void Document::resumeScriptedAnimationControllerCallbacks()
   4541 {
   4542     if (m_scriptedAnimationController)
   4543         m_scriptedAnimationController->resume();
   4544 }
   4545 
   4546 String Document::displayStringModifiedByEncoding(const String& str) const
   4547 {
   4548     if (m_decoder)
   4549         return m_decoder->encoding().displayString(str.impl());
   4550     return str;
   4551 }
   4552 
   4553 PassRefPtr<StringImpl> Document::displayStringModifiedByEncoding(PassRefPtr<StringImpl> str) const
   4554 {
   4555     if (m_decoder)
   4556         return m_decoder->encoding().displayString(str);
   4557     return str;
   4558 }
   4559 
   4560 template <typename CharacterType>
   4561 void Document::displayBufferModifiedByEncodingInternal(CharacterType* buffer, unsigned len) const
   4562 {
   4563     if (m_decoder)
   4564         m_decoder->encoding().displayBuffer(buffer, len);
   4565 }
   4566 
   4567 // Generate definitions for both character types
   4568 template void Document::displayBufferModifiedByEncodingInternal<LChar>(LChar*, unsigned) const;
   4569 template void Document::displayBufferModifiedByEncodingInternal<UChar>(UChar*, unsigned) const;
   4570 
   4571 void Document::enqueuePageshowEvent(PageshowEventPersistence persisted)
   4572 {
   4573     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously.
   4574     dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, persisted), this);
   4575 }
   4576 
   4577 void Document::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
   4578 {
   4579     enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
   4580 }
   4581 
   4582 void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
   4583 {
   4584     if (!ContextFeatures::pushStateEnabled(this))
   4585         return;
   4586 
   4587     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
   4588     dispatchWindowEvent(PopStateEvent::create(stateObject, domWindow() ? domWindow()->history() : 0));
   4589 }
   4590 
   4591 void Document::addToTopLayer(Element* element, const Element* before)
   4592 {
   4593     if (element->isInTopLayer())
   4594         return;
   4595 
   4596     ASSERT(!m_topLayerElements.contains(element));
   4597     ASSERT(!before || m_topLayerElements.contains(before));
   4598     if (before) {
   4599         size_t beforePosition = m_topLayerElements.find(before);
   4600         m_topLayerElements.insert(beforePosition, element);
   4601     } else {
   4602         m_topLayerElements.append(element);
   4603     }
   4604     element->setIsInTopLayer(true);
   4605 }
   4606 
   4607 void Document::removeFromTopLayer(Element* element)
   4608 {
   4609     if (!element->isInTopLayer())
   4610         return;
   4611     size_t position = m_topLayerElements.find(element);
   4612     ASSERT(position != notFound);
   4613     m_topLayerElements.remove(position);
   4614     element->setIsInTopLayer(false);
   4615 }
   4616 
   4617 void Document::webkitExitPointerLock()
   4618 {
   4619     if (!page())
   4620         return;
   4621     if (Element* target = page()->pointerLockController()->element()) {
   4622         if (target->document() != this)
   4623             return;
   4624     }
   4625     page()->pointerLockController()->requestPointerUnlock();
   4626 }
   4627 
   4628 Element* Document::webkitPointerLockElement() const
   4629 {
   4630     if (!page() || page()->pointerLockController()->lockPending())
   4631         return 0;
   4632     if (Element* element = page()->pointerLockController()->element()) {
   4633         if (element->document() == this)
   4634             return element;
   4635     }
   4636     return 0;
   4637 }
   4638 
   4639 void Document::decrementLoadEventDelayCount()
   4640 {
   4641     ASSERT(m_loadEventDelayCount);
   4642     --m_loadEventDelayCount;
   4643 
   4644     if (frame() && !m_loadEventDelayCount && !m_loadEventDelayTimer.isActive())
   4645         m_loadEventDelayTimer.startOneShot(0);
   4646 }
   4647 
   4648 void Document::loadEventDelayTimerFired(Timer<Document>*)
   4649 {
   4650     if (frame())
   4651         frame()->loader()->checkCompleted();
   4652 }
   4653 
   4654 int Document::requestAnimationFrame(PassRefPtr<RequestAnimationFrameCallback> callback)
   4655 {
   4656     if (!m_scriptedAnimationController) {
   4657         m_scriptedAnimationController = ScriptedAnimationController::create(this);
   4658         // We need to make sure that we don't start up the animation controller on a background tab, for example.
   4659         if (!page())
   4660             m_scriptedAnimationController->suspend();
   4661     }
   4662 
   4663     return m_scriptedAnimationController->registerCallback(callback);
   4664 }
   4665 
   4666 void Document::cancelAnimationFrame(int id)
   4667 {
   4668     if (!m_scriptedAnimationController)
   4669         return;
   4670     m_scriptedAnimationController->cancelCallback(id);
   4671 }
   4672 
   4673 void Document::serviceScriptedAnimations(double monotonicAnimationStartTime)
   4674 {
   4675     if (!m_scriptedAnimationController)
   4676         return;
   4677     m_scriptedAnimationController->serviceScriptedAnimations(monotonicAnimationStartTime);
   4678 }
   4679 
   4680 PassRefPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const
   4681 {
   4682     // FIXME: It's not clear from the documentation at
   4683     // http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html
   4684     // when this method should throw and nor is it by inspection of iOS behavior. It would be nice to verify any cases where it throws under iOS
   4685     // and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819
   4686     Frame* frame = window ? window->frame() : this->frame();
   4687     return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force);
   4688 }
   4689 
   4690 static void wheelEventHandlerCountChanged(Document* document)
   4691 {
   4692     Page* page = document->page();
   4693     if (!page)
   4694         return;
   4695 
   4696     ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
   4697     if (!scrollingCoordinator)
   4698         return;
   4699 
   4700     FrameView* frameView = document->view();
   4701     if (!frameView)
   4702         return;
   4703 
   4704     scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
   4705 }
   4706 
   4707 void Document::didAddWheelEventHandler()
   4708 {
   4709     ++m_wheelEventHandlerCount;
   4710     Frame* mainFrame = page() ? page()->mainFrame() : 0;
   4711     if (mainFrame)
   4712         mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
   4713 
   4714     wheelEventHandlerCountChanged(this);
   4715 }
   4716 
   4717 void Document::didRemoveWheelEventHandler()
   4718 {
   4719     ASSERT(m_wheelEventHandlerCount > 0);
   4720     --m_wheelEventHandlerCount;
   4721     Frame* mainFrame = page() ? page()->mainFrame() : 0;
   4722     if (mainFrame)
   4723         mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
   4724 
   4725     wheelEventHandlerCountChanged(this);
   4726 }
   4727 
   4728 void Document::didAddTouchEventHandler(Node* handler)
   4729 {
   4730     if (!m_touchEventTargets.get())
   4731         m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
   4732     m_touchEventTargets->add(handler);
   4733     if (Document* parent = parentDocument()) {
   4734         parent->didAddTouchEventHandler(this);
   4735         return;
   4736     }
   4737     if (Page* page = this->page()) {
   4738         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   4739             scrollingCoordinator->touchEventTargetRectsDidChange(this);
   4740         if (m_touchEventTargets->size() == 1)
   4741             page->chrome().client()->needTouchEvents(true);
   4742     }
   4743 }
   4744 
   4745 void Document::didRemoveTouchEventHandler(Node* handler)
   4746 {
   4747     if (!m_touchEventTargets.get())
   4748         return;
   4749     ASSERT(m_touchEventTargets->contains(handler));
   4750     m_touchEventTargets->remove(handler);
   4751     if (Document* parent = parentDocument()) {
   4752         parent->didRemoveTouchEventHandler(this);
   4753         return;
   4754     }
   4755 
   4756     Page* page = this->page();
   4757     if (!page)
   4758         return;
   4759     if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
   4760         scrollingCoordinator->touchEventTargetRectsDidChange(this);
   4761     if (m_touchEventTargets->size())
   4762         return;
   4763     for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
   4764         if (frame->document() && frame->document()->hasTouchEventHandlers())
   4765             return;
   4766     }
   4767     page->chrome().client()->needTouchEvents(false);
   4768 }
   4769 
   4770 void Document::didRemoveEventTargetNode(Node* handler)
   4771 {
   4772     if (m_touchEventTargets) {
   4773         m_touchEventTargets->removeAll(handler);
   4774         if ((handler == this || m_touchEventTargets->isEmpty()) && parentDocument())
   4775             parentDocument()->didRemoveEventTargetNode(this);
   4776     }
   4777 }
   4778 
   4779 void Document::resetLastHandledUserGestureTimestamp()
   4780 {
   4781     m_lastHandledUserGestureTimestamp = currentTime();
   4782 }
   4783 
   4784 HTMLIFrameElement* Document::seamlessParentIFrame() const
   4785 {
   4786     if (!shouldDisplaySeamlesslyWithParent())
   4787         return 0;
   4788 
   4789     return toHTMLIFrameElement(this->ownerElement());
   4790 }
   4791 
   4792 bool Document::shouldDisplaySeamlesslyWithParent() const
   4793 {
   4794     if (!RuntimeEnabledFeatures::seamlessIFramesEnabled())
   4795         return false;
   4796     HTMLFrameOwnerElement* ownerElement = this->ownerElement();
   4797     if (!ownerElement)
   4798         return false;
   4799     return m_mayDisplaySeamlesslyWithParent && ownerElement->hasTagName(iframeTag) && ownerElement->fastHasAttribute(seamlessAttr);
   4800 }
   4801 
   4802 DocumentLoader* Document::loader() const
   4803 {
   4804     if (!m_frame)
   4805         return 0;
   4806 
   4807     DocumentLoader* loader = m_frame->loader()->documentLoader();
   4808     if (!loader)
   4809         return 0;
   4810 
   4811     if (m_frame->document() != this)
   4812         return 0;
   4813 
   4814     return loader;
   4815 }
   4816 
   4817 IntSize Document::viewportSize() const
   4818 {
   4819     if (!view())
   4820         return IntSize();
   4821     return view()->visibleContentRect(ScrollableArea::IncludeScrollbars).size();
   4822 }
   4823 
   4824 IntSize Document::initialViewportSize() const
   4825 {
   4826     if (!view())
   4827         return IntSize();
   4828     return view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
   4829 }
   4830 
   4831 Node* eventTargetNodeForDocument(Document* doc)
   4832 {
   4833     if (!doc)
   4834         return 0;
   4835     Node* node = doc->focusedElement();
   4836     if (!node && doc->isPluginDocument()) {
   4837         PluginDocument* pluginDocument = toPluginDocument(doc);
   4838         node =  pluginDocument->pluginNode();
   4839     }
   4840     if (!node && doc->isHTMLDocument())
   4841         node = doc->body();
   4842     if (!node)
   4843         node = doc->documentElement();
   4844     return node;
   4845 }
   4846 
   4847 void Document::adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>& quads, RenderObject* renderer)
   4848 {
   4849     if (!view())
   4850         return;
   4851 
   4852     LayoutRect visibleContentRect = view()->visibleContentRect();
   4853     for (size_t i = 0; i < quads.size(); ++i) {
   4854         quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
   4855         adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
   4856     }
   4857 }
   4858 
   4859 void Document::adjustFloatRectForScrollAndAbsoluteZoom(FloatRect& rect, RenderObject* renderer)
   4860 {
   4861     if (!view())
   4862         return;
   4863 
   4864     LayoutRect visibleContentRect = view()->visibleContentRect();
   4865     rect.move(-visibleContentRect.x(), -visibleContentRect.y());
   4866     adjustFloatRectForAbsoluteZoom(rect, renderer);
   4867 }
   4868 
   4869 bool Document::hasActiveParser()
   4870 {
   4871     return m_activeParserCount || (m_parser && m_parser->processingData());
   4872 }
   4873 
   4874 void Document::decrementActiveParserCount()
   4875 {
   4876     --m_activeParserCount;
   4877     if (!frame())
   4878         return;
   4879     // FIXME: This should always be enabled, but it seems to cause
   4880     // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
   4881     // see http://webkit.org/b/110554 and http://webkit.org/b/110401
   4882     loader()->checkLoadComplete();
   4883     frame()->loader()->checkLoadComplete();
   4884 }
   4885 
   4886 void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
   4887 {
   4888     m_contextFeatures = features;
   4889 }
   4890 
   4891 static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject* obj2)
   4892 {
   4893     if (!obj1 || !obj2)
   4894         return 0;
   4895 
   4896     for (RenderObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
   4897         for (RenderObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
   4898             if (currObj1 == currObj2)
   4899                 return currObj1;
   4900         }
   4901     }
   4902 
   4903     return 0;
   4904 }
   4905 
   4906 void Document::updateHoverActiveState(const HitTestRequest& request, Element* innerElement, const PlatformMouseEvent* event)
   4907 {
   4908     ASSERT(!request.readOnly());
   4909 
   4910     Element* innerElementInDocument = innerElement;
   4911     while (innerElementInDocument && innerElementInDocument->document() != this) {
   4912         innerElementInDocument->document()->updateHoverActiveState(request, innerElementInDocument, event);
   4913         innerElementInDocument = innerElementInDocument->document()->ownerElement();
   4914     }
   4915 
   4916     Element* oldActiveElement = activeElement();
   4917     if (oldActiveElement && !request.active()) {
   4918         // We are clearing the :active chain because the mouse has been released.
   4919         for (RenderObject* curr = oldActiveElement->renderer(); curr; curr = curr->parent()) {
   4920             if (curr->node()) {
   4921                 ASSERT(!curr->node()->isTextNode());
   4922                 curr->node()->setActive(false);
   4923                 m_userActionElements.setInActiveChain(curr->node(), false);
   4924             }
   4925         }
   4926         setActiveElement(0);
   4927     } else {
   4928         Element* newActiveElement = innerElementInDocument;
   4929         if (!oldActiveElement && newActiveElement && request.active() && !request.touchMove()) {
   4930             // We are setting the :active chain and freezing it. If future moves happen, they
   4931             // will need to reference this chain.
   4932             for (RenderObject* curr = newActiveElement->renderer(); curr; curr = curr->parent()) {
   4933                 if (curr->node() && !curr->isText())
   4934                     m_userActionElements.setInActiveChain(curr->node(), true);
   4935             }
   4936 
   4937             setActiveElement(newActiveElement);
   4938         }
   4939     }
   4940     // If the mouse has just been pressed, set :active on the chain. Those (and only those)
   4941     // nodes should remain :active until the mouse is released.
   4942     bool allowActiveChanges = !oldActiveElement && activeElement();
   4943 
   4944     // If the mouse is down and if this is a mouse move event, we want to restrict changes in
   4945     // :hover/:active to only apply to elements that are in the :active chain that we froze
   4946     // at the time the mouse went down.
   4947     bool mustBeInActiveChain = request.active() && request.move();
   4948 
   4949     RefPtr<Node> oldHoverNode = hoverNode();
   4950 
   4951     // A touch release does not set a new hover target; setting the element we're working with to 0
   4952     // will clear the chain of hovered elements all the way to the top of the tree.
   4953     if (request.touchRelease())
   4954         innerElementInDocument = 0;
   4955 
   4956     // Check to see if the hovered node has changed.
   4957     // If it hasn't, we do not need to do anything.
   4958     Node* newHoverNode = innerElementInDocument;
   4959     while (newHoverNode && !newHoverNode->renderer())
   4960         newHoverNode = newHoverNode->parentOrShadowHostNode();
   4961 
   4962     // Update our current hover node.
   4963     setHoverNode(newHoverNode);
   4964 
   4965     // We have two different objects. Fetch their renderers.
   4966     RenderObject* oldHoverObj = oldHoverNode ? oldHoverNode->renderer() : 0;
   4967     RenderObject* newHoverObj = newHoverNode ? newHoverNode->renderer() : 0;
   4968 
   4969     // Locate the common ancestor render object for the two renderers.
   4970     RenderObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj);
   4971 
   4972     Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
   4973     Vector<RefPtr<Node>, 32> nodesToAddToChain;
   4974 
   4975     if (oldHoverObj != newHoverObj) {
   4976         // If the old hovered node is not nil but it's renderer is, it was probably detached as part of the :hover style
   4977         // (for instance by setting display:none in the :hover pseudo-class). In this case, the old hovered element (and its ancestors)
   4978         // must be updated, to ensure it's normal style is re-applied.
   4979         if (oldHoverNode && !oldHoverObj) {
   4980             for (Node* node = oldHoverNode.get(); node; node = node->parentNode()) {
   4981                 if (!mustBeInActiveChain || (node->isElementNode() && toElement(node)->inActiveChain()))
   4982                     nodesToRemoveFromChain.append(node);
   4983             }
   4984 
   4985         }
   4986 
   4987         // The old hover path only needs to be cleared up to (and not including) the common ancestor;
   4988         for (RenderObject* curr = oldHoverObj; curr && curr != ancestor; curr = curr->hoverAncestor()) {
   4989             if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
   4990                 nodesToRemoveFromChain.append(curr->node());
   4991         }
   4992     }
   4993 
   4994     // Now set the hover state for our new object up to the root.
   4995     for (RenderObject* curr = newHoverObj; curr; curr = curr->hoverAncestor()) {
   4996         if (curr->node() && !curr->isText() && (!mustBeInActiveChain || curr->node()->inActiveChain()))
   4997             nodesToAddToChain.append(curr->node());
   4998     }
   4999 
   5000     // mouseenter and mouseleave events do not bubble, so they are dispatched iff there is a capturing
   5001     // event handler on an ancestor or a normal event handler on the element itself. This special
   5002     // handling is necessary to avoid O(n^2) capturing event handler checks. We'll check the previously
   5003     // hovered node's ancestor tree for 'mouseleave' handlers here, then check the newly hovered node's
   5004     // ancestor tree for 'mouseenter' handlers after dispatching the 'mouseleave' events (as the handler
   5005     // for 'mouseleave' might set a capturing 'mouseenter' handler, odd as that might be).
   5006     bool ancestorHasCapturingMouseleaveListener = false;
   5007     if (event && newHoverNode != oldHoverNode.get()) {
   5008         for (Node* node = oldHoverNode.get(); node; node = node->parentOrShadowHostNode()) {
   5009             if (node->hasCapturingEventListeners(eventNames().mouseleaveEvent)) {
   5010                 ancestorHasCapturingMouseleaveListener = true;
   5011                 break;
   5012             }
   5013         }
   5014     }
   5015 
   5016     size_t removeCount = nodesToRemoveFromChain.size();
   5017     for (size_t i = 0; i < removeCount; ++i) {
   5018         nodesToRemoveFromChain[i]->setHovered(false);
   5019         if (event && (ancestorHasCapturingMouseleaveListener || nodesToRemoveFromChain[i]->hasEventListeners(eventNames().mouseleaveEvent)))
   5020             nodesToRemoveFromChain[i]->dispatchMouseEvent(*event, eventNames().mouseleaveEvent, 0, newHoverNode);
   5021     }
   5022 
   5023     bool ancestorHasCapturingMouseenterListener = false;
   5024     if (event && newHoverNode != oldHoverNode.get()) {
   5025         for (Node* node = newHoverNode; node; node = node->parentOrShadowHostNode()) {
   5026             if (node->hasCapturingEventListeners(eventNames().mouseenterEvent)) {
   5027                 ancestorHasCapturingMouseenterListener = true;
   5028                 break;
   5029             }
   5030         }
   5031     }
   5032 
   5033     bool sawCommonAncestor = false;
   5034     size_t addCount = nodesToAddToChain.size();
   5035     for (size_t i = 0; i < addCount; ++i) {
   5036         // Elements past the common ancestor do not change hover state, but might change active state.
   5037         if (ancestor && nodesToAddToChain[i] == ancestor->node())
   5038             sawCommonAncestor = true;
   5039         if (allowActiveChanges)
   5040             nodesToAddToChain[i]->setActive(true);
   5041         if (!sawCommonAncestor) {
   5042             nodesToAddToChain[i]->setHovered(true);
   5043             if (event && (ancestorHasCapturingMouseenterListener || nodesToAddToChain[i]->hasEventListeners(eventNames().mouseenterEvent)))
   5044                 nodesToAddToChain[i]->dispatchMouseEvent(*event, eventNames().mouseenterEvent, 0, oldHoverNode.get());
   5045         }
   5046     }
   5047 
   5048     updateStyleIfNeeded();
   5049 }
   5050 
   5051 bool Document::haveStylesheetsLoaded() const
   5052 {
   5053     return !m_styleSheetCollection->hasPendingSheets() || m_ignorePendingStylesheets;
   5054 }
   5055 
   5056 Locale& Document::getCachedLocale(const AtomicString& locale)
   5057 {
   5058     AtomicString localeKey = locale;
   5059     if (locale.isEmpty() || !RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
   5060         localeKey = defaultLanguage();
   5061     LocaleIdentifierToLocaleMap::AddResult result = m_localeCache.add(localeKey, nullptr);
   5062     if (result.isNewEntry)
   5063         result.iterator->value = Locale::create(localeKey);
   5064     return *(result.iterator->value);
   5065 }
   5066 
   5067 Document* Document::ensureTemplateDocument()
   5068 {
   5069     if (const Document* document = templateDocument())
   5070         return const_cast<Document*>(document);
   5071 
   5072     if (isHTMLDocument())
   5073         m_templateDocument = HTMLDocument::create(DocumentInit(blankURL()).withRegistrationContext(registrationContext()));
   5074     else
   5075         m_templateDocument = Document::create(DocumentInit(blankURL()));
   5076 
   5077     m_templateDocument->setTemplateDocumentHost(this); // balanced in dtor.
   5078 
   5079     return m_templateDocument.get();
   5080 }
   5081 
   5082 PassRefPtr<FontLoader> Document::fontloader()
   5083 {
   5084     if (!m_fontloader)
   5085         m_fontloader = FontLoader::create(this);
   5086     return m_fontloader;
   5087 }
   5088 
   5089 void Document::didAssociateFormControl(Element* element)
   5090 {
   5091     if (!frame() || !frame()->page())
   5092         return;
   5093     m_associatedFormControls.add(element);
   5094     if (!m_didAssociateFormControlsTimer.isActive())
   5095         m_didAssociateFormControlsTimer.startOneShot(0);
   5096 }
   5097 
   5098 void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
   5099 {
   5100     ASSERT_UNUSED(timer, timer == &m_didAssociateFormControlsTimer);
   5101     if (!frame() || !frame()->page())
   5102         return;
   5103 
   5104     Vector<RefPtr<Element> > associatedFormControls;
   5105     copyToVector(m_associatedFormControls, associatedFormControls);
   5106 
   5107     frame()->page()->chrome().client()->didAssociateFormControls(associatedFormControls);
   5108     m_associatedFormControls.clear();
   5109 }
   5110 
   5111 PassOwnPtr<LifecycleNotifier> Document::createLifecycleNotifier()
   5112 {
   5113     return DocumentLifecycleNotifier::create(this);
   5114 }
   5115 
   5116 DocumentLifecycleNotifier* Document::lifecycleNotifier()
   5117 {
   5118     return static_cast<DocumentLifecycleNotifier*>(ScriptExecutionContext::lifecycleNotifier());
   5119 }
   5120 
   5121 } // namespace WebCore
   5122