Created
February 4, 2009 07:49
-
-
Save hotchpotch/58007 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var p = function(arg) { | |
Application.console.log(arg); | |
// liberator.log(arg); | |
} | |
const HatenaBookmark = {}; | |
HatenaBookmark.Data = new Struct('url', 'title', 'comment', 'icon'); | |
HatenaBookmark.Data.defaultValue('icon', function() bookmarks.getFavicon(this.url)); | |
HatenaBookmark.Data.prototype.__defineGetter__('stext', function() { | |
if (typeof this._stext == 'undefined') { | |
this._stext = this.comment + "\0" + this.title + "\0" + this.url; | |
} | |
return this._stext; | |
}); | |
HatenaBookmark.Data.prototype.__defineGetter__("extra", function () [ | |
["comment", this.comment, "Comment"], | |
].filter(function (item) item[1])); | |
var XMigemoCore; | |
var XMigemoTextUtils; | |
try { | |
XMigemoCore = Cc['@piro.sakura.ne.jp/xmigemo/factory;1'] | |
.getService(Components.interfaces.pIXMigemoFactory) | |
.getService("ja"); | |
XMigemoTextUtils = Cc['@piro.sakura.ne.jp/xmigemo/text-utility;1'].getService(Ci.pIXMigemoTextUtils); | |
} catch (e if e instanceof TypeError) { | |
} | |
HatenaBookmark.useMigemo = !!(!liberator.globalVariables.hatena_bookmark_no_migemo && XMigemoCore); | |
HatenaBookmark.Command = { | |
templateDescription: function (item, text) { | |
return <> | |
{ | |
!(item.extra && item.extra.length) ? "" : | |
<span class="extra-info"> | |
{ | |
template.map(item.extra, function (e) | |
<><span highlight={e[2]}>{e[1]}</span></>, | |
<> </>/* Non-breaking space */) | |
} | |
</span> | |
} | |
</> | |
}, | |
templateTitleIcon: function (item, text) { | |
var simpleURL = text.replace(/^https?:\/\//, ''); | |
if (simpleURL.indexOf('/') == simpleURL.length-1) | |
simpleURL = simpleURL.replace('/', ''); | |
return <><span highlight="CompIcon">{item.icon ? <img src={item.icon}/> : <></>}</span><span class="td-strut"/>{item.item.title} | |
<a href={item.item.url} highlight="simpleURL"><span class="extra-info">{ | |
simpleURL | |
}</span></a> | |
</> | |
}, | |
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.stext); | |
} 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 ('-clear' in args) { | |
// HatenaBookmark.UserData.clear(); | |
// liberator.echo('Clear: HatenaBookmark cache data.'); | |
// 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'; | |
} | |
} | |
}, | |
} | |
HatenaBookmark.Command.options = { | |
completer: function(context) { | |
context.format = { | |
anchored: true, | |
title: ['TITLE', 'Info'], | |
keys: { text: "url", description: "url", icon: "icon", extra: "extra"}, | |
process: [ | |
HatenaBookmark.Command.templateTitleIcon, | |
HatenaBookmark.Command.templateDescription, | |
], | |
} | |
context.ignoreCase = true; | |
if (context.migemo) delete context.migemo; | |
context.filters = [HatenaBookmark.Command.filter]; | |
context.completions = HatenaBookmark.UserData.bookmarks; | |
}, | |
argCount: '*', | |
bang: true, | |
count: true, | |
literal: 0, | |
options: [ | |
[['-clear'], commands.OPTION_NOARG] // XXX | |
], | |
} | |
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 | |
); | |
HatenaBookmark.UserData = { | |
get bookmarks() { | |
this.init(); | |
return this._bookmarks; | |
}, | |
clear: function() { | |
this._inited = false; | |
this.init(); | |
}, | |
init: function() { | |
if (!this._inited) { | |
if (this._bookmarks) | |
delete this._bookmarks; | |
this._inited = true; | |
this.preloadLimit = 500; | |
this.preload(); | |
} | |
}, | |
preload: function() { | |
this.load({ | |
offset: 0, | |
limit: this.preloadLimit | |
}); | |
}, | |
load: function(query) { | |
var url = 'http://b.hatena.ne.jp/my/search.data'; | |
var xhr = new XMLHttpRequest(); | |
var self = this; | |
if (query.async) { | |
xhr.onreadystatechange = function() { | |
if (xhr.readyState == 4) { | |
if (xhr.status == 200) { | |
self.completeHandler(xhr) | |
} else { | |
liberator.echoerr('XHR Error: ' + xhr.statusText); | |
// throw new Error(xhr.statusText); | |
} | |
} | |
} | |
} | |
xhr.open('POST', url, query.async); | |
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); | |
xhr.send(this.makeQuery(query)); | |
if (!query.async) { | |
if (xhr.status == 200) { | |
this.completeHandler(xhr); | |
} else { | |
liberator.echoerr('XHR Error: ' + xhr.statusText); | |
// throw new Error(xhr.statusText); | |
} | |
} | |
}, | |
makeQuery: function(data) { | |
var pairs = []; | |
var regexp = /%20/g; | |
for (var k in data) { | |
if (typeof data[k] == 'undefined') continue; | |
var v = data[k].toString(); | |
var pair = encodeURIComponent(k).replace(regexp,'+') + '=' + | |
encodeURIComponent(v).replace(regexp,'+'); | |
pairs.push(pair); | |
} | |
return pairs.join('&'); | |
}, | |
completeHandler: function(res) { | |
if (this._loaded) return; | |
if (!this._bookmarks) { | |
this.createDataStructure(res.responseText || ''); | |
if (this._bookmarks.length == this.preloadLimit) { | |
this.load({ | |
offset: this.preloadLimit, | |
async: true | |
}); | |
} else { | |
this._loaded = 1; | |
} | |
} else { | |
this.updateDataStructure(res.responseText || ''); | |
this._loaded = 1; | |
} | |
}, | |
updateDataStructure: function(data) { | |
this.pushData(this._bookmarks, data); | |
}, | |
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) { | |
ary.push(new HatenaBookmark.Data(tmp[i+2]/* url */, tmp[i]/* title */, tmp[i+1]/* comment */)); | |
} | |
}, | |
mapFunc: function(item) { | |
item = item.split("\n"); | |
return { | |
url: item[2], | |
comment: item[1], | |
title: item[0], | |
} | |
}, | |
}; | |
})(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment