web components v1

45
CLUB AJAX

Upload: mike-wilcox

Post on 22-Jan-2018

460 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Web Components v1

CLUB AJAX

Page 2: Web Components v1

by Mike Wilcox, January 2017

Web Components and ES6 Classes

Page 3: Web Components v1

JS Frameworks• Some more mobile friendly than others

• Although hard to say that any of them truly are • Jeff Atwood complains about poor Ember perf for Discourse

• Isomorphic/Universal Apps using server side rendering • Creates faster visual content on the page • But also creates a “valley of death” where the page is no functional

• Virtual DOM can sometimes be effective • Sometimes effective • Sometimes not

• On demand loading • Some frameworks support it, some don’t

Page 4: Web Components v1
Page 5: Web Components v1

Dojo

Page 6: Web Components v1

Dojo<div class='createSection' data-dojo-attach-point='createSection'> <div class='row'> <div data-dojo-attach-point="filterName" data-dojo-type="app/components/ui/TextFilter" data-dojo-props="fieldLabel:'${messages.filterName}', required: true”>

Page 7: Web Components v1

Dojo<div class='field'> ${labelNode} <div data-dojo-attach-point="textbox" class='fieldWidget' data-dojo-type="dijit/form/TextBox" data-dojo-attach-event="onKeyUp: _update"></div> </div>

Page 8: Web Components v1

define([ 'dojo/_base/declare', 'dx/Widget', 'dojo/text!./templates/TextFilter.html', 'dijit/form/TextBox'], function(declare, Widget, template) { return declare(Widget, { templateString: template, postMixInProperties: function(){ }, postCreate: function(){ }, focus: function(){ this.textbox.focus(); }, _setValueAttr: function(value){ this.textbox.set('value', value); }, _getValueAttr: function(){ return this.textbox.get('value'); },

Dojo

Page 9: Web Components v1

Ember

Page 10: Web Components v1

Ember<div class="client-page"> {{side-nav nav=navigation clientId=model.client.id}}

Page 11: Web Components v1

Ember<div class="nav-items"> {{#each nav as |link|}} {{#unless (eq link.state "hidden") }} {{#if (eq link.state "disabled") }} <div class="side-nav-link {{link.state}}"> <div class="side-nav-title">{{link.title}}</div> </div> {{else}} {{#link-to link.route title=link.title class=link.state}} <div class="side-nav-link {{link.state}}"> <div class="side-nav-title">{{link.title}}</div> </div> {{/link-to}} {{/if}} {{/unless}} {{/each}} </div>

Page 12: Web Components v1

Emberimport Ember from ‘ember'; import Navigation from '../../mixins/navigation'; export default Ember.Component.extend(Navigation, { classNames: ['side-nav'], nav: null, clientId: ‘NA’,

activeNavigation: Ember.computed('navigation', function () { let activeNavigationObject = []; this.get('navigation').forEach((mainItem)=> { ... }); return activeNavigationObject;}),

});

Page 13: Web Components v1

Angular 2

Page 14: Web Components v1

Angular<div [ngBusy]="{busy: busy, message: 'Please wait...'}"> <div *ngIf="settingView"> <my-actions [links]="settingView.actionUrls"></my-actions> </div> </div>

Page 15: Web Components v1

Angular<h4>Actions</h4> <div class="section"> <a href="{{links[0]}}">Change Your Password</a> <a href="{{links[1]}}">Change Your Security Questions</a> <a href="{{links[2]}}">Change other usernames for a Single Sign-On Experience</a> </div>

Page 16: Web Components v1

Angularimport { Component, Input, OnInit } from '@angular/core'; @Component({ moduleId: module.id.toString(), selector: 'my-actions', templateUrl: 'actions.component.html'}) export class ActionsComponent implements OnInit { constructor() { } @Input() links: string[] = []; ngOnInit() { }}

Page 17: Web Components v1

React

Page 18: Web Components v1

Reactimport React from 'react'; import { render } from 'react-dom'; import Text from './form-sections/text'; export default class Form extends React.Component { constructor(props) { super(props); } render() { return ( <ay-form ref="form"> <Text /> </ay-form> ); }}

Page 19: Web Components v1

Reactimport React from 'react'; import { render } from 'react-dom'; import pure from 'react-addons-pure-render-mixin'; export default class Text extends React.Component { constructor(props) { super(props); this.shouldComponentUpdate = pure.shouldComponentUpdate.bind(this); } render() { return ( <section> <ay-field type="text" value="" name="where" placeholder="Where"></ay-field> </section> ); }}

Page 20: Web Components v1

jQuery

Page 21: Web Components v1

React<div class="jq-picker"></div> <script> $.ready(function(){ $(".jq-picker").jqPicker(options); });</script>

Page 22: Web Components v1

JS Frameworks + Web Components• Web Components are “just HTML” so they will work with all of them

• It may require some manual wiring, like using addEventListener

• With plugins, you can make use of framework template functionality • https://github.com/webcomponents/react-integration • https://github.com/clubajax/react-inject-change-events

Page 23: Web Components v1

What are they?

Page 24: Web Components v1

Web Components Benefits• Part of the DOM - lifecycle tools for free!

• Future-proof and cross-browser (web standard) for creating and extending reusable components.

• Requires no library or framework to get started. Vanilla JS/HTML FTW!

• Provides a familiar programming model. It's just DOM/CSS/HTML.

• Creates a very modular system

• Tightly integrated with the browser's DevTools.

• Leverage existing accessibility features.

Page 25: Web Components v1

Web Components• Custom Elements

• Shadow DOM

• Templates

• HTML Imports

All four of these items are a WC3 spec, all of which makes up Web Components

Page 26: Web Components v1

Custom Elements• Define your own element types and functionality • Provides a standard way to associate JavaScript logic with an

element • Lifecycle methods • No confusing context — “this” is the element • Easy to inspect in debuggers

We could do custom elements with IE6… the difference is the life cycle methods

<x-tabs> <ul>Tab 1</ul> <ul>Tab 2</ul> <ul>Tab 3</ul> </x-tabs>

Page 27: Web Components v1

Shadow DOM

Content can be “projected” into provided slots

• Shadow DOM refers to the ability of the browser to include a subtree of DOM elements into the rendering of a document, but not into the main document DOM tree.

• CSS style rules are constrained to the shadow tree they were defined in.

• The DOM is also encapsulated. For example, document.querySelectorAll('div'); will not return any results from a custom element with Shadow DOM

Page 28: Web Components v1

Templates• The template element is used to declare fragments of HTML

that can be cloned and inserted in the document by script.

• Contains a DocumentFragment in its HTMLTemplateElement.content property

Page 29: Web Components v1

HTML Imports

<link rel=“import” href=“./my-bugger.html” /> <link rel=“import” href=“./my-zapper.html” />

• Can import all in one file: JavaScript, HTML, and CSS

• Effectively, an HTML document.

• HTML Imports can be the dependency management system, replacing AMD or CommonJS

• HTML Imports let you include and reuse HTML documents in other HTML documents, just as script tags let you include external JavaScript in their pages.

Page 30: Web Components v1

HTML Imports - CONS

The HTML Import spec does not have consensus. Mozilla is still holding out, after two years.

<link rel=“import” href=“./my-bugger.html” /> <link rel=“import” href=“./my-zapper.html” />

• Confusing context when importing templates

• Spec essentially competes with ES modules

• Globals

Page 31: Web Components v1

Can I use…?

Page 32: Web Components v1

Browser Support• Chrome v54

• WebKit Nightly v18

• Edge has begun prototyping

• Firefox has an open bug

Page 33: Web Components v1

Browser Stats

Page 34: Web Components v1

We need to support old IE because we…• want to expose our servers to unsupported, insecure browsers.

• like to pay the extra IE development cost (8:25%, 9:10%, 10:5%).

• enjoy tying up QA to spend extra time testing more browser versions

https://www.xfive.co/blog/stop-supporting-ie10-ie9-ie8/

Seriously, management often encourages the support of old versions because they are not aware of the cost and risk.

Page 35: Web Components v1

Polyfills• A polyfill for HTML Custom Elements.

• ShadyDOM provides a shim for ShadowDOM V1. It is less correct but less intrusive and faster than the ShadowDOM Polyfill.

• ShadyCSS provides a shim for CSS Custom Properties, CSS Mixins with @apply support, and ShadowDOM V1 style encapsulation with the ShadyDOM library.

Page 36: Web Components v1

v0 vs v1*

*The differences between the old spec and the recent changes

Page 37: Web Components v1

v0var proto = Object.create(HTMLElement.prototype);proto.createdCallback = function() { // invoked on creation}; proto.attachedCallback = function() { // invoked when added to the document}; proto.detachedCallback = function() { // invoked when removed from the document}; proto.attributeChangedCallback = function(attrName, oldVal, newVal) { // invoked when an attribute is changed}; var MyComponent = document.registerElement('my-component', { prototype: proto});

Page 38: Web Components v1

class MyComponent extends HTMLElement { static get observedAttributes() { return ['value', 'disabled']; } constructor ( ) { super(); } connectedCallback ( ) { } disconnectedCallback ( ) { } attributeChangedCallback(attrName, oldVal, newVal) { } adoptedCallback() { }} customElements.define('my-component', MyComponent);

v1 constructor: the element is created or upgraded

connectedCallback: the element is inserted into the DOM

disconnectedCallback: the element is removed from the DOM.

attributeChangedCallback: an attribute was added, removed, or updated

adoptedCallback the element has been moved into a new document

define: exposes the element name for use in markup

Page 39: Web Components v1

HistoryQ: Why did the spec change?

A: The old spec did not work with ES6 classes

Q: Does the new spec work wth ES5?

A: uh, sort of…

Q: Who changed it?

A: Blame Apple's Ryosuke Niwa. He’s made a few changes…

Q: Should I wait to use Web Components until v1 is implemented?

A: No, not any more than you would wait for any other shim-able browser feature

Page 40: Web Components v1

Inheritance

class MyButton extends HTMLButtonElement { constructor () { super(...arguments); }} customElements.define('my-button', MyButton, {extends: 'button'});

Extends something other than HTMLElement

Extra argument when defining

Blocked by Apple.

Use native tag, and extended tag in “is”

This is what it would look like… if it were implemented.

Page 41: Web Components v1

ES6 Classes

class MyComponent extends HTMLElement { static something () { return 'something'; } constructor () { super(); } connectedCallback () { // } }

always call super() first in the constructor. “this” is not established until after

Commas are forbidden to emphasize that class definitions are different from object literals.

Classes are sugar for prototypal inheritance. MyComponent is a function that inherits from the HTMLElement prototype.

static is similar to: MyComponent.something = function () {

return ’something’;}

data properties are not allowed like in objects: {a: true} (yet) getters and setters must be used.

super is used as a function in the constructor, as property references: super.someMethod();

Page 42: Web Components v1

Custom Element API Considerations• Sync important properties with attributes

• getters/setters over methods

• Broadcast changes via events

• Use standard properties and event names (“value”, “change”)

• innerHTML — what happens, before and after initialization?

• Appending children

• Use :defined or alternative

• Consider Shadow DOM styling pros and cons

Page 43: Web Components v1

DEMOS

Page 44: Web Components v1

Refshttps://github.com/webcomponents/shadydom

https://github.com/webcomponents/shadycss

https://webkit.org/blog/7027/introducing-custom-elements/

https://github.com/webcomponents/react-integration

https://github.com/clubajax/react-inject-change-events

https://hacks.mozilla.org/2014/12/mozilla-and-web-components/

https://www.polymer-project.org/1.0/blog/2016-12-21-polymer-2.0-update

https://developers.google.com/web/fundamentals/getting-started/primers/customelements?hl=en#historysupport

https://twitter.com/AaronGustafson/status/717028669948977153

https://github.com/w3c/webcomponents/issues/509

Page 45: Web Components v1

CLUB AJAX