Sunday, October 29, 2017

WebComponents via AMD - pragmatic view

What I need for apps is ability to use AMD dependencies for my and external web components:
  • use the external libs from their CDN on prod, and local on developer machine
  • own AMD-based JS loading web components via AMD (webpack, dojo, requirejs) dependencies
  • own HTML syntax web components which list dependencies in JS section via AMD
Why AMD API? It is running without any compilers/transpilers in browser and compatible with webpack in case of need the bundling.

Why AMD instead of ES6 imports?

While ES6 imports are giving ability to load module from relative path, that is not enough as libraries could be served from different locations including different domains. AMD provides runtime URL resolving based on configuration making a combination of local component development with CDN dependencies a breathe.

How to load WebComponents via AMD?

require([   "link-import!iron-demo-helpers/demo-pages-shared-styles.html|onload"
        ,   "link-import!iron-demo-helpers/demo-snippet.html"
        ,   "link-import!../test-element.html"
        ], (a,b,c)=> console.log(`${a}, ${b}, ${c} webComponents loaded`) );

Of course the AMD configuration should be set to define URL mappings and common script loaded

  var dojoConfig ={ async: true
                  , packages:
                      [ { name: "webcomponentsjs", location: webcomponent_root }
                      , { name: "polymer", location: polymer_root }
                      ]
                  , aliases:  [ [ "link-import"  , isLocal ? "/components/link-import/link-import.js" : "../../link-import.js" ]
                              , [ /(vaadin-)(.*)/, (m,x,y)=>`${vaadin_root}/${x}${y}`   ]
                              , [ /(iron-)(.*)/  , (m,x,y)=>`${iron_root}/${x}${y}`     ]
                              ]
                  , deps: [ "webcomponentsjs/webcomponents-lite" ] // common for all pages
                  };

Here the Polymer and Vaadin Elements are used as good example of WebComponent frameworks.

Your custom WebComponent could use Polymer 2.x syntax and defined as HTML. Just the script section will have a class declaration wrappd into define() and dependencies are listed as JS strings instead of link imports:

        const NAME = 'test-element'
        define( NAME
            ,   [   "link-import!polymer/polymer-element.html"
                ,   "link-import!iron-ajax/iron-ajax.html"
                ,   "link-import!vaadin-material-theme/vaadin-text-field.html" //,   "link-import!vaadin-valo-theme/vaadin-combo-box.html"
                ,   "link-import!vaadin-combo-box/vaadin-combo-box.html"
                ]
            , ()=>
            {
                class TestElement extends Polymer.Element
                {
                    static get is() { return 'test-element'; }

                    static get properties()
                    {
                        return  {   prop1: {
                                        type: String,
                                        value: 'test-element'
                                    }
                                };
                    }
                }

                window.customElements.define( TestElement.is, TestElement );
            });
        require([NAME]);

Where to find the working sample of loading and making WebComponent via AMD?

cdn.xml4jquery.com/ajax/libs/AmdHarness/link-import/test/demo/index.html

What library I need to use AMD loader in my WebComponent?

link-import on github or NPM

Want to go wild?

Help me with creation of module loader for JS and WebComponents as jQuery plugin. The async API for jQuery is already available via xml4jQuery, WebComponents integration is missing:
$('.my-el')
    .html('loading...')
    .linkImport('vaadin-combo-box/vaadin-combo-box.html') // path resolved by config
    .html('');
$('my-el')
    .html('loading...')
    .asWebComponent('vaadin-combo-box') // path resolved by config, WC loaded, and injected
    .prop('items',['red','green','blue]) // property assigned once WC is ready

//  will be auto-populated  even if the code run way later:
$.defineWebComponent( 'my-component' )
    .$on('load')
    .$then( ()=>$.get('colors.json') )
    .addWebComponent('vaadin-combo-box')
    .$then( (combo, colors)=> combo.items = colors );
Happy coding!

Saturday, September 16, 2017

Moraga fiscal emergency solution

The sfchronicle post inspired me to look on infrastructure cost solutions across the globe and national scope. Seems the cities and larger entities already developed several ways of making sustainable and balanced budgeting models. 

The base principle came from this brief review: the cost should be placed on shoulders the entities which actually utilizing the infrastructure. From the owners of properties to utility companies. 

For utilities the shared infrastructure rental from municipal entity, for landscape owners - the amount of water and traffic they create, ...

There is a way to have the rental super-attractive by making it significantly cheaper than servicing by themselves. The way to achieve that: use the shared infrastructure for different services. The drain system with embedded fiberoptics(cable TV, internet, phone), power, sewage and water. The highly modularized, oriented on hot-swap non-destructive replacement  grid will cost a fraction of single service. And having many services will cut the cost on level of magnitude.

Monday, July 24, 2017

SVG use notes

Notes for myself.
Dimensions Embedded SVG within HTML page have several ways to define those:

  1. CSS via style="width:18px;height:18px" or class name like class="icon"
  2. attributes via width="18px" height="18px"
  3. viewport and viewBox attributes
While all of above could define the image sizes, there is a need for discipline in orchestrating all. The best way is to rely on CSS for sizing within HTML. Hence to use only #1. 
The reason is that in HTML CSS has higher priority than width/height attributes and if SVG tag has any default style, it would override those width/height inline attributes.

For cross-browser compatibility you still need the viewBox="0 0 1000 1000" attribute to define dimensions in SVG coordinates, usually it matches the image size. Only exception is a tile - when multiple images collected in SVG and you want to display only one a time. That is an advanced technique handy for collections like color icons. 
More on W3C site.

Sunday, June 4, 2017

XmlView moved to CDN

XmlView bookmarklet and XSLT makes the table presentation of JSON and XML in browser.

Now the XmlView would work for any web site which does escalate the security setting to use only own domain resources. So far it is almost any web site on interned.

What is new:
  1. Bookmarklet uses https on CDN which permits to see the transformantion without altering CORS browser settings
  2. Flickr and LinkedIn web services given for reference of JSON RESTful APIs
This release 1.0.0 is now located on https://cdn.xml4jquery.com/ajax/libs/XmlView/1.0.0/
Happy coding

Friday, May 26, 2017

xml4jQuery 1.1.0 released

Proud of it. Finally passed a full set of tests on all features I had in mind:

  • event handling 
  • call chain results propagated into callbacks 
  • Promise support for single run and $then() for recurrent call chain invocation 
  • error handling matching the Promise behavior 

$(".toFill")    .html("Click here")
                .$on('click')
                .html('Loading...')
                .sleep(1000)
                .xmlTransform( 'test/test.xml', 'test/test.xsl')
                .toggleClass('clickable')
                .prepend('Still clickable <hr/>');
 Also not so visible:

  • moved tests to ES6, they shortened at least twice 
  • made release build script to match CDN and NPM deployments, before it was a manual process 
  • started to use ApiFusion.com for project documentation 
For next release:

  • IE tests compatibility via AMD loader shim to load ES6 in IE on fly
  • $then() to accept other async chain 
Somewhere in future
  • refactor sources to ES6, target compiler to ES6, 
  • auto-transpiler shim for IE reference implementation

  xml4jQuery.com

Thursday, May 18, 2017

JS in browser tricks

Convert arguments, NodeList, attributes to normal JS array

Little notes for myself
Array.prototype.slice.call(arguments).forEach( el=>console.log(el) ) // arguments to normal JS array
Object.keys({a:0}) // keys to array


[... this.attributes].filter( el=>!el.name.indexOf('data-') ).forEach( el=> console.log(el.name, el.value) ) // DomElement attributes (NamedNodeMap) to array es6
Array.from(this.attributes).filter( el=>!el.name.indexOf('data-') ) // -||- es5 + shim
Array.prototype.forEach.call(document.querySelectorAll( 'input[type=checkbox]' ), item => item.checked = true ); // es5

// ES6 

let divsArray = [...document.querySelectorAll('div')]; // Convert NodeList to Array

let argsArray = [...arguments]; // Convert Arguments to Array
For IE and legacy use polyfills from core-js or babel-polyfill

Sunday, October 16, 2016

Deployed first site to Amazon Elastic Beanstalk

It is a single environment to manage DB, site, firewall, load balancer,... cool stuff. But also quite useful. Need to organize the process though, but it is justifiable. Now could replicate environment without many manual steps. I hope the site will grow to the level of need for auto-scale feature in Beanstalk.

In competitive stacks with automatic scaling given by Heroku or Google Apps Engine there is a huge gap in supported frameworks. The decent CMS is almost impossible to configure and support by night-time project owner there. Unlike others Amazon made a classic LAMP available out of the box. Well, almost: for complete Drupal app I still need to:

  1. add DB in RDS, open access to my IP in security group, create schema 
  2. install app, create key pair for ssh access, open ssh access to my IP in site security group, 
  3. adjust .htaccess zip and download application folder. This archive content is now a primary deployment unit. For convenience it will be placed in git repo. 
My wish to Amazon folks: with covering the steps above you will completely reach the declared goal of creating the ready-to-use complex site like CMS with a push of a button. Just make a GIT repo for each app type and have the process started with a git fork and finished with running app. 

Another wish: make a DNS server( or configure /etc/hosts in each instance) a part of BeanStalk so entries like "dbhost" could be used inside of instances and configured as part of sub-cloud without ever need to know what is ec2-123-45-678-8.us-west-2.compute.amazonaws.com means.