Esempio n. 1
0
void XMLDocumentParser::parseEndElement()
{
    exitText();

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

    if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptElementIfPossible(toElement(n.get()))) {
        popCurrentNode();
        n->remove(IGNORE_EXCEPTION);
        return;
    }

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

    Element* element = toElement(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 = toScriptElementIfPossible(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();
}
Esempio n. 2
0
JSC::JSInternalPromise* ScriptModuleLoader::fetch(JSC::JSGlobalObject* jsGlobalObject, JSC::ExecState* exec, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSValue initiator)
{
    auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject);
    auto& jsPromise = *JSC::JSInternalPromiseDeferred::create(exec, &globalObject);
    auto deferred = DeferredPromise::create(globalObject, jsPromise);
    if (moduleKeyValue.isSymbol()) {
        deferred->reject(TypeError, ASCIILiteral("Symbol module key should be already fulfilled with the inlined resource."));
        return jsPromise.promise();
    }

    if (!moduleKeyValue.isString()) {
        deferred->reject(TypeError, ASCIILiteral("Module key is not Symbol or String."));
        return jsPromise.promise();
    }

    // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script

    URL completedURL(URL(), asString(moduleKeyValue)->value(exec));
    if (!completedURL.isValid()) {
        deferred->reject(TypeError, ASCIILiteral("Module key is a valid URL."));
        return jsPromise.promise();
    }

    ASSERT_WITH_MESSAGE(JSC::jsDynamicCast<JSElement*>(initiator), "Initiator should be an JSElement");
    auto* scriptElement = toScriptElementIfPossible(&JSC::jsCast<JSElement*>(initiator)->wrapped());
    ASSERT_WITH_MESSAGE(scriptElement, "Initiator should be ScriptElement.");

    if (auto* frame = m_document.frame()) {
        auto loader = CachedModuleScriptLoader::create(*this, deferred.get());
        m_loaders.add(loader.copyRef());
        if (!loader->load(*scriptElement, completedURL)) {
            loader->clearClient();
            m_loaders.remove(WTFMove(loader));

            deferred->reject(frame->script().moduleLoaderAlreadyReportedErrorSymbol());
            return jsPromise.promise();
        }
    }

    return jsPromise.promise();
}
Esempio n. 3
0
void ScriptRunner::timerFired()
{
    Ref<Document> protect(m_document);

    Vector<PendingScript> scripts;
    scripts.swap(m_scriptsToExecuteSoon);

    size_t numInOrderScriptsToExecute = 0;
    for (; numInOrderScriptsToExecute < m_scriptsToExecuteInOrder.size() && m_scriptsToExecuteInOrder[numInOrderScriptsToExecute].cachedScript()->isLoaded(); ++numInOrderScriptsToExecute)
        scripts.append(m_scriptsToExecuteInOrder[numInOrderScriptsToExecute]);
    if (numInOrderScriptsToExecute)
        m_scriptsToExecuteInOrder.remove(0, numInOrderScriptsToExecute);

    size_t size = scripts.size();
    for (size_t i = 0; i < size; ++i) {
        CachedScript* cachedScript = scripts[i].cachedScript();
        RefPtr<Element> element = scripts[i].releaseElementAndClear();
        toScriptElementIfPossible(element.get())->execute(cachedScript);
        m_document.decrementLoadEventDelayCount();
    }
}
Esempio n. 4
0
void XMLDocumentParser::parseStartElement()
{
    if (!m_sawFirstElement && m_parsingFragment) {
        // skip dummy element for fragments
        m_sawFirstElement = true;
        return;
    }

    exitText();

    String localName = m_stream.name();
    String uri       = m_stream.namespaceUri();
    String prefix    = prefixFromQName(m_stream.qualifiedName().toString());

    if (m_parsingFragment && uri.isNull()) {
        Q_ASSERT(prefix.isNull());
        uri = m_defaultNamespaceURI;
    }

    QualifiedName qName(prefix, localName, uri);
    RefPtr<Element> newElement = document()->createElement(qName, true);
    if (!newElement) {
        stopParsing();
        return;
    }

    bool isFirstElement = !m_sawFirstElement;
    m_sawFirstElement = true;

    Vector<Attribute> prefixedAttributes;
    ExceptionCode ec = 0;
    handleNamespaceAttributes(prefixedAttributes, m_stream.namespaceDeclarations(), ec);
    if (ec) {
        setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
        stopParsing();
        return;
    }

    handleElementAttributes(prefixedAttributes, m_stream.attributes(), ec);
    setAttributes(newElement.get(), prefixedAttributes, parserContentPolicy());
    if (ec) {
        stopParsing();
        return;
    }

    ScriptElement* scriptElement = toScriptElementIfPossible(newElement.get());
    if (scriptElement)
        m_scriptStartPosition = textPosition();

    m_currentNode->parserAppendChild(newElement.get());

    pushCurrentNode(newElement.get());
    if (m_view && !newElement->attached())
        Style::attachRenderTree(newElement.get());

    if (newElement->hasTagName(HTMLNames::htmlTag))
        static_cast<HTMLHtmlElement*>(newElement.get())->insertedByParser();

    if (isFirstElement && document()->frame())
        document()->frame()->loader().dispatchDocumentElementAvailable();
}