Merge pull request #1683 from ajaxorg/static_highlight
fix static highlight bugs
This commit is contained in:
commit
f8e96328e4
4 changed files with 69 additions and 67 deletions
|
|
@ -19,9 +19,10 @@
|
||||||
|
|
||||||
<p>Syntax highlighting using Ace language modes and themes.</p>
|
<p>Syntax highlighting using Ace language modes and themes.</p>
|
||||||
|
|
||||||
<div class="code" ace-mode="ace/mode/css" ace-theme="ace/theme/chrome">
|
<div class="code" ace-mode="ace/mode/css" ace-theme="ace/theme/chrome" ace-gutter="true">
|
||||||
.code {
|
.code {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
@ -41,28 +42,20 @@ function wobble (flam) {
|
||||||
<script src="../../build/src-noconflict/ext-static_highlight.js"></script>
|
<script src="../../build/src-noconflict/ext-static_highlight.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var highlighter = ace.require("ace/ext/static_highlight")
|
var highlight = ace.require("ace/ext/static_highlight")
|
||||||
var dom = ace.require("ace/lib/dom")
|
var dom = ace.require("ace/lib/dom")
|
||||||
function qsa(sel) {
|
function qsa(sel) {
|
||||||
return [].slice.call(document.querySelectorAll(sel));
|
return [].slice.call(document.querySelectorAll(sel));
|
||||||
}
|
}
|
||||||
|
|
||||||
qsa(".code").forEach(function (codeEl) {
|
qsa(".code").forEach(function (codeEl) {
|
||||||
var cs = getComputedStyle(codeEl);
|
highlight(codeEl, {
|
||||||
codeEl.style.cssText = codeEl.style.cssText +
|
mode: codeEl.getAttribute('ace-mode'),
|
||||||
'width: ' + cs.width + ';' +
|
theme: codeEl.getAttribute('ace-theme'),
|
||||||
'height: ' + cs.height + ';';
|
startLineNumber: 1,
|
||||||
var mode = codeEl.getAttribute('ace-mode');
|
showGutter: codeEl.getAttribute("ace-gutter"),
|
||||||
var theme = codeEl.getAttribute('ace-theme');
|
trim: true
|
||||||
var data = codeEl.textContent.trim();
|
}, function (highlighted) {
|
||||||
|
|
||||||
highlighter.render(data, mode, theme, 1, false, function (highlighted) {
|
|
||||||
dom.importCssString(highlighted.css, "ace_highlight");
|
|
||||||
dom.importCssString('.ace_editor { overflow: auto; ' +
|
|
||||||
'position:absolute; top:0; bottom:0; right:0; left:0; }' +
|
|
||||||
'.ace_gutter { position: relative; }',
|
|
||||||
'atropa_hial');
|
|
||||||
codeEl.innerHTML = highlighted.html;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -231,10 +231,6 @@
|
||||||
border-left-width: 1px;
|
border-left-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_line {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {
|
.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,49 @@ var TextLayer = require("../layer/text").Text;
|
||||||
var baseStyles = require("../requirejs/text!./static.css");
|
var baseStyles = require("../requirejs/text!./static.css");
|
||||||
var config = require("../config");
|
var config = require("../config");
|
||||||
var dom = require("../lib/dom");
|
var dom = require("../lib/dom");
|
||||||
|
|
||||||
|
|
||||||
|
var highlight = function(el, opts, callback) {
|
||||||
|
var m = el.className.match(/lang-(\w+)/);
|
||||||
|
var mode = opts.mode || m && ("ace/mode/" + m[1]);
|
||||||
|
if (!mode)
|
||||||
|
return false;
|
||||||
|
var theme = opts.theme || "ace/theme/textmate";
|
||||||
|
|
||||||
|
var data = "";
|
||||||
|
var nodes = [];
|
||||||
|
|
||||||
|
if (el.firstElementChild) {
|
||||||
|
var textLen = 0;
|
||||||
|
for (var i = 0; i < el.childNodes.length; i++) {
|
||||||
|
var ch = el.childNodes[i];
|
||||||
|
if (ch.nodeType == 3) {
|
||||||
|
textLen += ch.data.length;
|
||||||
|
data += ch.data;
|
||||||
|
} else {
|
||||||
|
nodes.push(textLen, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data = dom.getInnerText(el);
|
||||||
|
if (opts.trim)
|
||||||
|
data = data.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight.render(data, mode, theme, opts.firstLineNumber, !opts.showGutter, function (highlighted) {
|
||||||
|
dom.importCssString(highlighted.css, "ace_highlight");
|
||||||
|
el.innerHTML = highlighted.html;
|
||||||
|
var container = el.firstChild.firstChild;
|
||||||
|
for (var i = 0; i < nodes.length; i += 2) {
|
||||||
|
var pos = highlighted.session.doc.indexToPosition(nodes[i]);
|
||||||
|
var node = nodes[i + 1];
|
||||||
|
var lineEl = container.children[pos.row];
|
||||||
|
lineEl && lineEl.appendChild(node);
|
||||||
|
}
|
||||||
|
callback && callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms a given input code snippet into HTML using the given mode
|
* Transforms a given input code snippet into HTML using the given mode
|
||||||
*
|
*
|
||||||
|
|
@ -56,7 +99,7 @@ var dom = require("../lib/dom");
|
||||||
* @returns {object} An object containing the properties `html` and `css`.
|
* @returns {object} An object containing the properties `html` and `css`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.render = function(input, mode, theme, lineStart, disableGutter, callback) {
|
highlight.render = function(input, mode, theme, lineStart, disableGutter, callback) {
|
||||||
var waiting = 0;
|
var waiting = 0;
|
||||||
var modeCache = EditSession.prototype.$modes;
|
var modeCache = EditSession.prototype.$modes;
|
||||||
|
|
||||||
|
|
@ -81,7 +124,7 @@ exports.render = function(input, mode, theme, lineStart, disableGutter, callback
|
||||||
|
|
||||||
// loads or passes the specified mode module then calls renderer
|
// loads or passes the specified mode module then calls renderer
|
||||||
function done() {
|
function done() {
|
||||||
var result = exports.renderSync(input, mode, theme, lineStart, disableGutter);
|
var result = highlight.renderSync(input, mode, theme, lineStart, disableGutter);
|
||||||
return callback ? callback(result) : result;
|
return callback ? callback(result) : result;
|
||||||
}
|
}
|
||||||
return waiting || done();
|
return waiting || done();
|
||||||
|
|
@ -95,7 +138,7 @@ exports.render = function(input, mode, theme, lineStart, disableGutter, callback
|
||||||
* @returns {object} An object containing: html, css
|
* @returns {object} An object containing: html, css
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.renderSync = function(input, mode, theme, lineStart, disableGutter) {
|
highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) {
|
||||||
lineStart = parseInt(lineStart || 1, 10);
|
lineStart = parseInt(lineStart || 1, 10);
|
||||||
|
|
||||||
var session = new EditSession("");
|
var session = new EditSession("");
|
||||||
|
|
@ -119,7 +162,7 @@ exports.renderSync = function(input, mode, theme, lineStart, disableGutter) {
|
||||||
if (!disableGutter)
|
if (!disableGutter)
|
||||||
stringBuilder.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'>" + (ix + lineStart) + "</span>");
|
stringBuilder.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'>" + (ix + lineStart) + "</span>");
|
||||||
textLayer.$renderLine(stringBuilder, ix, true, false);
|
textLayer.$renderLine(stringBuilder, ix, true, false);
|
||||||
stringBuilder.push("</div>");
|
stringBuilder.push("\n</div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's prepare the whole html
|
// let's prepare the whole html
|
||||||
|
|
@ -133,48 +176,11 @@ exports.renderSync = function(input, mode, theme, lineStart, disableGutter) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
css: baseStyles + theme.cssText,
|
css: baseStyles + theme.cssText,
|
||||||
html: html
|
html: html,
|
||||||
|
session: session
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports = highlight;
|
||||||
|
module.exports.highlight =highlight;
|
||||||
exports.highlight = function(el, opts, callback) {
|
|
||||||
var m = el.className.match(/lang-(\w+)/);
|
|
||||||
var mode = opts.mode || m && ("ace/mode/" + m[1]);
|
|
||||||
if (!mode)
|
|
||||||
return false;
|
|
||||||
var theme = opts.theme || "ace/theme/textmate";
|
|
||||||
|
|
||||||
var data = "";
|
|
||||||
var nodes = [];
|
|
||||||
|
|
||||||
if (el.firstElementChild) {
|
|
||||||
var textLen = 0;
|
|
||||||
for (var i = 0; i < el.childNodes.length; i++) {
|
|
||||||
var ch = el.childNodes[i];
|
|
||||||
if (ch.nodeType == 3) {
|
|
||||||
textLen += ch.data.length;
|
|
||||||
data += ch.data;
|
|
||||||
} else {
|
|
||||||
nodes.push(textLen, ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data = dom.getInnerText(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.render(data, mode, theme, 1, true, function (highlighted) {
|
|
||||||
dom.importCssString(highlighted.css, "ace_highlight");
|
|
||||||
el.innerHTML = highlighted.html;
|
|
||||||
var container = el.firstChild.firstChild
|
|
||||||
for (var i = 0; i < nodes.length; i += 2) {
|
|
||||||
var pos = highlighted.session.doc.indexToPosition(nodes[i])
|
|
||||||
var node = nodes[i + 1];
|
|
||||||
var lineEl = container.children[pos.row];
|
|
||||||
lineEl && lineEl.appendChild(nodes[i+1]);
|
|
||||||
}
|
|
||||||
callback && callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,14 @@ module.exports = {
|
||||||
var mode = new JavaScriptMode();
|
var mode = new JavaScriptMode();
|
||||||
|
|
||||||
var result = highlighter.render(snippet, mode, theme);
|
var result = highlighter.render(snippet, mode, theme);
|
||||||
assert.equal(result.html, "<div class='ace-tomorrow'><div class='ace_static_highlight'><div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>1</span><span class='ace_comment ace_doc'>/**\xa0this\xa0is\xa0a\xa0function</span></div><div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>2</span><span class='ace_comment ace_doc'>*</span></div><div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>3</span><span class='ace_comment ace_doc'>*/</span></div><div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>4</span><span class='ace_storage ace_type'>function</span>\xa0<span class='ace_entity ace_name ace_function'>hello</span>\xa0<span class='ace_paren ace_lparen'>(</span><span class='ace_variable ace_parameter'>a</span><span class='ace_punctuation ace_operator'>,\xa0</span><span class='ace_variable ace_parameter'>b</span><span class='ace_punctuation ace_operator'>,\xa0</span><span class='ace_variable ace_parameter'>c</span><span class='ace_paren ace_rparen'>)</span>\xa0<span class='ace_paren ace_lparen'>{</span></div><div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>5</span>\xa0\xa0\xa0\xa0<span class='ace_storage ace_type'>console</span><span class='ace_punctuation ace_operator'>.</span><span class='ace_support ace_function ace_firebug'>log</span><span class='ace_paren ace_lparen'>(</span><span class='ace_identifier'>a</span>\xa0<span class='ace_keyword ace_operator'>*</span>\xa0<span class='ace_identifier'>b</span>\xa0<span class='ace_keyword ace_operator'>+</span>\xa0<span class='ace_identifier'>c</span>\xa0<span class='ace_keyword ace_operator'>+</span>\xa0<span class='ace_string'>'sup$'</span><span class='ace_paren ace_rparen'>)</span><span class='ace_punctuation ace_operator'>;</span></div><div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>6</span><span class='ace_paren ace_rparen'>}</span></div></div></div>");
|
assert.equal(result.html, "<div class='ace-tomorrow'><div class='ace_static_highlight'>"
|
||||||
|
+ "<div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>1</span><span class='ace_comment ace_doc'>/**\xa0this\xa0is\xa0a\xa0function</span>\n</div>"
|
||||||
|
+ "<div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>2</span><span class='ace_comment ace_doc'>*</span>\n</div>"
|
||||||
|
+ "<div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>3</span><span class='ace_comment ace_doc'>*/</span>\n</div>"
|
||||||
|
+ "<div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>4</span><span class='ace_storage ace_type'>function</span>\xa0<span class='ace_entity ace_name ace_function'>hello</span>\xa0<span class='ace_paren ace_lparen'>(</span><span class='ace_variable ace_parameter'>a</span><span class='ace_punctuation ace_operator'>,\xa0</span><span class='ace_variable ace_parameter'>b</span><span class='ace_punctuation ace_operator'>,\xa0</span><span class='ace_variable ace_parameter'>c</span><span class='ace_paren ace_rparen'>)</span>\xa0<span class='ace_paren ace_lparen'>{</span>\n</div>"
|
||||||
|
+ "<div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>5</span>\xa0\xa0\xa0\xa0<span class='ace_storage ace_type'>console</span><span class='ace_punctuation ace_operator'>.</span><span class='ace_support ace_function ace_firebug'>log</span><span class='ace_paren ace_lparen'>(</span><span class='ace_identifier'>a</span>\xa0<span class='ace_keyword ace_operator'>*</span>\xa0<span class='ace_identifier'>b</span>\xa0<span class='ace_keyword ace_operator'>+</span>\xa0<span class='ace_identifier'>c</span>\xa0<span class='ace_keyword ace_operator'>+</span>\xa0<span class='ace_string'>'sup$'</span><span class='ace_paren ace_rparen'>)</span><span class='ace_punctuation ace_operator'>;</span>\n</div>"
|
||||||
|
+ "<div class='ace_line'><span class='ace_gutter ace_gutter-cell' unselectable='on'>6</span><span class='ace_paren ace_rparen'>}</span>\n</div>"
|
||||||
|
+ "</div></div>");
|
||||||
assert.ok(!!result.css);
|
assert.ok(!!result.css);
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue