diff options
author | anekos | 2008-12-03 10:08:23 +0000 |
---|---|---|
committer | anekos | 2008-12-03 10:08:23 +0000 |
commit | 5bc8635b848acdc4a80e6bd3e62fa8a263b4f7f4 (patch) | |
tree | 66259199f6ce6017ba271c761fce71b2b54faa15 | |
parent | 349971e3526f2e529c71c0ecc3f44be2716e70fd (diff) | |
download | vimperator-plugins-5bc8635b848acdc4a80e6bd3e62fa8a263b4f7f4.tar.bz2 |
フルスクリーン化などの追加
git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@25781 d0d07461-0603-4401-acd4-de1884942a52
-rw-r--r-- | stella.js | 245 |
1 files changed, 198 insertions, 47 deletions
@@ -2,7 +2,7 @@ // @name すてら // @description-ja ステータスラインに動画の再生時間などを表示する。 // @license Creative Commons Attribution-Share Alike 3.0 Unported -// @version 0.06 +// @version 0.07 // @author anekos (anekos@snca.net) // @minVersion 2.0pre // @maxVersion 2.0pre @@ -12,14 +12,19 @@ // 作成中 // // TODO -// user command -// :fetchvideo // Icons // Other video hosting websites +// auto fullscreen // -// Links: +// Link: // http://d.hatena.ne.jp/nokturnalmortum/ // +// Refs: +// http://yuichis.homeip.net/nicodai.user.html +// http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/nicontroller.js +// http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/youtubeamp.js +// Thanks! +// // License: // http://creativecommons.org/licenses/by-sa/3.0/ @@ -32,6 +37,7 @@ const ID_PREFIX = 'anekos-stela-'; const InVimperator = !!(liberator && modules && modules.liberator); + const DOUBLE_CLICK_INTERVAL = 300; // }}} @@ -120,22 +126,48 @@ (isNum(v) ? (parseInt((v / 60)) + ':' + lz(v % 60, 2)) : '??:??'); - function setWithBackup (target, values) { - let backup = target.__stella_backup = {}; + function storeStyle (target, values) { + let [style, cstyle] = [target.style, content.getComputedStyle(target, '')]; + let backup = style.__stella_backup = {}; for (let [name, value] in Iterator(values)) { - backup[name] = target[name]; - target[name] = value; + backup[name] = cstyle[name]; + style[name] = value; } - liberator.log(target.__stella_backup) } - function restoreFromBackup (target, doDelete) { - if (!target.__stella_backup) + function restoreStyle (target, doDelete) { + let style = target.style; + if (!style.__stella_backup) return; - for (let [name, value] in Iterator(target.__stella_backup)) - target[name] = value; + let backup = style.__stella_backup; + for (let name in Iterator(backup)) + style[name] = backup[name]; if (doDelete) - delete target.__stella_backup; + delete style.__stella_backup; + } + + function getElementByIdEx (id) + let (p = content.document.getElementById(id)) + (p && (p.wrappedJSObject || p)); + + function fixDoubleClick (obj, click, dblClick) { + let clicked = 0; + let original = {click: obj[click], dblClick: obj[dblClick]}; + liberator.log(original); + obj[click] = function () { + let self = this, args = arguments; + let _clicked = ++clicked; + setTimeout(function () { + if (_clicked == clicked--) + original.click.apply(self, args); + else + clicked = 0; + }, DOUBLE_CLICK_INTERVAL); + }; + obj[dblClick] = function () { + clicked = 0; + original.dblClick.apply(this, arguments); + }; } // }}} @@ -193,6 +225,12 @@ initialize: function () void null, + finalize: function () { + // 念のためフルスクリーンは解除しておく + if (this.has('fullscreen', 'rwt') && this.isValid && this.fullscreen) + this.fullscreen = false; + }, + is: function (state) (this.state == state), has: function (name, ms) @@ -222,10 +260,15 @@ get statusText () this.timeCodes, + get storage () + (content.document.__stella_storage || (content.document.__stella_storage = {})), + get timeCodes () (toTimeCode(this.currentTime) + '/' + toTimeCode(this.totalTime)), get title () undefined, + get isValid () (~buffer.URL.indexOf('http://www.nicovideo.jp/watch/')), + get volume () undefined, set volume (value) value, @@ -317,7 +360,7 @@ this.player.__stella_fullscreen = !this.player.__stella_fullscreen; if (this.fullscreen) { liberator.log('full') - setWithBackup(this.player.style, { + storeStyle(this.player, { position: 'fixed', left: '0px', top: '0px', @@ -326,7 +369,7 @@ }); } else { liberator.log('normal') - restoreFromBackup(this.player.style); + restoreStyle(this.player); } }, @@ -358,6 +401,8 @@ get totalTime () parseInt(this.player.getDuration()), + get isValid () buffer.URL.match(/^http:\/\/(?:[^.]+\.)?youtube\.com\/watch/), + get volume () parseInt(this.player.getVolume()), set volume (value) (this.player.setVolume(value), value), @@ -376,25 +421,41 @@ Player.apply(this, arguments); } + // Normal / Fullscreen + NicoPlayer.Variables = [ + ['videowindow._xscale', 100, null], + ['videowindow._yscale', 100, null], + ['videowindow._x', 6, 0], + ['videowindow._y', 65, 0], + ['controller._x', 6, -1000], + ['inputArea._x', 4, -1000], + ['controller._visible', 1, 1], + ['inputArea._visible', 1, 1], + ['waku._visible', 1, 0], + ['tabmenu._visible', 1, 0], + ['videowindow.video_mc.video.smoothing', null, 1], + ['videowindow.video_mc.video.deblocking', null, 5] + ]; + NicoPlayer.prototype = { __proto__: Player.prototype, functions: { + comment: 'rwt', currentTime: 'rw', - totalTime: 'r', - volume: 'rw', + fetch: 'x', + fileURL: '', + fullscreen: 'rwt', + id: 'r', + muted: 'rwt', + pause: 'x', play: 'x', - playOrPause: 'x', playEx: 'x', - pause: 'x', - muted: 'rwt', + playOrPause: 'x', repeating: 'rwt', - comment: 'rwt', title: 'r', - fileURL: '', - id: 'r', - fetch: 'x', - title: 'r' + totalTime: 'r', + volume: 'rw' }, icon: 'http://www.nicovideo.jp/favicon.ico', @@ -402,11 +463,88 @@ get comment () this.player.ext_isCommentVisible(), set comment (value) (this.player.ext_setCommentVisible(value), value), + get playerContainer () getElementByIdEx('flvplayer_container'), + get currentTime () parseInt(this.player.ext_getPlayheadTime()), set currentTime (value) (this.player.ext_setPlayheadTime(value), value), get fileExtension () '.flv', + get fullscreen () !!this.storage.fullscreen, + set fullscreen (value) { + let self = this; + value = !!value; + + if (this.storage.fullscreen === value) + return; + + this.storage.fullscreen = value; + + let variablesSetter = function () { + NicoPlayer.Variables.forEach(function ([name, normal, full]) { + let v = value ? full : normal; + if (v !== null) + self.player.SetVariable(name, v); + }); + }; + + let doc = content.document.wrappedJSObject; + let win = content.wrappedJSObject; + let player = getElementByIdEx('flvplayer'); + + win.toggleMaximizePlayer(); + + if(value) { + let f = function () { + let viewer = {w: 544, h: 384}; + let screen = { + w: content.innerWidth, + h: content.innerHeight + }; + let scale = { + w: Math.max(1, screen.w / viewer.w), + h: Math.max(1, screen.h / viewer.h) + }; + scale.v = Math.min(scale.w, scale.h); + storeStyle(doc.body, { + backgroundImage: 'url()', + backgroundRepeat: '', + backgroundColor: 'black' + }); + player.SetVariable('videowindow.video_mc.video.smoothing' , 1); + player.SetVariable('videowindow.video_mc.video.deblocking', 5); + storeStyle( + player, + (scale.w >= scale.h) ? { + width: Math.floor(viewer.w * scale.h) + 'px', + height: screen.h + 'px', + marginLeft: ((screen.w - viewer.w * scale.h) / 2) + 'px', + marginTop: '0px' + } : { + width: screen.w + 'px', + height: Math.floor(viewer.h * scale.w) + 'px', + marginLeft: '0px', + marginTop: ((screen.h - viewer.h * scale.w) / 2) + 'px' + } + ); + player.SetVariable('videowindow._xscale', 100 * scale.v); + player.SetVariable('videowindow._yscale', 100 * scale.v); + variablesSetter(); + }; + f(); + win.onresize = function () + (InVimperator && liberator.mode === modes.COMMAND_LINE) || setTimeout(f, 1000); + } else { + restoreStyle(doc.body); + //restoreStyle(player); + player.style.marginLeft = ''; + player.style.marginTop = ''; + variablesSetter(); + delete win.onresize; + } + win.scrollTo(0, 0); + }, + get id () let (m = currentURL().match(/\/watch\/([a-z]{2}\d+)/)) (m && m[1]), @@ -414,9 +552,7 @@ get muted () this.player.ext_isMute(), set muted (value) (this.player.ext_setMute(value), value), - get player () - let (p = content.document.getElementById('flvplayer')) - (p && (p.wrappedJSObject || p)), + get player () getElementByIdEx('flvplayer'), get repeating () this.player.ext_isRepeat(), set repeating (value) (this.player.ext_setRepeat(value), value), @@ -443,7 +579,6 @@ set volume (value) (this.player.ext_setVolume(value), value), fetch: function (filepath) { - liberator.log(this.id) let onComplete = function (xhr) { let res = xhr.responseText; let info = {}; @@ -482,6 +617,7 @@ 'pause', 'comment', 'repeat', + 'fullscreen', { name: 'volume-root', label: 'Volume', @@ -592,13 +728,15 @@ this.removeStatusPanel(); this.disable(); this.progressListener.uninstall(); + for each (let player in this.players) + player.finalize(); window.removeEventListener('resize', this.__onResize, false); }, get hidden () (this.panel.hidden), set hidden (v) (this.panel.hidden = v), - get valid () (this.where), + get isValid () (this.where), get player () this.players[this.where], @@ -607,12 +745,11 @@ get statusBarVisible () !this.statusBar.getAttribute('moz-collapsed', false), set statusBarVisible (value) (this.statusBar.setAttribute('moz-collapsed', !value), value), - get where () ( - (~buffer.URL.indexOf('http://www.nicovideo.jp/watch/') && 'niconico') - || - (buffer.URL.match(/^http:\/\/(?:[^.]+\.)?youtube\.com\/watch/) && 'youtube') - ), - + get where () { + for (let [name, player] in Iterator(this.players)) + if (player.isValid) + return name; + }, addUserCommands: function () { let stella = this; @@ -623,7 +760,7 @@ (funcS instanceof Function) ? funcS : function (arg, bang) { - if (!stella.valid) + if (!stella.isValid) raise('Stella: Current page is not supported'); let p = stella.player; let func = bang ? funcB : funcS; @@ -684,6 +821,7 @@ icon.setAttribute('class', 'statusbarpanel-iconic'); icon.style.marginRight = '4px'; setClickEvent('icon', icon); + icon.addEventListener('dblclick', bindr(this, this.onIconDblClick), false); let labels = this.labels = {}; let toggles = this.toggles = {}; @@ -759,11 +897,15 @@ } }, + onFullscreenClick: function () this.player.toggle('fullscreen'), + onIconClick: function () this.player.playOrPause(), + onIconDblClick: function () this.player.toggle('fullscreen'), + onLocationChange: function () { - if (this.__valid !== this.valid) { - (this.__valid = this.valid) ? this.enable() : this.disable(); + if (this.__valid !== this.isValid) { + (this.__valid = this.isValid) ? this.enable() : this.disable(); } }, @@ -779,13 +921,13 @@ this.player.currentTime = this.player.totalTime * per; }, - onMutedClick: function (event) (this.player.toggle('muted')), + onMutedClick: function (event) this.player.toggle('muted'), onPauseClick: function () this.player.pause(), onPlayClick: function () this.player.play(), - onRepeatingClick: function () (this.player.toggle('repeating')), + onRepeatingClick: function () this.player.toggle('repeating'), onResize: function () { if (this.__fullScreen !== window.fullScreen) { @@ -794,23 +936,30 @@ } }, - onSetMutedClick: function (event) (this.player.volume = event.target.getAttribute('volume')) + onSetVolumeClick: function (event) (this.player.volume = event.target.getAttribute('volume')) }; + fixDoubleClick(Stella.prototype, 'onIconClick', 'onIconDblClick'); + // }}} /********************************************************************************* * Install {{{ *********************************************************************************/ - let (nsl = liberator.plugins.nico_statusline) { + if (InVimperator) { + let estella = liberator.plugins.stella; + let install = function () { - let stella = liberator.plugins.nico_statusline = new Stella(); + let stella = liberator.plugins.stella = new Stella(); stella.addUserCommands(); liberator.log('Stella: installed.') } - if (nsl) { - nsl.finalize(); + + // すでにインストール済みの場合は、一度ファイナライズする + // (デバッグ時に前のパネルが残ってしまうため) + if (estella) { + estella.finalize(); install(); } else { window.addEventListener( @@ -822,6 +971,8 @@ false ); } + } else { + /* do something */ } // }}} |