diff --git a/js/JavaScriptParser.js b/js/JavaScriptParser.js index e7e82c7b4..babfc0b6f 100644 --- a/js/JavaScriptParser.js +++ b/js/JavaScriptParser.js @@ -21,13 +21,23 @@ var JavaScriptParser = function(options) { // Parse a string of JavaScript code or JSON and return the parse tree as a wikitext parse tree JavaScriptParser.prototype.parse = function(type,code) { - // Get the parse tree - var parseTree = esprima.parse(code,{ - tokens: true, - range: true - }), + var parseTree, result = [], t,endLastToken = 0; + // Try to parse the code + try { + parseTree = esprima.parse(code,{tokens: true,range: true}); + } catch(ex) { + // Return a helpful error if the parse failed + return new WikiTextParseTree([ + Renderer.ElementNode("pre",{"class": "javascript-source"},[ + Renderer.TextNode(code.substring(0,ex.index)), + Renderer.ErrorNode(ex), + Renderer.TextNode(code.substring(ex.index)) + ]) + ],new Dependencies(),this.store); + } + // Render the tokens with the appropriate class for(t=0; t endLastToken) { diff --git a/js/Renderer.js b/js/Renderer.js index f55f84954..62e18c8c9 100644 --- a/js/Renderer.js +++ b/js/Renderer.js @@ -423,6 +423,17 @@ RawNode.prototype.renderInDom = function(domNode) { domNode.appendChild(div); }; +/* +Static method to construct an error message +*/ +var ErrorNode = function(text) { + return new ElementNode("span",{ + "class": "tw-error" + },[ + new TextNode(text) + ]); +}; + /* Static method to construct a label */ @@ -492,6 +503,7 @@ var Renderer = { ElementNode: ElementNode, TextNode: TextNode, EntityNode: EntityNode, + ErrorNode: ErrorNode, LabelNode: LabelNode, SplitLabelNode: SplitLabelNode, SliderNode: SliderNode diff --git a/tiddlywiki5/styles.css b/tiddlywiki5/styles.css index 878fcc8fb..39f5610c3 100644 --- a/tiddlywiki5/styles.css +++ b/tiddlywiki5/styles.css @@ -107,6 +107,20 @@ a.tw-slider-label::after { content: "\00a0\27a4"; } +.tw-error { + background-color: #B94A48; + padding: 2px 4px 3px; + font-family: Helvetica, Arial, sans-serif; + font-size: 11px; + font-weight: bold; + font-style: normal; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + .label { text-transform: uppercase; font-weight: bold; diff --git a/tiddlywiki5/tiddlers/Introduction.tid b/tiddlywiki5/tiddlers/Introduction.tid index 13471eef2..7a49c16f0 100644 --- a/tiddlywiki5/tiddlers/Introduction.tid +++ b/tiddlywiki5/tiddlers/Introduction.tid @@ -8,6 +8,7 @@ Some useful tiddlers for feature testing: * ClockTiddler showing automatic refreshing of tiddlers * ImageTests showing different ways of embedding images * SampleData showing how JSON tiddlers are handled +* SampleJavaScript and SampleJavaScriptWithError showing how JavaScript code is displayed * VideoTests showing how different online video formats can be embedded * SliderTests showing how sliders work diff --git a/tiddlywiki5/tiddlers/SampleJavaScript.tid b/tiddlywiki5/tiddlers/SampleJavaScript.tid new file mode 100644 index 000000000..5c9f8d7fd --- /dev/null +++ b/tiddlywiki5/tiddlers/SampleJavaScript.tid @@ -0,0 +1,9 @@ +title: SampleJavaScript +type: application/javascript + +/* +This is an example JavaScript file +*/ +function myFunction(param) { + return param * Math.PI; // Perform a calculation +} diff --git a/tiddlywiki5/tiddlers/SampleJavaScriptWithError.tid b/tiddlywiki5/tiddlers/SampleJavaScriptWithError.tid new file mode 100644 index 000000000..7048b060a --- /dev/null +++ b/tiddlywiki5/tiddlers/SampleJavaScriptWithError.tid @@ -0,0 +1,13 @@ +title: SampleJavaScriptWithError +type: application/javascript + +/* +This is an example JavaScript file +*/ +function myFunction(param) { + if(=) { // An error + param = param/17; + } + return param * Math.PI; // Perform a calculation +} +