-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow to add a dependency dynamically via JS expression (#6602)
* Add a new dependency type JS_EXPRESSION * Call endEagerDependencyLoading when JS Expression dependency execution has ended * Add GWT unit test for checking dependencies loading order and changes processing. * Use NativeFunction instead of ExecuteJavaScriptProcessor Move loading dynamic import to ResourceLoader Rename ResourceLoadEvent.resourceUrl to ResourceLoadEvent.resourceData * Add Gwt unit tests and IT test * Add server side unit tests. * Hide unnecessary public method. * Add javadocs to public method one more time. * Fix javadocs once again * Remove extra file left after a merge and fix code review comments. * Use async mode for GWT unit tests
- Loading branch information
Denis
authored and
Johannes Eriksson
committed
Oct 4, 2019
1 parent
9653de2
commit b7000f5
Showing
12 changed files
with
532 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,15 +16,20 @@ | |
|
||
package com.vaadin.client; | ||
|
||
import java.util.function.Supplier; | ||
|
||
import com.google.gwt.core.client.Duration; | ||
import com.google.gwt.core.client.GWT; | ||
import com.google.gwt.core.client.Scheduler; | ||
import com.google.gwt.core.client.Scheduler.RepeatingCommand; | ||
import com.google.gwt.user.client.Timer; | ||
|
||
import com.vaadin.client.flow.collection.JsArray; | ||
import com.vaadin.client.flow.collection.JsCollections; | ||
import com.vaadin.client.flow.collection.JsMap; | ||
import com.vaadin.client.flow.collection.JsSet; | ||
import com.vaadin.client.flow.util.NativeFunction; | ||
|
||
import elemental.client.Browser; | ||
import elemental.dom.Document; | ||
import elemental.dom.Element; | ||
|
@@ -127,19 +132,20 @@ public void onError(ResourceLoadEvent event) { | |
*/ | ||
public static class ResourceLoadEvent { | ||
private final ResourceLoader loader; | ||
private final String resourceUrl; | ||
private final String resourceData; | ||
|
||
/** | ||
* Creates a new event. | ||
* | ||
* @param loader | ||
* the resource loader that has loaded the resource | ||
* @param resourceUrl | ||
* the url of the loaded resource | ||
* @param resourceData | ||
* the url or content of the loaded resource or the JS | ||
* expression that imports the resource | ||
*/ | ||
public ResourceLoadEvent(ResourceLoader loader, String resourceUrl) { | ||
public ResourceLoadEvent(ResourceLoader loader, String resourceData) { | ||
this.loader = loader; | ||
this.resourceUrl = resourceUrl; | ||
this.resourceData = resourceData; | ||
} | ||
|
||
/** | ||
|
@@ -152,12 +158,14 @@ public ResourceLoader getResourceLoader() { | |
} | ||
|
||
/** | ||
* Gets the absolute url of the loaded resource. | ||
* Gets the absolute url or content of the loaded resource or the JS | ||
* expression that imports the resource. | ||
* | ||
* @return the absolute url of the loaded resource | ||
* @return the absolute url or content of the loaded resource or the JS | ||
* expression that imports the resource | ||
*/ | ||
public String getResourceUrl() { | ||
return resourceUrl; | ||
public String getResourceData() { | ||
return resourceData; | ||
} | ||
|
||
} | ||
|
@@ -356,7 +364,7 @@ private void loadScript(String scriptUrl, | |
* listener to notify when script is loaded | ||
*/ | ||
public void inlineScript(String scriptContents, | ||
final ResourceLoadListener resourceLoadListener) { | ||
final ResourceLoadListener resourceLoadListener) { | ||
ResourceLoadEvent event = new ResourceLoadEvent(this, scriptContents); | ||
if (loadedResources.has(scriptContents)) { | ||
if (resourceLoadListener != null) { | ||
|
@@ -635,6 +643,25 @@ public void inlineStyleSheet(String styleSheetContents, | |
} | ||
} | ||
|
||
/** | ||
* Loads a dynamic import via the provided JS {@code expression} and reports | ||
* the result via the {@code resourceLoadListener}. | ||
* | ||
* @param expression | ||
* the JS expression which returns a Promise | ||
* @param resourceLoadListener | ||
* a listener to report the Promise result exection | ||
*/ | ||
public void loadDynamicImport(String expression, | ||
ResourceLoadListener resourceLoadListener) { | ||
|
||
ResourceLoadEvent event = new ResourceLoadEvent(this, expression); | ||
NativeFunction function = new NativeFunction(expression); | ||
runPromiseExpression(expression, () -> function.call(null), | ||
() -> resourceLoadListener.onLoad(event), | ||
() -> resourceLoadListener.onError(event)); | ||
} | ||
|
||
private void addCssLoadHandler(String styleSheetContents, | ||
ResourceLoadEvent event, StyleElement styleSheetElement) { | ||
if (BrowserInfo.get().isSafariOrIOS() || BrowserInfo.get().isOpera()) { | ||
|
@@ -707,8 +734,8 @@ private static boolean addListener(String resourceId, | |
|
||
private void fireError(ResourceLoadEvent event) { | ||
registry.getSystemErrorHandler() | ||
.handleError("Error loading " + event.getResourceUrl()); | ||
String resource = event.getResourceUrl(); | ||
.handleError("Error loading " + event.getResourceData()); | ||
String resource = event.getResourceData(); | ||
|
||
JsArray<ResourceLoadListener> listeners = loadListeners.get(resource); | ||
loadListeners.delete(resource); | ||
|
@@ -723,8 +750,8 @@ private void fireError(ResourceLoadEvent event) { | |
} | ||
|
||
private void fireLoad(ResourceLoadEvent event) { | ||
Console.log("Loaded " + event.getResourceUrl()); | ||
String resource = event.getResourceUrl(); | ||
Console.log("Loaded " + event.getResourceData()); | ||
String resource = event.getResourceData(); | ||
JsArray<ResourceLoadListener> listeners = loadListeners.get(resource); | ||
loadedResources.add(resource); | ||
loadListeners.delete(resource); | ||
|
@@ -737,4 +764,22 @@ private void fireLoad(ResourceLoadEvent event) { | |
} | ||
} | ||
} | ||
|
||
private static native void runPromiseExpression(String expression, | ||
Supplier<Object> promiseSupplier, Runnable onSuccess, | ||
Runnable onError) | ||
/*-{ | ||
try { | ||
var promise = [email protected]::get(*)(); | ||
if ( !(promise instanceof Promise )){ | ||
throw new Error('The expression "'+expression+'" result is not a Promise.'); | ||
} | ||
promise.then( function(result) { [email protected]::run(*)(); } , | ||
function(error) { [email protected]::run(*)(); } ); | ||
} | ||
catch(error) { | ||
[email protected]::run(*)(); | ||
} | ||
}-*/; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.