diff options
-rw-r--r-- | PDF.js.js | 252 | ||||
-rw-r--r-- | auto-bookmark.js | 74 | ||||
-rw-r--r-- | bookmarktoolbar-hint.js | 30 | ||||
-rw-r--r-- | clock.js | 9 | ||||
-rw-r--r-- | direct_bookmark.js | 14 | ||||
-rw-r--r-- | erection.js | 266 | ||||
-rw-r--r-- | feedSomeKeys_3.js | 2 | ||||
-rw-r--r-- | function-template.js | 100 | ||||
-rw-r--r-- | gmail-commando.js | 13 | ||||
-rw-r--r-- | hints-for-embedded.js | 34 | ||||
-rw-r--r-- | loginManager.js | 18 | ||||
-rw-r--r-- | newtab.js | 80 | ||||
-rw-r--r-- | prevent-pseudo-domain.js | 14 | ||||
-rw-r--r-- | readcatlater.js | 5 | ||||
-rw-r--r-- | sbmcommentsviewer.js | 10 | ||||
-rw-r--r-- | stella.js | 16 | ||||
-rw-r--r-- | twittperator.js | 609 | ||||
-rw-r--r-- | twittperator/browsing.tw | 131 | ||||
-rw-r--r-- | twittperator/copy.tw | 24 | ||||
-rw-r--r-- | twittperator/eject-alert.tw | 5 | ||||
-rw-r--r-- | twittperator/mstrans.tw | 24 | ||||
-rw-r--r-- | twittperator/ril.tw | 21 | ||||
-rw-r--r-- | twittperator/rt.tw | 44 | ||||
-rw-r--r--[-rwxr-xr-x] | twittperator/twsidebar.tw | 69 | ||||
-rw-r--r-- | video-controller.js | 3 | ||||
-rw-r--r-- | walk-input.js | 11 |
26 files changed, 1449 insertions, 429 deletions
diff --git a/PDF.js.js b/PDF.js.js new file mode 100644 index 0000000..58b4671 --- /dev/null +++ b/PDF.js.js @@ -0,0 +1,252 @@ +/* NEW BSD LICENSE {{{ +Copyright (c) 2012, 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 # +# に参考になる日本語訳がありますが、有効なのは上記英文となります。 # +################################################################################### + +}}} */ + +// INFO {{{ +let INFO = +<> + <plugin name="PDF.js.js" version="1.0.0" + href="http://vimpr.github.com/" + summary="PDF.js controller." + lang="en-US" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="anekos@snca.net">anekos</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p></p> + <item> + <tags>:pdfjs-mapping-sample</tags> + <description><p>mapping sample</p><code><![CDATA[ + nnoremap -urls ^\\.pdf$ i :<C-u>pdfjs index<Space> + nnoremap -urls ^\\.pdf$ z :<C-u>pdfjs zoom<Space> + ]]></code></description> + </item> + </plugin> +</>; +// }}} + +(function () { + + let scrollCount = 1; + + // Functions {{{ + + function getScrollHeight (count) { + let base = content.innerHeight / 10; + if (count > 0) + scrollCount = count; + return base * scrollCount; + } + + function addMap (keys, desc, action) { + mappings.addUserMap( + [modes.NORMAL], + keys, + desc + ' - PDF.js.js', + action, + { + count: true, + matchingUrls: /\.pdf$/ + } + ); + } + + function getOutline () { + return Array.slice(content.document.querySelector('#outlineView').querySelectorAll('.outlineItem > a')); + } + + function getOutlineLevel (node) { + let level = 0; + while (node && (node.getAttribute('id') != 'outlineView')) { + node = node.parentNode; + level++; + } + return node ? (level / 2): 0; + } + + function nSpace (level) { + let res = ''; + for (i = 0; i < level; i++) + res += ' '; + return res; + } + + // }}} + + // Mappings {{{ + + addMap( + ['j'], + 'Scroll Down', + function (count) { + content.document.querySelector('#viewerContainer').scrollTop += getScrollHeight(count); + } + ); + + addMap( + ['k'], + 'Scroll up', + function (count) { + content.document.querySelector('#viewerContainer').scrollTop -= getScrollHeight(count); + } + ); + + addMap( + ['n'], + 'Next page', + function (count) { + content.window.wrappedJSObject.PDFView.page += (count > 0 ? count : 1); + } + ); + + addMap( + ['p'], + 'Previous page', + function (count) { + content.window.wrappedJSObject.PDFView.page -= (count > 0 ? count : 1); + } + ); + + addMap( + ['gg'], + 'Go to page top or N page.', + function (count) { + if (count > 0) + content.window.wrappedJSObject.PDFView.page = count; + else + content.window.wrappedJSObject.PDFView.page = 1; + } + ); + + addMap( + ['zh'], + 'Fit to page.', + function (count) { + liberator.execute('pdfjs zoom page-fit'); + } + ); + + addMap( + ['zw'], + 'Fit to page to width.', + function (count) { + liberator.execute('pdfjs zoom page-width'); + } + ); + + addMap( + ['za'], + 'Fit to page to width.', + function (count) { + liberator.execute('pdfjs zoom auto'); + } + ); + + addMap( + ['zz'], + 'Fit to page to width.', + function (count) { + commandline.open('', 'pdfjs zoom ', modes.EX); + } + ); + + // }}} + + commands.addUserCommand( // {{{ + ['pdfjs'], + 'PDF.js', + function () void 'Meow is best', + { + subCommands: [ + new Command( + ['i[ndex]'], + 'Jump page by index', + function (args) { + let index = args.literalArg.match(/^#(\d+)$/); + if (index) { + let os = getOutline(); + buffer.followLink(os[parseInt(index[1], 10)], liberator.CURRENT_TAB); + } else { + content.window.wrappedJSObject.PDFView.page = parseInt(args.literalArg, 10); + } + }, + { + literal: 0, + completer: function (context, args) { + function desc (o) { + const PageRE = /#page=(\d+)\&/; + if (o.href && PageRE.test(o.href)) { + return String(<>{nSpace(getOutlineLevel(o))} {o.textContent} (p{o.href.match(PageRE)[1]})</>); + } else { + return String(<>{nSpace(getOutlineLevel(o))} {o.textContent}</>); + } + } + + let os = getOutline(); + context.compare = void 0; + context.filters = [CompletionContext.Filter.textDescription]; + context.completions = [ + [ + '#' + i, desc(o) + ] + for ([i, o] in Iterator(os)) + ]; + } + } + ), + + new Command( + ['z[oom]'], + 'Zoom', + function (args) { + content.window.wrappedJSObject.PDFView.parseScale(args.literalArg); + }, + { + literal: 0, + completer: function (context, args) { + let os = Array.slice(content.document.querySelector('#scaleSelect').querySelectorAll('option')); + context.completions = [ + [o.value, o.textContent] + for ([, o] in Iterator(os)) + ]; + } + } + ) + ] + }, + true + ); // }}} + +})(); + +// vim:sw=2 ts=2 et si fdm=marker: diff --git a/auto-bookmark.js b/auto-bookmark.js index 829178c..a3ed359 100644 --- a/auto-bookmark.js +++ b/auto-bookmark.js @@ -35,7 +35,7 @@ THE POSSIBILITY OF SUCH DAMAGE. // INFO {{{ let INFO = <> - <plugin name="AutoBookmark" version="1.2.0" + <plugin name="AutoBookmark" version="1.3.1" href="http://vimpr.github.com/" summary="Auto update bookmark" lang="en-US" @@ -50,7 +50,7 @@ let INFO = <description><p></p></description> </item> </plugin> - <plugin name="AutoBookmark" version="1.2.0" + <plugin name="AutoBookmark" version="1.3.1" href="http://vimpr.github.com/" summary="自動更新するブックマーク" lang="ja" @@ -209,11 +209,32 @@ let INFO = function namesCompleter (hidden) { // {{{ return function (context, args) { + function toTime (data) { + if (data.last && data.last.date) + return new Date(data.last.date).getTime(); + return 0; + } + + let bs = [ + data + for ([, data] in Iterator(bookmarks)) + if (!!data.hidden === !!hidden) + ]; + context.title = ['Bookmark name']; + if (args['-sort'] == 'title') { + }else { + // default date sorting + context.compare = void 0; + bs.sort(function (a, b) { + let d = toTime(b) - toTime(a); + return (d == 0 ? a.name.localeCompare(b.name) : d); + }); + } + context.completions = [ - [name, data.current.URL] - for ([name, data] in Iterator(bookmarks)) - if (!!data.hidden === !!hidden) + [data.name, data.current.URL] + for ([, data] in Iterator(bs)) ]; }; } // }}} @@ -281,16 +302,28 @@ let INFO = } // }}} function updateCurrent (data, URL, title) { // {{{ + let now = new Date().toString(); + + liberator.log('update-current: 1'); data.current = { URL: URL, - title: title + title: title, + added: now + }; + liberator.log('update-current: 2'); + data.last = { + date: now }; if (data.pages) { + liberator.log('update-current: 3'); if (data.pages.some(function (it) (it.URL == URL))) return; + liberator.log('update-current: 4'); } else { data.pages = []; + liberator.log('update-current: 5'); } + liberator.log('update-current: 6'); data.pages.push(data.current); } // }}} @@ -308,7 +341,13 @@ let INFO = true ); // }}} - commands.addUserCommand( // {{{ + // {{{ + let commandOptions = [ + [ ['-sort'], commands.OPTION_STRING, null, + [ ['last', 'Last updated date (default)'], ['name', 'By name'] ] ] + ]; + + commands.addUserCommand( 'autobookmark', 'Auto bookmarking', function () { @@ -364,7 +403,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter() + completer: namesCompleter(), + options: commandOptions } ), new Command( @@ -379,7 +419,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter() + completer: namesCompleter(), + options: commandOptions } ), new Command( @@ -395,7 +436,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter() + completer: namesCompleter(), + options: commandOptions } ), new Command( @@ -429,7 +471,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter() + completer: namesCompleter(), + options: commandOptions } ), new Command( @@ -453,7 +496,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter() + completer: namesCompleter(), + options: commandOptions } ), new Command( @@ -470,7 +514,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter(true) + completer: namesCompleter(true), + options: commandOptions } ), new Command( @@ -481,7 +526,8 @@ let INFO = }, { literal: 0, - completer: namesCompleter(false) + completer: namesCompleter(false), + options: commandOptions } ) ] diff --git a/bookmarktoolbar-hint.js b/bookmarktoolbar-hint.js index 3257d30..363455d 100644 --- a/bookmarktoolbar-hint.js +++ b/bookmarktoolbar-hint.js @@ -2,7 +2,7 @@ // @name BookmarksToolbar-Hint // @description Feature the BookmarksToolbar-Hint // @description-ja ブックマークツールバーのヒント機能を提供 -// @version 0.2c +// @version 0.2e // ==/VimperatorPlugin== // // Usage: @@ -35,7 +35,7 @@ liberator.plugins.bookmarkToolbarHints = (function(){ tooltipbox.removeChild(tooltipbox.firstChild); } } - function getToolbar() toolbar || (toolbar = document.getElementById('bookmarksBarContent')); + function getToolbar() toolbar || (toolbar = document.getElementById('PlacesToolbarItems')); function onKeyPress(event){ manager.onEvent(event); event.stopPropagation(); @@ -43,7 +43,11 @@ liberator.plugins.bookmarkToolbarHints = (function(){ } function updateSelector(){ for (let i=0; i<tooltipbox.childNodes.length; i++){ - tooltipbox.childNodes[i].style.color = (i+1).toString().indexOf(currentNum+1) == 0 ? "red" : "black"; + if (useShift) { + tooltipbox.childNodes[i].style.color = (i+1) == (currentNum+1) ? "red" : "black"; + } else { + tooltipbox.childNodes[i].style.color = (i+1).toString().indexOf(currentNum+1) == 0 ? "red" : "black"; + } } } function itemOpen(target){ @@ -54,7 +58,7 @@ liberator.plugins.bookmarkToolbarHints = (function(){ else fn.call(target, {button:1, ctrlKey:true}); } else { - liberator.open(target.node.uri, where); + liberator.open(target._placesNode.uri, where); } closeMenus(target); liberator.modules.options.guioptions = manager.go; @@ -77,7 +81,8 @@ liberator.plugins.bookmarkToolbarHints = (function(){ var toolbar; var current; var currentNum = 0; - var useShift = false; + var pressedNum = ""; + var useShift = true; var where = liberator.CURERNT_TAB; var manager = { get toolbar() getToolbar(), @@ -136,6 +141,7 @@ liberator.plugins.bookmarkToolbarHints = (function(){ currentNum = currentNum == 0 ? hints.length -1 : currentNum - 1; } useShift = true; + pressedNum = ""; updateSelector(); return; case "l": @@ -144,8 +150,10 @@ liberator.plugins.bookmarkToolbarHints = (function(){ } return; case "<BS>": - if (key == "<BS>" && currentNum > 0){ - currentNum = Math.floor(currentNum / 10); + if (key == "<BS>" && pressedNum.length > 0){ + pressedNum = pressedNum.substring(0,pressedNum.length - 1); + currentNum = pressedNum.length > 0 ? parseInt(pressedNum,10) : 0; + useShift = pressedNum.length == 0; updateSelector(); return; } @@ -162,15 +170,16 @@ liberator.plugins.bookmarkToolbarHints = (function(){ return; default: if (/^[0-9]$/.test(key)){ - let num = parseInt(key,10); - if (!useShift && currentNum) num += currentNum * 10; - + useShift = false; + pressedNum += key; + let num = parseInt(pressedNum,10); if (hints.length >= num*10){ currentNum = num - 1; updateSelector(); return; } if (hints[num-1]){ + pressedNum = ""; if (toolbarOpen(hints[num-1])) return; } } @@ -180,6 +189,7 @@ liberator.plugins.bookmarkToolbarHints = (function(){ }, quit: function(){ currentNum = 0; + pressedNum = ""; useShift = false; window.removeEventListener('keypress',onKeyPress,true); liberator.modules.modes.reset(true); @@ -5,9 +5,8 @@ let PLUGIN_INFO = <description lang="ja">とけい</description>
<author mail="janus_wel@fb3.so-net.ne.jp" homepage="http://d.hatena.ne.jp/janus_wel">janus_wel</author>
<license document="http://www.opensource.org/licenses/bsd-license.php">New BSD License</license>
-<version>0.15.2</version>
-<minVersion>2.0pre</minVersion>
-<maxVersion>2.2pre</maxVersion>
+<version>0.15.3</version>
+<minVersion>3.0</minVersion>
<updateURL>https://github.com/vimpr/vimperator-plugins/raw/master/clock.js</updateURL>
<detail><![CDATA[
== USAGE ==
@@ -337,9 +336,7 @@ function year() { // node control
function getCommandlineStack() {
- let messageTextarea = window.document.getElementById('liberator-message');
- let commandlineStack = messageTextarea.parentNode;
- return commandlineStack.localName === 'stack' ? commandlineStack : null;
+ return window.document.getElementById('liberator-bottombar');
}
} )();
diff --git a/direct_bookmark.js b/direct_bookmark.js index c696498..46d5a79 100644 --- a/direct_bookmark.js +++ b/direct_bookmark.js @@ -175,8 +175,6 @@ for Migemo search: require XUL/Migemo Extension d.xhr = req;
return d;
}
- http.get = function (url) http({method:"get", url:url});
- http.post = function (url, data) http({method:"post", url:url, data:data, headers:{"Content-Type":"application/x-www-form-urlencoded"}});
Deferred.Deferred = Deferred;
Deferred.http = http;
@@ -290,11 +288,6 @@ for Migemo search: require XUL/Migemo Extension return doc;
}
- //
- //
- //
- //
-
function getNormalizedPermalink(url){
var canonical = plugins.libly.$U.getFirstNodeFromXPath('//link[@rel="canonical"]');
return canonical ? canonical.href : url;
@@ -338,11 +331,6 @@ for Migemo search: require XUL/Migemo Extension return [user, password];
}
- //
- //
- //
- //
-
var services = {
'h': {
description:'Hatena bookmark',
@@ -725,7 +713,7 @@ for Migemo search: require XUL/Migemo Extension if (arg["-s"]) targetServices = arg["-s"];
if (arg[0] && withUrl) url = arg[0];
- comment = arg.literalArg;
+ var comment = arg.literalArg;
var tags = [];
var re = /\[([^\]]+)\]([^\[].*)?/g;
diff --git a/erection.js b/erection.js new file mode 100644 index 0000000..be7e1d2 --- /dev/null +++ b/erection.js @@ -0,0 +1,266 @@ +/* NEW BSD LICENSE {{{ +Copyright (c) 2012, 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 # +# に参考になる日本語訳がありますが、有効なのは上記英文となります。 # +################################################################################### + +}}} */ + +// INFO {{{ +let INFO = +<> + <plugin name="erection" version="1.1.1" + href="http://vimpr.github.com/" + summary="Show the Erection." + lang="en-US" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="anekos@snca.net">anekos</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p></p> + <item> + <tags>:erection-copy</tags> + <spec>:erection copy <a>erection</a></spec> + <description><p>Copy erected text.</p></description> + </item> + <item> + <tags>:erection-show</tags> + <spec>:erection show <a>erection</a></spec> + <description><p>Show erected text with the image.</p></description> + </item> + </plugin> + <plugin name="エレクチオン" version="1.1.1" + href="http://vimpr.github.com/" + summary="どうしてなの――ッ!! どうしてエレクチオンしないのよーッ!!" + lang="ja" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="anekos@snca.net">anekos</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p></p> + <item> + <tags>:erection-copy</tags> + <spec>:erection copy <a>erection</a></spec> + <description><p>エレクチオンテキストをクリップボードにコピーします。</p></description> + </item> + <item> + <tags>:erection-show</tags> + <spec>:erection show <a>erection</a></spec> + <description><p>エレクチオンテキストと画像を表示します。</p></description> + </item> + </plugin> +</>; +// }}} + +(function () { + + const VERSION = INFO.@version[0]; + + function erect (callback) { + const VC = + Cc["@mozilla.org/xpcom/version-comparator;1"] + .getService(Ci.nsIVersionComparator); + + const Store = storage.newMap('erection', {store: true}); + + function parentUntil (e, tagName) { + while (e = e.parentNode) { + if (e.tagName === tagName) + return e; + } + return; + } + + function siblingUntil (e, tagName) { + while (e = e.nextSibling) { + if (e.tagName === tagName) + return e; + } + return; + } + + function prop (propName) { + return function (e) { + return e[propName]; + } + } + + function fix (text) { + return text && text.replace(/[\s\n\r]+|・\\/g, ' ').trim(); + } + + let textContent = prop('textContent'); + + function onComplete (xhr) { + let erections = []; + + let doc = xhr.response; + for (let [, img] in Iterator(doc.querySelectorAll('td > p > font > img'))) { + let p = parentUntil(img, 'P'); + + let entry = {imageURL: img.src}; + entry.text = Array.map(p.querySelectorAll('strong'), textContent).filter(function (t) !t.replace(/\s+/g, '').match(/^・+$/)).join("\n"); + let [by, from] = Array.map(siblingUntil(p.nextSibling, 'P').querySelectorAll('font'), function (it) it.textContent); + entry.by = by; + entry.from = from; + + erections.push(entry); + } + + for (let [, img] in Iterator(doc.querySelectorAll('td > p > img'))) { + let p = parentUntil(img, 'P'); + + let entry = {imageURL: img.src}; + entry.text = Array.map(p.querySelectorAll('strong'), textContent).filter(function (t) !t.replace(/\s+/g, '').match(/^・+$/)).join("\n"); + let [by, from] = Array.map(siblingUntil(p.nextSibling, 'P').querySelectorAll('font'), textContent); + entry.by = by; + entry.from = from; + + erections.push(entry); + } + + for (let [, e] in Iterator(erections)) { + for (let [n, t] in Iterator(e)) { + if (typeof t === 'string') + e[n] = fix(t); + } + } + + Store.set('version', VERSION); + Store.set('erections', erections); + Store.save(); + + return callback(erections); + } + + if (VC.compare(Store.get('version'), VERSION) == 0) { + //liberator.log('Get erections from Cache'); + callback(Store.get('erections')); + return; + } + + //liberator.log('Get erections from Web'); + + let xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) + onComplete(xhr); + }; + xhr.open('GET', 'http://doutanuki.web.fc2.com/erection.htm'); + xhr.responseType = 'document'; + xhr.send(null); + } + + function erectionCompleter (context, args) { + context.title = ['セリフ', '人物 (出典)']; + context.compare = false; + context.incomplete = true; + + context.filters = [CompletionContext.Filter.textDescription]; + + erect(function (erections) { + context.completions = [ + [n + ': ' + e.text, e.by + (e.from || '')] + for ([n, e] in Iterator(erections)) + ]; + context.incomplete = false; + }); + } + + function makeErectionCommand (action) { + return function (args) { + let num = parseInt(args.literalArg, 10); + return erect(function (erections) { + return action(erections[num], args); + }); + } + } + + let subOption = { + literal: 0, + completer: erectionCompleter + }; + + commands.addUserCommand( + ['erection'], + 'Erection', + function (args) { + }, + { + subCommands: [ + new Command( + ['c[opy]'], + 'Copy text', + makeErectionCommand(function (e) { + util.copyToClipboard(String(<>{e.text} - {e.by} {e.from} {e.imageURL}</>)); + }), + subOption + ), + new Command( + ['s[how]'], + 'Show text and image', + makeErectionCommand(function (e) { + liberator.echo(<> + <div style="height: 800px"> + <h1>{e.text}</h1> + <img src={e.imageURL} /> + <span>{e.by}</span> <span>{e.from}</span> + </div> + </>); + }), + subOption + ), + new Command( + ['e[xcommand]'], + 'Open command line with select erection', + makeErectionCommand(function (e, args) { + let cmdArgs = String(<>{e.text} - {e.by} {e.from} {e.imageURL}</>); + setTimeout(function () commandline.open('', args[0] + ' ' + cmdArgs, modes.EX), 1); + }), + { + literal: 1, + completer: function (context, args) { + if (args.length <= 1) { + completion.ex(context); + } else { + erectionCompleter(context, args); + } + } + } + ) + ] + }, + true + ); + + erect(function () void 0); + +})(); + +// vim:sw=2 ts=2 et si fdm=marker: diff --git a/feedSomeKeys_3.js b/feedSomeKeys_3.js index 82d15ba..30bf52d 100644 --- a/feedSomeKeys_3.js +++ b/feedSomeKeys_3.js @@ -692,7 +692,7 @@ let INFO = <> { literal: 0, options: [ - [['-modes', '-m'], commands.OPTION_LIST] + [['-modes', '-m'], commands.OPTION_LIST], [['-urls', '-u'], commands.OPTION_STRING, regexpValidator, urlCompleter({})], [['-ignoreurls', '-iu'], commands.OPTION_NOARG] ], diff --git a/function-template.js b/function-template.js index 5dac6fd..f739cae 100644 --- a/function-template.js +++ b/function-template.js @@ -1,5 +1,5 @@ /* NEW BSD LICENSE {{{ -Copyright (c) 2009-2011, anekos. +Copyright (c) 2009-2012, anekos. All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -32,30 +32,73 @@ THE POSSIBILITY OF SUCH DAMAGE. }}} */ -// PLUGIN_INFO {{{ -let PLUGIN_INFO = -<VimperatorPlugin> - <name>Functions Template</name> - <name lang="ja">関数テンプレート</name> - <description>function Template</description> - <description lang="ja">Vimperator の関数のテンプレート</description> - <version>1.3.0</version> - <author mail="anekos@snca.net" homepage="http://d.hatena.ne.jp/nokturnalmortum/">anekos</author> - <license>new BSD License (Please read the source code comments of this plugin)</license> - <license lang="ja">修正BSDライセンス (ソースコードのコメントを参照してください)</license> - <updateURL>https://github.com/vimpr/vimperator-plugins/raw/master/function-template.js</updateURL> - <minVersion>3.0</minVersion> - <detail><![CDATA[ - Functions template - (Fix|Add) me! - ]]></detail> - <detail lang="ja"><![CDATA[ - 関数のテンプレート - (おかしい|書かれていない)(関数|引数|説明)があったら適当に(足|なお)してください。 - ]]></detail> -</VimperatorPlugin>; +// INFO {{{ +let INFO = +<> + <plugin name="XXXX" version="1.0.0" + href="http://vimpr.github.com/" + summary="XXXXX" + lang="en-US" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="xxxx@xxxx.net">xxxxx</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p> + This is the Sample Plugin + </p> + <item> + <tags>:hoge</tags> + <spec>:hoge <oa>-opt1=<a>val1</a></oa></spec> + <description><p> + Description for Command + </p> + <code><![CDATA[ +javascript<<EOM +liberator.globalVariables.this_is_sample = [{ + neko_tails: 2, + neko_eyes: 2, + neko_legs: 4, + neko_head: 1 + }]; +EOM + ]]></code> + </description> + </item> + </plugin> + <plugin name="XXXX" version="1.0.0" + href="http://vimpr.github.com/" + summary="XXXXX" + lang="ja" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="xxxx@xxxx.net">xxxxx</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p> + サンプル用のプラグインだよ + </p> + <item> + <tags>:hoge</tags> + <spec>:hoge <oa>-opt1=<a>val1</a></oa></spec> + <description><p> + コマンドの説明 + </p> + <code><![CDATA[ +javascript<<EOM +liberator.globalVariables.this_is_sample = [{ + neko_tails: 2, + neko_eyes: 2, + neko_legs: 4, + neko_head: 1 + }]; +EOM + ]]></code> + </description> + </item> + </plugin> +</>; // }}} + (function () { // XXX 以下は実行しないよ。 return; @@ -102,7 +145,7 @@ let PLUGIN_INFO = subCommands: [ new Command( ['subA'], - 'Sub command A' + 'Sub command A', function (args) { // addUserCommand のと同じ }, @@ -112,7 +155,7 @@ let PLUGIN_INFO = ), new Command( ['subB'], - 'Sub command B' + 'Sub command B', function (args) { }, {} ) @@ -129,7 +172,7 @@ let PLUGIN_INFO = options.add( ['names'], 'description', - 'string', // type: string, stringlist, charlist, boolean + 'string', // type: string, stringlist, charlist, boolean, number 'defaultValue', { scope: Option.SCOPE_GLOBAL, // <- default @@ -143,6 +186,11 @@ let PLUGIN_INFO = return value; }, completer: function () { + return [ + ["value1", "description one"], + ["value2", "description two"], + ["value3", "description three"], + ]; }, validator: function () { }, diff --git a/gmail-commando.js b/gmail-commando.js index 7b4e929..3d2f95f 100644 --- a/gmail-commando.js +++ b/gmail-commando.js @@ -1,5 +1,5 @@ /* NEW BSD LICENSE {{{ -Copyright (c) 2010-2011, anekos. +Copyright (c) 2010-2012, anekos. All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -234,16 +234,15 @@ let INFO = get labels() A(this.doc.querySelectorAll('a.n0')).filter(function (it) (/#label/.test(it.href))), - // 入力欄 と 検索ボタンは Buzz の有効無効によって ID が変わる - get input() this.doc.querySelector('input.w-as1.nr'), + get input() this.doc.querySelector('input.gbqfif'), - get searchButton() this.doc.querySelector('div.J-Zh-I.J-J5-Ji.L3.J-Zh-I-Js-Zq'), + get searchButton() this.doc.querySelector('button.gbqfb'), - get translateButton () (this.mail && this.mail.querySelector('tr > td.SA > .iL.B9')), - get translateButtons () A(this.doc.querySelectorAll('tr > td.SA > .iL.B9')), + get translateButton () (this.mail && this.mail.querySelector('div.adJ > .B9.J-J5-Ji')), + get translateButtons () A(this.doc.querySelectorAll('div.adJ > .B9.J-J5-Ji')), get mail () - let (es = this.mails.filter(function (it) !it.querySelector('.hF.hH > img.hG'))) + let (es = this.mails.filter(function (it) !it.querySelector('.ads > .hH'))) (es.length && es[0]), get mails () A(this.doc.querySelectorAll('.h7')), diff --git a/hints-for-embedded.js b/hints-for-embedded.js index d4bc451..1fa940b 100644 --- a/hints-for-embedded.js +++ b/hints-for-embedded.js @@ -35,7 +35,7 @@ THE POSSIBILITY OF SUCH DAMAGE. // INFO {{{ let INFO = <> - <plugin name="HintsForEmbeded" version="1.5.1" + <plugin name="HintsForEmbeded" version="1.6.0" href="http://github.com/vimpr/vimperator-plugins/blob/master/hints-for-embedded.js" summary="Add the hints mode for embedded objects." lang="en-US" @@ -133,6 +133,7 @@ let INFO = let modeName = liberator.globalVariables.hints_for_embedded_mode || 'hints-for-embedded'; let where = liberator.globalVariables.hints_for_embedded_where; let openParent = liberator.globalVariables.hints_for_embedded_open_parent_link || 0; + let useVLC = liberator.globalVariables.hints_for_embedded_use_vlc || 0; if (typeof where === 'undefined') where = liberator.NEW_TAB; @@ -151,25 +152,29 @@ let INFO = site: /youtube/, name: /^src$/, value: /http:\/\/www\.youtube\.com\/(?:embed|v)\/([-a-zA-Z0-9_]+)/, - url: function (id) ('http://www.youtube.com/watch?v=' + id) + url: function (id) ('http://www.youtube.com/watch?v=' + id), + vlc: true }, youtube: { site: /youtube/, name: /.*/, value: /youtube\.com\/v\/([-a-zA-Z0-9_]+)/, - url: function (id) ('http://www.youtube.com/watch?v=' + id) + url: function (id) ('http://www.youtube.com/watch?v=' + id), + vlc: true }, youtube_image: { site: /ytimg\.com/, name: /^flashvars$/, value: /video_id=([-a-zA-Z0-9_]+)/, - url: function (id) ('http://www.youtube.com/watch?v=' + id) + url: function (id) ('http://www.youtube.com/watch?v=' + id), + vlc: true }, vimeo: { site: /vimeo/, name: /.*/, value: /clip_id=(\d+)/, - url: function (id) ('http://vimeo.com/' + id) + url: function (id) ('http://vimeo.com/' + id), + vlc: true }, collegehumor: { site: /collegehumor/, @@ -185,16 +190,18 @@ let INFO = function getInfo (elem) getAttrs(elem).concat((Array.slice(elem.querySelectorAll('object,embed,param')) || []).map(getInfo)); - function open (elem) { + function open (elem, where) { let info = getInfo(elem.wrappedJSObject); + let doOpen = function (url) liberator.open(url, where); + if (elem.tagName === 'IMG' && elem.src) { if (openParent) { let p = elem.parentNode; if (p.tagName === 'A' && /(gif|png|jpe?g)$/i.test(p.href)) - return liberator.open(p.href, liberator.NEW_TAB); + return doOpen(p.href); } - return liberator.open(elem.src, liberator.NEW_TAB); + return doOOpen(elem.src); } let site = @@ -204,14 +211,19 @@ let INFO = return site; })(); + if (site) { + if (useVLC && site.vlc) { + doOpen = function (url) io.run('vlc', [url]); + } + for each (let [n, v] in info) { [n, v] = [String(n), String(v)]; if (site.name && !site.name.test(n)) continue; let m = n.match(site.value) || v.match(site.value); if (m) - return site.url(Array.slice(m, 1)); + return doOpen(site.url(Array.slice(m, 1))); } } @@ -222,7 +234,7 @@ let INFO = commandline.input( 'Select the link you wish to open: ', function (url) { - liberator.open(url, where); + doOpen(url); }, { default: urls[0][1], @@ -237,7 +249,7 @@ let INFO = modeName, DESC, function (elem) { - liberator.open(open(elem), where); + open(elem, where); }, function () '//embed | //object | //img | //iframe' ); diff --git a/loginManager.js b/loginManager.js index da8bdbd..80b1eab 100644 --- a/loginManager.js +++ b/loginManager.js @@ -217,14 +217,16 @@ Object.defineProperty( enumerable: true, get: function(){ let currentURI = makeURI(buffer.URL); - for (let n in Iterator(this, true)){ - if (n === "auto") continue; - let s = this[n]; - if (s.URL && s.URL.test(buffer.URL)) - return s; - for (let [, h] in Iterator(s.HOST)){ - let sURI = makeURI(h); - if (sURI.host === currentURI.host) return s; + if (/^https?/.test(currentURI.scheme)) { + for (let n in Iterator(this, true)){ + if (n === "auto") continue; + let s = this[n]; + if (s.URL && s.URL.test(buffer.URL)) + return s; + for (let [, h] in Iterator(s.HOST)){ + let sURI = makeURI(h); + if (sURI.host === currentURI.host) return s; + } } } // XXX (補完に|エラーを)出さないためのダミー diff --git a/newtab.js b/newtab.js new file mode 100644 index 0000000..b9e9061 --- /dev/null +++ b/newtab.js @@ -0,0 +1,80 @@ +/* NEW BSD LICENSE {{{ +Copyright (c) 2012, 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 # +# に参考になる日本語訳がありますが、有効なのは上記英文となります。 # +################################################################################### + +}}} */ + +// INFO {{{ +let INFO = +<> + <plugin name="Newtab" version="1.0.0" + href="http://vimpr.github.com/" + summary="Add about:newtab URL Completer." + lang="en-US" + xmlns="http://vimperator.org/namespaces/liberator"> + <author email="anekos@snca.net">anekos</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p> + Add completer. + <code><![CDATA[ + :set complete+=n + ]]></code> + </p> + </plugin> +</>; +// }}} + +(function () { + + // ~/repos/mozilla-central/browser/modules/NewTabUtils.jsm + + let NTU = {}; + Cu.import("resource:///modules/NewTabUtils.jsm", NTU); + + delete completion.urlCompleters.n; + + completion.addUrlCompleter( + 'n', + 'about:newtab completer', + function (context, args) { + context.title = ['about:newtab', 'Title']; + context.filters = [CompletionContext.Filter.textAndDescription]; + context.completions = [ + [t.url, t.title] + for ([, t] in Iterator(NTU.NewTabUtils.links.getLinks())) + ]; + } + ); + +})(); + +// vim:sw=2 ts=2 et si fdm=marker: diff --git a/prevent-pseudo-domain.js b/prevent-pseudo-domain.js index 58fe064..7981874 100644 --- a/prevent-pseudo-domain.js +++ b/prevent-pseudo-domain.js @@ -1,28 +1,30 @@ // ORIGINAL: http://vimperator.g.hatena.ne.jp/kei-s/20101005 (function() { - hasMultipleWords = function(s) { + function hasMultipleWords (s) { return s.split(/\s/).length > 1; } - isWord = function(s) { + function isWord (s) { return /^[^\s\.]+$/i.test(s); } - isIPAddress = function(s) { + function isIPAddress (s) { return /^([0-9]+\.){3}([0-9]+)$/i.test(s); } - hasScheme = function(s) { + function hasScheme (s) { return /^([a-zA-Z0-9-]+):/i.test(s); } let tldList = "local|museum|travel|aero|arpa|coop|info|jobs|name|nvus|biz|com|edu|gov|int|mil|net|org|pro|xxx|ac|ad|ae|af|ag|ai|ak|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|ct|cu|cv|cx|cy|cz|dc|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fl|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hi|hk|hm|hn|hr|ht|hu|ia|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|ks|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mi|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|nd|ne|nf|ng|nh|ni|nj|nl|nm|no|np|nr|nu|ny|nz|oh|ok|om|or|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ri|ro|ru|rw|sa|sb|sc|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tx|tz|ua|ug|uk|um|us|ut|uy|uz|va|vc|ve|vg|vi|vn|vt|vu|wa|wf|wi|ws|wv|wy|ye|yt|yu|za|zm|zw".split("|"); - hasTLD = function(s) { + function hasTLD (s) { let m = s.match(/^(?:(?:[^\.\s:\/]+\.)+?)+([a-zA-Z]+)(?::\d+)?(?:\/[^\s]*)?$/i); return m != null && tldList.indexOf(m[1]) != -1; } - requirePrefix = function(s) { + function requirePrefix (s) { + if (!s) + return false; let validators = [hasMultipleWords, isWord, isIPAddress, hasScheme, hasTLD]; return !(validators.some(function(validator) { return validator(s); })); } diff --git a/readcatlater.js b/readcatlater.js index 60ce3f1..770bc3e 100644 --- a/readcatlater.js +++ b/readcatlater.js @@ -147,12 +147,11 @@ let PLUGIN_INFO = const history = Cc["@mozilla.org/browser/nav-history-service;1"]. getService(Ci.nsINavHistoryService); - let [folderId, folderGUID] = [prefs.get('folderId', false), prefs.get('folderGUID', false)]; + let folderId = prefs.get('folderId', false); - if (!(folderGUID && folderId && (folderId == bookmarks.getItemIdForGUID(folderGUID)))) { + if (!folderId) { folderId = bookmarks.createFolder(bookmarks.toolbarFolder, FOLDER_NAME, bookmarks.DEFAULT_INDEX); prefs.set('folderId', folderId); - prefs.set('folderGUID', bookmarks.getItemGUID(folderId)); } /* diff --git a/sbmcommentsviewer.js b/sbmcommentsviewer.js index 650950d..3e6d599 100644 --- a/sbmcommentsviewer.js +++ b/sbmcommentsviewer.js @@ -251,8 +251,8 @@ var SBM = { //{{{ } var pageURL, items; try { - pageURL = evaluateXPath(rss, '//rss:channel/rss:link')[0].textContent; - items = evaluateXPath(rss, '//rss:item'); + pageURL = evaluateXPath(rss, '//channel/link')[0].textContent; + items = evaluateXPath(rss, '//item'); } catch(e){ liberator.log(e); } @@ -313,7 +313,7 @@ var SBM = { //{{{ }); return c; } else { - liberator.log('Faild: LivedoorClip'); + liberator.log('Failed: LivedoorClip'); } } }, //}}} @@ -341,7 +341,7 @@ var SBM = { //{{{ }); return c; } else { - liberator.log('Faild: Buzzurl'); + liberator.log('Failed: Buzzurl'); } } }, //}}} @@ -368,7 +368,7 @@ var SBM = { //{{{ }); return c; } else { - liberator.echo('Faild: Topsy'); + liberator.echo('Failed: Topsy'); } } } //}}} @@ -39,7 +39,7 @@ let PLUGIN_INFO = <name lang="ja">すてら</name> <description>For Niconico/YouTube/Vimeo, Add control commands and information display(on status line).</description> <description lang="ja">ニコニコ動画/YouTube/Vimeo 用。操作コマンドと情報表示(ステータスライン上に)追加します。</description> - <version>0.33.0</version> + <version>0.33.1</version> <author mail="anekos@snca.net" homepage="http://d.hatena.ne.jp/nokturnalmortum/">anekos</author> <license>new BSD License (Please read the source code comments of this plugin)</license> <license lang="ja">修正BSDライセンス (ソースコードのコメントを参照してください)</license> @@ -1031,7 +1031,7 @@ Thanks: fetch: function (filepath) { // all(1080p,720p,480p,360p) -> 37, 22, 35, 34, 5 // FIXME 一番初めが最高画質だと期待 - let cargs = content.wrappedJSObject.yt.config_.PLAYER_CONFIG.args; + let cargs = content.wrappedJSObject.yt.playerConfig.args; cargs.url_encoded_fmt_stream_map.split(',')[0].split('&').forEach(function(x) { let [key, val] = x.split('='); if (key == 'url') { @@ -1160,7 +1160,7 @@ Thanks: fetch: function (filepath) { // all(1080p,720p,480p,360p) -> 37, 22, 35, 34, 5 // FIXME 一番初めが最高画質だと期待 - let cargs = content.wrappedJSObject.yt.config_.PLAYER_CONFIG.args; + let cargs = content.wrappedJSObject.yt.playerConfig.args; cargs.url_encoded_fmt_stream_map.split(',')[0].split('&').forEach(function(x) { let [key, val] = x.split('='); if (key == 'url') { @@ -1351,9 +1351,15 @@ Thanks: ]; }, - get player () content.document.getElementById('flvplayer').wrappedJSObject.__proto__, + get player () { + return ( + U.getElementById('flvplayer') + || + U.getElementById('external_nicoplayer') + ).wrappedJSObject.__proto__; + }, - get playerContainer () U.getElementByIdEx('flvplayer_container'), + // get playerContainer () U.getElementByIdEx('flvplayer_container'), get ready () { try { diff --git a/twittperator.js b/twittperator.js index a28d2ba..76e4023 100644 --- a/twittperator.js +++ b/twittperator.js @@ -2,7 +2,7 @@ * The MIT License * * Copyright (c) 2010 teramako - * Copyright (c) 2010-2011 anekos + * Copyright (c) 2010-2012 anekos * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,7 @@ // INFO {{{ let INFO = <> - <plugin name="Twittperator" version="1.17.1" + <plugin name="Twittperator" version="1.18.0" href="https://github.com/vimpr/vimperator-plugins/raw/master/twittperator.js" summary="Twitter Client using OAuth and Streaming API"> <author email="teramako@gmail.com" href="http://d.hatena.ne.jp/teramako/">teramako</author> @@ -39,6 +39,7 @@ let INFO = <h2>Command</h2> - Use completion for comfort. <item> + <tags><![CDATA[:twittperator :tw]]></tags> <spec>:tw<oa>ittperator</oa> -getPIN</spec> <description> <p>Opens the page to authorize Twittperator and get your PIN from Twitter.</p> @@ -174,7 +175,7 @@ let INFO = Write the plugin. </p> </plugin> - <plugin name="Twittperator" version="1.17.1" + <plugin name="Twittperator" version="1.18.0" href="https://github.com/vimpr/vimperator-plugins/raw/master/twittperator.js" lang="ja" summary="OAuth/StreamingAPI対応Twitterクライアント"> @@ -188,6 +189,7 @@ let INFO = <h2>Command</h2> - 適当に補完しましょう。 <item> + <tags><![CDATA[:twittperator :tw]]></tags> <spec>:tw<oa>ittperator</oa> -getPIN</spec> <description> <p>PINコード取得ページを開きます。</p> @@ -2123,34 +2125,19 @@ let INFO = Store.set("consumerKey", "GQWob4E5tCHVQnEVPvmorQ"); Store.set("consumerSecret", "gVwj45GaW6Sp7gdua6UFyiF910ffIety0sD1dv36Cz8"); // }}} - - // アクセストークン取得前 {{{ - function preSetup() { - commands.addUserCommand(["tw[ittperator]"], "Twittperator setup command", - function(args) { - if (args["-getPIN"]) { - tw.getRequestToken(function(url) { - liberator.open(url, { where: liberator.NEW_TAB }); - }); - Twittperator.echo("Please get PIN code and execute\n :tw -setPIN {PINcode}"); - } else if (args["-setPIN"]) { - tw.setPin(args["-setPIN"]); - } - }, { - options: [ - [["-getPIN"], commands.OPTION_NOARG], - [["-setPIN"], commands.OPTION_STRING, null, null] - ], - }, true); - } // }}} - // アクセストークン取得後 {{{ - function setup() { - function rejectMine(st) + let Predicates = { // {{{ + notMine: function (st) let (n = setting.screenName) - (n ? (!st.user || st.user.screen_name !== n) : st); + (n ? (!st.user || st.user.screen_name !== n) : st), + mine: function (st) + (!Predicates.notMine(st)) + }; // }}} + let Completers = (function() { // {{{ + function rt(st) + ("retweeted_status" in st ? st.retweeted_status : st); - function seleceMine(st) - (!rejectMine(st)); + function removeNewLine(text) + text.replace(/\r\n|[\r\n]/g, ' '); function setTimelineCompleter(context) { // {{{ function statusObjectFilter(item) @@ -2193,290 +2180,307 @@ let INFO = } } // }}} - const Completers = (function() { // {{{ - function rt(st) - ("retweeted_status" in st ? st.retweeted_status : st); - - function removeNewLine(text) - text.replace(/\r\n|[\r\n]/g, ' '); - - function completer(generator, nort) { - let getHistory = nort ? function() history - : function() history.map(rt); - return function(filter) { - function completer(context, args) { - let cs = []; - for (let [, it] in Iterator(getHistory())) { - if (filter && !filter(it)) - continue; - let item = generator(it); - if (item[0]) - cs.push(item); - } - context.completions = cs; + function completer(generator, nort) { + let getHistory = nort ? function() history + : function() history.map(rt); + return function(filter) { + function completer(context, args) { + let cs = []; + for (let [, it] in Iterator(getHistory())) { + if (filter && !filter(it)) + continue; + let item = generator(it); + if (item[0]) + cs.push(item); } - return makeTimelineCompleter(completer); + context.completions = cs; } + return makeTimelineCompleter(completer); } + } - return { - name: - completer(function(s) [s.user.screen_name, s]), - atname: - completer(function(s) ['@' + s.user.screen_name, s]), - text: - completer(function(s) [removeNewLine(s.text), s]), - id: - completer(function(s) [s.id, s]), - rawid: - completer(function(s) [s.id, s], true), - name_id: - completer(function(s) ["@" + s.user.screen_name + "#" + s.id, s]), - name_id_text: - completer(function(s) ["@" + s.user.screen_name + "#" + s.id + ": " + removeNewLine(s.text), s]), - screenName: - completer(function(s) [s.user.screen_name, s]), - statusPage: - completer(function(s) [s.user.screen_name + '/status/' + s.id , s]), - hashtag: - function(filter) { - return makeTimelineCompleter(function(context, args){ - context.completions = [ - [ - ['#' + h.text for ([, h] in Iterator(s.entities.hashtags))].join(' '), - s - ] - for ([, s] in Iterator(history)) - if (s.entities && s.entities.hashtags && s.entities.hashtags[0]) + return { + name: + completer(function(s) [s.user.screen_name, s]), + atname: + completer(function(s) ['@' + s.user.screen_name, s]), + text: + completer(function(s) [removeNewLine(s.text), s]), + id: + completer(function(s) [s.id, s]), + rawid: + completer(function(s) [s.id, s], true), + name_id: + completer(function(s) ["@" + s.user.screen_name + "#" + s.id, s]), + name_id_text: + completer(function(s) ["@" + s.user.screen_name + "#" + s.id + ": " + removeNewLine(s.text), s]), + screenName: + completer(function(s) [s.user.screen_name, s]), + statusPage: + completer(function(s) [s.user.screen_name + '/status/' + s.id , s]), + hashtag: + function(filter) { + return makeTimelineCompleter(function(context, args){ + context.completions = [ + [ + ['#' + h.text for ([, h] in Iterator(s.entities.hashtags))].join(' '), + s ] - }); - } - }; - })(); // }}} - - const SubCommand = function(init) { // {{{ - if (!(init.completer instanceof Array)) - init.completer = [init.completer]; - - return { - __proto__: init, - get expr() { - return RegExp( - "^" + - this.command.map(function(c) - let (r = util.escapeRegex(c)) - (/^\W$/.test(c) ? r : r + "( |$)") - ).join("|") - ); - }, - match: function(s) s.match(this.expr), - action: function(args) init.action(args.literalArg.replace(this.expr, "").trim()) - }; - }; // }}} - - const SubCommands = [ // {{{ - SubCommand({ - command: ["+"], - description: "Fav a tweet", - action: function(arg) { - let m = arg.match(/^\d+/); - if (m) - Twitter.favorite(m[0]); - }, - timelineCompleter: true, - completer: Completers.id(rejectMine) - }), - SubCommand({ - command: ["-"], - description: "Unfav a tweet", - action: function(arg) { - let m = arg.match(/^\d+/); - if (m) - Twitter.favorite(m[0]); + for ([, s] in Iterator(history)) + if (s.entities && s.entities.hashtags && s.entities.hashtags[0]) + ] + }); + } + }; + })(); // }}} + let SubCommand = function(init) { // {{{ + if (!(init.completer instanceof Array)) + init.completer = [init.completer]; + + return { + __proto__: init, + get expr() { + return RegExp( + "^" + + this.command.map(function(c) + let (r = util.escapeRegex(c)) + (/^\W$/.test(c) ? r : r + "( |$)") + ).join("|") + ); + }, + match: function(s) s.match(this.expr), + action: function(args) init.action(args.literalArg.replace(this.expr, "").trim()) + }; + }; // }}} + let SubCommands = [ // {{{ + SubCommand({ + command: ["+"], + description: "Fav a tweet", + action: function(arg) { + let m = arg.match(/^\d+/); + if (m) + Twitter.favorite(m[0]); + }, + timelineCompleter: true, + completer: Completers.id(Predicates.notMine) + }), + SubCommand({ + command: ["-"], + description: "Unfav a tweet", + action: function(arg) { + let m = arg.match(/^\d+/); + if (m) + Twitter.favorite(m[0]); + }, + timelineCompleter: true, + completer: Completers.id(Predicates.notMine) + }), + SubCommand({ + command: ["@"], + description: "Show mentions or follower tweets", + action: function(arg) { + if (arg.length > 0) { + Twittperator.showUserTimeline(arg); + } else { + Twittperator.showTwitterMentions(); + } + }, + timelineCompleter: true, + completer: Completers.name() + }), + SubCommand({ + command: ["?"], + description: "Twitter search", + action: function(arg) Twittperator.showTwitterSearchResult(arg), + completer: [ + function (context, args) { + let lst = [[buffer.URL, 'Current Tab']]; + let w = buffer.getCurrentWord(); + if (w && w.length) + lst.push([w, 'Current word']); + context.completions = lst; }, - timelineCompleter: true, - completer: Completers.id(rejectMine) - }), - SubCommand({ - command: ["@"], - description: "Show mentions or follower tweets", - action: function(arg) { - if (arg.length > 0) { - Twittperator.showUserTimeline(arg); - } else { - Twittperator.showTwitterMentions(); + Completers.text() + ] + }), + SubCommand({ + command: ["/"], + description: "Open link", + action: function(arg) Twittperator.openLink(arg), + timelineCompleter: true, + completer: Completers.text(function(s) /https?:\/\//.test(s.text)) + }), + SubCommand({ + command: ["delete"], + description: "Delete status", + action: function(arg) { + let m = arg.match(/^\d+/); + if (m) + Twitter.destroy(m[0]); + }, + timelineCompleter: true, + completer: Completers.rawid(Predicates.selectMine) + }), + SubCommand({ + command: ["activity"], + description: "Activity Summary", + action: function(arg) { + Twittperator.activitySummary(arg); + }, + timelineCompleter: true, + completer: Completers.id(function(st) st.id) + }), + SubCommand({ + command: ["info"], + description: "Display status information", + action: function(arg) { + function dtdd(obj) { + let items = <></>; + for (let [n, v] in Iterator(obj)) { + let cont = (v && typeof v === "object") ? dtdd(v) : v; + items += <><dt>{n}</dt><dd>{cont}</dd></>; } - }, - timelineCompleter: true, - completer: Completers.name() - }), - SubCommand({ - command: ["?"], - description: "Twitter search", - action: function(arg) Twittperator.showTwitterSearchResult(arg), - completer: [ - function (context, args) { - let lst = [[buffer.URL, 'Current Tab']]; - let w = buffer.getCurrentWord(); - if (w && w.length) - lst.push([w, 'Current word']); - context.completions = lst; - }, - Completers.text() - ] - }), - SubCommand({ - command: ["/"], - description: "Open link", - action: function(arg) Twittperator.openLink(arg), - timelineCompleter: true, - completer: Completers.text(function(s) /https?:\/\//.test(s.text)) - }), - SubCommand({ - command: ["delete"], - description: "Delete status", - action: function(arg) { - let m = arg.match(/^\d+/); - if (m) - Twitter.destroy(m[0]); - }, - timelineCompleter: true, - completer: Completers.rawid(seleceMine) - }), - SubCommand({ - command: ["activity"], - description: "Activity Summary", - action: function(arg) { - Twittperator.activitySummary(arg); - }, - timelineCompleter: true, - completer: Completers.id(function(st) st.id) - }), - SubCommand({ - command: ["info"], - description: "Display status information", - action: function(arg) { - function dtdd(obj) { - let items = <></>; - for (let [n, v] in Iterator(obj)) { - let cont = (v && typeof v === "object") ? dtdd(v) : v; - items += <><dt>{n}</dt><dd>{cont}</dd></>; - } - return <dl>{items}</dl>; - } + return <dl>{items}</dl>; + } - let m = arg.match(/^\d+/); - if (!m) - return; - let id = m[0]; - history.filter(function(st) st.id === id).map(dtdd).forEach(liberator.echo); - }, - timelineCompleter: true, - completer: Completers.rawid(function(st) st.id) - }), - SubCommand({ - command: ["lookupuser"], - description: "Lookup users", - action: function(arg) { - Twittperator.lookupUser(arg.split(/\s+/)); - }, - timelineCompleter: true, - completer: Completers.screenName() - }), - SubCommand({ - command: ["track"], - description: "Track the specified words.", - action: function(arg) { - if (arg.trim().length > 0) { - Store.set("trackWords", arg); - TrackingStream.start({track: arg}); - } else { - TrackingStream.stop(); - } - }, - completer: function(context, args) { - let cs = []; - if (setting.trackWords) - cs.push([setting.trackWords, "Global variable"]); - if (Store.get("trackWords")) - cs.push([Store.get("trackWords"), "Current tracking words"]); - context.completions = cs; + let m = arg.match(/^\d+/); + if (!m) + return; + let id = m[0]; + history.filter(function(st) st.id === id).map(dtdd).forEach(liberator.echo); + }, + timelineCompleter: true, + completer: Completers.rawid(function(st) st.id) + }), + SubCommand({ + command: ["lookupuser"], + description: "Lookup users", + action: function(arg) { + Twittperator.lookupUser(arg.split(/\s+/)); + }, + timelineCompleter: true, + completer: Completers.screenName() + }), + SubCommand({ + command: ["track"], + description: "Track the specified words.", + action: function(arg) { + if (arg.trim().length > 0) { + Store.set("trackWords", arg); + TrackingStream.start({track: arg}); + } else { + TrackingStream.stop(); } - }), - SubCommand({ - command: ["home"], - description: "Open user home.", - action: function(arg) liberator.open("http://twitter.com/" + arg, liberator.NEW_TAB), - timelineCompleter: true, - completer: Completers.screenName(rejectMine) - }), - SubCommand({ - command: ["status"], - description: "Open status page.", - action: function(arg) liberator.open("http://twitter.com/" + arg, liberator.NEW_TAB), - timelineCompleter: true, - completer: Completers.statusPage(function (s) s.id) - }), - SubCommand({ - command: ["thread"], - description: "Show tweets thread.", - action: function(arg) { - function showThread () { - Twittperator.showTL(thread); - } - function getStatus(id, next) { - let result; - if (history.some(function (it) (it.id == id && (result = it)))) { - return next(result); - } - // XXX エラーの時はなにか表示しておくべき? - tw.jsonGet("statuses/show/" + id, null, function(res) next(res), showThread); + }, + completer: function(context, args) { + let cs = []; + if (setting.trackWords) + cs.push([setting.trackWords, "Global variable"]); + if (Store.get("trackWords")) + cs.push([Store.get("trackWords"), "Current tracking words"]); + context.completions = cs; + } + }), + SubCommand({ + command: ["home"], + description: "Open user home.", + action: function(arg) liberator.open("http://twitter.com/" + arg, liberator.NEW_TAB), + timelineCompleter: true, + completer: Completers.screenName(Predicates.notMine) + }), + SubCommand({ + command: ["status"], + description: "Open status page.", + action: function(arg) liberator.open("http://twitter.com/" + arg, liberator.NEW_TAB), + timelineCompleter: true, + completer: Completers.statusPage(function (s) s.id) + }), + SubCommand({ + command: ["thread"], + description: "Show tweets thread.", + action: function(arg) { + function showThread () { + Twittperator.showTL(thread); + } + function getStatus(id, next) { + let result; + if (history.some(function (it) (it.id == id && (result = it)))) { + return next(result); } - function trace(st) { - thread.push(st); - if (st.in_reply_to_status_id) { - getStatus(st.in_reply_to_status_id, trace); - } else { - showThread(); - } + // XXX エラーの時はなにか表示しておくべき? + tw.jsonGet("statuses/show/" + id, null, function(res) next(res), showThread); + } + function trace(st) { + thread.push(st); + if (st.in_reply_to_status_id) { + getStatus(st.in_reply_to_status_id, trace); + } else { + showThread(); } + } - Twittperator.echo("Start thread tracing.."); - let thread = []; - getStatus(parseInt(arg), trace); - }, - timelineCompleter: true, - completer: Completers.id(function (it) it.in_reply_to_status_id) - }), - SubCommand({ - command: ["resetoauth"], - description: "Reset OAuth Information", - action: function(arg) { - Twittperator.confirm( - 'Do you want to reset OAuth information?', - function () { - Store.remove("consumerKey"); - Store.remove("consumerSecret"); - Store.remove("token"); - Store.remove("tokenSecret"); - Store.save(); - Twittperator.echo("OAuth information were reset."); - } - ); - }, - timelineCompleter: false, - completer: Completers.id(function (it) it.in_reply_to_status_id) - }), - SubCommand({ - command: ["findpeople"], - description: "Find people with the words.", - action: function(arg) Twittperator.showUsersSeachResult(arg), - }), - ]; // }}} + Twittperator.echo("Start thread tracing.."); + let thread = []; + getStatus(parseInt(arg), trace); + }, + timelineCompleter: true, + completer: Completers.id(function (it) it.in_reply_to_status_id) + }), + SubCommand({ + command: ["resetoauth"], + description: "Reset OAuth Information", + action: function(arg) { + Twittperator.confirm( + 'Do you want to reset OAuth information?', + function () { + Store.remove("consumerKey"); + Store.remove("consumerSecret"); + Store.remove("token"); + Store.remove("tokenSecret"); + Store.save(); + Twittperator.echo("OAuth information were reset."); + } + ); + }, + timelineCompleter: false, + completer: Completers.id(function (it) it.in_reply_to_status_id) + }), + SubCommand({ + command: ["findpeople"], + description: "Find people with the words.", + action: function(arg) Twittperator.showUsersSeachResult(arg), + }), + ]; + + SubCommands.add = function(subCmd) { + this.push(subCmd); + return; + }; // }}} + // アクセストークン取得前 {{{ + function preSetup() { + commands.addUserCommand(["tw[ittperator]"], "Twittperator setup command", + function(args) { + if (args["-getPIN"]) { + tw.getRequestToken(function(url) { + liberator.open(url, { where: liberator.NEW_TAB }); + }); + Twittperator.echo("Please get PIN code and execute\n :tw -setPIN {PINcode}"); + } else if (args["-setPIN"]) { + tw.setPin(args["-setPIN"]); + } + }, { + options: [ + [["-getPIN"], commands.OPTION_NOARG], + [["-setPIN"], commands.OPTION_STRING, null, null] + ], + }, true); + } // }}} + // アクセストークン取得後 {{{ + function setup() { function findSubCommand(s) { // {{{ - for (let [, cmd] in Iterator(SubCommands)) { + for (let [, cmd] in util.Array(SubCommands)) { let m = cmd.match(s); if (m) return [cmd, m]; @@ -2531,15 +2535,15 @@ let INFO = if (m = arg.match(/^D\s+/)) { context.title = "Entry"; context.advance(m[0].length); - Completers.name(rejectMine)(context, args); + Completers.name(Predicates.notMine)(context, args); return; } else if (m = arg.match(/(RT\s+)@.*$/)) { (m.index === 0 ? Completers.name_id - : Completers.name_id_text)(m.index === 0 && rejectMine)(context, args); + : Completers.name_id_text)(m.index === 0 && Predicates.notMine)(context, args); } else if (m = tailMatch(/(^|\b|\s)#[^#\s]*$/, arg)) { Completers.hashtag()(context, args); } else if (m = tailMatch(/(^|\b|\s)@[^@\s]*$/, arg)) { - (m.index === 0 ? Completers.name_id(rejectMine) : Completers.atname(rejectMine))(context, args); + (m.index === 0 ? Completers.name_id(Predicates.notMine) : Completers.atname(Predicates.notMine))(context, args); } if (m) @@ -2655,6 +2659,9 @@ let INFO = __context__.Twitter = Twitter; __context__.Utils = Utils; __context__.Store = Store; + __context__.SubCommand = SubCommand; + __context__.SubCommands = SubCommands; + __context__.Completers = Completers; Twittperator.loadPlugins(); diff --git a/twittperator/browsing.tw b/twittperator/browsing.tw new file mode 100644 index 0000000..6eeeda7 --- /dev/null +++ b/twittperator/browsing.tw @@ -0,0 +1,131 @@ +/* NEW BSD LICENSE {{{ +Copyright (c) 2012, Jagua. +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 # +# ɎQlɂȂ{܂ALȂ̂͏LpƂȂ܂B # +################################################################################### + +}}} */ + +/* + * Please write the below line into .vimperatorrc. + * let g:twittperator_plugin_browsing = 1 + * + * You can add the settings for each site + * by setting liberator.globalVariables.tw_browsing_format. + */ + +// INFO {{{ +let INFO = +<> + <plugin name="Now Browsing! Now Reading!" version="1.0.0" + href="http://vimpr.github.com/" + summary="twittperator plugin. assist to tweet about a site you are browsing now." + lang="en-US" + xmlns="http://vimperator.org/namespaces/liberator"> + <author homepage="https://github.com/Jagua">Jagua</author> + <license>New BSD License</license> + <project name="Vimperator" minVersion="3.0"/> + <p>twittperator plugin. assist to tweet about a site you are browsing now.</p> + <item> + <tags>:tw!browsing</tags> + <tags>:tw!reading</tags> + <spec>:tw!browsing <a>comment</a></spec> + <description><p>make a :tw Now browsing prompt</p></description> + <tags>g:tw_browsing_format</tags> + <spec>g:tw_browsing_format = <a>FORMATS OF EACH SITE</a></spec> + <description><p>setting sample</p><code><![CDATA[ +javascript<<EOM +liberator.globalVariables.tw_browsing_format = [{ + url: /^http:\/\/www\.youtube\.com\/watch\?v=[a-zA-Z0-9]+/, + format: function (title, url, selection, comment) { + let r = url; + if (url.match(/^http:\/\/www\.youtube\.com\/watch\?v=([a-zA-Z0-9]+)/)) { + r = 'http://youtu.be/' + RegExp.$1; + } + return title + ' ' + r + ' ' + comment; + }, + },{ + url: /.*/, + format: function (title, url, selection, comment) { + return (selection ? '"' + selection + '" ' : '') + (comment ? comment + ' ' : '') + 'Now reading: ' + title + ' ' + url; + }, + }]; +EOM + ]]></code></description> + </item> + </plugin> +</>; +// }}} + + +(function () { + const TW = liberator.plugins.twittperator; + + var format = liberator.globalVariables.tw_browsing_format || []; + + const default_format = [{ + url: /.*/, + format: function (title, url, selection, comment) { + return (selection ? '"' + selection + '" ' : '') + (comment ? comment + ' ' : '') + 'Now browsing: ' + title + ' ' + url; + }, + }]; + + format = format.concat(default_format); + + function browsing(comment) { + var tweet = ''; + var title = buffer.title; + var url = buffer.URL; + var selection = window.content.getSelection().toString(); + + format.forEach(function (def) { + if (url.match(def.url) && tweet == '') + tweet = def.format(title, url, selection, comment); + }); + return tweet; + } + + ['browsing', 'reading'].forEach(function (cmdName) { + TW.SubCommands.add( + TW.SubCommand({ + command: [cmdName], + description: 'Now ' + cmdName, + action: function(arg) { + setTimeout(function () { + commandline.open(':', 'tw ' + browsing(arg), modes.EX); + }, 100); + }, + timelineComplete: false, + }) + ); + }); + +})(); + +// vim: set et fdm=syntax fenc= ft=javascript sts=2 sw=2 ts=2 : diff --git a/twittperator/copy.tw b/twittperator/copy.tw new file mode 100644 index 0000000..50a280a --- /dev/null +++ b/twittperator/copy.tw @@ -0,0 +1,24 @@ +/* + * Please write the below line into .vimperatorrc. + * let g:twittperator_plugin_copy = 1 + * + */ + +(function () { + const TW = liberator.plugins.twittperator; + + TW.SubCommands.add( + TW.SubCommand({ + command: ['copy'], + description: "Copy a tweet", + action: function(arg) { + util.copyToClipboard(arg); + }, + timelineComplete: true, + completer: TW.Completers.text(function(s) s.id) + }) + ); +})(); + +// vim: set et fdm=syntax fenc= ft=javascript sts=2 sw=2 ts=2 : + diff --git a/twittperator/eject-alert.tw b/twittperator/eject-alert.tw index 9e6fe5a..08b3eaf 100644 --- a/twittperator/eject-alert.tw +++ b/twittperator/eject-alert.tw @@ -1,16 +1,17 @@ /* * Please write the below line into .vimperatorrc. - * let g:twittperator_plugin_reply_eject_alert = 1 + * let g:twittperator_plugin_eject_alert = 1 * let g:twittperator_screen_name = "<YOUR_SCREEN_NAME>" */ (function () { let screenName = liberator.globalVariables.twittperator_screen_name; + let dev = function () (liberator.globalVariables.twittperator_plugin_eject_alert_device || ''); plugins.twittperator.ChirpUserStream.addListener( function onMsg (msg, raw) { if (msg.text && msg.user && msg.in_reply_to_screen_name === screenName) - io.system('eject && eject -t'); + io.system('sh -c "' + ['eject', dev(), '&&', 'eject', '-t', dev()].join(' ') + '" &'); } ); })(); diff --git a/twittperator/mstrans.tw b/twittperator/mstrans.tw new file mode 100644 index 0000000..9f4a582 --- /dev/null +++ b/twittperator/mstrans.tw @@ -0,0 +1,24 @@ +/* + * Please write the below line into .vimperatorrc. + * let g:twittperator_plugin_mstrans = 1 + * + * Require: mstrans.js + */ + +(function () { + const TW = liberator.plugins.twittperator; + + TW.SubCommands.add( + TW.SubCommand({ + command: ['mstrans'], + description: "Translate a tweet", + action: function(arg) { + liberator.execute('mstrans ' + arg); + }, + timelineComplete: true, + completer: TW.Completers.text(function(s) s.id) + }) + ); +})(); + +// vim: set et fdm=syntax fenc= ft=javascript sts=2 sw=2 ts=2 : diff --git a/twittperator/ril.tw b/twittperator/ril.tw new file mode 100644 index 0000000..2b9c430 --- /dev/null +++ b/twittperator/ril.tw @@ -0,0 +1,21 @@ +/* + * Please write the below line into .vimperatorrc. + * let g:twittperator_plugin_ril = 1 + */ + +(function () { + const TW = liberator.plugins.twittperator; + + TW.SubCommands.add( + TW.SubCommand({ + command: ['ril'], + action: function(arg) { + liberator.execute('readitlater add https://twitter.com/' + arg); + }, + timelineCompleter: true, + completer: TW.Completers.statusPage(function(s) s.id) + }) + ); +})(); + +// vim: sw=2 ts=2 et fdm=marker ft=javascript: diff --git a/twittperator/rt.tw b/twittperator/rt.tw new file mode 100644 index 0000000..fde9194 --- /dev/null +++ b/twittperator/rt.tw @@ -0,0 +1,44 @@ +/* + * Please write the below line into .vimperatorrc. + * let g:twittperator_plugin_rt = 1 + */ + +(function () { + const TW = liberator.plugins.twittperator; + + TW.SubCommands.add( + TW.SubCommand({ + command: ['rt'], + description: 'Official retweet', + action: function(arg) { + setTimeout(function () { + commandline.open(':', 'tw RT ' + arg, modes.EX); + }, 100); + }, + timelineComplete: true, + completer: TW.Completers.name_id(function(s) s.id) + }) + ); + + TW.SubCommands.add( + TW.SubCommand({ + command: ['urt'], + description: 'Unofficial retweet', + action: function(arg) { + arg.match(/^@([a-zA-Z0-9_]+)#\d+: (.*)$/); + var screen_name = RegExp.$1; + var text = RegExp.$2; + if (screen_name && text) { + setTimeout(function () { + commandline.open(':', 'tw RT @' + screen_name + ': ' + text, modes.EX); + }, 100); + } + }, + timelineComplete: true, + completer: TW.Completers.name_id_text(function(s) s.id) + }) + ); + +})(); + +// vim: set et fdm=syntax fenc= ft=javascript sts=2 sw=2 ts=2 : diff --git a/twittperator/twsidebar.tw b/twittperator/twsidebar.tw index 0961c00..a9cc9ce 100755..100644 --- a/twittperator/twsidebar.tw +++ b/twittperator/twsidebar.tw @@ -38,6 +38,12 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () { // リストの最大保持数 listMax: 100, + // リストの表示順(昇順/降順) + listAscendingOrder: true, + + // ツイートされる度に最新ツイート位置までスクロールする + listAutoScroll: true, + // 日本語だけ for filter stream jpOnly: true, @@ -48,7 +54,13 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () { dontStop: true, // サイドバーが閉じていても、こっそり開始しておく - silentStart: false + silentStart: false, + + // 配列かオブジェクトを返すと、変更できる。 + // 文字列 "reject" を返すと、そもそもツイートが表示されなくなる。 + modifier: function (msg, tab, streamName) { + return [msg, tab, streamName]; + } }; // 日本語判定 @@ -158,6 +170,17 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () { function append (t, tab, streamName) { tab = tab || 'home'; + let modified = Config.modifier && Config.modifier(t, tab, streamName); + if (modified) { + if (modified instanceof Array) { + [t, tab, streamName] = modified; + } if (modified === 'reject') { + return; + } else { + t = modified; + } + } + let now = JSON.stringify({name: t.name, text: t.text, tab: tab}); if (latest === now) { if (latestNode) @@ -172,13 +195,47 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () { let cntr = getSidebarWindow().document.getElementById('tw-anekos-sb-' + tab + '-list'); let dom = xmlToDom(messageToXML(t)); let repDom = dom.cloneNode(true); + let visibleIndex = cntr.getIndexOfFirstVisibleRow(); let len = cntr.itemCount; - cntr.appendChild(repDom); + if (Config.listAscendingOrder) { + cntr.appendChild(repDom); + } else { + cntr.insertBefore(repDom, cntr.firstChild); + visibleIndex += 1; + } latestNode = repDom; - cntr.scrollToIndex(len - 1); - if (len > Config.listMax) - cntr.removeChild(cntr.firstChild); + if (len > Config.listMax) { + if (Config.listAscendingOrder) { + cntr.removeChild(cntr.firstChild); + visibleIndex -= 1; + } else { + cntr.removeChild(cntr.lastChild); + } + len -= 1; + } + + if (Config.listAutoScroll) { + if (Config.listAscendingOrder) { + cntr.scrollToIndex(len - 1); + } else { + cntr.scrollToIndex(0); + } + } else { + if (Config.listAscendingOrder) { + if (len - visibleIndex < 10) { // 10 = 絶妙な値!これでいいのか! + cntr.scrollToIndex(len - 1); + } else { + cntr.scrollToIndex(visibleIndex); + } + } else { + if (visibleIndex < 3) { // 3 = 絶妙な値!これでいいのか! + cntr.scrollToIndex(0); + } else { + cntr.scrollToIndex(visibleIndex); + } + } + } } return append; @@ -237,8 +294,6 @@ liberator.modules.TWAnekoSB = ANekoSB = (function () { type: 'favorite' }; appendTweet(t, 'home', streamName); - appendTweet(t, 'debug', streamName); - Config.sound.debug.play(); } } catch (e) { liberator.log(e); diff --git a/video-controller.js b/video-controller.js index 8fa22c1..0368afd 100644 --- a/video-controller.js +++ b/video-controller.js @@ -97,6 +97,9 @@ let INFO = value = parseFloat(value); elem.volume = Math.min(value > 1 ? value / 100 : value, 100); }, + fullscreen: function (elem) { + elem.mozRequestFullScreen(); + }, seek: function (elem, value) { elem.currentTime = timeCodeToSec(value); } diff --git a/walk-input.js b/walk-input.js index 80cef02..f5dd445 100644 --- a/walk-input.js +++ b/walk-input.js @@ -1,6 +1,6 @@ // Vimperator plugin: 'Walk Input' // License: BSD -// Version: 1.2.3 +// Version: 1.3.0 // Maintainer: Takayama Fumihiko <tekezo@pqrs.org> // anekos <anekos@snca.net> @@ -20,7 +20,7 @@ // PLUGIN_INFO {{{ let INFO = -<plugin name="Walk-Input" version="1.2.3" +<plugin name="Walk-Input" version="1.3.0" href="http://github.com/vimpr/vimperator-plugins/blob/master/walk-input.js" summary="The focus walks 'input' and 'textarea' element." xmlns="http://vimperator.org/namespaces/liberator"> @@ -133,9 +133,12 @@ var walkinput = function (forward) { elem.element.focus(); }; -mappings.addUserMap([modes.NORMAL, modes.INSERT], ['<M-i>', '<A-i>'], +let mapForward = liberator.globalVariables.walk_input_map_forward || '<M-i> <A-i>' +let mapBackward = liberator.globalVariables.walk_input_map_backward || '<M-S-i> <A-S-i>' + +mappings.addUserMap([modes.NORMAL, modes.INSERT], mapForward.split(/\s+/), 'Walk Input Fields (Forward)', function () walkinput(true)); -mappings.addUserMap([modes.NORMAL, modes.INSERT], ['<M-S-i>', '<A-S-i>'], +mappings.addUserMap([modes.NORMAL, modes.INSERT], mapBackward.split(/\s+/), 'Walk Input Fields (Backward)', function () walkinput(false)); })(); |