aboutsummaryrefslogtreecommitdiffstats
path: root/scroll_div.js
blob: 7d713103e922d477118190985424f99f589f8420 (plain)
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
(function () {

  let re = /auto|scroll/i;

  function isScrollable (e, doc) {
    try {
      let s = doc.defaultView.getComputedStyle(e, '');
      if (e.scrollHeight <= e.clientHeight)
        return;
      for each (let n in ['overflow', 'overflowY', 'overflowX']) {
        if (s[n] && s[n].match(re))
          return true;
      }
    } catch (e) {
      liberator.log(e);
    }
  }

  // FIXME
  function flashElement (e, doc) {
    var indicator = doc.createElement("div");
    indicator.id = "liberator-frame-indicator";
    // NOTE: need to set a high z-index - it's a crapshoot!
    var style = "background-color: red; opacity: 0.5; z-index: 999;" +
                "position: fixed; top: 0; bottom: 0; left: 0; right: 0;";
    indicator.setAttribute("style", style);
    e.appendChild(indicator);

    // remove the frame indicator
    setTimeout(function () { e.removeChild(indicator); }, 500);
  }

  // スクロール可能な要素のリストを返す
  function scrollableElements () {
    let result = [];
    let doc = content.document;

    // var r = doc.evaluate("//div[contains(@style, 'overflow')]", doc, null, 7, null)
    // for (var i = 0; i < r.snapshotLength; i++) {
    //   r.snapshotItem(i).scrollTop += dy;
    // }

    var r = doc.evaluate("//div", doc, null, 7, null)
    for (var i = 0; i < r.snapshotLength; i++) {
      let e = r.snapshotItem(i);
      if (isScrollable(e, doc))
        result.push(e);
    }

    liberator.log('scrollableElements: ' + result.length);
    return result;
  }

  // スクロール対象を変更
  function shiftScrollElement (n) {
    let idx = content.document.__div_scroller_index || 0;
    let es = scrollableElements();
    idx += (n || 1);
    if (idx < 0)
      idx = es.length - 1;
    if (idx >= es.length)
      idx = 0;
    content.document.__div_scroller_index = idx;
  }

  // 現在のスクロール対象を返す
  function currentElement () {
    let es = scrollableElements();
    let idx = content.document.__div_scroller_index || 0;
    return es[idx];
  }

  // スクロールする
  function scroll (dy) {
    let elem = currentElement();
    if (elem)
      elem.scrollTop += dy;
    //for each (let elem in scrollableElements()) {
    //  liberator.log(elem.tagName);
    //  liberator.log(elem.id);
    //  elem.scrollTop += dy;
    //}
  }

  liberator.mappings.addUserMap(
    [liberator.modes.NORMAL], 
    ['<Leader>j'],
    'Scroll down',
    function () scroll(30)
  );

  liberator.mappings.addUserMap(
    [liberator.modes.NORMAL], 
    ['<Leader>k'],
    'Scroll up',
    function () scroll(-30)
  );

  liberator.mappings.addUserMap(
    [liberator.modes.NORMAL], 
    [']d'],
    'Shift Scroll Element',
    function () shiftScrollElement(1)
  );

  liberator.mappings.addUserMap(
    [liberator.modes.NORMAL], 
    ['[d'],
    'Shift Scroll Element',
    function () shiftScrollElement(-1)
  );


})();