var PLUGIN_INFO =
: <>>}{item.item.title}
{
simpleURL
}
>
},
filter: function (_item) {
var item = _item.item;
// 'this' is context object.
if (HatenaBookmark.useMigemo) {
if (!this.migemo) {
this.migemo = HatenaBookmark.Command.compileRegexp(this.filter);
}
var migemo = this.migemo;
return migemo.test(item.data);
} else {
return this.match(item.url) || this.match(item.comment) || this.match(item.title);
}
},
compileRegexp: function(str) {
let a;
with (XMigemoTextUtils) {
a = sanitize(trim(str)).split(/\s+/).join(' ');
}
return new RegExp(XMigemoTextUtils.getANDFindRegExpFromTerms(XMigemoCore.getRegExps(a)), 'gim');
},
execute: function(args) {
if (args['-reload']) {
HatenaBookmark.reload();
liberator.echo('HatenaBookmark data reloaded.');
return;
}
var url = HatenaBookmark.Command.genURL(args);
liberator.open(url);
},
executeTab: function(args) {
var url = HatenaBookmark.Command.genURL(args);
liberator.open(url, liberator.NEW_TAB);
},
genURL: function(args) {
var url = (args.string || '').replace(/\s/g, '');
if (url.length) {
if (args.bang) {
return 'http://b.hatena.ne.jp/entry/' + url.replace('#', '%23');
} else {
return url;
}
} else {
if (args.bang) {
return 'http://b.hatena.ne.jp/';
} else {
return 'http://b.hatena.ne.jp/my';
}
}
},
createCompleter: function(titles) {
return function(context) {
context.format = {
anchored: true,
title: titles,
keys: { text: "url", description: "url", icon: "icon", extra: "extra"},
process: [
HatenaBookmark.Command.templateTitleIcon,
HatenaBookmark.Command.templateDescription,
],
}
context.ignoreCase = true;
if (HatenaBookmark.useSuffixArray) {
context.filters = [];
context.completions = HatenaBookmark.SuffixArray.search(context.filter);
} else {
if (context.migemo) delete context.migemo;
context.filters = [HatenaBookmark.Command.filter];
context.completions = HatenaBookmark.UserData.bookmarks;
}
}
}
}
HatenaBookmark.Command.options = {
completer: HatenaBookmark.Command.createCompleter(['TITLE', 'Info']),
literal: 0,
argCount: '*',
bang: true,
options: [
[['-reload'], commands.OPTION_NOARG]
],
}
commands.addUserCommand(
['bs[earch]'],
'Hatena Bookmark UserSearch',
HatenaBookmark.Command.execute,
HatenaBookmark.Command.options,
true
);
commands.addUserCommand(
['tabbs[earch]'],
'Hatena Bookmark UserSearch',
HatenaBookmark.Command.executeTab,
HatenaBookmark.Command.options,
true
);
completion.addUrlCompleter("H", "Hatena Bookmarks", HatenaBookmark.Command.createCompleter(["Hatena Bookmarks"]));
HatenaBookmark.Cache = {
get store() {
if (!this._store) {
let key = 'plugins-hatena-bookmark-search-data';
this._store = storage.newMap(key, true);
}
return this._store;
},
get now() {
return (new Date * 1);
},
clear : function () {
let store = this.store;
store.remove('expire');
store.remove('data');
store.remove('saryindexes');
},
get data () {
let store = this.store;
let expire = store.get('expire');
if (expire && expire > this.now) {
return store.get('data');
} else {
return this.loadByRemote();
}
},
get expire() {
// 24 hours;
return this.now + (liberator.globalVariables.hatena_bookmark_cache_expire || 1000 * 60 * 24);
},
loadByRemote: function() {
let r = util.httpGet('http://b.hatena.ne.jp/my.name');
let check = eval('(' + r.responseText + ')');
if (!check.login) {
liberator.echo('please login hatena bookmark && :bsearch -reload ');
this.store.set('expire', this.expire);
this.store.set('data', '');
return '';
} else {
let url = 'http://b.hatena.ne.jp/my/search.data';
let res = util.httpGet(url);
this.store.set('expire', this.expire);
this.store.set('data', res.responseText);
return res.responseText;
}
},
get sary() {
let data = this.data;
if (data[0] != "\0") {
data = data.substr(0, data.length * 3/4).split("\n").map(function(s, i)
(i % 3 == 0) ? ("\0" + s) : s
).join("\n");
this.store.set('expire', this.expire);
this.store.set('data', data);
}
let sary = new SuffixArray(data);
let saryindexes = this.store.get('saryindexes');
if (saryindexes) {
sary.sary = saryindexes.split(',');
} else {
sary.make();
this.store.set('saryindexes', sary.sary.join(','));
}
return sary;
},
}
HatenaBookmark.SuffixArray = {
get cache() HatenaBookmark.Cache,
reload: function() {
this.cache.clear();
this.sary = null;
},
search: function(word) {
if (word.length < 2) return [];
if (!this.sary) {
this.sary = this.cache.sary;
}
let sary = this.sary;
let indexes;
p.b(function() {
indexes = sary.search(word);
}, 'search/' + word);
/*
* title
* comment
* url
*/
var str = this.sary.string;
let tmp = [];
let res = [];
for (let i = 0, len = indexes.length; i < len; i++) {
let sIndex = str.lastIndexOf("\0", indexes[i]);
if (tmp.indexOf(sIndex) == -1) {
tmp.push(sIndex);
let eIndex = str.indexOf("\0", indexes[i]);
if (sIndex != -1 && eIndex != -1) {
res.push(new HatenaBookmark.Data(str.substring(sIndex, eIndex-1)));
}
}
}
return res;
},
}
HatenaBookmark.UserData = {
get bookmarks() {
this.init();
return this._bookmarks;
},
get cache() HatenaBookmark.Cache,
reload: function() {
this._inited = false;
this.cache.clear();
this.init();
},
init: function() {
if (!this._inited) {
let cache = HatenaBookmark.Cache.data;
if (this._bookmarks)
delete this._bookmarks;
this._inited = true;
this.createDataStructure(cache);
}
},
createDataStructure: function(data) {
this._bookmarks = [];
this.pushData(this._bookmarks, data);
},
pushData: function(ary, data) {
var infos = data.split("\n");
var tmp = infos.splice(0, infos.length * 3/4);
var len = tmp.length;
for (var i = 0; i < len; i+=3) {
/*
* title
* comment
* URL
*/
ary.push(new HatenaBookmark.Data(tmp[i] + "\n" + tmp[i+1] + "\n" + tmp[i+2]));
}
}
};
let SuffixArray = function (string) {
this.string = string;
this.lowerString = string.toLowerCase();
this.defaultLength = 255;
}
SuffixArray.prototype = {
make: function SuffixArray_createSuffixArray() {
let string = this.lowerString;
let sary = [];
let saryIndex = 0;
let str;
let index;
let dLen = this.defaultLength;
p.b(function() {
for (let i = 0, len = string.length; i < len; i++) {
str = string.substr(i, dLen);
index = str.indexOf("\n");
if (index != 0) {
if (index != -1)
str = str.substr(0, index);
sary[saryIndex++] = [str, i];
}
}
}, 'create');
p.b(function() {
sary.sort(function(a, b) {
if (a[0] > b[0]) {
return 1;
} else if (a[0] < b[0]) {
return -1;
}
return 0;
});
}, 'sort');
this.sary = sary.map(function([_,i]) i);
},
set sary (sary) { this._sary = sary; this._len = sary.length },
get sary () this._sary,
get length () this._len,
search: function SuffixArray_search(word) {
let wLen = word.length;
if (wLen == 0) return [];
if (!this.sary) this.make();
word = word.toLowerCase();
let string = this.lowerString;
let sary = this.sary;
let len = this.length;
let lastIndex = -1;
let index = parseInt(len / 2);
let floor =
/* * ==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;