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