mirror of
https://github.com/arsenetar/PrismHighlight.git
synced 2026-01-26 00:21:39 +00:00
First Version ( v0.1 )
First Version of the PrismHighlight Mediawiki extension.
This commit is contained in:
3
prism/plugins/prism-autolinker.css
Normal file
3
prism/plugins/prism-autolinker.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.token a {
|
||||
color: inherit;
|
||||
}
|
||||
61
prism/plugins/prism-autolinker.js
Normal file
61
prism/plugins/prism-autolinker.js
Normal file
@@ -0,0 +1,61 @@
|
||||
(function(){
|
||||
|
||||
if (!self.Prism) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = /\b([a-z]{3,7}:\/\/|tel:)[\w-+%~/.]+/,
|
||||
email = /\b\S+@[\w.]+[a-z]{2}/,
|
||||
linkMd = /\[([^\]]+)]\(([^)]+)\)/,
|
||||
|
||||
// Tokens that may contain URLs and emails
|
||||
candidates = ['comment', 'url', 'attr-value', 'string'];
|
||||
|
||||
for (var language in Prism.languages) {
|
||||
var tokens = Prism.languages[language];
|
||||
|
||||
Prism.languages.DFS(tokens, function (type, def) {
|
||||
if (candidates.indexOf(type) > -1) {
|
||||
if (!def.pattern) {
|
||||
def = this[type] = {
|
||||
pattern: def
|
||||
};
|
||||
}
|
||||
|
||||
def.inside = def.inside || {};
|
||||
|
||||
if (type == 'comment') {
|
||||
def.inside['md-link'] = linkMd;
|
||||
}
|
||||
|
||||
def.inside['url-link'] = url;
|
||||
def.inside['email-link'] = email;
|
||||
}
|
||||
});
|
||||
|
||||
tokens['url-link'] = url;
|
||||
tokens['email-link'] = email;
|
||||
}
|
||||
|
||||
Prism.hooks.add('wrap', function(env) {
|
||||
if (/-link$/.test(env.type)) {
|
||||
env.tag = 'a';
|
||||
|
||||
var href = env.content;
|
||||
|
||||
if (env.type == 'email-link') {
|
||||
href = 'mailto:' + href;
|
||||
}
|
||||
else if (env.type == 'md-link') {
|
||||
// Markdown
|
||||
var match = env.content.match(linkMd);
|
||||
|
||||
href = match[2];
|
||||
env.content = match[1];
|
||||
}
|
||||
|
||||
env.attributes.href = href;
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
52
prism/plugins/prism-file-highlight.js
Normal file
52
prism/plugins/prism-file-highlight.js
Normal file
@@ -0,0 +1,52 @@
|
||||
(function(){
|
||||
|
||||
if (!window.Prism || !document.querySelector) {
|
||||
return;
|
||||
}
|
||||
|
||||
var Extensions = {
|
||||
'js': 'javascript',
|
||||
'html': 'markup',
|
||||
'svg': 'markup'
|
||||
};
|
||||
|
||||
Array.prototype.slice.call(document.querySelectorAll('pre[data-src]')).forEach(function(pre) {
|
||||
var src = pre.getAttribute('data-src');
|
||||
var extension = (src.match(/\.(\w+)$/) || [,''])[1];
|
||||
var language = Extensions[extension] || extension;
|
||||
|
||||
var code = document.createElement('code');
|
||||
code.className = 'language-' + language;
|
||||
|
||||
pre.textContent = '';
|
||||
|
||||
code.textContent = 'Loading…';
|
||||
|
||||
pre.appendChild(code);
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open('GET', src, true);
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
console.log(xhr.readyState, xhr.status, src);
|
||||
if (xhr.readyState == 4) {
|
||||
|
||||
if (xhr.status < 400 && xhr.responseText) {
|
||||
code.textContent = xhr.responseText;
|
||||
|
||||
Prism.highlightElement(code);
|
||||
}
|
||||
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';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
});
|
||||
|
||||
})();
|
||||
3
prism/plugins/prism-ie8.css
Normal file
3
prism/plugins/prism-ie8.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.token a {
|
||||
color: inherit;
|
||||
}
|
||||
42
prism/plugins/prism-ie8.js
Normal file
42
prism/plugins/prism-ie8.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function(){
|
||||
|
||||
if (!window.Prism) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dummy = document.createElement('header');
|
||||
|
||||
if (!String.prototype.trim) {
|
||||
String.prototype.trim = function () {
|
||||
return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
||||
};
|
||||
}
|
||||
|
||||
// textContent polyfill
|
||||
if (!('textContent' in dummy) && ('innerText' in dummy) && Object.defineProperty) {
|
||||
Object.defineProperty(Element.prototype, 'textContent', {
|
||||
get: function() {
|
||||
return this.innerText;
|
||||
},
|
||||
set: function(text) {
|
||||
this.innerText = text;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// IE8 doesn't have DOMContentLoaded
|
||||
if (!document.addEventListener && 'textContent' in dummy) {
|
||||
setTimeout(Prism.highlightAll, 10);
|
||||
}
|
||||
|
||||
// Test if innerHTML line break bug is present
|
||||
dummy.innerHTML = '\r\n';
|
||||
|
||||
if (dummy.textContent.indexOf('\n') === -1) {
|
||||
// IE8 innerHTML bug: Discards line breaks
|
||||
Prism.hooks.add('after-highlight', function(env) {
|
||||
env.element.innerHTML = env.highlightedCode.replace(/\r?\n/g, '<br>');
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
47
prism/plugins/prism-line-highlight.css
Normal file
47
prism/plugins/prism-line-highlight.css
Normal file
@@ -0,0 +1,47 @@
|
||||
pre[data-line] {
|
||||
position: relative;
|
||||
padding: 1em 0 1em 3em;
|
||||
}
|
||||
|
||||
.line-highlight {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: inherit 0;
|
||||
margin-top: 1em; /* Same as .prism’s padding-top */
|
||||
|
||||
background: hsla(24, 20%, 50%,.08);
|
||||
background: -moz-linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
|
||||
background: -webkit-linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
|
||||
background: -o-linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
|
||||
background: linear-gradient(left, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
line-height: inherit;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.line-highlight:before,
|
||||
.line-highlight[data-end]:after {
|
||||
content: attr(data-start);
|
||||
position: absolute;
|
||||
top: .4em;
|
||||
left: .6em;
|
||||
min-width: 1em;
|
||||
padding: 0 .5em;
|
||||
background-color: hsla(24, 20%, 50%,.4);
|
||||
color: hsl(24, 20%, 95%);
|
||||
font: bold 65%/1.5 sans-serif;
|
||||
text-align: center;
|
||||
vertical-align: .3em;
|
||||
border-radius: 999px;
|
||||
text-shadow: none;
|
||||
box-shadow: 0 1px white;
|
||||
}
|
||||
|
||||
.line-highlight[data-end]:after {
|
||||
content: attr(data-end);
|
||||
top: auto;
|
||||
bottom: .4em;
|
||||
}
|
||||
94
prism/plugins/prism-line-highlight.js
Normal file
94
prism/plugins/prism-line-highlight.js
Normal file
@@ -0,0 +1,94 @@
|
||||
(function(){
|
||||
|
||||
if(!window.Prism) {
|
||||
return;
|
||||
}
|
||||
|
||||
function $$(expr, con) {
|
||||
return Array.prototype.slice.call((con || document).querySelectorAll(expr));
|
||||
}
|
||||
|
||||
var CRLF = crlf = /\r?\n|\r/g;
|
||||
|
||||
function highlightLines(pre, lines, classes) {
|
||||
var ranges = lines.replace(/\s+/g, '').split(','),
|
||||
offset = +pre.getAttribute('data-line-offset') || 0;
|
||||
|
||||
var lineHeight = parseFloat(getComputedStyle(pre).lineHeight);
|
||||
|
||||
for (var i=0, range; range = ranges[i++];) {
|
||||
range = range.split('-');
|
||||
|
||||
var start = +range[0],
|
||||
end = +range[1] || start;
|
||||
|
||||
var line = document.createElement('div');
|
||||
|
||||
line.textContent = Array(end - start + 2).join(' \r\n');
|
||||
line.className = (classes || '') + ' line-highlight';
|
||||
line.setAttribute('data-start', start);
|
||||
|
||||
if(end > start) {
|
||||
line.setAttribute('data-end', end);
|
||||
}
|
||||
|
||||
line.style.top = (start - offset - 1) * lineHeight + 'px';
|
||||
|
||||
(pre.querySelector('code') || pre).appendChild(line);
|
||||
}
|
||||
}
|
||||
|
||||
function applyHash() {
|
||||
var hash = location.hash.slice(1);
|
||||
|
||||
// Remove pre-existing temporary lines
|
||||
$$('.temporary.line-highlight').forEach(function (line) {
|
||||
line.parentNode.removeChild(line);
|
||||
});
|
||||
|
||||
var range = (hash.match(/\.([\d,-]+)$/) || [,''])[1];
|
||||
|
||||
if (!range || document.getElementById(hash)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var id = hash.slice(0, hash.lastIndexOf('.')),
|
||||
pre = document.getElementById(id);
|
||||
|
||||
if (!pre) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pre.hasAttribute('data-line')) {
|
||||
pre.setAttribute('data-line', '');
|
||||
}
|
||||
|
||||
highlightLines(pre, range, 'temporary ');
|
||||
|
||||
document.querySelector('.temporary.line-highlight').scrollIntoView();
|
||||
}
|
||||
|
||||
var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
|
||||
|
||||
Prism.hooks.add('after-highlight', function(env) {
|
||||
var pre = env.element.parentNode;
|
||||
var lines = pre && pre.getAttribute('data-line');
|
||||
|
||||
if (!pre || !lines || !/pre/i.test(pre.nodeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(fakeTimer);
|
||||
|
||||
$$('.line-highlight', pre).forEach(function (line) {
|
||||
line.parentNode.removeChild(line);
|
||||
});
|
||||
|
||||
highlightLines(pre, lines);
|
||||
|
||||
fakeTimer = setTimeout(applyHash, 1);
|
||||
});
|
||||
|
||||
addEventListener('hashchange', applyHash);
|
||||
|
||||
})();
|
||||
40
prism/plugins/prism-line-numbers.css
Normal file
40
prism/plugins/prism-line-numbers.css
Normal file
@@ -0,0 +1,40 @@
|
||||
pre.line-numbers {
|
||||
position: relative;
|
||||
padding-left: 3.8em;
|
||||
counter-reset: linenumber;
|
||||
}
|
||||
|
||||
pre.line-numbers > code {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.line-numbers .line-numbers-rows {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
font-size: 100%;
|
||||
left: -3.8em;
|
||||
width: 3em; /* works for line-numbers below 1000 lines */
|
||||
letter-spacing: -1px;
|
||||
border-right: 1px solid #999;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
|
||||
.line-numbers-rows > span {
|
||||
pointer-events: none;
|
||||
display: block;
|
||||
counter-increment: linenumber;
|
||||
}
|
||||
|
||||
.line-numbers-rows > span:before {
|
||||
content: counter(linenumber);
|
||||
color: #999;
|
||||
display: block;
|
||||
padding-right: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
24
prism/plugins/prism-line-numbers.js
Normal file
24
prism/plugins/prism-line-numbers.js
Normal file
@@ -0,0 +1,24 @@
|
||||
Prism.hooks.add('after-highlight', function (env) {
|
||||
// works only for <code> wrapped inside <pre data-line-numbers> (not inline)
|
||||
var pre = env.element.parentNode;
|
||||
if (!pre || !/pre/i.test(pre.nodeName) || pre.className.indexOf('line-numbers') === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var linesNum = (1 + env.code.split('\n').length);
|
||||
var lineNumbersWrapper;
|
||||
|
||||
lines = new Array(linesNum);
|
||||
lines = lines.join('<span></span>');
|
||||
|
||||
lineNumbersWrapper = document.createElement('span');
|
||||
lineNumbersWrapper.className = 'line-numbers-rows';
|
||||
lineNumbersWrapper.innerHTML = lines;
|
||||
|
||||
if (pre.hasAttribute('data-start')) {
|
||||
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
|
||||
}
|
||||
|
||||
env.element.appendChild(lineNumbersWrapper);
|
||||
|
||||
});
|
||||
17
prism/plugins/prism-show-invisibles.css
Normal file
17
prism/plugins/prism-show-invisibles.css
Normal file
@@ -0,0 +1,17 @@
|
||||
.token.tab:not(:empty):before,
|
||||
.token.cr:before,
|
||||
.token.lf:before {
|
||||
color: hsl(24, 20%, 85%);
|
||||
}
|
||||
|
||||
.token.tab:not(:empty):before {
|
||||
content: '▸';
|
||||
}
|
||||
|
||||
.token.cr:before {
|
||||
content: '␍';
|
||||
}
|
||||
|
||||
.token.lf:before {
|
||||
content: '␊';
|
||||
}
|
||||
15
prism/plugins/prism-show-invisibles.js
Normal file
15
prism/plugins/prism-show-invisibles.js
Normal file
@@ -0,0 +1,15 @@
|
||||
(function(){
|
||||
|
||||
if(!window.Prism) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var language in Prism.languages) {
|
||||
var tokens = Prism.languages[language];
|
||||
|
||||
tokens.tab = /\t/g;
|
||||
tokens.lf = /\n/g;
|
||||
tokens.cr = /\r/g;
|
||||
}
|
||||
|
||||
})();
|
||||
11
prism/plugins/prism-wpd.css
Normal file
11
prism/plugins/prism-wpd.css
Normal file
@@ -0,0 +1,11 @@
|
||||
code[class*="language-"] a[href],
|
||||
pre[class*="language-"] a[href] {
|
||||
cursor: help;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
code[class*="language-"] a[href]:hover,
|
||||
pre[class*="language-"] a[href]:hover {
|
||||
cursor: help;
|
||||
text-decoration: underline;
|
||||
}
|
||||
159
prism/plugins/prism-wpd.js
Normal file
159
prism/plugins/prism-wpd.js
Normal file
@@ -0,0 +1,159 @@
|
||||
(function(){
|
||||
|
||||
if (!self.Prism) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Prism.languages.css) {
|
||||
Prism.languages.css.atrule = {
|
||||
pattern: Prism.languages.css.atrule,
|
||||
inside: {
|
||||
'atrule-id': /^@[\w-]+/
|
||||
}
|
||||
};
|
||||
|
||||
Prism.languages.css.selector = {
|
||||
pattern: Prism.languages.css.selector,
|
||||
inside: {
|
||||
'pseudo-class': /:[\w-]+/,
|
||||
'pseudo-element': /::[\w-]+/
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (Prism.languages.markup) {
|
||||
Prism.languages.markup.tag.inside.tag.inside['tag-id'] = /[\w-]+/;
|
||||
|
||||
var Tags = {
|
||||
HTML: {
|
||||
'a': 1, 'abbr': 1, 'acronym': 1, 'b': 1, 'basefont': 1, 'bdo': 1, 'big': 1, 'blink': 1, 'cite': 1, 'code': 1, 'dfn': 1, 'em': 1, 'kbd': 1, 'i': 1,
|
||||
'rp': 1, 'rt': 1, 'ruby': 1, 's': 1, 'samp': 1, 'small': 1, 'spacer': 1, 'strike': 1, 'strong': 1, 'sub': 1, 'sup': 1, 'time': 1, 'tt': 1, 'u': 1,
|
||||
'var': 1, 'wbr': 1, 'noframes': 1, 'summary': 1, 'command': 1, 'dt': 1, 'dd': 1, 'figure': 1, 'figcaption': 1, 'center': 1, 'section': 1, 'nav': 1,
|
||||
'article': 1, 'aside': 1, 'hgroup': 1, 'header': 1, 'footer': 1, 'address': 1, 'noscript': 1, 'isIndex': 1, 'main': 1, 'mark': 1, 'marquee': 1,
|
||||
'meter': 1, 'menu': 1
|
||||
},
|
||||
SVG: {
|
||||
'animateColor': 1, 'animateMotion': 1, 'animateTransform': 1, 'glyph': 1, 'feBlend': 1, 'feColorMatrix': 1, 'feComponentTransfer': 1,
|
||||
'feFuncR': 1, 'feFuncG': 1, 'feFuncB': 1, 'feFuncA': 1, 'feComposite': 1, 'feConvolveMatrix': 1, 'feDiffuseLighting': 1, 'feDisplacementMap': 1,
|
||||
'feFlood': 1, 'feGaussianBlur': 1, 'feImage': 1, 'feMerge': 1, 'feMergeNode': 1, 'feMorphology': 1, 'feOffset': 1, 'feSpecularLighting': 1,
|
||||
'feTile': 1, 'feTurbulence': 1, 'feDistantLight': 1, 'fePointLight': 1, 'feSpotLight': 1, 'linearGradient': 1, 'radialGradient': 1, 'altGlyph': 1,
|
||||
'textPath': 1, 'tref': 1, 'altglyph': 1, 'textpath': 1, 'tref': 1, 'altglyphdef': 1, 'altglyphitem': 1, 'clipPath': 1, 'color-profile': 1, 'cursor': 1,
|
||||
'font-face': 1, 'font-face-format': 1, 'font-face-name': 1, 'font-face-src': 1, 'font-face-uri': 1, 'foreignObject': 1, 'glyph': 1, 'glyphRef': 1,
|
||||
'hkern': 1, 'vkern': 1,
|
||||
},
|
||||
MathML: {}
|
||||
}
|
||||
}
|
||||
|
||||
var language;
|
||||
|
||||
Prism.hooks.add('wrap', function(env) {
|
||||
if ((['tag-id'].indexOf(env.type) > -1
|
||||
|| (env.type == 'property' && env.content.indexOf('-') != 0)
|
||||
|| (env.type == 'atrule-id'&& env.content.indexOf('@-') != 0)
|
||||
|| (env.type == 'pseudo-class'&& env.content.indexOf(':-') != 0)
|
||||
|| (env.type == 'pseudo-element'&& env.content.indexOf('::-') != 0)
|
||||
|| (env.type == 'attr-name' && env.content.indexOf('data-') != 0)
|
||||
) && env.content.indexOf('<') === -1
|
||||
) {
|
||||
var searchURL = 'w/index.php?fulltext&search=';
|
||||
|
||||
env.tag = 'a';
|
||||
|
||||
var href = 'http://docs.webplatform.org/';
|
||||
|
||||
if (env.language == 'css') {
|
||||
href += 'wiki/css/'
|
||||
|
||||
if (env.type == 'property') {
|
||||
href += 'properties/';
|
||||
}
|
||||
else if (env.type == 'atrule-id') {
|
||||
href += 'atrules/';
|
||||
}
|
||||
else if (env.type == 'pseudo-class') {
|
||||
href += 'selectors/pseudo-classes/';
|
||||
}
|
||||
else if (env.type == 'pseudo-element') {
|
||||
href += 'selectors/pseudo-elements/';
|
||||
}
|
||||
}
|
||||
else if (env.language == 'markup') {
|
||||
if (env.type == 'tag-id') {
|
||||
// Check language
|
||||
language = getLanguage(env.content) || language;
|
||||
|
||||
if (language) {
|
||||
href += 'wiki/' + language + '/elements/';
|
||||
}
|
||||
else {
|
||||
href += searchURL;
|
||||
}
|
||||
}
|
||||
else if (env.type == 'attr-name') {
|
||||
if (language) {
|
||||
href += 'wiki/' + language + '/attributes/';
|
||||
}
|
||||
else {
|
||||
href += searchURL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
href += env.content;
|
||||
|
||||
env.attributes.href = href;
|
||||
env.attributes.target = '_blank';
|
||||
}
|
||||
});
|
||||
|
||||
function getLanguage(tag) {
|
||||
var tagL = tag.toLowerCase();
|
||||
|
||||
if (Tags.HTML[tagL]) {
|
||||
return 'html';
|
||||
}
|
||||
else if (Tags.SVG[tag]) {
|
||||
return 'svg';
|
||||
}
|
||||
else if (Tags.MathML[tag]) {
|
||||
return 'mathml';
|
||||
}
|
||||
|
||||
// Not in dictionary, perform check
|
||||
if (Tags.HTML[tagL] !== 0) {
|
||||
var htmlInterface = (document.createElement(tag).toString().match(/\[object HTML(.+)Element\]/) || [])[1];
|
||||
|
||||
if (htmlInterface && htmlInterface != 'Unknown') {
|
||||
Tags.HTML[tagL] = 1;
|
||||
return 'html';
|
||||
}
|
||||
}
|
||||
|
||||
Tags.HTML[tagL] = 0;
|
||||
|
||||
if (Tags.SVG[tag] !== 0) {
|
||||
var svgInterface = (document.createElementNS('http://www.w3.org/2000/svg', tag).toString().match(/\[object SVG(.+)Element\]/) || [])[1];
|
||||
|
||||
if (svgInterface && svgInterface != 'Unknown') {
|
||||
Tags.SVG[tag] = 1;
|
||||
return 'svg';
|
||||
}
|
||||
}
|
||||
|
||||
Tags.SVG[tag] = 0;
|
||||
|
||||
// Lame way to detect MathML, but browsers don’t expose interface names there :(
|
||||
if (Tags.MathML[tag] !== 0) {
|
||||
if (tag.indexOf('m') === 0) {
|
||||
Tags.MathML[tag] = 1;
|
||||
return 'mathml';
|
||||
}
|
||||
}
|
||||
|
||||
Tags.MathML[tag] = 0;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user