Last active
March 18, 2016 11:55
-
-
Save bduisenov/2c5ef0e4ff4874f2c5d2 to your computer and use it in GitHub Desktop.
gwt jsinterop mapping to vue.js
This file contains hidden or 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
import jsinterop.annotations.JsConstructor; | |
import jsinterop.annotations.JsFunction; | |
import jsinterop.annotations.JsIgnore; | |
import jsinterop.annotations.JsMethod; | |
import jsinterop.annotations.JsOverlay; | |
import jsinterop.annotations.JsPackage; | |
import jsinterop.annotations.JsProperty; | |
import jsinterop.annotations.JsType; | |
import com.google.gwt.dom.client.Element; | |
/** | |
* Created by bduisenov on 16/12/15. | |
*/ | |
@JsType(namespace = JsPackage.GLOBAL, isNative = true) | |
public class Vue<T> { | |
@JsProperty | |
private static Config config; | |
/** | |
* The data object for the Vue instance. It can be accessed as vm.$data | |
*/ | |
@JsProperty | |
private Data<T> $data; | |
@JsConstructor | |
public Vue(Options<T> options) { | |
} | |
/** | |
* Vue.config is an object containing Vue’s global settings. Here are the list of all the | |
* avaiable settings with their default values | |
* | |
* <code> | |
* { | |
* // print stack trace for warnings? | |
* debug: true, | |
* // attribute prefix for directives | |
* prefix: 'v-', | |
* // interpolation delimiters | |
* // for HTML interpolations, add | |
* // 1 extra outer-most character. | |
* delimiters: ['{{', '}}'], | |
* // suppress warnings? | |
* silent: false, | |
* // interpolate mustache bindings? | |
* interpolate: true, | |
* // use async updates (for directives & watchers)? | |
* async: true, | |
* // allow altering observed Array's prototype chain? | |
* proto: true | |
* } | |
* </code> | |
*/ | |
@JsType | |
public static class Config { | |
public boolean debug = true; | |
public Config(boolean debug) { | |
this.debug = debug; | |
} | |
} | |
/** | |
* The instantiation options used for the current Vue instance. This is useful when you want to | |
* include custom properties in the options | |
* | |
* @param <T> | |
*/ | |
@JsType | |
public static class Options<T> { | |
/** | |
* Provide the Vue instance with an existing DOM element. It can be a CSS selector string, | |
* an actual HTMLElement, or a function that returns an HTMLElement. The resolved element | |
* will be accessible as vm.$el. | |
* | |
* When used in Vue.extend, a function must be provided so each instance gets a separately | |
* created element. | |
* | |
* If the option is available at instantiation, the instance will immediately enter | |
* compilation; otherwise, the user will have to explicitly call vm.$mount() to manually | |
* start the compilation. | |
*/ | |
public String el; | |
/** | |
* The data object for the Vue instance. It can be accessed as vm.$data | |
*/ | |
public Data<T> data; | |
/** | |
* A string template to be inserted into vm.$el. Any existing markup inside vm.$el will be | |
* overwritten, unless content insertion points are present in the template. If the replace | |
* option is true, the template will replace vm.$el entirely. | |
* | |
* If it starts with # it will be used as a querySelector and use the selected element’s | |
* innerHTML and the template string. This allows the use of the common | |
* <script type="x-template"> trick to include templates. | |
*/ | |
public String template; | |
/** | |
* An object where keys are expressions to watch and values are the corresponding callbacks. | |
* The value can also be a string of a method name. The Vue instance will call $watch() for | |
* each entry in the object at instantiation | |
* | |
* <code> | |
* var vm = new Vue({ | |
* data: { | |
* a: 1 | |
* }, | |
* watch: { | |
* 'a': function (val, oldVal) { | |
* console.log('new: %s, old: %s', val, oldVal) | |
* } | |
* } | |
* }) | |
* vm.a = 2 // -> new: 2, old: 1 | |
* </code> | |
*/ | |
public Watch watch; | |
@JsIgnore | |
public Options(String el, Data<T> data) { | |
this.el = el; | |
this.data = data; | |
} | |
@JsIgnore | |
public Options(String el, Data<T> data, String template) { | |
this.el = el; | |
this.data = data; | |
this.template = template; | |
} | |
@JsIgnore | |
public Options(String el, Data<T> data, Watch watch) { | |
this.el = el; | |
this.data = data; | |
this.watch = watch; | |
} | |
} | |
@JsType | |
public static class Data<T> { | |
public T data; | |
@JsIgnore | |
public Data(T data) { | |
this.data = data; | |
} | |
} | |
@FunctionalInterface | |
@JsFunction | |
public interface Function2<T> { | |
void apply(T newVal, T oldVal); | |
} | |
@JsType | |
public static class Watch { | |
@JsType | |
public static class Handler { | |
Function2 handler; | |
} | |
@JsProperty | |
Handler data; | |
@JsProperty | |
boolean deep; | |
} | |
@JsOverlay | |
public final Data<T> get$data() { | |
return $data; | |
} | |
@JsOverlay | |
public final void set$data(T $data) { | |
this.$data = new Data<>($data); | |
} | |
/** | |
* Set a data value on the Vue instance given a valid keypath. If the path doesn’t exist it will | |
* be created. | |
*/ | |
@JsMethod(name = "$set") | |
protected native void $setInner(String keypath, T value); | |
@JsOverlay | |
public final void $set(String keypath, T value) { | |
$setInner("data." + keypath, value); | |
} | |
@JsOverlay | |
public final void $set(T value) { | |
$setInner("data", value); | |
} | |
/** | |
* If the Vue instance didn’t get an el option at instantiation, you can manually call $mount() | |
* to assign an element to it and start the compilation. If no argument is provided, an empty | |
* <div> will be automatically created. Calling $mount() on an already mounted instance will | |
* have no effect. The method returns the instance itself so you can chain other instance | |
* methods after it. | |
*/ | |
public native void $mount(Element element); | |
public native void $mount(String id); | |
/** | |
* Completely destroy a vm. Clean up its connections with other existing vms, unbind all its | |
* directives and remove its $el from the DOM. Also, all $on and $watch listeners will be | |
* automatically removed. | |
*/ | |
public native void $destroy(); | |
public native void $destroy(boolean remove); | |
/** | |
* Watch an expression on the Vue instance for changes. The expression can be a single keypath | |
* or actual expressions | |
*/ | |
public native void $watch(String expression, Function2 callback); | |
/** | |
* To also detect nested value changes inside Objects, you need to pass in true for the third | |
* deep argument. Note that you don’t need to do so to listen for Array mutations. | |
*/ | |
public native void $watch(String expression, Function2 callback, boolean deep); | |
/** | |
* Passing in true for the fourth immediate argument will trigger the callback immediately with | |
* the current value of the expression | |
*/ | |
public native void $watch(String expression, Function2 callback, boolean deep, boolean immediate); | |
@JsOverlay | |
public static <T> Vue<T> create(String el, T data) { | |
return new Vue<>(new Options<>(el, new Data<>(data))); | |
} | |
@JsOverlay | |
public static <T> Vue<T> create(String el, T data, Function2 watchHandler) { | |
final Watch watch = new Watch(); | |
final Watch.Handler handler = new Watch.Handler(); | |
handler.handler = watchHandler; | |
watch.data = handler; | |
watch.deep = true; | |
Vue.config = new Config(true); | |
return new Vue<>(new Options<>(el, new Data<>(data), watch)); | |
} | |
@JsOverlay | |
public static <T> Vue<T> create(Config config, String el, T data, Function2 watchHandler) { | |
final Watch watch = new Watch(); | |
final Watch.Handler handler = new Watch.Handler(); | |
handler.handler = watchHandler; | |
watch.data = handler; | |
watch.deep = true; | |
return new Vue<>(new Options<>(el, new Data<>(data), watch)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment