[483] | 1 | define([ |
---|
| 2 | "dojo/_base/declare", |
---|
| 3 | "dojo/_base/lang", |
---|
| 4 | "dojo/_base/array", |
---|
| 5 | "dojo/query", |
---|
| 6 | "dojo/dom-class", |
---|
| 7 | "dojo/dom-attr", |
---|
| 8 | "dojo/dom-construct", |
---|
| 9 | "dojo/request/xhr", |
---|
| 10 | "dijit/_Widget", |
---|
| 11 | "dijit/_Templated", |
---|
| 12 | "dojox/highlight" |
---|
| 13 | ], function(declare, lang, array, query, domClass, domAttr, domConstruct, xhr, _Widget, _Templated){ |
---|
| 14 | |
---|
| 15 | return declare("dojox.highlight.widget.Code", [_Widget, _Templated],{ |
---|
| 16 | // summary: |
---|
| 17 | // A simple source code formatting widget that adds line numbering, alternating line colors |
---|
| 18 | // and line range support on top of dojox.highlight module. |
---|
| 19 | |
---|
| 20 | url: "", |
---|
| 21 | range:null, |
---|
| 22 | style:"", |
---|
| 23 | listType:"1", |
---|
| 24 | lang:"", |
---|
| 25 | |
---|
| 26 | // Note: If more control over formatting is required, the order list items can be replaced |
---|
| 27 | // with a table implementation instead... exercise is left for those that need it... |
---|
| 28 | templateString: |
---|
| 29 | '<div class="formatted" style="${style}">'+ |
---|
| 30 | '<div class="titleBar"></div>'+ |
---|
| 31 | '<ol type="${listType}" dojoAttachPoint="codeList" class="numbers"></ol>' + |
---|
| 32 | '<div style="display:none" dojoAttachPoint="containerNode"></div>' + |
---|
| 33 | '</div>', |
---|
| 34 | |
---|
| 35 | postCreate: function(){ |
---|
| 36 | this.inherited(arguments); |
---|
| 37 | if(this.url){ |
---|
| 38 | xhr(this.url, {}).then(lang.hitch(this,"_populate"), lang.hitch(this,"_loadError")); |
---|
| 39 | // load from a url |
---|
| 40 | /*dojo.xhrGet({ |
---|
| 41 | url: this.url, |
---|
| 42 | // then poopulate: |
---|
| 43 | load: lang.hitch(this,"_populate"), |
---|
| 44 | error: lang.hitch(this,"_loadError") |
---|
| 45 | });*/ |
---|
| 46 | }else{ |
---|
| 47 | // or just populate from our internal content |
---|
| 48 | this._populate(this.containerNode.innerHTML); |
---|
| 49 | } |
---|
| 50 | }, |
---|
| 51 | |
---|
| 52 | _populate: function(data){ |
---|
| 53 | // put the content in a common node |
---|
| 54 | this.containerNode.innerHTML = |
---|
| 55 | "<pre><code class='" + this.lang + "'>" + |
---|
| 56 | data.replace(/\</g,"<") + |
---|
| 57 | "</code></pre>"; |
---|
| 58 | // highlight it |
---|
| 59 | query("pre > code",this.containerNode).forEach(dojox.highlight.init); |
---|
| 60 | // FIXME: in ie7, the innerHTML in a real <pre> isn't split by \n's ? |
---|
| 61 | // split the content into lines |
---|
| 62 | var lines = this.containerNode.innerHTML.split("\n"); |
---|
| 63 | array.forEach(lines,function(line,i){ |
---|
| 64 | // setup all the lines of the content as <li>'s |
---|
| 65 | var li = domConstruct.create('li'); |
---|
| 66 | // add some style sugar: |
---|
| 67 | domClass.add(li, (i % 2 !== 0 ? "even" : "odd")); |
---|
| 68 | line = "<pre><code>" + line + " </code></pre>"; |
---|
| 69 | line = line.replace(/\t/g," "); |
---|
| 70 | li.innerHTML = line; |
---|
| 71 | this.codeList.appendChild(li); |
---|
| 72 | },this); |
---|
| 73 | // save our data |
---|
| 74 | this._lines = query("li",this.codeList); |
---|
| 75 | this._updateView(); |
---|
| 76 | }, |
---|
| 77 | |
---|
| 78 | // FIXME: user _setRangeAttr pattern? so you can code.set('range', [1, 100]); |
---|
| 79 | setRange: function(/* Array */range){ |
---|
| 80 | // summary: |
---|
| 81 | // update the view to a new passed range |
---|
| 82 | if(range instanceof Array){ |
---|
| 83 | this.range = range; |
---|
| 84 | this._updateView(); |
---|
| 85 | } |
---|
| 86 | }, |
---|
| 87 | |
---|
| 88 | _updateView: function(){ |
---|
| 89 | // summary: |
---|
| 90 | // set the list to the current range |
---|
| 91 | if(this.range){ |
---|
| 92 | var r = this.range; |
---|
| 93 | this._lines |
---|
| 94 | // hide them all |
---|
| 95 | .style({ display:"none" }) |
---|
| 96 | .filter(function(n,i){ |
---|
| 97 | // remove nodes out of range |
---|
| 98 | return (i + 1 >= r[0] && i + 1 <= r[1]); |
---|
| 99 | }) |
---|
| 100 | // set them visible again |
---|
| 101 | .style({ display:"" }) |
---|
| 102 | ; |
---|
| 103 | // set the "start" attribute on the OL so numbering works |
---|
| 104 | domAttr.set(this.codeList,"start",r[0]); |
---|
| 105 | } |
---|
| 106 | }, |
---|
| 107 | |
---|
| 108 | _loadError: function(error){ |
---|
| 109 | // summary: |
---|
| 110 | // a generic error handler for the url="" |
---|
| 111 | console.warn("loading: ", this.url, " FAILED", error); |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | }); |
---|
| 115 | |
---|
| 116 | }); |
---|