Falkon Develop
Cross-platform Qt-based web browser
speeddial.user.js
Go to the documentation of this file.
1// ==UserScript==
2// @name _falkon_speeddial
3// @run-at document-end
4// @include falkon:speeddial
5// ==/UserScript==
6
7var scriptData = {};
8var editingId = -1;
9var ignoreNextChanged = false;
10
11function b64DecodeUnicode(str) {
12 return decodeURIComponent(atob(str).split('').map(function(c) {
13 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
14 }).join(''));
15}
16
17function emitChanged(pages)
18{
19 ignoreNextChanged = true;
20 external.speedDial.changed(pages);
21}
22
23function addSpeedDial()
24{
25 onEditClick(addBox('', scriptData.newPage , ''));
26 alignPage();
27}
28
29function configureSpeedDial()
30{
31 // ====================== LOAD SETTINGS ========================= //
32 $('#PgInRow').val(scriptData.maxPagesRow);
33 $('#sliderValuePg').html(scriptData.maxPagesRow);
34 $('#SdSize').val(scriptData.dialWidth);
35 $('#SdSizeToggle').prop('checked', scriptData.dialWidth != 240);
36 $('#sliderValueSd').html(scriptData.dialWidth);
37 $('#BgImgSelSiz').val(scriptData.bSize).attr('selected', 'selected');
38 $('#BgImgToggle').prop('checked', scriptData.imgBackground != "");
39 $('#SdCntrToggle').prop('checked', scriptData.sdCenter == "true");
40 $('#SdLockDials').prop('checked', scriptData.lockDials == "true");
41 $('#BgImgToggle').is(':checked') ? $('#BgImgSel').removeAttr('disabled') : $('#BgImgSel').attr('disabled', 'disabled');
42 $('#BgImgToggle').is(':checked') ? $('#BgImgSelSiz').removeAttr('disabled') : $('#BgImgSelSiz').attr('disabled', 'disabled');
43 $('#SdSizeToggle').is(':checked') ? $('#SdSize').removeAttr('disabled') : $('#SdSize').attr('disabled', 'disabled');
44 if ($('#BgImgToggle').prop('checked') != true) {
45 $('#ImgSelectorMenu').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
46 $('#BgImgSel').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
47 $('#BgImgSelSiz').css('visibility', 'hidden');
48 }
49 if ($('#SdSizeToggle').prop('checked') != true)
50 $('#SdSizeStateColor').css('color', 'rgba(0,0,0, 0.0)');
51 // ======================== SHOW DIALOG ======================== //
52 $('#fadeOverlay2').css({'filter' : 'alpha(opacity=100)'}).fadeIn();
53 $('#fadeOverlay2').click(function() { $(this).fadeOut('slow'); });
54 $('#settingsBox').click(function(event) { event.stopPropagation(); });
55}
56
57function escapeTitle(title) {
58 title = title.replace(/"/g, '"');
59 title = title.replace(/'/g, ''');
60 return title;
61}
62
63function unescapeTitle(title) {
64 title = title.replace(/"/g, '"');
65 title = title.replace(/'/g, '\'');
66 return title;
67}
68
69function escapeUrl(url) {
70 url = url.replace(/"/g, '');
71 url = url.replace(/'/g, '');
72 return url;
73}
74
75function onRemoveClick(box) {
76 removeBox($(box).index());
77}
78
79function onFetchTitleClick(checkbox) {
80 var displayStyle;
81 checkbox.checked ? displayStyle = 'hidden' : displayStyle = 'visible';
82 $('#titleLine').css({'visibility' : displayStyle });
83}
84
85function hideEditBox() {
86 $('#fadeOverlay').fadeOut("slow", function() {$("#fadeOverlay").remove();});
87}
88
89function onEditClick(box) {
90 editingId = $(box).index();
91 var boxUrl = $(box).children('a').first().attr('href');
92 var boxTitle = escapeTitle($(box).children('span').first().text());
93 if (boxUrl === '')
94 boxUrl = 'http://';
95
96 $('body').append('<div id="fadeOverlay" class="overlay" style="display:none;">' +
97 '<div id="overlay-edit">' +
98 '<img src="' + $(box).children('img').first().attr('src') + '"> ' +
99 '<table><tr><td>' + scriptData.url + ': </td><td>' +
100 '<input type="text" id="formUrl" value="' + boxUrl + '"></td></tr>' +
101 '<tr id="titleLine"><td>' + scriptData.title + ': </td><td>' +
102 '<input type="text" id="formTitle" value="' + boxTitle + '"></td></tr>' +
103 '<tr><td></td><td><div class="checkbox"><input type="checkbox" id="fetchTitle">' +
104 '<label for="fetchTitle"></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ' + scriptData.titleFetchTitle + ' </div></td></tr>' +
105 '</table><p class="buttonbox"><input id="cancelEditBox" type="button" value=" ' + scriptData.cancel + ' ">&nbsp;&nbsp;&nbsp;' +
106 '<input id="acceptEditBox" type="button" value=" ' + scriptData.edit + ' "></p>' +
107 '</div></div>');
108
109 $('#fetchTitle').click(function() {
110 onFetchTitleClick(this);
111 });
112
113 $('#cancelEditBox').click(function() {
114 hideEditBox();
115 location.reload();
116 });
117
118 $('#acceptEditBox').click(boxEdited);
119
120 $('#fadeOverlay').css({'filter' : 'alpha(opacity=100)'}).fadeIn();
121 $('#fadeOverlay').click(function() {hideEditBox()});
122 $('#overlay-edit').click(function(event) { event.stopPropagation(); });
123
124 var temp = $('#formUrl').val();
125 $('#formUrl').focus().val('').val(temp); // focus and move cursor to end
126}
127
128function onReloadClick(box) {
129 var url = $(box).children('a').first().attr('href');
130 var img = $(box).children('img').first();
131
132 if (url === '')
133 return;
134
135 $(img).attr('src', scriptData.loadingImage);
136 external.speedDial.loadThumbnail(url, false);
137}
138
139function boxEdited() {
140 if (editingId == -1)
141 return;
142
143 external.speedDial.urlFromUserInput($('#formUrl').val(), function(newUrl) {
144 var box = document.getElementById('quickdial').getElementsByTagName('div')[editingId];
145 var a = box.getElementsByTagName('a')[0];
146 var originalUrl = a.getAttribute('href');
147 setBoxUrl(editingId, newUrl);
148 setBoxTitle(editingId, $('#formTitle').val());
149 var changedUrl = a.getAttribute('href');
150 var fetchTitleChecked = document.getElementById('fetchTitle').checked;
151
152 var pages = allPages();
153
154 if (fetchTitleChecked || (originalUrl != changedUrl && changedUrl !== '') ) {
155 var img = box.getElementsByTagName('img')[0];
156 img.setAttribute('src', scriptData.loadingImage);
157
158 $('#fadeOverlay').fadeOut("slow", function() {
159 $("#fadeOverlay").remove();
160 });
161 external.speedDial.loadThumbnail(a.getAttribute('href'), fetchTitleChecked);
162 } else {
163 hideEditBox();
164 }
165 emitChanged(pages);
166 });
167}
168
169function allPages() {
170 var urls = $('a[class="boxUrl"]');
171 var titles = $('span[class="boxTitle"]');
172 var value = "";
173 $('div.entry').each(function(i) {
174 var url = $(this).children('a').first().attr('href');
175 var title = $(this).children('span[class="boxTitle"]').first().text();
176
177 value += 'url:"' + escapeUrl(url) + '"|title:"' + escapeTitle(title) + '";';
178 });
179
180 return value;
181}
182
183function reloadAll() {
184 if (confirm(scriptData.titleWarnRel))
185 $('div.entry').each(function(i) {
186 onReloadClick($(this));
187 });
188}
189
190function addBox(url, title, img_source) {
191 var div = document.createElement('div');
192 div.setAttribute('class', 'entry');
193 var img = document.createElement('img');
194 img.setAttribute('src', img_source);
195 var a = document.createElement('a');
196 a.setAttribute('href', url);
197 a.setAttribute('class', 'boxUrl');
198 var span1 = document.createElement('span');
199 span1.setAttribute('class', 'boxTitle');
200 span1.setAttribute('title', unescapeTitle(title));
201 span1.innerText = unescapeTitle(title);
202 var span2 = document.createElement('span');
203 span2.setAttribute('class', 'edit');
204 span2.setAttribute('title', scriptData.titleEdit);
205 span2.onclick = function() {
206 onEditClick(div);
207 };
208 var span3 = document.createElement('span');
209 span3.setAttribute('class', 'close');
210 span3.setAttribute('title', scriptData.titleRemove);
211 span3.onclick = function() {
212 onRemoveClick(div);
213 };
214 var span4 = document.createElement('span');
215 span4.setAttribute('class', 'reload');
216 span4.setAttribute('title', scriptData.titleReload);
217 span4.onclick = function() {
218 onReloadClick(div);
219 };
220 div.appendChild(img);
221 div.appendChild(img);
222 div.appendChild(a);
223 div.appendChild(span1);
224 div.appendChild(span2);
225 div.appendChild(span3);
226 div.appendChild(span4);
227 document.getElementById("quickdial").appendChild(div);
228 if (img_source == scriptData.loadingImage) {
229 external.speedDial.loadThumbnail(url, false);
230 }
231 return div;
232}
233
234function setBoxImage(id, img_source) {
235 var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
236 if (box === undefined)
237 return;
238 var img = box.getElementsByTagName('img')[0];
239 img.setAttribute('src', img_source + '?' + new Date());
240}
241
242function setTitleToUrl(url, title) {
243 var changed = false;
244 var boxes = document.getElementById('quickdial').getElementsByTagName('div');
245 for (i = 0; i < boxes.length; ++i) {
246 var box = boxes[i];
247
248 if (box === undefined)
249 continue;
250
251 var boxUrl = box.getElementsByTagName('a')[0].getAttribute('href');
252 if (url != boxUrl)
253 continue;
254
255 var span = box.getElementsByTagName('span')[0];
256 if (span.innerText != title) {
257 changed = true;
258 span.innerText = title;
259 }
260 }
261 if (changed)
262 emitChanged(allPages());
263}
264
265function setImageToUrl(url, img_source) {
266 var aElement = $('a[href="' + url + '"]');
267 $(aElement).each(function() {
268 var box = $(this).parent();
269 var imgElement = $(box).children("img").first();
270 if ($(imgElement).size() == 0)
271 return;
272 $(imgElement).attr('src', img_source/* + '?' + new Date()*/);
273 });
274}
275
276function setBoxUrl(id, url) {
277 var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
278 if (box === undefined)
279 return;
280 var a = box.getElementsByTagName('a')[0];
281 a.setAttribute('href', url);
282}
283
284function setBoxTitle(id, title) {
285 var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
286 if (box === undefined)
287 return;
288 var span = box.getElementsByTagName('span')[0];
289 span.innerText = title;
290}
291
292function removeBox(id) {
293 if (confirm(scriptData.titleWarn))
294 var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
295 if (box === undefined)
296 return;
297 var url = box.getElementsByTagName('a')[0].getAttribute('href');
298 document.getElementById("quickdial").removeChild(box);
299 alignPage();
300 external.speedDial.removeImageForUrl(url);
301 emitChanged(allPages());
302}
303
304function alignPage() {
305 var dialWidth = parseInt(scriptData.dialWidth);
306 var dialHeight = Math.floor(Math.round(dialWidth / 1.54));
307 $('head').append('<style>#quickdial img{height:auto;width:'+dialWidth+'px}</style>');
308 $('#quickdial div.entry').css({'width' : dialWidth + 'px',
309 'height' : dialHeight + 'px'});
310 var fullwidth = $(window).width();
311 var width = Math.floor(fullwidth - 76);
312 var height = $(window).height();
313 var boxWidth = Math.floor(dialWidth + 12);
314 var boxHeight = dialHeight + 22;
315 var maxBoxes = Math.floor(width / boxWidth);
316 if (maxBoxes > scriptData.maxPagesRow) maxBoxes = scriptData.maxPagesRow;
317 if (maxBoxes < 1) maxBoxes = 1;
318 var maxwidth = maxBoxes * boxWidth;
319 $("#quickdial").css('width', maxwidth + 'px');
320 var boxesCount = $("#quickdial").children("div").size();
321 var rows = Math.ceil(boxesCount / maxBoxes);
322 var margintop = (height - rows * boxHeight) / 2;
323 if (margintop < 0) margintop = 0;
324 $("#quickdial").css('margin-top', margintop + 'px');
325 $("span.boxTitle").css('font-size', ((dialHeight - dialWidth / 1.77) / 1.5) + 'px');
326 if (scriptData.sdCenter == "true") {
327 enableCentering();
328 } else {
329 disableCentering();
330 }
331}
332
333function bgImageSel() {
334 external.speedDial.getOpenFileName(function(arr) {
335 if (arr.length) {
336 document.getElementById('BgImgHold').value = arr[0];
337 document.getElementById('BgImgHoldUrl').value = arr[1];
338 bgImgUpdate();
339 }
340 });
341}
342
343function saveSettings() {
344 scriptData.maxPagesRow = $('#PgInRow').val();
345 scriptData.dialWidth = $('#SdSize').val();
346 scriptData.sdCenter = $('#SdCntrToggle').prop('checked');
347 scriptData.lockDials = $('#SdLockDials').prop('checked');
348 external.speedDial.setBackgroundImage($('#BgImgHoldUrl').val());
349 external.speedDial.setBackgroundImageSize($('#BgImgSelSiz').val());
350 external.speedDial.setPagesInRow(scriptData.maxPagesRow);
351 external.speedDial.setSdSize(scriptData.dialWidth);
352 external.speedDial.setSdCentered(scriptData.sdCenter == "true");
353 external.speedDial.setLockDials(scriptData.lockDials == "true");
354 alignPage();
355}
356
357function bgImgToggle() {
358 var check = document.getElementById('BgImgToggle');
359 var BgImgSel = document.getElementById('BgImgSel');
360 var BgImgHoldUrl = document.getElementById('BgImgHoldUrl');
361 var BgImgSz = document.getElementById('BgImgSelSiz');
362 BgImgSel.disabled = (check.checked ? false : true);
363 BgImgHoldUrl.disabled = (check.checked ? false : true);
364 BgImgSz.disabled = (check.checked ? false : true);
365 BgImgHoldUrl.value = (check.checked ? scriptData.urlBackground : '');
366 if ($('#BgImgToggle').prop('checked') != true) {
367 $('#ImgSelectorMenu').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
368 $('#BgImgSel').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
369 $('#BgImgSelSiz').css('visibility', 'hidden');
370 } else {
371 $('#ImgSelectorMenu').css({'color' : '#eaeaea', 'text-shadow' : '1px 1px 2px #000000, 0 0 1em #000000'});
372 $('#BgImgSel').css({'color' : '#eaeaea', 'text-shadow' : '1px 1px 2px #000000, 0 0 1em #000000'});
373 $('#BgImgSelSiz').css('visibility', 'visible');
374 };
375}
376
377function sdSizeToggle() {
378 var check = document.getElementById('SdSizeToggle');
379 var SdSize = document.getElementById('SdSize');
380 var SdSizeSl = document.getElementById('sliderValueSd');
381 SdSize.disabled = (check.checked ? false : true);
382 SdSize.value = (check.checked ? SdSize.value : 240);
383 SdSizeSl.innerHTML = (check.checked ? scriptData.dialWidth : 240);
384 if ($('#SdSizeToggle').prop('checked') != true) {
385 $('#SdSizeStateColor').css('color', 'rgba(0,0,0, 0.0)');
386 } else {
387 $('#SdSizeStateColor').css('color', '#eaeaea')
388 }
389}
390
391function bgImgUpdate() {
392 var imgUrl = document.getElementById('BgImgHold').value;
393 var imgSize = document.getElementById('BgImgSelSiz').value;
394 var imgThumb = document.getElementById('thumb');
395 imgThumb.style.backgroundImage = 'url("' + imgUrl + '")';
396 imgThumb.title = imgUrl.substring(imgUrl.lastIndexOf('/')+1);
397 imgThumb.style.backgroundSize = imgSize;
398 document.documentElement.style.backgroundImage = 'url("' + imgUrl + '")';
399 document.documentElement.style.backgroundSize = imgSize;
400}
401
402function enableCentering() {
403 $('#quickdial div.entry').css({
404 float: 'none',
405 display: 'inline-block'
406 });
407}
408
409function disableCentering() {
410 $('#quickdial div.entry').css({
411 float: scriptData.leftStr,
412 display: 'block'
413 });
414}
415
416function init() {
417 scriptData = document.getElementById("script-data").dataset;
418
419 document.getElementById("button-configure-speed-dial").onclick = configureSpeedDial;
420 document.getElementById("button-add-speed-dial").onclick = addSpeedDial;
421 document.getElementById("PgInRow").oninput = function() {
422 $('#sliderValuePg').html(this.value);
423 };
424 document.getElementById("SdSizeToggle").onchange = sdSizeToggle;
425 document.getElementById("SdSize").oninput = function() {
426 $('#sliderValueSd').html(this.value);
427 };
428 document.getElementById("BgImgSel").onclick = function() {
429 if ($('#BgImgSelSiz').attr('disabled') != 'disabled') {
430 bgImageSel();
431 }
432 };
433 document.getElementById("BgImgToggle").onchange = function() {
434 bgImgToggle();
435 bgImgUpdate();
436 };
437 document.getElementById("BgImgSelSiz").onchange = bgImgUpdate;
438 document.getElementById("button-cancel").onclick = function() {
439 $('#fadeOverlay2').fadeOut('slow');
440 location.reload();
441 };
442 document.getElementById("button-apply").onclick = function() {
443 saveSettings();
444 $('#fadeOverlay2').fadeOut('slow');
445 location.reload();
446 };
447
448 if (scriptData.imgBackground == '') {
449 document.getElementById("html").style.backgroundSize = "cover";
450 }
451
452 $(document).keyup(function(e) {
453 if (editingId == -1)
454 return;
455 if (e.keyCode == 13)
456 boxEdited();
457 else if (e.keyCode == 27)
458 $('#fadeOverlay').click();
459 });
460
461 var pages = JSON.parse(b64DecodeUnicode(scriptData.initialScript));
462 for (var i = 0; i < pages.length; ++i) {
463 var page = pages[i];
464 addBox(page.url, page.title, page.img);
465 }
466
467 external.speedDial.pagesChanged.connect(function() {
468 if (ignoreNextChanged) {
469 ignoreNextChanged = false;
470 return;
471 }
472 window.location.reload();
473 });
474
475 external.speedDial.thumbnailLoaded.connect(setImageToUrl);
476 external.speedDial.pageTitleLoaded.connect(setTitleToUrl);
477
478 $(window).resize(function() { alignPage(); });
479 $("#quickdial").sortable({
480 revert: true,
481 cursor: 'move',
482 containment: 'document',
483 opacity: 0.8,
484 distance: 40,
485 disabled: scriptData.lockDials == "true",
486 start: function(event, ui) {
487 disableCentering();
488 },
489 stop: function(event, ui) {
490 if (scriptData.sdCenter == "true")
491 enableCentering();
492 },
493 update: function(event, ui) {
494 emitChanged(allPages());
495 }
496 });
497
498 alignPage();
499}
500
501%JQUERY%
502%JQUERY-UI%
503
504// Initialize
505if (window._falkon_external) {
506 init();
507} else {
508 document.addEventListener("_falkon_external_created", init);
509}