| 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 |