/**
* ==VimperatorPlugin==
* @name moreqmarks.js
* @description add feature(record position, stack, queue) to QuickMarks
* @description-ja QuickMarksに機能追加(位置の記憶、qmarksとは別のスタックとキュー追加)
* @author hogelog
* @version 0.05
* ==/VimperatorPlugin==
*
* MAPPINGS:
* "gj" -> Jump to QuickMark for current URL
* "gd" -> Delete QuickMark for current URL
* "gs" -> Push QuickMarkStack for current URL
* "gS" -> Pop QuickMarkStack and Jump
* "gq" -> Queue QuickMarkQueue for current URL
* "gQ" -> Dequeue QuickMarkStack and Jump
*
* COMMANDS:
* :qmarkpu[sh], :qmpu[sh] -> Push QuickMarkStack for current URL
* :qmarkpo[p], :qmpo[p] -> Pop QuickMarkStack and Jump
* :stackli[st], :stli[st] -> List QuickMarkStack
* :qmarkqu[eue], :qmqu[eue] -> Queue QuickMarkQueue for current URL
* :qmarkde[que], :qmde[que] -> Dequeue QuickMarkStack and Jump
* :queueli[st], :quli[st] -> List QuickMarkQueue
*
*/
(function(){
var use_position = true;
var use_default_data = true;
var qmarks = {};
var qmark_stack = [];
var qmark_queue = [];
// TODO: move to a storage module
var savedMarks = liberator.modules.options.getPref("extensions.vimperator.moreqmarks", "").split("\n");
var savedMarkStack = liberator.modules.options.getPref("extensions.vimperator.moreqmarkstack", "").split("\n");
var savedMarkQueue = liberator.modules.options.getPref("extensions.vimperator.moreqmarkqueue", "").split("\n");
// load the saved quickmarks -- TODO: change to sqlite
if(use_default_data) {
var defaultMarks = liberator.modules.options.getPref("extensions.vimperator.quickmarks", "").split("\n");
for (var i = 0; i < defaultMarks.length - 1; i += 2) {
var url = defaultMarks[i+1];
qmarks[defaultMarks[i]] = {url: url, x: 0, y: 0};
}
}
for (var i = 0; i < savedMarks.length - 1; i += 4) {
var url = savedMarks[i+1];
var x = savedMarks[i+2];
var y = savedMarks[i+3];
qmarks[savedMarks[i]] = {url: url, x: x, y:y};
}
for (var i = 0; i < savedMarkStack.length - 1; i += 3) {
var url = savedMarkStack[i];
var x = savedMarkStack[i+1];
var y = savedMarkStack[i+2];
qmark_stack.push({url: url, x: x, y:y});
}
for (var i = 0; i < savedMarkQueue.length - 1; i += 3) {
var url = savedMarkQueue[i];
var x = savedMarkQueue[i+1];
var y = savedMarkQueue[i+2];
qmark_queue.unshift({url: url, x: x, y:y});
}
function add_qmark(qmark, item, target) {
switch(target) {
case "stack":
qmark_stack.push(item);
break;
case "queue":
qmark_queue.unshift(item);
break;
case "mark":
default:
qmarks[qmark] = item;
break;
}
}
function get_qmark(qmark, target) {
switch(target) {
case "stack":
return qmark_stack[qmark_stack.length-1];
case "queue":
return item = qmark_queue[qmark_queue.length-1];
case "mark":
default:
return qmarks[qmark];
}
}
function get_qmarks(target) {
var marks = [];
// TODO: should we sort these in a-zA-Z0-9 order?
var count = 0;
var list;
switch(target) {
case "stack":
list = qmark_stack;
break;
case "queue":
list = qmark_queue;
break;
case "mark":
default:
list = qmarks;
break;
}
for (var mark in list) {
marks.push([mark, list[mark].url, list[mark].x, list[mark].y]);
}
marks.sort();
return marks;
}
function list_qmarks(marks) {
if(use_position) {
var list = ":" + liberator.modules.util.escapeHTML(liberator.modules.commandline.command) + "
" +
"
mark | line | col | file |
";
for (var i = 0; i < marks.length; i++)
{
list += "" +
" " + marks[i][0] + " | " +
"" + Math.round(marks[i][2] * 100) + "% | " +
"" + Math.round(marks[i][3] * 100) + "% | " +
"" + liberator.modules.util.escapeHTML(marks[i][1]) + " | " +
"
";
}
list += "
";
return list;
} else {
var list = ":" + liberator.modules.util.escapeHTML(liberator.modules.commandline.command) + "
" +
"QuickMark | URL |
";
for (var i = 0; i < marks.length; i++)
{
list += " " + marks[i][0] +
" | " + liberator.modules.util.escapeHTML(marks[i][1]) + " |
";
}
list += "
";
return list;
}
}
function jump_item(item, where, find) {
var url = item.url;
var x = item.x;
var y = item.y;
if (url) {
if(find) {
for (let [number, browser] in Iterator(liberator.modules.tabs.browsers)) {
var marked_url = browser.contentDocument.location.href;
if(marked_url == url) {
liberator.modules.tabs.select(number, false);
var win = getBrowser().selectedTab.linkedBrowser.contentWindow;
if(use_position) {
if(x!=0 || y!=0) {
win.scrollTo(x*win.scrollMaxX, y*win.scrollMaxY);
}
}
return true;
}
}
}
var tab = open_url(url, where);
if(tab) {
var win = tab.linkedBrowser.contentWindow;
if(use_position) {
if(x!=0 || y!=0) {
// scrollMaxX and scrollMaxY are 0 before construct content
// But small document(scrollMaxX = 0 and scrollMaxY = 0) is marked,
// maybe f is run forever.
var f = function() {
if(win.scrollMaxX==0 && win.scrollMaxY==0) {
setTimeout(f, 100);
} else {
win.scrollTo(x*win.scrollMaxX, y*win.scrollMaxY);
}
}
f();
}
}
}
return true;
}
return false;
}
function save_qmarks(target) {
switch(target) {
case "stack":
var savedQuickMarkStack = "";
for (var mark in qmark_stack) {
savedQuickMarkStack += qmark_stack[mark].url + "\n";
savedQuickMarkStack += qmark_stack[mark].x + "\n";
savedQuickMarkStack += qmark_stack[mark].y + "\n";
}
liberator.modules.options.setPref("extensions.vimperator.moreqmarkstack", savedQuickMarkStack);
break;
case "queue":
var savedQuickMarkQueue = "";
for (var mark in qmark_queue) {
savedQuickMarkQueue += qmark_queue[mark].url + "\n";
savedQuickMarkQueue += qmark_queue[mark].x + "\n";
savedQuickMarkQueue += qmark_queue[mark].y + "\n";
}
liberator.modules.options.setPref("extensions.vimperator.moreqmarkqueue", savedQuickMarkQueue);
break;
case "mark":
default:
var savedQuickMarks = "";
for (var mark in qmarks) {
savedQuickMarks += mark + "\n";
savedQuickMarks += qmarks[mark].url + "\n";
savedQuickMarks += qmarks[mark].x + "\n";
savedQuickMarks += qmarks[mark].y + "\n";
}
liberator.modules.options.setPref("extensions.vimperator.moreqmarks", savedQuickMarks);
if(use_default_data) {
var savedQuickMarks = "";
for (var mark in qmarks) {
savedQuickMarks += mark + "\n";
savedQuickMarks += qmarks[mark].url + "\n";
}
liberator.modules.options.setPref("extensions.vimperator.quickmarks", savedQuickMarks);
}
break;
}
}
function open_url(url, where) {
if (liberator.forceNewTab && liberator.has("tabs"))
where = liberator.NEW_TAB;
else if (!where || !liberator.has("tabs"))
where = liberator.CURRENT_TAB;
var whichwindow = window;
// decide where to load the first url
switch (where)
{
case liberator.CURRENT_TAB:
getBrowser().loadURIWithFlags(url, null, null, null, null);
return getBrowser().selectedTab;
case liberator.NEW_TAB:
return getBrowser().selectedTab = getBrowser().addTab(url, null, null, null);
case liberator.NEW_BACKGROUND_TAB:
return getBrowser().addTab(url, null, null, null);
case liberator.NEW_WINDOW:
window.open();
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
whichwindow = wm.getMostRecentWindow("navigator:browser");
whichwindow.loadURI(url, null, null);
return witchWindow.getBrowser().selectedTab;
case "mark":
default:
liberator.echoerr("Exxx: Invalid 'where' directive in liberator.plugins.moreqmarks openurls(...)");
return false;
}
}
//// MAPPINGS
var modes = [liberator.modules.modes.NORMAL];
liberator.modules.mappings.addUserMap(modes,
["gj"], "Jump to QuickMark for current URL",
function (arg)
{
var where = /\bquickmark\b/.test(liberator.modules.options["activate"]) ? liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB;
liberator.modules.quickmarks.jumpTo(arg, where, true);
},
{arg: true});
liberator.modules.mappings.addUserMap(modes,
["gd"], "Delete QuickMark for current URL",
function ()
{
liberator.plugins.moreqmarks.remove('', liberator.modules.buffer.URL);
});
liberator.modules.mappings.addUserMap(modes,
["gs"], "Push QuickMarkStack for current URL",
function ()
{
liberator.plugins.moreqmarks.add("", liberator.modules.buffer.URL, "stack");
});
liberator.modules.mappings.addUserMap(modes,
["gS"], "Pop QuickMarkStack and Jump",
function ()
{
var where = /\bquickmark\b/.test(liberator.modules.options["activate"]) ? liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB;
if(liberator.modules.quickmarks.jumpTo("", where, true, "stack")) {
liberator.modules.quickmarks.remove("", "", "stack");
}
});
liberator.modules.mappings.addUserMap(modes,
["gq"], "Queue QuickMarkQueue for current URL",
function ()
{
liberator.plugins.moreqmarks.add("", liberator.modules.buffer.URL, "queue");
});
liberator.modules.mappings.addUserMap(modes,
["gQ"], "Dequeue QuickMarkStack and Jump",
function ()
{
var where = /\bquickmark\b/.test(liberator.modules.options["activate"]) ? liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB;
if(liberator.modules.quickmarks.jumpTo("", where, true, "queue")) {
liberator.modules.quickmarks.remove("", "", "queue");
}
});
//// COMMANDS
liberator.modules.commands.add(["qmarkpu[sh]", "qmpu[sh]"], "Push QuickMarkStack for current URL",
function ()
{
liberator.plugins.moreqmarks.add("", liberator.modules.buffer.URL, "stack");
});
liberator.modules.commands.add(["qmarkpo[p]", "qmpo[p]"], "Pop QuickMarkStack and Jump",
function ()
{
var where = /\bquickmark\b/.test(liberator.modules.options["activate"]) ? liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB;
liberator.modules.quickmarks.jumpTo("", where, true, "stack");
});
liberator.modules.commands.add(["stackli[st]", "stls"], "List QuickMarkStack",
function ()
{
liberator.plugins.moreqmarks.list("", "stack");
});
liberator.modules.commands.add(["qmarkqu[eue]", "qmqu[eue]"], "Queue QuickMarkQueue for current URL",
function ()
{
liberator.plugins.moreqmarks.add("", liberator.modules.buffer.URL, "queue");
});
liberator.modules.commands.add(["qmarkde[que]", "qmde[que]"], "Dequeue QuickMarkStack and Jump",
function ()
{
var where = /\bquickmark\b/.test(liberator.modules.options["activate"]) ? liberator.NEW_TAB : liberator.NEW_BACKGROUND_TAB;
liberator.modules.quickmarks.jumpTo("", where, true, "queue");
});
liberator.modules.commands.add(["queueli[st]", "quli[st]"], "List QuickMarkQueue",
function ()
{
liberator.plugins.moreqmarks.list("", "queue");
});
//// PUBLIC SECTION
liberator.plugins.moreqmarks = {
add: function (qmark, url, target)
{
if(use_position) {
var win = window.content;
var x, y;
if (win.document.body.localName.toLowerCase() == "frameset") {
x = 0;
y = 0;
} else {
x = win.scrollMaxX ? win.pageXOffset / win.scrollMaxX : 0;
y = win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : /*
* ==VimperatorPlugin==
* @name youtubeamp.js
* @description this script gives you keyboard oprations for YouTube.com.
* @description-ja YouTube のプレーヤーをキーボードで操作できるようにする。
* @author janus_wel <janus_wel@fb3.so-net.ne.jp>
* @version 0.12
* @minversion 2.0pre 2008/10/16
* ==/VimperatorPlugin==
*
* LICENSE
* New BSD License
*
* USAGE
* :ytinfo
* プレーヤーに関しての情報を表示する。今のところバージョンだけ。
* :ytpause
* 再生 / 一時停止を切り替える。
* :ytmute
* 音声あり / なしを切り替える。
* :ytsize
* 最大化 / ノーマルを切り替える。動いてない。
* :ytseek [position]
* 指定した場所にシークする。秒数で指定が可能。
* 指定なしの場合一番最初にシークする。
* :ytseek! delta
* 現在の位置から delta 分離れた所にシークする。秒数で指定が可能。
* マイナスを指定すると戻る。指定なしの場合変化しない。
* :ytvolume [volume]
* ボリュームを設定する。 0 ~ 100 が指定できる。
* 指定なしの場合 100 にセットする。
* :ytvolume! delta
* ボリュームを現在の値から変更する。 -100 ~ +100 を指定可能。
* 指定なしの場合変化しない。
*
* SEE ALSO
* http://code.google.com/apis/youtube/js_api_reference.html
*
* HISTORY
* 2008/10/07 ver. 0.10 - initial written.
* */
(function() {
Function.prototype.bind = function(object) {
var __method = this;
return function() {
return __method.apply(object, arguments);
};
};
// class definition
// YouTubePlayerController Class
function YouTubePlayerController() {
this.initialize.apply(this, arguments);
}
YouTubePlayerController.prototype = {
initialize: function() {
this.fuller = this._changeToFull.bind(this);
},
constants: {
VERSION: '0.12',
CARDINAL_NUMBER: 10,
YOUTUBE_DOMAIN: '.youtube.jp',
YOUTUBE_URL: '^http://[^.]+\\.youtube\\.com/',
WATCH_URL: 'http://[^.]+\\.youtube\\.com/watch',
WATCH_PAGE: 1,
PLAYER_NODE_ID: 'movie_player',
STATE_PLAYING: 1,
SIZE_WIDTH_DEFAULT: 480,
SIZE_HEIGHT_DEFAULT: 385,
NAME_PLAYER_VERSION: 'PLAYER_VERSION',
SEEKTO_DEFAULT: 0,
SEEKBY_DEFAULT: 0,
VOLUMETO_DEFAULT: 100,
VOLUMEBY_DEFAULT: 0,
HIDE_NODES: [
'old-masthead',
'watch-vid-title',
'watch-other-vids',
'old-footer',
'copyright',
'watch-main-area',
'watch-comments-stats',
'watch-video-response',
'chrome-promo',
'watch-video-quality-setting',
],
},
getControllerVersion: function() { return this.constants.VERSION; },
pagecheck: function() {
if(this.getURL().match(this.constants.WATCH_URL)) return this.constants.WATCH_PAGE;
throw new Error('current tab is not watch page on youtube.com');
},
getURL: function() { return liberator.modules.buffer.URL; },
_player: function() {
if(this.pagecheck() === this.constants.WATCH_PAGE) {
let player = this._getElementById(this.constants.PLAYER_NODE_ID);
if(! player) throw new Error('player is not found');
return player;
}
return null;
},
togglePlay: function() {
var p = this._player();
(p.getPlayerState() !== this.constants.STATE_PLAYING)
? p.playVideo()
: p.pauseVideo();
},
toggleMute: function() {
var p = this._player();
p.isMuted() ? p.unMute() : p.mute();
},
toggleSize: function() {
var p = this._player();
(p.width == this.constants.SIZE_WIDTH_DEFAULT && p.height == this.constants.SIZE_HEIGHT_DEFAULT)
? this._fullSize()
: this._normalSize();
},
_changeToFull: function() {
var p = this._player();
setTimeout(function() {
p.width = content.innerWidth;
p.height = content.innerHeight;
}, 0);
},
_getElementById: function(id) {
var e = window.content.document.getElementById(id);
if(!e) return null;
return e.wrappedJSObject
? e.wrappedJSObject
: e;
},
_fullSize: function() {
var b = this._getElementById('baseDiv');
this.defMargin = b.style.margin;
this.defPadding = b.style.padding;
this.defWidth = b.style.width;
b.style.margin = 0;
b.style.padding = 0;
b.style.width = '100%';
for(let i=0, max=this.constants.HIDE_NODES.length ; i<max ; ++i) {
let h = this._getElementById(this.constants.HIDE_NODES[i]);
if(h) { h.style.display = 'none'; }
}
this._changeToFull();
window.addEventListener(
'resize',
this.fuller,
false
);
},
_normalSize: function() {
var b = this._getElementById('baseDiv');
b.style.margin = this.defMargin;
b.style.padding = this.defPadding;
b.style.width = this.defWidth;
for(let i=0, max=this.constants.HIDE_NODES.length ; i<max ; ++i) {
let h = this._getElementById(this.constants.HIDE_NODES[i]);
if(h) { h.style.display = 'block'; }
}
var p = this._player();
p.width = this.constants.SIZE_WIDTH_DEFAULT;
p.height = this.constants.SIZE_HEIGHT_DEFAULT;
window.removeEventListener(
'resize',
this.fuller,
false
);
},
seekTo: function(position) {
if(position) {
if(position.match(/^(\d+):(\d+)$/)) {
position = parseInt(RegExp.$1, this.constants.CARDINAL_NUMBER) * 60
+ parseInt(RegExp.$2, this.constants.CARDINAL_NUMBER);
}
if(isNaN(position)) throw new Error('assign unsigned number : seekTo()');
}
else position = this.constants.SEEKTO_DEFAULT;
var p = this._player();
p.seekTo(position);
},
seekBy: function(delta) {
if(delta) {
if(isNaN(delta)) throw new Error('assign signed number : seekBy()');
}
else delta = this.constants.SEEKBY_DEFAULT;
var p = this._player();
var position = p.getCurrentTime();
position += parseInt(delta, this.constants.CARDINAL_NUMBER);
p.seekTo(position);
},
volumeTo: function(volume) {
if(volume) {
if(isNaN(volume)) throw new Error('assign unsigned number : volumeTo()');
}
else volume = this.constants.VOLUMETO_DEFAULT;
var p = this._player();
p.setVolume(volume);
},
volumeBy: function(delta) {
if(delta) {
if(isNaN(delta)) throw new Error('assign signed number : volumeBy()');
}
else delta = this.constants.VOLUMEBY_DEFAULT;
var p = this._player();
var volume = p.getVolume();
volume += parseInt(delta, this.constants.CARDINAL_NUMBER);
p.setVolume(volume);
},
};
// global object
var controller = new YouTubePlayerController();
// command register
liberator.modules.commands.addUserCommand(
['ytinfo'],
'display player information',
function() {
try {
let info = [
'controller version : ' + controller.getControllerVersion(),
].join('\n');
liberator.echo(info, liberator.modules.commandline.FORCE_MULTILINE);
}
catch(e) { liberator.echoerr(e); }
},
{}
);
liberator.modules.commands.addUserCommand(
['ytpause'],
'toggle play / pause',
function() {
try { controller.togglePlay(); }
catch(e) { liberator.echoerr(e); }
},
{}
);
liberator.modules.commands.addUserCommand(
['ytmute'],
'toggle mute',
function() {
try { controller.toggleMute(); }
catch(e) { liberator.echoerr(e); }
},
{}
);
liberator.modules.commands.addUserCommand(
['ytseek'],
'controll seek bar',
function(args) {
try {
let arg = (args.length > 1)
? args[0].toString()
: args.string;
args.bang ? controller.seekBy(arg) : controller.seekTo(arg);
}
catch(e) { liberator.echoerr(e); }
},
{
bang: true,
}
);
liberator.modules.commands.addUserCommand(
['ytvolume'],
'controll volume',
function(args) {
try {
let arg = (args.length > 1)
? args[0].toString()
: args.string;
args.bang ? controller.volumeBy(arg) : controller.volumeTo(arg);
}
catch(e) { liberator.echoerr(e); }
},
{
bang: true,
}
);
liberator.modules.commands.addUserCommand(
['ytsize'],
'toggle video size',
function() {
try { controller.toggleSize(); }
catch(e) { liberator.echoerr(e); }
},
{}
);
})()
// vim: set sw=4 ts=4 et;