root/lang/javascript/userscripts/reblogcommand.user.js

Revision 36509, 7.1 kB (checked in by ku, 7 years ago)

fx3.6 bug fix + more precise error handling.

Line 
1// ==UserScript==
2// @name           ReblogCommand
3// @namespace      http://white.s151.xrea.com/
4// @include        http://*
5// @include        https://*
6// @exclude        http://www.tumblr.com/share
7// ==/UserScript==
8
9(function() {
10
11        const ALLOW_OWN_DOMAIN = true;
12
13var boot = function() {
14        var $X = window.Minibuffer.$X;
15        var D  = window.Minibuffer.D;
16        var createDocumentFromString  = window.Minibuffer.createDocumentFromString;
17
18// ----------------------------------------------------------------------------
19// Reblog
20// ----------------------------------------------------------------------------
21
22        function isTumblrDashboardURL(url) {
23                return url.match("^http://www\\.tumblr\\.com/dashboard") ? true : false;
24        }
25
26        function isTumblrUserURL(url) {
27                return url.match("^https?://[^.]+\\.tumblr\\.com/post/(\\d+)") ||
28                        // tumblr allow to use own domain. but this is risky.
29                        // $X('id("tumblr_controls")[self::iframe]', Boolean)
30                        (ALLOW_OWN_DOMAIN && url.match("^https?://[^/]+/post/(\\d+)")) ? true : false;
31        }
32
33        function isLdrOrFldrURL(url) {
34                return url.indexOf('http://reader.livedoor.com/reader/') == 0 ||
35                       url.indexOf('http://reader.livedoor.com/public/') == 0 ||
36                       url.indexOf('http://fastladder.com/reader/') == 0 ||
37                       url.indexOf('http://fastladder.com/public/') == 0;
38        }
39
40        function getIDByPermalink(url) {
41                if (isTumblrUserURL(url)) {
42                        return RegExp.$1;
43                }
44                // return what ?
45                return false;
46        }
47
48        function getURLByID(id, token) {
49                if (token) return "http://www.tumblr.com/reblog/" + id + "/" + token + "?redirect_to=/dashboard";
50                return "http://www.tumblr.com/reblog/" + id;
51        }
52
53        // copy from tombloo
54        function unescapeHTML(s) {
55                return s.replace(/"/g, '"')
56                        .replace(/&lt;/g, '<')
57                        .replace(/&gt;/g, '>')
58                        .replace(/&amp;/g, '&');
59}
60
61        // copy from tombloo
62        function getReblogToken(url) {
63                url = unescapeHTML(url);
64                if (/&pid=([^&]*)&rk=([^&"]*)/.test(url) || /\/reblog\/([^\/]+)\/([^?]*)/.test(url))
65                        return {
66                                id    : RegExp.$1,
67                                token : RegExp.$2
68                        };
69        }
70
71        function parseParams(doc) {
72                // name() returns in lower case on fx3.6
73                var elms = $X('id("edit_post")//*[translate(name(),"input", "INPUT") ="INPUT" or translate(name(),"textarea", "TEXTAREA")="TEXTAREA" or translate(name(),"select", "SELECT")="SELECT"]', doc);
74                var params = {};
75                elms.forEach(function(elm) {
76                        params[elm.name] = elm.value;
77                });
78                return params;
79        }
80
81        function createPostData(params) {
82                var arr = [];
83                for (var param in params) {
84                if (param != "preview_post" && param != "send_to_twitter") {
85                                arr.push(encodeURIComponent(param));
86                                arr.push("=");
87                                arr.push(encodeURIComponent(params[param]));
88                                arr.push("&");
89                        }
90                }
91                return arr.join('');
92        }
93
94        function reblog(aURL) {
95                var id = getIDByPermalink(aURL);
96                var d;
97                with (D()) {
98                        d = Deferred();
99                        if (!id) {
100                                wait(0).next(function() { d.call(); });
101                                return d;
102                        }
103                }
104                window.Minibuffer.status('ReblogCommand'+id, 'Reblog ...');
105                d = D();
106                var url = aURL;
107                var reblogd = d.xhttp.get(url).
108                next(function(res) {
109                        var token = getReblogToken(res.responseText.match('iframe src="((?:\\"|[^"])*)"')[1]);
110                        url = getURLByID(token.id, token.token);
111                        return d.xhttp.get(url);
112                }).
113                next(function(res) {
114                        var params = parseParams( createDocumentFromString(res.responseText));
115                        if (!params.form_key)
116                                reblogd.fail("invalid reblog params.");
117                        return d.xhttp.post(url, createPostData(params));
118                }).
119                next(function(res) {
120                        if ( ! res.finalUrl.match( /^http:\/\/www\.tumblr\.com\/dashboard/ ) )
121                                reblogd.fail("reblog failed.");
122                        window.Minibuffer.status('ReblogCommand'+id, 'Reblog ... done.', 100);
123                        d.call();
124                }).
125                error(function(e) {
126                        var message = e.message || e;
127                        if (confirm(message + '\nreblog manually ? \n' + url)) reblogManually(url);
128                        d.call();
129                });
130                return d;
131        }
132
133        function reblogManually(aURL) {
134                var url = aURL;
135                var d = D();
136                d.xhttp.get(url).
137                next(function(res) {
138                        var token = getReblogToken(res.responseText.match('iframe src="((?:\\"|[^"])*)"')[1]);
139                        url = getURLByID(token.id, token.token);
140                        GM_openInTab(url);
141                });
142        }
143
144        function spClearPins(url) {
145                unsafeWindow.pin.remove(url);
146        }
147
148// ----------------------------------------------------------------------------
149// Command
150// ----------------------------------------------------------------------------
151
152        function getTargetCommand() {
153                var target_cmd = '';
154                if (isLdrOrFldrURL(window.location.href)) {
155                        target_cmd = 'pinned-or-current-link';
156                } else if (isTumblrUserURL(window.location.href)) {
157                        target_cmd = 'location';
158                } else if (window.LDRize) {
159                        target_cmd = 'pinned-or-current-link';
160                } else {
161                        target_cmd = 'location';
162                }
163                return target_cmd;
164        }
165
166        window.Minibuffer.addShortcutkey({
167                key: 't',
168                description: 'Reblog',
169                command: function() {
170                        var target_cmd = getTargetCommand();
171                        var clear_pin  = '';
172                        if (isLdrOrFldrURL(window.location.href)) {
173                                if (!window.Minibuffer.execute('pinned-or-current-link').filter(isTumblrUserURL).length) {
174                                        target_cmd = 'current-link';
175                                        clear_pin = '';
176                                } else {
177                                        clear_pin = '-c';
178                                }
179                        } else {
180                                clear_pin = (target_cmd == 'pinned-or-current-link') ? ' | clear-pin' : '';
181                        }
182                        window.Minibuffer.execute(target_cmd + ' | reblog ' + clear_pin);
183                }});
184
185        window.Minibuffer.addShortcutkey({
186                key: 'T',
187                description: 'Reblog manually',
188                command: function() {
189                        var target_cmd = getTargetCommand();
190                        var clear_pin = (target_cmd == 'pinned-or-current-link') ? ' | clear-pin' : '';
191                        window.Minibuffer.execute(target_cmd + ' | reblog -m' + clear_pin );
192                }});
193
194        window.Minibuffer.addCommand({
195                name: 'reblog',
196                command: function(stdin) {
197                        var args = this.args;
198                        var urls = [];
199                        if (!stdin.length) {
200                                if (isTumblrDashboardURL(window.location.href.toString())) {
201                                        var link = window.Minibuffer.execute('current-link');
202                                        if (link) urls = [link.toString()];
203                                } else {
204                                        // command line is just 'reblog'
205                                        urls = [window.location.href];
206                                }
207                        } else if (isLdrOrFldrURL(window.location.href)) {
208                                var tmp = [];
209                                stdin.forEach(function(url, index) { tmp[index] = url; });
210                                urls = tmp;
211                        } else if (stdin.every(function(a) { return typeof a == 'string' })) {
212                                // command line is 'location | reblog'
213                                urls = stdin;
214                        } else if (stdin.every(function(a) { return a && a.nodeName == 'A'; })) {
215                                // command line is 'pinned-or-current-link | reblog'
216                                urls = stdin.map(function(node) { return node.href; });
217                        }
218
219                        // reblog
220                        if (args.length == 1 && args[0] == '-m') {
221                                urls.forEach(reblogManually);
222                        } else {
223                                urls = urls.filter(isTumblrUserURL);
224                                if (isLdrOrFldrURL(window.location.href) && args.length == 1 && args[0] == '-c') {
225                                        urls.forEach(spClearPins);
226                                }
227                                if (!urls.length) return stdin;
228                                var lst = urls.map(reblog);
229                                if (lst.length > 1) {
230                                        with (D()) {
231                                                parallel(lst).wait(2).
232                                                next(function() { window.Minibuffer.status('ReblogCommand','Everything is OK', 1000); });
233                                        }
234                                }
235                        }
236                        return stdin;
237                }
238        });
239};
240        if (document.body.id == 'tinymce')
241                return;
242
243        if (window.Minibuffer) {
244                boot();
245        } else {
246                window.addEventListener('GM_MinibufferLoaded', boot, false);
247        }
248
249})();
Note: See TracBrowser for help on using the browser.