diff --git a/demo/static-highlighter/client-noconflict.html b/demo/static-highlighter/client-noconflict.html new file mode 100644 index 00000000..80f3647a --- /dev/null +++ b/demo/static-highlighter/client-noconflict.html @@ -0,0 +1,85 @@ + + + + + Static Code highlighter using Ace + + + + + +

Client Side Syntax Highlighting

+ +

Syntax highlighting using Ace language modes and themes.

+ +
+.code { + width: 50%; + position: relative; + white-space: pre-wrap; +} + +
+ +
+function wobble (flam) {
+    return flam.wobbled = true;
+}
+// I'm not exactly sure how to
+// turn on softwrap like effects.
+var longString = 'this will not wrap ******************************************';
+
+
+
+
+// the scrollbars are from overflow auto on .ace_editor.
+
+
+ + + + + + + + diff --git a/lib/ace/ext/static_highlight.js b/lib/ace/ext/static_highlight.js index aa8c4ce6..5bfee3da 100644 --- a/lib/ace/ext/static_highlight.js +++ b/lib/ace/ext/static_highlight.js @@ -34,55 +34,104 @@ define(function(require, exports, module) { var EditSession = require("../edit_session").EditSession; var TextLayer = require("../layer/text").Text; var baseStyles = require("../requirejs/text!./static.css"); +var config = require("../config"); +/** + * Transforms a given input code snippet into HTML using the given mode + * + * @param {string} input Code snippet + * @param {string|mode} mode String specifying the mode to load such as + * `ace/mode/javascript` or, a mode loaded from `/ace/mode` + * (use 'ServerSideHiglighter.getMode'). + * @param {string|theme} theme String specifying the theme to load such as + * `ace/theme/twilight` or, a theme loaded from `/ace/theme`. + * @param {number} lineStart A number indicating the first line number. Defaults + * to 1. + * @param {boolean} disableGutter Specifies whether or not to disable the gutter. + * `true` disables the gutter, `false` enables the gutter. Defaults to `false`. + * @param {function} callback When specifying the mode or theme as a string, + * this method has no return value and you must specify a callback function. The + * callback will receive the rendered object containing the properties `html` + * and `css`. + * @returns {object} An object containing the properties `html` and `css`. + */ -/* Transforms a given input code snippet into HTML using the given mode -* -* @param {string} input Code snippet -* @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode') -* @param {string} r Code snippet -* @returns {object} An object containing: html, css -*/ - -exports.render = function(input, mode, theme, lineStart, disableGutter) { +exports.render = function(input, mode, theme, lineStart, disableGutter, callback) { lineStart = parseInt(lineStart || 1, 10); - var session = new EditSession(""); - session.setMode(mode); - session.setUseWorker(false); - - var textLayer = new TextLayer(document.createElement("div")); - textLayer.setSession(session); - textLayer.config = { - characterWidth: 10, - lineHeight: 20 - }; - - session.setValue(input); - - var stringBuilder = []; - var length = session.getLength(); - - for(var ix = 0; ix < length; ix++) { - stringBuilder.push("
"); - if (!disableGutter) - stringBuilder.push("" + (ix + lineStart) + ""); - textLayer.$renderLine(stringBuilder, ix, true, false); - stringBuilder.push("
"); + // if theme and mode are both objects return the expected object. + // preserves current behavior of giving mode and theme objects + if(typeof theme !== 'string' && typeof mode !== 'string') { + return renderer(mode, theme); } - // let's prepare the whole html - var html = "
\ -
\ - :code\ -
\ -
".replace(/:cssClass/, theme.cssClass).replace(/:code/, stringBuilder.join("")); + // if either the theme or the mode were specified as objects + // then we need to lazily load them. + + // loads or passes the specified theme module then loads the mode. + if (typeof theme == "string") { + config.loadModule(['theme', theme], function (theme) { + checkMode(theme); + }); + } else { + // if theme was given as an object pass it through. + checkMode(theme); + } + + // loads or passes the specified mode module then calls renderer + function checkMode (theme) { + if (typeof mode == "string") { + config.loadModule(['mode', mode], function (mode) { + callback(renderer(new mode.Mode(), theme)); + }); + } else { + // if mode was given as an object pass it through. + callback(renderer(mode, theme)); + } + } + + // this was previously the body of exports.render + // exports.render does the same thing it did before but now + // if you give it mode or theme as strings you must specify a callback + // which will receive the return value of renderer. + // specifying the mode or theme as a string did not work before. + function renderer (mode, theme) { + var session = new EditSession(""); + session.setMode(mode); + session.setUseWorker(false); + var textLayer = new TextLayer(document.createElement("div")); + textLayer.setSession(session); + textLayer.config = { + characterWidth: 10, + lineHeight: 20 + }; - textLayer.destroy(); + session.setValue(input); + + var stringBuilder = []; + var length = session.getLength(); + + for(var ix = 0; ix < length; ix++) { + stringBuilder.push("
"); + if (!disableGutter) + stringBuilder.push("" + (ix + lineStart) + ""); + textLayer.$renderLine(stringBuilder, ix, true, false); + stringBuilder.push("
"); + } + + // let's prepare the whole html + var html = "
\ +
\ + :code\ +
\ +
".replace(/:cssClass/, theme.cssClass).replace(/:code/, stringBuilder.join("")); - return { - css: baseStyles + theme.cssText, - html: html - }; + textLayer.destroy(); + + return { + css: baseStyles + theme.cssText, + html: html + }; + } }; });