root/lang/javascript/vimperator-plugins/trunk/maine_coon.js

Revision 37868, 15.1 kB (checked in by anekos, 2 months ago)

version++

Line 
1/*
2Copyright (c) 2008-2010, anekos.
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without modification,
6are permitted provided that the following conditions are met:
7
8    1. Redistributions of source code must retain the above copyright notice,
9       this list of conditions and the following disclaimer.
10    2. Redistributions in binary form must reproduce the above copyright notice,
11       this list of conditions and the following disclaimer in the documentation
12       and/or other materials provided with the distribution.
13    3. The names of the authors may not be used to endorse or promote products
14       derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25THE POSSIBILITY OF SUCH DAMAGE.
26
27
28###################################################################################
29# http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license       #
30# に参考になる日本語訳がありますが、有効なのは上記英文となります。                #
31###################################################################################
32
33*/
34
35let PLUGIN_INFO =
36<VimperatorPlugin>
37  <name>Maine Coon</name>
38  <name lang="ja">メインクーン</name>
39  <description>Make the screen larger</description>
40  <description lang="ja">なるべくでかい画面で使えるように</description>
41  <version>2.5.2</version>
42  <author mail="anekos@snca.net" homepage="http://d.hatena.ne.jp/nokturnalmortum/">anekos</author>
43  <minVersion>2.3</minVersion>
44  <maxVersion>2.4</maxVersion>
45  <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/maine_coon.js</updateURL>
46  <license>new BSD License (Please read the source code comments of this plugin)</license>
47  <license lang="ja">修正BSDライセンス (ソースコードのコメントを参照してください)</license>
48  <detail><![CDATA[
49    == Requires ==
50      _libly.js
51    == Options ==
52      mainecoon:
53        Possible values
54          c:
55            Hide caption-bar
56          a:
57            Hide automatically command-line
58          f:
59            Fullscreeen
60          C:
61            Hide caption-bar
62            If window is maximized, then window maximize after window is hid.
63          m:
64            Displays the message to command-line.
65            (e.g. "Yanked http://..." "-- CARET --")
66          l:
67            Large mode (Hide status line)
68          u:
69            Displays the message of current page URL when page is loaded.
70        >||
71          :set mainecoon=ac
72        ||<
73        The default value of this option is "amu".
74        === note ===
75          The C and c options probably are supported on some OSs only.
76    == Global Variables ==
77      maine_coon_targets:
78        Other elements IDs that you want to hide.
79        let g:maine_coon_targets = "sidebar-2 sidebar-2-splitter"
80      maine_coon_default:
81        The default value of 'mainecoon' option.
82        >||
83          let g:maine_coon_default = "ac"
84        ||<
85      maine_coon_style:
86        The Style for message output.
87        >||
88          let g:maine_coon_style = "border: 1px solid pink; padding: 3px; color: pink; background: black; font: 18px/1 sans-serif;"
89        ||<
90    == Example ==
91      === The mapping for large mode (l) ===
92        >||
93          :noremap <silent> s :set mainecoon!=l<CR>
94        ||<
95    == Thanks ==
96      snaka72 (hidechrome part):
97        http://vimperator.g.hatena.ne.jp/snaka72/20090106/1231262955
98    == Maine Coon ==
99      http://en.wikipedia.org/wiki/Maine_Coon
100  ]]></detail>
101  <detail lang="ja"><![CDATA[
102    == Requires ==
103      _libly.js
104    == Options ==
105      mainecoon:
106        以下の文字の組み合わせを指定します。
107          c:
108            キャプションバーを隠す
109          a:
110            自動でコマンドラインを隠す
111          f:
112            フルスクリーン
113          C:
114            キャプションバーを隠す
115            ウィンドウが最大化されているときは、隠したあとに最大化し直します
116          m:
117            コマンドラインへのメッセージを表示します。
118            ("Yanked http://..." "-- CARET --" など)
119          l:
120            ラージモード (Hide status line)
121          u:
122            ページが読み込まれたときにURLをポップアップ表示する。
123        "c" と "f" の併用は意味がありません。
124        >||
125          :set mainecoon=ac
126        ||<
127        デフォルト値は "amu"
128        === 備考 ===
129          C c オプションはいくつかの OS でのみ有効です。多分。
130    == Global Variables ==
131      maine_coon_targets:
132        フルスクリーン時にの非表示にしたい要素のIDを空白区切りで指定します。
133        >||
134          let g:maine_coon_targets = "sidebar-2 sidebar-2-splitter"
135        ||<
136      maine_coon_default:
137        オプションのデフォルト値を設定します。
138        >||
139          let g:maine_coon_default = "ac"
140        ||<
141      maine_coon_style:
142        メッセージ表示のスタイル指定です。
143        >||
144          let g:maine_coon_style = "border: 1px solid pink; padding: 3px; color: pink; background: black; font: 18px/1 sans-serif;"
145        ||<
146    == Example ==
147      === ラージモード(l) 用のマッピング ===
148        >||
149          :noremap <silent> s :set mainecoon!=l<CR>
150        ||<
151    == Thanks ==
152      snaka72 (hidechrome part):
153        http://vimperator.g.hatena.ne.jp/snaka72/20090106/1231262955
154    == メインクーン ==
155      http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%AF%E3%83%BC%E3%83%B3
156  ]]></detail>
157</VimperatorPlugin>;
158
159let tagetIDs = (liberator.globalVariables.maine_coon_targets || '').split(/\s+/);
160let elemStyle =
161  (
162    liberator.globalVariables.maine_coon_style
163    ||
164    libly.$U.toStyleText({
165      height: '1em',
166      margin: 0,
167      padding: '3px',
168      border: '1px solid #b3b3b3',
169      borderLeft: 0,
170      borderBottom: 0,
171      textAlign: 'left',
172      color: '#000',
173      font: '11px/1 sans-serif',
174      background: '#ebebeb'
175    })
176  );
177
178
179(function () {
180
181  let U = libly.$U;
182  let mainWindow = document.getElementById('main-window');
183  let messageBox = document.getElementById('liberator-message');
184
185  function s2b (s, d) !!((!/^(\d+|false)$/i.test(s)|parseInt(s)|!!d*2)&1<<!s);
186
187  function hideTargets (hide) {
188    tagetIDs.forEach(
189      function (id)
190        let (elem = document.getElementById(id))
191          (elem && (elem.collapsed = hide))
192    );
193  }
194
195  function getWindowInfo () {
196      let box = mainWindow.boxObject;
197      let x = screenX < 0 ? 0 : screenX;
198      let y = screenY < 0 ? 0 : screenY;
199      let width =  box.width;
200      let height = box.height;
201      let adjustHeight = box.screenY - y; // maybe caption height?
202      let adjustWidth  = (box.screenX - x) * 2;
203      return {
204        x: x,
205        y: y,
206        width: width,
207        height: height,
208        adjustHeight: adjustHeight,
209        adjustWidth: adjustWidth,
210        state: window.windowState
211      };
212  }
213
214  function delay (f, t)
215    setTimeout(f, t || 0);
216
217  function refreshWindow () {
218    // FIXME
219    let old = window.outerWidth;
220    window.outerWidth = old + 1;
221    window.outerWidth = old;
222  }
223
224  function getHideChrome ()
225    s2b(mainWindow.getAttribute('hidechrome'), false);
226
227  function hideChrome (hide, maximize) {
228    hide = !!hide;
229    if (getHideChrome() === hide)
230      return;
231    if (hide)
232      windowInfo = getWindowInfo();
233    mainWindow.setAttribute('hidechrome', hide);
234    delay(function () {
235      window.outerWidth = windowInfo.width;
236      window.outerHeight = windowInfo.height + windowInfo.adjustHeight;
237    });
238    if (maximize && windowInfo.state == window.STATE_MAXIMIZED)
239      delay(function () window.maximize());
240    refreshWindow();
241  }
242
243  function setFullscreen (full) {
244    full = !!full;
245    if (full === !!window.fullScreen)
246      return;
247    window.fullScreen = full;
248    delay(function () {
249      hideTargets(full);
250      document.getElementById('status-bar').setAttribute('moz-collapsed',
251                                                         options.get('mainecoon').has('l'));
252      document.getElementById('navigator-toolbox').collapsed = full;
253      if (!full)
254        window.maximize();
255    }, 1000); // FIXME
256  }
257
258  function nothing (value)
259    (value === undefined);
260
261  function important (style)
262    style.replace(/(!important)?\s*;/g, ' !important;');
263
264  let echo = (function () {
265    let time = 40;
266    let remove;
267
268    return function (message) {
269      if (remove)
270        remove();
271      let doc = window.content.document;
272
273      // XXX 中身なしっぽいときは、あきらめる。代替手段が欲しい
274      if (!doc.body)
275        return;
276
277      let style =
278        'opacity: 1; ' +
279        important(
280          highlight.get('StatusLine').value +
281          U.toStyleText({
282            position: 'fixed',
283            zIndex: 1000,
284            left: 0,
285            bottom: 0,
286            MozBoxSizing: 'content-box',
287          }) +
288          elemStyle
289        );
290      let elem = U.xmlToDom(<div id="liberator_maine_coon" style={style}>{message}</div>, doc);
291      doc.body.appendChild(elem);
292      let count = time;
293      let handle = setInterval(function () {
294        try {
295          if (count <= 0) {
296            if (remove)
297              remove();
298          } else {
299            elem.style.MozOpacity = count / time;
300          }
301          count--;
302        } catch (e) { // XXX ほんとは DOM 関連だけキャッチしたい
303          remove(true);
304          liberator.log(e);
305        }
306      }, 100);
307      remove = function (noDOM) {
308        if (!noDOM)
309          doc.body.removeChild(elem);
310        clearInterval(handle);
311        remove = null;
312      };
313    };
314  })();
315
316  let setAutoHideCommandLine = (function () {
317    let hiddenNodes = [];
318
319    return function (hide) {
320      hide = !!hide;
321
322      if (hide === autoHideCommandLine)
323        return;
324
325      autoHideCommandLine = hide;
326
327      if (hide) {
328        let cs = messageBox.parentNode.childNodes;
329        hiddenNodes = [];
330        for (let i = 0, l = cs.length, c; i < l; i++) {
331          c = cs[i];
332          if (c.id == 'liberator-commandline')
333            continue;
334          let style = window.getComputedStyle(c, '');
335          hiddenNodes.push([c, c.collapsed, style.display]);
336          if (c.id != 'liberator-message')
337            c.style.display = 'none';
338          c.collapsed = true;
339        }
340      } else {
341        hiddenNodes.forEach(function ([c, v, d]) [c.collapsed, c.style.display] = [v, d]);
342      }
343    }
344  })();
345
346
347  let useEcho = false;
348  let autoHideCommandLine = false;
349  let displayURL = true;
350  let inputting = false;
351  let windowInfo = {};
352
353  {
354    let a = liberator.globalVariables.maine_coon_auto_hide;
355    let d = liberator.globalVariables.maine_coon_default;
356
357    let def = !nothing(d) ? d :
358              nothing(a)  ? 'amu' :
359              s2b(a)      ? 'amu' :
360              'm';
361
362    autocommands.add(
363      'VimperatorEnter',
364      /.*/,
365      function () delay(function () options.get('mainecoon').set(def), 1000)
366    );
367  }
368
369
370  {
371    let last;
372    messageBox.watch('value', function (name, oldValue, newValue) {
373      try {
374        if (autoHideCommandLine
375        && useEcho
376        && /\S/.test(newValue)
377        && messageBox.collapsed
378        && last != newValue
379        && newValue != 'Press ENTER or type command to continue') {
380          echo(newValue);
381        }
382      } catch (e) {
383        liberator.reportError(e);
384      }
385      last = newValue;
386      return newValue;
387    });
388  }
389
390  {
391    // for multiline input
392    let cmdline = document.getElementById("liberator-commandline");
393    messageBox.inputField.__defineGetter__("scrollWidth", function() {
394        return cmdline.clientWidth;
395    });
396  }
397
398  U.around(commandline, 'input', function (next, args) {
399    let result = next();
400    inputting = true;
401    return result;
402  });
403
404  U.around(commandline, 'open', function (next, args) {
405    messageBox.collapsed = false;
406    return next();
407  });
408
409  U.around(commandline, 'close', function (next, args) {
410    if (autoHideCommandLine && !inputting)
411      messageBox.collapsed = true;
412    return next();
413  });
414
415  U.around(commandline._callbacks.submit, modes.EX, function (next, args) {
416    let r = next();
417    if (autoHideCommandLine && !inputting && !(modes.extended & modes.OUTPUT_MULTILINE))
418      commandline.close();
419    return r;
420  });
421
422  let (callback = function (next) (inputting = false, next())) {
423    U.around(commandline._callbacks.submit, modes.PROMPT, callback);
424    U.around(commandline._callbacks.cancel, modes.PROMPT, callback);
425  }
426
427  events.addSessionListener(
428    document.getElementById("appcontent"),
429    "DOMContentLoaded",
430    function (event) {
431      let doc = event.originalTarget;
432      if (doc instanceof HTMLDocument && !doc.defaultView.frameElement && displayURL)
433        echo(doc.location.href);
434    },
435    true
436  );
437
438  options.add(
439    ['mainecoon'],
440    'Make big screen like a Maine Coon',
441    'charlist',
442    '',
443    {
444      setter: function (value) {
445        function has (c)
446          (value.indexOf(c) >= 0);
447
448        document.getElementById('status-bar').setAttribute('moz-collapsed', has('l'));
449
450        if (has('f')) {
451          hideChrome(false);
452          delay(function () setFullscreen(true));
453        } else if (has('c')) {
454          setFullscreen(false);
455          delay(function () hideChrome(true));
456        } else if (has('C')) {
457          setFullscreen(false);
458          delay(function () hideChrome(true, true));
459        } else {
460          hideChrome(false);
461          delay(function () setFullscreen(false));
462        }
463
464        setAutoHideCommandLine(has('a'));
465        useEcho = has('m');
466        displayURL = has('u');
467
468        return value;
469      },
470      completer: function (context, args) {
471        context.title = ['Value', 'Description'];
472        context.completions = [
473          ['c', 'Hide caption bar'],
474          ['f', 'Fullscreen'],
475          ['a', 'Hide automatically command-line'],
476          ['C', 'Hide caption bar (maximize)'],
477          ['m', 'Displays the message to command-line'],
478          ['l', 'Large mode. Hide status-line'],
479          ['u', 'Displays the message of current page URL when page is loaded.'],
480        ];
481      },
482      validater: function (value) /^[cfa]*$/.test(value)
483    }
484  );
485
486  // XXX obsolete
487  commands.addUserCommand(
488    ['fullscreen', 'fs'],
489    'Toggle fullscreen mode',
490    function () setFullscreen(!window.fullScreen),
491    {},
492    true
493  );
494
495})();
496
497// vim:sw=2 ts=2 et si fdm=marker:
Note: See TracBrowser for help on using the browser.