void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType) { ASSERT(scriptElement); ASSERT(cachedScript.get()); Element* element = scriptElement->element(); ASSERT(element); ASSERT(element->inDocument()); m_document->incrementLoadEventDelayCount(); switch (executionType) { case ASYNC_EXECUTION: m_scriptsToExecuteSoon.append(PendingScript(element, cachedScript.get())); if (!m_timer.isActive()) m_timer.startOneShot(0); break; case IN_ORDER_EXECUTION: m_scriptsToExecuteInOrder.append(PendingScript(element, cachedScript.get())); break; default: ASSERT_NOT_REACHED(); } }
void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType) { ASSERT(scriptElement); // Temporary: intended to help debug how null CachedScript objects can even get queued for execution, which // seems to sometimes happen (see http://code.google.com/p/chromium/issues/detail?id=75604 ) if (!cachedScript.get()) CRASH(); Element* element = scriptElement->element(); ASSERT(element); ASSERT(element->inDocument()); m_document->incrementLoadEventDelayCount(); switch (executionType) { case ASYNC_EXECUTION: m_scriptsToExecuteSoon.append(PendingScript(element, cachedScript.get())); if (!m_timer.isActive()) m_timer.startOneShot(0); break; case IN_ORDER_EXECUTION: m_scriptsToExecuteInOrder.append(PendingScript(element, cachedScript.get())); break; default: ASSERT_NOT_REACHED(); } }
void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType) { ASSERT(scriptElement); ASSERT(cachedScript.get()); Element& element = scriptElement->element(); ASSERT(element.inDocument()); m_document.incrementLoadEventDelayCount(); switch (executionType) { case ASYNC_EXECUTION: m_pendingAsyncScripts.add(scriptElement, PendingScript(&element, cachedScript.get())); break; case IN_ORDER_EXECUTION: m_scriptsToExecuteInOrder.append(PendingScript(&element, cachedScript.get())); break; } }
void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, ResourcePtr<ScriptResource> resource, ExecutionType executionType) { ASSERT(scriptLoader); ASSERT(resource.get()); Element* element = scriptLoader->element(); ASSERT(element); ASSERT(element->inDocument()); m_document->incrementLoadEventDelayCount(); switch (executionType) { case ASYNC_EXECUTION: m_pendingAsyncScripts.add(scriptLoader, PendingScript(element, resource.get())); break; case IN_ORDER_EXECUTION: m_scriptsToExecuteInOrder.append(PendingScript(element, resource.get())); break; } }
void AsyncScriptRunner::executeScriptSoon(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript) { ASSERT_ARG(scriptElement, scriptElement); Element* element = scriptElement->element(); ASSERT(element); ASSERT(element->inDocument()); m_document->incrementLoadEventDelayCount(); m_scriptsToExecuteSoon.append(PendingScript(element, cachedScript.get())); if (!m_timer.isActive()) m_timer.startOneShot(0); }
void ScriptRunner::queueScriptForExecution(ScriptElement* scriptElement, CachedResourceHandle<CachedScript> cachedScript, ExecutionType executionType) { ASSERT(scriptElement); ASSERT(cachedScript.get()); Element* element = scriptElement->element(); ASSERT(element); ASSERT(element->inDocument()); m_document->incrementLoadEventDelayCount(); switch (executionType) { case ASYNC_EXECUTION: m_pendingAsyncScripts.add(scriptElement, PendingScript(element, cachedScript.get())); break; case IN_ORDER_EXECUTION: m_scriptsToExecuteInOrder.append(PendingScript(element, cachedScript.get())); ActionLogFormat(ActionLog::WRITE_MEMORY, "ScriptRunner-%p-%p", static_cast<void*>(this), static_cast<void*>(scriptElement)); break; } }
// http://dev.w3.org/html5/spec/Overview.html#prepare-a-script bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes) { if (m_alreadyStarted) return false; ScriptLoaderClient* client = this->client(); bool wasParserInserted; if (m_parserInserted) { wasParserInserted = true; m_parserInserted = false; } else { wasParserInserted = false; } if (wasParserInserted && !client->asyncAttributeValue()) m_forceAsync = true; // FIXME: HTML5 spec says we should check that all children are either comments or empty text nodes. if (!client->hasSourceAttribute() && !m_element->hasChildren()) return false; if (!m_element->inDocument()) return false; if (!isScriptTypeSupported(supportLegacyTypes)) return false; if (wasParserInserted) { m_parserInserted = true; m_forceAsync = false; } m_alreadyStarted = true; // FIXME: If script is parser inserted, verify it's still in the original document. Document& elementDocument = m_element->document(); Document* contextDocument = elementDocument.contextDocument().get(); if (!contextDocument || !contextDocument->allowExecutingScripts(m_element)) return false; if (!isScriptForEventSupported()) return false; if (!client->charsetAttributeValue().isEmpty()) m_characterEncoding = client->charsetAttributeValue(); else m_characterEncoding = elementDocument.characterSet(); if (client->hasSourceAttribute()) { FetchRequest::DeferOption defer = FetchRequest::NoDefer; if (!m_parserInserted || client->asyncAttributeValue() || client->deferAttributeValue()) defer = FetchRequest::LazyLoad; if (!fetchScript(client->sourceAttributeValue(), defer)) return false; } if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parserInserted && !client->asyncAttributeValue()) { m_willExecuteWhenDocumentFinishedParsing = true; m_willBeParserExecuted = true; } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) { m_willBeParserExecuted = true; } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.isRenderingReady()) { m_willBeParserExecuted = true; m_readyToBeParserExecuted = true; } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) { m_willExecuteInOrder = true; m_pendingScript = PendingScript(m_element, m_resource.get()); contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRunner::IN_ORDER_EXECUTION); // Note that watchForLoad can immediately call notifyFinished. m_pendingScript.watchForLoad(this); } else if (client->hasSourceAttribute()) { m_pendingScript = PendingScript(m_element, m_resource.get()); LocalFrame* frame = m_element->document().frame(); if (frame) { ScriptState* scriptState = ScriptState::forMainWorld(frame); if (scriptState->contextIsValid()) ScriptStreamer::startStreaming(m_pendingScript, PendingScript::Async, frame->settings(), scriptState, frame->frameScheduler()->loadingTaskRunner()); } contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRunner::ASYNC_EXECUTION); // Note that watchForLoad can immediately call notifyFinished. m_pendingScript.watchForLoad(this); } else { // Reset line numbering for nested writes. TextPosition position = elementDocument.isInDocumentWrite() ? TextPosition() : scriptStartPosition; KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) ? elementDocument.url() : KURL(); if (!executeScript(ScriptSourceCode(scriptContent(), scriptURL, position))) { dispatchErrorEvent(); return false; } } return true; }