ext-static_highlight.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. define("ace/ext/static_highlight",["ace_require","exports","module","ace/edit_session","ace/layer/text","ace/config","ace/lib/dom","ace/lib/lang"], function(ace_require, exports, module) {
  2. "use strict";
  3. var EditSession = ace_require("../edit_session").EditSession;
  4. var TextLayer = ace_require("../layer/text").Text;
  5. var baseStyles = ".ace_static_highlight {\
  6. font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'Droid Sans Mono', monospace;\
  7. font-size: 12px;\
  8. white-space: pre-wrap\
  9. }\
  10. .ace_static_highlight .ace_gutter {\
  11. width: 2em;\
  12. text-align: right;\
  13. padding: 0 3px 0 0;\
  14. margin-right: 3px;\
  15. contain: none;\
  16. }\
  17. .ace_static_highlight.ace_show_gutter .ace_line {\
  18. padding-left: 2.6em;\
  19. }\
  20. .ace_static_highlight .ace_line { position: relative; }\
  21. .ace_static_highlight .ace_gutter-cell {\
  22. -moz-user-select: -moz-none;\
  23. -khtml-user-select: none;\
  24. -webkit-user-select: none;\
  25. user-select: none;\
  26. top: 0;\
  27. bottom: 0;\
  28. left: 0;\
  29. position: absolute;\
  30. }\
  31. .ace_static_highlight .ace_gutter-cell:before {\
  32. content: counter(ace_line, decimal);\
  33. counter-increment: ace_line;\
  34. }\
  35. .ace_static_highlight {\
  36. counter-reset: ace_line;\
  37. }\
  38. ";
  39. var config = ace_require("../config");
  40. var dom = ace_require("../lib/dom");
  41. var escapeHTML = ace_require("../lib/lang").escapeHTML;
  42. function Element(type) {
  43. this.type = type;
  44. this.style = {};
  45. this.textContent = "";
  46. }
  47. Element.prototype.cloneNode = function() {
  48. return this;
  49. };
  50. Element.prototype.appendChild = function(child) {
  51. this.textContent += child.toString();
  52. };
  53. Element.prototype.toString = function() {
  54. var stringBuilder = [];
  55. if (this.type != "fragment") {
  56. stringBuilder.push("<", this.type);
  57. if (this.className)
  58. stringBuilder.push(" class='", this.className, "'");
  59. var styleStr = [];
  60. for (var key in this.style) {
  61. styleStr.push(key, ":", this.style[key]);
  62. }
  63. if (styleStr.length)
  64. stringBuilder.push(" style='", styleStr.join(""), "'");
  65. stringBuilder.push(">");
  66. }
  67. if (this.textContent) {
  68. stringBuilder.push(this.textContent);
  69. }
  70. if (this.type != "fragment") {
  71. stringBuilder.push("</", this.type, ">");
  72. }
  73. return stringBuilder.join("");
  74. };
  75. var simpleDom = {
  76. createTextNode: function(textContent, element) {
  77. return escapeHTML(textContent);
  78. },
  79. createElement: function(type) {
  80. return new Element(type);
  81. },
  82. createFragment: function() {
  83. return new Element("fragment");
  84. }
  85. };
  86. var SimpleTextLayer = function() {
  87. this.config = {};
  88. this.dom = simpleDom;
  89. };
  90. SimpleTextLayer.prototype = TextLayer.prototype;
  91. var highlight = function(el, opts, callback) {
  92. var m = el.className.match(/lang-(\w+)/);
  93. var mode = opts.mode || m && ("ace/mode/" + m[1]);
  94. if (!mode)
  95. return false;
  96. var theme = opts.theme || "ace/theme/textmate";
  97. var data = "";
  98. var nodes = [];
  99. if (el.firstElementChild) {
  100. var textLen = 0;
  101. for (var i = 0; i < el.childNodes.length; i++) {
  102. var ch = el.childNodes[i];
  103. if (ch.nodeType == 3) {
  104. textLen += ch.data.length;
  105. data += ch.data;
  106. } else {
  107. nodes.push(textLen, ch);
  108. }
  109. }
  110. } else {
  111. data = el.textContent;
  112. if (opts.trim)
  113. data = data.trim();
  114. }
  115. highlight.render(data, mode, theme, opts.firstLineNumber, !opts.showGutter, function (highlighted) {
  116. dom.importCssString(highlighted.css, "ace_highlight");
  117. el.innerHTML = highlighted.html;
  118. var container = el.firstChild.firstChild;
  119. for (var i = 0; i < nodes.length; i += 2) {
  120. var pos = highlighted.session.doc.indexToPosition(nodes[i]);
  121. var node = nodes[i + 1];
  122. var lineEl = container.children[pos.row];
  123. lineEl && lineEl.appendChild(node);
  124. }
  125. callback && callback();
  126. });
  127. };
  128. highlight.render = function(input, mode, theme, lineStart, disableGutter, callback) {
  129. var waiting = 1;
  130. var modeCache = EditSession.prototype.$ace_modes;
  131. if (typeof theme == "string") {
  132. waiting++;
  133. config.loadModule(['theme', theme], function(m) {
  134. theme = m;
  135. --waiting || done();
  136. });
  137. }
  138. var modeOptions;
  139. if (mode && typeof mode === "object" && !mode.getTokenizer) {
  140. modeOptions = mode;
  141. mode = modeOptions.path;
  142. }
  143. if (typeof mode == "string") {
  144. waiting++;
  145. config.loadModule(['mode', mode], function(m) {
  146. if (!modeCache[mode] || modeOptions)
  147. modeCache[mode] = new m.Mode(modeOptions);
  148. mode = modeCache[mode];
  149. --waiting || done();
  150. });
  151. }
  152. function done() {
  153. var result = highlight.renderSync(input, mode, theme, lineStart, disableGutter);
  154. return callback ? callback(result) : result;
  155. }
  156. return --waiting || done();
  157. };
  158. highlight.renderSync = function(input, mode, theme, lineStart, disableGutter) {
  159. lineStart = parseInt(lineStart || 1, 10);
  160. var session = new EditSession("");
  161. session.setUseWorker(false);
  162. session.setMode(mode);
  163. var textLayer = new SimpleTextLayer();
  164. textLayer.setSession(session);
  165. Object.keys(textLayer.$tabStrings).forEach(function(k) {
  166. if (typeof textLayer.$tabStrings[k] == "string") {
  167. var el = simpleDom.createFragment();
  168. el.textContent = textLayer.$tabStrings[k];
  169. textLayer.$tabStrings[k] = el;
  170. }
  171. });
  172. session.setValue(input);
  173. var length = session.getLength();
  174. var outerEl = simpleDom.createElement("div");
  175. outerEl.className = theme.cssClass;
  176. var innerEl = simpleDom.createElement("div");
  177. innerEl.className = "ace_static_highlight" + (disableGutter ? "" : " ace_show_gutter");
  178. innerEl.style["counter-reset"] = "ace_line " + (lineStart - 1);
  179. for (var ix = 0; ix < length; ix++) {
  180. var lineEl = simpleDom.createElement("div");
  181. lineEl.className = "ace_line";
  182. if (!disableGutter) {
  183. var gutterEl = simpleDom.createElement("span");
  184. gutterEl.className ="ace_gutter ace_gutter-cell";
  185. gutterEl.textContent = "";
  186. lineEl.appendChild(gutterEl);
  187. }
  188. textLayer.$renderLine(lineEl, ix, false);
  189. lineEl.textContent += "\n";
  190. innerEl.appendChild(lineEl);
  191. }
  192. outerEl.appendChild(innerEl);
  193. return {
  194. css: baseStyles + theme.cssText,
  195. html: outerEl.toString(),
  196. session: session
  197. };
  198. };
  199. module.exports = highlight;
  200. module.exports.highlight = highlight;
  201. }); (function() {
  202. window.ace_require(["ace/ext/static_highlight"], function(m) {
  203. if (typeof module == "object" && typeof exports == "object" && module) {
  204. module.exports = m;
  205. }
  206. });
  207. })();