diff --git a/_assets/css/_styles.scss b/_assets/css/_styles.scss index deb41ba..76366a4 100644 --- a/_assets/css/_styles.scss +++ b/_assets/css/_styles.scss @@ -4630,3 +4630,24 @@ div#sidetoc { display: none; } } + +div{ + &.k-content { + &.k-state-active{ + .copy-code-btn { + padding:7px 10px; + } + } + } +} +.copy-code-btn { + position: absolute; + top: 0; + right: 0; + padding:10px; + z-index: 100; + + &:hover { + cursor: pointer; + } +} diff --git a/_assets/js/clipboard.min.js b/_assets/js/clipboard.min.js index 580433f..0937701 100644 --- a/_assets/js/clipboard.min.js +++ b/_assets/js/clipboard.min.js @@ -1,7 +1,7 @@ /*! - * clipboard.js v1.5.12 + * clipboard.js v2.0.0 * https://zenorocha.github.io/clipboard.js - * + * * Licensed MIT © Zeno Rocha */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(r)return r(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n?n:t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;ao;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],i=[];if(o&&e)for(var r=0,a=o.length;a>r;r++)o[r].fn!==e&&o[r].fn._!==e&&i.push(o[r]);return i.length?n[t]=i:delete n[t],this}},e.exports=o},{}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","select"],r);else if("undefined"!=typeof o)r(n,e("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=n(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},a=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,o.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,o.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),t}();t.exports=a})},function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return r(t,e,n);if(c.nodeList(t))return i(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function r(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function i(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return u(document.body,t,e,n)}var c=n(6),u=n(5);t.exports=o},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){r.off(t,o),e.apply(n,arguments)}var r=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;for(o;o0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===d(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,f.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return u("action",t)}},{key:"defaultTarget",value:function(t){var e=u("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return u("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),e}(s.default);t.exports=p})},function(t,e){function n(t,e){for(;t&&t.nodeType!==o;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}var o=9;if("undefined"!=typeof Element&&!Element.prototype.matches){var r=Element.prototype;r.matches=r.matchesSelector||r.mozMatchesSelector||r.msMatchesSelector||r.oMatchesSelector||r.webkitMatchesSelector}t.exports=n},function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function r(t,e,n,r,i){return"function"==typeof t.addEventListener?o.apply(null,arguments):"function"==typeof n?o.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return o(t,e,n,r,i)}))}function i(t,e,n,o){return function(n){n.delegateTarget=a(n.target,e),n.delegateTarget&&o.call(t,n)}}var a=n(4);t.exports=r},function(t,e){e.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},e.nodeList=function(t){var n=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===n||"[object HTMLCollection]"===n)&&"length"in t&&(0===t.length||e.node(t[0]))},e.string=function(t){return"string"==typeof t||t instanceof String},e.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e){function n(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}t.exports=n}])}); diff --git a/_assets/js/code-snippet.js b/_assets/js/code-snippet.js index 66e4712..717b003 100644 --- a/_assets/js/code-snippet.js +++ b/_assets/js/code-snippet.js @@ -1,23 +1,76 @@ var hasDataLang = false; +var clipboard; const selectedLanguageKey = "Selected_TabStrip_Language_Key"; // Necessary for the offline docs. const localStorageMock = { - getItem: function() { + getItem: function () { return null; }, - setItem: function() { + setItem: function () { } }; +function usesClipboardJs() { + return window.ClipboardJS && !/\[native code\]/.test(window.ClipboardJS.toString()); +}; + +function setTooltip(btn, message) { + $(btn).attr('data-original-title', message) + .tooltip('show'); +}; + +function hideTooltip(btn) { + $(btn).tooltip('hide'); +}; + + +function addCopyButton(element, index) { + var isCopyButtonOutsideCode = element.parentNode.className.indexOf("k-content") >= 0; + $(isCopyButtonOutsideCode ? $(element).parent() : element) + .prepend(''); + + if (usesClipboardJs()) { + var copyButtonSelector = '.copy-code-btn'; + var id = copyButtonSelector.slice(1) + "-" + index; + var copyButton = isCopyButtonOutsideCode ? $(element).prev(copyButtonSelector) : $(element).children(copyButtonSelector); + $(copyButton).attr('id', id) + clipboard = new ClipboardJS("#" + id, { + text: function () { + return $(element).text(); + } + }); + + clipboard.on('success', function (e) { + setTooltip(e.trigger, 'Copied!'); + setTimeout(function () { + hideTooltip(e.trigger); + }, 1000); + }); + + $(copyButton).hover(function (e) { + setTooltip(e.target, 'Copy code') + }, function (e) { + hideTooltip(e.target); + }); + $(copyButton).tooltip({ + container: 'body', + trigger: 'manual', + placement: 'top', + title: 'Copy code' + }); + } +} + function handleDataLangCodeSnippets() { - $("pre[data-lang]").each(function() { + $("pre[data-lang]").each(function () { + if (this.parentNode.className.indexOf("k-content") >= 0) { return; } var langs = $(this).nextUntil(":not(pre)", "pre").add(this); - var tabs = $.map(langs, function(item) { + var tabs = $.map(langs, function (item) { var title = $(item).attr("data-lang").replace("tab-", ""); return $("
  • ").text(title); }); @@ -29,9 +82,9 @@ function handleDataLangCodeSnippets() { tabs[0].addClass("k-state-active"); var tabstrip = $("
    ") - .insertBefore(this) - .append($("
      ").append(tabs)) - .append(langs); + .insertBefore(this) + .append($("
        ").append(tabs)) + .append(langs); langs.wrap("
        "); @@ -43,11 +96,11 @@ function handleDataLangCodeSnippets() { $(function () { $("pre").addClass("prettyprint"); - + function getStorage() { return localStorage !== undefined ? localStorage : localStorageMock; } - + function saveLanguage(language) { getStorage().setItem(selectedLanguageKey, language); } @@ -112,10 +165,10 @@ $(function () { 'ASPNET': 'html', 'XML': 'xml', 'TypeScript': 'commonjs', - 'C++' : 'cpp', - 'C' : 'c', - 'Objective-C' : 'm', - 'Java' : 'java' + 'C++': 'cpp', + 'C': 'c', + 'Objective-C': 'm', + 'Java': 'java' }; if (hasDataLang) { @@ -127,6 +180,11 @@ $(function () { }); } + $("pre").each(function (index) { + addCopyButton(this, index); + }); + + prettyPrint(); /* END TabStrip logic */ diff --git a/_assets/js/main.js b/_assets/js/main.js index 4cec22e..44c4697 100644 --- a/_assets/js/main.js +++ b/_assets/js/main.js @@ -1,6 +1,7 @@ //= require jquery.min //= require bootstrap.min //= require prettify +//= require clipboard.min //= require kendo/kendo.core.min //= require kendo/kendo.data.min