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