Commit message: None
CVE: CVE-2015-6768
CWE: CWE-264
Vulnerability description: The DOM implementation in Google Chrome before 47.0.2526.73 allows remote attackers to bypass the Same Origin Policy via unspecified vectors, a different vulnerability than CVE-2015-6770.

Project: Chrome

    AutofocusTask() { }

Project: Chrome

DEFINE_TRACE(Document)
{
#if ENABLE(OILPAN)
    visitor->trace(m_importsController);
    visitor->trace(m_docType);
    visitor->trace(m_implementation);
    visitor->trace(m_autofocusElement);
    visitor->trace(m_focusedElement);
    visitor->trace(m_hoverNode);
    visitor->trace(m_activeHoverElement);
    visitor->trace(m_documentElement);
    visitor->trace(m_titleElement);
    visitor->trace(m_axObjectCache);
    visitor->trace(m_markers);
    visitor->trace(m_cssTarget);
    visitor->trace(m_currentScriptStack);
    visitor->trace(m_scriptRunner);
    visitor->trace(m_listsInvalidatedAtDocument);
    for (int i = 0; i < numNodeListInvalidationTypes; ++i)
        visitor->trace(m_nodeLists[i]);
    visitor->trace(m_topLayerElements);
    visitor->trace(m_elemSheet);
    visitor->trace(m_nodeIterators);
    visitor->trace(m_ranges);
    visitor->trace(m_styleEngine);
    visitor->trace(m_formController);
    visitor->trace(m_visitedLinkState);
    visitor->trace(m_frame);
    visitor->trace(m_domWindow);
    visitor->trace(m_fetcher);
    visitor->trace(m_parser);
    visitor->trace(m_contextFeatures);
    visitor->trace(m_styleSheetList);
    visitor->trace(m_documentTiming);
    visitor->trace(m_mediaQueryMatcher);
    visitor->trace(m_scriptedAnimationController);
    visitor->trace(m_scriptedIdleTaskController);
    visitor->trace(m_taskRunner);
    visitor->trace(m_textAutosizer);
    visitor->trace(m_registrationContext);
    visitor->trace(m_customElementMicrotaskRunQueue);
    visitor->trace(m_elementDataCache);
    visitor->trace(m_associatedFormControls);
    visitor->trace(m_useElementsNeedingUpdate);
    visitor->trace(m_layerUpdateSVGFilterElements);
    visitor->trace(m_timers);
    visitor->trace(m_templateDocument);
    visitor->trace(m_templateDocumentHost);
    visitor->trace(m_visibilityObservers);
    visitor->trace(m_userActionElements);
    visitor->trace(m_svgExtensions);
    visitor->trace(m_timeline);
    visitor->trace(m_compositorPendingAnimations);
    visitor->trace(m_contextDocument);
    visitor->trace(m_canvasFontCache);
    visitor->trace(m_intersectionObserverController);
    visitor->trace(m_intersectionObserverData);
    WillBeHeapSupplementable<Document>::trace(visitor);
#endif
    TreeScope::trace(visitor);
    ContainerNode::trace(visitor);
    ExecutionContext::trace(visitor);
    DocumentLifecycleNotifier::trace(visitor);
    SecurityContext::trace(visitor);
}

Project: Chrome

Document::Document(const DocumentInit& initializer, DocumentClassFlags documentClasses)
    : ContainerNode(0, CreateDocument)
    , TreeScope(*this)
    , m_hasNodesWithPlaceholderStyle(false)
    , m_evaluateMediaQueriesOnStyleRecalc(false)
    , m_pendingSheetLayout(NoLayoutWithPendingSheets)
    , m_frame(initializer.frame())
    , m_domWindow(m_frame ? m_frame->localDOMWindow() : 0)
    , m_importsController(initializer.importsController())
    , m_activeParserCount(0)
    , m_contextFeatures(ContextFeatures::defaultSwitch())
    , m_wellFormed(false)
    , m_printing(false)
    , m_wasPrinting(false)
    , m_paginatedForScreen(false)
    , m_compatibilityMode(NoQuirksMode)
    , m_compatibilityModeLocked(false)
    , m_executeScriptsWaitingForResourcesTask(CancellableTaskFactory::create(this, &Document::executeScriptsWaitingForResources))
    , m_hasAutofocused(false)
    , m_clearFocusedElementTimer(this, &Document::clearFocusedElementTimerFired)
    , m_domTreeVersion(++s_globalTreeVersion)
    , m_styleVersion(0)
    , m_listenerTypes(0)
    , m_mutationObserverTypes(0)
    , m_visitedLinkState(VisitedLinkState::create(*this))
    , m_visuallyOrdered(false)
    , m_readyState(Complete)
    , m_parsingState(FinishedParsing)
    , m_gotoAnchorNeededAfterStylesheetsLoad(false)
    , m_containsValidityStyleRules(false)
    , m_containsPlugins(false)
    , m_updateFocusAppearanceSelectionBahavior(SelectionBehaviorOnFocus::Reset)
    , m_ignoreDestructiveWriteCount(0)
    , m_markers(adoptPtrWillBeNoop(new DocumentMarkerController))
    , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
    , m_cssTarget(nullptr)
    , m_loadEventProgress(LoadEventNotRun)
    , m_startTime(currentTime())
    , m_scriptRunner(ScriptRunner::create(this))
    , m_xmlVersion("1.0")
    , m_xmlStandalone(StandaloneUnspecified)
    , m_hasXMLDeclaration(0)
    , m_designMode(false)
    , m_isRunningExecCommand(false)
    , m_hasAnnotatedRegions(false)
    , m_annotatedRegionsDirty(false)
    , m_useSecureKeyboardEntryWhenActive(false)
    , m_documentClasses(documentClasses)
    , m_isViewSource(false)
    , m_sawElementsInKnownNamespaces(false)
    , m_isSrcdocDocument(false)
    , m_isMobileDocument(false)
    , m_layoutView(0)
#if !ENABLE(OILPAN)
    , m_weakFactory(this)
#endif
    , m_contextDocument(initializer.contextDocument())
    , m_hasFullscreenSupplement(false)
    , m_loadEventDelayCount(0)
    , m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
    , m_pluginLoadingTimer(this, &Document::pluginLoadingTimerFired)
    , m_documentTiming(*this)
    , m_writeRecursionIsTooDeep(false)
    , m_writeRecursionDepth(0)
    , m_taskRunner(MainThreadTaskRunner::create(this))
    , m_registrationContext(initializer.registrationContext(this))
    , m_elementDataCacheClearTimer(this, &Document::elementDataCacheClearTimerFired)
    , m_timeline(AnimationTimeline::create(this))
    , m_templateDocumentHost(nullptr)
    , m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
    , m_timers(timerTaskRunner()->adoptClone())
    , m_hasViewportUnits(false)
    , m_parserSyncPolicy(AllowAsynchronousParsing)
    , m_nodeCount(0)
{
    if (m_frame) {
        ASSERT(m_frame->page());
        provideContextFeaturesToDocumentFrom(*this, *m_frame->page());

        m_fetcher = m_frame->loader().documentLoader()->fetcher();
        FrameFetchContext::provideDocumentToContext(m_fetcher->context(), this);
    } else if (m_importsController) {
        m_fetcher = FrameFetchContext::createContextAndFetcher(nullptr);
        FrameFetchContext::provideDocumentToContext(m_fetcher->context(), this);
    } else {
        m_fetcher = ResourceFetcher::create(nullptr);
    }

    if (initializer.shouldSetURL())
        setURL(initializer.url());

    initSecurityContext(initializer);
    initDNSPrefetch();

#if !ENABLE(OILPAN)
    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
        m_nodeListCounts[i] = 0;
#endif

    InstanceCounters::incrementCounter(InstanceCounters::DocumentCounter);

    m_lifecycle.advanceTo(DocumentLifecycle::Inactive);

    m_styleEngine = StyleEngine::create(*this);

    ASSERT(!parentDocument() || !parentDocument()->activeDOMObjectsAreSuspended());

    liveDocumentSet().add(this);
}

Project: Chrome

    ParseQualifiedNameResult() { }

Project: Chrome

    explicit ParseQualifiedNameResult(QualifiedNameStatus status) : status(status) { }

Project: Chrome

    ParseQualifiedNameResult(QualifiedNameStatus status, UChar32 character) : status(status), character(character) { }

Project: Chrome

static bool acceptsEditingFocus(const Element& element)
{
    ASSERT(element.hasEditableStyle());

    return element.document().frame() && element.rootEditableElement();
}

Project: Chrome

const OriginAccessEntry& Document::accessEntryFromURL()
{
    if (!m_accessEntryFromURL) {
        m_accessEntryFromURL = adoptPtr(new OriginAccessEntry(url().protocol(), url().host(), OriginAccessEntry::AllowRegisterableDomains));
    }
    return *m_accessEntryFromURL;
}

Project: Chrome

SVGDocumentExtensions& Document::accessSVGExtensions()
{
    if (!m_svgExtensions)
        m_svgExtensions = adoptPtrWillBeNoop(new SVGDocumentExtensions(this));
    return *m_svgExtensions;
}

Project: Chrome

void Document::activeChainNodeDetached(Element& element)
{
    if (!m_activeHoverElement)
        return;

    if (element != m_activeHoverElement)
        return;

    Node* activeNode = ComposedTreeTraversal::parent(element);
    while (activeNode && activeNode->isElementNode() && !activeNode->layoutObject())
        activeNode = ComposedTreeTraversal::parent(*activeNode);

    m_activeHoverElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
}

Project: Chrome

Element* Document::activeElement() const
{
    if (Element* element = adjustedFocusedElement())
        return element;
    return body();
}

Project: Chrome

void Document::addConsoleMessage(PassRefPtrWillBeRawPtr<ConsoleMessage> consoleMessage)
{
    if (!isContextThread()) {
        m_taskRunner->postTask(BLINK_FROM_HERE, AddConsoleMessageTask::create(consoleMessage->source(), consoleMessage->level(), consoleMessage->message()));
        return;
    }

    if (!m_frame)
        return;

    if (!consoleMessage->scriptState() && consoleMessage->url().isNull() && !consoleMessage->lineNumber()) {
        consoleMessage->setURL(url().string());
        if (!isInDocumentWrite() && scriptableDocumentParser()) {
            ScriptableDocumentParser* parser = scriptableDocumentParser();
            if (parser->isParsingAtLineNumber())
                consoleMessage->setLineNumber(parser->lineNumber().oneBasedInt());
        }
    }
    m_frame->console().addMessage(consoleMessage);
}

Project: Chrome

void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
{
    if (eventType == EventTypeNames::DOMSubtreeModified) {
        UseCounter::count(*this, UseCounter::DOMSubtreeModifiedEvent);
        addMutationEventListenerTypeIfEnabled(DOMSUBTREEMODIFIED_LISTENER);
    } else if (eventType == EventTypeNames::DOMNodeInserted) {
        UseCounter::count(*this, UseCounter::DOMNodeInsertedEvent);
        addMutationEventListenerTypeIfEnabled(DOMNODEINSERTED_LISTENER);
    } else if (eventType == EventTypeNames::DOMNodeRemoved) {
        UseCounter::count(*this, UseCounter::DOMNodeRemovedEvent);
        addMutationEventListenerTypeIfEnabled(DOMNODEREMOVED_LISTENER);
    } else if (eventType == EventTypeNames::DOMNodeRemovedFromDocument) {
        UseCounter::count(*this, UseCounter::DOMNodeRemovedFromDocumentEvent);
        addMutationEventListenerTypeIfEnabled(DOMNODEREMOVEDFROMDOCUMENT_LISTENER);
    } else if (eventType == EventTypeNames::DOMNodeInsertedIntoDocument) {
        UseCounter::count(*this, UseCounter::DOMNodeInsertedIntoDocumentEvent);
        addMutationEventListenerTypeIfEnabled(DOMNODEINSERTEDINTODOCUMENT_LISTENER);
    } else if (eventType == EventTypeNames::DOMCharacterDataModified) {
        UseCounter::count(*this, UseCounter::DOMCharacterDataModifiedEvent);
        addMutationEventListenerTypeIfEnabled(DOMCHARACTERDATAMODIFIED_LISTENER);
    } else if (eventType == EventTypeNames::webkitAnimationStart || eventType == EventTypeNames::animationstart) {
        addListenerType(ANIMATIONSTART_LISTENER);
    } else if (eventType == EventTypeNames::webkitAnimationEnd || eventType == EventTypeNames::animationend) {
        addListenerType(ANIMATIONEND_LISTENER);
    } else if (eventType == EventTypeNames::webkitAnimationIteration || eventType == EventTypeNames::animationiteration) {
        addListenerType(ANIMATIONITERATION_LISTENER);
        if (view()) {
            view()->scheduleAnimation();
        }
    } else if (eventType == EventTypeNames::webkitTransitionEnd || eventType == EventTypeNames::transitionend) {
        addListenerType(TRANSITIONEND_LISTENER);
    } else if (eventType == EventTypeNames::scroll) {
        addListenerType(SCROLL_LISTENER);
    }
}

Project: Chrome

void Document::adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>& quads, LayoutObject& layoutObject)
{
    if (!view())
        return;

    LayoutRect visibleContentRect(view()->visibleContentRect());
    for (size_t i = 0; i < quads.size(); ++i) {
        quads[i].move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y().toFloat()));
        adjustFloatQuadForAbsoluteZoom(quads[i], layoutObject);
    }
}

Project: Chrome

void Document::adjustFloatRectForScrollAndAbsoluteZoom(FloatRect& rect, LayoutObject& layoutObject)
{
    if (!view())
        return;

    LayoutRect visibleContentRect(view()->visibleContentRect());
    rect.move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y().toFloat()));
    adjustFloatRectForAbsoluteZoom(rect, layoutObject);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState)
{
    EventQueueScope scope;

    switch (source->nodeType()) {
    case DOCUMENT_NODE:
        exceptionState.throwDOMException(NotSupportedError, "The node provided is of type '" + source->nodeName() + "', which may not be adopted.");
        return nullptr;
    case ATTRIBUTE_NODE: {
        Attr* attr = toAttr(source.get());
        if (RefPtrWillBeRawPtr<Element> ownerElement = attr->ownerElement())
            ownerElement->removeAttributeNode(attr, exceptionState);
        break;
    }
    default:
        if (source->isShadowRoot()) {
            exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a shadow root, which may not be adopted.");
            return nullptr;
        }

        if (source->isFrameOwnerElement()) {
            HTMLFrameOwnerElement* frameOwnerElement = toHTMLFrameOwnerElement(source.get());
            if (frame() && frame()->tree().isDescendantOf(frameOwnerElement->contentFrame())) {
                exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a frame which contains this document.");
                return nullptr;
            }
        }
        if (source->parentNode()) {
            source->parentNode()->removeChild(source.get(), exceptionState);
            if (exceptionState.hadException())
                return nullptr;
            RELEASE_ASSERT(!source->parentNode());
        }
    }

    this->adoptIfNeeded(*source);

    return source;
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::all()
{
    return ensureCachedCollection<HTMLAllCollection>(DocAll);
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::allForBinding()
{
    UseCounter::count(*this, UseCounter::DocumentAll);
    return all();
}

Project: Chrome

bool Document::allowExecutingScripts(Node* node)
{
    LocalFrame* frame = executingFrame();
    if (!frame)
        return false;
    if (!node->document().executingFrame())
        return false;
    if (!frame->script().canExecuteScripts(AboutToExecuteScript))
        return false;
    return true;
}

Project: Chrome

bool Document::allowInlineEventHandlers(Node* node, EventListener* listener, const String& contextURL, const WTF::OrdinalNumber& contextLine)
{
    if (!ContentSecurityPolicy::shouldBypassMainWorld(this) && !contentSecurityPolicy()->allowInlineEventHandlers(contextURL, contextLine))
        return false;

    LocalFrame* frame = executingFrame();
    if (!frame)
        return false;
    if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
        return false;
    if (node && node->document() != this && !node->document().allowInlineEventHandlers(node, listener, contextURL, contextLine))
        return false;

    return true;
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLCollection> Document::anchors()
{
    return ensureCachedCollection<HTMLCollection>(DocAnchors);
}

Project: Chrome

AnimationClock& Document::animationClock()
{
    ASSERT(page());
    return page()->animator().clock();
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLCollection> Document::applets()
{
    return ensureCachedCollection<HTMLCollection>(DocApplets);
}

Project: Chrome

static void assertLayoutTreeUpdated(Node& root)
{
    for (Node& node : NodeTraversal::inclusiveDescendantsOf(root)) {
        if (!node.isElementNode()
            && !node.isTextNode()
            && !node.isShadowRoot()
            && !node.isDocumentNode())
            continue;
        ASSERT(!node.needsStyleRecalc());
        ASSERT(!node.childNeedsStyleRecalc());
        ASSERT(!node.childNeedsDistributionRecalc());
        ASSERT(!node.needsStyleInvalidation());
        ASSERT(!node.childNeedsStyleInvalidation());
        for (ShadowRoot* shadowRoot = node.youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
            assertLayoutTreeUpdated(*shadowRoot);
    }
}

Project: Chrome

v8::Local<v8::Object> Document::associateWithWrapper(v8::Isolate* isolate, const WrapperTypeInfo* wrapperType, v8::Local<v8::Object> wrapper)
{
    wrapper = V8DOMWrapper::associateObjectWithWrapper(isolate, this, wrapperType, wrapper);
    DOMWrapperWorld& world = DOMWrapperWorld::current(isolate);
    if (world.isMainWorld() && frame())
        frame()->script().windowProxy(world)->updateDocumentWrapper(wrapper);
    return wrapper;
}

Project: Chrome

void Document::attach(const AttachContext& context)
{
    ASSERT(m_lifecycle.state() == DocumentLifecycle::Inactive);
    ASSERT(!m_axObjectCache || this != &axObjectCacheOwner());

    m_layoutView = new LayoutView(this);
    setLayoutObject(m_layoutView);

    m_layoutView->setIsInWindow(true);
    m_layoutView->setStyle(StyleResolver::styleForDocument(*this));
    m_layoutView->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);

    ContainerNode::attach(context);

    if (TextAutosizer* autosizer = textAutosizer())
        autosizer->updatePageInfo();

    m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
}

Project: Chrome

bool Document::attemptedToDetermineEncodingFromContentSniffing() const
{
    return m_encodingData.attemptedToDetermineEncodingFromContentSniffing();
}

Project: Chrome

AXObjectCache* Document::axObjectCache() const
{
    Settings* settings = this->settings();
    if (!settings || !settings->accessibilityEnabled())
        return 0;

    Document& cacheOwner = this->axObjectCacheOwner();

    if (!cacheOwner.layoutView())
        return 0;

    ASSERT(&cacheOwner == this || !m_axObjectCache);
    if (!cacheOwner.m_axObjectCache)
        cacheOwner.m_axObjectCache = AXObjectCache::create(cacheOwner);
    return cacheOwner.m_axObjectCache.get();
}

Project: Chrome

Document& Document::axObjectCacheOwner() const
{
    Document* top = const_cast<Document*>(this);
    LocalFrame* frame = this->frame();
    if (!frame)
        return *top;

    while (frame && frame->owner() && frame->owner()->isLocal()) {
        HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(frame->owner());
        top = &owner->document();
        frame = top->frame();
    }

    if (top->frame() && top->frame()->pagePopupOwner()) {
        ASSERT(!top->m_axObjectCache);
        return top->frame()->pagePopupOwner()->document().axObjectCacheOwner();
    }

    ASSERT(top);
    return *top;
}

Project: Chrome

const KURL& Document::baseURLForOverride(const KURL& baseURLOverride) const
{
    const KURL* baseURLFromParent = 0;
    bool shouldUseParentBaseURL = baseURLOverride.isEmpty();
    if (!shouldUseParentBaseURL) {
        const KURL& aboutBlankURL = blankURL();
        shouldUseParentBaseURL = (baseURLOverride == aboutBlankURL);
    }
    if (shouldUseParentBaseURL) {
        if (Document* parent = parentDocument())
            baseURLFromParent = &parent->baseURL();
    }
    return baseURLFromParent ? *baseURLFromParent : baseURLOverride;
}

Project: Chrome

HTMLElement* Document::body() const
{
    if (!documentElement() || !isHTMLHtmlElement(documentElement()))
        return 0;

    for (HTMLElement* child = Traversal<HTMLElement>::firstChild(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
        if (isHTMLFrameSetElement(*child) || isHTMLBodyElement(*child))
            return child;
    }

    return 0;
}

Project: Chrome

bool Document::canAcceptChild(const Node& newChild, const Node* oldChild, ExceptionState& exceptionState) const
{
    if (oldChild && oldChild->nodeType() == newChild.nodeType())
        return true;

    int numDoctypes = 0;
    int numElements = 0;

    for (Node& child : NodeTraversal::childrenOf(*this)) {
        if (oldChild && *oldChild == child)
            continue;

        switch (child.nodeType()) {
        case DOCUMENT_TYPE_NODE:
            numDoctypes++;
            break;
        case ELEMENT_NODE:
            numElements++;
            break;
        default:
            break;
        }
    }

    if (newChild.isDocumentFragment()) {
        for (Node& child : NodeTraversal::childrenOf(toDocumentFragment(newChild))) {
            switch (child.nodeType()) {
            case ATTRIBUTE_NODE:
            case CDATA_SECTION_NODE:
            case DOCUMENT_FRAGMENT_NODE:
            case DOCUMENT_NODE:
            case TEXT_NODE:
                exceptionState.throwDOMException(HierarchyRequestError, "Nodes of type '" + newChild.nodeName() +
                    "' may not be inserted inside nodes of type '#document'.");
                return false;
            case COMMENT_NODE:
            case PROCESSING_INSTRUCTION_NODE:
                break;
            case DOCUMENT_TYPE_NODE:
                numDoctypes++;
                break;
            case ELEMENT_NODE:
                numElements++;
                break;
            }
        }
    } else {
        switch (newChild.nodeType()) {
        case ATTRIBUTE_NODE:
        case CDATA_SECTION_NODE:
        case DOCUMENT_FRAGMENT_NODE:
        case DOCUMENT_NODE:
        case TEXT_NODE:
            exceptionState.throwDOMException(HierarchyRequestError, "Nodes of type '" + newChild.nodeName() +
                "' may not be inserted inside nodes of type '#document'.");
            return false;
        case COMMENT_NODE:
        case PROCESSING_INSTRUCTION_NODE:
            return true;
        case DOCUMENT_TYPE_NODE:
            numDoctypes++;
            break;
        case ELEMENT_NODE:
            numElements++;
            break;
        }
    }

    if (numElements > 1 || numDoctypes > 1) {
        exceptionState.throwDOMException(HierarchyRequestError,
            String::format("Only one %s on document allowed.",
            numElements > 1 ? "element" : "doctype"));
        return false;
    }

    return true;
}

Project: Chrome

void Document::cancelParsing()
{
    detachParser();
    setParsingState(FinishedParsing);
    setReadyState(Complete);
}

Project: Chrome

CanvasFontCache* Document::canvasFontCache()
{
    if (!m_canvasFontCache)
        m_canvasFontCache = CanvasFontCache::create(*this);

    return m_canvasFontCache.get();
}

Project: Chrome

PassRefPtrWillBeRawPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
    if (!layoutView())
        return nullptr;

    HitTestResult result = hitTestInDocument(this, x, y);
    PositionWithAffinity positionWithAffinity = result.position();
    if (positionWithAffinity.position().isNull())
        return nullptr;

    Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
    return Range::createAdjustedToTreeScope(*this, rangeCompliantPosition);
}

Project: Chrome

void Document::checkLoadEventSoon()
{
    if (frame() && !m_loadEventDelayTimer.isActive())
        m_loadEventDelayTimer.startOneShot(0, BLINK_FROM_HERE);
}

Project: Chrome

void Document::childrenChanged(const ChildrenChange& change)
{
    ContainerNode::childrenChanged(change);
    m_documentElement = ElementTraversal::firstWithin(*this);
}

Project: Chrome

void Document::clearAXObjectCache()
{
    ASSERT(&axObjectCacheOwner() == this);
    if (m_axObjectCache)
        m_axObjectCache->dispose();
    m_axObjectCache.clear();
}

Project: Chrome

void Document::clearFocusedElement()
{
    setFocusedElement(nullptr, FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
}

Project: Chrome

void Document::clearFocusedElementSoon()
{
    if (!m_clearFocusedElementTimer.isActive())
        m_clearFocusedElementTimer.startOneShot(0, BLINK_FROM_HERE);
}

Project: Chrome

void Document::clearFocusedElementTimerFired(Timer<Document>*)
{
    updateLayoutTreeIfNeeded();
    m_clearFocusedElementTimer.stop();

    if (m_focusedElement && !m_focusedElement->isFocusable())
        m_focusedElement->blur();
}

Project: Chrome

PassRefPtrWillBeRawPtr<Document> Document::cloneDocumentWithoutChildren()
{
    DocumentInit init(url());
    if (isXMLDocument()) {
        if (isXHTMLDocument())
            return XMLDocument::createXHTML(init.withRegistrationContext(registrationContext()));
        return XMLDocument::create(init);
    }
    return create(init);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Node> Document::cloneNode(bool deep)
{
    RefPtrWillBeRawPtr<Document> clone = cloneDocumentWithoutChildren();
    clone->cloneDataFromDocument(*this);
    if (deep)
        cloneChildNodes(clone.get());
    return clone.release();
}

Project: Chrome

void Document::close(ExceptionState& exceptionState)
{

    if (importLoader()) {
        exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support close().");
        return;
    }

    if (!isHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "Only HTML documents support close().");
        return;
    }

    close();
}

Project: Chrome

static Editor::Command command(Document* document, const String& commandName)
{
    LocalFrame* frame = document->frame();
    if (!frame || frame->document() != document)
        return Editor::Command();

    document->updateLayoutTreeIfNeeded();
    return frame->editor().command(commandName, CommandFromDOM);
}

Project: Chrome

KURL Document::completeURL(const String& url) const
{
    return completeURLWithOverride(url, m_baseURL);
}

Project: Chrome

KURL Document::completeURLWithOverride(const String& url, const KURL& baseURLOverride) const
{
    ASSERT(baseURLOverride.isEmpty() || baseURLOverride.isValid());

    if (url.isNull())
        return KURL();
    const KURL& baseURL = baseURLForOverride(baseURLOverride);
    if (!encoding().isValid())
        return KURL(baseURL, url);
    return KURL(baseURL, url, encoding());
}

Project: Chrome

AtomicString Document::convertLocalName(const AtomicString& name)
{
    return isHTMLDocument() ? name.lower() : name;
}

Project: Chrome

    static PassOwnPtr<AutofocusTask> create()
    {
        return adoptPtr(new AutofocusTask());
    }

Project: Chrome

PassRefPtrWillBeRawPtr<Attr> Document::createAttribute(const AtomicString& name, ExceptionState& exceptionState)
{
    if (isHTMLDocument() && name != name.lower())
        UseCounter::count(*this, UseCounter::HTMLDocumentCreateAttributeNameNotLowercase);
    return createAttributeNS(nullAtom, name, exceptionState, true);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Attr> Document::createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState, bool shouldIgnoreNamespaceChecks)
{
    AtomicString prefix, localName;
    if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
        return nullptr;

    QualifiedName qName(prefix, localName, namespaceURI);

    if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(qName)) {
        exceptionState.throwDOMException(NamespaceError, "The namespace URI provided ('" + namespaceURI + "') is not valid for the qualified name provided ('" + qualifiedName + "').");
        return nullptr;
    }

    return Attr::create(*this, qName, emptyAtom);
}

Project: Chrome

PassRefPtrWillBeRawPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& exceptionState)
{
    if (isHTMLDocument()) {
        exceptionState.throwDOMException(NotSupportedError, "This operation is not supported for HTML documents.");
        return nullptr;
    }
    if (data.contains("]]>")) {
        exceptionState.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
        return nullptr;
    }
    return CDATASection::create(*this, data);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Comment> Document::createComment(const String& data)
{
    return Comment::create(*this, data);
}

Project: Chrome

PassRefPtrWillBeRawPtr<DocumentFragment> Document::createDocumentFragment()
{
    return DocumentFragment::create(*this);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Text> Document::createEditingTextNode(const String& text)
{
    return Text::createEditingText(*this, text);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
{
    if (!isValidName(name)) {
        exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + name + "') is not a valid name.");
        return nullptr;
    }

    if (isXHTMLDocument() || isHTMLDocument())
        return HTMLElementFactory::createHTMLElement(convertLocalName(name), *this, 0, false);

    return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
{
    RefPtrWillBeRawPtr<Element> e = nullptr;

    if (qName.namespaceURI() == xhtmlNamespaceURI)
        e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, createdByParser);
    else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
        e = SVGElementFactory::createSVGElement(qName.localName(), *this, createdByParser);

    if (e)
        m_sawElementsInKnownNamespaces = true;
    else
        e = Element::create(qName, this);

    if (e->prefix() != qName.prefix())
        e->setTagNameForCreateElementNS(qName);

    ASSERT(qName == e->tagQName());

    return e.release();
}

Project: Chrome

PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
{
    QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
    if (qName == QualifiedName::null())
        return nullptr;

    return createElement(qName, false);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState& exceptionState)
{
    QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
    if (qName == QualifiedName::null())
        return nullptr;

    RefPtrWillBeRawPtr<Element> element;
    if (CustomElement::isValidName(qName.localName()) && registrationContext())
        element = registrationContext()->createCustomTagElement(*this, qName);
    else
        element = createElement(qName, false);

    if (!typeExtension.isEmpty())
        CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);

    return element.release();
}

Project: Chrome

PassRefPtrWillBeRawPtr<Event> Document::createEvent(const String& eventType, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<Event> event = nullptr;
    for (const auto& factory : eventFactories()) {
        event = factory->create(eventType);
        if (event)
            return event.release();
    }
    exceptionState.throwDOMException(NotSupportedError, "The provided event type ('" + eventType + "') is invalid.");
    return nullptr;
}

Project: Chrome

PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
{
    ASSERT(root);
    return NodeIterator::create(root, whatToShow, filter);
}

Project: Chrome

PassRefPtrWillBeRawPtr<DocumentParser> Document::createParser()
{
    if (isHTMLDocument()) {
        bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(this);
        return HTMLDocumentParser::create(toHTMLDocument(*this), reportErrors, m_parserSyncPolicy);
    }
    return XMLDocumentParser::create(*this, view());
}

Project: Chrome

PassRefPtrWillBeRawPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& exceptionState)
{
    if (!isValidName(target)) {
        exceptionState.throwDOMException(InvalidCharacterError, "The target provided ('" + target + "') is not a valid name.");
        return nullptr;
    }
    if (data.contains("?>")) {
        exceptionState.throwDOMException(InvalidCharacterError, "The data provided ('" + data + "') contains '?>'.");
        return nullptr;
    }
    return ProcessingInstruction::create(*this, target, data);
}

Project: Chrome

static inline QualifiedName createQualifiedName(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
{
    AtomicString prefix, localName;
    if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
        return QualifiedName::null();

    QualifiedName qName(prefix, localName, namespaceURI);
    if (!Document::hasValidNamespaceForElements(qName)) {
        exceptionState.throwDOMException(NamespaceError, "The namespace URI provided ('" + namespaceURI + "') is not valid for the qualified name provided ('" + qualifiedName + "').");
        return QualifiedName::null();
    }

    return qName;
}

Project: Chrome

PassRefPtrWillBeRawPtr<Range> Document::createRange()
{
    return Range::create(*this);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Text> Document::createTextNode(const String& data)
{
    return Text::create(*this, data);
}

Project: Chrome

PassRefPtrWillBeRawPtr<TouchList> Document::createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch>>& touches) const
{
    return TouchList::adopt(touches);
}

Project: Chrome

PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
{
    ASSERT(root);
    return TreeWalker::create(root, whatToShow, filter);
}

Project: Chrome

WeakPtrWillBeRawPtr<Document> Document::createWeakPtr()
{
#if ENABLE(OILPAN)
    return this;
#else
    return m_weakFactory.createWeakPtr();
#endif
}

Project: Chrome

CustomElementMicrotaskRunQueue* Document::customElementMicrotaskRunQueue()
{
    if (!m_customElementMicrotaskRunQueue)
        m_customElementMicrotaskRunQueue = CustomElementMicrotaskRunQueue::create();
    return m_customElementMicrotaskRunQueue.get();
}

Project: Chrome

void Document::decrementLoadEventDelayCount()
{
    ASSERT(m_loadEventDelayCount);
    --m_loadEventDelayCount;

    if (!m_loadEventDelayCount)
        checkLoadEventSoon();
}

Project: Chrome

void Document::didAssociateFormControl(Element* element)
{
    if (!frame() || !frame()->page())
        return;
    m_associatedFormControls.add(element);
    if (!m_didAssociateFormControlsTimer.isActive())
        m_didAssociateFormControlsTimer.startOneShot(0, BLINK_FROM_HERE);
}

Project: Chrome

void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
{
    ASSERT_UNUSED(timer, timer == &m_didAssociateFormControlsTimer);
    if (!frame() || !frame()->page())
        return;

    WillBeHeapVector<RefPtrWillBeMember<Element>> associatedFormControls;
    copyToVector(m_associatedFormControls, associatedFormControls);

    frame()->page()->chromeClient().didAssociateFormControls(associatedFormControls, frame());
    m_associatedFormControls.clear();
}

Project: Chrome

void Document::didChangeVisibilityState()
{
    dispatchEvent(Event::createBubble(EventTypeNames::visibilitychange));
    dispatchEvent(Event::createBubble(EventTypeNames::webkitvisibilitychange));

    PageVisibilityState state = pageVisibilityState();
    for (DocumentVisibilityObserver* observer : m_visibilityObservers)
        observer->didChangeVisibilityState(state);

    if (state == PageVisibilityStateVisible)
        timeline().setAllCompositorPending();

    if (hidden() && m_canvasFontCache)
        m_canvasFontCache->pruneAll();
}

Project: Chrome

void Document::didInsertText(Node* text, unsigned offset, unsigned length)
{
    for (Range* range : m_ranges)
        range->didInsertText(text, offset, length);

    m_markers->shiftMarkers(text, offset, length);
}

Project: Chrome

void Document::didLoadAllImports()
{
    if (!haveStylesheetsLoaded())
        return;
    if (!importLoader())
        styleResolverMayHaveChanged();
    didLoadAllScriptBlockingResources();
}

Project: Chrome

void Document::didLoadAllScriptBlockingResources()
{
    loadingTaskRunner()->postTask(BLINK_FROM_HERE, m_executeScriptsWaitingForResourcesTask->cancelAndCreate());

    if (frame())
        frame()->loader().client()->didRemoveAllPendingStylesheet();

    if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
        view()->processUrlFragment(m_url);
}

Project: Chrome

void Document::didRemoveAllPendingStylesheet()
{
    styleResolverMayHaveChanged();

    if (HTMLImportLoader* import = importLoader())
        import->didRemoveAllPendingStylesheet();
    if (!haveImportsLoaded())
        return;
    didLoadAllScriptBlockingResources();
}

Project: Chrome

void Document::didRemoveText(Node* text, unsigned offset, unsigned length)
{
    for (Range* range : m_ranges)
        range->didRemoveText(text, offset, length);

    m_markers->removeMarkers(text, offset, length);
    m_markers->shiftMarkers(text, offset + length, 0 - length);
}

Project: Chrome

void Document::didSplitTextNode(Text& oldNode)
{
    for (Range* range : m_ranges)
        range->didSplitTextNode(oldNode);

    if (m_frame)
        m_frame->selection().didSplitTextNode(oldNode);

}

Project: Chrome

void Document::didUpdateSecurityOrigin()
{
    if (!m_frame)
        return;
    m_frame->updateSecurityOrigin(securityOrigin());
}

Project: Chrome

void Document::disableEval(const String& errorMessage)
{
    if (!frame())
        return;

    frame()->script().disableEval(errorMessage);
}

Project: Chrome

void Document::dispatchEventsForPrinting()
{
    if (!m_scriptedAnimationController)
        return;
    m_scriptedAnimationController->dispatchEventsAndCallbacksForPrinting();
}

Project: Chrome

void Document::dispatchUnloadEvents()
{
    PluginScriptForbiddenScope forbidPluginDestructorScripting;
    RefPtrWillBeRawPtr<Document> protect(this);
    if (m_parser)
        m_parser->stopParsing();

    if (m_loadEventProgress == LoadEventNotRun)
        return;

    if (m_loadEventProgress <= UnloadEventInProgress) {
        Element* currentFocusedElement = focusedElement();
        if (isHTMLInputElement(currentFocusedElement))
            toHTMLInputElement(*currentFocusedElement).endEditing();
        if (m_loadEventProgress < PageHideInProgress) {
            m_loadEventProgress = PageHideInProgress;
            if (LocalDOMWindow* window = domWindow())
                window->dispatchEvent(PageTransitionEvent::create(EventTypeNames::pagehide, false), this);
            if (!m_frame)
                return;

            RefPtrWillBeRawPtr<DocumentLoader> documentLoader = m_frame->loader().provisionalDocumentLoader();
            m_loadEventProgress = UnloadEventInProgress;
            RefPtrWillBeRawPtr<Event> unloadEvent(Event::create(EventTypeNames::unload));
            if (documentLoader && !documentLoader->timing().unloadEventStart() && !documentLoader->timing().unloadEventEnd()) {
                DocumentLoadTiming& timing = documentLoader->timing();
                ASSERT(timing.navigationStart());
                timing.markUnloadEventStart();
                m_frame->localDOMWindow()->dispatchEvent(unloadEvent, this);
                timing.markUnloadEventEnd();
            } else {
                m_frame->localDOMWindow()->dispatchEvent(unloadEvent, m_frame->document());
            }
        }
        m_loadEventProgress = UnloadEventHandled;
    }

    if (!m_frame)
        return;

    bool keepEventListeners = m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->loader().provisionalDocumentLoader()
        && isSecureTransitionTo(m_frame->loader().provisionalDocumentLoader()->url());
    if (!keepEventListeners)
        removeAllEventListenersRecursively();
}

Project: Chrome

void Document::dispose()
{
    ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);

    m_docType = nullptr;
    m_focusedElement = nullptr;
    m_hoverNode = nullptr;
    m_activeHoverElement = nullptr;
    m_titleElement = nullptr;
    m_documentElement = nullptr;
    m_contextFeatures = ContextFeatures::defaultSwitch();
    m_userActionElements.documentDidRemoveLastRef();
    m_associatedFormControls.clear();

    m_scriptRunner->dispose();
    detachParser();

    m_registrationContext.clear();

    destroyTreeScopeData();

    removeDetachedChildren();

    m_formController.clear();

    m_markers->clear();

    if (m_scriptedAnimationController)
        m_scriptedAnimationController->clearDocumentPointer();
    m_scriptedAnimationController.clear();

    m_scriptedIdleTaskController.clear();

    if (svgExtensions())
        accessSVGExtensions().pauseAnimations();

    if (m_intersectionObserverData)
        m_intersectionObserverData->dispose();

    m_lifecycle.advanceTo(DocumentLifecycle::Disposed);
    DocumentLifecycleNotifier::notifyDocumentWasDisposed();

    m_canvasFontCache.clear();
}

Project: Chrome

PassRefPtrWillBeRawPtr<DocumentNameCollection> Document::documentNamedItems(const AtomicString& name)
{
    return ensureCachedCollection<DocumentNameCollection>(DocumentNamedItems, name);
}

Project: Chrome

void Document::elementDataCacheClearTimerFired(Timer<Document>*)
{
    m_elementDataCache.clear();
}

Project: Chrome

CSSStyleSheet& Document::elementSheet()
{
    if (!m_elemSheet)
        m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
    return *m_elemSheet;
}

Project: Chrome

WillBeHeapVector<RawPtrWillBeMember<Element>> Document::elementsFromPoint(int x, int y) const
{
    if (!layoutView())
        return WillBeHeapVector<RawPtrWillBeMember<Element>>();
    return TreeScope::elementsFromPoint(x, y);
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLCollection> Document::embeds()
{
    return ensureCachedCollection<HTMLCollection>(DocEmbeds);
}

Project: Chrome

AtomicString Document::encodingName() const
{
    return AtomicString(encoding().name());
}

Project: Chrome

bool Document::encodingWasDetectedFromContentSniffing() const
{
    return m_encodingData.encodingWasDetectedFromContentSniffing();
}

Project: Chrome

void Document::enforceStrictMixedContentChecking()
{
    securityContext().setShouldEnforceStrictMixedContentChecking(true);
    if (frame())
        frame()->loader().client()->didEnforceStrictMixedContentChecking();
}

Project: Chrome

void Document::enqueueAnimationFrameEvent(PassRefPtrWillBeRawPtr<Event> event)
{
    ensureScriptedAnimationController().enqueueEvent(event);
}

Project: Chrome

void Document::enqueueResizeEvent()
{
    RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::resize);
    event->setTarget(domWindow());
    ensureScriptedAnimationController().enqueuePerFrameEvent(event.release());
}

Project: Chrome

void Document::enqueueScrollEventForNode(Node* target)
{
    RefPtrWillBeRawPtr<Event> scrollEvent = target->isDocumentNode() ? Event::createBubble(EventTypeNames::scroll) : Event::create(EventTypeNames::scroll);
    scrollEvent->setTarget(target);
    ensureScriptedAnimationController().enqueuePerFrameEvent(scrollEvent.release());
}

Project: Chrome

IntersectionObserverController& Document::ensureIntersectionObserverController()
{
    if (!m_intersectionObserverController)
        m_intersectionObserverController = IntersectionObserverController::create(this);
    return *m_intersectionObserverController;
}

Project: Chrome

NodeIntersectionObserverData& Document::ensureIntersectionObserverData()
{
    if (!m_intersectionObserverData)
        m_intersectionObserverData = new NodeIntersectionObserverData();
    return *m_intersectionObserverData;
}

Project: Chrome

ScriptedIdleTaskController& Document::ensureScriptedIdleTaskController()
{
    if (!m_scriptedIdleTaskController)
        m_scriptedIdleTaskController = ScriptedIdleTaskController::create(this);
    return *m_scriptedIdleTaskController;
}

Project: Chrome

StyleResolver& Document::ensureStyleResolver() const
{
    return m_styleEngine->ensureResolver();
}

Project: Chrome

Document& Document::ensureTemplateDocument()
{
    if (isTemplateDocument())
        return *this;

    if (m_templateDocument)
        return *m_templateDocument;

    if (isHTMLDocument()) {
        DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL()).withNewRegistrationContext();
        m_templateDocument = HTMLDocument::create(init);
    } else {
        m_templateDocument = Document::create(DocumentInit(blankURL()));
    }

    m_templateDocument->m_templateDocumentHost = this; // balanced in dtor.

    return *m_templateDocument.get();
}

Project: Chrome

void Document::evaluateMediaQueryList()
{
    if (m_mediaQueryMatcher)
        m_mediaQueryMatcher->mediaFeaturesChanged();
}

Project: Chrome

void Document::evaluateMediaQueryListIfNeeded()
{
    if (!m_evaluateMediaQueriesOnStyleRecalc)
        return;
    evaluateMediaQueryList();
    m_evaluateMediaQueriesOnStyleRecalc = false;
}

Project: Chrome

Document::EventFactorySet& Document::eventFactories()
{
    DEFINE_STATIC_LOCAL(EventFactorySet, s_eventFactory, ());
    return s_eventFactory;
}

Project: Chrome

EventQueue* Document::eventQueue() const
{
    if (!m_domWindow)
        return 0;
    return m_domWindow->eventQueue();
}

Project: Chrome

void Document::executeScriptsWaitingForResources()
{
    if (!isRenderingReady())
        return;
    if (ScriptableDocumentParser* parser = scriptableDocumentParser())
        parser->executeScriptsWaitingForResources();
}

Project: Chrome

LocalFrame* Document::executingFrame()
{
    LocalDOMWindow* window = executingWindow();
    if (!window)
        return 0;
    return window->frame();
}

Project: Chrome

LocalDOMWindow* Document::executingWindow()
{
    if (LocalDOMWindow* owningWindow = domWindow())
        return owningWindow;
    if (HTMLImportsController* import = this->importsController())
        return import->master()->domWindow();
    return 0;
}

Project: Chrome

AXObjectCache* Document::existingAXObjectCache() const
{
    if (!axObjectCacheOwner().layoutView())
        return 0;

    return axObjectCacheOwner().m_axObjectCache.get();
}

Project: Chrome

void Document::exitPointerLock()
{
    if (!page())
        return;
    if (Element* target = page()->pointerLockController().element()) {
        if (target->document() != this)
            return;
    }
    page()->pointerLockController().requestPointerUnlock();
}

Project: Chrome

HTMLBodyElement* Document::firstBodyElement() const
{
    if (!documentElement())
        return 0;

    for (HTMLElement* child = Traversal<HTMLElement>::firstChild(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
        if (isHTMLBodyElement(*child))
            return toHTMLBodyElement(child);
    }

    return 0;
}

Project: Chrome

const KURL& Document::firstPartyForCookies() const
{
    if (SchemeRegistry::shouldTreatURLSchemeAsFirstPartyWhenTopLevel(topDocument().url().protocol()))
        return topDocument().url();

    const OriginAccessEntry& accessEntry = topDocument().accessEntryFromURL();
    const Document* currentDocument = this;
    while (currentDocument) {
        while (currentDocument->isSrcdocDocument())
            currentDocument = currentDocument->parentDocument();
        ASSERT(currentDocument);

        if (accessEntry.matchesDomain(*currentDocument->securityOrigin()) == OriginAccessEntry::DoesNotMatchOrigin)
            return SecurityOrigin::urlWithUniqueSecurityOrigin();

        currentDocument = currentDocument->parentDocument();
    }

    return topDocument().url();
}

Project: Chrome

FormController& Document::formController()
{
    if (!m_formController) {
        m_formController = FormController::create();
        if (m_frame && m_frame->loader().currentItem() && m_frame->loader().currentItem()->isCurrentDocument(this))
            m_frame->loader().currentItem()->setDocumentState(m_formController->formElementsState());
    }
    return *m_formController;
}

Project: Chrome

DocumentState* Document::formElementsState() const
{
    if (!m_formController)
        return 0;
    return m_formController->formElementsState();
}

Project: Chrome

Locale& Document::getCachedLocale(const AtomicString& locale)
{
    AtomicString localeKey = locale;
    if (locale.isEmpty() || !RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
        return Locale::defaultLocale();
    LocaleIdentifierToLocaleMap::AddResult result = m_localeCache.add(localeKey, nullptr);
    if (result.isNewEntry)
        result.storedValue->value = Locale::create(localeKey);
    return *(result.storedValue->value);
}

Project: Chrome

EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
{
    LocalDOMWindow* domWindow = this->domWindow();
    if (!domWindow)
        return 0;
    return domWindow->getAttributeEventListener(eventType);
}

Project: Chrome

bool Document::hasAppCacheManifest() const
{
    return isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
}

Project: Chrome

bool Document::hasFocus() const
{
    return page() && page()->focusController().isDocumentFocused(*this);
}

Project: Chrome

bool Document::hasPendingForcedStyleRecalc() const
{
    return hasPendingStyleRecalc() && !inStyleRecalc() && styleChangeType() >= SubtreeStyleChange;
}

Project: Chrome

bool Document::hasSVGRootNode() const
{
    return isSVGSVGElement(documentElement());
}

Project: Chrome

bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName)
{
    return hasValidNamespaceForElements(qName);
}

Project: Chrome

bool Document::hasValidNamespaceForElements(const QualifiedName& qName)
{
    if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) // createElementNS(null, "html:div")
        return false;
    if (qName.prefix() == xmlAtom && qName.namespaceURI() != XMLNames::xmlNamespaceURI) // createElementNS("http://www.example.com", "xml:lang")
        return false;

    if (qName.prefix() == xmlnsAtom || (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom))
        return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
    return qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI;
}

Project: Chrome

bool Document::haveImportsLoaded() const
{
    if (!m_importsController)
        return true;
    return !m_importsController->shouldBlockScriptExecution(*this);
}

Project: Chrome

bool Document::haveStylesheetsLoaded() const
{
    return m_styleEngine->haveStylesheetsLoaded();
}

Project: Chrome

HTMLHeadElement* Document::head() const
{
    Node* de = documentElement();
    if (!de)
        return 0;

    return Traversal<HTMLHeadElement>::firstChild(*de);
}

Project: Chrome

bool Document::hidden() const
{
    return pageVisibilityState() != PageVisibilityStateVisible;
}

Project: Chrome

void Document::hoveredNodeDetached(Element& element)
{
    if (!m_hoverNode)
        return;

    m_hoverNode->updateDistribution();
    if (element != m_hoverNode && (!m_hoverNode->isTextNode() || element != ComposedTreeTraversal::parent(*m_hoverNode)))
        return;

    m_hoverNode = ComposedTreeTraversal::parent(element);
    while (m_hoverNode && !m_hoverNode->layoutObject())
        m_hoverNode = ComposedTreeTraversal::parent(*m_hoverNode);

    if (!page()->isCursorVisible())
        return;

    if (frame())
        frame()->eventHandler().scheduleHoverStateUpdate();
}

Project: Chrome

Vector<IconURL> Document::iconURLs(int iconTypesMask)
{
    IconURL firstFavicon;
    IconURL firstTouchIcon;
    IconURL firstTouchPrecomposedIcon;
    Vector<IconURL> secondaryIcons;

    for (HTMLLinkElement* linkElement = head() ? Traversal<HTMLLinkElement>::firstChild(*head()) : 0; linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
        if (!(linkElement->iconType() & iconTypesMask))
            continue;
        if (linkElement->href().isEmpty())
            continue;

        IconURL newURL(linkElement->href(), linkElement->iconSizes(), linkElement->type(), linkElement->iconType());
        if (linkElement->iconType() == Favicon) {
            if (firstFavicon.m_iconType != InvalidIcon)
                secondaryIcons.append(firstFavicon);
            firstFavicon = newURL;
        } else if (linkElement->iconType() == TouchIcon) {
            if (firstTouchIcon.m_iconType != InvalidIcon)
                secondaryIcons.append(firstTouchIcon);
            firstTouchIcon = newURL;
        } else if (linkElement->iconType() == TouchPrecomposedIcon) {
            if (firstTouchPrecomposedIcon.m_iconType != InvalidIcon)
                secondaryIcons.append(firstTouchPrecomposedIcon);
            firstTouchPrecomposedIcon = newURL;
        } else {
            ASSERT_NOT_REACHED();
        }
    }

    Vector<IconURL> iconURLs;
    if (firstFavicon.m_iconType != InvalidIcon)
        iconURLs.append(firstFavicon);
    else if (m_url.protocolIsInHTTPFamily() && iconTypesMask & Favicon)
        iconURLs.append(IconURL::defaultFavicon(m_url));

    if (firstTouchIcon.m_iconType != InvalidIcon)
        iconURLs.append(firstTouchIcon);
    if (firstTouchPrecomposedIcon.m_iconType != InvalidIcon)
        iconURLs.append(firstTouchPrecomposedIcon);
    for (int i = secondaryIcons.size() - 1; i >= 0; --i)
        iconURLs.append(secondaryIcons[i]);
    return iconURLs;
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLCollection> Document::images()
{
    return ensureCachedCollection<HTMLCollection>(DocImages);
}

Project: Chrome

DOMImplementation& Document::implementation()
{
    if (!m_implementation)
        m_implementation = DOMImplementation::create(*this);
    return *m_implementation;
}

Project: Chrome

void Document::implicitClose()
{
    ASSERT(!inStyleRecalc());
    if (processingLoadEvent() || !m_parser)
        return;
    if (frame() && frame()->navigationScheduler().locationChangePending()) {
        suppressLoadEvent();
        return;
    }

    RefPtrWillBeRawPtr<LocalDOMWindow> protectedWindow(this->domWindow());

    m_loadEventProgress = LoadEventInProgress;

    ScriptableDocumentParser* parser = scriptableDocumentParser();
    m_wellFormed = parser && parser->wellFormed();

    detachParser();

    if (frame() && frame()->script().canExecuteScripts(NotAboutToExecuteScript)) {
        ImageLoader::dispatchPendingLoadEvents();
        ImageLoader::dispatchPendingErrorEvents();

        HTMLLinkElement::dispatchPendingLoadEvents();
        HTMLStyleElement::dispatchPendingLoadEvents();
    }


    if (svgExtensions())
        accessSVGExtensions().dispatchSVGLoadEventToOutermostSVGElements();

    if (protectedWindow)
        protectedWindow->documentWasClosed();

    if (frame()) {
        frame()->loader().client()->dispatchDidHandleOnloadEvents();
        loader()->applicationCacheHost()->stopDeferringEvents();
    }

    if (!frame()) {
        m_loadEventProgress = LoadEventCompleted;
        return;
    }


    if (frame()->navigationScheduler().locationChangePending() && elapsedTime() < cLayoutScheduleThreshold) {
        m_loadEventProgress = LoadEventCompleted;
        return;
    }

    if (!ownerElement() || (ownerElement()->layoutObject() && !ownerElement()->layoutObject()->needsLayout())) {
        updateLayoutTreeIfNeeded();

        if (view() && layoutView() && (!layoutView()->firstChild() || layoutView()->needsLayout()))
            view()->layout();
    }

    m_loadEventProgress = LoadEventCompleted;

    if (frame() && layoutView() && settings()->accessibilityEnabled()) {
        if (AXObjectCache* cache = axObjectCache()) {
            if (this == &axObjectCacheOwner())
                cache->handleLoadComplete(this);
            else
                cache->handleLayoutComplete(this);
        }
    }

    if (svgExtensions())
        accessSVGExtensions().startAnimations();
}

Project: Chrome

bool Document::importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtrWillBeRawPtr<ContainerNode> newContainerNode, ExceptionState& exceptionState)
{
    for (Node& oldChild : NodeTraversal::childrenOf(*oldContainerNode)) {
        RefPtrWillBeRawPtr<Node> newChild = importNode(&oldChild, true, exceptionState);
        if (exceptionState.hadException())
            return false;
        newContainerNode->appendChild(newChild.release(), exceptionState);
        if (exceptionState.hadException())
            return false;
    }

    return true;
}

Project: Chrome

HTMLImportLoader* Document::importLoader() const
{
    if (!m_importsController)
        return 0;
    return m_importsController->loaderFor(*this);
}

Project: Chrome

PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
{
    switch (importedNode->nodeType()) {
    case TEXT_NODE:
        return createTextNode(importedNode->nodeValue());
    case CDATA_SECTION_NODE:
        return CDATASection::create(*this, importedNode->nodeValue());
    case PROCESSING_INSTRUCTION_NODE:
        return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), exceptionState);
    case COMMENT_NODE:
        return createComment(importedNode->nodeValue());
    case DOCUMENT_TYPE_NODE: {
        DocumentType* doctype = toDocumentType(importedNode);
        return DocumentType::create(this, doctype->name(), doctype->publicId(), doctype->systemId());
    }
    case ELEMENT_NODE: {
        Element* oldElement = toElement(importedNode);
        if (!hasValidNamespaceForElements(oldElement->tagQName())) {
            exceptionState.throwDOMException(NamespaceError, "The imported node has an invalid namespace.");
            return nullptr;
        }
        RefPtrWillBeRawPtr<Element> newElement = createElement(oldElement->tagQName(), false);

        newElement->cloneDataFromElement(*oldElement);

        if (deep) {
            if (!importContainerNodeChildren(oldElement, newElement, exceptionState))
                return nullptr;
            if (isHTMLTemplateElement(*oldElement)
                && !ensureTemplateDocument().importContainerNodeChildren(
                    toHTMLTemplateElement(oldElement)->content(),
                    toHTMLTemplateElement(newElement)->content(), exceptionState))
                return nullptr;
        }

        return newElement.release();
    }
    case ATTRIBUTE_NODE:
        return Attr::create(*this, QualifiedName(nullAtom, AtomicString(toAttr(importedNode)->name()), nullAtom), toAttr(importedNode)->value());
    case DOCUMENT_FRAGMENT_NODE: {
        if (importedNode->isShadowRoot()) {
            exceptionState.throwDOMException(NotSupportedError, "The node provided is a shadow root, which may not be imported.");
            return nullptr;
        }
        DocumentFragment* oldFragment = toDocumentFragment(importedNode);
        RefPtrWillBeRawPtr<DocumentFragment> newFragment = createDocumentFragment();
        if (deep && !importContainerNodeChildren(oldFragment, newFragment, exceptionState))
            return nullptr;

        return newFragment.release();
    }
    case DOCUMENT_NODE:
        exceptionState.throwDOMException(NotSupportedError, "The node provided is a document, which may not be imported.");
        return nullptr;
    }

    ASSERT_NOT_REACHED();
    return nullptr;
}

Project: Chrome

void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change)
{
    ASSERT(inStyleRecalc());
    ASSERT(documentElement());

    bool didRecalcDocumentElement = false;
    RefPtr<ComputedStyle> documentElementStyle = documentElement()->mutableComputedStyle();
    if (change == Force)
        documentElement()->clearAnimationStyleChange();
    if (!documentElementStyle || documentElement()->needsStyleRecalc() || change == Force) {
        documentElementStyle = ensureStyleResolver().styleForElement(documentElement());
        didRecalcDocumentElement = true;
    }

    WritingMode rootWritingMode = documentElementStyle->writingMode();
    TextDirection rootDirection = documentElementStyle->direction();

    HTMLElement* body = this->body();
    RefPtr<ComputedStyle> bodyStyle;

    if (body) {
        bodyStyle = body->mutableComputedStyle();
        if (didRecalcDocumentElement)
            body->clearAnimationStyleChange();
        if (!bodyStyle || body->needsStyleRecalc() || didRecalcDocumentElement)
            bodyStyle = ensureStyleResolver().styleForElement(body, documentElementStyle.get());
        rootWritingMode = bodyStyle->writingMode();
        rootDirection = bodyStyle->direction();
    }

    const ComputedStyle* backgroundStyle = documentElementStyle.get();
    if (isHTMLHtmlElement(documentElement()) && isHTMLBodyElement(body) && !backgroundStyle->hasBackground())
        backgroundStyle = bodyStyle.get();
    Color backgroundColor = backgroundStyle->visitedDependentColor(CSSPropertyBackgroundColor);
    FillLayer backgroundLayers = backgroundStyle->backgroundLayers();
    for (auto currentLayer = &backgroundLayers; currentLayer; currentLayer = currentLayer->next()) {
        currentLayer->setClip(BorderFillBox);

        if (currentLayer->attachment() == ScrollBackgroundAttachment)
            currentLayer->setAttachment(LocalBackgroundAttachment);
    }
    EImageRendering imageRendering = backgroundStyle->imageRendering();

    const ComputedStyle* overflowStyle = nullptr;
    if (Element* element = viewportDefiningElement(documentElementStyle.get())) {
        if (element == body) {
            overflowStyle = bodyStyle.get();
        } else {
            ASSERT(element == documentElement());
            overflowStyle = documentElementStyle.get();

            if (bodyStyle && !bodyStyle->isOverflowVisible())
                UseCounter::count(*this, UseCounter::BodyScrollsInAdditionToViewport);
        }
    }

    if (styleEngine().usesRemUnits() && (documentElement()->needsAttach() || !documentElement()->computedStyle() || documentElement()->computedStyle()->fontSize() != documentElementStyle->fontSize())) {
        ensureStyleResolver().invalidateMatchedPropertiesCache();
        documentElement()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::FontSizeChange));
    }

    EOverflow overflowX = OAUTO;
    EOverflow overflowY = OAUTO;
    float columnGap = 0;
    if (overflowStyle) {
        overflowX = overflowStyle->overflowX();
        overflowY = overflowStyle->overflowY();
        if (overflowX == OVISIBLE)
            overflowX = OAUTO;
        if (overflowY == OVISIBLE)
            overflowY = OAUTO;
        columnGap = overflowStyle->columnGap();
    }

    RefPtr<ComputedStyle> documentStyle = layoutView()->mutableStyle();
    if (documentStyle->writingMode() != rootWritingMode
        || documentStyle->direction() != rootDirection
        || documentStyle->visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor
        || documentStyle->backgroundLayers() != backgroundLayers
        || documentStyle->imageRendering() != imageRendering
        || documentStyle->overflowX() != overflowX
        || documentStyle->overflowY() != overflowY
        || documentStyle->columnGap() != columnGap) {
        RefPtr<ComputedStyle> newStyle = ComputedStyle::clone(*documentStyle);
        newStyle->setWritingMode(rootWritingMode);
        newStyle->setDirection(rootDirection);
        newStyle->setBackgroundColor(backgroundColor);
        newStyle->accessBackgroundLayers() = backgroundLayers;
        newStyle->setImageRendering(imageRendering);
        newStyle->setOverflowX(overflowX);
        newStyle->setOverflowY(overflowY);
        newStyle->setColumnGap(columnGap);
        layoutView()->setStyle(newStyle);
        setupFontBuilder(*newStyle);
    }

    if (body) {
        if (const ComputedStyle* style = body->computedStyle()) {
            if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
                body->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::WritingModeChange));
        }
    }

    if (const ComputedStyle* style = documentElement()->computedStyle()) {
        if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
            documentElement()->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::WritingModeChange));
    }
}

Project: Chrome

void Document::initContentSecurityPolicy(PassRefPtrWillBeRawPtr<ContentSecurityPolicy> csp)
{
    setContentSecurityPolicy(csp ? csp : ContentSecurityPolicy::create());
    if (m_frame && m_frame->tree().parent() && m_frame->tree().parent()->isLocalFrame()) {
        ContentSecurityPolicy* parentCSP = toLocalFrame(m_frame->tree().parent())->document()->contentSecurityPolicy();
        if (shouldInheritSecurityOriginFromOwner(m_url)) {
            contentSecurityPolicy()->copyStateFrom(parentCSP);
        } else if (isPluginDocument()) {
            contentSecurityPolicy()->copyPluginTypesFrom(parentCSP);
        }
    }
    contentSecurityPolicy()->bindToExecutionContext(this);
}

Project: Chrome

void Document::initSecurityContext()
{
    initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_importsController));
}

Project: Chrome

void Document::initSecurityContext(const DocumentInit& initializer)
{
    if (haveInitializedSecurityOrigin()) {
        ASSERT(securityOrigin());
        return;
    }

    if (initializer.isHostedInReservedIPRange())
        setHostedInReservedIPRange();

    if (!initializer.hasSecurityContext()) {
        m_cookieURL = KURL(ParsedURLString, emptyString());
        setSecurityOrigin(SecurityOrigin::createUnique());
        initContentSecurityPolicy();
        return;
    }

    m_cookieURL = m_url;
    enforceSandboxFlags(initializer.sandboxFlags());
    if (initializer.shouldEnforceStrictMixedContentChecking())
        enforceStrictMixedContentChecking();
    setInsecureRequestsPolicy(initializer.insecureRequestsPolicy());
    if (initializer.insecureNavigationsToUpgrade()) {
        for (auto toUpgrade : *initializer.insecureNavigationsToUpgrade())
            addInsecureNavigationUpgrade(toUpgrade);
    }
    setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));

    if (importsController()) {
        setContentSecurityPolicy(importsController()->master()->contentSecurityPolicy());
    } else {
        initContentSecurityPolicy();
    }

    if (Settings* settings = initializer.settings()) {
        if (!settings->webSecurityEnabled()) {
            securityOrigin()->grantUniversalAccess();
        } else if (securityOrigin()->isLocal()) {
            if (settings->allowUniversalAccessFromFileURLs()) {
                securityOrigin()->grantUniversalAccess();
            } else if (!settings->allowFileAccessFromFileURLs()) {
                securityOrigin()->blockLocalAccessFromLocalOrigin();
            }
        }
    }

    if (initializer.shouldTreatURLAsSrcdocDocument()) {
        m_isSrcdocDocument = true;
        setBaseURLOverride(initializer.parentBaseURL());
    }

    if (!shouldInheritSecurityOriginFromOwner(m_url))
        return;


    if (!initializer.owner()) {
        didFailToInitializeSecurityOrigin();
        return;
    }

    if (isSandboxed(SandboxOrigin)) {
        if (initializer.owner()->securityOrigin()->canLoadLocalResources())
            securityOrigin()->grantLoadLocalResources();
        return;
    }

    m_cookieURL = initializer.owner()->cookieURL();
    setSecurityOrigin(initializer.owner()->securityOrigin());
}

Project: Chrome

IntersectionObserverController* Document::intersectionObserverController()
{
    return m_intersectionObserverController;
}

Project: Chrome

void Document::invalidateNodeListCaches(const QualifiedName* attrName)
{
    for (const LiveNodeListBase* list : m_listsInvalidatedAtDocument)
        list->invalidateCacheForAttribute(attrName);
}

Project: Chrome

bool Document::isDelayingLoadEvent()
{
#if ENABLE(OILPAN)
    if (ThreadState::current()->sweepForbidden()) {
        if (!m_loadEventDelayCount)
            checkLoadEventSoon();
        return true;
    }
#endif
    return m_loadEventDelayCount;
}

Project: Chrome

bool Document::isFrameSet() const
{
    if (!isHTMLDocument())
        return false;
    return isHTMLFrameSetElement(body());
}

Project: Chrome

bool Document::isInInvisibleSubframe() const
{
    if (!ownerElement())
        return false; // this is the root element

    ASSERT(frame());
    return !frame()->ownerLayoutObject();
}

Project: Chrome

bool Document::isLoadCompleted()
{
    return m_readyState == Complete;
}

Project: Chrome

static bool isOriginPotentiallyTrustworthy(SecurityOrigin* origin, String* errorMessage)
{
    if (errorMessage)
        return origin->isPotentiallyTrustworthy(*errorMessage);
    return origin->isPotentiallyTrustworthy();
}

Project: Chrome

bool Document::isSecureContext(String& errorMessage, const SecureContextCheck privilegeContextCheck) const
{
    return isSecureContextImpl(&errorMessage, privilegeContextCheck);
}

Project: Chrome

bool Document::isSecureContext(const SecureContextCheck privilegeContextCheck) const
{
    return isSecureContextImpl(nullptr, privilegeContextCheck);
}

Project: Chrome

bool Document::isSecureContextImpl(String* errorMessage, const SecureContextCheck privilegeContextCheck) const
{
    if (SecurityContext::isSandboxed(SandboxOrigin)) {
        RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url());
        if (!isOriginPotentiallyTrustworthy(origin.get(), errorMessage))
            return false;
        if (SchemeRegistry::schemeShouldBypassSecureContextCheck(origin->protocol()))
            return true;
    } else {
        if (!isOriginPotentiallyTrustworthy(securityOrigin(), errorMessage))
            return false;
        if (SchemeRegistry::schemeShouldBypassSecureContextCheck(securityOrigin()->protocol()))
            return true;
    }

    if (privilegeContextCheck == StandardSecureContextCheck) {
        Document* context = parentDocument();
        while (context) {
            if (!context->isSrcdocDocument()) {
                if (context->securityContext().isSandboxed(SandboxOrigin)) {
                    RefPtr<SecurityOrigin> origin = SecurityOrigin::create(context->url());
                    if (!isOriginPotentiallyTrustworthy(origin.get(), errorMessage))
                        return false;
                } else {
                    if (!isOriginPotentiallyTrustworthy(context->securityOrigin(), errorMessage))
                        return false;
                }
            }
            context = context->parentDocument();
        }
    }
    return true;
}

Project: Chrome

static bool isValidNameNonASCII(const UChar* characters, unsigned length)
{
    for (unsigned i = 0; i < length;) {
        bool first = i == 0;
        UChar32 c;
        U16_NEXT(characters, i, length, c); // Increments i.
        if (first ? !isValidNameStart(c) : !isValidNamePart(c))
            return false;
    }

    return true;
}

Project: Chrome

static inline bool isValidNamePart(UChar32 c)
{
    if (isValidNameStart(c))
        return true;

    if (c == 0x00B7 || c == 0x0387)
        return true;

    if (c == '-' || c == '.')
        return true;

    const uint32_t otherNamePartMask = Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining | Letter_Modifier | Number_DecimalDigit;
    if (!(Unicode::category(c) & otherNamePartMask))
        return false;

    if (c >= 0xF900 && c < 0xFFFE)
        return false;

    CharDecompositionType decompType = decompositionType(c);
    if (decompType == DecompositionFont || decompType == DecompositionCompat)
        return false;

    return true;
}

Project: Chrome

static inline bool isValidNameStart(UChar32 c)
{
    if ((c >= 0x02BB && c <= 0x02C1) || c == 0x559 || c == 0x6E5 || c == 0x6E6)
        return true;

    if (c == ':' || c == '_')
        return true;

    const uint32_t nameStartMask = Letter_Lowercase | Letter_Uppercase | Letter_Other | Letter_Titlecase | Number_Letter;
    if (!(Unicode::category(c) & nameStartMask))
        return false;

    if (c >= 0xF900 && c < 0xFFFE)
        return false;

    CharDecompositionType decompType = decompositionType(c);
    if (decompType == DecompositionFont || decompType == DecompositionCompat)
        return false;

    return true;
}

Project: Chrome

String Document::lastModified() const
{
    DateComponents date;
    bool foundDate = false;
    if (m_frame) {
        if (DocumentLoader* documentLoader = loader()) {
            const AtomicString& httpLastModified = documentLoader->response().httpHeaderField(HTTPNames::Last_Modified);
            if (!httpLastModified.isEmpty()) {
                date.setMillisecondsSinceEpochForDateTime(convertToLocalTime(parseDate(httpLastModified)));
                foundDate = true;
            }
        }
    }
    if (!foundDate)
        date.setMillisecondsSinceEpochForDateTime(convertToLocalTime(currentTimeMS()));
    return String::format("%02d/%02d/%04d %02d:%02d:%02d", date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
}

Project: Chrome

void Document::layoutUpdated()
{
    if (frame() && frame()->page())
        frame()->page()->chromeClient().layoutUpdated(frame());

    markers().updateRenderedRectsForMarkers();

    if (isRenderingReady() && body() && !styleEngine().hasPendingSheets()) {
        if (!m_documentTiming.firstLayout())
            m_documentTiming.markFirstLayout();
    }
}

Project: Chrome

HTMLLinkElement* Document::linkManifest() const
{
    HTMLHeadElement* head = this->head();
    if (!head)
        return 0;

    for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
        if (!linkElement->relAttribute().isManifest())
            continue;
        return linkElement;
    }

    return 0;
}

Project: Chrome

Document::WeakDocumentSet& Document::liveDocumentSet()
{
    DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WeakDocumentSet>, set, (adoptPtrWillBeNoop(new WeakDocumentSet())));
    return *set;
}

Project: Chrome

void Document::loadEventDelayTimerFired(Timer<Document>*)
{
    if (frame())
        frame()->loader().checkCompleted();
}

Project: Chrome

void Document::loadPluginsSoon()
{
    if (!m_pluginLoadingTimer.isActive())
        m_pluginLoadingTimer.startOneShot(0, BLINK_FROM_HERE);
}

Project: Chrome

DocumentLoader* Document::loader() const
{
    if (!m_frame)
        return 0;

    DocumentLoader* loader = m_frame->loader().documentLoader();
    if (!loader)
        return 0;

    if (m_frame->document() != this)
        return 0;

    return loader;
}

Project: Chrome

WebTaskRunner* Document::loadingTaskRunner() const
{
    if (frame())
        return frame()->frameScheduler()->loadingTaskRunner();
    if (m_importsController)
        return m_importsController->master()->loadingTaskRunner();
    if (m_contextDocument)
        return m_contextDocument->loadingTaskRunner();
    return Platform::current()->currentThread()->scheduler()->loadingTaskRunner();
}

Project: Chrome

void Document::logExceptionToConsole(const String& errorMessage, int scriptId, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
{
    RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, columnNumber);
    consoleMessage->setScriptId(scriptId);
    consoleMessage->setCallStack(callStack);
    addConsoleMessage(consoleMessage.release());
}

Project: Chrome

void Document::maybeHandleHttpRefresh(const String& content, HttpRefreshType httpRefreshType)
{
    if (m_isViewSource || !m_frame)
        return;

    double delay;
    String refreshURL;
    if (!parseHTTPRefresh(content, httpRefreshType == HttpRefreshFromMetaTag, delay, refreshURL))
        return;
    if (refreshURL.isEmpty())
        refreshURL = url().string();
    else
        refreshURL = completeURL(refreshURL).string();

    if (protocolIsJavaScript(refreshURL)) {
        String message = "Refused to refresh " + m_url.elidedString() + " to a javascript: URL";
        addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
        return;
    }

    if (httpRefreshType == HttpRefreshFromMetaTag && isSandboxed(SandboxAutomaticFeatures)) {
        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.";
        addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, message));
        return;
    }
    m_frame->navigationScheduler().scheduleRedirect(delay, refreshURL);
}

Project: Chrome

void Document::mediaQueryAffectingValueChanged()
{
    styleResolverChanged();
    m_evaluateMediaQueriesOnStyleRecalc = true;
    styleEngine().clearMediaQueryRuleSetStyleSheets();
    InspectorInstrumentation::mediaQueryResultChanged(this);
}

Project: Chrome

MediaQueryMatcher& Document::mediaQueryMatcher()
{
    if (!m_mediaQueryMatcher)
        m_mediaQueryMatcher = MediaQueryMatcher::create(*this);
    return *m_mediaQueryMatcher;
}

Project: Chrome

void Document::modifiedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
{
    if (isActive())
        styleEngine().modifiedStyleSheet(sheet);
    styleResolverChanged(updateMode);
}

Project: Chrome

void Document::moveNodeIteratorsToNewDocument(Node& node, Document& newDocument)
{
    WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator>> nodeIteratorsList = m_nodeIterators;
    for (NodeIterator* ni : nodeIteratorsList) {
        if (ni->root() == node) {
            detachNodeIterator(ni);
            newDocument.attachNodeIterator(ni);
        }
    }
}

Project: Chrome

static LayoutObject* nearestCommonHoverAncestor(LayoutObject* obj1, LayoutObject* obj2)
{
    if (!obj1 || !obj2)
        return 0;

    for (LayoutObject* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
        for (LayoutObject* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
            if (currObj1 == currObj2)
                return currObj1;
        }
    }

    return 0;
}

Project: Chrome

bool Document::needsFullLayoutTreeUpdate() const
{
    if (!isActive() || !view())
        return false;
    if (!m_useElementsNeedingUpdate.isEmpty())
        return true;
    if (!m_layerUpdateSVGFilterElements.isEmpty())
        return true;
    if (needsStyleRecalc())
        return true;
    if (needsStyleInvalidation())
        return true;
    if (childNeedsDistributionRecalc())
        return true;
    if (DocumentAnimations::needsAnimationTimingUpdate(*this))
        return true;
    return false;
}

Project: Chrome

bool Document::needsLayoutTreeUpdate() const
{
    if (!isActive() || !view())
        return false;
    if (needsFullLayoutTreeUpdate())
        return true;
    if (childNeedsStyleRecalc())
        return true;
    if (childNeedsStyleInvalidation())
        return true;
    if (layoutView()->wasNotifiedOfSubtreeChange())
        return true;
    return false;
}

Project: Chrome

void Document::nodeChildrenWillBeRemoved(ContainerNode& container)
{
    EventDispatchForbiddenScope assertNoEventDispatch;
    for (Range* range : m_ranges)
        range->nodeChildrenWillBeRemoved(container);

    for (NodeIterator* ni : m_nodeIterators) {
        for (Node& n : NodeTraversal::childrenOf(container))
            ni->nodeWillBeRemoved(n);
    }

    if (LocalFrame* frame = this->frame()) {
        for (Node& n : NodeTraversal::childrenOf(container)) {
            frame->eventHandler().nodeWillBeRemoved(n);
            frame->selection().nodeWillBeRemoved(n);
            frame->page()->dragCaretController().nodeWillBeRemoved(n);
        }
    }
}

Project: Chrome

void Document::nodeWillBeRemoved(Node& n)
{
    for (NodeIterator* ni : m_nodeIterators)
        ni->nodeWillBeRemoved(n);

    for (Range* range : m_ranges)
        range->nodeWillBeRemoved(n);

    if (LocalFrame* frame = this->frame()) {
        frame->eventHandler().nodeWillBeRemoved(n);
        frame->selection().nodeWillBeRemoved(n);
        frame->page()->dragCaretController().nodeWillBeRemoved(n);
    }
}

Project: Chrome

void Document::notifyLayoutTreeOfSubtreeChanges()
{
    if (!layoutView()->wasNotifiedOfSubtreeChange())
        return;

    m_lifecycle.advanceTo(DocumentLifecycle::InLayoutSubtreeChange);

    layoutView()->handleSubtreeModifications();
    ASSERT(!layoutView()->wasNotifiedOfSubtreeChange());

    m_lifecycle.advanceTo(DocumentLifecycle::LayoutSubtreeChangeClean);
}

Project: Chrome

void Document::notifyResizeForViewportUnits()
{
    if (m_mediaQueryMatcher)
        m_mediaQueryMatcher->viewportChanged();
    if (!hasViewportUnits())
        return;
    ensureStyleResolver().notifyResizeForViewportUnits();
    setNeedsStyleRecalcForViewportUnits();
}

Project: Chrome

void Document::open(Document* enteredDocument, ExceptionState& exceptionState)
{
    if (importLoader()) {
        exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support open().");
        return;
    }

    if (!isHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "Only HTML documents support open().");
        return;
    }

    if (enteredDocument) {
        if (!securityOrigin()->canAccess(enteredDocument->securityOrigin())) {
            exceptionState.throwSecurityError("Can only call open() on same-origin documents.");
            return;
        }
        setSecurityOrigin(enteredDocument->securityOrigin());
        setURL(enteredDocument->url());
        m_cookieURL = enteredDocument->cookieURL();
    }

    open();
}

Project: Chrome

KURL Document::openSearchDescriptionURL()
{
    static const char openSearchMIMEType[] = "application/opensearchdescription+xml";
    static const char openSearchRelation[] = "search";

    if (!frame() || frame()->tree().parent())
        return KURL();

    if (!loadEventFinished())
        return KURL();

    if (!head())
        return KURL();

    for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head()); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
        if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
            continue;
        if (linkElement->href().isEmpty())
            continue;
        return linkElement->href();
    }

    return KURL();
}

Project: Chrome

String Document::outgoingOrigin() const
{
    return securityOrigin()->toString();
}

Project: Chrome

String Document::outgoingReferrer() const
{
    if (securityOrigin()->isUnique()) {
        return String();
    }

    const Document* referrerDocument = this;
    if (LocalFrame* frame = m_frame) {
        while (frame->document()->isSrcdocDocument()) {
            frame = toLocalFrame(frame->tree().parent());
            ASSERT(frame);
        }
        referrerDocument = frame->document();
    }
    return referrerDocument->m_url.strippedForUseAsReferrer();
}

Project: Chrome

HTMLFrameOwnerElement* Document::ownerElement() const
{
    if (!frame())
        return 0;
    return frame()->deprecatedLocalOwner();
}

Project: Chrome

void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
{
    RefPtr<ComputedStyle> style = styleForPage(pageIndex);

    int width = pageSize.width();
    int height = pageSize.height();
    switch (style->pageSizeType()) {
    case PAGE_SIZE_AUTO:
        break;
    case PAGE_SIZE_AUTO_LANDSCAPE:
        if (width < height)
            std::swap(width, height);
        break;
    case PAGE_SIZE_AUTO_PORTRAIT:
        if (width > height)
            std::swap(width, height);
        break;
    case PAGE_SIZE_RESOLVED: {
        FloatSize size = style->pageSize();
        width = size.width();
        height = size.height();
        break;
    }
    default:
        ASSERT_NOT_REACHED();
    }
    pageSize = IntSize(width, height);

    marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width);
    marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width);
    marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width);
    marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width);
}

Project: Chrome

PageVisibilityState Document::pageVisibilityState() const
{
    if (!m_frame || !m_frame->page())
        return PageVisibilityStateHidden;
    return m_frame->page()->visibilityState();
}

Project: Chrome

bool Document::parseQualifiedName(const AtomicString& qualifiedName, AtomicString& prefix, AtomicString& localName, ExceptionState& exceptionState)
{
    unsigned length = qualifiedName.length();

    if (!length) {
        exceptionState.throwDOMException(InvalidCharacterError, "The qualified name provided is empty.");
        return false;
    }

    ParseQualifiedNameResult returnValue;
    if (qualifiedName.is8Bit())
        returnValue = parseQualifiedNameInternal(qualifiedName, qualifiedName.characters8(), length, prefix, localName);
    else
        returnValue = parseQualifiedNameInternal(qualifiedName, qualifiedName.characters16(), length, prefix, localName);
    if (returnValue.status == QNValid)
        return true;

    StringBuilder message;
    message.appendLiteral("The qualified name provided ('");
    message.append(qualifiedName);
    message.appendLiteral("') ");

    if (returnValue.status == QNMultipleColons) {
        message.appendLiteral("contains multiple colons.");
    } else if (returnValue.status == QNInvalidStartChar) {
        message.appendLiteral("contains the invalid name-start character '");
        message.append(returnValue.character);
        message.appendLiteral("'.");
    } else if (returnValue.status == QNInvalidChar) {
        message.appendLiteral("contains the invalid character '");
        message.append(returnValue.character);
        message.appendLiteral("'.");
    } else if (returnValue.status == QNEmptyPrefix) {
        message.appendLiteral("has an empty namespace prefix.");
    } else {
        ASSERT(returnValue.status == QNEmptyLocalName);
        message.appendLiteral("has an empty local name.");
    }

    if (returnValue.status == QNInvalidStartChar || returnValue.status == QNInvalidChar)
        exceptionState.throwDOMException(InvalidCharacterError, message.toString());
    else
        exceptionState.throwDOMException(NamespaceError, message.toString());
    return false;
}

Project: Chrome

static ParseQualifiedNameResult parseQualifiedNameInternal(const AtomicString& qualifiedName, const CharType* characters, unsigned length, AtomicString& prefix, AtomicString& localName)
{
    bool nameStart = true;
    bool sawColon = false;
    int colonPos = 0;

    for (unsigned i = 0; i < length;) {
        UChar32 c;
        U16_NEXT(characters, i, length, c)
        if (c == ':') {
            if (sawColon)
                return ParseQualifiedNameResult(QNMultipleColons);
            nameStart = true;
            sawColon = true;
            colonPos = i - 1;
        } else if (nameStart) {
            if (!isValidNameStart(c))
                return ParseQualifiedNameResult(QNInvalidStartChar, c);
            nameStart = false;
        } else {
            if (!isValidNamePart(c))
                return ParseQualifiedNameResult(QNInvalidChar, c);
        }
    }

    if (!sawColon) {
        prefix = nullAtom;
        localName = qualifiedName;
    } else {
        prefix = AtomicString(characters, colonPos);
        if (prefix.isEmpty())
            return ParseQualifiedNameResult(QNEmptyPrefix);
        int prefixStart = colonPos + 1;
        localName = AtomicString(characters + prefixStart, length - prefixStart);
    }

    if (localName.isEmpty())
        return ParseQualifiedNameResult(QNEmptyLocalName);

    return ParseQualifiedNameResult(QNValid);
}

Project: Chrome

void Document::platformColorsChanged()
{
    if (!isActive())
        return;

    styleEngine().platformColorsChanged();
}

Project: Chrome

void Document::pluginLoadingTimerFired(Timer<Document>*)
{
    updateLayout();
}

Project: Chrome

Element* Document::pointerLockElement() const
{
    if (!page() || page()->pointerLockController().lockPending())
        return 0;
    if (Element* element = page()->pointerLockController().element()) {
        if (element->document() == this)
            return element;
    }
    return 0;
}

Project: Chrome

void Document::postInspectorTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task)
{
    m_taskRunner->postInspectorTask(location, task);
}

Project: Chrome

void Document::postTask(const WebTraceLocation& location, PassOwnPtr<ExecutionContextTask> task)
{
    m_taskRunner->postTask(location, task);
}

Project: Chrome

MouseEventWithHitTestResults Document::prepareMouseEvent(const HitTestRequest& request, const LayoutPoint& documentPoint, const PlatformMouseEvent& event)
{
    ASSERT(!layoutView() || layoutView()->isLayoutView());

    if (!layoutView() || !view() || !view()->didFirstLayout())
        return MouseEventWithHitTestResults(event, HitTestResult(request, LayoutPoint()));

    HitTestResult result(request, documentPoint);
    layoutView()->hitTest(result);

    if (!request.readOnly())
        updateHoverActiveState(request, result.innerElement());

    return MouseEventWithHitTestResults(event, result);
}

Project: Chrome

void Document::processBaseElement()
{
    const AtomicString* href = 0;
    const AtomicString* target = 0;
    for (HTMLBaseElement* base = Traversal<HTMLBaseElement>::firstWithin(*this); base && (!href || !target); base = Traversal<HTMLBaseElement>::next(*base)) {
        if (!href) {
            const AtomicString& value = base->fastGetAttribute(hrefAttr);
            if (!value.isNull())
                href = &value;
        }
        if (!target) {
            const AtomicString& value = base->fastGetAttribute(targetAttr);
            if (!value.isNull())
                target = &value;
        }
        if (contentSecurityPolicy()->isActive())
            UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
    }

    KURL baseElementURL;
    if (href) {
        String strippedHref = stripLeadingAndTrailingHTMLSpaces(*href);
        if (!strippedHref.isEmpty())
            baseElementURL = KURL(url(), strippedHref);
    }
    if (m_baseElementURL != baseElementURL && contentSecurityPolicy()->allowBaseURI(baseElementURL)) {
        m_baseElementURL = baseElementURL;
        updateBaseURL();
    }

    m_baseTarget = target ? *target : nullAtom;
}

Project: Chrome

bool Document::queryCommandEnabled(const String& commandName, ExceptionState& exceptionState)
{
    if (!isHTMLDocument() && !isXHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "queryCommandEnabled is only supported on HTML documents.");
        return false;
    }

    return command(this, commandName).isEnabled();
}

Project: Chrome

bool Document::queryCommandIndeterm(const String& commandName, ExceptionState& exceptionState)
{
    if (!isHTMLDocument() && !isXHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "queryCommandIndeterm is only supported on HTML documents.");
        return false;
    }

    return command(this, commandName).state() == MixedTriState;
}

Project: Chrome

bool Document::queryCommandState(const String& commandName, ExceptionState& exceptionState)
{
    if (!isHTMLDocument() && !isXHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "queryCommandState is only supported on HTML documents.");
        return false;
    }

    return command(this, commandName).state() == TrueTriState;
}

Project: Chrome

bool Document::queryCommandSupported(const String& commandName, ExceptionState& exceptionState)
{
    if (!isHTMLDocument() && !isXHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "queryCommandSupported is only supported on HTML documents.");
        return false;
    }

    return command(this, commandName).isSupported();
}

Project: Chrome

String Document::queryCommandValue(const String& commandName, ExceptionState& exceptionState)
{
    if (!isHTMLDocument() && !isXHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "queryCommandValue is only supported on HTML documents.");
        return "";
    }

    return command(this, commandName).value();
}

Project: Chrome

const AtomicString& Document::referrer() const
{
    if (loader())
        return loader()->request().httpReferrer();
    return nullAtom;
}

Project: Chrome

ScriptValue Document::registerElement(ScriptState* scriptState, const AtomicString& name, const ElementRegistrationOptions& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
{
    OriginsUsingFeatures::countMainWorldOnly(scriptState, *this, OriginsUsingFeatures::Feature::DocumentRegisterElement);

    if (!registrationContext()) {
        exceptionState.throwDOMException(NotSupportedError, "No element registration context is available.");
        return ScriptValue();
    }

    CustomElementConstructorBuilder constructorBuilder(scriptState, options);
    registrationContext()->registerElement(this, &constructorBuilder, name, validNames, exceptionState);
    return constructorBuilder.bindingsReturnValue();
}

Project: Chrome

void Document::registerNodeList(const LiveNodeListBase* list)
{
#if ENABLE(OILPAN)
    m_nodeLists[list->invalidationType()].add(list);
#else
    m_nodeListCounts[list->invalidationType()]++;
#endif
    if (list->isRootedAtTreeScope())
        m_listsInvalidatedAtDocument.add(list);
}

Project: Chrome

void Document::registerNodeListWithIdNameCache(const LiveNodeListBase* list)
{
#if ENABLE(OILPAN)
    m_nodeLists[InvalidateOnIdNameAttrChange].add(list);
#else
    m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
#endif
}

Project: Chrome

void Document::registerVisibilityObserver(DocumentVisibilityObserver* observer)
{
    ASSERT(!m_visibilityObservers.contains(observer));
    m_visibilityObservers.add(observer);
}

Project: Chrome

void Document::removeAllEventListeners()
{
    ContainerNode::removeAllEventListeners();

    if (LocalDOMWindow* domWindow = this->domWindow())
        domWindow->removeAllEventListeners();
}

Project: Chrome

void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
{
    if (!m_focusedElement)
        return;

    if (!node->inDocument())
        return;
    bool contains = node->containsIncludingShadowDOM(m_focusedElement.get());
    if (contains && (m_focusedElement != node || !amongChildrenOnly))
        clearFocusedElement();
}

Project: Chrome

void Document::removeFormAssociation(Element* element)
{
    auto it = m_associatedFormControls.find(element);
    if (it == m_associatedFormControls.end())
        return;
    m_associatedFormControls.remove(it);
    if (m_associatedFormControls.isEmpty())
        m_didAssociateFormControlsTimer.stop();
}

Project: Chrome

void Document::removeTitle(Element* titleElement)
{
    if (m_titleElement != titleElement)
        return;

    m_titleElement = nullptr;

    if (isHTMLDocument() || isXHTMLDocument()) {
        if (HTMLTitleElement* title = Traversal<HTMLTitleElement>::firstWithin(*this))
            setTitleElement(title);
    } else if (isSVGDocument()) {
        if (SVGTitleElement* title = Traversal<SVGTitleElement>::firstWithin(*this))
            setTitleElement(title);
    }

    if (!m_titleElement)
        updateTitle(String());
}

Project: Chrome

void Document::removedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
{
    if (isActive())
        styleEngine().modifiedStyleSheet(sheet);
    styleResolverChanged(updateMode);
}

Project: Chrome

void Document::reportBlockedScriptExecutionToInspector(const String& directiveText)
{
    InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
}

Project: Chrome

int Document::requestAnimationFrame(FrameRequestCallback* callback)
{
    return ensureScriptedAnimationController().registerCallback(callback);
}

Project: Chrome

int Document::requestIdleCallback(IdleRequestCallback* callback, const IdleRequestOptions& options)
{
    return ensureScriptedIdleTaskController().registerCallback(callback, options);
}

Project: Chrome

void Document::resumeScheduledTasks()
{
    ExecutionContext::resumeScheduledTasks();
    m_taskRunner->resume();
}

Project: Chrome

void Document::scheduleLayoutTreeUpdate()
{
    ASSERT(!hasPendingStyleRecalc());
    ASSERT(shouldScheduleLayoutTreeUpdate());
    ASSERT(needsLayoutTreeUpdate());

    if (!view()->shouldThrottleRendering())
        page()->animator().scheduleVisualUpdate(frame());
    m_lifecycle.ensureStateAtMost(DocumentLifecycle::VisualUpdatePending);

    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScheduleStyleRecalculation", TRACE_EVENT_SCOPE_THREAD, "data", InspectorRecalculateStylesEvent::data(frame()));
    InspectorInstrumentation::didScheduleStyleRecalculation(this);

    ++m_styleVersion;
}

Project: Chrome

void Document::scheduleSVGFilterLayerUpdateHack(Element& element)
{
    if (element.styleChangeType() == NeedsReattachStyleChange)
        return;
    element.setSVGFilterNeedsLayerUpdate();
    m_layerUpdateSVGFilterElements.add(&element);
    scheduleLayoutTreeUpdateIfNeeded();
}

Project: Chrome

void Document::scheduleUseShadowTreeUpdate(SVGUseElement& element)
{
    m_useElementsNeedingUpdate.add(&element);
    scheduleLayoutTreeUpdateIfNeeded();
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLCollection> Document::scripts()
{
    return ensureCachedCollection<HTMLCollection>(DocScripts);
}

Project: Chrome

Element* Document::scrollingElement()
{
    if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
        if (inQuirksMode()) {
            updateLayoutTreeIfNeeded();
            HTMLBodyElement* body = firstBodyElement();
            if (body && body->layoutObject() && body->layoutObject()->hasOverflowClip())
                return nullptr;

            return body;
        }

        return documentElement();
    }

    return body();
}

Project: Chrome

SelectorQueryCache& Document::selectorQueryCache()
{
    if (!m_selectorQueryCache)
        m_selectorQueryCache = adoptPtr(new SelectorQueryCache());
    return *m_selectorQueryCache;
}

Project: Chrome

void Document::setActiveHoverElement(PassRefPtrWillBeRawPtr<Element> newActiveElement)
{
    if (!newActiveElement) {
        m_activeHoverElement.clear();
        return;
    }

    m_activeHoverElement = newActiveElement;
}

Project: Chrome

void Document::setAutofocusElement(Element* element)
{
    if (!element) {
        m_autofocusElement = nullptr;
        return;
    }
    if (m_hasAutofocused)
        return;
    m_hasAutofocused = true;
    ASSERT(!m_autofocusElement);
    m_autofocusElement = element;
    m_taskRunner->postTask(BLINK_FROM_HERE, AutofocusTask::create());
}

Project: Chrome

void Document::setBody(PassRefPtrWillBeRawPtr<HTMLElement> prpNewBody, ExceptionState& exceptionState)
{
    RefPtrWillBeRawPtr<HTMLElement> newBody = prpNewBody;

    if (!newBody) {
        exceptionState.throwDOMException(HierarchyRequestError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLElement"));
        return;
    }
    if (!documentElement()) {
        exceptionState.throwDOMException(HierarchyRequestError, "No document element exists.");
        return;
    }

    if (!isHTMLBodyElement(*newBody) && !isHTMLFrameSetElement(*newBody)) {
        exceptionState.throwDOMException(HierarchyRequestError, "The new body element is of type '" + newBody->tagName() + "'. It must be either a 'BODY' or 'FRAMESET' element.");
        return;
    }

    HTMLElement* oldBody = body();
    if (oldBody == newBody)
        return;

    if (oldBody)
        documentElement()->replaceChild(newBody.release(), oldBody, exceptionState);
    else
        documentElement()->appendChild(newBody.release(), exceptionState);
}

Project: Chrome

void Document::setCSSTarget(Element* newTarget)
{
    if (m_cssTarget)
        m_cssTarget->pseudoStateChanged(CSSSelector::PseudoTarget);
    m_cssTarget = newTarget;
    if (m_cssTarget)
        m_cssTarget->pseudoStateChanged(CSSSelector::PseudoTarget);
}

Project: Chrome

void Document::setCompatibilityMode(CompatibilityMode mode)
{
    if (m_compatibilityModeLocked || mode == m_compatibilityMode)
        return;
    m_compatibilityMode = mode;
    selectorQueryCache().invalidate();
}

Project: Chrome

void Document::setContent(const String& content)
{
    open();
    m_parser->append(content);
    close();
}

Project: Chrome

void Document::setContentLanguage(const AtomicString& language)
{
    if (m_contentLanguage == language)
        return;
    m_contentLanguage = language;

    setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Language));
}

Project: Chrome

void Document::setDesignMode(const String& value)
{
    bool newValue = m_designMode;
    if (equalIgnoringCase(value, "on")) {
        newValue = true;
        UseCounter::count(*this, UseCounter::DocumentDesignModeEnabeld);
    } else if (equalIgnoringCase(value, "off")) {
        newValue = false;
    }
    if (newValue == m_designMode)
        return;
    m_designMode = newValue;
    setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::DesignMode));
}

Project: Chrome

void Document::setDir(const AtomicString& value)
{
    Element* rootElement = documentElement();
    if (isHTMLHtmlElement(rootElement))
        toHTMLHtmlElement(rootElement)->setDir(value);
}

Project: Chrome

void Document::setDomain(const String& newDomain, ExceptionState& exceptionState)
{
    UseCounter::count(*this, UseCounter::DocumentSetDomain);

    if (isSandboxed(SandboxDocumentDomain)) {
        exceptionState.throwSecurityError("Assignment is forbidden for sandboxed iframes.");
        return;
    }

    if (SchemeRegistry::isDomainRelaxationForbiddenForURLScheme(securityOrigin()->protocol())) {
        exceptionState.throwSecurityError("Assignment is forbidden for the '" + securityOrigin()->protocol() + "' scheme.");
        return;
    }

    if (newDomain.isEmpty()) {
        exceptionState.throwSecurityError("'" + newDomain + "' is an empty domain.");
        return;
    }

    OriginAccessEntry accessEntry(securityOrigin()->protocol(), newDomain, OriginAccessEntry::AllowSubdomains);
    OriginAccessEntry::MatchResult result = accessEntry.matchesOrigin(*securityOrigin());
    if (result == OriginAccessEntry::DoesNotMatchOrigin) {
        exceptionState.throwSecurityError("'" + newDomain + "' is not a suffix of '" + domain() + "'.");
        return;
    }

    if (result == OriginAccessEntry::MatchesOriginButIsPublicSuffix) {
        exceptionState.throwSecurityError("'" + newDomain + "' is a top-level domain.");
        return;
    }

    securityOrigin()->setDomainFromDOM(newDomain);
    if (m_frame)
        m_frame->script().updateSecurityOrigin(securityOrigin());
}

Project: Chrome

void Document::setEncodingData(const DocumentEncodingData& newData)
{
    if (m_titleElement
        && encoding() != newData.encoding()
        && !ElementTraversal::firstWithin(*m_titleElement)
        && encoding() == Latin1Encoding()
        && m_titleElement->textContent().containsOnlyLatin1()) {

        CString originalBytes = m_titleElement->textContent().latin1();
        OwnPtr<TextCodec> codec = newTextCodec(newData.encoding());
        String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), DataEOF);
        m_titleElement->setTextContent(correctlyDecodedTitle);
    }

    ASSERT(newData.encoding().isValid());
    m_encodingData = newData;

    bool shouldUseVisualOrdering = m_encodingData.encoding().usesVisualOrdering();
    if (shouldUseVisualOrdering != m_visuallyOrdered) {
        m_visuallyOrdered = shouldUseVisualOrdering;
        if (layoutView())
            layoutView()->mutableStyleRef().setRTLOrdering(m_visuallyOrdered ? VisualOrder : LogicalOrder);
        setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::VisuallyOrdered));
    }
}

Project: Chrome

bool Document::setFocusedElement(PassRefPtrWillBeRawPtr<Element> prpNewFocusedElement, const FocusParams& params)
{
    ASSERT(!m_lifecycle.inDetach());

    m_clearFocusedElementTimer.stop();

    RefPtrWillBeRawPtr<Element> newFocusedElement = prpNewFocusedElement;

    if (newFocusedElement && (newFocusedElement->document() != this))
        return true;

    if (NodeChildRemovalTracker::isBeingRemoved(newFocusedElement.get()))
        return true;

    if (m_focusedElement == newFocusedElement)
        return true;

    bool focusChangeBlocked = false;
    RefPtrWillBeRawPtr<Element> oldFocusedElement = m_focusedElement;
    m_focusedElement = nullptr;

    if (oldFocusedElement) {
        if (oldFocusedElement->active())
            oldFocusedElement->setActive(false);

        oldFocusedElement->setFocus(false);

        if (page() && (page()->focusController().isFocused())) {
            oldFocusedElement->dispatchBlurEvent(newFocusedElement.get(), params.type, params.sourceCapabilities);

            if (m_focusedElement) {
                focusChangeBlocked = true;
                newFocusedElement = nullptr;
            }

            oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, newFocusedElement.get(), params.sourceCapabilities); // DOM level 3 name for the bubbling blur event.
            oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, newFocusedElement.get(), params.sourceCapabilities); // DOM level 2 name for compatibility.

            if (m_focusedElement) {
                focusChangeBlocked = true;
                newFocusedElement = nullptr;
            }
            if (newFocusedElement)
                updateLayoutTreeIgnorePendingStylesheets();
        }

        if (view()) {
            Widget* oldWidget = widgetForElement(*oldFocusedElement);
            if (oldWidget)
                oldWidget->setFocus(false, params.type);
            else
                view()->setFocus(false, params.type);
        }
    }

    if (newFocusedElement && newFocusedElement->isFocusable()) {
        if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(*newFocusedElement)) {
            focusChangeBlocked = true;
            goto SetFocusedElementDone;
        }
        m_focusedElement = newFocusedElement;

        m_focusedElement->setFocus(true);
        cancelFocusAppearanceUpdate();
        m_focusedElement->updateFocusAppearance(params.selectionBehavior);

        if (page() && (page()->focusController().isFocused())) {
            m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), params.type, params.sourceCapabilities);


            if (m_focusedElement != newFocusedElement) {
                focusChangeBlocked = true;
                goto SetFocusedElementDone;
            }
            m_focusedElement->dispatchFocusInEvent(EventTypeNames::focusin, oldFocusedElement.get(), params.type, params.sourceCapabilities); // DOM level 3 bubbling focus event.

            if (m_focusedElement != newFocusedElement) {
                focusChangeBlocked = true;
                goto SetFocusedElementDone;
            }

            m_focusedElement->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, oldFocusedElement.get(), params.type, params.sourceCapabilities); // DOM level 2 for compatibility.

            if (m_focusedElement != newFocusedElement) {
                focusChangeBlocked = true;
                goto SetFocusedElementDone;
            }
        }

        if (m_focusedElement->isRootEditableElement())
            frame()->spellChecker().didBeginEditing(m_focusedElement.get());

        if (view()) {
            Widget* focusWidget = widgetForElement(*m_focusedElement);
            if (focusWidget) {
                updateLayout();
                focusWidget = widgetForElement(*m_focusedElement);
            }
            if (focusWidget)
                focusWidget->setFocus(true, params.type);
            else
                view()->setFocus(true, params.type);
        }
    }

    if (!focusChangeBlocked && m_focusedElement) {
        if (AXObjectCache* cache = axObjectCache())
            cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFocusedElement.get());
    }

    if (!focusChangeBlocked && frameHost())
        frameHost()->chromeClient().focusedNodeChanged(oldFocusedElement.get(), m_focusedElement.get());

SetFocusedElementDone:
    updateLayoutTreeIfNeeded();
    if (LocalFrame* frame = this->frame())
        frame->selection().didChangeFocus();
    return !focusChangeBlocked;
}

Project: Chrome

void Document::setHoverNode(PassRefPtrWillBeRawPtr<Node> newHoverNode)
{
    m_hoverNode = newHoverNode;
}

Project: Chrome

void Document::setImportsController(HTMLImportsController* controller)
{
    ASSERT(!m_importsController || !controller);
    m_importsController = controller;
    if (!m_importsController && !loader())
        m_fetcher->clearContext();
}

Project: Chrome

void Document::setMimeType(const AtomicString& mimeType)
{
    m_mimeType = mimeType;
}

Project: Chrome

void Document::setNeedsFocusedElementCheck()
{
    setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::createWithExtraData(StyleChangeReason::PseudoClass, StyleChangeExtraData::Focus));
}

Project: Chrome

void Document::setParsingState(ParsingState parsingState)
{
    m_parsingState = parsingState;

    if (parsing() && !m_elementDataCache)
        m_elementDataCache = ElementDataCache::create();
}

Project: Chrome

void Document::setReadyState(ReadyState readyState)
{
    if (readyState == m_readyState)
        return;

    switch (readyState) {
    case Loading:
        if (!m_documentTiming.domLoading()) {
            m_documentTiming.markDomLoading();
        }
        break;
    case Interactive:
        if (!m_documentTiming.domInteractive())
            m_documentTiming.markDomInteractive();
        break;
    case Complete:
        if (!m_documentTiming.domComplete())
            m_documentTiming.markDomComplete();
        break;
    }

    m_readyState = readyState;
    dispatchEvent(Event::create(EventTypeNames::readystatechange));
}

Project: Chrome

void Document::setStateForNewFormElements(const Vector<String>& stateVector)
{
    if (!stateVector.size() && !m_formController)
        return;
    formController().setStateForNewFormElements(stateVector);
}

Project: Chrome

void Document::setThreadedParsingEnabledForTesting(bool enabled)
{
    s_threadedParsingEnabledForTesting = enabled;
}

Project: Chrome

void Document::setTitle(const String& title)
{
    if (!isHTMLDocument() && !isXHTMLDocument()) {
        m_titleElement = nullptr;
    } else if (!m_titleElement) {
        HTMLElement* headElement = head();
        if (!headElement)
            return;
        m_titleElement = HTMLTitleElement::create(*this);
        headElement->appendChild(m_titleElement.get());
    }

    if (isHTMLTitleElement(m_titleElement))
        toHTMLTitleElement(m_titleElement)->setText(title);
    else
        updateTitle(title);
}

Project: Chrome

void Document::setTitleElement(Element* titleElement)
{
    if (m_titleElement && m_titleElement != titleElement) {
        if (isHTMLDocument() || isXHTMLDocument()) {
            m_titleElement = Traversal<HTMLTitleElement>::firstWithin(*this);
        } else if (isSVGDocument()) {
            m_titleElement = Traversal<SVGTitleElement>::firstWithin(*this);
        }
    } else {
        m_titleElement = titleElement;
    }

    if (isHTMLTitleElement(m_titleElement))
        updateTitle(toHTMLTitleElement(m_titleElement)->text());
    else if (isSVGTitleElement(m_titleElement))
        updateTitle(toSVGTitleElement(m_titleElement)->textContent());
}

Project: Chrome

void Document::setURL(const KURL& url)
{
    const KURL& newURL = url.isEmpty() ? blankURL() : url;
    if (newURL == m_url)
        return;

    m_url = newURL;
    m_accessEntryFromURL = nullptr;
    updateBaseURL();
    contextFeatures().urlDidChange(this);
}

Project: Chrome

void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtrWillBeRawPtr<EventListener> listener)
{
    LocalDOMWindow* domWindow = this->domWindow();
    if (!domWindow)
        return;
    domWindow->setAttributeEventListener(eventType, listener);
}

Project: Chrome

void Document::setXMLStandalone(bool standalone, ExceptionState& exceptionState)
{
    m_xmlStandalone = standalone ? Standalone : NotStandalone;
}

Project: Chrome

void Document::setXMLVersion(const String& version, ExceptionState& exceptionState)
{
    if (!XMLDocumentParser::supportsXMLVersion(version)) {
        exceptionState.throwDOMException(NotSupportedError, "This document does not support the XML version '" + version + "'.");
        return;
    }

    m_xmlVersion = version;
}

Project: Chrome

void Document::setupFontBuilder(ComputedStyle& documentStyle)
{
    FontBuilder fontBuilder(*this);
    RefPtrWillBeRawPtr<CSSFontSelector> selector = styleEngine().fontSelector();
    fontBuilder.createFontForDocument(selector, documentStyle);
}

Project: Chrome

static bool shouldInheritSecurityOriginFromOwner(const KURL& url)
{
    return url.isEmpty() || url.protocolIsAbout();
}

Project: Chrome

bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
{
    if (attrName) {
#if ENABLE(OILPAN)
        return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeLists, *attrName);
#else
        return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
#endif
    }

    for (int type = 0; type < numNodeListInvalidationTypes; ++type) {
#if ENABLE(OILPAN)
        if (!m_nodeLists[type].isEmpty())
#else
        if (m_nodeListCounts[type])
#endif
            return true;
    }

    return false;
}

Project: Chrome

bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const HeapHashSet<WeakMember<const LiveNodeListBase>>[], const QualifiedName&)
{
    return false;
}

Project: Chrome

bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
{
    if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
        return true;
    return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
}

Project: Chrome

bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
{
    return false;
}

Project: Chrome

bool Document::shouldMergeWithLegacyDescription(ViewportDescription::Type origin)
{
    return settings() && settings()->viewportMetaMergeContentQuirk() && m_legacyViewportDescription.isMetaViewportType() && m_legacyViewportDescription.type == origin;
}

Project: Chrome

bool Document::shouldScheduleLayout() const
{
    if (!isActive())
        return false;

    if (isRenderingReady() && body())
        return true;

    if (documentElement() && !isHTMLHtmlElement(*documentElement()))
        return true;

    return false;
}

Project: Chrome

bool Document::shouldScheduleLayoutTreeUpdate() const
{
    if (!isActive())
        return false;
    if (inStyleRecalc())
        return false;
    if (m_lifecycle.state() == DocumentLifecycle::InPreLayout)
        return false;
    if (!shouldScheduleLayout())
        return false;
    return true;
}

Project: Chrome

void showLiveDocumentInstances()
{
    Document::WeakDocumentSet& set = Document::liveDocumentSet();
    fprintf(stderr, "There are %u documents currently alive:\n", set.size());
    for (Document* document : set)
        fprintf(stderr, "- Document %p URL: %s\n", document, document->url().string().utf8().data());
}

Project: Chrome

PassRefPtr<ComputedStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
{
    ASSERT_ARG(element, element->document() == this);
    StyleEngine::IgnoringPendingStylesheet ignoring(styleEngine());
    return ensureStyleResolver().styleForElement(element, element->parentNode() ? element->parentNode()->ensureComputedStyle() : 0);
}

Project: Chrome

PassRefPtr<ComputedStyle> Document::styleForPage(int pageIndex)
{
    updateDistribution();
    return ensureStyleResolver().styleForPage(pageIndex);
}

Project: Chrome

StyleResolver* Document::styleResolver() const
{
    return m_styleEngine->resolver();
}

Project: Chrome

void Document::styleResolverChanged(StyleResolverUpdateMode updateMode)
{
    styleEngine().resolverChanged(updateMode);

    if (didLayoutWithPendingStylesheets() && !styleEngine().hasPendingSheets()) {
        m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;

        ASSERT(layoutView() || importsController());
        if (layoutView())
            layoutView()->invalidatePaintForViewAndCompositedLayers();
    }
}

Project: Chrome

void Document::styleResolverMayHaveChanged()
{
    styleResolverChanged(hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate);
}

Project: Chrome

String Document::suggestedMIMEType() const
{
    if (isXMLDocument()) {
        if (isXHTMLDocument())
            return "application/xhtml+xml";
        if (isSVGDocument())
            return "image/svg+xml";
        return "application/xml";
    }
    if (xmlStandalone())
        return "text/xml";
    if (isHTMLDocument())
        return "text/html";

    if (DocumentLoader* documentLoader = loader())
        return documentLoader->responseMIMEType();
    return String();
}

Project: Chrome

void Document::suppressLoadEvent()
{
    if (!loadEventFinished())
        m_loadEventProgress = LoadEventCompleted;
}

Project: Chrome

void Document::suspendScheduledTasks()
{
    ExecutionContext::suspendScheduledTasks();
    m_taskRunner->suspend();
}

Project: Chrome

void Document::tasksWereSuspended()
{
    scriptRunner()->suspend();

    if (m_parser)
        m_parser->suspendScheduledTasks();
    if (m_scriptedAnimationController)
        m_scriptedAnimationController->suspend();
}

Project: Chrome

TextAutosizer* Document::textAutosizer()
{
    if (!m_textAutosizer)
        m_textAutosizer = TextAutosizer::create(this);
    return m_textAutosizer.get();
}

Project: Chrome

Color Document::themeColor() const
{
    for (HTMLMetaElement* metaElement = head() ? Traversal<HTMLMetaElement>::firstChild(*head()) : 0; metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
        Color color = Color::transparent;
        if (equalIgnoringCase(metaElement->name(), "theme-color") && CSSParser::parseColor(color, metaElement->content().string().stripWhiteSpace(), true))
            return color;
    }
    return Color();
}

Project: Chrome

WebTaskRunner* Document::timerTaskRunner() const
{
    if (frame())
        return m_frame->frameScheduler()->timerTaskRunner();
    if (m_importsController)
        return m_importsController->master()->timerTaskRunner();
    if (m_contextDocument)
        return m_contextDocument->timerTaskRunner();
    return Platform::current()->currentThread()->scheduler()->timerTaskRunner();
}

Project: Chrome

DOMTimerCoordinator* Document::timers()
{
    return &m_timers;
}

Project: Chrome

Document& Document::topDocument() const
{
    Document* doc = const_cast<Document*>(this);
    for (HTMLFrameOwnerElement* element = doc->ownerElement(); element; element = doc->ownerElement())
        doc = &element->document();

    ASSERT(doc);
    return *doc;
}

Project: Chrome

void Document::unregisterNodeList(const LiveNodeListBase* list)
{
#if ENABLE(OILPAN)
    ASSERT(m_nodeLists[list->invalidationType()].contains(list));
    m_nodeLists[list->invalidationType()].remove(list);
#else
    m_nodeListCounts[list->invalidationType()]--;
#endif
    if (list->isRootedAtTreeScope()) {
        ASSERT(m_listsInvalidatedAtDocument.contains(list));
        m_listsInvalidatedAtDocument.remove(list);
    }
}

Project: Chrome

void Document::unregisterNodeListWithIdNameCache(const LiveNodeListBase* list)
{
#if ENABLE(OILPAN)
    ASSERT(m_nodeLists[InvalidateOnIdNameAttrChange].contains(list));
    m_nodeLists[InvalidateOnIdNameAttrChange].remove(list);
#else
    ASSERT(m_nodeListCounts[InvalidateOnIdNameAttrChange] > 0);
    m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
#endif
}

Project: Chrome

void Document::unregisterVisibilityObserver(DocumentVisibilityObserver* observer)
{
    ASSERT(m_visibilityObservers.contains(observer));
    m_visibilityObservers.remove(observer);
}

Project: Chrome

void Document::unscheduleSVGFilterLayerUpdateHack(Element& element)
{
    element.clearSVGFilterNeedsLayerUpdate();
    m_layerUpdateSVGFilterElements.remove(&element);
}

Project: Chrome

void Document::unscheduleUseShadowTreeUpdate(SVGUseElement& element)
{
    m_useElementsNeedingUpdate.remove(&element);
}

Project: Chrome

void Document::updateBaseURL()
{
    KURL oldBaseURL = m_baseURL;
    if (!m_baseElementURL.isEmpty())
        m_baseURL = m_baseElementURL;
    else if (!m_baseURLOverride.isEmpty())
        m_baseURL = m_baseURLOverride;
    else
        m_baseURL = m_url;

    selectorQueryCache().invalidate();

    if (!m_baseURL.isValid())
        m_baseURL = KURL();

    if (m_elemSheet) {
        ASSERT(!m_elemSheet->contents()->ruleCount());
        m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
    }

    if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) {
        for (HTMLAnchorElement& anchor : Traversal<HTMLAnchorElement>::startsAfter(*this))
            anchor.invalidateCachedVisitedLinkHash();
    }
}

Project: Chrome

void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
{
    Element* element = focusedElement();
    if (!element)
        return;
    updateLayout();
    if (element->isFocusable())
        element->updateFocusAppearance(m_updateFocusAppearanceSelectionBahavior);
}

Project: Chrome

void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)
{
    DocumentLifecycle::PreventThrottlingScope preventThrottling(lifecycle());

    updateLayoutTreeIgnorePendingStylesheets();
    updateLayout();

    if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view())
        view()->flushAnyPendingPostLayoutTasks();
}

Project: Chrome

void Document::updateLayoutTree(StyleRecalcChange change)
{
    ASSERT(isMainThread());

    ScriptForbiddenScope forbidScript;

    if (!view() || !isActive())
        return;

    if (view()->shouldThrottleRendering())
        return;

    if (change != Force && !needsLayoutTreeUpdate()) {
        if (lifecycle().state() < DocumentLifecycle::StyleClean) {
            lifecycle().advanceTo(DocumentLifecycle::InStyleRecalc);
            lifecycle().advanceTo(DocumentLifecycle::StyleClean);
        }
        return;
    }

    if (inStyleRecalc())
        return;

    RELEASE_ASSERT(!view()->isInPerformLayout());
    RELEASE_ASSERT(!view()->isPainting());

    RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get());

    TRACE_EVENT_BEGIN1("blink,devtools.timeline", "UpdateLayoutTree", "beginData", InspectorRecalculateStylesEvent::data(frame()));
    TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "UpdateLayoutTree");

    unsigned startElementCount = styleEngine().styleForElementCount();

    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);

    DocumentAnimations::updateAnimationTimingIfNeeded(*this);
    evaluateMediaQueryListIfNeeded();
    updateUseShadowTreesIfNeeded();
    updateDistribution();
    updateStyleInvalidationIfNeeded();


    updateStyle(change);

    notifyLayoutTreeOfSubtreeChanges();

    if (hoverNode() && !hoverNode()->layoutObject() && frame())
        frame()->eventHandler().dispatchFakeMouseMoveEventSoon();

    if (m_focusedElement && !m_focusedElement->isFocusable())
        clearFocusedElementSoon();
    layoutView()->clearHitTestCache();

    ASSERT(!DocumentAnimations::needsAnimationTimingUpdate(*this));

    unsigned elementCount = styleEngine().styleForElementCount() - startElementCount;

    TRACE_EVENT_END1("blink,devtools.timeline", "UpdateLayoutTree", "elementCount", elementCount);
    InspectorInstrumentation::didRecalculateStyle(cookie, elementCount);

#if ENABLE(ASSERT)
    assertLayoutTreeUpdated(*this);
#endif
}

Project: Chrome

void Document::updateLayoutTreeForNodeIfNeeded(Node* node)
{
    ASSERT(node);
    if (!node->canParticipateInComposedTree())
        return;
    if (!needsLayoutTreeUpdate())
        return;
    if (!node->inDocument())
        return;

    bool needsRecalc = needsFullLayoutTreeUpdate() || node->needsStyleRecalc() || node->needsStyleInvalidation();

    if (!needsRecalc) {
        for (const ContainerNode* ancestor = LayoutTreeBuilderTraversal::parent(*node); ancestor && !needsRecalc; ancestor = LayoutTreeBuilderTraversal::parent(*ancestor))
            needsRecalc = ancestor->needsStyleRecalc() || ancestor->needsStyleInvalidation() || ancestor->needsAdjacentStyleRecalc();
    }

    if (needsRecalc)
        updateLayoutTreeIfNeeded();
}

Project: Chrome

void Document::updateLayoutTreeIgnorePendingStylesheets()
{
    StyleEngine::IgnoringPendingStylesheet ignoring(styleEngine());

    if (styleEngine().hasPendingSheets()) {
        HTMLElement* bodyElement = body();
        if (bodyElement && !bodyElement->layoutObject() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
            m_pendingSheetLayout = DidLayoutWithPendingSheets;
            styleResolverChanged();
        } else if (m_hasNodesWithPlaceholderStyle) {
            updateLayoutTree(Force);
        }
    }
    updateLayoutTreeIfNeeded();
}

Project: Chrome

void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
{
    for (Range* range : m_ranges)
        range->nodeChildrenChanged(container);
}

Project: Chrome

void Document::updateRangesAfterNodeMovedToAnotherDocument(const Node& node)
{
    ASSERT(node.document() != this);
    if (m_ranges.isEmpty())
        return;

    AttachedRangeSet ranges = m_ranges;
    for (Range* range : ranges)
        range->updateOwnerDocumentIfNeeded();
}

Project: Chrome

void Document::updateSecurityOrigin(PassRefPtr<SecurityOrigin> origin)
{
    setSecurityOrigin(origin);
    didUpdateSecurityOrigin();
}

Project: Chrome

void Document::updateStyleInvalidationIfNeeded()
{
    ScriptForbiddenScope forbidScript;

    if (!isActive())
        return;
    if (!childNeedsStyleInvalidation())
        return;
    TRACE_EVENT0("blink", "Document::updateStyleInvalidationIfNeeded");
    styleEngine().styleInvalidator().invalidate(*this);
}

Project: Chrome

void Document::updateTitle(const String& title)
{
    if (m_rawTitle == title)
        return;

    m_rawTitle = title;

    String oldTitle = m_title;
    if (m_rawTitle.isEmpty())
        m_title = String();
    else if (m_rawTitle.is8Bit())
        m_title = canonicalizedTitle<LChar>(this, m_rawTitle);
    else
        m_title = canonicalizedTitle<UChar>(this, m_rawTitle);

    if (!m_frame || oldTitle == m_title)
        return;
    m_frame->loader().client()->dispatchDidReceiveTitle(m_title);
}

Project: Chrome

void Document::updateUseShadowTreesIfNeeded()
{
    ScriptForbiddenScope forbidScript;

    if (m_useElementsNeedingUpdate.isEmpty())
        return;

    WillBeHeapVector<RawPtrWillBeMember<SVGUseElement>> elements;
    copyToVector(m_useElementsNeedingUpdate, elements);
    m_useElementsNeedingUpdate.clear();

    for (SVGUseElement* element : elements)
        element->buildPendingResource();
}

Project: Chrome

void Document::updateViewportDescription()
{
    if (frame() && frame()->isMainFrame()) {
        frameHost()->chromeClient().dispatchViewportPropertiesDidChange(m_viewportDescription);
    }
}

Project: Chrome

String Document::userAgent() const
{
    return frame() ? frame()->loader().userAgent() : String();
}

Project: Chrome

Element* Document::viewportDefiningElement(const ComputedStyle* rootStyle) const
{
    Element* rootElement = documentElement();
    Element* bodyElement = body();
    if (!rootElement)
        return 0;
    if (!rootStyle) {
        rootStyle = rootElement->computedStyle();
        if (!rootStyle)
            return 0;
    }
    if (bodyElement && rootStyle->isOverflowVisible() && isHTMLHtmlElement(*rootElement))
        return bodyElement;
    return rootElement;
}

Project: Chrome

String Document::visibilityState() const
{
    return pageVisibilityStateString(pageVisibilityState());
}

Project: Chrome

static Widget* widgetForElement(const Element& focusedElement)
{
    LayoutObject* layoutObject = focusedElement.layoutObject();
    if (!layoutObject || !layoutObject->isLayoutPart())
        return 0;
    return toLayoutPart(layoutObject)->widget();
}

Project: Chrome

PassRefPtrWillBeRawPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
{
    return ensureCachedCollection<WindowNameCollection>(WindowNamedItems, name);
}

Project: Chrome

void Document::write(const SegmentedString& text, Document* enteredDocument, ExceptionState& exceptionState)
{
    if (importLoader()) {
        exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support write().");
        return;
    }

    if (!isHTMLDocument()) {
        exceptionState.throwDOMException(InvalidStateError, "Only HTML documents support write().");
        return;
    }

    if (enteredDocument && !securityOrigin()->canAccess(enteredDocument->securityOrigin())) {
        exceptionState.throwSecurityError("Can only call write() on same-origin documents.");
        return;
    }

    NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);

    m_writeRecursionIsTooDeep = (m_writeRecursionDepth > 1) && m_writeRecursionIsTooDeep;
    m_writeRecursionIsTooDeep = (m_writeRecursionDepth > cMaxWriteRecursionDepth) || m_writeRecursionIsTooDeep;

    if (m_writeRecursionIsTooDeep)
        return;

    bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();

    if (!hasInsertionPoint && m_ignoreDestructiveWriteCount) {
        addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, ExceptionMessages::failedToExecute("write", "Document", "It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.")));
        return;
    }

    if (!hasInsertionPoint)
        open(enteredDocument, ASSERT_NO_EXCEPTION);

    ASSERT(m_parser);
    m_parser->insert(text);
}

Project: Chrome

void Document::write(const String& text, Document* enteredDocument, ExceptionState& exceptionState)
{
    write(SegmentedString(text), enteredDocument, exceptionState);
}

Project: Chrome

void Document::write(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
{
    ASSERT(callingWindow);
    StringBuilder builder;
    for (const String& string : text)
        builder.append(string);
    write(builder.toString(), callingWindow->document(), exceptionState);
}

Project: Chrome

void Document::writeln(const String& text, Document* enteredDocument, ExceptionState& exceptionState)
{
    write(text, enteredDocument, exceptionState);
    if (exceptionState.hadException())
        return;
    write("\n", enteredDocument);
}

Project: Chrome

void Document::writeln(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
{
    ASSERT(callingWindow);
    StringBuilder builder;
    for (const String& string : text)
        builder.append(string);
    writeln(builder.toString(), callingWindow->document(), exceptionState);
}

Project: Chrome

Document::~Document()
{
    ASSERT(!layoutView());
    ASSERT(!parentTreeScope());
    ASSERT(!m_axObjectCache);
#if !ENABLE(OILPAN)
    ASSERT(m_ranges.isEmpty());
    ASSERT(!hasGuardRefCount());
    ASSERT(!m_importsController);
    ASSERT(m_visibilityObservers.isEmpty());

    if (m_templateDocument)
        m_templateDocument->m_templateDocumentHost = nullptr; // balanced in ensureTemplateDocument().

    m_scriptRunner.clear();

    removeAllEventListenersRecursively();

    ASSERT(!m_parser || m_parser->refCount() == 1);
    detachParser();

    if (m_styleSheetList)
        m_styleSheetList->detachFromDocument();

    m_timeline->detachFromDocument();

    m_styleEngine->detachFromDocument();

    if (m_elemSheet)
        m_elemSheet->clearOwnerNode();

    if (hasRareData())
        clearRareData();

    ASSERT(m_listsInvalidatedAtDocument.isEmpty());

    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
        ASSERT(!m_nodeListCounts[i]);

    liveDocumentSet().remove(this);
#endif

    InstanceCounters::decrementCounter(InstanceCounters::DocumentCounter);
}