Wednesday, June 11, 2014

Wherefore Art Thou ApplyAuthorStyles?


Up today I start revisiting styling of Polymer elements. Styling custom elements was one of the first tasks that I undertook when I started on Patterns in Polymer. Recent changes in both Polymer and Chrome have rendered that work invalid—to the point that I had to pull the chapter from the book.

I am aware of various CSS selectors that have been added recently to help with this, but tonight I would like to see if I can get my Polymer elements styled the same as similar elements elsewhere on the page. For example, I have been including Bootstrap CSS on the page:
<!DOCTYPE html>
<html lang="en">
  <head>
    <link type="text/css" rel="stylesheet" href="assets/bootstrap.min.css">
    <script src="bower_components/platform/platform.js"></script>
    <link rel="import" href="elements/x-pizza.html">
  </head>
  <body>
    <h1>JavaScript Pizza Builder</h1>
    <x-pizza></x-pizza>
  </body>
</html>
Which would then apply to things within my custom elements by virtue of a now-deprecated applyAuthorStyles setting in the backing class of the Polymer element:
Polymer('x-pizza', {
  applyAuthorStyles: true,
  // ...
}
This would result in standard elements within my custom element having the same look and feel as elements contained on the page:



Now that Chrome no longer supports this (and it has been removed from Polymer), things like buttons and drop down lists are no longer styled:



I could style them inside the element, but for standard elements like this, I have no desire to chose a style. The site using the element should have control—and it should not have to be aware of any specialized selectors. If I, as a site author, want my buttons to have an orange, dashed border then even buttons inside Polymer elements that I want to use should have orange, dashed borders:
<style>button {
    border: 3px dashed orange;
  }
</style>
In regular Polymer styling, non-specialized selectors need to go inside the template that will be inside the element's shadow DOM. That is, this would need to be inside the element's <template> tag:
<link rel="import"
      href="../bower_components/polymer/polymer.html">
<polymer-element name="x-pizza">
  <template>
    <style>
      button {
        border: 3px dashed orange;
      }
    </style>
    <!-- Actual HTML definition here... -->
  </template>
  <script src="x_pizza.js"></script>
</polymer-element>
My hope is that I can do something similar for external stylesheets. If Boostrap is used on the containing site with a URL of /assets/bootstrap.min.css, then hopefully pulling that stylesheet into the Polymer element's template will style the drop-downs and buttons in the same Bootstrap style:
<link rel="import"
      href="../bower_components/polymer/polymer.html">
<script src="../bower_components/snap.svg/dist/snap.svg.js"></script>
<polymer-element name="x-pizza">
  <template>
    <link type="text/css" rel="stylesheet" href="/assets/bootstrap.min.css">
    <!-- Actual HTML definition here... -->
  </template>
  <script src="x_pizza.js"></script>
</polymer-element>
And indeed that does the trick:



Of course, a custom Polymer element with an external CSS hard-coded like that is pretty useless. If I wanted to dynamically copy CSS from the main site, I might add it in the attached() life-cycle method of the Polymer element:
Polymer('x-pizza', {
  // ...
  attached: function() {
    var link = this.shadowRoot.ownerDocument.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.href = '/assets/bootstrap.min.css';
    this.shadowRoot.appendChild(link);

    this.updatePizzaState();
  },
  // ...
});
That does not work however. The <link> tag is added to the shadow root, but the styles that are contained in the linked CSS are not applied.

Unfortunately, I cannot figure out how to get the styling shim to apply to linked CSS. The documentation describes Platform.ShadowCSS.addCssToDocument() which has functionality similar to what I need, but ShadowCSS does not appear to be a property on Platform (version 0.3.2).

Stuck, I call it a night here. Hopefully some more digging tomorrow will uncover the proper method to make this happen. And if I am really lucky, I hope to find a way to work around all of this.




Day #91

1 comment:

  1. You could have a look at this

    https://groups.google.com/a/dartlang.org/forum/?utm_medium=email&utm_source=footer#!msg/web/RAC8nE7DfTI/rUekcMlNcXIJ

    It may hold an answer to what you seek, as it seems similar to what you're doing. Then it may not.

    ReplyDelete