Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SWC-7064, SWC-7092 - Use Elemental2 for JsInterop models #5559

Merged
merged 3 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,19 @@
<dependency>
<groupId>com.google.jsinterop</groupId>
<artifactId>base</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
</dependency>

<dependency>
<groupId>com.google.elemental2</groupId>
<artifactId>elemental2-core</artifactId>
<version>1.2.2</version>
</dependency>

<dependency>
<groupId>com.google.elemental2</groupId>
<artifactId>elemental2-dom</artifactId>
<version>1.2.2</version>
Comment on lines +956 to +965
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elemental2 provides JsInterop bindings for browser APIs.

</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.sagebionetworks.web.client;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.rpc.AsyncCallback;
import elemental2.dom.FileList;
import java.util.List;
import org.sagebionetworks.repo.model.EntityHeader;
import org.sagebionetworks.web.client.mvp.AppPlaceHistoryMapper;
Expand Down Expand Up @@ -120,7 +120,7 @@ public void setAppPlaceHistoryMapper(

void initializeToastContainer();

void setDropZoneHandler(CallbackP<JavaScriptObject> fileListCallback);
void setDropZoneHandler(CallbackP<FileList> fileListCallback);

void clearDropZoneHandler();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import static org.sagebionetworks.web.shared.WebConstants.REPO_SERVICE_URL_KEY;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.UmbrellaException;
Expand All @@ -19,6 +18,7 @@
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.inject.Inject;
import elemental2.dom.FileList;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
Expand Down Expand Up @@ -60,7 +60,7 @@ public class GlobalApplicationStateImpl implements GlobalApplicationState {
private DateTimeUtils dateTimeUtils;
private SynapseJavascriptClient jsClient;
private SessionStorage sessionStorage;
private CallbackP<JavaScriptObject> fileListCallback;
private CallbackP<FileList> fileListCallback;
private SynapseProperties synapseProperties;
private PortalGinInjector ginInjector;
private final OneSageUtils oneSageUtils;
Expand Down Expand Up @@ -459,7 +459,7 @@ public boolean isDragAndDropListenerSet() {
return fileListCallback != null;
}

public void onDrop(JavaScriptObject fileList) {
public void onDrop(FileList fileList) {
if (isDragAndDropListenerSet()) {
fileListCallback.invoke(fileList);
}
Expand Down Expand Up @@ -520,7 +520,7 @@ function allowDrag(e) {
function handleDrop(e) {
e.preventDefault();
hideDropZone();
globalAppState.@org.sagebionetworks.web.client.GlobalApplicationStateImpl::onDrop(Lcom/google/gwt/core/client/JavaScriptObject;)(e.dataTransfer.files);
globalAppState.@org.sagebionetworks.web.client.GlobalApplicationStateImpl::onDrop(Lelemental2/dom/FileList;)(e.dataTransfer.files);
}

dropZone.addEventListener('dragenter', allowDrag);
Expand All @@ -540,7 +540,7 @@ function handleDrop(e) {
}-*/;

@Override
public void setDropZoneHandler(CallbackP<JavaScriptObject> fileListCallback) {
public void setDropZoneHandler(CallbackP<FileList> fileListCallback) {
this.fileListCallback = fileListCallback;
}

Expand Down
705 changes: 670 additions & 35 deletions src/main/java/org/sagebionetworks/web/client/PortalGinModule.java

Large diffs are not rendered by default.

17 changes: 2 additions & 15 deletions src/main/java/org/sagebionetworks/web/client/SynapseJSNIUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.xhr.client.XMLHttpRequest;
import elemental2.dom.Blob;
import org.sagebionetworks.repo.model.file.FileHandleAssociateType;
import org.sagebionetworks.web.client.callback.MD5Callback;
import org.sagebionetworks.web.client.widget.provenance.nchart.LayoutResult;
Expand Down Expand Up @@ -43,10 +44,6 @@ public LayoutResult nChartlayout(

public void setPageDescription(String newDescription);

public JavaScriptObject getFileList(String fileFieldId);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved these to a new SynapseJsInteropUtils interface & class


public JavaScriptObject getFileBlob(int index, JavaScriptObject fileList);

public void uploadFileChunk(
String contentType,
JavaScriptObject blob,
Expand All @@ -57,15 +54,13 @@ public void uploadFileChunk(
ProgressCallback callback
);

public String getContentType(JavaScriptObject fileList, int index);

public boolean isFileAPISupported();

public boolean isElementExists(String elementId);

public String getFileUrl(String fileFieldId);

public void getFileMd5(JavaScriptObject blob, MD5Callback callback);
public void getFileMd5(Blob blob, MD5Callback callback);

public void getFilePartMd5(
JavaScriptObject blob,
Expand All @@ -74,12 +69,6 @@ public void getFilePartMd5(
MD5Callback md5Callback
);

public double getFileSize(JavaScriptObject blob);

String[] getMultipleUploadFileNames(JavaScriptObject fileList);

String getWebkitRelativePath(JavaScriptObject fileList, int index);

public void consoleLog(String message);

public void consoleError(String message);
Expand Down Expand Up @@ -117,8 +106,6 @@ public void getFilePartMd5(

boolean elementSupportsAttribute(Element el, String attribute);

Element getElementById(String elementId);

String getCdnEndpoint();

String getAccessTokenCookieUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.xhr.client.XMLHttpRequest;
import elemental2.dom.Blob;
import org.sagebionetworks.repo.model.file.FileHandleAssociateType;
import org.sagebionetworks.web.client.callback.MD5Callback;
import org.sagebionetworks.web.client.jsinterop.SRC;
Expand Down Expand Up @@ -219,9 +220,7 @@ public void setPageTitle(String newTitle) {
@Override
public void setPageDescription(String newDescription) {
if (Document.get() != null) {
NodeList<com.google.gwt.dom.client.Element> tags = Document
.get()
.getElementsByTagName("meta");
NodeList<Element> tags = Document.get().getElementsByTagName("meta");
for (int i = 0; i < tags.getLength(); i++) {
MetaElement metaTag = ((MetaElement) tags.getItem(i));
if (metaTag.getName().equals("description")) {
Expand All @@ -246,33 +245,6 @@ public void uploadFileChunk(
_directUploadBlob(contentType, blob, startByte, endByte, url, xhr);
}

@Override
public JavaScriptObject getFileList(String fileFieldId) {
return _getFileList(fileFieldId);
}

private static final native JavaScriptObject _getFileList(
String fileFieldId
) /*-{
var fileToUploadElement = $doc.getElementById(fileFieldId);
if (fileToUploadElement && 'files' in fileToUploadElement) {
return fileToUploadElement.files;
}
return null;
}-*/;

@Override
public JavaScriptObject getFileBlob(int index, JavaScriptObject fileList) {
return _getFileBlob(index, fileList);
}

private static final native JavaScriptObject _getFileBlob(
int index,
JavaScriptObject fileList
) /*-{
return fileList[index];
}-*/;

private static final native void _directUploadBlob(
String contentType,
JavaScriptObject fileToUpload,
Expand Down Expand Up @@ -324,64 +296,10 @@ private static final native double _getTotal(JavaScriptObject evt) /*-{
return 0;
}-*/;

@Override
public String getContentType(JavaScriptObject fileList, int index) {
return _getContentType(fileList, index);
}

private static final native String _getContentType(
JavaScriptObject fileList,
int index
) /*-{
return fileList[index].type;
}-*/;

@Override
public String getWebkitRelativePath(JavaScriptObject fileList, int index) {
return _getWebkitRelativePath(fileList, index);
}

private static final native String _getWebkitRelativePath(
JavaScriptObject fileList,
int index
) /*-{
return fileList[index].webkitRelativePath;
}-*/;

@Override
public double getFileSize(JavaScriptObject blob) {
return _getFileSize(blob);
}

private static final native double _getFileSize(JavaScriptObject blob) /*-{
return blob.size;
}-*/;

@Override
public String[] getMultipleUploadFileNames(JavaScriptObject fileList) {
String unSplitNames = _getFilesSelected(fileList);
if (unSplitNames.equals("")) return null;
return unSplitNames.split(";");
}

private static native String _getFilesSelected(JavaScriptObject fileList) /*-{
var out = "";
for (i = 0; i < fileList.length; i++) {
var file = fileList[i];
out += file.name + ';';
}
return out;
}-*/;

public boolean isElementExists(String elementId) {
return Document.get().getElementById(elementId) != null;
}

@Override
public Element getElementById(String elementId) {
return Document.get().getElementById(elementId);
}

/**
* Return the last modified time of the File (in milliseconds since the UNIX epoch). -1 if undefined.
*/
Expand All @@ -404,12 +322,12 @@ private static final native double _getLastModified(
* calculate the md5.
*/
@Override
public void getFileMd5(JavaScriptObject blob, MD5Callback md5Callback) {
_getFileMd5(blob, md5Callback);
public void getFileMd5(Blob file, MD5Callback md5Callback) {
_getFileMd5(file, md5Callback);
}

private static final native void _getFileMd5(
JavaScriptObject file,
Blob file,
MD5Callback md5Callback
) /*-{
if ($wnd.Worker) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.sagebionetworks.web.client;

import com.google.gwt.dom.client.Element;
import elemental2.dom.Blob;
import elemental2.dom.FileList;
import org.sagebionetworks.web.client.callback.MD5Callback;

public interface SynapseJsInteropUtils {
FileList getFileList(String fileFieldId);

String[] getMultipleUploadFileNames(FileList fileList);

String getWebkitRelativePath(FileList fileList, double index);

Element getElementById(String elementId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.sagebionetworks.web.client;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import elemental2.dom.Blob;
import elemental2.dom.DomGlobal;
import elemental2.dom.File;
import elemental2.dom.FileList;
import elemental2.dom.HTMLInputElement;
import jsinterop.base.Js;
import org.sagebionetworks.web.client.callback.MD5Callback;

public class SynapseJsInteropUtilsImpl implements SynapseJsInteropUtils {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewrote all of these from JSNI to JsInterop using the Elemental2 classes


@Override
public FileList getFileList(String fileFieldId) {
elemental2.dom.Element fileToUploadElement =
DomGlobal.document.getElementById(fileFieldId);
if (
fileToUploadElement instanceof HTMLInputElement &&
((HTMLInputElement) fileToUploadElement).files != null
) return ((HTMLInputElement) fileToUploadElement).files;

return null;
}

private static String getFilesSelected(FileList fileList) {
StringBuilder out = new StringBuilder();
for (double i = 0; i < fileList.length; i++) {
File file = fileList.item(i);
out.append(file.name).append(';');
}
return out.toString();
}

@Override
public String[] getMultipleUploadFileNames(FileList fileList) {
String unSplitNames = getFilesSelected(fileList);
if (unSplitNames.isEmpty()) return null;
return unSplitNames.split(";");
}

@Override
public String getWebkitRelativePath(FileList fileList, double index) {
return (String) Js
.asPropertyMap(fileList.item(index))
.get("webkitRelativePath");
}
Comment on lines +43 to +48
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elemental2's File model does not surface the webkitRelativePath field, but we can easily get it with Js.asPropertyMap(obj).get("key")


@Override
public Element getElementById(String elementId) {
return Document.get().getElementById(elementId);
}
}
12 changes: 0 additions & 12 deletions src/main/java/org/sagebionetworks/web/client/jsinterop/JSON.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.sagebionetworks.web.client.jsinterop;

import elemental2.core.Global;
import org.sagebionetworks.gwt.client.schema.adapter.JSONObjectGwt;
import org.sagebionetworks.schema.adapter.JSONEntity;
import org.sagebionetworks.schema.adapter.JSONObjectAdapter;
Expand All @@ -20,6 +21,6 @@ public static Object toJsInteropCompatibleObject(JSONEntity entity) {
}
// This is a quick-and-dirty implementation--serialize the object to a string and use JSON.parse to deserialize it
// It would be more efficient to update the JSONObjectGwt instance to directly create and return a native object.
return JSON.parse(adapter.toJSONString());
return Global.JSON.parse(adapter.toJSONString());
}
}
Loading