/* NEW BSD LICENSE {{{
Copyright (c) 2010, anekos.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
###################################################################################
# http://sourceforge.jp/projects/opensource/wiki/licenses%2Fnew_BSD_license #
# に参考になる日本語訳がありますが、有効なのは上記英文となります。 #
###################################################################################
}}} */
// PLUGIN_INFO {{{
let PLUGIN_INFO =
Extention manager death yohooo
Store or restore current extensions state with name.
The following sub-commands are interpreted.
extention manager
拡張の有効無効状態を name で保存復帰します。
以下の sub-commands があります。
問題のある拡張などをあぶり出すためのコマンドです。 二分探索ぽい方法よって、効率的に困った拡張を探し出します。 自動的に拡張の有効無効を切り替えていくので、かなり楽が出来ると思います。
作業手順。 (ok fail start を実行すると自動的に再起動します)
問題のある拡張がなんであるか、確定したら ok/fail したときにメッセージが出ます。 メッセージを確認したら、":extbisect reset" で拡張の状態を元に戻してください。
テストを行うことで、エラーで Firefox が終了してしまう場合は、再起動後に ok / fail を実行してください。
// Vimperator plugin: "Update Haiku"
// Last Change: 12-Jan-2009. Jan 2008
// License: Creative Commons
// Maintainer: mattn <mattn.jp@gmail.com> - http://mattn.kaoriya.net/
//
// The script allows you to update Haiku status from Vimperator.
//
// Commands:
// :haiku some thing text
// post "some thing text" to keyword 'id:username' on Hatena Haiku.
// :haiku #keyword some thing text
// post "some thing text" to keyword 'id:keyword' on Hatena Haiku.
// :haiku!/
// show public timeline.
// :haiku! someone
// show someone's statuses.
// :haiku! album
// show album timeline.
// :haiku!+ someone
// fav someone's last status.. mean put Hatena Star.
// :haiku!- someone
// un-fav someone's last status.. mean remove Hatena Star.
// :haiku! #keyword
// show the keyword timeline.
var PLUGIN_INFO =
<VimperatorPlugin>
<name>{NAME}</name>
<description>Hatena Haiku Client</description>
<author mail="mattn.jp@gmail.com" homepage="http://mattn.kaoriya.net">mattn</author>
<license>Creative Commons</license>
<minVersion>2.0a1</minVersion>
<maxVersion>2.0</maxVersion>
<updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/haiku.js</updateURL>
<detail><![CDATA[
The script allows you to update Haiku status from Vimperator.
== Commands ==
:haiku some thing text:
post "some thing text" to keyword 'id:username' on Hatena Haiku.
:haiku #keyword some thing text:
post "some thing text" to keyword 'id:keyword' on Hatena Haiku.
:haiku!/:
show public timeline.
:haiku! someone:
show someone's statuses.
:haiku! album:
show album timeline.
:haiku!+ someone:
fav someone's last status.. mean put Hatena Star.
:haiku!- someone:
un-fav someone's last status.. mean remove Hatena Star.
:haiku! #keyword:
show the keyword timeline.
]]></detail>
</VimperatorPlugin>;
(function(){
liberator.plugins.haiku = {
get cache() statuses
};
var passwordManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
var CLIENT_NAME = encodeURIComponent(config.name + "::plugin::haiku.js");
var evalFunc = window.eval;
var statuses = null;
try {
var sandbox = new Components.utils.Sandbox("about:blank");
if (Components.utils.evalInSandbox("true", sandbox) === true) {
evalFunc = function(text) {
return Components.utils.evalInSandbox(text, sandbox);
}
}
} catch (e) { liberator.log('warning: haiku.js is working with unsafe sandbox.'); }
function sprintf(format){
var i = 1, re = /%s/, result = "" + format;
while (re.test(result) && i < arguments.length) result = result.replace(re, arguments[i++]);
return result;
}
function sayHaiku(username, password, stat){
var keyword = '';
var user = '', id = '';
if (stat.match(/^#([^ ].+)\s+(.*)$/)) [keyword, stat] = [RegExp.$1, RegExp.$2];
else if (stat.match(/^@([^\s#]+)(?:#(\d+))?\s+(.*)$/)) [user, id, stat] = [RegExp.$1, RegExp.$2, RegExp.$3];
stat = stat.split("\\n").map(function(str) encodeURIComponent(str)).join("\n");
//liberator.log({keyword:keyword,user:user,id:id,stat:stat},0);
if (user && !(id && isValidStatusID(id))){
id = getStatusIDFromUserID(user);
if (!id) stat = "@" + user + "\n" + stat;
}
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://h.hatena.ne.jp/api/statuses/update.json", false, username, password);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var senddata = [
"status=", stat,
keyword ? "&keyword=" + encodeURIComponent(keyword) : id ? "&in_reply_to_status_id=" + id : "",
"&source=" + CLIENT_NAME
].join('');
//liberator.log('xhr.send(' + senddata +')',0);
xhr.send(senddata);
}
function favHaiku(username, password, user){
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://h.hatena.ne.jp/api/statuses/user_timeline/" + user + ".json", false, username, password);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
xhr.open("POST", "http://h.hatena.ne.jp/api/favorites/create/" + evalFunc(xhr.responseText)[0].id + '.json', false, username, password);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
}
function unfavHaiku(username, password, user){
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://h.hatena.ne.jp/api/statuses/user_timeline/" + user + ".json?count=1", false, username, password);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
xhr.open("POST", "http://h.hatena.ne.jp/api/favorites/destroy/" + evalFunc(xhr.responseText)[0].id + '.json', false, username, password);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
}
function isValidStatusID(id){
if (!statuses) return false;
return statuses.some(function(status) status.id == id);
}
function getStatusIDFromUserID(userid){
if (!statuses) return null;
return statuses.filter(function(status) status.in_reply_to_user_id == userid)[0].id;
}
function getTimelineURLFromTarget(target){
if (target == "/"){
return "http://h.hatena.ne.jp/api/statuses/public_timeline.json";
} else if (target == "album"){
return "http://h.hatena.ne.jp/api/statuses/album.json";
} else if (/^#(.+)/.test(target)){
return "http://h.hatena.ne.jp/api/statuses/keyword_timeline/" +
encodeURIComponent(RegExp.$1) + ".json";
} else if (/^@?(.+)/.test(target)){
return "http://h.hatena.ne.jp/api/statuses/user_timeline/" + RegExp.$1 + ".json";
}
return "http://h.hatena.ne.jp/api/statuses/friends_timeline.json";
}
function statusToXML(statuses){
var html = <style type="text/css"><![CDATA[
span.haiku.entry-title { text-decoration: underline; }
.haiku.entry-content { white-space: normal; }
.haiku.entry-content a { text-decoration: none; }
dl.haiku { margin-left: 1em; }
img.haiku.photo { border; 0px; width: 16px; height: 16px; vertical-align: baseline; }
]]></style>;
statuses.forEach(function(status) {
var text = status.text;
var keyword = status.keyword;
var star = status.favorited > 0 ? <><img src="http://s.hatena.ne.jp/images/star.gif"/><span style="color:orange;">{'x' + status.favorited}</span></> : <></>;
var replies = <></>;
if (text.indexOf(keyword+"=") == 0) text = status.text.substr(keyword.length + 1);
text = convert(text);
keyword = convert(keyword);
if (status.replies.length > 0){
replies = <dl class="haiku"></dl>;
status.replies.forEach(function(rep){
replies.* += <>
<dt>
<img src={rep.user.profile_image_url} alt={rep.user.screen_name} class="haiku photo"/>
<strong>{rep.user.name}</strong>
</dt>
<dd class="haiku entry-content">{rep.text.substr(keyword.length)}</dd>
</>;
});
}
html += <>