Create a MarkDown tag

Use the component API and external library to parse markdown text

by Andrew Holloway

HTML

<script src="https://cdn.rawgit.com/showdownjs/showdown/1.4.2/dist/showdown.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.22/webcomponents.min.js"></script>
<h1>Tests!</h1>

<hr>

<ah-markdown>
## Render some markdown
</ah-markdown>

<ah-markdown>
  List of items:
  
  1. a
  1. b
  1. c
</ah-markdown>

<ah-markdown>
  [here][md1] is a sample link
  
  [md1]: https://www.untropy.net/
</ah-markdown>

<ah-markdown test="alpha">
  Each tag is separate, [see?][md1]
  
  [md1]: https://www.yahoo.com/
</ah-markdown>

CSS

ah-markdown {
  display: block;
  font-family: monospace;
}

JavaScript

// Custom tag to render Markdown via content or 'src' attribute
// http://webcomponents.org/polyfills/custom-elements/
// https://github.com/showdownjs/showdown

!function() {
  var MDProto = Object.create(HTMLElement.prototype);

  MDProto.converter = new showdown.Converter();
  MDProto.createdCallback = function() {
    // this is called when an element is constructed (but not attached yet?)
    this.shadowDom = this.attachShadow({mode: 'open'});
  };

  MDProto.attachedCallback = function() {
    // this comes into play when the element is sent to the screen
    var externalMd = this.getAttribute('src') || null;
    this._updateRendering();
  };

  MDProto.attributeChangedCallback = function(name, oldValue, newValue) {
    // this triggers when an attribute (name) is changed from (old) to (new)
    // if the value changes, we should re-render the src tag into the container
  };

  MDProto._updateRendering = function() {
    // whenever we get this call, pull the file from `src` and render that, or 
    // render the contents of the tag as markdown
    // if there's some error, emit it with coloring and error stuff to help
    this.shadowDom.innerHTML = this.converter.makeHtml(this.innerHTML);
  };

  var MD = document.registerElement('ah-markdown', {
    prototype: MDProto
  });
}();