Search code examples
javascriptpolymerweb-component

What is the best way to build self-injecting elements in polymer?


I am trying to figure out how to best build elements that inject themselves into templates of other element without the need to alter that other elements template code. Example:

<core-scaffold>
  <core-header-panel navigation="" flex="">
    <core-toolbar id="navheader">
      <span>Menu</span>
    </core-toolbar>
    <core-menu>
      <core-item label="One" horizontal="" center="" layout="" class=""></core-item>
      <core-item label="Two" horizontal="" center="" layout="" class="core-selected" active=""></core-item>
    </core-menu>
  </core-header-panel>

  <span tool="">Title</span>

  <div id="content"><p>If drawer is hidden, press button to display drawer.</p></div>
</core-scaffold>

This is the standard code-scaffold example from the polymer project. What I would like to add polymer elements into the <core-scaffold> template behind the div #content element by just importing that element. I do not want to alter the existing element code at all, the new element needs to inject itself at the right position.

What would be the best way to achieve that?


Solution

  • When defining the element that injects itself in, give it an attached function that searches for the intended location and moves itself there.

    Simple example (running demo):

    <style>
      #content {
        background-color: rgb(226, 226, 252);
      }
    </style>
    <div id="content">
    
    </div>
    
    <polymer-element name="self-injector">
      <template>I'm the self-injector!</template>
      <script>
        Polymer('self-injector', {
          attached: function() {
            document.querySelector('#content').appendChild(this);
          }
        })
      </script>
    </polymer-element>
    
    <self-injector></self-injector> 
    

    The only sticky wicket here is how to find where you want to inject into. (e.g. are you assuming that there's only one core-scaffold on the page, or should the injecting element find the nearest one, etc). Most of that is up to you and your use cases. The only thing you need to know there is how to query the shadow dom. This article goes over the selectors that you may need, ::shadow and /deep/.