| OLD | NEW |
| (Empty) | |
| 1 <!-- |
| 2 @license |
| 3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. |
| 4 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
| 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
| 6 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
| 7 Code distributed by Google as part of the polymer project is also |
| 8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
| 9 --> |
| 10 <link rel="import" href="../polymer/polymer.html"> |
| 11 <link rel="import" href="marked-import.html"> |
| 12 |
| 13 <!-- |
| 14 Element wrapper for the [marked](http://marked.org/) library. |
| 15 |
| 16 `<marked-element>` accepts Markdown source either via its `markdown` attribute: |
| 17 |
| 18 <marked-element markdown="`Markdown` is _awesome_!"></marked-element> |
| 19 |
| 20 Or, you can provide it via a `<script type="text/markdown">` element child: |
| 21 |
| 22 <marked-element> |
| 23 <script type="text/markdown"> |
| 24 Check out my markdown! |
| 25 |
| 26 We can even embed elements without fear of the HTML parser mucking up th
eir |
| 27 textual representation: |
| 28 |
| 29 ```html |
| 30 <awesome-sauce> |
| 31 <div>Oops, I'm about to forget to close this div. |
| 32 </awesome-sauce> |
| 33 ``` |
| 34 </script> |
| 35 </marked-element> |
| 36 |
| 37 Note that the `<script type="text/markdown">` approach is _static_. Changes to |
| 38 the script content will _not_ update the rendered markdown! |
| 39 @element marked-element |
| 40 @group Molecules |
| 41 @hero hero.svg |
| 42 @demo demo/index.html |
| 43 --> |
| 44 <dom-module id="marked-element"> |
| 45 |
| 46 <template> |
| 47 <div id="content"></div> |
| 48 </template> |
| 49 |
| 50 </dom-module> |
| 51 |
| 52 <script> |
| 53 |
| 54 'use strict'; |
| 55 |
| 56 Polymer({ |
| 57 |
| 58 is: 'marked-element', |
| 59 |
| 60 properties: { |
| 61 |
| 62 /** The markdown source that should be rendered by this element. */ |
| 63 markdown: { |
| 64 observer: 'render', |
| 65 type: String, |
| 66 value: null |
| 67 } |
| 68 |
| 69 }, |
| 70 |
| 71 ready: function() { |
| 72 if (!this.markdown) { |
| 73 // Use the Markdown from the first `<script>` descendant whose MIME type
starts with |
| 74 // "text/markdown". Script elements beyond the first are ignored. |
| 75 var markdownElement = Polymer.dom(this).querySelector('[type^="text/mark
down"]'); |
| 76 if (markdownElement != null) { |
| 77 this.markdown = this._unindent(markdownElement.textContent); |
| 78 } |
| 79 } |
| 80 }, |
| 81 |
| 82 /** |
| 83 * Renders `markdown` to HTML when the element is attached. |
| 84 * |
| 85 * This serves a dual purpose: |
| 86 * |
| 87 * * Prevents unnecessary work (no need to render when not visible). |
| 88 * |
| 89 * * `attached` fires top-down, so we can give ancestors a chance to |
| 90 * register listeners for the `syntax-highlight` event _before_ we render |
| 91 * any markdown. |
| 92 * |
| 93 */ |
| 94 attached: function() { |
| 95 this._attached = true; |
| 96 this.render(); |
| 97 }, |
| 98 |
| 99 detached: function() { |
| 100 this._attached = false; |
| 101 }, |
| 102 |
| 103 /** |
| 104 * Renders `markdown` into this element's DOM. |
| 105 * |
| 106 * This is automatically called whenever the `markdown` property is changed. |
| 107 * |
| 108 * The only case where you should be calling this is if you are providing |
| 109 * markdown via `<script type="text/markdown">` after this element has been |
| 110 * constructed (or updating that markdown). |
| 111 */ |
| 112 render: function() { |
| 113 if (!this._attached) return; |
| 114 if (!this.markdown) { |
| 115 this.$.content.innerHTML = ''; |
| 116 return; |
| 117 } |
| 118 |
| 119 this.$.content.innerHTML = marked(this.markdown, { |
| 120 highlight: this._highlight.bind(this), |
| 121 }); |
| 122 }, |
| 123 |
| 124 _highlight: function(code, lang) { |
| 125 var event = this.fire('syntax-highlight', {code: code, lang: lang}); |
| 126 return event.detail.code || code; |
| 127 }, |
| 128 |
| 129 _unindent: function(text) { |
| 130 if (!text) return text; |
| 131 var lines = text.replace(/\t/g, ' ').split('\n'); |
| 132 var indent = lines.reduce(function(prev, line) { |
| 133 if (/^\s*$/.test(line)) return prev; // Completely ignore blank lines. |
| 134 |
| 135 var lineIndent = line.match(/^(\s*)/)[0].length; |
| 136 if (prev === null) return lineIndent; |
| 137 return lineIndent < prev ? lineIndent : prev; |
| 138 }, null); |
| 139 |
| 140 return lines.map(function(l) { return l.substr(indent); }).join('\n'); |
| 141 }, |
| 142 |
| 143 }); |
| 144 |
| 145 </script> |
| OLD | NEW |