From 978d32eca3d3312d70a00a10abbb0c12215f7303 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 13 Apr 2013 19:41:53 +0400 Subject: [PATCH] Create client-noconflict.html MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Is this the right way to use the static highlighter with theĀ  noconflict build? Edit as necessary. This is about as good as I can get it... loads modules from script tags makes div visible after highlighting fixes display (sort of) codeEl margin & padding 0 editor overflow auto, gutter position relative replace code element with div mode can be specified as a string mode and theme may be specified as strings This preserves the behavior of this method when specifying mode and theme as objects. It adds the ability to specify mode and theme as module paths. When specifying mode and / or theme as a module path you must provide a callback function. The callback function will receive the same value as the return value previously returned when specifying mode and theme as objects. Good stuff. multiple elements with different modes and themes The example shows multiple elements highlighted with different modes and themes all in the same page. The pre element isn't ideal. The example shows how to transfer the computed width and height of the element into its inline style so that it won't dramatically change shape and disrupt the page once it's had highlighting applied. It would probably be better to replace the elements entirely and apply sizing styles to the replacement elements but that isn't always an option. --- .../static-highlighter/client-noconflict.html | 85 +++++++++++ lib/ace/ext/static_highlight.js | 133 ++++++++++++------ 2 files changed, 176 insertions(+), 42 deletions(-) create mode 100644 demo/static-highlighter/client-noconflict.html 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 + }; + } }; });