Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Polymer vs Extract Widget patent - Code comparison

View gist:64dfd60ddae05aeaff4e
Sending Request…

See also "Extract Widget" Patent FR2962237B1 - Process to create an application of gadget type incorporated into a container of widget type and Patent FR2962237B1 - Main claim, scope and applications and Components model comparison with the patent

Introduction

innerHTML and outerHTML

The CSS !important property

The BASE tag and absolute/relative URLs

cssText

Note

Encapsulation/Confinement

Conclusion

Annex - Some definitions to understand the EW code

Introduction

This is a continutation of:

"Extract Widget" Patent FR2962237B1 - Process to create an application of gadget type incorporated into a container of widget type and Patent FR2962237B1 - Main claim, scope and applications

This gist compares the code used by the Polymer project with the code used by the Extract Widget projects based on the patent FR2962237B1, mainly the Extract Widget framework: node-ewa for the server side which as mentioned in node-gadgets and node-bot is not public, and the browser side used for example in extractwidget demo or BlimpMe! project, we call them the EW framework in what follows.

The code is from before 2012 when we were forced to stop the projects and has not been modified since that time, we have copied it as it is, so it can look a bit strange, strange indentation, strange variable names, etc, this is mainly because at a certain point of time the clear and minified versions of the core framework got a little mixed, the core framework was used for all the projects but with some small variations sometimes as explained at the end of this gist (problematic of one gadget vs several gadgets in the page).

Knowing what we were looking for, we just looked for it inside the Polymer code and found some obvious similitudes, in some cases one could argue that the comparison is a bit trivial or out of the context or that we are comparing things that everybody is using/doing, but no, not everybody is hacking the DOM like this and the similitudes are there.

For now we did not perform a really deep analysis, so maybe some things are not totally correct below, but it's already precise enough and shows that for both frameworks the ways of manipulating the DOM are very similar.

innerHTML and outerHTML

EW is fixing some misimplementation for some browsers:

if (typeof($b.outerHTML)=="undefined")
{
  HTMLElement.prototype.__defineGetter__("outerHTML", function() {
  var span = document.createElement("span"); span.appendChild(this.cloneNode(true));
  return span.innerHTML;
  });
};

Polymer does the same, see bower_components/webcomponentsjs/src/ShadowDOM/wrappers/HTMLElement.js:

function getOuterHTML(node, parentNode) {
    switch (node.nodeType) {
      case Node.ELEMENT_NODE:
        var tagName = node.tagName.toLowerCase();
        var s = '<' + tagName;
        var attrs = node.attributes;
        for (var i = 0, attr; attr = attrs[i]; i++) {
          s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
        }
        if (voidElements[tagName]) {
          if (needsSelfClosingSlash(node))
            s += '/';
          return s + '>';
        }
        return s + '>' + getInnerHTML(node) + '</' + tagName + '>';
      case Node.TEXT_NODE:
        var data = node.data;
        if (parentNode && plaintextParents[parentNode.localName])
          return data;
        return escapeData(data);
      case Node.COMMENT_NODE:
        return '<!--' + node.data + '-->';
      default:
        console.error(node);
        throw new Error('not implemented');
    }
  }
  function getInnerHTML(node) {
    if (node instanceof wrappers.HTMLTemplateElement)
      node = node.content;
    var s = '';
    for (var child = node.firstChild; child; child = child.nextSibling) {
      s += getOuterHTML(child, node);
    }
    return s;
  }
  ...
  HTMLElement.prototype = Object.create(Element.prototype);
  mixin(HTMLElement.prototype, {
    get innerHTML() {
      return getInnerHTML(this);
    },
    set innerHTML(value) {
  ...

But EW can extend the case to more specific ones too:

BlimpClass.prototype.getObjectHTML=function(obj) {
try {
var tmp=this.$I(obj.cloneNode(true));
var tmphtml=this.getOuter(tmp);
} catch(ee) {
var tmphtml=this.getOuter(obj);
}
return tmphtml;
};


BlimpClass.prototype.getOuter=function(obj) {
try {
if (((parseInt(obj.$c.length)==0)||(obj.outerHTML.indexOf('<PARAM')==-1))&&(brow))
{
var tmphtml=obj.outerHTML.split('</OBJECT>')[0];
for (var i=0;i<obj.$c.length;i++)
{
if (obj.$c[i].nodeName!='OBJECT')
{
tmphtml +=obj.$c[i].outerHTML;
} else {
tmphtml +=this.getOuter(obj.$c[i]);
}
};
tmphtml +='</OBJECT>';
} else {
var tmphtml=obj.outerHTML;
};
return tmphtml;
} catch(ee){}
};

or

document.write=function(v) {try {var tmp=that.$$('DIV');tmp.innerHTML=v;$b.$a(tmp);} catch(ee) {}};

and like Polymer do sometimes quite strange things:

BlimpClass.prototype.setTranspa=function(obj,tmphtml) {
var reg=new RegExp("window", "g");
tmphtml=tmphtml.replace(reg,"transparent");
if (obj.nodeName=='OBJECT')
{
tmphtml=this.AddParamFast(this.html_decode(tmphtml,'ENT_NOQUOTES',0),'wmode','transparent');
} else if (obj.nodeName=='EMBED') {
tmphtml=tmphtml.split('>')[0]+' wmode="transparent"></EMBED>';
};
return tmphtml;
};
BlimpClass.prototype.setIniouter=function(obj,tmphtml) {
tmphtml=this.setTranspa(obj,tmphtml);
var xht=this.html_decode(tmphtml,'ENT_NOQUOTES',1);
var xht2=this.html_decode(tmphtml,'ENT_NOQUOTES',0);
obj.iniouterHTML=function() {return xht;};
obj.iniouterHTML2=function() {return xht2;};
};
BlimpClass.prototype.html_decode=function(str,par,savehtml)
{
var xdiv=this.$$('DIV');
$b.$a(xdiv);
xdiv.innerHTML = '<textarea id="innerConverter">' + str + '</textarea>';
var content = this.$_$("innerConverter").value;
$b.$r(xdiv);
if (savehtml==1)
{
var reg=new RegExp("%", "g");
content=content.replace(reg,"xxmtcxx");
};
return content;
};

EW is injecting the code via innerHTML and other manipulations:

EWM.prototype.setInner=function(obj) {
    //var d0=new Date().valueOf();
    try {var bbase=obj.w_w[5];} catch(ee) {var bbase=baseurl;};
    var tmp2=$$('DIV');
    tmp2.$s.width=obj.w_w[1]+'px';
    tmp2.$s.height=obj.w_w[2]+'px';
    tmp2.innerHTML=obj.w_w[gadgetObjectRank+1];
    if (obj.w_w[4]!='') {tmp2.$s.overflow='hidden';};
    tmp2.$s.background='white';
    obj.$a(tmp2);
    //var d=new Date().valueOf();
    //alert(d-d0);
    if (this.activPage)
    {
    var tmp4=function() {if (getStyle($b,brow?'backgroundImage':'background-Image').indexOf('transpa.png')==-1) {$b.style.backgroundImage='url(http://www.blimpme.com/mobile/bbrowser/transpa.png)';$b.style.backgroundColor='#09164D';} else {clearInterval(__bg0);}};
    __bg0=setInterval(tmp4,1000);
    };
    if ((parseInt(ff)==1)&&(bbase!=''))
    {
    y_r(tmp2,bbase);
    };
    if (bbase!='')
    {
    y_rb(tmp2,bbase);
    };
};

While the innerHTML method is not supposed to be used any longer, apparently Polymer uses it, see bower_components/polymer/polymer.js:

injectBoundHTML: function(html, element) {
      var template = document.createElement('template');
      template.innerHTML = html;
      var fragment = this.instanceTemplate(template);
      if (element) {
        element.textContent = '';
        element.appendChild(fragment);
      }
      return fragment;
    }

function createDOM(inTagOrNode, inHTML, inAttrs) {
    var dom = typeof inTagOrNode == 'string' ?
        document.createElement(inTagOrNode) : inTagOrNode.cloneNode(true);
    dom.innerHTML = inHTML;
    if (inAttrs) {
      for (var n in inAttrs) {
        dom.setAttribute(n, inAttrs[n]);
      }
    }
    return dom;
}

The CSS !important property

The CSS "!important" property is a kind of hack usually used when the devs get lost with their CSS or have badly designed their site in order to set a style property that cannot be overriden by other style definitions.

So, this is supposed to be rarely used. The EW framework was using it on purpose in order to perform a Shadow DOM-like styles isolation, example:

EWA.prototype.setStyleParent=function(obj,bool) {
    try {
        var tmpn=this.getStyle(obj,'background-color');
    } catch(ee) {var tmpn='';};
    if (bool) {
        var tmpc=this.twidth!='0px'?';width: 100% ! important':'';
        var tmpd=this.theight!='0px'?';height: 100% !important':'';
        obj.$s.cssText=tmpn=='transparent'?'border:0 !important;margin:0 !important;padding:0 !important;min-width:0px !important;min-height:0px !important;position:relative !important;left:0px !important;top:0px !important;background-image:url(http://www.blimpme.com/mobile/bbrowser/transpa.png) !important;background-color:white !important'+tmpc+tmpd:
        'border:0 !important;margin:0 !important;padding:0 !important;min-width:0px !important;min-height:0px !important;position:relative !important;left:0px !important;top:0px !important;background-image:url(http://www.blimpme.com/mobile/bbrowser/transpa.png) !important'+tmpc+tmpd;
    } else {
        obj.$s.cssText=tmpn=='transparent'?'margin:0 !important;padding:0 !important;min-width:0px !important;min-height:0px !important;position:relative !important;left:0px !important;top:0px !important;background-color:white !important'+';width: '+this.twidth+' ! important;height: '+this.theight+' ! important':
        'margin:0 !important;padding:0 !important;min-width:0px !important;min-height:0px !important;position:relative !important;left:0px !important;top:0px !important'+';width: '+this.twidth+' ! important;height: '+this.theight+' ! important';
    };
};

An example of resulting custom element can be seen here

The Polymer project web site built with Web Components is full of "!important" properties, as it can be seen on the "Welcome to the past future" home page (OK, we cannot resist to do this joke, Web Components are still the future but the future could have happened before...) and we don't think that the Polymer team got lost with its CSS neither badly designed the site, most likely they are using it to isolate the properties of the different custom elements in the page, like for the EW, and this is oustanding to see that this property is still used to perform this.

The "!important" property appears several time in Polymer code and examples:

bower_components/polymer/layout.html:  display: none !important;
bower_components/polymer/test/unit/css-parse.html:        margin-left: 0 !important;
bower_components/polymer/test/unit/css-parse.html:      assert.equal(tree.rules[3].rules[0].cssText, 'margin-left: 0 !important;', 'unexpected cssText in @media');
bower_components/polymer/polymer.js:style.textContent = 'template {display: none !important;} /* injected by platform.js */';
bower_components/webcomponentsjs/src/ShadowCSS/ShadowCSS.js:  addCssToDocument('style { display: none !important; }\n');
bower_components/webcomponentsjs/tests/ShadowCSS/html/compressed.html:      h1,h2,h3,h4,h5{font-weight:300;letter-spacing:-0.01em;line-height:48px;margin:0}h1{font-size:40px}polyfill-next-selector{content:':host h1'}::content h1{font-size:40px}h2{font-size:24px}polyfill-next-selector{content:':host h2'}::content h2{font-size:24px}h3{font-size:20px}polyfill-next-selector{content:':host h3'}::content h3{font-size:20px}h4{font-size:16px;font-weight:500}polyfill-next-selector{content:':host h4'}::content h4{font-size:16px;font-weight:500}h5{font-size:12px;font-weight:500}polyfill-next-selector{content:':host h5'}::content h5{font-size:12px;font-weight:500}.platform{color:#9f499b}.elements-using{color:#3e50b4}.elements-creating{color:#e81d62}.main-bg{background-color:#eee !important}.main-purple{background-color:#1f2036}.main-purple paper-button{background:#262742 !important;color:white;fill:currentcolor}.main-purple paper-button:hover{background:#3a3b56 !important}code,pre{color:#9f499b;font-family:"Source Code Pro",Monaco,Menlo,Consolas,"Courier New",monospace}pre,.prettyprint{background-color:#fafafa;padding:16px;margin:30px 0}pre .typ,pre .inline,.prettyprint .typ,.prettyprint .inline{color:#6b499f}pre .pun,.prettyprint .pun{color:#5c6bc0}pre .str,pre .string,.prettyprint .str,.prettyprint .string{color:#ff4081}pre .pln,.prettyprint .pln{color:#7986cb}pre .kwd,.prettyprint .kwd{color:#d61a7f}pre .atn,pre .attribute-name,.prettyprint .atn,.prettyprint .attribute-name{color:#6b499f}pre .atv,pre .attribute-value,.prettyprint .atv,.prettyprint .attribute-value{color:#7986cb}pre .com,pre .comment,.prettyprint .com,.prettyprint .comment{color:#8a8a8a}:host{display:block}:host([sidebar]){padding-left:265px}polyfill-next-selector{content:':host[sidebar]:not(.mobile) site-banner app-bar.fixed'}:host([sidebar]:not(.mobile)) ::content site-banner app-bar.fixed{margin-left:265px}polyfill-next-selector{content:':host.scrolling:not(.mobile) site-banner'}:host(.scrolling:not(.mobile)) ::content site-banner{height:80px !important;padding-bottom:0;position:fixed !important;width:100%;box-shadow:0 1px 5px rgba(0,0,0,0.3)}polyfill-next-selector{content:':host.scrolling:not(.mobile) > article'}:host(.scrolling:not(.mobile)) ::content article{padding-top:310px}polyfill-next-selector{content:':host site-banner app-bar.fixed'}:host ::content site-banner app-bar.fixed{position:fixed}polyfill-next-selector{content:':host > article'}:host ::content article{padding:24px 64px;max-width:912px;min-height:300px;overflow:hidden}@media only screen and (max-width: 850px){:host([sidebar]){padding-left:0 !important}polyfill-next-selector{content:':host > article'}:host ::content article{padding-left:15px;padding-right:15px}}@media only screen and (max-width: 580px){polyfill-next-selector{content:':host > article '}::content article{padding-top:70px}}

The BASE tag and absolute/relative URLs

EW was using the BASE tag for some gadgets so all the baseURIs properties of all elements were associated to the right origin:

var tmp=this.$T('base');
if (tmp.length==0) {
    var baseurl = document.location.href;
    var lslash = baseurl.lastIndexOf("/");
    baseurl = baseurl.substr(0,lslash+1);
} else {
    var xb=tmp[0];
    var baseurl=xb.href;
};
this.baseurl=baseurl;

EWM.prototype.loadGadget=function(w_w,boo,callback) {
    var that=this;
    try {
    var boi=w_w[0];
    } catch(ee) {var boi='<img src="http://www.blimpme.com/img/badgadget.png" style="width:100%;height:100%"/>';};
    try {var bbase=w_w[5];} catch(ee) {var bbase=baseurl;};
    if (bbase!='')
    {
    var xbase=$$('BASE');
    xbase.href=bbase;
    zhead.insertBefore(xbase,zhead.firstChild);
};

or was transforming all relative URLs of a gadget into absolute URLs:

var xb=this.$$('BASE');
xb.href=this.b_b;
var xhead=this.$I(this.$T('head')[0]);
xhead.insertBefore(xb,xhead.firstChild);

or

var y_r2 = function(y_y,y_z){
    y_y = decodeURIComponent(y_y);
    var y_d = new RegExp(/^(http:\/\/)?([^\/]+)/i);
    var z_b = new RegExp("url\\((.[^)]*?)\\)","gi");
    var z_c = new RegExp("([^:])/+","gi");
    var z_d = new RegExp("http://.[^/]*?/","gi");
    var z_g = new RegExp(/(background|action)\s*=\s*(["'])(.*?)\1/gi);
    var z_h = new RegExp(/<style[^>]*?>(.*?)<\/style>/gi);
    var z_i = new RegExp(/(["'])(.*?)\1/gi);
    var z_j = new RegExp(/<link[^>]*?>/gi);
    var dm = y_d.exec(y_y)[0];
    var z_e = z_d.exec(y_y);
    if(z_e==null){ z_e = y_y;}else{z_e = z_e[0];};
    if(z_e.lastIndexOf('/')!=(z_e.length-1)) z_e = z_e+'/';
    var r=null;
    while((r=z_b.exec(y_z))!=null){
    var z_f = r[1].replace(/^["']/,"");
    z_f = z_f.replace(/["']$/,"");
    z_f = z_f.replace(/^(&quot;)/,"");
    z_f = z_f.replace(/(&quot;)$/,"");
    z_f = z_f.replace(/^\s+/g,"").replace(/\s+$/g,'');
    if (z_f.substr(0,7)!='http://') z_f = z_e+z_f;
    z_f = z_f.replace(z_c,"$1/");
    z_f = z_f.replace(/^\s+/,"");
    z_f = z_f.replace(/\s+$/,"");
    y_z = y_z.replace(r[0],"url('"+z_f+"')");
    };
    r=null;
    var tab=new Array();
    while ((r = z_g.exec(y_z))!=null){
    var x_h= r[3].substr(0,7).toLowerCase();
    if (x_h!='http://'){
    var nr = y_y+r[3];
    tab.push(new Array(r[3],nr));
    };
    };
    for ( var i=0 ; i<tab.length ; i++){
    y_z = y_z.replace(tab[i][0],tab[i][1]);
    };
    while ((r=z_h.exec(y_z))!=null){
    var s = r[1];
    if(s.indexOf("@import")!=-1){
    var r2=null;
    while ((r2 = z_i.exec(s))!=null){
    if (r2[2].substr(0,7).toLowerCase()!='http://'){
    y_z=y_z.replace(r2[2],y_y+r2[2]);
    };
    };
    };
    };
    while ((r=z_j.exec(y_z))!=null){
    var l = r[0];
    var z_k = new RegExp(/href\s*=\s*(["'])(.*?)\1/gi);
    var r2 = z_k.exec(l);
    if (r2!=null){
    if (r2[2].substr(0,1)=='/'){
    var s=l.replace(r2[2],dm+r2[2]);
    y_z = y_z.replace(l,s);
    } else if (r2[2].substr(0,7).toLowerCase()!='http://'){
    var s=l.replace(r2[2],y_y+r2[2]);
    y_z = y_z.replace(l,s);
    };
    };
    };
    return y_z;
};

or 

BlimpClass.prototype.setAbsoluteLinks = function(obj) {
obj=this.$I(obj);
try {
var baseurl = document.location.href;
var lslash = baseurl.lastIndexOf("/");
baseurl = baseurl.substr(0,lslash+1);
try {
try {
if (this.site=='') {
var tmp=obj.getElementsByTagName('SCRIPT');
for (var i=0;i<tmp.length;i++)
{
tmp[i].parentNode.removeChild(tmp[i]);
}
};
} catch(ee) {};
if ((obj.outerHTML.toLowerCase().indexOf('<object')!=-1)||(obj.outerHTML.toLowerCase().indexOf('<embed')!=-1))
{
if (brow) {
var tmp=this.$$('DIV');
tmp.$a(obj);
this.setiniOBJ(tmp);
var tmpobj=tmp.firstChild.outerHTML;
} else {
this.cleanPage(obj,false);
var tmpobj=obj.outerHTML;
}
} else {
var tmpobj=obj.outerHTML;
};
var regstyle = new RegExp(/style\s*=\s*(["'])(.*?)\1/gi);
var regsrc = new RegExp(/src\s*=\s*(["'])(.*?)\1/gi);
var matches = tmpobj.match(regstyle);
if (matches){
for (var i=0 ; i< matches.length ; i++){
var curstyle = matches[i];
var newstyle = curstyle;
if (curstyle.indexOf('src',0)!=-1){
var msrc = curstyle.match(regsrc);
if (msrc){
for (var j=0 ; j<msrc.length ; j++){
var cursrc = msrc[j];
var regsrc2 = new RegExp(/(["'])(.*?)\1/gi);
var regquote = new RegExp(/^["']|["']$/gi);
var value = cursrc.match(regsrc2)[0].replace(regquote,'');
if (value.substr(0,7).toLowerCase()!='http://'){
var newvalue = baseurl+value;
var newsrc = cursrc.replace(value,newvalue);
newstyle = newstyle.replace(cursrc,newsrc);
}
}
}
tmpobj = tmpobj.replace(curstyle,newstyle);
}
}
};
obj.myHTML=tmpobj;
} catch(ee){};
} catch(ee){};
};

Note that the example is handling the specific cases of CSS @import and background(url) that will be mentioned below.

Polymer is resolving the URLs the same way as shown in bower_components/polymer/src/lib/resolve-url.html:

  (function() {
    // path fixup for urls in cssText that's expected to 
    // come from a given ownerDocument
    function resolveCss(cssText, ownerDocument) {
      return cssText.replace(CSS_URL_RX, function(m, pre, url, post) {
        return pre + '\'' + 
          resolve(url.replace(/["']/g, ''), ownerDocument) + 
          '\'' + post;
      });
    }
    // url fixup for urls in an element's attributes made relative to 
    // ownerDoc's base url
    function resolveAttrs(element, ownerDocument) {
      for (var name in URL_ATTRS) {
        var a$ = URL_ATTRS[name];
        for (var i=0, l=a$.length, a, at, v; (i<l) && (a=a$[i]); i++) {
          if (name === '*' || element.localName === name) {
            at = element.attributes[a];
            v = at && at.value;
            if (v && (v.search(BINDING_RX) < 0)) {
              at.value = (a === 'style') ?
                resolveCss(v, ownerDocument) :
                resolve(v, ownerDocument);
            }
          }
        }
      }
    }
    function resolve(url, ownerDocument) {
      var resolver = getUrlResolver(ownerDocument);
      resolver.href = url;
      return resolver.href || url;
    }
    var tempDoc;
    var tempDocBase;
    function resolveUrl(url, baseUri) {
      if (!tempDoc) {
        tempDoc = document.implementation.createHTMLDocument('temp');
        tempDocBase = tempDoc.createElement('base');
        tempDoc.head.appendChild(tempDocBase);
      }
      tempDocBase.href = baseUri;
      return resolve(url, tempDoc);
    }
    function getUrlResolver(ownerDocument) {
      return ownerDocument.__urlResolver || 
        (ownerDocument.__urlResolver = ownerDocument.createElement('a'));
    }
    var CSS_URL_RX = /(url\()([^)]*)(\))/g;
    var URL_ATTRS = {
      '*': ['href', 'src', 'style', 'url'],
      form: ['action']
    };
    var BINDING_RX = /\{\{|\[\[/;
    // exports
    Polymer.ResolveUrl = {
      resolveCss: resolveCss,
      resolveAttrs: resolveAttrs,
      resolveUrl: resolveUrl
    };
  })();

and in bower_components/webcomponentsjs/src/HTMLImports/path.js (the case of @import):

HTMLImports.addModule(function(scope) {

var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;

// path fixup: style elements in imports must be made relative to the main
// document. We fixup url's in url() and @import.
var path = {

  resolveUrlsInStyle: function(style, linkUrl) {
    var doc = style.ownerDocument;
    var resolver = doc.createElement('a');
    style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);
    return style;
  },

  resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {
    var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);
    r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);
    return r;
  },

  replaceUrls: function(text, urlObj, linkUrl, regexp) {
    return text.replace(regexp, function(m, pre, url, post) {
      var urlPath = url.replace(/["']/g, '');
      if (linkUrl) {
        urlPath = (new URL(urlPath, linkUrl)).href;
      }
      urlObj.href = urlPath;
      urlPath = urlObj.href;
      return pre + '\'' + urlPath + '\'' + post;
    });
  }

};

or solving the background(url) issue:

  if (hasTemplateElement) {
    // TODO(rafaelw): Remove when fix for
    // https://codereview.chromium.org/164803002/
    // makes it to Chrome release.
    (function() {
      var t = document.createElement('template');
      var d = t.content.ownerDocument;
      var html = d.appendChild(d.createElement('html'));
      var head = html.appendChild(d.createElement('head'));
      var base = d.createElement('base');
      base.href = document.baseURI;
      head.appendChild(base);
    })();
  }

which is similar to some hacks used by the EW to correct for example the FF behavior where the BASE tag had to be attached to the gadget itself in addition to the HEAD:

BlimpClass.prototype.reconstruct=function(ga) {
var that=this;
if (!L_L)
{
var xb=this.$$('BASE');
xb.href=this.b_b;
var xhead=this.$I(this.$T('head')[0]);
xhead.insertBefore(xb,xhead.firstChild);
if ((parseInt(ff)==1)&&(this.b_b!=''))
{
ga.body='<base href="'+this.b_b+'" />'+this.y_r2(this.b_b,ga.body);

or in bower_components/webcomponentsjs/src/HTMLImports/importer.js to import and instantiate a custom element:

function makeDocument(resource, url) {
  // create a new HTML document
  var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
  // cache the new document's source url
  doc._URL = url;
  // establish a relative path via <base>
  var base = doc.createElement('base');
  base.setAttribute('href', url);
  // add baseURI support to browsers (IE) that lack it.
  if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
    // Use defineProperty since Safari throws an exception when using assignment.
    Object.defineProperty(doc, 'baseURI', {value:url});
  }
  // ensure UTF-8 charset
  var meta = doc.createElement('meta');
  meta.setAttribute('charset', 'utf-8');

  doc.head.appendChild(meta);
  doc.head.appendChild(base);
  // install html
  doc.body.innerHTML = resource;
  // TODO(sorvell): ideally this code is not aware of Template polyfill,
  // but for now the polyfill needs help to bootstrap these templates
  if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
    HTMLTemplateElement.bootstrap(doc);
  }
  return doc;
}

and some strange manipulations in bower_components/webcomponentsjs/src/ShadowCSS/ShadowCSS.js apparently linked to the @import in CSS:

var frame = document.createElement('iframe');
frame.style.display = 'none';

function initFrame() {
  frame.initialized = true;
  document.body.appendChild(frame);
  var doc = frame.contentDocument;
  var base = doc.createElement('base');
  base.href = document.baseURI;
  doc.head.appendChild(base);
}

function inFrame(fn) {
  if (!frame.initialized) {
    initFrame();
  }
  document.body.appendChild(frame);
  fn(frame.contentDocument);
  document.body.removeChild(frame);
}

// TODO(sorvell): use an iframe if the cssText contains an @import to workaround
// https://code.google.com/p/chromium/issues/detail?id=345114
var isChrome = navigator.userAgent.match('Chrome');
function withCssRules(cssText, callback) {
  if (!callback) {
    return;
  }
  var rules;
  if (cssText.match('@import') && isChrome) {
    var style = cssTextToStyle(cssText);
    inFrame(function(doc) {
      doc.head.appendChild(style.impl);
      rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
      callback(rules);
    });
  }

The intent for using the BASE tag in the Extract Widget was to apply it per gadget, but as already explained the BASE tag at that time did apply to the whole page, so was only used to display a gadget per page, and it had to be changed dynamically for each gadget displayed, for several gadgets in a page the links were transformed in absolute and the BASE tag not used in the page.

This was challenging to use the BASE tag at that time since browsers were not handling it the same way and very correctly, for example this was not working on Opera, the tag had to be appended twice for FF, the dynamic change did not work for some browsers, etc

Polymer seems more lucky since apparently it manipulates it now all the (sometimes strange) ways it can.

cssText

Used in the EW to associate Shadow DOM-like style tags to a gadget (ie inherited styles not associated to the objects of the gadget) :

var cs=$$('style');
var r0 = z_i.exec(r[0]);
if (r0!=null) cs.setAttribute('type',r0[2]);
var r0 = z_k.exec(r[0]);
if (r0!=null) cs.setAttribute('media',r0[2]);
if (cs.styleSheet)
{
cs.styleSheet.cssText=r[1];
} else {
cs.appendChild(document.createTextNode(r[1]));
};
r3.push(cs);
};

Used by Polymer to do the same, bower_components/webcomponentsjs/src/ShadowCSS/ShadowCSS.js:

function cssTextToStyle(cssText) {
  var style = document.createElement('style');
  style.textContent = cssText;
  return style;
}

Note

Maybe we did not look correctly but we did not find any live examples of sites mixing different custom elements (ie from different origins or representing different gadgets in the page) using Polymer, except the Polymer project site, all the examples we found had a custom element alone or encapsulated inside an iframe, so maybe the concepts of the patent are still not so trivial to implement when it comes to mix custom elements not interfering between each others but able to interact between each others.

We don't know exactly what define the specs but maybe it would be interesting that the scope of a BASE tag inside a template is limited to the template itself.

Encapsulation/Confinement

The patent describes methods for gadgets that are composed of browsers elements (ie DOM-based elements) that have their own properties but isolated, so the other elements of the page cannot interfer with them (and vice versa) and that can interact with the rest of the page (and vice versa, ie is not a sandboxed gadget), allowing to build and use gadgets in a simple way and to display them on any device supporting a DOM rendering.

The Shadow DOM spec implements similar concepts, now the scope of the objects isolation can vary, that's why we wrote |wrap| suggestion in strict mode whose intention was to propose different levels of isolation like Shadow DOM and different scopes of execution for imports.

Conclusion

Not seeing obvious similitudes between the Polymer and the EW code, therefore between the Web Components and the patent, or arguing that these are standard practices while we see that today it's still difficult to accomplish and that we still need to hack the entire DOM all possible ways to do it, as well as performing very strange and not usual manipulations, could only be the result of very bad faith.

A good summary of a paradox that the patent adresses can be found here "See the irony? The web's most basic content, HTML, requires the greatest amount of effort to work with. Fortunately, Web Components are here to get us back on track"

Annex - Some definitions to understand the EW code

var $=function(id) {
return document.getElementById(id);
};
var $$=function(xelement){
var a=document.createElement(xelement);
a=$I(a);
a.$s=a.style;
return a;
};
var $D=function(x){
try {
return decodeURIComponent(x);
} catch(ee) {return x};
};
var $I=function(a){
try {a.$a=a.appendChild;} catch(ee) {};
try {a.$r=a.removeChild;} catch(ee) {};
try {a.$c=a.childNodes;} catch(ee) {};
return a;
};
var $E=function(x){
return encodeURIComponent(x);
};
var $T = function(tag){
return document.getElementsByTagName(tag);
};
var $b = $I(document.body);
Something went wrong with that request. Please try again.