Extract highlight.js internal api code to its own file
This commit is contained in:
parent
93721e7e98
commit
978e54ab64
2 changed files with 145 additions and 127 deletions
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
|
var highlightJS = require('./highlight.js-internals.js').HighlightJS;
|
||||||
|
|
||||||
var diffJson = null;
|
var diffJson = null;
|
||||||
var defaultTarget = "body";
|
var defaultTarget = "body";
|
||||||
var currentSelectionColumnId = -1;
|
var currentSelectionColumnId = -1;
|
||||||
|
|
@ -71,7 +73,7 @@
|
||||||
|
|
||||||
// collect all the diff files and execute the highlight on their lines
|
// collect all the diff files and execute the highlight on their lines
|
||||||
var $files = $target.find(".d2h-file-wrapper");
|
var $files = $target.find(".d2h-file-wrapper");
|
||||||
$files.map(function(i, file) {
|
$files.map(function(_i, file) {
|
||||||
var oldLinesState;
|
var oldLinesState;
|
||||||
var newLinesState;
|
var newLinesState;
|
||||||
var $file = $(file);
|
var $file = $(file);
|
||||||
|
|
@ -79,7 +81,7 @@
|
||||||
|
|
||||||
// collect all the code lines and execute the highlight on them
|
// collect all the code lines and execute the highlight on them
|
||||||
var $codeLines = $file.find(".d2h-code-line-ctn");
|
var $codeLines = $file.find(".d2h-code-line-ctn");
|
||||||
$codeLines.map(function(i, line) {
|
$codeLines.map(function(_j, line) {
|
||||||
var $line = $(line);
|
var $line = $(line);
|
||||||
var text = line.textContent;
|
var text = line.textContent;
|
||||||
var lineParent = line.parentNode;
|
var lineParent = line.parentNode;
|
||||||
|
|
@ -102,11 +104,11 @@
|
||||||
newLinesState = result.top;
|
newLinesState = result.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
var originalStream = nodeStream(line);
|
var originalStream = highlightJS.nodeStream(line);
|
||||||
if (originalStream.length) {
|
if (originalStream.length) {
|
||||||
var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||||
resultNode.innerHTML = result.value;
|
resultNode.innerHTML = result.value;
|
||||||
result.value = mergeStreams(originalStream, nodeStream(resultNode), text);
|
result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
$line.addClass("hljs");
|
$line.addClass("hljs");
|
||||||
|
|
@ -198,129 +200,6 @@
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Copied from Highlight.js Private API
|
|
||||||
* Will be removed when this part of the API is exposed
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Utility functions */
|
|
||||||
|
|
||||||
function escape(value) {
|
|
||||||
return value.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
|
|
||||||
}
|
|
||||||
|
|
||||||
function tag(node) {
|
|
||||||
return node.nodeName.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stream merging */
|
|
||||||
|
|
||||||
function nodeStream(node) {
|
|
||||||
var result = [];
|
|
||||||
(function _nodeStream(node, offset) {
|
|
||||||
for (var child = node.firstChild; child; child = child.nextSibling) {
|
|
||||||
if (child.nodeType == 3)
|
|
||||||
offset += child.nodeValue.length;
|
|
||||||
else if (child.nodeType == 1) {
|
|
||||||
result.push({
|
|
||||||
event: 'start',
|
|
||||||
offset: offset,
|
|
||||||
node: child
|
|
||||||
});
|
|
||||||
offset = _nodeStream(child, offset);
|
|
||||||
// Prevent void elements from having an end tag that would actually
|
|
||||||
// double them in the output. There are more void elements in HTML
|
|
||||||
// but we list only those realistically expected in code display.
|
|
||||||
if (!tag(child).match(/br|hr|img|input/)) {
|
|
||||||
result.push({
|
|
||||||
event: 'stop',
|
|
||||||
offset: offset,
|
|
||||||
node: child
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
})(node, 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergeStreams(original, highlighted, value) {
|
|
||||||
var processed = 0;
|
|
||||||
var result = '';
|
|
||||||
var nodeStack = [];
|
|
||||||
|
|
||||||
function selectStream() {
|
|
||||||
if (!original.length || !highlighted.length) {
|
|
||||||
return original.length ? original : highlighted;
|
|
||||||
}
|
|
||||||
if (original[0].offset != highlighted[0].offset) {
|
|
||||||
return (original[0].offset < highlighted[0].offset) ? original : highlighted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
To avoid starting the stream just before it should stop the order is
|
|
||||||
ensured that original always starts first and closes last:
|
|
||||||
if (event1 == 'start' && event2 == 'start')
|
|
||||||
return original;
|
|
||||||
if (event1 == 'start' && event2 == 'stop')
|
|
||||||
return highlighted;
|
|
||||||
if (event1 == 'stop' && event2 == 'start')
|
|
||||||
return original;
|
|
||||||
if (event1 == 'stop' && event2 == 'stop')
|
|
||||||
return highlighted;
|
|
||||||
... which is collapsed to:
|
|
||||||
*/
|
|
||||||
return highlighted[0].event == 'start' ? original : highlighted;
|
|
||||||
}
|
|
||||||
|
|
||||||
function open(node) {
|
|
||||||
function attrStr(a) {
|
|
||||||
return ' ' + a.nodeName + '="' + escape(a.value) + '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
result += '<' + tag(node) + Array.prototype.map.call(node.attributes, attrStr).join('') + '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(node) {
|
|
||||||
result += '</' + tag(node) + '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function render(event) {
|
|
||||||
(event.event == 'start' ? open : close)(event.node);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (original.length || highlighted.length) {
|
|
||||||
var stream = selectStream();
|
|
||||||
result += escape(value.substr(processed, stream[0].offset - processed));
|
|
||||||
processed = stream[0].offset;
|
|
||||||
if (stream == original) {
|
|
||||||
/*
|
|
||||||
On any opening or closing tag of the original markup we first close
|
|
||||||
the entire highlighted node stack, then render the original tag along
|
|
||||||
with all the following original tags at the same offset and then
|
|
||||||
reopen all the tags on the highlighted stack.
|
|
||||||
*/
|
|
||||||
nodeStack.reverse().forEach(close);
|
|
||||||
do {
|
|
||||||
render(stream.splice(0, 1)[0]);
|
|
||||||
stream = selectStream();
|
|
||||||
} while (stream == original && stream.length && stream[0].offset == processed);
|
|
||||||
nodeStack.reverse().forEach(open);
|
|
||||||
} else {
|
|
||||||
if (stream[0].event == 'start') {
|
|
||||||
nodeStack.push(stream[0].node);
|
|
||||||
} else {
|
|
||||||
nodeStack.pop();
|
|
||||||
}
|
|
||||||
render(stream.splice(0, 1)[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result + escape(value.substr(processed));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* **** Highlight.js Private API **** */
|
|
||||||
|
|
||||||
module.exports.Diff2HtmlUI = Diff2HtmlUI;
|
module.exports.Diff2HtmlUI = Diff2HtmlUI;
|
||||||
|
|
||||||
// Expose diff2html in the browser
|
// Expose diff2html in the browser
|
||||||
|
|
|
||||||
139
src/ui/js/highlight.js-internals.js
Normal file
139
src/ui/js/highlight.js-internals.js
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* highlight.js
|
||||||
|
* Author: isagalaev
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
function HighlightJS() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copied from Highlight.js Private API
|
||||||
|
* Will be removed when this part of the API is exposed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Utility functions */
|
||||||
|
|
||||||
|
function escape(value) {
|
||||||
|
return value.replace(/&/gm, '&').replace(/</gm, '<').replace(/>/gm, '>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function tag(node) {
|
||||||
|
return node.nodeName.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stream merging */
|
||||||
|
|
||||||
|
HighlightJS.prototype.nodeStream = function(node) {
|
||||||
|
var result = [];
|
||||||
|
(function _nodeStream(node, offset) {
|
||||||
|
for (var child = node.firstChild; child; child = child.nextSibling) {
|
||||||
|
if (child.nodeType == 3)
|
||||||
|
offset += child.nodeValue.length;
|
||||||
|
else if (child.nodeType == 1) {
|
||||||
|
result.push({
|
||||||
|
event: 'start',
|
||||||
|
offset: offset,
|
||||||
|
node: child
|
||||||
|
});
|
||||||
|
offset = _nodeStream(child, offset);
|
||||||
|
// Prevent void elements from having an end tag that would actually
|
||||||
|
// double them in the output. There are more void elements in HTML
|
||||||
|
// but we list only those realistically expected in code display.
|
||||||
|
if (!tag(child).match(/br|hr|img|input/)) {
|
||||||
|
result.push({
|
||||||
|
event: 'stop',
|
||||||
|
offset: offset,
|
||||||
|
node: child
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
})(node, 0);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
HighlightJS.prototype.mergeStreams = function(original, highlighted, value) {
|
||||||
|
var processed = 0;
|
||||||
|
var result = '';
|
||||||
|
var nodeStack = [];
|
||||||
|
|
||||||
|
function selectStream() {
|
||||||
|
if (!original.length || !highlighted.length) {
|
||||||
|
return original.length ? original : highlighted;
|
||||||
|
}
|
||||||
|
if (original[0].offset != highlighted[0].offset) {
|
||||||
|
return (original[0].offset < highlighted[0].offset) ? original : highlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
To avoid starting the stream just before it should stop the order is
|
||||||
|
ensured that original always starts first and closes last:
|
||||||
|
if (event1 == 'start' && event2 == 'start')
|
||||||
|
return original;
|
||||||
|
if (event1 == 'start' && event2 == 'stop')
|
||||||
|
return highlighted;
|
||||||
|
if (event1 == 'stop' && event2 == 'start')
|
||||||
|
return original;
|
||||||
|
if (event1 == 'stop' && event2 == 'stop')
|
||||||
|
return highlighted;
|
||||||
|
... which is collapsed to:
|
||||||
|
*/
|
||||||
|
return highlighted[0].event == 'start' ? original : highlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(node) {
|
||||||
|
function attrStr(a) {
|
||||||
|
return ' ' + a.nodeName + '="' + escape(a.value) + '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
result += '<' + tag(node) + Array.prototype.map.call(node.attributes, attrStr).join('') + '>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(node) {
|
||||||
|
result += '</' + tag(node) + '>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function render(event) {
|
||||||
|
(event.event == 'start' ? open : close)(event.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (original.length || highlighted.length) {
|
||||||
|
var stream = selectStream();
|
||||||
|
result += escape(value.substr(processed, stream[0].offset - processed));
|
||||||
|
processed = stream[0].offset;
|
||||||
|
if (stream == original) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
On any opening or closing tag of the original markup we first close
|
||||||
|
the entire highlighted node stack, then render the original tag along
|
||||||
|
with all the following original tags at the same offset and then
|
||||||
|
reopen all the tags on the highlighted stack.
|
||||||
|
*/
|
||||||
|
nodeStack.reverse().forEach(close);
|
||||||
|
do {
|
||||||
|
render(stream.splice(0, 1)[0]);
|
||||||
|
stream = selectStream();
|
||||||
|
} while (stream == original && stream.length && stream[0].offset == processed);
|
||||||
|
nodeStack.reverse().forEach(open);
|
||||||
|
} else {
|
||||||
|
if (stream[0].event == 'start') {
|
||||||
|
nodeStack.push(stream[0].node);
|
||||||
|
} else {
|
||||||
|
nodeStack.pop();
|
||||||
|
}
|
||||||
|
render(stream.splice(0, 1)[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result + escape(value.substr(processed));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* **** Highlight.js Private API **** */
|
||||||
|
|
||||||
|
module.exports.HighlightJS = new HighlightJS();
|
||||||
|
|
||||||
|
})();
|
||||||
Loading…
Reference in a new issue