Code.js 3.1 KB

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