diff --git a/components.js b/components.js index 0a49d3c511..650111759f 100644 --- a/components.js +++ b/components.js @@ -587,7 +587,9 @@ var components = { }, "show-language": { "title": "Show Language", - "owner": "nauzilus" + "owner": "nauzilus", + "noCSS": true, + "require": "toolbar" }, "jsonp-highlight": { "title": "JSONP Highlight", @@ -659,6 +661,16 @@ var components = { "title": "Data-URI Highlight", "owner": "Golmote", "noCSS": true + }, + "toolbar": { + "title": "Toolbar", + "owner": "mAAdhaTTah" + }, + "copy-to-clipboard": { + "title": "Copy to Clipboard Button", + "owner": "mAAdhaTTah", + "require": "toolbar", + "noCSS": true } } }; diff --git a/package.json b/package.json index 4ae0326080..a51a2a96cc 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,9 @@ "author": "Lea Verou", "license": "MIT", "readmeFilename": "README.md", + "optionalDependencies": { + "clipboard": "^1.5.5" + }, "devDependencies": { "chai": "^2.3.0", "gulp": "^3.8.6", diff --git a/plugins/copy-to-clipboard/index.html b/plugins/copy-to-clipboard/index.html new file mode 100644 index 0000000000..abd5e57e4a --- /dev/null +++ b/plugins/copy-to-clipboard/index.html @@ -0,0 +1,48 @@ + + +
+ + + +Add a button that copies the code block to the clipboard when clicked.
+In addition to including the plugin file with your PrismJS build, ensure Clipboard.js is loaded before the plugin.
+ +The simplest way to include Clipboard.js is to use any of the
+ recommended CDNs. If you're using Browserify, Clipboard.js will be loaded auotmatically
+ if it's included in your package.json
.
+ If you don't load Clipboard.js yourself, the plugin will load it from a CDN for you.
Attach a toolbar for plugins to easily register buttons on the top of a code block.
+The Toolbar plugin allows for several methods to register your button, using the Prism.plugins.toolbar.registerButton
function.
The simplest method is through the HTML API. Add a data-label
attribute to the pre
element, and the Toolbar
+ plugin will read the value of that attribute and append a label to the code snippet.
<pre data-src="plugins/toolbar/prism-toolbar.js" data-label="Hello World!"></pre>
+
+ If you want to provide arbitrary HTML to the label, create a template
element with the HTML you want in the label, and provide the
+ template
element's id
to data-label
. The Toolbar plugin will use the template's content for the button.
+ You can also use to declare your event handlers inline:
<pre data-src="plugins/toolbar/prism-toolbar.js" data-label="my-label-button"></pre>
+
+ <template id="my-label-button"><button onclick="console.log('This is an inline-handler');">My button</button></template>
+
+ For more flexibility, the Toolbar exposes a JavaScript function that can be used to register new buttons or labels to the Toolbar,
+ Prism.plugins.toolbar.registerButton
.
The function accepts a key for the button and an object with a text
property string and an optional
+ onClick
function or url
string. The onClick
function will be called when the button is clicked, while the
+ url
property will be set to the anchor tag's href
.
Prism.plugins.toolbar.registerButton('hello-world', {
+ text: 'Hello World!', // required
+ onClick: function (env) { // optional
+ alert('This code snippet is written in ' + env.language + '.');
+ }
+});
+
+ See how the above code registers the Hello World!
button? You can use this in your plugins to register your own buttons with the toolbar.
If you need more control, you can provide a function to registerButton
that returns either a span
, a
, or
+ button
element.
Prism.plugins.toolbar.registerButton('select-code', function() {
+ var button = document.createElement('button');
+ button.innerHTML = 'Select Code';
+
+ button.addEventListener('click', function () {
+ // Source: http://stackoverflow.com/a/11128179/2757940
+ if (document.body.createTextRange) { // ms
+ var range = document.body.createTextRange();
+ range.moveToElementText(env.element);
+ range.select();
+ } else if (window.getSelection) { // moz, opera, webkit
+ var selection = window.getSelection();
+ var range = document.createRange();
+ range.selectNodeContents(env.element);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+ });
+
+ return button;
+});
+
+ The above function creates the Select Code button you see, and when you click it, the code gets highlighted.
+ +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 body
tag with a comma-separated string indicating the
+ order.
<body data-toolbar-order="select-code,hello-world,label">
+tag + pre.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, template; + var text = pre.getAttribute('data-label'); + try { + // Any normal text will blow up this selector. + template = document.querySelector('template#' + text); + } catch (e) {} + + 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.innerHTML = text; + } + + return element; + }); + + /** + * Register the toolbar with Prism. + */ + Prism.hooks.add('complete', hook); +})(); diff --git a/plugins/toolbar/prism-toolbar.min.js b/plugins/toolbar/prism-toolbar.min.js new file mode 100644 index 0000000000..c069c1ebec --- /dev/null +++ b/plugins/toolbar/prism-toolbar.min.js @@ -0,0 +1 @@ +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var t=[],e={},n=function(){};Prism.plugins.toolbar={};var a=Prism.plugins.toolbar.registerButton=function(n,a){var o;o="function"==typeof a?a:function(t){var e;return"function"==typeof a.onClick?(e=document.createElement("button"),e.type="button",e.addEventListener("click",function(){a.onClick.call(this,t)})):"string"==typeof a.url?(e=document.createElement("a"),e.href=a.url):e=document.createElement("span"),e.textContent=a.text,e},t.push(e[n]=o)},o=Prism.plugins.toolbar.hook=function(a){var o=a.element.parentNode;if(o&&/pre/i.test(o.nodeName)){o.classList.add("code-toolbar");var r=document.createElement("div");r.classList.add("toolbar"),document.body.hasAttribute("data-toolbar-order")&&(t=document.body.getAttribute("data-toolbar-order").split(",").map(function(t){return e[t]||n})),t.forEach(function(t){var e=t(a);if(e){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(e),r.appendChild(n)}}),o.appendChild(r)}};a("label",function(t){var e=t.element.parentNode;if(e&&/pre/i.test(e.nodeName)&&e.hasAttribute("data-label")){var n,a=e.getAttribute("data-label"),o=document.querySelector("template#"+a);return o?n=o.content:(e.hasAttribute("data-url")?(n=document.createElement("a"),n.href=e.getAttribute("data-url")):n=document.createElement("span"),n.innerHTML=a),n}}),Prism.hooks.add("complete",o)}}(); \ No newline at end of file