Chrome Canary には document.webkitRegister があった

昨日はFirefox Nightlyにdocument.registerが実装されたって話を書いたが、もしやChrome Canaryにもあるんじゃ?と思って見てみたら、あった。

ただし、webkitプレフィックス付き。

function mixin (aTarget, aSource) {
  Object.getOwnPropertyNames(aSource).forEach(function(key){
    Object.defineProperty(aTarget, key, Object.getOwnPropertyDescriptor(aSource, key));
  });
  return aTarget;
}
/**
 * @function
 * @param {String} aTagName
 * @param {Object} aPrototype
 * @param {Object} [aLifeCycle]
 * @param {Function} [aLifeCycle.attributeChanged]
 * @param {Function} [aLifeCycle.inserted]
 * @param {Function} [aLifeCycle.removed]
 *
 * @return {Function} a constructor of the custom elmeent
 */
var createCustomElement = (function() {
  var register = "register";
  if (typeof document.register !== "function") {
    if (typeof document.webkitRegister === "function") {
      register = "webkitRegister";
    } else {
      console.error("document.register is not implemented");
      return function() {};
    }
  }
  return function createCustomElement (aTagName, aPrototype, aLifecyle) {
    var option = { prototype: mixin(Object.create(HTMLElement.prototype), aPrototype) };
    if (aLifeCycle) {
      option.lifecycle = aLifeCycle;
    }
    console.info("createCustomElement", aTagName);
    return document[register](aTagName, option);
  };
}());

Firefox, Chrome の両対応を狙うならこんな感じでしょうか。

var XHello = createCustomElement("x-hello", {
  hello: function () {
    console.log("Hello Custom Element");
  },
}, {
  created: function () {
    console.log(this.localName, "created");
  }
});

document.body.appendChild(new XHello);
// or
document.body.appendChild(document.createElement("x-hello"));

Firefox と違い、Chrome では x-が必須ではなく、-があれば良さそう。test-helloなどの要素名でも通る。
あと、lifecycleのcreatedなどはまだ実装されていないのか、呼び出されないみたい。