Skip to content

Commit 73abc01

Browse files
committed
Merge branch 'release/v1.0-beta-5'
2 parents e72d535 + 69aaecf commit 73abc01

File tree

74 files changed

+1477
-482
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1477
-482
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</p>
88

99
Vue GWT integrates [Vue.js](https://vuejs.org/) with [GWT 2.8](http://www.gwtproject.org/) using [JsInterop](https://github.com/google/jsinterop-base) and [Elemental2](https://github.com/google/elemental2).
10-
It lets you write Vue.js components in Java.
10+
It lets you write Vue Components in Java.
1111

1212
<p align="center">
1313
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"/>
@@ -18,6 +18,7 @@ It lets you write Vue.js components in Java.
1818

1919
* **Vue.js** Components with a **Java controller**
2020
* Template expressions **type checking** at compile time
21+
* [**Web Components** (Custom Elements)](advanced/custom-elements.md) support
2122
* **HTML templates are compiled** during Java Compilation (only requires Vue.js runtime)
2223
* Use **regular Java Objects and Collections** in your templates
2324
* Supports [**injection** in Components](https://axellience.github.io/vue-gwt/essential/dependency-injection.html)

core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<parent>
88
<groupId>com.axellience</groupId>
99
<artifactId>vue-gwt-parent</artifactId>
10-
<version>1.0-beta-4</version>
10+
<version>1.0-beta-5</version>
1111
</parent>
1212

1313
<artifactId>vue-gwt-core</artifactId>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.axellience.vuegwt.core.annotations.component;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.Target;
5+
6+
import static java.lang.annotation.ElementType.METHOD;
7+
import static java.lang.annotation.RetentionPolicy.CLASS;
8+
9+
/**
10+
* Method annotated with this will emit an event automatically when called
11+
* Similar to @Emit() from vue-property-decorator
12+
* https://github.com/kaorun343/vue-property-decorator
13+
*/
14+
@Target(METHOD)
15+
@Retention(CLASS)
16+
public @interface Emit
17+
{
18+
String value() default "";
19+
}

core/src/main/java/com/axellience/vuegwt/core/annotations/style/Style.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
import static java.lang.annotation.RetentionPolicy.SOURCE;
88

99
/**
10-
* Annotation placed on Vue Components
10+
* Annotation placed on Style
11+
* Will be removed in Vue GWT beta-6.
12+
* Please check https://axellience.github.io/vue-gwt/gwt-integration/client-bundles-and-styles.html#styles
13+
* to see how to use styles in your templates without this annotation.
1114
* @author Adrien Baron
1215
*/
1316
@Target(TYPE)
1417
@Retention(SOURCE)
18+
@Deprecated
1519
public @interface Style
1620
{}

core/src/main/java/com/axellience/vuegwt/core/client/Vue.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
import com.axellience.vuegwt.core.client.component.VueComponent;
44
import com.axellience.vuegwt.core.client.component.options.VueComponentOptions;
5+
import com.axellience.vuegwt.core.client.customelement.CustomElementOptions;
6+
import com.axellience.vuegwt.core.client.customelement.VueCustomElementType;
57
import com.axellience.vuegwt.core.client.directive.options.VueDirectiveOptions;
68
import com.axellience.vuegwt.core.client.jsnative.jsfunctions.JsRunnable;
79
import com.axellience.vuegwt.core.client.tools.VueGWTTools;
810
import com.axellience.vuegwt.core.client.vue.VueConfig;
911
import com.axellience.vuegwt.core.client.vue.VueFactory;
1012
import com.axellience.vuegwt.core.client.vue.VueJsConstructor;
11-
import elemental2.core.Array;
1213
import elemental2.dom.Element;
14+
import jsinterop.annotations.JsMethod;
1315
import jsinterop.annotations.JsOverlay;
1416
import jsinterop.annotations.JsPackage;
1517
import jsinterop.annotations.JsProperty;
@@ -133,10 +135,53 @@ public static <T extends VueComponent> VueJsConstructor<T> extendJavaComponent(
133135
return extendedVueJsConstructor;
134136
}
135137

138+
@JsOverlay
139+
public static <T extends VueComponent> VueCustomElementType<T> customElement(
140+
String componentTag, Class<T> vueComponentClass)
141+
{
142+
return Vue.customElement(componentTag, vueComponentClass, new CustomElementOptions<>());
143+
}
144+
145+
@JsOverlay
146+
public static <T extends VueComponent> VueCustomElementType<T> customElement(
147+
String componentTag, VueFactory<T> vueFactory)
148+
{
149+
return Vue.customElement(componentTag, vueFactory, new CustomElementOptions<>());
150+
}
151+
152+
@JsOverlay
153+
public static <T extends VueComponent> VueCustomElementType<T> customElement(
154+
String componentTag, VueJsConstructor<T> vueJsConstructor)
155+
{
156+
return Vue.customElement(componentTag, vueJsConstructor, new CustomElementOptions<>());
157+
}
158+
159+
@JsOverlay
160+
public static <T extends VueComponent> VueCustomElementType<T> customElement(
161+
String componentTag, Class<T> vueComponentClass, CustomElementOptions<T> options)
162+
{
163+
return Vue.customElement(componentTag, VueGWT.getFactory(vueComponentClass), options);
164+
}
165+
166+
@JsOverlay
167+
public static <T extends VueComponent> VueCustomElementType<T> customElement(
168+
String componentTag, VueFactory<T> vueFactory, CustomElementOptions<T> options)
169+
{
170+
return Vue.customElement(componentTag, vueFactory.getJsConstructor(), options);
171+
}
172+
173+
@JsOverlay
174+
public static <T extends VueComponent> VueCustomElementType<T> customElement(
175+
String componentTag, VueJsConstructor<T> vueJsConstructor, CustomElementOptions<T> options)
176+
{
177+
VueCustomElementLibInjector.ensureInjected();
178+
return Vue.customElementNative(componentTag, vueJsConstructor, options);
179+
}
180+
136181
// @formatter:off
137182
public static native <T extends VueComponent> VueJsConstructor<T> extend(VueComponentOptions<T> componentOptions);
138183

139-
public static native void nextTick(JsRunnable callback, Array context);
184+
public static native void nextTick(JsRunnable callback);
140185

141186
public static native <T> T set(Object object, String key, T value);
142187
public static native boolean set(Object object, String key, boolean value);
@@ -151,6 +196,9 @@ public static <T extends VueComponent> VueJsConstructor<T> extendJavaComponent(
151196
public static native void directive(String id, VueDirectiveOptions directiveOptions);
152197
public static native VueDirectiveOptions directive(String id);
153198

199+
@JsMethod(name = "customElement")
200+
public static native <T extends VueComponent> VueCustomElementType<T> customElementNative(String componentTag, VueJsConstructor<T> vueJsConstructor, CustomElementOptions options);
201+
154202
public static native <T extends VueComponent> void component(String id, VueComponentOptions<T> componentOptions);
155203
public static native <T extends VueComponent> void component(String id, VueJsConstructor<T> vueJsConstructor);
156204
public static native <T extends VueComponent> VueJsConstructor<T> component(String id);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.axellience.vuegwt.core.client;
2+
3+
import elemental2.dom.DomGlobal;
4+
import elemental2.dom.HTMLScriptElement;
5+
import jsinterop.base.JsPropertyMap;
6+
7+
class VueCustomElementLibInjector
8+
{
9+
static void ensureInjected()
10+
{
11+
if (isCustomElementInjected())
12+
return;
13+
14+
HTMLScriptElement scriptElement =
15+
(HTMLScriptElement) DomGlobal.document.createElement("script");
16+
scriptElement.text = VUE_CUSTOM_ELEMENT;
17+
DomGlobal.document.body.appendChild(scriptElement);
18+
}
19+
20+
private static boolean isCustomElementInjected()
21+
{
22+
return ((JsPropertyMap) DomGlobal.window).get("VueCustomElement") != null;
23+
}
24+
25+
/**
26+
* vue-custom-element v1.4.2
27+
* (c) 2017 Karol Fabjańczuk
28+
* Modified by Adrien Baron
29+
* @license MIT
30+
*/
31+
private static String VUE_CUSTOM_ELEMENT = "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):e.VueCustomElement=t()}(this,function(){\"use strict\";function e(e,t){return e.__proto__=t,e}function t(e,t){if(!e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return!t||\"object\"!=typeof t&&\"function\"!=typeof t?e:t}function n(){return Reflect.construct(HTMLElement,[],this.__proto__.constructor)}function o(e){function o(){!0===i.shadow&&HTMLElement.prototype.attachShadow&&this.attachShadow({mode:\"open\"}),i.constructorCallback.call(this,this)}function r(){i.connectedCallback.call(this,this)}function c(){i.disconnectedCallback.call(this,this)}function a(e,t,n){i.attributeChangedCallback.call(this,e,t,n,this)}var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(\"undefined\"!=typeof customElements){if(f){var u=function(e){function r(e){var n;!function(e,t){if(!(e instanceof t))throw new TypeError(\"Cannot call a class as a function\")}(this,r);var c=t(this,(r.__proto__||Object.getPrototypeOf(r)).call(this)),a=e?HTMLElement.call(e):c;return o.call(a),n=a,t(c,n)}return function(e,t){if(\"function\"!=typeof t&&null!==t)throw new TypeError(\"Super expression must either be null or a function, not \"+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(r,n),d(r,null,[{key:\"observedAttributes\",get:function(){return i.observedAttributes||[]}}]),r}();return u.prototype.connectedCallback=r,u.prototype.disconnectedCallback=c,u.prototype.attributeChangedCallback=a,customElements.define(e,u),u}var l=function(e){var t=e?HTMLElement.call(e):this;return o.call(t),t};return l.observedAttributes=i.observedAttributes||[],l.prototype=Object.create(HTMLElement.prototype,{constructor:{configurable:!0,writable:!0,value:l}}),l.prototype.connectedCallback=r,l.prototype.disconnectedCallback=c,l.prototype.attributeChangedCallback=a,customElements.define(e,l),l}}function r(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=e.length-t,o=new Array(n);n--;)o[n]=e[n+t];return o}function c(e){var t=e,n=[\"true\",\"false\"].indexOf(e)>-1,o=parseFloat(t,10),r=!isNaN(o)&&isFinite(t);return n?t=\"true\"===t:r&&(t=o),t}function a(e,t){if(e&&e.length)e.forEach(function(e){var n=h(e);-1===t.camelCase.indexOf(n)&&t.camelCase.push(n)});else if(e&&\"object\"===(void 0===e?\"undefined\":m(e)))for(var n in e){var o=h(n);-1===t.camelCase.indexOf(o)&&t.camelCase.push(o)}}function i(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1],n=[];return r(e).forEach(function(e){if(\"#text\"===e.nodeName)e.nodeValue.trim()&&n.push(t(\"span\",e.nodeValue));else if(\"#comment\"!==e.nodeName){var o=function(e){var t={};return r(e.attributes).forEach(function(e){t[\"vue-slot\"===e.nodeName?\"slot\":e.nodeName]=e.nodeValue}),t}(e),c={attrs:o,domProps:{innerHTML:e.innerHTML}};o.slot&&(c.slot=o.slot,o.slot=void 0),n.push(t(e.tagName,c))}}),n}function u(e,t){for(var n=arguments.length,o=Array(n>2?n-2:0),r=2;r<n;r++)o[r-2]=arguments[r];var c=function(e,t){var n={bubbles:!1,cancelable:!1,detail:t},o=void 0;return\"function\"==typeof window.CustomEvent?o=new CustomEvent(e,n):(o=document.createEvent(\"CustomEvent\")).initCustomEvent(e,n.bubbles,n.cancelable,n.detail),o}(t,[].concat(o));e.dispatchEvent(c)}function l(e,t,n,o,r){if(!e.__vue_custom_element__){var a=function(e,t,n){var o=t.propsData||{};return n.hyphenate.forEach(function(t,r){var a=e.attributes[t],i=n.camelCase[r];\"object\"!==(void 0===a?\"undefined\":m(a))||a instanceof Attr?a instanceof Attr&&a.value&&(o[i]=c(a.value)):o[i]=a}),o}(e,n.options,o),l=n.extend({beforeCreate:function(){this.$emit=function(){for(var t,n=arguments.length,o=Array(n),r=0;r<n;r++)o[r]=arguments[r];u.apply(void 0,[e].concat(o)),this.__proto__&&(t=this.__proto__.$emit).call.apply(t,[this].concat(o))}}}),s=e.cloneNode(!0).childNodes,f={propsData:a,props:o.camelCase,computed:{reactiveProps:function(){var e=this,t={};return o.camelCase.forEach(function(n){t[n]=e[n]}),t}},render:function(e){var t={props:this.reactiveProps};return e(l,t,i(s,e))}};if(r.shadow&&e.shadowRoot?(e.shadowRoot.innerHTML=\"<div></div>\",f.el=e.shadowRoot.children[0]):(e.innerHTML=\"<div></div>\",f.el=e.children[0]),function(e,t){t.camelCase.forEach(function(n,o){Object.defineProperty(e,n,{get:function(){return this.__vue_custom_element__[n]},set:function(e){if(\"object\"!==(void 0===e?\"undefined\":m(e))&&\"function\"!=typeof e||!this.__vue_custom_element__)this.setAttribute(t.hyphenate[o],c(e));else{var n=t.camelCase[o];this.__vue_custom_element__[n]=e}}})})}(e,o),e.__vue_custom_element__=new t(f),r.shadow&&r.shadowCss&&e.shadowRoot){var d=document.createElement(\"style\");d.type=\"text/css\",d.appendChild(document.createTextNode(r.shadowCss)),e.shadowRoot.appendChild(d)}e.removeAttribute(\"vce-cloak\"),e.setAttribute(\"vce-ready\",\"\"),u(e,\"vce-ready\")}}function s(e){e.customElement=function(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=function(e){var t={camelCase:[],hyphenate:[]},n=e.options;return n?(n.mixins&&n.mixins.forEach(function(e){a(e.props,t)}),a(n.props,t),t.camelCase.forEach(function(e){t.hyphenate.push(b(e))}),t):t}(n);return o(t,{constructorCallback:function(e){\"function\"==typeof r.constructorCallback&&r.constructorCallback.call(this,e)},connectedCallback:function(t){this.__detached__||l(this,e,n,i,r),\"function\"==typeof r.connectedCallback&&r.connectedCallback.call(this,t),this.__detached__=!1},disconnectedCallback:function(e){var t=this;this.__detached__=!0,\"function\"==typeof r.disconnectedCallback&&r.disconnectedCallback.call(this,e),setTimeout(function(){t.__detached__&&t.__vue_custom_element__&&t.__vue_custom_element__.$destroy(!0)},r.destroyTimeout||3e3)},attributeChangedCallback:function(e,t,n,o){if(this.__vue_custom_element__&&void 0!==n){var a=h(e);\"function\"==typeof r.attributeChangedCallback&&r.attributeChangedCallback.call(this,o,e,t,n),this.__vue_custom_element__[a]=c(n)}},observedAttributes:i.hyphenate,shadow:!!r.shadow&&!!HTMLElement.prototype.attachShadow})}}Object.setPrototypeOf=Object.setPrototypeOf||e;e.bind(Object);var f=\"undefined\"!=typeof Symbol&&\"undefined\"!=typeof Reflect,d=function(){function e(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,\"value\"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,n,o){return n&&e(t.prototype,n),o&&e(t,o),t}}();Object.setPrototypeOf(n.prototype,HTMLElement.prototype),Object.setPrototypeOf(n,HTMLElement);var p=/-(\\w)/g,h=function(e){return e.replace(p,function(e,t){return t?t.toUpperCase():\"\"})},_=/([^-])([A-Z])/g,b=function(e){return e.replace(_,\"$1-$2\").replace(_,\"$1-$2\").toLowerCase()},m=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e};return s.createElement=function(e){return new e},\"undefined\"!=typeof window&&window.Vue&&(window.Vue.use(s),s.installed&&(s.installed=!1)),s});";
32+
}

core/src/main/java/com/axellience/vuegwt/core/client/VueGWT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import jsinterop.annotations.JsIgnore;
1313
import jsinterop.annotations.JsPackage;
1414
import jsinterop.annotations.JsType;
15-
import jsinterop.base.JsConstructorFn;
15+
import jsinterop.base.Js;
1616
import jsinterop.base.JsPropertyMap;
1717

1818
import javax.inject.Provider;
@@ -156,7 +156,7 @@ public static <T extends VueComponent> VueJsConstructor<T> getJsConstructor(
156156
public static <T extends VueComponent> ComponentJavaConstructor getJavaConstructor(
157157
Class<T> vueComponentClass)
158158
{
159-
return (ComponentJavaConstructor) JsConstructorFn.of(vueComponentClass);
159+
return (ComponentJavaConstructor) Js.asConstructorFn(vueComponentClass);
160160
}
161161

162162
/**

core/src/main/java/com/axellience/vuegwt/core/client/VueLibInjector.java

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

core/src/main/java/com/axellience/vuegwt/core/client/component/VueComponent.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import com.axellience.vuegwt.core.client.component.options.watch.WatcherRegistration;
1010
import com.axellience.vuegwt.core.client.vnode.ScopedSlot;
1111
import com.axellience.vuegwt.core.client.vnode.VNode;
12-
import elemental2.core.Array;
12+
import elemental2.core.JsArray;
1313
import elemental2.dom.Element;
1414
import jsinterop.annotations.JsOverlay;
1515
import jsinterop.annotations.JsPackage;
@@ -38,17 +38,17 @@ public abstract class VueComponent
3838
@JsProperty private VueComponentOptions $options;
3939
@JsProperty private VueComponent $parent;
4040
@JsProperty private VueComponent $root;
41-
@JsProperty private Array<VueComponent> $children;
41+
@JsProperty private JsArray<VueComponent> $children;
4242
@JsProperty private Object $refs;
43-
@JsProperty private JsPropertyMap<Array<VNode>> $slots;
43+
@JsProperty private JsPropertyMap<JsArray<VNode>> $slots;
4444
@JsProperty private JsPropertyMap<ScopedSlot> $scopedSlots;
4545
@JsProperty private boolean $isServer;
4646
@JsProperty private Object $ssrContext;
47-
@JsProperty private Object $props;
4847
@JsProperty private Object $vnode;
4948
@JsProperty private JsPropertyMap<String> $attrs;
5049
@JsProperty private Object $listeners;
5150

51+
@JsProperty public JsPropertyMap<Object> $props;
5252
@JsProperty public String _uid;
5353

5454
// @formatter:off
@@ -115,7 +115,7 @@ public abstract class VueComponent
115115
}
116116

117117
@JsOverlay
118-
public final Array<VueComponent> $children()
118+
public final JsArray<VueComponent> $children()
119119
{
120120
return $children;
121121
}
@@ -127,7 +127,7 @@ public abstract class VueComponent
127127
}
128128

129129
@JsOverlay
130-
public final JsPropertyMap<Array<VNode>> $slots()
130+
public final JsPropertyMap<JsArray<VNode>> $slots()
131131
{
132132
return $slots;
133133
}
@@ -150,12 +150,6 @@ public abstract class VueComponent
150150
return $ssrContext;
151151
}
152152

153-
@JsOverlay
154-
public final Object $props()
155-
{
156-
return $props;
157-
}
158-
159153
@JsOverlay
160154
public final Object $vnode()
161155
{

0 commit comments

Comments
 (0)