genki (owner)

Revisions

gist: 132009 Download_button fork
public
Public Clone URL: git://gist.github.com/132009.git
Embed All Files: show embed
gdol.js #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
* s21g GoogleDocs Outliner
*
* (C) 2009 Genki Takiuchi <genki{at}s21g{dot}com>
*/
function gdol_cleanup(){
  var ol = document.getElementById("outline");
  if(ol){
    clearInterval(ol.timer);
    ol.doc.body.style.marginRight = '0px';
    ol.parentNode.removeChild(ol);
  }
}
function gdol_toggle(){
  var ol = document.getElementById('outline');
  if(ol.hidden){
    ol.style.height = '';
    ol.style.bottom = '10px';
  }else{
    ol.style.bottom = '';
    ol.style.height = '16px';
  }
  ol.hidden = !ol.hidden;
  ol.updateMargin();
}
function gdol_focus(id){
  var frame = document.getElementById("wys_frame");
  var doc = frame.contentDocument;
  var ol = document.getElementById("outline");
  var elm = ol.list[id];
  frame.contentWindow.scrollTo(0, elm.offsetTop);
}
(function(){
  var lengthOf = function(str){
    try{return str.replace(/¥s¥n/g, '').length;}
    catch(e){return 0;}
  };
  function parse(elm, html, list){
    if(elm.id == "outline") return;
    if(!elm.tagName){
      if(html.marker){
        var text = elm.textContent || elm.innerText;
        html[html.marker].add(lengthOf(text));
      }
      return;
    }
    var m = elm.tagName.match(/h([1-6])/i);
    var count = 0;
    if(m){
      var lv = m[1];
      for(var l=1; l<lv; ++l){
        html.push("&nbsp;&nbsp;");
      }
      html.push("-&nbsp;");
      html.push('<a href="javascript:gdol_focus(', list.length, ')">');
      html.push(elm.innerHTML);
      html.push('</a>');
      html.marker = html.length;
      html.push({
        count:0,
        toString:function(){
          return ["<small>", this.count, "</small>"].join("");
        },
        parent:(lv > 1 ? html.stack[lv - 2] : null),
        add:function(c){this.count += c; if(this.parent) this.parent.add(c);}
      });
      html.push('<br />');
      html.stack = html.stack.slice(0, lv - 1);
      html.stack[lv - 1] = html[html.marker];
      list.push(elm);
    }
    var elms = elm.childNodes;
    for(var i=0,l=elms.length; i<l; ++i){
      parse(elms[i], html, list);
    }
    if(html.marker){
      html[html.marker].add(count);
    }
  }
  gdol_cleanup();
  var ol = document.getElementById("outline");
  ol = document.createElement("div");
  ol.id = "outline";
  ol.style.position = "absolute";
  ol.style.top = "130px";
  ol.style.right = "20px";
  ol.style.padding = "5px";
  ol.style.fontSize = "12px";
  ol.style.background = "#FFF";
  ol.style.border = "1px solid #000";
  ol.style.overflowY = "scroll";
  ol.style.bottom = "10px";
  document.body.appendChild(ol);
 
  var refresh = function(){
    var html = [];
    var frame = document.getElementById("wys_frame");
    ol.doc = frame.contentDocument;
    ol.updateMargin = function(){
      if(ol.hidden){
        ol.doc.body.style.marginRight = '0px';
      }else{
        ol.doc.body.style.marginRight = [ol.offsetWidth + 10, 'px'].join('');
      }
    };
    ol.list = [];
    html.stack = [];
    html.push('<b><a href="javascript:gdol_toggle()">GoogleDocs Outliner</a></b>');
    html.push(' [<a href="javascript:gdol_cleanup()">X</a>]');
    html.push('<div id="gdol_list">');
    parse(ol.doc.body, html, ol.list);
    html.push('</div>&copy; 2009 <a href="http://twitter.com/takiuchi">takiuchi</a>');
    html = html.join('');
    if(html != ol.innerHTML){
      ol.innerHTML = html;
      ol.updateMargin();
    }
  };
  ol.timer = setInterval(refresh, 2000);
  refresh();
})();