##// END OF EJS Templates
Gif is a searchable image too
neko259 -
r1851:6df43500 default
parent child Browse files
Show More
@@ -1,220 +1,220 b''
1 /*
1 /*
2 @licstart The following is the entire license notice for the
2 @licstart The following is the entire license notice for the
3 JavaScript code in this page.
3 JavaScript code in this page.
4
4
5
5
6 Copyright (C) 2013 neko259
6 Copyright (C) 2013 neko259
7
7
8 The JavaScript code in this page is free software: you can
8 The JavaScript code in this page is free software: you can
9 redistribute it and/or modify it under the terms of the GNU
9 redistribute it and/or modify it under the terms of the GNU
10 General Public License (GNU GPL) as published by the Free Software
10 General Public License (GNU GPL) as published by the Free Software
11 Foundation, either version 3 of the License, or (at your option)
11 Foundation, either version 3 of the License, or (at your option)
12 any later version. The code is distributed WITHOUT ANY WARRANTY;
12 any later version. The code is distributed WITHOUT ANY WARRANTY;
13 without even the implied warranty of MERCHANTABILITY or FITNESS
13 without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
14 FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
15
15
16 As additional permission under GNU GPL version 3 section 7, you
16 As additional permission under GNU GPL version 3 section 7, you
17 may distribute non-source (e.g., minimized or compacted) forms of
17 may distribute non-source (e.g., minimized or compacted) forms of
18 that code without the copy of the GNU GPL normally required by
18 that code without the copy of the GNU GPL normally required by
19 section 4, provided you include this license notice and a URL
19 section 4, provided you include this license notice and a URL
20 through which recipients can access the Corresponding Source.
20 through which recipients can access the Corresponding Source.
21
21
22 @licend The above is the entire license notice
22 @licend The above is the entire license notice
23 for the JavaScript code in this page.
23 for the JavaScript code in this page.
24 */
24 */
25
25
26 var ITEM_VOLUME_LEVEL = 'volumeLevel';
26 var ITEM_VOLUME_LEVEL = 'volumeLevel';
27 var IMAGE_TYPES = ['png', 'jpg', 'jpeg', 'bmp'];
27 var IMAGE_TYPES = ['png', 'jpg', 'jpeg', 'bmp', 'gif'];
28
28
29 /**
29 /**
30 * An email is a hidden file to prevent spam bots from posting. It has to be
30 * An email is a hidden file to prevent spam bots from posting. It has to be
31 * hidden.
31 * hidden.
32 */
32 */
33 function hideEmailFromForm() {
33 function hideEmailFromForm() {
34 $('.form-email').parent().parent().hide();
34 $('.form-email').parent().parent().hide();
35 }
35 }
36
36
37 /**
37 /**
38 * Highlight code blocks with code highlighter
38 * Highlight code blocks with code highlighter
39 */
39 */
40 function highlightCode(node) {
40 function highlightCode(node) {
41 node.find('pre code').each(function(i, e) {
41 node.find('pre code').each(function(i, e) {
42 hljs.highlightBlock(e);
42 hljs.highlightBlock(e);
43 });
43 });
44 }
44 }
45
45
46 function updateFavPosts(data) {
46 function updateFavPosts(data) {
47 var includePostBody = $('#fav-panel').is(":visible");
47 var includePostBody = $('#fav-panel').is(":visible");
48
48
49 var allNewPostCount = 0;
49 var allNewPostCount = 0;
50
50
51 if (includePostBody) {
51 if (includePostBody) {
52 var favoriteThreadPanel = $('#fav-panel');
52 var favoriteThreadPanel = $('#fav-panel');
53 favoriteThreadPanel.empty();
53 favoriteThreadPanel.empty();
54 }
54 }
55
55
56 $.each($.parseJSON(data), function (_, dict) {
56 $.each($.parseJSON(data), function (_, dict) {
57 var newPostCount = dict.new_post_count;
57 var newPostCount = dict.new_post_count;
58 allNewPostCount += newPostCount;
58 allNewPostCount += newPostCount;
59
59
60 if (includePostBody) {
60 if (includePostBody) {
61 var favThreadNode = $('<div class="post"></div>');
61 var favThreadNode = $('<div class="post"></div>');
62 favThreadNode.append($(dict.post_url));
62 favThreadNode.append($(dict.post_url));
63 favThreadNode.append(' ');
63 favThreadNode.append(' ');
64 favThreadNode.append($('<span class="title">' + dict.title + '</span>'));
64 favThreadNode.append($('<span class="title">' + dict.title + '</span>'));
65
65
66 if (newPostCount > 0) {
66 if (newPostCount > 0) {
67 favThreadNode.append(' (<a href="' + dict.newest_post_link + '">+' + newPostCount + "</a>)");
67 favThreadNode.append(' (<a href="' + dict.newest_post_link + '">+' + newPostCount + "</a>)");
68 }
68 }
69
69
70 favoriteThreadPanel.append(favThreadNode);
70 favoriteThreadPanel.append(favThreadNode);
71
71
72 addRefLinkPreview(favThreadNode[0]);
72 addRefLinkPreview(favThreadNode[0]);
73 }
73 }
74 });
74 });
75
75
76 var newPostCountNode = $('#new-fav-post-count');
76 var newPostCountNode = $('#new-fav-post-count');
77 if (allNewPostCount > 0) {
77 if (allNewPostCount > 0) {
78 newPostCountNode.text('(+' + allNewPostCount + ')');
78 newPostCountNode.text('(+' + allNewPostCount + ')');
79 newPostCountNode.show();
79 newPostCountNode.show();
80 } else {
80 } else {
81 newPostCountNode.hide();
81 newPostCountNode.hide();
82 }
82 }
83 }
83 }
84
84
85 function initFavPanel() {
85 function initFavPanel() {
86 var favPanelButton = $('#fav-panel-btn');
86 var favPanelButton = $('#fav-panel-btn');
87 if (favPanelButton.length > 0 && typeof SharedWorker != 'undefined') {
87 if (favPanelButton.length > 0 && typeof SharedWorker != 'undefined') {
88 var worker = new SharedWorker($('body').attr('data-update-script'));
88 var worker = new SharedWorker($('body').attr('data-update-script'));
89 worker.port.onmessage = function(e) {
89 worker.port.onmessage = function(e) {
90 updateFavPosts(e.data);
90 updateFavPosts(e.data);
91 };
91 };
92 worker.onerror = function(event){
92 worker.onerror = function(event){
93 throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
93 throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")");
94 };
94 };
95 worker.port.start();
95 worker.port.start();
96
96
97 $(favPanelButton).click(function() {
97 $(favPanelButton).click(function() {
98 var favPanel = $('#fav-panel');
98 var favPanel = $('#fav-panel');
99 favPanel.toggle();
99 favPanel.toggle();
100
100
101 worker.port.postMessage({ includePostBody: favPanel.is(':visible')});
101 worker.port.postMessage({ includePostBody: favPanel.is(':visible')});
102
102
103 return false;
103 return false;
104 });
104 });
105
105
106 $(document).on('keyup.removepic', function(e) {
106 $(document).on('keyup.removepic', function(e) {
107 if(e.which === 27) {
107 if(e.which === 27) {
108 $('#fav-panel').hide();
108 $('#fav-panel').hide();
109 }
109 }
110 });
110 });
111 }
111 }
112 }
112 }
113
113
114 function setVolumeLevel(level) {
114 function setVolumeLevel(level) {
115 localStorage.setItem(ITEM_VOLUME_LEVEL, level);
115 localStorage.setItem(ITEM_VOLUME_LEVEL, level);
116 }
116 }
117
117
118 function getVolumeLevel() {
118 function getVolumeLevel() {
119 var level = localStorage.getItem(ITEM_VOLUME_LEVEL);
119 var level = localStorage.getItem(ITEM_VOLUME_LEVEL);
120 if (level == null) {
120 if (level == null) {
121 level = 1.0;
121 level = 1.0;
122 }
122 }
123 return level
123 return level
124 }
124 }
125
125
126 function processVolumeUser(node) {
126 function processVolumeUser(node) {
127 if (!window.localStorage) return;
127 if (!window.localStorage) return;
128 node.prop("volume", getVolumeLevel());
128 node.prop("volume", getVolumeLevel());
129 node.on('volumechange', function(event) {
129 node.on('volumechange', function(event) {
130 setVolumeLevel(event.target.volume);
130 setVolumeLevel(event.target.volume);
131 $("video,audio").prop("volume", getVolumeLevel());
131 $("video,audio").prop("volume", getVolumeLevel());
132 });
132 });
133 }
133 }
134
134
135 /**
135 /**
136 * Add all scripts than need to work on post, when the post is added to the
136 * Add all scripts than need to work on post, when the post is added to the
137 * document.
137 * document.
138 */
138 */
139 function addScriptsToPost(post) {
139 function addScriptsToPost(post) {
140 addRefLinkPreview(post[0]);
140 addRefLinkPreview(post[0]);
141 highlightCode(post);
141 highlightCode(post);
142 processVolumeUser(post.find("video,audio"));
142 processVolumeUser(post.find("video,audio"));
143 }
143 }
144
144
145 /**
145 /**
146 * Fix compatibility issues with some rare browsers
146 * Fix compatibility issues with some rare browsers
147 */
147 */
148 function compatibilityCrutches() {
148 function compatibilityCrutches() {
149 if (window.operamini) {
149 if (window.operamini) {
150 $('#form textarea').each(function() { this.placeholder = ''; });
150 $('#form textarea').each(function() { this.placeholder = ''; });
151 }
151 }
152 }
152 }
153
153
154 function addContextMenu() {
154 function addContextMenu() {
155 $.contextMenu({
155 $.contextMenu({
156 selector: '.file-menu',
156 selector: '.file-menu',
157 trigger: 'left',
157 trigger: 'left',
158
158
159 build: function($trigger, e) {
159 build: function($trigger, e) {
160 var fileSearchUrl = $trigger.data('search-url');
160 var fileSearchUrl = $trigger.data('search-url');
161 var isImage = IMAGE_TYPES.indexOf($trigger.data('type')) > -1;
161 var isImage = IMAGE_TYPES.indexOf($trigger.data('type')) > -1;
162 var hasUrl = fileSearchUrl.length > 0;
162 var hasUrl = fileSearchUrl.length > 0;
163 return {
163 return {
164 items: {
164 items: {
165 duplicates: {
165 duplicates: {
166 name: gettext('Duplicates search'),
166 name: gettext('Duplicates search'),
167 callback: function(key, opts) {
167 callback: function(key, opts) {
168 window.location = '/feed/?image=' + $trigger.data('filename');
168 window.location = '/feed/?image=' + $trigger.data('filename');
169 }
169 }
170 },
170 },
171 google: {
171 google: {
172 name: 'Google',
172 name: 'Google',
173 visible: isImage && hasUrl,
173 visible: isImage && hasUrl,
174 callback: function(key, opts) {
174 callback: function(key, opts) {
175 window.location = 'https://www.google.com/searchbyimage?image_url=' + fileSearchUrl;
175 window.location = 'https://www.google.com/searchbyimage?image_url=' + fileSearchUrl;
176 }
176 }
177 },
177 },
178 iqdb: {
178 iqdb: {
179 name: 'IQDB',
179 name: 'IQDB',
180 visible: isImage && hasUrl,
180 visible: isImage && hasUrl,
181 callback: function(key, opts) {
181 callback: function(key, opts) {
182 window.location = 'http://iqdb.org/?url=' + fileSearchUrl;
182 window.location = 'http://iqdb.org/?url=' + fileSearchUrl;
183 }
183 }
184 },
184 },
185 tineye: {
185 tineye: {
186 name: 'TinEye',
186 name: 'TinEye',
187 visible: isImage && hasUrl,
187 visible: isImage && hasUrl,
188 callback: function(key, opts) {
188 callback: function(key, opts) {
189 window.location = 'http://tineye.com/search?url=' + fileSearchUrl;
189 window.location = 'http://tineye.com/search?url=' + fileSearchUrl;
190 }
190 }
191 }
191 }
192 },
192 },
193 };
193 };
194 }
194 }
195 });
195 });
196 }
196 }
197
197
198 $( document ).ready(function() {
198 $( document ).ready(function() {
199 hideEmailFromForm();
199 hideEmailFromForm();
200
200
201 $("a[href='#top']").click(function() {
201 $("a[href='#top']").click(function() {
202 $("html, body").animate({ scrollTop: 0 }, "slow");
202 $("html, body").animate({ scrollTop: 0 }, "slow");
203 return false;
203 return false;
204 });
204 });
205
205
206 addImgPreview();
206 addImgPreview();
207
207
208 addRefLinkPreview();
208 addRefLinkPreview();
209
209
210 highlightCode($(document));
210 highlightCode($(document));
211
211
212 initFavPanel();
212 initFavPanel();
213
213
214 var volumeUsers = $("video,audio");
214 var volumeUsers = $("video,audio");
215 processVolumeUser(volumeUsers);
215 processVolumeUser(volumeUsers);
216
216
217 addContextMenu();
217 addContextMenu();
218
218
219 compatibilityCrutches();
219 compatibilityCrutches();
220 });
220 });
General Comments 0
You need to be logged in to leave comments. Login now