OLD | NEW |
1 // Copyright (c) 2009, Google Inc. | 1 // Copyright (c) 2009, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 17 matching lines...) Expand all Loading... |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 #include "config.h" | 30 #include "config.h" |
31 #include "bindings/dart/DartController.h" | 31 #include "bindings/dart/DartController.h" |
32 | 32 |
33 #include "DartDocument.h" | 33 #include "DartDocument.h" |
34 #include "DartWindow.h" | 34 #include "DartWindow.h" |
35 #include "HTMLNames.h" | 35 #include "HTMLNames.h" |
36 #include "V8Navigator.h" | 36 #include "V8Navigator.h" |
37 #include "bindings/dart/DartApplicationLoader.h" | 37 #include "bindings/dart/DartApplicationLoader.h" |
| 38 #include "bindings/dart/DartAsyncLoader.h" |
38 #include "bindings/dart/DartDOMData.h" | 39 #include "bindings/dart/DartDOMData.h" |
39 #include "bindings/dart/DartDOMWrapper.h" | 40 #include "bindings/dart/DartDOMWrapper.h" |
40 #include "bindings/dart/DartDebugServer.h" | 41 #include "bindings/dart/DartDebugServer.h" |
41 #include "bindings/dart/DartGCController.h" | 42 #include "bindings/dart/DartGCController.h" |
42 #include "bindings/dart/DartIsolateDestructionObserver.h" | 43 #include "bindings/dart/DartIsolateDestructionObserver.h" |
43 #include "bindings/dart/DartNativeUtilities.h" | 44 #include "bindings/dart/DartNativeUtilities.h" |
44 #include "bindings/dart/DartScriptState.h" | 45 #include "bindings/dart/DartScriptState.h" |
45 #include "bindings/dart/DartTimeline.h" | 46 #include "bindings/dart/DartTimeline.h" |
46 #include "bindings/dart/DartUtilities.h" | 47 #include "bindings/dart/DartUtilities.h" |
47 #include "bindings/dart/ThreadSafeDartIsolateWrapper.h" | 48 #include "bindings/dart/ThreadSafeDartIsolateWrapper.h" |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 destinationContext->postTask(adoptPtr(new MessageNotifyTask(domData->threadS
afeIsolateWrapper()))); | 311 destinationContext->postTask(adoptPtr(new MessageNotifyTask(domData->threadS
afeIsolateWrapper()))); |
311 } | 312 } |
312 | 313 |
313 class SpawnUriErrorEventDispatcher : public DartApplicationLoader::ErrorEventDis
patcher { | 314 class SpawnUriErrorEventDispatcher : public DartApplicationLoader::ErrorEventDis
patcher { |
314 public: | 315 public: |
315 // TODO(antonm): this is used to dispatch DOM error event. Most probably we
need | 316 // TODO(antonm): this is used to dispatch DOM error event. Most probably we
need |
316 // nothing like that for spawnDomUri, but need to double check. | 317 // nothing like that for spawnDomUri, but need to double check. |
317 void dispatchErrorEvent() { } | 318 void dispatchErrorEvent() { } |
318 }; | 319 }; |
319 | 320 |
320 class ApplicationLoadedCallback : public VoidCallback { | 321 class DartSpawnLoadCallback : public DartAsyncLoader::LoadCallback { |
321 public: | 322 public: |
322 ApplicationLoadedCallback(Dart_Isolate isolate, PassRefPtr<Document> documen
t) : m_isolate(isolate), m_document(document) { } | 323 DartSpawnLoadCallback(Dart_Isolate isolate, const String& url, Document* ori
ginDocument) |
| 324 : LoadCallback(originDocument) |
| 325 , m_isolate(isolate) |
| 326 , m_url(url) |
| 327 { |
| 328 } |
323 | 329 |
324 bool handleEvent() | 330 void ready(PassRefPtr<DartAsyncLoader> loader) |
325 { | 331 { |
326 ASSERT(isMainThread()); | 332 RefPtr<DartAsyncLoader> asyncLoader = loader; |
327 ASSERT(Dart_CurrentIsolate() == m_isolate); | 333 RefPtr<SpawnUriErrorEventDispatcher> errorEventDispatcher = adoptRef(new
SpawnUriErrorEventDispatcher()); |
328 | 334 |
329 Dart_ExitIsolate(); | 335 RefPtr<DartApplicationLoader> applicationLoader = adoptRef(new DartAppli
cationLoader(m_isolate, document(), errorEventDispatcher, asyncLoader, false)); |
| 336 |
| 337 applicationLoader->load(asyncLoader->scriptUrl(), asyncLoader->scriptSou
rce(), asyncLoader->scriptLineNumber()); |
330 Dart_IsolateMakeRunnable(m_isolate); | 338 Dart_IsolateMakeRunnable(m_isolate); |
331 Dart_EnterIsolate(m_isolate); | |
332 | |
333 return true; | |
334 } | 339 } |
335 | 340 |
336 private: | 341 private: |
337 Dart_Isolate m_isolate; | 342 Dart_Isolate m_isolate; |
338 RefPtr<Document> m_document; | 343 String m_url; |
339 }; | |
340 | |
341 class LoadIsolateSourcesTask : public ScriptExecutionContext::Task { | |
342 public: | |
343 LoadIsolateSourcesTask(const char* url, Dart_Isolate isolate, Document* docu
ment) | |
344 : m_url(strdup(url)), m_isolate(isolate), m_document(document) | |
345 { } | |
346 | |
347 ~LoadIsolateSourcesTask() | |
348 { | |
349 free(m_url); | |
350 } | |
351 | |
352 virtual void performTask(ScriptExecutionContext* context) | |
353 { | |
354 ASSERT(isMainThread()); | |
355 | |
356 RefPtr<SpawnUriErrorEventDispatcher> errorEventDispatcher = adoptRef(new
SpawnUriErrorEventDispatcher()); | |
357 RefPtr<VoidCallback> applicationLoadedCallback = adoptRef(new Applicatio
nLoadedCallback(m_isolate, m_document)); | |
358 RefPtr<DartApplicationLoader> applicationLoader = adoptRef(new DartAppli
cationLoader(m_isolate, m_document, errorEventDispatcher, applicationLoadedCallb
ack, false)); | |
359 applicationLoader->loadScriptResource(m_url); | |
360 } | |
361 | |
362 private: | |
363 char* const m_url; | |
364 const Dart_Isolate m_isolate; | |
365 Document* m_document; | |
366 }; | 344 }; |
367 | 345 |
368 Dart_Isolate DartController::createPureIsolateCallback(const char* scriptURL, co
nst char* entryPoint, void* data, char** errorMsg) | 346 Dart_Isolate DartController::createPureIsolateCallback(const char* scriptURL, co
nst char* entryPoint, void* data, char** errorMsg) |
369 { | 347 { |
370 bool needApplicationLoader = false; | 348 bool needAsyncLoader = false; |
371 | 349 |
372 { | 350 { |
373 DartApiScope apiScope; | 351 DartApiScope apiScope; |
374 // Hacky way to find out if it's spawnFunction or spawnUri. | 352 // Hacky way to find out if it's spawnFunction or spawnUri. |
375 Dart_Handle parentIsolateRootLibrary = Dart_RootLibrary(); | 353 Dart_Handle parentIsolateRootLibrary = Dart_RootLibrary(); |
376 if (Dart_IsError(parentIsolateRootLibrary)) { | 354 if (Dart_IsError(parentIsolateRootLibrary)) { |
377 *errorMsg = strdup(Dart_GetError(parentIsolateRootLibrary)); | 355 *errorMsg = strdup(Dart_GetError(parentIsolateRootLibrary)); |
378 return 0; | 356 return 0; |
379 } | 357 } |
380 Dart_Handle parentIsolateURLHandle = Dart_LibraryUrl(parentIsolateRootLi
brary); | 358 Dart_Handle parentIsolateURLHandle = Dart_LibraryUrl(parentIsolateRootLi
brary); |
381 if (Dart_IsError(parentIsolateURLHandle)) { | 359 if (Dart_IsError(parentIsolateURLHandle)) { |
382 *errorMsg = strdup(Dart_GetError(parentIsolateURLHandle)); | 360 *errorMsg = strdup(Dart_GetError(parentIsolateURLHandle)); |
383 return 0; | 361 return 0; |
384 } | 362 } |
385 const char * parentIsolateURL = 0; | 363 const char * parentIsolateURL = 0; |
386 Dart_Handle result = Dart_StringToCString(parentIsolateURLHandle, &paren
tIsolateURL); | 364 Dart_Handle result = Dart_StringToCString(parentIsolateURLHandle, &paren
tIsolateURL); |
387 if (Dart_IsError(result)) { | 365 if (Dart_IsError(result)) { |
388 *errorMsg = strdup(Dart_GetError(result)); | 366 *errorMsg = strdup(Dart_GetError(result)); |
389 return 0; | 367 return 0; |
390 } | 368 } |
391 | 369 |
392 needApplicationLoader = strcmp(scriptURL, parentIsolateURL); | 370 needAsyncLoader = strcmp(scriptURL, parentIsolateURL); |
393 } | 371 } |
394 | 372 |
395 DartDOMData* parentDOMData = static_cast<DartDOMData*>(data); | 373 DartDOMData* parentDOMData = static_cast<DartDOMData*>(data); |
396 ScriptExecutionContext* context = parentDOMData->scriptExecutionContext(); | 374 ScriptExecutionContext* context = parentDOMData->scriptExecutionContext(); |
397 ASSERT(context->isDocument()); | 375 ASSERT(context->isDocument()); |
398 Document* document = static_cast<Document*>(context); | 376 Document* document = static_cast<Document*>(context); |
399 | 377 |
400 Dart_Isolate isolate = createIsolate(scriptURL, entryPoint, document, false,
errorMsg); | 378 Dart_Isolate isolate = createIsolate(scriptURL, entryPoint, document, false,
errorMsg); |
401 if (!isolate) | 379 if (!isolate) |
402 return 0; | 380 return 0; |
403 | 381 |
404 if (needApplicationLoader) { | 382 if (needAsyncLoader) { |
405 context->postTask(adoptPtr(new LoadIsolateSourcesTask(scriptURL, isolate
, document))); | 383 // We need to request the sources asynchronously. |
| 384 RefPtr<DartSpawnLoadCallback> callback = adoptRef(new DartSpawnLoadCallb
ack(isolate, scriptURL, document)); |
| 385 // A DartAsyncLoader will delete itself once all resources are fetched. |
| 386 DartAsyncLoader* asyncLoader = new DartAsyncLoader(scriptURL, callback); |
| 387 asyncLoader->fetchScriptResource(scriptURL); |
406 Dart_ExitIsolate(); | 388 Dart_ExitIsolate(); |
407 } else { | 389 } else { |
408 // FIXME: avoid copying parent snapshot. | 390 // FIXME: avoid copying parent snapshot. |
409 ASSERT(DartDOMData::current()->applicationSnapshot()->isEmpty()); | 391 ASSERT(DartDOMData::current()->applicationSnapshot()->isEmpty()); |
410 DartDOMData::current()->applicationSnapshot()->append(*parentDOMData->ap
plicationSnapshot()); | 392 DartDOMData::current()->applicationSnapshot()->append(*parentDOMData->ap
plicationSnapshot()); |
411 | 393 |
412 { | 394 { |
413 DartApiScope apiScope; | 395 DartApiScope apiScope; |
414 | 396 |
415 // Initialize child isolate using the parent's snapshot. | 397 // Initialize child isolate using the parent's snapshot. |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 { | 531 { |
550 DEFINE_STATIC_LOCAL(HashSet<String>, types, ()); | 532 DEFINE_STATIC_LOCAL(HashSet<String>, types, ()); |
551 if (types.isEmpty()) { | 533 if (types.isEmpty()) { |
552 types.add("application/dart"); | 534 types.add("application/dart"); |
553 types.add("application/dart-app"); | 535 types.add("application/dart-app"); |
554 types.add("application/dart-script"); | 536 types.add("application/dart-script"); |
555 } | 537 } |
556 return !mimeType.isEmpty() && types.contains(mimeType); | 538 return !mimeType.isEmpty() && types.contains(mimeType); |
557 } | 539 } |
558 | 540 |
559 | |
560 class DartScriptRunner : public EventListener { | 541 class DartScriptRunner : public EventListener { |
561 public: | 542 public: |
562 static PassRefPtr<DartScriptRunner> create() | 543 static PassRefPtr<DartScriptRunner> create() |
563 { | 544 { |
564 return adoptRef(new DartScriptRunner()); | 545 return adoptRef(new DartScriptRunner()); |
565 } | 546 } |
566 | 547 |
567 virtual void handleEvent(ScriptExecutionContext* context, Event*) | 548 virtual void handleEvent(ScriptExecutionContext* context, Event*) |
568 { | 549 { |
569 ASSERT(context->isDocument()); | 550 ASSERT(context->isDocument()); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 virtual void dispatchErrorEvent() | 633 virtual void dispatchErrorEvent() |
653 { | 634 { |
654 m_scriptElement->dispatchErrorEvent(); | 635 m_scriptElement->dispatchErrorEvent(); |
655 } | 636 } |
656 | 637 |
657 WTF::OrdinalNumber startLineNumber() | 638 WTF::OrdinalNumber startLineNumber() |
658 { | 639 { |
659 return m_scriptElement->startLineNumber(); | 640 return m_scriptElement->startLineNumber(); |
660 } | 641 } |
661 | 642 |
| 643 ScriptLoader* loader() |
| 644 { |
| 645 return m_scriptElement; |
| 646 } |
| 647 |
662 virtual ~ScriptElementProxy() { } | 648 virtual ~ScriptElementProxy() { } |
663 | 649 |
664 protected: | 650 protected: |
665 ScriptElementProxy(ScriptLoader* scriptElement) | 651 ScriptElementProxy(ScriptLoader* scriptElement) |
666 : m_scriptElement(scriptElement) | 652 : m_scriptElement(scriptElement) |
667 { | 653 { |
668 } | 654 } |
669 | 655 |
670 ScriptLoader* m_scriptElement; | 656 ScriptLoader* m_scriptElement; |
671 }; | 657 }; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 : ScriptElementProxy(scriptElement) | 707 : ScriptElementProxy(scriptElement) |
722 { | 708 { |
723 } | 709 } |
724 | 710 |
725 SVGScriptElement* asSVGScriptElement() const | 711 SVGScriptElement* asSVGScriptElement() const |
726 { | 712 { |
727 return static_cast<SVGScriptElement*>(m_scriptElement->element()); | 713 return static_cast<SVGScriptElement*>(m_scriptElement->element()); |
728 } | 714 } |
729 }; | 715 }; |
730 | 716 |
| 717 class DartDomLoadCallback : public DartAsyncLoader::LoadCallback { |
| 718 public: |
| 719 DartDomLoadCallback(DartController* controller, const String& url, Document*
originDocument, PassRefPtr<ScriptElementProxy> proxy) |
| 720 : LoadCallback(originDocument, proxy->loader()) |
| 721 , m_controller(controller) |
| 722 , m_url(url) |
| 723 , m_proxy(proxy) |
| 724 { |
| 725 } |
| 726 |
| 727 void ready(PassRefPtr<DartAsyncLoader> asyncLoader) |
| 728 { |
| 729 m_controller->loadAndRunScript(m_url, asyncLoader, m_proxy); |
| 730 } |
| 731 |
| 732 private: |
| 733 DartController* m_controller; |
| 734 String m_url; |
| 735 RefPtr<ScriptElementProxy> m_proxy; |
| 736 }; |
| 737 |
| 738 void DartController::loadAndRunScript(const String& url, PassRefPtr<DartAsyncLoa
der> loader, PassRefPtr<ScriptElementProxy> proxy) |
| 739 { |
| 740 RefPtr<DartAsyncLoader> asyncLoader = loader; |
| 741 Document* document = frame()->document(); |
| 742 |
| 743 createDOMEnabledIsolate(url, "main", document); |
| 744 |
| 745 // FIXME: it may make sense to ensure that we'll never call evaluate more th
an once for the same script tag. |
| 746 RefPtr<DartApplicationLoader> applicationLoader = adoptRef(new DartApplicati
onLoader(Dart_CurrentIsolate(), document, proxy, asyncLoader)); |
| 747 applicationLoader->load(asyncLoader->scriptUrl(), asyncLoader->scriptSource(
), asyncLoader->scriptLineNumber()); |
| 748 |
| 749 Dart_ExitIsolate(); |
| 750 } |
| 751 |
| 752 |
731 void DartController::loadScripts() | 753 void DartController::loadScripts() |
732 { | 754 { |
733 if (m_scriptsLoaded) | 755 if (m_scriptsLoaded) |
734 return; | 756 return; |
735 | 757 |
736 Timeline timeline(frame(), "DC::loadScripts"); | 758 Timeline timeline(frame(), "DC::loadScripts"); |
737 initVMIfNeeded(); | 759 initVMIfNeeded(); |
738 | 760 |
739 Document* document = frame()->document(); | 761 Document* document = frame()->document(); |
740 RefPtr<NodeList> scripts = document->getElementsByTagName("script"); | 762 RefPtr<NodeList> scripts = document->getElementsByTagName("script"); |
741 Vector< RefPtr<Node> > scriptsCopy(scripts->length()); | 763 Vector< RefPtr<Node> > scriptsCopy(scripts->length()); |
742 for (unsigned i = 0; i < scripts->length(); ++i) | 764 for (unsigned i = 0; i < scripts->length(); ++i) |
743 scriptsCopy[i] = scripts->item(i); | 765 scriptsCopy[i] = scripts->item(i); |
744 for (unsigned i = 0; i < scriptsCopy.size(); ++i) { | 766 for (unsigned i = 0; i < scriptsCopy.size(); ++i) { |
745 RefPtr<ScriptElementProxy> scriptElementProxy; | 767 RefPtr<ScriptElementProxy> scriptElementProxy; |
746 if (document->isHTMLDocument()) | 768 if (document->isHTMLDocument()) |
747 scriptElementProxy = HTMLScriptElementProxy::create(scriptsCopy[i].g
et()); | 769 scriptElementProxy = HTMLScriptElementProxy::create(scriptsCopy[i].g
et()); |
748 else if (document->isSVGDocument()) | 770 else if (document->isSVGDocument()) |
749 scriptElementProxy = SVGScriptElementProxy::create(scriptsCopy[i].ge
t()); | 771 scriptElementProxy = SVGScriptElementProxy::create(scriptsCopy[i].ge
t()); |
750 ASSERT(scriptElementProxy); | 772 ASSERT(scriptElementProxy); |
751 | 773 |
752 String typeAttr = scriptElementProxy->typeAttributeValue(); | 774 String typeAttr = scriptElementProxy->typeAttributeValue(); |
753 if (!isDartMimeType(typeAttr.stripWhiteSpace().lower())) | 775 if (!isDartMimeType(typeAttr.stripWhiteSpace().lower())) |
754 continue; | 776 continue; |
755 | 777 |
756 String scriptURL = scriptElementProxy->sourceAttributeValue(); | 778 String scriptURL = scriptElementProxy->sourceAttributeValue(); |
757 createDOMEnabledIsolate(scriptURL, "main", document); | 779 String url = scriptURL.isEmpty() ? document->url() : scriptURL; |
758 | 780 |
759 // FIXME: it may make sense to ensure that we'll never call evaluate mor
e than once for the same script tag. | 781 RefPtr<DartDomLoadCallback> callback = adoptRef(new DartDomLoadCallback(
this, url, document, scriptElementProxy)); |
760 RefPtr<DartApplicationLoader> applicationLoader = adoptRef(new DartAppli
cationLoader(Dart_CurrentIsolate(), document, scriptElementProxy)); | 782 |
| 783 // A DartAsyncLoader will delete itself once all resources are fetched. |
| 784 DartAsyncLoader* asyncLoader = new DartAsyncLoader(url, callback); |
| 785 WTF::OrdinalNumber startLineNumber = scriptElementProxy->startLineNumber
(); |
| 786 intptr_t lineOffset = startLineNumber == OrdinalNumber::beforeFirst() ?
0 : startLineNumber.zeroBasedInt(); |
761 if (scriptURL.isEmpty()) | 787 if (scriptURL.isEmpty()) |
762 applicationLoader->load(m_frame->document()->url(), scriptElementPro
xy->scriptContent(), scriptElementProxy->startLineNumber()); | 788 asyncLoader->process(m_frame->document()->url(), scriptElementProxy-
>scriptContent(), lineOffset); |
763 else | 789 else |
764 applicationLoader->loadScriptResource(scriptURL); | 790 asyncLoader->fetchScriptResource(scriptURL); |
765 | |
766 Dart_ExitIsolate(); | |
767 } | 791 } |
768 | 792 |
769 m_scriptsLoaded = true; | 793 m_scriptsLoaded = true; |
770 } | 794 } |
771 | 795 |
772 void DartController::bindToWindowObject(Frame* frame, const String& key, NPObjec
t* object) | 796 void DartController::bindToWindowObject(Frame* frame, const String& key, NPObjec
t* object) |
773 { | 797 { |
774 // FIXME: proper management of lifetime. | 798 // FIXME: proper management of lifetime. |
775 m_npObjectMap.set(key, object); | 799 m_npObjectMap.set(key, object); |
776 } | 800 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 scriptState = new DartScriptState(isolate, libraryId, v8Context); | 928 scriptState = new DartScriptState(isolate, libraryId, v8Context); |
905 libraryIdMap->add(libraryId, scriptState); | 929 libraryIdMap->add(libraryId, scriptState); |
906 } else { | 930 } else { |
907 scriptState = libraryIter->value; | 931 scriptState = libraryIter->value; |
908 } | 932 } |
909 result.append(scriptState); | 933 result.append(scriptState); |
910 } | 934 } |
911 } | 935 } |
912 | 936 |
913 } | 937 } |
OLD | NEW |