OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv
ed. |
6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> | 6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 , m_isExternalScript(false) | 61 , m_isExternalScript(false) |
62 , m_alreadyStarted(alreadyStarted) | 62 , m_alreadyStarted(alreadyStarted) |
63 , m_haveFiredLoad(false) | 63 , m_haveFiredLoad(false) |
64 , m_willBeParserExecuted(false) | 64 , m_willBeParserExecuted(false) |
65 , m_readyToBeParserExecuted(false) | 65 , m_readyToBeParserExecuted(false) |
66 , m_willExecuteWhenDocumentFinishedParsing(false) | 66 , m_willExecuteWhenDocumentFinishedParsing(false) |
67 , m_forceAsync(!parserInserted) | 67 , m_forceAsync(!parserInserted) |
68 , m_willExecuteInOrder(false) | 68 , m_willExecuteInOrder(false) |
69 { | 69 { |
70 ASSERT(m_element); | 70 ASSERT(m_element); |
71 if (parserInserted && element->document()->scriptableDocumentParser() && !el
ement->document()->isInDocumentWrite()) | 71 if (parserInserted && element->document().scriptableDocumentParser() && !ele
ment->document().isInDocumentWrite()) |
72 m_startLineNumber = element->document()->scriptableDocumentParser()->lin
eNumber(); | 72 m_startLineNumber = element->document().scriptableDocumentParser()->line
Number(); |
73 } | 73 } |
74 | 74 |
75 ScriptLoader::~ScriptLoader() | 75 ScriptLoader::~ScriptLoader() |
76 { | 76 { |
77 stopLoadRequest(); | 77 stopLoadRequest(); |
78 } | 78 } |
79 | 79 |
80 void ScriptLoader::insertedInto(ContainerNode* insertionPoint) | 80 void ScriptLoader::insertedInto(ContainerNode* insertionPoint) |
81 { | 81 { |
82 if (insertionPoint->inDocument() && !m_parserInserted) | 82 if (insertionPoint->inDocument() && !m_parserInserted) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 return true; | 161 return true; |
162 } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSp
ace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLeg
acySupportedJavaScriptLanguage(type))) { | 162 } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSp
ace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLeg
acySupportedJavaScriptLanguage(type))) { |
163 return true; | 163 return true; |
164 } | 164 } |
165 | 165 |
166 return false; | 166 return false; |
167 } | 167 } |
168 | 168 |
169 Document* ScriptLoader::executingDocument() const | 169 Document* ScriptLoader::executingDocument() const |
170 { | 170 { |
171 Document* document = m_element->document(); | 171 Document& document = m_element->document(); |
172 if (!document->import()) | 172 if (!document.import()) |
173 return document; | 173 return &document; |
174 return document->import()->master(); | 174 return document.import()->master(); |
175 } | 175 } |
176 | 176 |
177 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script | 177 // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script |
178 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
TypeSupport supportLegacyTypes) | 178 bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
TypeSupport supportLegacyTypes) |
179 { | 179 { |
180 if (m_alreadyStarted) | 180 if (m_alreadyStarted) |
181 return false; | 181 return false; |
182 | 182 |
183 ScriptLoaderClient* client = this->client(); | 183 ScriptLoaderClient* client = this->client(); |
184 | 184 |
(...skipping 20 matching lines...) Expand all Loading... |
205 | 205 |
206 if (wasParserInserted) { | 206 if (wasParserInserted) { |
207 m_parserInserted = true; | 207 m_parserInserted = true; |
208 m_forceAsync = false; | 208 m_forceAsync = false; |
209 } | 209 } |
210 | 210 |
211 m_alreadyStarted = true; | 211 m_alreadyStarted = true; |
212 | 212 |
213 // FIXME: If script is parser inserted, verify it's still in the original do
cument. | 213 // FIXME: If script is parser inserted, verify it's still in the original do
cument. |
214 Document* executingDocument = this->executingDocument(); | 214 Document* executingDocument = this->executingDocument(); |
215 Document* elementDocument = m_element->document(); | 215 Document& elementDocument = m_element->document(); |
216 | 216 |
217 // FIXME: Eventually we'd like to evaluate scripts which are inserted into a | 217 // FIXME: Eventually we'd like to evaluate scripts which are inserted into a |
218 // viewless document but this'll do for now. | 218 // viewless document but this'll do for now. |
219 // See http://bugs.webkit.org/show_bug.cgi?id=5727 | 219 // See http://bugs.webkit.org/show_bug.cgi?id=5727 |
220 if (!executingDocument->frame()) | 220 if (!executingDocument->frame()) |
221 return false; | 221 return false; |
222 | 222 |
223 if (!executingDocument->frame()->script()->canExecuteScripts(AboutToExecuteS
cript)) | 223 if (!executingDocument->frame()->script()->canExecuteScripts(AboutToExecuteS
cript)) |
224 return false; | 224 return false; |
225 | 225 |
226 if (!isScriptForEventSupported()) | 226 if (!isScriptForEventSupported()) |
227 return false; | 227 return false; |
228 | 228 |
229 if (!client->charsetAttributeValue().isEmpty()) | 229 if (!client->charsetAttributeValue().isEmpty()) |
230 m_characterEncoding = client->charsetAttributeValue(); | 230 m_characterEncoding = client->charsetAttributeValue(); |
231 else | 231 else |
232 m_characterEncoding = elementDocument->charset(); | 232 m_characterEncoding = elementDocument.charset(); |
233 | 233 |
234 if (client->hasSourceAttribute()) { | 234 if (client->hasSourceAttribute()) { |
235 if (!fetchScript(client->sourceAttributeValue())) | 235 if (!fetchScript(client->sourceAttributeValue())) |
236 return false; | 236 return false; |
237 } | 237 } |
238 | 238 |
239 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { | 239 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse
rInserted && !client->asyncAttributeValue()) { |
240 m_willExecuteWhenDocumentFinishedParsing = true; | 240 m_willExecuteWhenDocumentFinishedParsing = true; |
241 m_willBeParserExecuted = true; | 241 m_willBeParserExecuted = true; |
242 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { | 242 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn
cAttributeValue()) { |
243 m_willBeParserExecuted = true; | 243 m_willBeParserExecuted = true; |
244 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu
ment->haveStylesheetsAndImportsLoaded()) { | 244 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu
ment.haveStylesheetsAndImportsLoaded()) { |
245 m_willBeParserExecuted = true; | 245 m_willBeParserExecuted = true; |
246 m_readyToBeParserExecuted = true; | 246 m_readyToBeParserExecuted = true; |
247 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { | 247 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() &&
!m_forceAsync) { |
248 m_willExecuteInOrder = true; | 248 m_willExecuteInOrder = true; |
249 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::IN_ORDER_EXECUTION); | 249 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::IN_ORDER_EXECUTION); |
250 m_resource->addClient(this); | 250 m_resource->addClient(this); |
251 } else if (client->hasSourceAttribute()) { | 251 } else if (client->hasSourceAttribute()) { |
252 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::ASYNC_EXECUTION); | 252 executingDocument->scriptRunner()->queueScriptForExecution(this, m_resou
rce, ScriptRunner::ASYNC_EXECUTION); |
253 m_resource->addClient(this); | 253 m_resource->addClient(this); |
254 } else { | 254 } else { |
255 // Reset line numbering for nested writes. | 255 // Reset line numbering for nested writes. |
256 TextPosition position = elementDocument->isInDocumentWrite() ? TextPosit
ion() : scriptStartPosition; | 256 TextPosition position = elementDocument.isInDocumentWrite() ? TextPositi
on() : scriptStartPosition; |
257 KURL scriptURL = (!elementDocument->isInDocumentWrite() && m_parserInser
ted) ? elementDocument->url() : KURL(); | 257 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInsert
ed) ? elementDocument.url() : KURL(); |
258 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); | 258 executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); |
259 } | 259 } |
260 | 260 |
261 return true; | 261 return true; |
262 } | 262 } |
263 | 263 |
264 bool ScriptLoader::fetchScript(const String& sourceUrl) | 264 bool ScriptLoader::fetchScript(const String& sourceUrl) |
265 { | 265 { |
266 ASSERT(m_element); | 266 ASSERT(m_element); |
267 | 267 |
268 RefPtr<Document> elementDocument = m_element->document(); | 268 RefPtr<Document> elementDocument = &m_element->document(); |
269 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) | 269 if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) |
270 return false; | 270 return false; |
271 if (!m_element->inDocument() || m_element->document() != elementDocument) | 271 if (!m_element->inDocument() || &m_element->document() != elementDocument) |
272 return false; | 272 return false; |
273 | 273 |
274 ASSERT(!m_resource); | 274 ASSERT(!m_resource); |
275 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 275 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
276 FetchRequest request(ResourceRequest(elementDocument->completeURL(source
Url)), m_element->localName()); | 276 FetchRequest request(ResourceRequest(elementDocument->completeURL(source
Url)), m_element->localName()); |
277 | 277 |
278 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); | 278 String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossori
ginAttr); |
279 if (!crossOriginMode.isNull()) { | 279 if (!crossOriginMode.isNull()) { |
280 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; | 280 StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMo
de, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
281 request.setPotentiallyCrossOriginEnabled(elementDocument->securityOr
igin(), allowCredentials); | 281 request.setPotentiallyCrossOriginEnabled(elementDocument->securityOr
igin(), allowCredentials); |
(...skipping 27 matching lines...) Expand all Loading... |
309 } | 309 } |
310 | 310 |
311 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) | 311 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) |
312 { | 312 { |
313 ASSERT(m_alreadyStarted); | 313 ASSERT(m_alreadyStarted); |
314 | 314 |
315 if (sourceCode.isEmpty()) | 315 if (sourceCode.isEmpty()) |
316 return; | 316 return; |
317 | 317 |
318 RefPtr<Document> executingDocument = this->executingDocument(); | 318 RefPtr<Document> executingDocument = this->executingDocument(); |
319 RefPtr<Document> elementDocument = m_element->document(); | 319 RefPtr<Document> elementDocument = &m_element->document(); |
320 Frame* frame = executingDocument->frame(); | 320 Frame* frame = executingDocument->frame(); |
321 | 321 |
322 bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()-
>shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecuri
tyPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); | 322 bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()-
>shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecuri
tyPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
323 | 323 |
324 if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !
elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url
(), m_startLineNumber))) | 324 if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !
elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url
(), m_startLineNumber))) |
325 return; | 325 return; |
326 | 326 |
327 if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosnif
f()) { | 327 if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosnif
f()) { |
328 executingDocument->addConsoleMessage(SecurityMessageSource, ErrorMessage
Level, "Refused to execute script from '" + m_resource->url().elidedString() + "
' because its MIME type ('" + m_resource->mimeType() + "') is not executable, an
d strict MIME type checking is enabled."); | 328 executingDocument->addConsoleMessage(SecurityMessageSource, ErrorMessage
Level, "Refused to execute script from '" + m_resource->url().elidedString() + "
' because its MIME type ('" + m_resource->mimeType() + "') is not executable, an
d strict MIME type checking is enabled."); |
329 return; | 329 return; |
330 } | 330 } |
331 | 331 |
332 if (frame) { | 332 if (frame) { |
333 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncre
menter(m_isExternalScript ? executingDocument.get() : 0); | 333 IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncre
menter(m_isExternalScript ? executingDocument.get() : 0); |
334 | 334 |
335 if (isHTMLScriptLoader(m_element)) | 335 if (isHTMLScriptLoader(m_element)) |
336 executingDocument->pushCurrentScript(toHTMLScriptElement(m_element))
; | 336 executingDocument->pushCurrentScript(toHTMLScriptElement(m_element))
; |
337 | 337 |
338 AccessControlStatus corsCheck = NotSharableCrossOrigin; | 338 AccessControlStatus corsCheck = NotSharableCrossOrigin; |
339 if (sourceCode.resource() && sourceCode.resource()->passesAccessControlC
heck(m_element->document()->securityOrigin())) | 339 if (sourceCode.resource() && sourceCode.resource()->passesAccessControlC
heck(m_element->document().securityOrigin())) |
340 corsCheck = SharableCrossOrigin; | 340 corsCheck = SharableCrossOrigin; |
341 | 341 |
342 // Create a script from the script element node, using the script | 342 // Create a script from the script element node, using the script |
343 // block's source and the script block's type. | 343 // block's source and the script block's type. |
344 // Note: This is where the script is compiled and actually executed. | 344 // Note: This is where the script is compiled and actually executed. |
345 frame->script()->executeScriptInMainWorld(sourceCode, corsCheck); | 345 frame->script()->executeScriptInMainWorld(sourceCode, corsCheck); |
346 | 346 |
347 if (isHTMLScriptLoader(m_element)) { | 347 if (isHTMLScriptLoader(m_element)) { |
348 ASSERT(executingDocument->currentScript() == m_element); | 348 ASSERT(executingDocument->currentScript() == m_element); |
349 executingDocument->popCurrentScript(); | 349 executingDocument->popCurrentScript(); |
(...skipping 21 matching lines...) Expand all Loading... |
371 dispatchLoadEvent(); | 371 dispatchLoadEvent(); |
372 } | 372 } |
373 resource->removeClient(this); | 373 resource->removeClient(this); |
374 } | 374 } |
375 | 375 |
376 void ScriptLoader::notifyFinished(Resource* resource) | 376 void ScriptLoader::notifyFinished(Resource* resource) |
377 { | 377 { |
378 ASSERT(!m_willBeParserExecuted); | 378 ASSERT(!m_willBeParserExecuted); |
379 | 379 |
380 RefPtr<Document> executingDocument = this->executingDocument(); | 380 RefPtr<Document> executingDocument = this->executingDocument(); |
381 RefPtr<Document> elementDocument = m_element->document(); | 381 RefPtr<Document> elementDocument = &m_element->document(); |
382 | 382 |
383 // Resource possibly invokes this notifyFinished() more than | 383 // Resource possibly invokes this notifyFinished() more than |
384 // once because ScriptLoader doesn't unsubscribe itself from | 384 // once because ScriptLoader doesn't unsubscribe itself from |
385 // Resource here and does it in execute() instead. | 385 // Resource here and does it in execute() instead. |
386 // We use m_resource to check if this function is already called. | 386 // We use m_resource to check if this function is already called. |
387 ASSERT_UNUSED(resource, resource == m_resource); | 387 ASSERT_UNUSED(resource, resource == m_resource); |
388 if (!m_resource) | 388 if (!m_resource) |
389 return; | 389 return; |
390 if (!elementDocument->fetcher()->canAccess(m_resource.get())) { | 390 if (!elementDocument->fetcher()->canAccess(m_resource.get())) { |
391 dispatchErrorEvent(); | 391 dispatchErrorEvent(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 if (isHTMLScriptLoader(element)) | 443 if (isHTMLScriptLoader(element)) |
444 return toHTMLScriptElement(element)->loader(); | 444 return toHTMLScriptElement(element)->loader(); |
445 | 445 |
446 if (isSVGScriptLoader(element)) | 446 if (isSVGScriptLoader(element)) |
447 return toSVGScriptElement(element)->loader(); | 447 return toSVGScriptElement(element)->loader(); |
448 | 448 |
449 return 0; | 449 return 0; |
450 } | 450 } |
451 | 451 |
452 } | 452 } |
OLD | NEW |