diff --git a/plugins/copy-to-clipboard/prism-copy-to-clipboard.js b/plugins/copy-to-clipboard/prism-copy-to-clipboard.js index ac73efebca..ce52a79143 100644 --- a/plugins/copy-to-clipboard/prism-copy-to-clipboard.js +++ b/plugins/copy-to-clipboard/prism-copy-to-clipboard.js @@ -39,6 +39,8 @@ var linkCopy = document.createElement('button'); linkCopy.textContent = 'Copy'; + var element = env.element; + if (!ClipboardJS) { callbacks.push(registerClipboard); } else { @@ -50,7 +52,7 @@ function registerClipboard() { var clip = new ClipboardJS(linkCopy, { 'text': function () { - return env.code; + return element.textContent; } }); diff --git a/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js b/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js index 199b42549d..3c8b52560e 100644 --- a/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js +++ b/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js @@ -1 +1 @@ -!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var r=window.ClipboardJS||void 0;r||"function"!=typeof require||(r=require("clipboard"));var i=[];if(!r){var o=document.createElement("script"),e=document.querySelector("head");o.onload=function(){if(r=window.ClipboardJS)for(;i.length;)i.pop()()},o.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js",e.appendChild(o)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(e){var t=document.createElement("button");return t.textContent="Copy",r?o():i.push(o),t;function o(){var o=new r(t,{text:function(){return e.code}});o.on("success",function(){t.textContent="Copied!",n()}),o.on("error",function(){t.textContent="Press Ctrl+C to copy",n()})}function n(){setTimeout(function(){t.textContent="Copy"},5e3)}})}else console.warn("Copy to Clipboard plugin loaded before Toolbar plugin.")}(); \ No newline at end of file +!function(){if("undefined"!=typeof self&&self.Prism&&self.document)if(Prism.plugins.toolbar){var i=window.ClipboardJS||void 0;i||"function"!=typeof require||(i=require("clipboard"));var c=[];if(!i){var o=document.createElement("script"),t=document.querySelector("head");o.onload=function(){if(i=window.ClipboardJS)for(;c.length;)c.pop()()},o.src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js",t.appendChild(o)}Prism.plugins.toolbar.registerButton("copy-to-clipboard",function(o){var t=document.createElement("button");t.textContent="Copy";var e=o.element;return i?n():c.push(n),t;function n(){var o=new i(t,{text:function(){return e.textContent}});o.on("success",function(){t.textContent="Copied!",r()}),o.on("error",function(){t.textContent="Press Ctrl+C to copy",r()})}function r(){setTimeout(function(){t.textContent="Copy"},5e3)}})}else console.warn("Copy to Clipboard plugin loaded before Toolbar plugin.")}(); \ No newline at end of file diff --git a/plugins/file-highlight/prism-file-highlight.js b/plugins/file-highlight/prism-file-highlight.js index 47f2278603..93db3acb2b 100644 --- a/plugins/file-highlight/prism-file-highlight.js +++ b/plugins/file-highlight/prism-file-highlight.js @@ -1,89 +1,141 @@ (function () { - if (typeof self === 'undefined' || !self.Prism || !self.document || !document.querySelector) { + if (typeof self === 'undefined' || !self.Prism || !self.document) { return; } + var Prism = window.Prism; + + var LOADING_MESSAGE = 'Loading…'; + var FAILURE_MESSAGE = function (status, message) { + return '✖ Error ' + status + ' while fetching file: ' + message; + }; + var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty'; + + var EXTENSIONS = { + 'js': 'javascript', + 'py': 'python', + 'rb': 'ruby', + 'ps1': 'powershell', + 'psm1': 'powershell', + 'sh': 'bash', + 'bat': 'batch', + 'h': 'c', + 'tex': 'latex' + }; + + var STATUS_ATTR = 'data-src-status'; + var STATUS_LOADING = 'loading'; + var STATUS_LOADED = 'loaded'; + var STATUS_FAILED = 'failed'; + + var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])' + + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])'; + + var lang = /\blang(?:uage)?-([\w-]+)\b/i; + /** - * @param {Element} [container=document] + * Sets the Prism `language-xxxx` or `lang-xxxx` class to the given language. + * + * @param {HTMLElement} element + * @param {string} language + * @returns {void} */ - self.Prism.fileHighlight = function(container) { - container = container || document; - - var Extensions = { - 'js': 'javascript', - 'py': 'python', - 'rb': 'ruby', - 'ps1': 'powershell', - 'psm1': 'powershell', - 'sh': 'bash', - 'bat': 'batch', - 'h': 'c', - 'tex': 'latex' - }; - - Array.prototype.slice.call(container.querySelectorAll('pre[data-src]')).forEach(function (pre) { - // ignore if already loaded - if (pre.hasAttribute('data-src-loaded')) { - return; - } + function setLanguageClass(element, language) { + var className = element.className; + className = className.replace(lang, ' ') + ' language-' + language; + element.className = className.replace(/\s+/g, ' ').trim(); + } - // load current - var src = pre.getAttribute('data-src'); - var language, parent = pre; - var lang = /\blang(?:uage)?-([\w-]+)\b/i; - while (parent && !lang.test(parent.className)) { - parent = parent.parentNode; - } + Prism.hooks.add('before-highlightall', function (env) { + env.selector += ', ' + SELECTOR; + }); - if (parent) { - language = (pre.className.match(lang) || [, ''])[1]; - } + Prism.hooks.add('before-sanity-check', function (env) { + var pre = /** @type {HTMLPreElement} */ (env.element); + if (pre.matches(SELECTOR)) { + env.code = ''; // fast-path the whole thing and go to complete - if (!language) { - var extension = (src.match(/\.(\w+)$/) || [, ''])[1]; - language = Extensions[extension] || extension; - } + pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading - var code = document.createElement('code'); - code.className = 'language-' + language; + // add code element with loading message + var code = pre.appendChild(document.createElement('CODE')); + code.textContent = LOADING_MESSAGE; - pre.textContent = ''; + var src = pre.getAttribute('data-src'); - code.textContent = 'Loading…'; + var language = env.language; + if (language === 'none') { + // the language might be 'none' because there is no language set; + // in this case, we want to use the extension as the language + var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1]; + language = EXTENSIONS[extension] || extension; + } - pre.appendChild(code); + // set language classes + setLanguageClass(code, language); + setLanguageClass(pre, language); - var xhr = new XMLHttpRequest(); + // preload the language + var autoloader = Prism.plugins.autoloader; + if (autoloader) { + autoloader.loadLanguages(language); + } + // load file + var xhr = new XMLHttpRequest(); xhr.open('GET', src, true); - xhr.onreadystatechange = function () { if (xhr.readyState == 4) { - if (xhr.status < 400 && xhr.responseText) { - code.textContent = xhr.responseText; + // mark as loaded + pre.setAttribute(STATUS_ATTR, STATUS_LOADED); + // highlight code + code.textContent = xhr.responseText; Prism.highlightElement(code); - // mark as loaded - pre.setAttribute('data-src-loaded', ''); - } - else if (xhr.status >= 400) { - code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText; - } - else { - code.textContent = '✖ Error: File does not exist or is empty'; + + } else { + // mark as failed + pre.setAttribute(STATUS_ATTR, STATUS_FAILED); + + if (xhr.status >= 400) { + code.textContent = FAILURE_MESSAGE(xhr.status, xhr.statusText); + } else { + code.textContent = FAILURE_EMPTY_MESSAGE; + } } } }; - xhr.send(null); - }); + } + }); + + Prism.plugins.fileHighlight = { + /** + * Executes the File Highlight plugin for all matching `pre` elements under the given container. + * + * Note: Elements which are already loaded or currently loading will not be touched by this method. + * + * @param {ParentNode} [container=document] + */ + highlight: function highlight(container) { + var elements = (container || document).querySelectorAll(SELECTOR); + + for (var i = 0, element; element = elements[i++];) { + Prism.highlightElement(element); + } + } }; - document.addEventListener('DOMContentLoaded', function () { - // execute inside handler, for dropping Event as argument - self.Prism.fileHighlight(); - }); + var logged = false; + /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */ + Prism.fileHighlight = function () { + if (!logged) { + console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.'); + logged = true; + } + Prism.plugins.fileHighlight.highlight.apply(this, arguments); + } })(); diff --git a/plugins/file-highlight/prism-file-highlight.min.js b/plugins/file-highlight/prism-file-highlight.min.js index fae37e1575..843072dff8 100644 --- a/plugins/file-highlight/prism-file-highlight.min.js +++ b/plugins/file-highlight/prism-file-highlight.min.js @@ -1 +1 @@ -"undefined"!=typeof self&&self.Prism&&self.document&&document.querySelector&&(self.Prism.fileHighlight=function(e){e=e||document;var i={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"};Array.prototype.slice.call(e.querySelectorAll("pre[data-src]")).forEach(function(e){if(!e.hasAttribute("data-src-loaded")){for(var t,a=e.getAttribute("data-src"),s=e,n=/\blang(?:uage)?-([\w-]+)\b/i;s&&!n.test(s.className);)s=s.parentNode;if(s&&(t=(e.className.match(n)||[,""])[1]),!t){var r=(a.match(/\.(\w+)$/)||[,""])[1];t=i[r]||r}var o=document.createElement("code");o.className="language-"+t,e.textContent="",o.textContent="Loading…",e.appendChild(o);var l=new XMLHttpRequest;l.open("GET",a,!0),l.onreadystatechange=function(){4==l.readyState&&(l.status<400&&l.responseText?(o.textContent=l.responseText,Prism.highlightElement(o),e.setAttribute("data-src-loaded","")):400<=l.status?o.textContent="✖ Error "+l.status+" while fetching file: "+l.statusText:o.textContent="✖ Error: File does not exist or is empty")},l.send(null)}})},document.addEventListener("DOMContentLoaded",function(){self.Prism.fileHighlight()})); \ No newline at end of file +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var o=window.Prism,h={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},g="data-src-status",u="loading",c="loaded",d="pre[data-src]:not(["+g+'="'+c+'"]):not(['+g+'="'+u+'"])',n=/\blang(?:uage)?-([\w-]+)\b/i;o.hooks.add("before-highlightall",function(e){e.selector+=", "+d}),o.hooks.add("before-sanity-check",function(e){var t=e.element;if(t.matches(d)){e.code="",t.setAttribute(g,u);var i=t.appendChild(document.createElement("CODE"));i.textContent="Loading…";var n=t.getAttribute("data-src"),a=e.language;if("none"===a){var s=(/\.(\w+)$/.exec(n)||[,"none"])[1];a=h[s]||s}f(i,a),f(t,a);var l=o.plugins.autoloader;l&&l.loadLanguages(a);var r=new XMLHttpRequest;r.open("GET",n,!0),r.onreadystatechange=function(){4==r.readyState&&(r.status<400&&r.responseText?(t.setAttribute(g,c),i.textContent=r.responseText,o.highlightElement(i)):(t.setAttribute(g,"failed"),400<=r.status?i.textContent=function(e,t){return"✖ Error "+e+" while fetching file: "+t}(r.status,r.statusText):i.textContent="✖ Error: File does not exist or is empty"))},r.send(null)}});var e=!(o.plugins.fileHighlight={highlight:function(e){for(var t,i=(e||document).querySelectorAll(d),n=0;t=i[n++];)o.highlightElement(t)}});o.fileHighlight=function(){e||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),e=!0),o.plugins.fileHighlight.highlight.apply(this,arguments)}}function f(e,t){var i=e.className;i=i.replace(n," ")+" language-"+t,e.className=i.replace(/\s+/g," ").trim()}}(); \ No newline at end of file diff --git a/plugins/jsonp-highlight/prism-jsonp-highlight.js b/plugins/jsonp-highlight/prism-jsonp-highlight.js index 5f0d68b547..3312e99ae9 100644 --- a/plugins/jsonp-highlight/prism-jsonp-highlight.js +++ b/plugins/jsonp-highlight/prism-jsonp-highlight.js @@ -1,11 +1,13 @@ (function () { - if (!self.Prism || !self.document || !document.querySelectorAll || ![].filter) return; + if (typeof self === 'undefined' || !self.Prism || !self.document) { + return; + } /** * @callback Adapter * @param {any} response * @param {HTMLPreElement} [pre] - * @returns {string} + * @returns {string | null} */ /** @@ -66,7 +68,9 @@ adapter = getAdapter(adapter); } if (typeof adapter === "function") { - var index = adapters.map(function (item) { return item.adapter; }).indexOf(adapter); + var index = adapters.findIndex(function (item) { + return item.adapter === adapter; + }); if (index >= 0) { adapters.splice(index, 1); } @@ -120,63 +124,101 @@ return null; }, 'bitbucket'); - var jsonpcb = 0, - loadMsg = "Loading\u2026"; - /** - * Highlights all `pre` elements with an `data-jsonp` by requesting the specified JSON and using the specified adapter - * or a registered adapter to extract the code to highlight from the response. The highlighted code will be inserted - * into the `pre` element. - */ - function highlight() { - Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function (pre) { - pre.textContent = ""; + var jsonpCallbackCounter = 0; + + var LOADING_MESSAGE = 'Loading…'; + var MISSING_ADAPTER_MESSAGE = function (name) { + return '✖ Error: JSONP adapter function "' + name + '" doesn\'t exist'; + }; + var TIMEOUT_MESSAGE = function (url) { + return '✖ Error: Timeout loading ' + url; + }; + var UNKNOWN_FAILURE_MESSAGE = '✖ Error: Cannot parse response (perhaps you need an adapter function?)'; + + var STATUS_ATTR = 'data-jsonp-status'; + var STATUS_LOADING = 'loading'; + var STATUS_LOADED = 'loaded'; + var STATUS_FAILED = 'failed'; + + var SELECTOR = 'pre[data-jsonp]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])' + + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])'; + - var code = document.createElement("code"); - code.textContent = loadMsg; - pre.appendChild(code); + Prism.hooks.add('before-highlightall', function (env) { + env.selector += ', ' + SELECTOR; + }); - var adapterName = pre.getAttribute("data-adapter"); + Prism.hooks.add('before-sanity-check', function (env) { + var pre = /** @type {HTMLPreElement} */ (env.element); + if (pre.matches(SELECTOR)) { + env.code = ''; // fast-path the whole thing and go to complete + + // mark as loading + pre.setAttribute(STATUS_ATTR, STATUS_LOADING); + + // add code element with loading message + var code = pre.appendChild(document.createElement('CODE')); + code.textContent = LOADING_MESSAGE; + + // set language + var language = env.language; + code.className = 'language-' + language; + + // preload the language + var autoloader = Prism.plugins.autoloader; + if (autoloader) { + autoloader.loadLanguages(language); + } + + var adapterName = pre.getAttribute('data-adapter'); var adapter = null; if (adapterName) { - if (typeof window[adapterName] === "function") { + if (typeof window[adapterName] === 'function') { adapter = window[adapterName]; - } - else { - code.textContent = "JSONP adapter function '" + adapterName + "' doesn't exist"; + } else { + // mark as failed + pre.setAttribute(STATUS_ATTR, STATUS_FAILED); + + code.textContent = MISSING_ADAPTER_MESSAGE(adapterName); return; } } - var cb = "prismjsonp" + jsonpcb++; + var callbackName = 'prismjsonp' + jsonpCallbackCounter++; + + var uri = document.createElement('a'); + var src = uri.href = pre.getAttribute('data-jsonp'); + uri.href += (uri.search ? '&' : '?') + (pre.getAttribute('data-callback') || 'callback') + '=' + callbackName; - var uri = document.createElement("a"); - var src = uri.href = pre.getAttribute("data-jsonp"); - uri.href += (uri.search ? "&" : "?") + (pre.getAttribute("data-callback") || "callback") + "=" + cb; var timeout = setTimeout(function () { // we could clean up window[cb], but if the request finally succeeds, keeping it around is a good thing - if (code.textContent === loadMsg) { - code.textContent = "Timeout loading '" + src + "'"; - } - }, 5000); - var script = document.createElement("script"); + // mark as failed + pre.setAttribute(STATUS_ATTR, STATUS_FAILED); + + code.textContent = TIMEOUT_MESSAGE(src); + }, Prism.plugins.jsonphighlight.timeout); + + + var script = document.createElement('script'); script.src = uri.href; - window[cb] = function (rsp) { + // the JSONP callback function + window[callbackName] = function (response) { + // clean up document.head.removeChild(script); clearTimeout(timeout); - delete window[cb]; - - var data = ""; + delete window[callbackName]; + // interpret the received data using the adapter(s) + var data = null; if (adapter) { - data = adapter(rsp, pre); - } - else { - for (var p in adapters) { - data = adapters[p].adapter(rsp, pre); + data = adapter(response, pre); + } else { + for (var i = 0, l = adapters.length; i < l; i++) { + data = adapters[i].adapter(response, pre); if (data !== null) { break; } @@ -184,23 +226,51 @@ } if (data === null) { - code.textContent = "Cannot parse response (perhaps you need an adapter function?)"; - } - else { + // mark as failed + pre.setAttribute(STATUS_ATTR, STATUS_FAILED); + + code.textContent = UNKNOWN_FAILURE_MESSAGE; + } else { + // mark as loaded + pre.setAttribute(STATUS_ATTR, STATUS_LOADED); + code.textContent = data; Prism.highlightElement(code); } }; document.head.appendChild(script); - }); - } + } + }); + Prism.plugins.jsonphighlight = { + /** + * The timeout after which an error message will be displayed. + * + * __Note:__ If the request succeeds after the timeout, it will still be processed and will override any + * displayed error messages. + */ + timeout: 5000, registerAdapter: registerAdapter, removeAdapter: removeAdapter, - highlight: highlight + + /** + * Highlights all `pre` elements under the given container with a `data-jsonp` attribute by requesting the + * specified JSON and using the specified adapter or a registered adapter to extract the code to highlight + * from the response. The highlighted code will be inserted into the `pre` element. + * + * Note: Elements which are already loaded or currently loading will not be touched by this method. + * + * @param {Element | Document} [container=document] + */ + highlight: function (container) { + var elements = (container || document).querySelectorAll(SELECTOR); + + for (var i = 0, element; element = elements[i++];) { + Prism.highlightElement(element); + } + } }; - highlight(); })(); diff --git a/plugins/jsonp-highlight/prism-jsonp-highlight.min.js b/plugins/jsonp-highlight/prism-jsonp-highlight.min.js index f969cf41d2..e647679723 100644 --- a/plugins/jsonp-highlight/prism-jsonp-highlight.min.js +++ b/plugins/jsonp-highlight/prism-jsonp-highlight.min.js @@ -1 +1 @@ -!function(){if(self.Prism&&self.document&&document.querySelectorAll&&[].filter){var d=[];t(function(t,e){if(t&&t.meta&&t.data){if(t.meta.status&&400<=t.meta.status)return"Error: "+(t.data.message||t.meta.status);if("string"==typeof t.data.content)return"function"==typeof atob?atob(t.data.content.replace(/\s/g,"")):"Your browser cannot decode base64"}return null},"github"),t(function(t,e){if(t&&t.meta&&t.data&&t.data.files){if(t.meta.status&&400<=t.meta.status)return"Error: "+(t.data.message||t.meta.status);var n=t.data.files,a=e.getAttribute("data-filename");if(null==a)for(var r in n)if(n.hasOwnProperty(r)){a=r;break}return void 0!==n[a]?n[a].content:"Error: unknown or missing gist file "+a}return null},"gist"),t(function(t,e){return t&&t.node&&"string"==typeof t.data?t.data:null},"bitbucket");var s=0,l="Loading…";Prism.plugins.jsonphighlight={registerAdapter:t,removeAdapter:function(t){if("string"==typeof t&&(t=n(t)),"function"==typeof t){var e=d.map(function(t){return t.adapter}).indexOf(t);0<=e&&d.splice(e,1)}},highlight:e},e()}function t(t,e){e=e||t.name,"function"!=typeof t||n(t)||n(e)||d.push({adapter:t,name:e})}function n(t){if("function"==typeof t){for(var e=0;n=d[e++];)if(n.adapter.valueOf()===t.valueOf())return n.adapter}else if("string"==typeof t){var n;for(e=0;n=d[e++];)if(n.name===t)return n.adapter}return null}function e(){Array.prototype.slice.call(document.querySelectorAll("pre[data-jsonp]")).forEach(function(a){a.textContent="";var r=document.createElement("code");r.textContent=l,a.appendChild(r);var t=a.getAttribute("data-adapter"),o=null;if(t){if("function"!=typeof window[t])return void(r.textContent="JSONP adapter function '"+t+"' doesn't exist");o=window[t]}var i="prismjsonp"+s++,e=document.createElement("a"),n=e.href=a.getAttribute("data-jsonp");e.href+=(e.search?"&":"?")+(a.getAttribute("data-callback")||"callback")+"="+i;var u=setTimeout(function(){r.textContent===l&&(r.textContent="Timeout loading '"+n+"'")},5e3),f=document.createElement("script");f.src=e.href,window[i]=function(t){document.head.removeChild(f),clearTimeout(u),delete window[i];var e="";if(o)e=o(t,a);else for(var n in d)if(null!==(e=d[n].adapter(t,a)))break;null===e?r.textContent="Cannot parse response (perhaps you need an adapter function?)":(r.textContent=e,Prism.highlightElement(r))},document.head.appendChild(f)})}}(); \ No newline at end of file +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var c=[];t(function(t,e){if(t&&t.meta&&t.data){if(t.meta.status&&400<=t.meta.status)return"Error: "+(t.data.message||t.meta.status);if("string"==typeof t.data.content)return"function"==typeof atob?atob(t.data.content.replace(/\s/g,"")):"Your browser cannot decode base64"}return null},"github"),t(function(t,e){if(t&&t.meta&&t.data&&t.data.files){if(t.meta.status&&400<=t.meta.status)return"Error: "+(t.data.message||t.meta.status);var n=t.data.files,a=e.getAttribute("data-filename");if(null==a)for(var r in n)if(n.hasOwnProperty(r)){a=r;break}return void 0!==n[a]?n[a].content:"Error: unknown or missing gist file "+a}return null},"gist"),t(function(t,e){return t&&t.node&&"string"==typeof t.data?t.data:null},"bitbucket");var m=0,p="data-jsonp-status",g="loading",h="loaded",v="failed",b="pre[data-jsonp]:not(["+p+'="'+h+'"]):not(['+p+'="'+g+'"])';Prism.hooks.add("before-highlightall",function(t){t.selector+=", "+b}),Prism.hooks.add("before-sanity-check",function(t){var r=t.element;if(r.matches(b)){t.code="",r.setAttribute(p,g);var i=r.appendChild(document.createElement("CODE"));i.textContent="Loading…";var e=t.language;i.className="language-"+e;var n=Prism.plugins.autoloader;n&&n.loadLanguages(e);var a=r.getAttribute("data-adapter"),o=null;if(a){if("function"!=typeof window[a])return r.setAttribute(p,v),void(i.textContent=function(t){return'✖ Error: JSONP adapter function "'+t+"\" doesn't exist"}(a));o=window[a]}var u="prismjsonp"+m++,s=document.createElement("a"),f=s.href=r.getAttribute("data-jsonp");s.href+=(s.search?"&":"?")+(r.getAttribute("data-callback")||"callback")+"="+u;var l=setTimeout(function(){r.setAttribute(p,v),i.textContent=function(t){return"✖ Error: Timeout loading "+t}(f)},Prism.plugins.jsonphighlight.timeout),d=document.createElement("script");d.src=s.href,window[u]=function(t){document.head.removeChild(d),clearTimeout(l),delete window[u];var e=null;if(o)e=o(t,r);else for(var n=0,a=c.length;n= 400) { - code.textContent = '✖ Error ' + xhr.status + ' while fetching file: ' + xhr.statusText; - } - else { - code.textContent = '✖ Error: File does not exist or is empty'; + + } else { + // mark as failed + pre.setAttribute(STATUS_ATTR, STATUS_FAILED); + + if (xhr.status >= 400) { + code.textContent = FAILURE_MESSAGE(xhr.status, xhr.statusText); + } else { + code.textContent = FAILURE_EMPTY_MESSAGE; + } } } }; - xhr.send(null); - }); + } + }); + + Prism.plugins.fileHighlight = { + /** + * Executes the File Highlight plugin for all matching `pre` elements under the given container. + * + * Note: Elements which are already loaded or currently loading will not be touched by this method. + * + * @param {ParentNode} [container=document] + */ + highlight: function highlight(container) { + var elements = (container || document).querySelectorAll(SELECTOR); + + for (var i = 0, element; element = elements[i++];) { + Prism.highlightElement(element); + } + } }; - document.addEventListener('DOMContentLoaded', function () { - // execute inside handler, for dropping Event as argument - self.Prism.fileHighlight(); - }); + var logged = false; + /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */ + Prism.fileHighlight = function () { + if (!logged) { + console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.'); + logged = true; + } + Prism.plugins.fileHighlight.highlight.apply(this, arguments); + } })();