[d24f17c] | 1 | (function () {
|
---|
| 2 |
|
---|
| 3 | if (typeof Prism === 'undefined' || typeof document === 'undefined') {
|
---|
| 4 | return;
|
---|
| 5 | }
|
---|
| 6 |
|
---|
| 7 | var callbacks = [];
|
---|
| 8 | var map = {};
|
---|
| 9 | var noop = function () {};
|
---|
| 10 |
|
---|
| 11 | Prism.plugins.toolbar = {};
|
---|
| 12 |
|
---|
| 13 | /**
|
---|
| 14 | * @typedef ButtonOptions
|
---|
| 15 | * @property {string} text The text displayed.
|
---|
| 16 | * @property {string} [url] The URL of the link which will be created.
|
---|
| 17 | * @property {Function} [onClick] The event listener for the `click` event of the created button.
|
---|
| 18 | * @property {string} [className] The class attribute to include with element.
|
---|
| 19 | */
|
---|
| 20 |
|
---|
| 21 | /**
|
---|
| 22 | * Register a button callback with the toolbar.
|
---|
| 23 | *
|
---|
| 24 | * @param {string} key
|
---|
| 25 | * @param {ButtonOptions|Function} opts
|
---|
| 26 | */
|
---|
| 27 | var registerButton = Prism.plugins.toolbar.registerButton = function (key, opts) {
|
---|
| 28 | var callback;
|
---|
| 29 |
|
---|
| 30 | if (typeof opts === 'function') {
|
---|
| 31 | callback = opts;
|
---|
| 32 | } else {
|
---|
| 33 | callback = function (env) {
|
---|
| 34 | var element;
|
---|
| 35 |
|
---|
| 36 | if (typeof opts.onClick === 'function') {
|
---|
| 37 | element = document.createElement('button');
|
---|
| 38 | element.type = 'button';
|
---|
| 39 | element.addEventListener('click', function () {
|
---|
| 40 | opts.onClick.call(this, env);
|
---|
| 41 | });
|
---|
| 42 | } else if (typeof opts.url === 'string') {
|
---|
| 43 | element = document.createElement('a');
|
---|
| 44 | element.href = opts.url;
|
---|
| 45 | } else {
|
---|
| 46 | element = document.createElement('span');
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | if (opts.className) {
|
---|
| 50 | element.classList.add(opts.className);
|
---|
| 51 | }
|
---|
| 52 |
|
---|
| 53 | element.textContent = opts.text;
|
---|
| 54 |
|
---|
| 55 | return element;
|
---|
| 56 | };
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | if (key in map) {
|
---|
| 60 | console.warn('There is a button with the key "' + key + '" registered already.');
|
---|
| 61 | return;
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | callbacks.push(map[key] = callback);
|
---|
| 65 | };
|
---|
| 66 |
|
---|
| 67 | /**
|
---|
| 68 | * Returns the callback order of the given element.
|
---|
| 69 | *
|
---|
| 70 | * @param {HTMLElement} element
|
---|
| 71 | * @returns {string[] | undefined}
|
---|
| 72 | */
|
---|
| 73 | function getOrder(element) {
|
---|
| 74 | while (element) {
|
---|
| 75 | var order = element.getAttribute('data-toolbar-order');
|
---|
| 76 | if (order != null) {
|
---|
| 77 | order = order.trim();
|
---|
| 78 | if (order.length) {
|
---|
| 79 | return order.split(/\s*,\s*/g);
|
---|
| 80 | } else {
|
---|
| 81 | return [];
|
---|
| 82 | }
|
---|
| 83 | }
|
---|
| 84 | element = element.parentElement;
|
---|
| 85 | }
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | /**
|
---|
| 89 | * Post-highlight Prism hook callback.
|
---|
| 90 | *
|
---|
| 91 | * @param env
|
---|
| 92 | */
|
---|
| 93 | var hook = Prism.plugins.toolbar.hook = function (env) {
|
---|
| 94 | // Check if inline or actual code block (credit to line-numbers plugin)
|
---|
| 95 | var pre = env.element.parentNode;
|
---|
| 96 | if (!pre || !/pre/i.test(pre.nodeName)) {
|
---|
| 97 | return;
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | // Autoloader rehighlights, so only do this once.
|
---|
| 101 | if (pre.parentNode.classList.contains('code-toolbar')) {
|
---|
| 102 | return;
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | // Create wrapper for <pre> to prevent scrolling toolbar with content
|
---|
| 106 | var wrapper = document.createElement('div');
|
---|
| 107 | wrapper.classList.add('code-toolbar');
|
---|
| 108 | pre.parentNode.insertBefore(wrapper, pre);
|
---|
| 109 | wrapper.appendChild(pre);
|
---|
| 110 |
|
---|
| 111 | // Setup the toolbar
|
---|
| 112 | var toolbar = document.createElement('div');
|
---|
| 113 | toolbar.classList.add('toolbar');
|
---|
| 114 |
|
---|
| 115 | // order callbacks
|
---|
| 116 | var elementCallbacks = callbacks;
|
---|
| 117 | var order = getOrder(env.element);
|
---|
| 118 | if (order) {
|
---|
| 119 | elementCallbacks = order.map(function (key) {
|
---|
| 120 | return map[key] || noop;
|
---|
| 121 | });
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | elementCallbacks.forEach(function (callback) {
|
---|
| 125 | var element = callback(env);
|
---|
| 126 |
|
---|
| 127 | if (!element) {
|
---|
| 128 | return;
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | var item = document.createElement('div');
|
---|
| 132 | item.classList.add('toolbar-item');
|
---|
| 133 |
|
---|
| 134 | item.appendChild(element);
|
---|
| 135 | toolbar.appendChild(item);
|
---|
| 136 | });
|
---|
| 137 |
|
---|
| 138 | // Add our toolbar to the currently created wrapper of <pre> tag
|
---|
| 139 | wrapper.appendChild(toolbar);
|
---|
| 140 | };
|
---|
| 141 |
|
---|
| 142 | registerButton('label', function (env) {
|
---|
| 143 | var pre = env.element.parentNode;
|
---|
| 144 | if (!pre || !/pre/i.test(pre.nodeName)) {
|
---|
| 145 | return;
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | if (!pre.hasAttribute('data-label')) {
|
---|
| 149 | return;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | var element; var template;
|
---|
| 153 | var text = pre.getAttribute('data-label');
|
---|
| 154 | try {
|
---|
| 155 | // Any normal text will blow up this selector.
|
---|
| 156 | template = document.querySelector('template#' + text);
|
---|
| 157 | } catch (e) { /* noop */ }
|
---|
| 158 |
|
---|
| 159 | if (template) {
|
---|
| 160 | element = template.content;
|
---|
| 161 | } else {
|
---|
| 162 | if (pre.hasAttribute('data-url')) {
|
---|
| 163 | element = document.createElement('a');
|
---|
| 164 | element.href = pre.getAttribute('data-url');
|
---|
| 165 | } else {
|
---|
| 166 | element = document.createElement('span');
|
---|
| 167 | }
|
---|
| 168 |
|
---|
| 169 | element.textContent = text;
|
---|
| 170 | }
|
---|
| 171 |
|
---|
| 172 | return element;
|
---|
| 173 | });
|
---|
| 174 |
|
---|
| 175 | /**
|
---|
| 176 | * Register the toolbar with Prism.
|
---|
| 177 | */
|
---|
| 178 | Prism.hooks.add('complete', hook);
|
---|
| 179 | }());
|
---|