-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
File Highlight & JSONP Highlight update (#1974)
- Loading branch information
1 parent
05c9f20
commit afea17d
Showing
7 changed files
with
343 additions
and
167 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
})(); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.