// This method is meant to match the HTML5 definition of "running a script"
// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
void HTMLScriptRunner::runScript(Element* script, const TextPosition1& scriptStartPosition)
{
    ASSERT(m_document);
    ASSERT(!haveParsingBlockingScript());
    {
        InsertionPointRecord insertionPointRecord(m_host->inputStream());
        NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);

        ScriptElement* scriptElement = toScriptElement(script);
        ASSERT(scriptElement);

        scriptElement->prepareScript(scriptStartPosition);

        if (!scriptElement->willBeParserExecuted())
            return;

        if (scriptElement->willExecuteWhenDocumentFinishedParsing())
            requestDeferredScript(script);
        else if (scriptElement->readyToBeParserExecuted()) {
            if (m_scriptNestingLevel == 1) {
                m_parsingBlockingScript.setElement(script);
                m_parsingBlockingScript.setStartingPosition(scriptStartPosition);
            } else {
                ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition);
                scriptElement->executeScript(sourceCode);
            }
        } else
            requestParsingBlockingScript(script);
    }
}
Beispiel #2
0
void XMLDocumentParser::parseEndElement()
{
    exitText();

    RefPtr<ContainerNode> n = m_currentNode;
    n->finishParsingChildren();

    if (!scriptingContentIsAllowed(m_scriptingPermission) && n->isElementNode() && toScriptElement(static_cast<Element*>(n.get()))) {
        popCurrentNode();
        ExceptionCode ec;
        n->remove(ec);
        return;
    }

    if (!n->isElementNode() || !m_view) {
        if (!m_currentNodeStack.isEmpty())
            popCurrentNode();
        return;
    }

    Element* element = static_cast<Element*>(n.get());

    // The element's parent may have already been removed from document.
    // Parsing continues in this case, but scripts aren't executed.
    if (!element->inDocument()) {
        popCurrentNode();
        return;
    }

    ScriptElement* scriptElement = toScriptElement(element);
    if (!scriptElement) {
        popCurrentNode();
        return;
    }

    // don't load external scripts for standalone documents (for now)
    ASSERT(!m_pendingScript);
    m_requestingScript = true;

    if (scriptElement->prepareScript(m_scriptStartPosition, ScriptElement::AllowLegacyTypeInTypeAttribute)) {
        if (scriptElement->readyToBeParserExecuted())
            scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));
        else if (scriptElement->willBeParserExecuted()) {
            m_pendingScript = scriptElement->cachedScript();
            m_scriptElement = element;
            m_pendingScript->addClient(this);

            // m_pendingScript will be 0 if script was already loaded and addClient() executed it.
            if (m_pendingScript)
                pauseParsing();
        } else
            m_scriptElement = 0;
    }
    m_requestingScript = false;
    popCurrentNode();
}
Beispiel #3
0
// This method is meant to match the HTML5 definition of "running a script"
// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStartPosition)
{
    ASSERT(m_document);
    ASSERT(!hasParserBlockingScript());
    {
        ScriptElement* scriptElement = toScriptElement(script);

        // This contains both and ASSERTION and a null check since we should not
        // be getting into the case of a null script element, but seem to be from
        // time to time. The assertion is left in to help find those cases and
        // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>.
        ASSERT(scriptElement);
        if (!scriptElement)
            return;

        // FIXME: This may be too agressive as we always deliver mutations at
        // every script element, even if it's not ready to execute yet. There's
        // unfortuantely no obvious way to tell if prepareScript is going to
        // execute the script from out here.
        if (!isExecutingScript()) {
#if ENABLE(CUSTOM_ELEMENTS)
            CustomElementRegistry::deliverAllLifecycleCallbacks();
#endif
            MutationObserver::deliverAllMutations();
        }

        InsertionPointRecord insertionPointRecord(m_host->inputStream());
        NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);

        scriptElement->prepareScript(scriptStartPosition);

        if (!scriptElement->willBeParserExecuted())
            return;

        if (scriptElement->willExecuteWhenDocumentFinishedParsing())
            requestDeferredScript(script);
        else if (scriptElement->readyToBeParserExecuted()) {
            if (m_scriptNestingLevel == 1) {
                m_parserBlockingScript.setElement(script);
                m_parserBlockingScript.setStartingPosition(scriptStartPosition);
            } else {
                ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition);
                scriptElement->executeScript(sourceCode);
            }
        } else
            requestParsingBlockingScript(script);
    }
}
Beispiel #4
0
// This method is meant to match the HTML5 definition of "running a script"
// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStartPosition)
{
    ASSERT(m_document);
    ASSERT(!hasParserBlockingScript());
    {
        ScriptElement* scriptElement = toScriptElementIfPossible(script);

        // This contains both and ASSERTION and a null check since we should not
        // be getting into the case of a null script element, but seem to be from
        // time to time. The assertion is left in to help find those cases and
        // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>.
        ASSERT(scriptElement);
        if (!scriptElement)
            return;

        // FIXME: This may be too agressive as we always deliver mutations at
        // every script element, even if it's not ready to execute yet. There's
        // unfortuantely no obvious way to tell if prepareScript is going to
        // execute the script from out here.
        if (!isExecutingScript())
            MicrotaskQueue::mainThreadQueue().performMicrotaskCheckpoint();

        InsertionPointRecord insertionPointRecord(m_host.inputStream());
        NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);

        scriptElement->prepareScript(scriptStartPosition);

        if (!scriptElement->willBeParserExecuted())
            return;

        if (scriptElement->willExecuteWhenDocumentFinishedParsing())
            requestDeferredScript(script);
        else if (scriptElement->readyToBeParserExecuted()) {
            if (m_scriptNestingLevel == 1)
                m_parserBlockingScript = PendingScript::create(*script, scriptStartPosition);
            else
                scriptElement->executeClassicScript(ScriptSourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition));
        } else
            requestParsingBlockingScript(script);
    }
}
// This method is meant to match the HTML5 definition of "running a script"
// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
void HTMLScriptRunner::runScript(Element* script, const TextPosition1& scriptStartPosition)
{
    ASSERT(m_document);
    ASSERT(!haveParsingBlockingScript());
    {
        InsertionPointRecord insertionPointRecord(m_host->inputStream());
        NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);

        ScriptElement* scriptElement = toScriptElement(script);

        // This contains both and ASSERTION and a null check since we should not
        // be getting into the case of a null script element, but seem to be from
        // time to time. The assertion is left in to help find those cases and
        // is being tracked by <https://bugs.webkit.org/show_bug.cgi?id=60559>.
        ASSERT(scriptElement);
        if (!scriptElement)
            return;

        scriptElement->prepareScript(scriptStartPosition);

        if (!scriptElement->willBeParserExecuted())
            return;

        if (scriptElement->willExecuteWhenDocumentFinishedParsing())
            requestDeferredScript(script);
        else if (scriptElement->readyToBeParserExecuted()) {
            if (m_scriptNestingLevel == 1) {
                m_parsingBlockingScript.setElement(script);
                m_parsingBlockingScript.setStartingPosition(scriptStartPosition);
            } else {
                ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition);
                scriptElement->executeScript(sourceCode);
            }
        } else
            requestParsingBlockingScript(script);
    }
}
void XMLDocumentParser::endElementNs()
{
    if (isStopped())
        return;

    if (m_parserPaused) {
        m_pendingCallbacks->appendEndElementNSCallback();
        return;
    }

    // JavaScript can detach the parser.  Make sure this is not released
    // before the end of this method.
    RefPtr<XMLDocumentParser> protect(this);

    exitText();

    RefPtr<ContainerNode> n = m_currentNode;
    n->finishParsingChildren();

    if (m_scriptingPermission == FragmentScriptingNotAllowed && n->isElementNode() && toScriptElement(static_cast<Element*>(n.get()))) {
        popCurrentNode();
        ExceptionCode ec;
        n->remove(ec);
        return;
    }

    if (!n->isElementNode() || !m_view) {
        popCurrentNode();
        return;
    }

    Element* element = static_cast<Element*>(n.get());

    // The element's parent may have already been removed from document.
    // Parsing continues in this case, but scripts aren't executed.
    if (!element->inDocument()) {
        popCurrentNode();
        return;
    }

    ScriptElement* scriptElement = toScriptElement(element);
    if (!scriptElement) {
        popCurrentNode();
        return;
    }

    // Don't load external scripts for standalone documents (for now).
    ASSERT(!m_pendingScript);
    m_requestingScript = true;

    if (scriptElement->prepareScript(m_scriptStartPosition, ScriptElement::AllowLegacyTypeInTypeAttribute)) {
        // FIXME: Script execution should be shared between
        // the libxml2 and Qt XMLDocumentParser implementations.

        if (scriptElement->readyToBeParserExecuted())
            scriptElement->executeScript(ScriptSourceCode(scriptElement->scriptContent(), document()->url(), m_scriptStartPosition));
        else if (scriptElement->willBeParserExecuted()) {
            m_pendingScript = scriptElement->cachedScript();
            m_scriptElement = element;
            m_pendingScript->addClient(this);

            // m_pendingScript will be 0 if script was already loaded and addClient() executed it.
            if (m_pendingScript)
                pauseParsing();
        } else
            m_scriptElement = 0;

        // JavaScript may have detached the parser
        if (isDetached())
            return;
    }
    m_requestingScript = false;
    popCurrentNode();
}