t2ym / i18n-element

I18N Base Element for Lit and Polymer
Other
9 stars 1 forks source link

[Polymer 3.0-preview] Preliminary research on Polymer 3.0 support (ES Modules instead of HTML Imports) #58

Closed t2ym closed 5 years ago

t2ym commented 6 years ago

[Polymer 3.0-preview] Preliminary research on Polymer 3.0 support (ES Modules instead of HTML Imports)

Proof of Concept Demo Page on GitHub Pages with Polymer 3.0-preview and many inelegant patches and temporary hacking

link to GitHub pages

Notes

Main hacking

Main Issues and Tasks (There are many other issues)

t2ym commented 6 years ago

Temporary hacking in converted legacy components (automated below and in this change)

Polymer({
  importPath: import.meta.url,
  __template: html`
    <span id="label1">Legacy UI label 1</span><br>
    <span id="label2">Legacy UI label 2</span><br>
    <span id="label3">Legacy UI label 3</span>
`,

  get _template() {
    if (this instanceof HTMLElement && !this.constructor._templateLocalizable) {
      this.constructor._templateLocalizable = BehaviorsStore._I18nBehavior._constructDefaultBundle(this.__template, this.is);
    }
    return this.__template;
  },

  set _template(t) {
    //this.__template = t;
  },

  is: 'i18n-legacy-element',

  behaviors: [
    BehaviorsStore.I18nBehavior
  ]
});

Automated _template conversion via i18n-behavior/i18n-behavior.js

  if (ElementMixin) {
    // Polymer 2.x
    BehaviorsStore._I18nBehavior = BehaviorsStore.I18nBehavior;
    BehaviorsStore.I18nBehavior = [ BehaviorsStore._I18nBehavior ];
    if (!document.currentScript) {
      // Polymer 3.x
      BehaviorsStore.I18nBehavior.push({
        get _template() { 
          if (this.__template) {
            return this.__template;
          }
          if (this instanceof HTMLElement &&
            this.constructor.name === 'PolymerGenerated' &&
            !this.constructor.__finalizeClass) {
            this.constructor.__finalizeClass = this.constructor._finalizeClass;
            this.constructor._finalizeClass = function _finalizeClass() {
              let info = this.generatedFrom;
              if (!this._templateLocalizable) {
                if (info._template) {
                  this._templateLocalizable = BehaviorsStore._I18nBehavior._constructDefaultBundle(info._template, info.is);
                }
                else {
                  let template = DomModule.import(info.is, 'template');
                  if (template) {
                    this._templateLocalizable = BehaviorsStore._I18nBehavior._constructDefaultBundle(template, info.is);
                  }
                }
              }
              if (!this.hasOwnProperty('importPath')) {
                Object.defineProperty(this, 'importPath', { value: info.importPath });
              }
              return this.__finalizeClass();
            }
          }
          return null;
        },
        set _template(value) {
          this.__template = value;
        }
      });
    }
t2ym commented 6 years ago

Browser Status

Browsers Version PoC Working Notes
Chrome 64+
Firefox Nightly 60.0a1 w/ patch below import.meta.url is not implemented; Bugzilla 1427610 Implement import.meta
Safari TP 49 (Safari 11.2, WebKit 13606.1.3.3)+
Edge 17.17101+ w/ patch below import.meta.url is not implemented

Patch import.meta.url (just for PoC)

Service Worker to replace import.meta.url with a literal string of response.url value

addEventListener('fetch', function (event) {
  if (event.request.method === 'GET') {
    event.respondWith(async function() {
      let response = await fetch(event.request);
      if (response.status === 200 && response.type !== 'opaque') {
        let url = new URL(response.url);
        if (url.pathname.match(/[.]js$/)) {
          let code = await response.text();
          if (code.indexOf('import.meta.url') >= 0) {
            code = code.replace(/import[.]meta[.]url/g, '\'' + response.url + '\'');
          }
          response = new Response(code, { headers: {'Content-Type': 'text/javascript'} });
        }
      }
      return response;
    }());
  }
});
t2ym commented 6 years ago

Integration with gulp-i18n-preprocess

gulp tasks

cd i18n-element/components/i18n-element/demo
../node_modules/.bin/gulp

unmodulize gulp filter to generate temporary HTMLs from JS modules

t2ym commented 5 years ago

Close as #60 is closed.