6. Polymer
Polymer makes it easier and faster to create
anything from a button to a complete
application across desktop, mobile, and
beyond.
● webcomponents.js
● polymer.js
● core-components
○ collapse
○ drawer
○ dropdown
○ field
○ header
○ icon
○ input
○ menu
○ range
○ splitter
○ toolbar
○ tooltip
7. Polymer Paper components
The Paper elements are a set of UI elements
that implement the material design spec
paper components
○ button
○ checkbox
○ dialog
○ elements
○ fab
○ focusable
○ icon
○ input
○ item
○ progress
○ radio
○ ripple
○ shadow
○ slider
○ tabs
○ toast
○ toggle
10. 1. Use JsInterop to wrap Js objects and export Java classes
a. @JsType Wrap JS Objects without writing JSNI
b. @JsExport Expose GWT classes and methods to JS (not used)
c. @JsFunction Use interfaces as JS Functions (some issues)
2. Hand write Java Interfaces for the Web API
a. Window, Document, Element, Style, Events, …
b. Implementation does not extend JSO, needs casting (issues)
c. They might come with Elemental-2.0
3. Code generation
a. There could be ways to create all the java boilerplate code
GWT JsInterop
11. 1. Create reusable methods to import and create new
instances of web components
2. Define a Java Interface per component and event
- Extends HTMLElement or Event
3. Optionally Wrap each Interface in a Widget class for
classic GWT apps.
How to consume WC
12. Interfaces for native JS objects
@JsType
public interface HTMLElement extends Element {
}
@JsType
public interface Element extends Node {
@JsProperty
String getInnerHTML();
@JsProperty
DOMTokenList getClassList();
void setAttribute(String name, String value);
String getAttribute(String name);
void removeAttribute(String name);
}
@JsType
public interface Node extends EventTarget {
}
@JsType
public interface EventTarget {
void addEventListener(String type, EventListener listener);
}
13. Reusable methods
public class Polymer {
// Ensures that the tagName has been registered, otherwise injects
// the appropriate <import> tag in the document header
public static void ensureHTMLImport(String tagName) {
if ( !registered(tagName)) {
String href = GWT.getModuleBaseForStaticFiles() +
"bower_components/" + tagName + "/" + tagName + ".html";
Element link = Document.get().createLinkElement();
link.setAttribute("rel", "import");
link.setAttribute("href", href);
Document.get().getHead().appendChild(htmlImport);
}
}
// Returns a new instance of the Element. It loads the webcomponent
// if not loaded yet.
public static <T> T createElement(String tagName) {
ensureHTMLImport(tagName);
return (T)Document.get().createElement(tagName);
}
}
15. Consume WC in Java (Element API)
// Create a new instance of PaperButton
PaperButtonElement button = Polymer.create(PaperButtonElement.TAG;
// Set some properties
button.icon("polymer")
.label("Polymer")
.raisedButton(false);
// Add event listeners
button.addEventListener("click", new EventListener() {
public void onBrowserEvent(Event event) {
...
}
});
// Append to the document
myContainerElement.appendChild(button);
16. The WC Widget Class
public class PaperButton extends PolymerWidget {
//Default Constructor.
public PaperButton() {
this("");
}
//Constructor used by UIBinder
public PaperButton(String html) {
this(PaperButtonElement.TAG, html);
}
// Used when this element is extended by another.
protected PaperButton(String tag, String html) {
super(tag, html);
}
// Gets a handle to the Polymer object's underlying DOM element.
public PaperButtonElement getPolymerElement() {
return (PaperButtonElement) getElement();
}
public boolean isRaised() {
return getPolymerElement().isRaised();
}
}
public class PolymerWidget extends HTMLPanel {
public PolymerWidget(String tag, String html) {
super(tag, html);
Polymer.ensureHTMLImport(tag);
}
}
17. Consume WC in Java (Widget API)
// Widgets allow consume WC using the GWT classic way.
PaperButton button = new PaperButton();
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// ...
}
});
RootPanel.get().add(button);
20. GWT-Polymer
1. It’s a code generator to produce GWT wrappers for
polymer elements
a. Scrapes source documentation
2. Uses standard JS libraries to parse components.
a. node.js, npm, bower, gulp
b. context-free parser + lodash.template
3. It’s a Vaadin Labs project
a. Just released a paper gwt API snapshot (using polymer 0.5)
b. Work in progress to support polymer 0.9 (hydrolysis parser)
c. Still under definition, expect package name changes, etc
21. GWT-Polymer workflow
1. Checkout git clone github.com/vaadin/gwt-polymer
2. Run npm install
3. Edit the bower.json file and add/remove the
components you need for your project.
4. Run bower install to download components
5. Run gulp gwt-api in order to generate all java files
6. Run mvn clean package to produce your package .jar
7. Everything is contained in the artefact (polyfill,
components, java code).
22. GWT-Polymer goals
1. Very little code to maintain.
a. 950 LOC / 108 KB
2. But it produces a lot of java code
a. 13400 LOC (paper & core elements)
3. It uses native JS parsers for JS code.
a. The same tools that polymer uses
b. No GWT generators nor APT processors.
4. Standard tools for web developers.
a. They can deliver gwt libraries without knowing java
23. Discussion
1. Should we deliver separated ready-to-use libraries?
a. GWT-Paper 0.5.6.x (matches paper version)
b. Vaadin-Components 0.5.0.x (matches vaadin version)
2. Should we support GWT Widgets or Elements?
3. Makes sense to use JS code generators, or should we
use the Java way?
4. Could we eventually support other JS parsers to wrap
other JS libraries?
a. closure annotations, typescript, etc.