Toolbar: `data-toolbar-order` is now inherited (#2205) The `data-toolbar-order` property is now inherited allowing for custom orderings/selections on an per-element basis.
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
diff --git a/plugins/toolbar/index.html b/plugins/toolbar/index.html
index 720a04c..31eb3e2 100644
--- a/plugins/toolbar/index.html
+++ b/plugins/toolbar/index.html
@@ -35,6 +35,8 @@
<pre><code><template id="my-label-button"><button onclick="console.log('This is an inline-handler');">My button</button></template></code></pre>
+ <h2>Registering buttons</h2>
+
<p>For more flexibility, the Toolbar exposes a JavaScript function that can be used to register new buttons or labels to the Toolbar,
<code>Prism.plugins.toolbar.registerButton</code>.</p>
@@ -78,9 +80,17 @@
<p>The above function creates the Select Code button you see, and when you click it, the code gets highlighted.</p>
+ <h2>Ordering buttons</h2>
+
<p>By default, the buttons will be added to the code snippet in the order they were registered. If more control over
- the order is needed, an HTML attribute can be added to the <code>body</code> tag with a comma-separated string indicating the
- order.</p>
+ the order is needed, the <code>data-toolbar-order</code> attribute can be used. Given a comma-separated list of button names, it will ensure that these buttons will be displayed in the given order. <br>
+ Buttons not listed will not be displayed. This means that buttons can be disabled using this technique.</p>
+
+ <p>Example: The "Hello World!" button will appear before the "Select Code" button and the custom label button will not be displayed.</p>
+
+ <pre data-toolbar-order="hello-world,select-code" data-label="Hello World!"><code><pre data-toolbar-order="hello-world,select-code" data-label="Hello World!"><code></code></pre></code></pre>
+
+ <p>The <code>data-toolbar-order</code> attribute is inherited, so you can define the button order for the whole document by adding the attribute to the <code>body</code> of the page.</p>
<pre><code><body data-toolbar-order="select-code,hello-world,label"></code></pre>
</section>
diff --git a/plugins/toolbar/prism-toolbar.js b/plugins/toolbar/prism-toolbar.js
index 893bded..60be9ce 100644
--- a/plugins/toolbar/prism-toolbar.js
+++ b/plugins/toolbar/prism-toolbar.js
@@ -64,6 +64,27 @@
};
/**
+ * 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
@@ -81,8 +102,8 @@
}
// Create wrapper for <pre> to prevent scrolling toolbar with content
- var wrapper = document.createElement("div");
- wrapper.classList.add("code-toolbar");
+ var wrapper = document.createElement('div');
+ wrapper.classList.add('code-toolbar');
pre.parentNode.insertBefore(wrapper, pre);
wrapper.appendChild(pre);
@@ -90,13 +111,16 @@
var toolbar = document.createElement('div');
toolbar.classList.add('toolbar');
- if (document.body.hasAttribute('data-toolbar-order')) {
- callbacks = document.body.getAttribute('data-toolbar-order').split(',').map(function(key) {
+ // order callbacks
+ var elementCallbacks = callbacks;
+ var order = getOrder(env.element);
+ if (order) {
+ elementCallbacks = order.map(function (key) {
return map[key] || noop;
});
}
- callbacks.forEach(function(callback) {
+ elementCallbacks.forEach(function(callback) {
var element = callback(env);
if (!element) {
diff --git a/plugins/toolbar/prism-toolbar.min.js b/plugins/toolbar/prism-toolbar.min.js
index 3b9f082..e692394 100644
--- a/plugins/toolbar/prism-toolbar.min.js
+++ b/plugins/toolbar/prism-toolbar.min.js
@@ -1 +1 @@
-!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var r=[],i={},a=function(){};Prism.plugins.toolbar={};var t=Prism.plugins.toolbar.registerButton=function(t,a){var e;e="function"==typeof a?a:function(t){var e;return"function"==typeof a.onClick?((e=document.createElement("button")).type="button",e.addEventListener("click",function(){a.onClick.call(this,t)})):"string"==typeof a.url?(e=document.createElement("a")).href=a.url:e=document.createElement("span"),a.className&&e.classList.add(a.className),e.textContent=a.text,e},t in i?console.warn('There is a button with the key "'+t+'" registered already.'):r.push(i[t]=e)},e=Prism.plugins.toolbar.hook=function(n){var t=n.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&!t.parentNode.classList.contains("code-toolbar")){var e=document.createElement("div");e.classList.add("code-toolbar"),t.parentNode.insertBefore(e,t),e.appendChild(t);var o=document.createElement("div");o.classList.add("toolbar"),document.body.hasAttribute("data-toolbar-order")&&(r=document.body.getAttribute("data-toolbar-order").split(",").map(function(t){return i[t]||a})),r.forEach(function(t){var e=t(n);if(e){var a=document.createElement("div");a.classList.add("toolbar-item"),a.appendChild(e),o.appendChild(a)}}),e.appendChild(o)}};t("label",function(t){var e=t.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&e.hasAttribute("data-label")){var a,n,o=e.getAttribute("data-label");try{n=document.querySelector("template#"+o)}catch(t){}return n?a=n.content:(e.hasAttribute("data-url")?(a=document.createElement("a")).href=e.getAttribute("data-url"):a=document.createElement("span"),a.textContent=o),a}}),Prism.hooks.add("complete",e)}}();
\ No newline at end of file
+!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var i=[],l={},c=function(){};Prism.plugins.toolbar={};var e=Prism.plugins.toolbar.registerButton=function(e,n){var t;t="function"==typeof n?n:function(e){var t;return"function"==typeof n.onClick?((t=document.createElement("button")).type="button",t.addEventListener("click",function(){n.onClick.call(this,e)})):"string"==typeof n.url?(t=document.createElement("a")).href=n.url:t=document.createElement("span"),n.className&&t.classList.add(n.className),t.textContent=n.text,t},e in l?console.warn('There is a button with the key "'+e+'" registered already.'):i.push(l[e]=t)},t=Prism.plugins.toolbar.hook=function(a){var e=a.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&!e.parentNode.classList.contains("code-toolbar")){var t=document.createElement("div");t.classList.add("code-toolbar"),e.parentNode.insertBefore(t,e),t.appendChild(e);var r=document.createElement("div");r.classList.add("toolbar");var n=i,o=function(e){for(;e;){var t=e.getAttribute("data-toolbar-order");if(null!=t)return(t=t.trim()).length?t.split(/\s*,\s*/g):[];e=e.parentElement}}(a.element);o&&(n=o.map(function(e){return l[e]||c})),n.forEach(function(e){var t=e(a);if(t){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(t),r.appendChild(n)}}),t.appendChild(r)}};e("label",function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-label")){var n,a,r=t.getAttribute("data-label");try{a=document.querySelector("template#"+r)}catch(e){}return a?n=a.content:(t.hasAttribute("data-url")?(n=document.createElement("a")).href=t.getAttribute("data-url"):n=document.createElement("span"),n.textContent=r),n}}),Prism.hooks.add("complete",t)}}();
\ No newline at end of file