Thursday, June 12, 2014

Platform.flags.shadow Does… Something?


Native elements in my <x-pizza> Polymer no longer honor styles from the main page in which they are contained. Absent any styling from within the Polymer definition, things like buttons and drop-down lists look decidedly drab:



This is not simply a question of making native elements look nice. Rather, the ability to pull in styles from the containing page are necessary so that native elements inside Polymer elements do not look out of place on the site.

My first attempts at addressing the situation yesterday did not go well. I was able to dynamically add <link> tags to the Polymer element's shadow DOM, but was unable to get the polyfills to do the right thing. The right thing in the case of CSS is to pull in the CSS from outside and inline it in the shadow DOM. Manually inserted <link> tags behave this way, but dynamically inserted tags seem to be too late for the polyfills.

Last night I had tried this in the attached() life-cycle method:
Polymer('x-pizza', {
  // ...
  attached: function() {
    var link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.href = '/assets/bootstrap.min.css';
    this.shadowRoot.appendChild(link);

    // Platform.ShadowCSS.addCssToDocument(link);
  },
  // ...
});
Since this seems to be added too late for the polyfills, I also tried the ready() life-cycle method. A Polymer is ready (has a shadow DOM) before it is attached (inserted into the page), so I hoped this might have an effect. It did not.

The Polymer styling documentation seems to suggest that similar behaviors to what I desire are possible. Unfortunately, the referenced Platform.ShadowCSS property is not defined in the version of the polyfill platform that I have (0.3.2, which is the latest).

I cannot find any obvious documentation on this, so I start digging through the Polymer code, eventually happening across the Platform.flags setting:
<!DOCTYPE html>
<html lang="en">
  <head>
    <link type="text/css" rel="stylesheet" href="assets/bootstrap.min.css">

    <!-- 1. Load Polymer before any code that touches the DOM. -->
    <script>
      Platform = {flags: {shadow: true}};
    </script>
    <script src="bower_components/platform/platform.js"></script>
    <!-- 2. Load component(s) -->
    <link rel="import" href="elements/x-pizza.html">
  </head>
  <body>
    <h1>JavaScript Pizza Builder</h1>
    <x-pizza></x-pizza>
  </body>
</html>
And, by virtue of that one setting, I get my document styles applied to my Polymer element's native elements. Even if I remove my attempts at dynamically inserting a CSS <link>, I still get my page's CSS (Bootstrap):



I am unsure what enabling Platform.flags.shadow is supposed to do, but it seems to have the weird effect of removing the Polymer element's content from the shadow DOM and inserting it directly in the page:



If Platform.flags.shadow is disabled, then I get a shadow root for my Polymer element:



I also no longer see the page styles applied to the Polymer element's native elements.

I think I need to investigate this setting a little more. I am unsure if I want to do this in the first place—it would seem as though potential users of my element would have to enable this flag. Since that could potentially break styling on other custom elements, it seems a bad idea in practice.

Day #91

No comments:

Post a Comment