Coder Social home page Coder Social logo

google / elemental2 Goto Github PK

View Code? Open in Web Editor NEW
147.0 28.0 35.0 360 KB

Type checked access to browser APIs for Java code.

License: Apache License 2.0

Java 51.00% Shell 9.78% Starlark 39.22%
j2cl gwt web-storage indexeddb webgl dom promise svg jsinterop

elemental2's Introduction

Elemental2 · Build Status

Elemental2 provides type checked access to all browser APIs for Java code. This is done by using closure extern files and generating JsTypes, which are part of the new JsInterop specification that is both implemented in GWT and J2CL.

Bazel dependencies

If your project uses Bazel, add this repository as an external dependency in your WORKSPACE file:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "com_google_elemental2",
    strip_prefix = "elemental2-1.2.1",
    url = "https://github.com/google/elemental2/archive/1.2.1.zip",
)

load("@com_google_elemental2//build_defs:repository.bzl", "load_elemental2_repo_deps")
load_elemental2_repo_deps()

load("@com_google_elemental2//build_defs:workspace.bzl", "setup_elemental2_workspace")
setup_elemental2_workspace()

Now from you can add elemental2 targets as needed to your j2cl_library deps.

Following are the different elemental2 modules and their target names:

module Bazel targets for J2CL
core @com_google_elemental2//:elemental2-core-j2cl
dom @com_google_elemental2//:elemental2-dom-j2cl
promise @com_google_elemental2//:elemental2-promise-j2cl
indexeddb @com_google_elemental2//:elemental2-indexeddb-j2cl
svg @com_google_elemental2//:elemental2-svg-j2cl
webgl @com_google_elemental2//:elemental2-webgl-j2cl
media @com_google_elemental2//:elemental2-media-j2cl
webstorage @com_google_elemental2//:elemental2-webstorage-j2cl

Maven dependencies

If your project uses Maven, add the following maven dependencies in your pom.xml:

<dependency>
  <groupId>com.google.elemental2</groupId>
  <artifactId>${artifact-id}</artifactId>
  <version>1.2.1</version>
</dependency>
module artifact-id
core elemental2-core
dom elemental2-dom
promise elemental2-promise
indexeddb elemental2-indexeddb
svg elemental2-svg
webgl elemental2-webgl
media elemental2-media
webstorage elemental2-webstorage

Download the jar files

You can also download manually the jars files.

module jar file
core elemental2-core.jar
dom elemental2-dom.jar
promise elemental2-promise.jar
indexeddb elemental2-indexeddb.jar
svg elemental2-svg.jar
webgl elemental2-webgl.jar
media elemental2-media.jar
webstorage elemental2-webstorage.jar

GWT

Elemental2 v1.0.0+ requires GWT 2.9 or above.

If you use Elemental2 with GWT, you need to inherit the right gwt module in your gwt.xml file:

module GWT module name
core elemental2.core.Core
dom elemental2.dom.Dom
promise elemental2.promise.Promise
indexeddb elemental2.indexeddb.IndexedDb
svg elemental2.svg.Svg
webgl elemental2.webgl.WebGl
media elemental2.media.Media
webstorage elemental2.webstorage.WebStorage

Build GWT compatible maven jar files

If you want to modify and/or build the last version on your own, follow the instructions below:

    $ npm install -g @bazel/bazelisk
    $ alias bazel=bazelisk
  • Clone this git repository:
    $ git clone https://github.com/google/elemental2.git
  • Run the release script:
        $ cd elemental2
        $ ./maven/release_elemental.sh --version local --no-deploy

The script will output the directory containing the generated jar files that can be used with maven.

Contributing

Please refer to the contributing document.

Licensing

Please refer to the license file.

Disclaimer

This is not an official Google product.

elemental2's People

Contributors

bugreportuser avatar cushon avatar dependabot[bot] avatar gkdn avatar ibaca avatar jdramaix avatar kant avatar lauraharker avatar mollyibot avatar niloc132 avatar nreid260 avatar paulcapron avatar realityforge avatar swuecho avatar tbroyer avatar tjgq avatar varomodt avatar vegegoku avatar zbynek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elemental2's Issues

JsString.replace offers some invalid overloads

JsString.replace overloads - half are invalid, or at least confusing since they allow the third argument, but it will be ignored:

//remove
@JsOverlay
 public final String replace(RegExp regex, Function str, String flags) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex),
       Js.<ReplaceStrUnionType>uncheckedCast(str),
       flags);
 }

 @JsOverlay
 public final String replace(RegExp regex, Function str) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex), Js.<ReplaceStrUnionType>uncheckedCast(str));
 }

//remove
 @JsOverlay
 public final String replace(RegExp regex, ReplaceStrUnionType str, String flags) {
   return replace(Js.<ReplaceRegexUnionType>uncheckedCast(regex), str, flags);
 }

 @JsOverlay
 public final String replace(RegExp regex, ReplaceStrUnionType str) {
   return replace(Js.<ReplaceRegexUnionType>uncheckedCast(regex), str);
 }

//remove
 @JsOverlay
 public final String replace(RegExp regex, String str, String flags) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex),
       Js.<ReplaceStrUnionType>uncheckedCast(str),
       flags);
 }

 @JsOverlay
 public final String replace(RegExp regex, String str) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex), Js.<ReplaceStrUnionType>uncheckedCast(str));
 }

//remove
 @JsOverlay
 public final String replace(ReplaceRegexUnionType regex, Function str, String flags) {
   return replace(regex, Js.<ReplaceStrUnionType>uncheckedCast(str), flags);
 }

 @JsOverlay
 public final String replace(ReplaceRegexUnionType regex, Function str) {
   return replace(regex, Js.<ReplaceStrUnionType>uncheckedCast(str));
 }

//remove
 public native String replace(ReplaceRegexUnionType regex, ReplaceStrUnionType str, String flags);

 public native String replace(ReplaceRegexUnionType regex, ReplaceStrUnionType str);

//remove
 @JsOverlay
 public final String replace(ReplaceRegexUnionType regex, String str, String flags) {
   return replace(regex, Js.<ReplaceStrUnionType>uncheckedCast(str), flags);
 }

 @JsOverlay
 public final String replace(ReplaceRegexUnionType regex, String str) {
   return replace(regex, Js.<ReplaceStrUnionType>uncheckedCast(str));
 }

//remove
 @JsOverlay
 public final String replace(String regex, Function str, String flags) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex),
       Js.<ReplaceStrUnionType>uncheckedCast(str),
       flags);
 }

 @JsOverlay
 public final String replace(String regex, Function str) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex), Js.<ReplaceStrUnionType>uncheckedCast(str));
 }

//remove
 @JsOverlay
 public final String replace(String regex, ReplaceStrUnionType str, String flags) {
   return replace(Js.<ReplaceRegexUnionType>uncheckedCast(regex), str, flags);
 }

 @JsOverlay
 public final String replace(String regex, ReplaceStrUnionType str) {
   return replace(Js.<ReplaceRegexUnionType>uncheckedCast(regex), str);
 }

//remove
 @JsOverlay
 public final String replace(String regex, String str, String flags) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex),
       Js.<ReplaceStrUnionType>uncheckedCast(str),
       flags);
 }

 @JsOverlay
 public final String replace(String regex, String str) {
   return replace(
       Js.<ReplaceRegexUnionType>uncheckedCast(regex), Js.<ReplaceStrUnionType>uncheckedCast(str));
 }

Example code: "fooBarBaz".replace(/([a-z])([A-Z])/, '$1-$2', 'g') does not work (returns "foo-BarBaz", but "fooBarBaz".replace(/([a-z])([A-Z])/g, '$1-$2') does work ("foo-Bar-Baz").

From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace:

Firefox-specific notes

  • flags was a non standard third argument only available in Gecko : str.replace(regexp|substr, newSubStr|function, flags)
  • Starting with Gecko 27 (Firefox 27 / Thunderbird 27 / SeaMonkey 2.24), this method has been adjusted to conform with the ECMAScript specification. When replace() is called with a global regular expression, the RegExp.lastIndex property (if specified) will be reset to 0 (bug 501739).
  • Starting with Gecko 39 (Firefox 39 / Thunderbird 39 / SeaMonkey 2.36), the non-standard flags argument is deprecated and throws a console warning (bug 1142351).
  • Starting with Gecko 47 (Firefox 47 / Thunderbird 47 / SeaMonkey 2.44), the non-standard flags argument is no longer supported in non-release builds and will soon be removed entirely (bug 1245801).
  • Starting with Gecko 49 (Firefox 49 / Thunderbird 49 / SeaMonkey 2.46), the non-standard flags argument is no longer supported (bug 1108382).

Chrome has apparently never supported it, nor have the other browsers.


I would have filed this against closure-compiler (with a patch, removing the arg from their externs file), but for some reason we are patching bugs in those externs here, and I assume there is a reason for that rather than fixing the source.

IndexedDb Cursor?

I can't seem to find out where the cursor is returned from an IndexedDb "get" using an Index + OpenCursor(IDBKeyRange). Any quick examples anywhere as a guide? I cannot find anything.

JsArray<String>.slice() always causes ClassCastException

Apologies if this should not be a bug (or should be filed against GWT itself), but it was a surprise to discover (and a pain to debug) - JsArray<T>.slice() returns T[], which always causes a class cast exception, at least where T is java.lang.String. Workaround: use JsString or Object.

Steps to reproduce:

    JsArray<String> strings = new JsArray<>("a", "b", "c");
    String[] sliced = strings.slice();
    DomGlobal.window.alert(sliced[0]);

Replace String with either JsString or Object above, and it will work. Note that Double fails in the same way, despite ostensibly also being a value that can be passed interchangeably in and out of other JS methods. In fact, it appears that even elemental2 expects that this will work correctly: elemental2.core.ITemplateArray apparently extends JsArray<String>.

I'm not sure how this issue can be reasonably mitigated, aside from baking checks into GWT that this sort of thing isn't safe. Perhaps those methods should be annotated with @UncheckedCast?

Window is missing postMessage

Dovetailing into #16... it turns out that elemental2's Window actually doesn't have a postMessage!

https://www.w3.org/TR/2009/WD-html5-20090423/browsers.html#windowproxy shows it, but for some reason closure (and therefore elemental2) fails to allow it on the window object, only on global. In html5.js:

/**
 * This is a superposition of the Window and Worker postMessage methods.
 * @param {*} message
 * @param {(string|!Array<!Transferable>)=} opt_targetOriginOrTransfer
 * @param {(string|!Array<!MessagePort>|!Array<!Transferable>)=}
 *     opt_targetOriginOrPortsOrTransfer
 * @return {void}
 */
function postMessage(message, opt_targetOriginOrTransfer,
    opt_targetOriginOrPortsOrTransfer) {}

It should almost certainly be attached to Window.prototype as well, or instead of a static method.

Lack of any SVG Documentation (or examples)?

Help!
I can't find any documentation anywhere about how to use SVG in Elemental 2.
All my attempts at 'guessing' what methods to use result in ClasCastException or TypeError (e.g. createSVGLength is not a function etc.).
There appears to be an SVGDocument class, but I have no idea how to access the instance.
Just a simple example to get started would suffice.

window.onerror is missing column, error arguments

As of HEAD:

  @JsFunction
  public interface OnerrorCallbackFn {
    Object onInvoke(String p0, String p1, double p2);
  }

From whatwg spec

[TreatNonObjectAsNull]
callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long colno, optional any error);

From MDN:

window.onerror

window.onerror = function(messageOrEvent, source, lineno, colno, error) { ... }

Function parameters:

  • message: error message (string or event object). Available as event (sic!) in HTML onerror="" handler and also as an event object when dispatching an Event to window in which case the other arguments will not be supplied (as opposed to ErrorEvent which does cause the full range of arguments to be supplied to window.onerror whereas the single error event object is supplied to window.addEventListener('error') handlers) .
  • source: URL of the script where the error was raised (string)
  • lineno: Line number where error was raised (number)
  • colno: Column number for the line where the error occurred (number)
  • error: Error Object (object)

Of note, this document also indicates that the last two arguments were missing from firefox until version 31 (though, this is almost old enough to still support the legacy dev mode plugin...).

Notes at https://github.com/google/closure-compiler/blob/master/externs/browser/w3c_dom1.js#L873 appear incorrect - msdn link redirects to a different MDN on the error event with no other detail about this, and the MDN link is the one I quoted above.

I wasn't sure if you wanted this filed upstream, or instead made into a diff as with most of the other bugs in closure externs, so I filed it here for triage.

Build should generate maven-compatible jars, poms

Presently, the bazel build for elemental2 generates a few jars, but they seem difficult to use at this time in gwt2 projects.

For any module $MODULE here, we get these jars:

  • lib$MODULE.jar - contains .class files and .gwt.xml
  • lib$MODULE-class.jar - contains only .class files
  • lib$MODULE__internal_src_generated.jar - contains only .java files

In contrast, currently in maven central we have a regular jar file, with .java, .class, and .gwt.xml, a -classes jar with only .java files (perhaps should contain .gwt.xml as well?) as well as a pom which declares dependencies.

This issue is to track the ability to generate jars suitable for use in gwt2, and a mechanism for deployment (be it maven or gradle) to binary repositories for downstream use. I'm aware that there is a mechanism which can be used inside of Google, but for open source contributions and forks this can enable non-googlers to deploy snapshots or releases with fixes more directly.

Missing Element.children

The Element class should have a children property returning an HTMLCollection<Element>. This is specified by the ParentNode mixin. (The same mixin also specifies firstElementChild, lastElementChild, and childElementCount, all of which are present.)

Latest release is incompatible with latest jsinterop-base release

Latest elemental2 release is 1.0.0-beta-1 (released April 5, 2017), and in Document has the inner type CreateTextNodeDataUnionType, which defines:

@JsOverlay
default double asDouble() {
  return Js.castToDouble(this);
}

However, latest jsinterop-base release is 1.0.0-beta-2 (released May 5, 2017) has a Js class with no castToDouble. Instead, it has

@SuppressWarnings("ReferenceEquality") // GWT is not good at optimizing equals
public static double asDouble(Object obj) {
  checkType(Js.typeof(obj) == "number");
  return InternalJsUtil.asDouble(obj);
}

This results in a compile-time error with GWT 2 (and a runtime error with j2cl).

HTMLIFrameElement is missing contentWindow

Extern files in closure correctly define the other iframe properties in w3c_dom2.js, but this was not added until html5 apparently, see https://www.w3.org/TR/2000/CR-DOM-Level-2-20000510/html.html#ID-67133006 where it is missing, reflecting closure externs.

However, the html5 spec does include it - https://www.w3.org/TR/2011/WD-html5-20110113/the-iframe-element.html, and I have yet to find an html IDL made anywhere in the last several years that fails to include it. Is there a reason that closure externs seem so inconsistent and out of date with the matching spec/idl files? Why is elemental2 not built from idl files instead, so it can be up to date if closure is unable to stay current?

Without this, there is no clear way to call postMessage, etc.

Window.prompt has wrong return type

window.prototype.prompt is added to w3c_dom2.js by the patch in the repo with no specified return type, so it's generated as java.lang.Object.

window.prototype.prompt is however already defined in Closure externs (in window.js, for more than 7 years!) with the correct return type.

There's another difference between those 2 definitions though (besides the return type): that the first argument is made optional in Elemental2 (which is more correct); so it would look like the fix would be to declare the return type as @return {?string} in Elemental2's w3c_dom2.js.diff.

Instantiating elemental2.dom.RequestInit

This is a question but potentially an issue. How should I instantiate the elemental2.dom.RequestInit type to pass it on the the elemental2.dom.Window.fetch(String, RequestInit) method? Shouldn't there be some kind of a builder available to easily construct such types?

Missing `HTMLSpanElement`

Version: 1.0.0RC

There is no elemental2.dom.HTMLSpanElement for representing <span> elements.

Although HTMLSpanElement adds no new properties or methods to HTMLElement, it does have its own interface in the spec. (Whereas other, similar elements do not: there is no HTMLStrongElement.)

Workaround: One can use the HTMLElement class to represent <span>s, but this is bad type safety given their workhorse nature. (Presumably this is precisely why W3C gave it its own interface.)

Generating POMs in bazel

Is there any mechanism for generating poms in Bazel? A brief look around suggests that there is nothing in place atm.

Until there is would you consider a pull request that:

  • checked in minimal poms for each jar in the location java/elemental2/<module>/pom.xml
  • an enhancement to build_gwt_mvn_jars.sh that copied these poms to exist side-by-side with jars
  • an enhancement to build_gwt_mvn_jars.sh that laid out the filesystem in a Maven2 compatible format.

This would make it a lot easier to integrate this into more traditional build systems.

elemental2.dom.HTMLDocument missing defaultView and elemental2.dom.Window missing getComputedStyle

For example, I wanted to do this (JSNI JavaScript) in Elemental 2:
var zindex = document.defaultView.getComputedStyle(elems[i],null).getPropertyValue("z-index");

But I could not find defaultView on Document or HTMLDocument, and could not find getComputedStyle except on ViewCSS (it seems it should be on Window).
What is ViewCSS and how do I achieve what I want here in Elemental 2? It seems it is not currently possible, and that my JSNI must stay for now.......

location isn't a Location in IE11, Edge

This is going to be a stretch... but let's talk it out anyway.

It turns out that GWT (and J2CL)'s type checking that is done on @JsType objects breaks on the window.location instance in basically any browser made by Microsoft, since as the title says, location isn't a Location.

Bug report filed with Microsoft: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14307901/

screen shot 2017-10-19 at 4 18 14 pm

The first two are sane enough, but the third is not quite right, and the fourth seems internally inconsistent, how can an object not be an instance of its own type's constructor.

The workaround is to either never need to cast to Location (which is a problem, given that Location is missing pieces, and updates haven't proven to be timely), or mark Location objects as actually just plain Object:

@JsType(name = "Object", namespace = JsPackage.GLOBAL, isNative = true)
public class Location {

If you happen to make your own Location object (because elemental2's is broken), you must do this, or use unchecked casts to convert. In the future when Elemental2 has a working Location object, but there is some annoying bug elsewhere in Elemental2, casting from an external library's location to elemental's will have this problem.

If we cannot expect prompt updates, we need casts to be able to work to not compound hacks with more hacks - and even then, it might be wise to expect instanceof to behave as expected.

So, if you'll forgive the hyperbole, I think we might benefit from bending the rules here, if it isn't too difficult to implement. Excluding a vendor's entire browser provider's offerings from functioning correctly due to a hard to identify bug seems... hard to accept.

elemental2.dom.Window is missing document variable

I'm trying to access the document from a elemental2.dom.HTMLIFrameElement but noticed that elemental2.dom.Window (via HTMLIFrameElement.contentWindow) has no document variable.
There is no chance to access an iframe document via elemental2.

This should be possible. Please see more details in the example at https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/contentWindow

I need to solve that via native gwt code:

public final native elemental2.dom.Document document(elemental2.dom.Window contentWindow) /*-{
	return contentWindow.document;
}-*/;

Missed members in History API interface

elemental2.dom.History doesn't contains next standard mebers:

  • property length;
  • function go;
  • function back;
  • function forward;

I can create PR, but I have a question.
History API extern's declaration splitted in html5.js and ie_dom.js. Should I to fully redeclare History API in dom_missing_api (including constructor and other stuff from html5.js), or it is enough to only add missed memebers in dom_missing_api?

Typed Arrays should have an overloaded from method or constructor that takes an Array

JavaScript code, typically with arrays with thousands of elements, that I am trying to emulate with Elemental2:

var f=new Float32Array(JSON.parse("[1.1, 2.3, 4.5, 8]"));
f
Float32Array(4) [1.100000023841858, 2.299999952316284, 4.5, 8]

I have not found a way to coerce a JavaScript Array of Numbers returned from JSON parse to a double[],. You can of course create a new array and copy the Array elements into the double[] one by one, but that is not the point.
Having all typed Arrays accept an Array would solve this problem.

Add setters to CSS union types

Would it be possible to add setter methods to the CSS style properties that are represented by a Union type? For example, to set the padding property you can't do

someElement.style.setPadding("100px")

Where as for non union types you can do:

someElement.style.color ="red";

Proposal: code generation for dictionary types

There are many dictionaries that are used as arguments to methods. This is problematic because as currently generated, any type defined in a spec as a dictionary cannot be constructed in elemental .
Of course, there are workarounds, but they are ugly and not type-safe. Take for example the following example of Element::animate (which is not in Elemental2 yet):

JsPropertyMapOfAny keyframeAnimationOptions = JsPropertyMap.of();
keyframeAnimationOptions.set("duration",10_000);
keyframeAnimationOptions.set("iterations", Infinity);     
document.querySelector("div.clouds").animate(transitions,  Js.uncheckedCast(keyframeAnimationOptions));

The second parameter is a KeyframeAnimationOptions, but since I cannot construct it, I have to create it as a property map, hope I spell the property names correctly and uncheckedCast it. It is basically back to raw JavaScript.
What I would like to write instead is:

KeyframeAnimationOptions options=new KeyframeAnimationOptions();
options.setDuration(10_000);
options.setIterations(Infinity);
document.querySelector("div.clouds").animate(transitions,options);

The root problem is the @JsType annotation added to Dict types. Any class that does not have an equivalent class in JavaScript should instead be descended from JsObject (with the changes in Issue #5 ),
with getters and setters for the properties that call JsObject::set and JsObject::get, for example:

public class AnimationEffectTimingProperties extends JsObject {

    public void setDuration(double duration){
        set("duration", duration);
    }

    public void setDuration(String duration){
        set("duration", duration);
    }

    public AnimationEffectTimingReadOnly.DurationUnionType getDuration(){
        return get("duration");
    }

    public void setIterations(double iterations){
        set("iterations", iterations);
    }

    public double getIterations(){
        return get("iterations");
    }
// ... more properties here
}

This then allows me to write type safe code, with code completion.

For an example that is applicable to Elemental2, see GeoLocation::getCurrentPosition or GeoLocation:watchPosition, which take a Dictionary (per the spec) of type PositionOptions (GeoLocationPostionOptions in elemental), but which you will not be able to construct as currently defined.

all methods from InternalUtils should be implemented by JsObject

Is there a reason JsObject does not have all the methods currently hidden in InternalUtils? Adding them would be trivial, for example:

    @JsOverlay
    public final <T> T get(String key) {
        return Utils.get(this, key);
    }

    @JsOverlay
    public final <T> void set(String key, T value) {
        Utils.set(this, key, value);
    }

    @JsOverlay
    public final boolean has(String key){
        return Utils.has(this, key);
    }

   // ...other methods here

    private static final class Utils{
        public static native <T> void set(JObject object, String key, T value)/*-{
            object[key] = value;
        }-*/;

        public static native <T> T get(JObject object, String key)/*-{
            return object[key];
        }-*/;

        public static native boolean has(JObject jObject, String key) /*-{
            return key in object;
        }-*/;

    // ... other methods here

     Utils(){}
    }

This change would also make JsPropertyMap redundant.

At the very least InternalUtils should be renamed and made public, but I think it would be more natural to invoke the methods on the object itself rather than calling static methods in a utility class

HTMLElement.style.setAttribute throw style.setAttribute is not a function

GWT version : 2.8.2
elemental2 version : 1.0.0-RC1

using the setAttribute from elemental2 CSSStyleDeclaration gives is not a function, while using setProperty works.

to repeat the case add the following code snippet

HTMLElement element= (HTMLElement) DomGlobal.document.createElement("div");
element.style.setProperty("padding-left","10px");//works
element.style.setAttribute("padding-right","10px");//fail

DomGlobal.document.body.appendChild(element);

the exception

App.java:13 Uncaught TypeError: element_0_g$.style.setAttribute is not a function
    at wzd_g$.xzd_g$ [as onModuleLoad_0_g$] (App.java:13)
    at Array.crb_g$ (org_00046sample_0004…MethodHolder.java:3)
    at initializeModules_0_g$ (ModuleUtils.java:44)
    at Dp_g$ (Impl.java:309)
    at Gp_g$ (Impl.java:368)
    at Impl.java:78
    at wqb_g$ (ModuleUtils.java:55)
    at App.java:9

i noticed that in the MDN documentation there is no setAttribute method
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration

if it is something need to be fixed and i can make a PR for, i will gladly do.
Thanks

Build fails with Bazel on Widows and VS Build tools 2017

  C:/Program Files/Git/usr/bin/bash.exe -c source external/bazel_tools/tools/genrule/genrule-setup.sh; [[ $(patch --version) == "GNU patch"* ]] && extra_args='--follow-symlinks' || extra_args='';patch ${extra_args} external/com_google_closure_compiler/externs/es6_collections.js -i java/elemental2/core/es6_collections.js.diff -o bazel-out/msvc_x64-fastbuild/genfiles/java/elemental2/core/es6_collections_patched.js .
patching file bazel-out/msvc_x64-fastbuild/genfiles/java/elemental2/core/es6_collections_patched.js (read from external/com_google_closure_compiler/externs/es6_collections.js)
Hunk #1 FAILED at 51.
Hunk #2 FAILED at 81.
Hunk #3 FAILED at 140.
Hunk #4 FAILED at 158.
Hunk #5 FAILED at 183.
Hunk #6 FAILED at 232.
6 out of 6 hunks FAILED -- saving rejects to file bazel-out/msvc_x64-fastbuild/genfiles/java/elemental2/core/es6_collections_patched.js.rej

Can't bazel build //...

Starting local Bazel server and connecting to it...
INFO: SHA256 (https://github.com/google/jsinterop-generator/archive/master.zip) = 8a12f0247e51630e57f4e69849d739f4f60f0c2664f7d5ffc61be220d75b4ba8
INFO: SHA256 (https://github.com/google/jsinterop-base/archive/master.zip) = 1b3e51c7d0cecbda5ade78feeff93791639d7fa48922a7ca63220654c69c0ee4
ERROR: /Users/kostik/Projects/elemental2/third_party/BUILD:228:1: error loading package '@com_google_jsinterop_base//java/jsinterop/base': Extension file not found. Unable to load package for '@com_google_j2cl//build_defs:rules.bzl': The repository could not be resolved and referenced by '//third_party:jsinterop-base'
ERROR: Analysis of target '//third_party:jsinterop-base' failed; build aborted: error loading package '@com_google_jsinterop_base//java/jsinterop/base': Extension file not found. Unable to load package for '@com_google_j2cl//build_defs:rules.bzl': The repository could not be resolved
INFO: Elapsed time: 11.512s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (35 packages loaded)
    currently loading: @com_google_jsinterop_base//java/jsinterop/base

I wanted to import it to my project. I saw there're errors, and decided to check whether it compiles. It obvious don't. Could you help with fixing it?

activeElement is missing from Document

Elemental2 version : 1.0.0-RC1
The document object provide by DomGloabl does not have the activeElement property
as a workaround i extended the HTMLDocument type and added the property and it worked out

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class MyDocument extends HTMLDocument {
    public Element activeElement;
}

checking this out on MDN it says it is supported by most of modern browsers.

https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement

Missing Document.execCommand

Elemental2 version : 1.0.0-RC1
The document object provided by DomGloabl does not have the execCommand function property
as a workaround i extended the HTMLDocument type and added the function and it worked out

@jstype(isNative = true, namespace = JsPackage.GLOBAL)
public class MyDocument extends HTMLDocument {
public native boolean execCommand(String aCommandName, boolean aShowDefaultUI, String aValueArgument);
}

the function seems to exist for gecko_dom extern in closure compiler
https://github.com/google/closure-compiler/blob/41a4dcce5ec80df173e3b5f22f93eabb6ee525a3/externs/browser/gecko_dom.js#L497

other links
https://www.w3.org/TR/clipboard-apis/

https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

Location do not contains fields

The closure externs seem ok, but elemental does not contain Location fields (href, protocol, search, etc).
https://github.com/google/closure-compiler/blob/master/externs/browser/ie_dom.js#L1252

I think this ie_dom is the one used because it is the unique place where 'forceReload' appears.

Current elemental2 Location class:

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public interface Location {
  void assign(String url);
  void reload();
  void reload(boolean forceReload);
  void replace(String url);
}

Document.window.getSelection is missing from DomGlobal.window

the getSelection method is missing from DomGlobal.window. It would be very nice to add it, in the meantime, I've been using the following workaround as generously suggested by @niloc132.

@JsMethod(name="getSelection", namespace=JsPackage.GLOBAL)
public static native Selection getSelection();

Can't create a bazel project which uses elemental2 with j2cl

Here's the repo: https://github.com/solomatov/j2cl-sandbox

When I run it, I got the following error:

konstantins-mbp:j2cl-sandbox kostik$ bazel build //...
INFO: Build options have changed, discarding analysis cache.
ERROR: /Users/kostik/Projects/j2cl-sandbox/src/sandbox/BUILD.bazel:10:1: error loading package '@com_google_elemental2//java/elemental2/core': Extension file not found. Unable to load package for '@com_google_jsinterop_generator//:jsinterop_generator.bzl': The repository could not be resolved and referenced by '//src/sandbox:main'
ERROR: Analysis of target '//src/sandbox:main' failed; build aborted: error loading package '@com_google_elemental2//java/elemental2/core': Extension file not found. Unable to load package for '@com_google_jsinterop_generator//:jsinterop_generator.bzl': The repository could not be resolved
INFO: Elapsed time: 0.200s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (6 packages loaded)
    currently loading: @bazel_tools//tools/jdk ... (3 packages)

Maven regards the current POMs as invalid

Note: This is the same issue as described in google/jsinterop-base#2 except in elemental2. This problem is a greater impact for this project as elemental2 projects have correctly defined dependencies but Maven refuses to follow them. Anyhoo the following description is a copy of the jsinterop-base issue:

...

The POM generated by this project is invalid and generates warning such as the following when run through modern version of maven (3.5.3):

[WARNING] The POM for com.google.elemental2:elemental2-dom:jar:1.0.0-RC1 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details

The problem is that the transitive dependency needs to be manually specified. Investigation seems to indicate that the problem is actually in the parent pom and simply updating to the latest parent pom fixes this.

The way to fix this is to change the pom output according to the following diff.

@@ -6,7 +6,7 @@
   <parent>
     <groupId>org.sonatype.oss</groupId>
     <artifactId>oss-parent</artifactId>
-    <version>7</version>
+    <version>8</version>
   </parent>
 

I am unfamiliar with the build system otherwise I would suggest the fix and assume that this should be a trivial fix for someone who is familiar.

If this is not the case then kick me and I can dive into it.

TypedArrays should support more than `Double` values

From what I can tell in the integer_entities.txt update, the build now can generate int or Integer in some cases instead of Double. This doesn't seem to have been applied to the TypedArray subtypes, resulting in some unique getAt and setAt calls. Working from PlayN sources as I patch them to use elemental2 instead of JSOs, ByteBuffer.getShort now must look like this:

    public final short getShort (int baseOffset) {
      short bytes = 0;
      if (order == ByteOrder.BIG_ENDIAN) {
          bytes = (short)(((byte) (double) byteArray.getAt(baseOffset)) << 8);
          bytes |= (((byte) (double) byteArray.getAt(baseOffset + 1)) & 0xFF);
      } else {
          bytes = (short) (((byte) (double) byteArray.getAt(baseOffset + 1)) << 8);
          bytes |= (((byte) (double) byteArray.getAt(baseOffset)) & 0xFF);
      }
      return bytes;
    }

Since Int8Array is a TypedArray is a JsArrayLike<Double>, the getAt call returns Double, which cannot be shifted, so first we cast to double, which still can't be shifted, so cast to byte. Technically we could cast to int in the second one, but I wanted to be precise here. We of course have to assume that the browser would never return something outside the range of a byte here.

    public final ByteBuffer putInt (int baseOffset, int value) {
      if (order == ByteOrder.BIG_ENDIAN) {
          for (int i = 3; i >= 0; i--) {
              byteArray.setAt(baseOffset + i, (double)(byte)(value & 0xFF));
              value = value >> 8;
          }
      } else {
          for (int i = 0; i <= 3; i++) {
              byteArray.setAt(baseOffset + i, (double)(byte)(value & 0xFF));
              value = value >> 8;
          }
      }
      return this;
    }

Same idea here - the int value is being shifted and masked, and can't be used directly as a double. Granted, the cast to byte isn't technically required here, but it does seem less un-clear to a reader than casting an int to a double so you can put it in a byte array.

I'm not sure exactly how this can be improved, without just listing all of these signatures by hand, but this is pretty terrible Java to have to write. At least in the case of PlayN it is hidden behind emul code, but I had understood that elemental2 was meant to be user facing for the most part.

JsIterator interface apparently permits Java code to implement two methods with the same name

@JsType(isNative = true, name = "Iterator", namespace = JsPackage.GLOBAL)
public interface JsIterator<VALUE> {
  JsIIterableResult<VALUE> next();

  JsIIterableResult<VALUE> next(VALUE p0);
}

Attempting to implement this results in runtime confusion, as the Java type is attempting to export two different functions, both with the same name "next". Here from just wrapping a plain iterator - returning null for the next(val0), and roughly this code for the next() method:

JsIIterableResult<SomeObject> val = JsIIterableResult.create();
if (iterator.hasNext()) {
  val.setValue(iterator.next());
}
val.setDone(!iterator.hasNext());
return val;
cggl.MyIterator_classLit = createForClass('my.pack.age', 'MyIterator', 355);
mp.MyIterator = function MyIterator(val$iterator){
  this.val$iterator2 = val$iterator;
}
;
defineClass(356, 1, {}, mp.MyIterator);
_.next = function next_1(p0){
  return castTo(p0, 59) , null;
}
;
_.next = function next_0(){
  var val;
  val = jb.emptyObjectLiteral();
  ju.$hasNext_8(this.val$iterator2) && (val.value = ju.$next(this.val$iterator2));
  val.done = !ju.$hasNext_8(this.val$iterator2);
  return val;
}
;

It isn't clear how the developer can know that this cannot be implemented by their own Java (aside from the "try-it-and-fail" approach), in contrast with EventInit, JsIterableResult and other interfaces. It looks like perhaps several bugs coming together, but at least for elemental2, the next(val) method could be removed. It doesn't appear to be a part of the spec except in a "sure, I guess you could do that, but we're not defining it" sort of way https://www.ecma-international.org/ecma-262/6.0/#sec-iteration, suggesting that the specifying the type (or count) of the argument in the interface may not be necessarily correct.

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator.

Proposals for new artifacts

Would this project consider accepting pull requests for additional artifacts? Is this on a case-by-case basis or is anything that is available as externs in the closure-compiler project a candidate. In particular I am interested in:

  • An elemental2-webassembly artifact based off @com_google_closure_compiler//:contrib/externs/webassembly.js. We have produced a jar for this and it seems to be reasonable - or at least we have not run into any issues yet.
  • An elemental2-webcrypto artifact based off @com_google_closure_compiler//:externs/browser/w3c_webcrypto.js. (We have yet to try this but it would be fun to play with.

Thoughts? Do they live in elemental2 or should they live elsewhere?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.