1
mirror of https://invent.kde.org/network/falkon.git synced 2024-11-11 01:22:10 +01:00

Rewrite internal sites to use user scripts instead of embedded code

It is no longer needed to setup web channel on unsafe js world
for internal pages, and thus it fixes issue where registering web
channel could fail in some cases.

BUG: 391875
FIXED-IN: 3.0.1
This commit is contained in:
David Rosca 2018-05-01 12:58:54 +02:00
parent bc26e9377c
commit 3787a606d3
No known key found for this signature in database
GPG Key ID: EBC3FC294452C6D8
12 changed files with 773 additions and 699 deletions

View File

@ -1071,26 +1071,29 @@ void MainApplication::setupUserScripts()
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
script.setWorldId(WebPage::SafeJsWorld);
script.setRunsOnSubFrames(true);
script.setSourceCode(Scripts::setupWebChannel(script.worldId()));
script.setSourceCode(Scripts::setupWebChannel());
m_webProfile->scripts()->insert(script);
// WebChannel for UnsafeJsWorld
QWebEngineScript script2;
script2.setName(QSL("_falkon_webchannel2"));
script2.setInjectionPoint(QWebEngineScript::DocumentCreation);
script2.setWorldId(WebPage::UnsafeJsWorld);
script2.setRunsOnSubFrames(true);
script2.setSourceCode(Scripts::setupWebChannel(script2.worldId()));
m_webProfile->scripts()->insert(script2);
// falkon:restore
QWebEngineScript falkonRestore;
falkonRestore.setWorldId(WebPage::SafeJsWorld);
falkonRestore.setSourceCode(QzTools::readAllFileContents(QSL(":html/restore.user.js")));
m_webProfile->scripts()->insert(falkonRestore);
// falkon:speeddial
QWebEngineScript falkonSpeedDial;
falkonSpeedDial.setWorldId(WebPage::SafeJsWorld);
falkonSpeedDial.setSourceCode(Scripts::setupSpeedDial());
m_webProfile->scripts()->insert(falkonSpeedDial);
// document.window object addons
QWebEngineScript script3;
script3.setName(QSL("_falkon_window_object"));
script3.setInjectionPoint(QWebEngineScript::DocumentCreation);
script3.setWorldId(WebPage::UnsafeJsWorld);
script3.setRunsOnSubFrames(true);
script3.setSourceCode(Scripts::setupWindowObject());
m_webProfile->scripts()->insert(script3);
QWebEngineScript documentWindowAddons;
documentWindowAddons.setName(QSL("_falkon_window_object"));
documentWindowAddons.setInjectionPoint(QWebEngineScript::DocumentCreation);
documentWindowAddons.setWorldId(WebPage::UnsafeJsWorld);
documentWindowAddons.setRunsOnSubFrames(true);
documentWindowAddons.setSourceCode(Scripts::setupWindowObject());
m_webProfile->scripts()->insert(documentWindowAddons);
}
void MainApplication::setUserStyleSheet(const QString &filePath)

View File

@ -4,11 +4,13 @@
<file>html/copyright</file>
<file>html/start.html</file>
<file>html/speeddial.html</file>
<file>html/speeddial.user.js</file>
<file>html/jquery.js</file>
<file>html/jquery-ui.js</file>
<file>html/loading.gif</file>
<file>html/config.html</file>
<file>html/restore.html</file>
<file>html/restore.user.js</file>
<file>html/tabcrash.html</file>
<file>html/close.svg</file>
<file>html/configure.svg</file>

View File

@ -133,165 +133,13 @@ li {padding: 5px;}
</style>
<script type="text/javascript">
var selectedRow = null;
function selectRow(row)
{
if (selectedRow) {
selectedRow.className = selectedRow.className.replace(/\bselected\b/, "");
}
row.className = row.className + " selected";
selectedRow = row;
}
function forEachInput(f)
{
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; ++i) {
f(inputs[i]);
}
}
function toggleWindow(e)
{
var win = e.getAttribute("data-window");
forEachInput(function(input) {
if (input.getAttribute("data-window") == win) {
input.checked = e.checked;
}
});
}
function toggleTab(e)
{
var win = e.getAttribute("data-window");
var winElement = null;
var checked = 0;
var total = 0;
forEachInput(function(input) {
if (input.getAttribute("data-window") != win) {
return;
}
if (!input.hasAttribute("data-tab")) {
winElement = input;
return;
}
if (input.checked) {
++checked;
}
++total;
});
if (checked == total) {
winElement.checked = true;
winElement.indeterminate = false;
} else if (checked > 0) {
winElement.indeterminate = true;
} else {
winElement.checked = false;
winElement.indeterminate = false;
}
}
function startNewSession()
{
document.getElementById("start-new-session-button").disabled = true;
external.recovery.startNewSession();
}
function restoreSession()
{
document.getElementById("restore-session-button").disabled = true;
var excludeWin = [];
var excludeTab = [];
forEachInput(function(input) {
if (input.checked || input.indeterminate || !input.hasAttribute("data-tab")) {
return;
}
excludeWin.unshift(input.getAttribute("data-window"));
excludeTab.unshift(input.getAttribute("data-tab"));
});
external.recovery.restoreSession(excludeWin, excludeTab);
}
function addWindow(winId)
{
var tr = document.createElement("tr");
tr.className = "window";
tr.onclick = function() { selectRow(tr); };
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "checkbox";
input.checked = true;
input.setAttribute("data-window", winId);
input.onclick = function() { toggleWindow(input); };
var span = document.createElement("span");
span.innerText = "%WINDOW% " + (winId + 1);
tr.appendChild(td);
td.appendChild(input);
td.appendChild(span);
document.getElementById("recovery-items").appendChild(tr);
}
function addTab(winId, tab)
{
var tr = document.createElement("tr");
tr.className = "tab";
tr.title = tab.url;
tr.onclick = function() { selectRow(tr); };
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "checkbox";
input.checked = true;
input.setAttribute("data-window", winId);
input.setAttribute("data-tab", tab.tab);
input.onclick = function() { toggleTab(input); };
var img = document.createElement("img");
img.src = tab.icon;
var span = document.createElement("span");
span.innerText = tab.title;
if (tab.pinned) {
span.innerText = "🖈 " + span.innerText;
}
if (tab.current) {
span.style.fontStyle = 'italic';
}
tr.appendChild(td);
td.appendChild(input);
td.appendChild(img);
td.appendChild(span);
document.getElementById("recovery-items").appendChild(tr);
}
function init()
{
var data = external.recovery.restoreData;
for (var i = 0; i < data.length; ++i) {
var win = data[i];
addWindow(win.window);
for (var j = 0; j < win.tabs.length; ++j) {
var tab = win.tabs[j];
addTab(win.window, tab);
}
}
}
</script>
</head>
<body>
<p hidden id="script-data"
data-window="%WINDOW%">
</p>
<div id="box">
<img class="warning" src="%IMAGE%" width=45>
<h1>%OOPS%</h1>
@ -319,22 +167,11 @@ function init()
</table>
<form>
<input class="button" type="submit" id="start-new-session-button" name="new-session" value="%BUTTON-START-NEW%" onclick="startNewSession();return false;">
<input class="button" type="submit" id="restore-session-button" name="restore-session" value=" %BUTTON-RESTORE% " onclick="restoreSession();return false;">
<input class="button" type="submit" id="start-new-session-button" name="new-session" value="%BUTTON-START-NEW%">
<input class="button" type="submit" id="restore-session-button" name="restore-session" value=" %BUTTON-RESTORE% ">
</form>
</div>
</div>
</body>
<script type="text/javascript">
// Initialize
if (window._falkon_external) {
init();
} else {
document.addEventListener("_falkon_external_created", init);
}
</script>
</html>

View File

@ -0,0 +1,183 @@
// ==UserScript==
// @name _falkon_restore
// @run-at document-end
// @include falkon:restore
// ==/UserScript==
(function() {
var scriptData = {};
var selectedRow = null;
function selectRow(row)
{
if (selectedRow) {
selectedRow.className = selectedRow.className.replace(/\bselected\b/, "");
}
row.className = row.className + " selected";
selectedRow = row;
}
function forEachInput(f)
{
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; ++i) {
f(inputs[i]);
}
}
function toggleWindow(e)
{
var win = e.getAttribute("data-window");
forEachInput(function(input) {
if (input.getAttribute("data-window") == win) {
input.checked = e.checked;
}
});
}
function toggleTab(e)
{
var win = e.getAttribute("data-window");
var winElement = null;
var checked = 0;
var total = 0;
forEachInput(function(input) {
if (input.getAttribute("data-window") != win) {
return;
}
if (!input.hasAttribute("data-tab")) {
winElement = input;
return;
}
if (input.checked) {
++checked;
}
++total;
});
if (checked == total) {
winElement.checked = true;
winElement.indeterminate = false;
} else if (checked > 0) {
winElement.indeterminate = true;
} else {
winElement.checked = false;
winElement.indeterminate = false;
}
}
function startNewSession()
{
document.getElementById("start-new-session-button").disabled = true;
external.recovery.startNewSession();
}
function restoreSession()
{
document.getElementById("restore-session-button").disabled = true;
var excludeWin = [];
var excludeTab = [];
forEachInput(function(input) {
if (input.checked || input.indeterminate || !input.hasAttribute("data-tab")) {
return;
}
excludeWin.unshift(input.getAttribute("data-window"));
excludeTab.unshift(input.getAttribute("data-tab"));
});
external.recovery.restoreSession(excludeWin, excludeTab);
}
function addWindow(winId)
{
var tr = document.createElement("tr");
tr.className = "window";
tr.onclick = function() { selectRow(tr); };
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "checkbox";
input.checked = true;
input.setAttribute("data-window", winId);
input.onclick = function() { toggleWindow(input); };
var span = document.createElement("span");
span.innerText = scriptData.window + " " + (winId + 1);
tr.appendChild(td);
td.appendChild(input);
td.appendChild(span);
document.getElementById("recovery-items").appendChild(tr);
}
function addTab(winId, tab)
{
var tr = document.createElement("tr");
tr.className = "tab";
tr.title = tab.url;
tr.onclick = function() { selectRow(tr); };
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "checkbox";
input.checked = true;
input.setAttribute("data-window", winId);
input.setAttribute("data-tab", tab.tab);
input.onclick = function() { toggleTab(input); };
var img = document.createElement("img");
img.src = tab.icon;
var span = document.createElement("span");
span.innerText = tab.title;
if (tab.pinned) {
span.innerText = "🖈 " + span.innerText;
}
if (tab.current) {
span.style.fontStyle = 'italic';
}
tr.appendChild(td);
td.appendChild(input);
td.appendChild(img);
td.appendChild(span);
document.getElementById("recovery-items").appendChild(tr);
}
function init()
{
scriptData = document.getElementById("script-data").dataset;
document.getElementById("start-new-session-button").onclick = function() {
startNewSession();
return false;
};
document.getElementById("restore-session-button").onclick = function() {
restoreSession();
return false;
};
var data = external.recovery.restoreData;
for (var i = 0; i < data.length; ++i) {
var win = data[i];
addWindow(win.window);
for (var j = 0; j < win.tabs.length; ++j) {
var tab = win.tabs[j];
addTab(win.window, tab);
}
}
}
// Initialize
if (window._falkon_external) {
init();
} else {
document.addEventListener("_falkon_external_created", init);
}
})();

View File

@ -503,460 +503,40 @@ input[type=checkbox] {
}
</style>
<script type="text/javascript" src="%JQUERY%"></script>
<script type="text/javascript" src="%JQUERY-UI%"></script>
<script type="text/javascript">
var LOADING_IMAGE = '%LOADING-IMG%';
var URL = '%URL%';
var TITLE = '%TITLE%';
var EDIT = '%APPLY%';
var NEW_PAGE = '%NEW-PAGE%';
var TITLE_EDIT = '%TITLE-EDIT%';
var TITLE_REMOVE = '%TITLE-REMOVE%';
var TITLE_RELOAD = '%TITLE-RELOAD%';
var TITLE_FETCHTITLE = '%TITLE-FETCHTITLE%';
var MAX_PAGES_ROW = %ROW-PAGES%;
var DIAL_WIDTH = %SD-SIZE%;
var SD_CENTER = %SD-CENTER%;
var editingId = -1;
var ignoreNextChanged = false;
if ("%IMG_BACKGROUND%" == '')
document.getElementById("html").style.backgroundSize = "cover";
$(document).keyup(function(e) {
if (editingId == -1)
return;
if (e.keyCode == 13)
boxEdited();
else if (e.keyCode == 27)
$('#fadeOverlay').click();
});
function emitChanged(pages)
{
ignoreNextChanged = true;
external.speedDial.changed(pages);
}
function addSpeedDial()
{
onEditClick(addBox('', NEW_PAGE, ''));
alignPage();
}
function configureSpeedDial()
{
// ====================== LOAD SETTINGS ========================= //
$('#PgInRow').val(MAX_PAGES_ROW);
$('#sliderValuePg').html(MAX_PAGES_ROW);
$('#SdSize').val(DIAL_WIDTH);
$('#SdSizeToggle').prop('checked', DIAL_WIDTH != 240);
$('#sliderValueSd').html(DIAL_WIDTH);
$('#BgImgSelSiz').val('%B_SIZE%').attr('selected', 'selected');
$('#BgImgToggle').prop('checked', "%IMG_BACKGROUND%" != "");
$('#SdCntrToggle').prop('checked', SD_CENTER);
$('#BgImgToggle').is(':checked') ? $('#BgImgSel').removeAttr('disabled') : $('#BgImgSel').attr('disabled', 'disabled');
$('#BgImgToggle').is(':checked') ? $('#BgImgSelSiz').removeAttr('disabled') : $('#BgImgSelSiz').attr('disabled', 'disabled');
$('#SdSizeToggle').is(':checked') ? $('#SdSize').removeAttr('disabled') : $('#SdSize').attr('disabled', 'disabled');
if ($('#BgImgToggle').prop('checked') != true) {
$('#ImgSelectorMenu').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSel').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSelSiz').css('visibility', 'hidden');
}
if ($('#SdSizeToggle').prop('checked') != true)
$('#SdSizeStateColor').css('color', 'rgba(0,0,0, 0.0)');
// ======================== SHOW DIALOG ======================== //
$('#fadeOverlay2').css({'filter' : 'alpha(opacity=100)'}).fadeIn();
$('#fadeOverlay2').click(function() { $(this).fadeOut('slow'); });
$('#settingsBox').click(function(event) { event.stopPropagation(); });
}
function escapeTitle(title) {
title = title.replace(/"/g, '&quot;');
title = title.replace(/'/g, '&apos;');
return title;
}
function unescapeTitle(title) {
title = title.replace(/&quot;/g, '"');
title = title.replace(/&apos;/g, '\'');
return title;
}
function escapeUrl(url) {
url = url.replace(/"/g, '');
url = url.replace(/'/g, '');
return url;
}
function onRemoveClick(box) {
removeBox($(box).index());
}
function onFetchTitleClick(checkbox) {
var displayStyle;
checkbox.checked ? displayStyle = 'hidden' : displayStyle = 'visible';
$('#titleLine').css({'visibility' : displayStyle });
}
function hideEditBox() {
$('#fadeOverlay').fadeOut("slow", function() {$("#fadeOverlay").remove();});
}
function onEditClick(box) {
editingId = $(box).index();
var boxUrl = $(box).children('a').first().attr('href');
var boxTitle = escapeTitle($(box).children('span').first().text());
if (boxUrl === '')
boxUrl = 'http://';
$('body').append('<div id="fadeOverlay" class="overlay" style="display:none;">' +
'<div id="overlay-edit">' +
'<img src="' + $(box).children('img').first().attr('src') + '"> ' +
'<table><tr><td>' + URL + ': </td><td>' +
'<input type="text" id="formUrl" value="' + boxUrl + '"></td></tr>' +
'<tr id="titleLine"><td>' + TITLE + ': </td><td>' +
'<input type="text" id="formTitle" value="' + boxTitle + '"></td></tr>' +
'<tr><td></td><td><div class="checkbox"><input type="checkbox" id="fetchTitle" onclick="onFetchTitleClick(this)">' +
'<label for="fetchTitle"></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ' + TITLE_FETCHTITLE + ' </div></td></tr>' +
'</table><p class="buttonbox"><input type="button" value=" %CANCEL% " onClick="hideEditBox();location.reload();">&nbsp;&nbsp;&nbsp;' +
'<input type="button" value=" ' + EDIT + ' " onClick="boxEdited()"></p>' +
'</div></div>');
$('#fadeOverlay').css({'filter' : 'alpha(opacity=100)'}).fadeIn();
$('#fadeOverlay').click(function() {hideEditBox()});
$('#overlay-edit').click(function(event) { event.stopPropagation(); });
$('#formUrl').focus().val($('#formUrl').val()); // focus and move cursor to end
}
function onReloadClick(box) {
var url = $(box).children('a').first().attr('href');
var img = $(box).children('img').first();
if (url === '')
return;
$(img).attr('src', LOADING_IMAGE);
external.speedDial.loadThumbnail(url, false);
}
function boxEdited() {
if (editingId == -1)
return;
external.speedDial.urlFromUserInput($('#formUrl').val(), function(newUrl) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[editingId];
var a = box.getElementsByTagName('a')[0];
var originalUrl = a.getAttribute('href');
setBoxUrl(editingId, newUrl);
setBoxTitle(editingId, $('#formTitle').val());
var changedUrl = a.getAttribute('href');
var fetchTitleChecked = document.getElementById('fetchTitle').checked;
var pages = allPages();
if (fetchTitleChecked || (originalUrl != changedUrl && changedUrl !== '') ) {
var img = box.getElementsByTagName('img')[0];
img.setAttribute('src', LOADING_IMAGE);
$('#fadeOverlay').fadeOut("slow", function() {
$("#fadeOverlay").remove();
});
external.speedDial.loadThumbnail(a.getAttribute('href'), fetchTitleChecked);
} else {
hideEditBox();
}
emitChanged(pages);
});
}
function allPages() {
var urls = $('a[class="boxUrl"]');
var titles = $('span[class="boxTitle"]');
var value = "";
$('div.entry').each(function(i) {
var url = $(this).children('a').first().attr('href');
var title = $(this).children('span[class="boxTitle"]').first().text();
value += 'url:"' + escapeUrl(url) + '"|title:"' + escapeTitle(title) + '";';
});
return value;
}
function reloadAll() {
if (confirm("%TITLE-WARN-REL%"))
$('div.entry').each(function(i) {
onReloadClick($(this));
});
}
function addBox(url, title, img_source) {
var div = document.createElement('div');
div.setAttribute('class', 'entry');
var img = document.createElement('img');
img.setAttribute('src', img_source);
var a = document.createElement('a');
a.setAttribute('href', url);
a.setAttribute('class', 'boxUrl');
var span1 = document.createElement('span');
span1.setAttribute('class', 'boxTitle');
span1.setAttribute('title', unescapeTitle(title));
span1.innerText = unescapeTitle(title);
var span2 = document.createElement('span');
span2.setAttribute('class', 'edit');
span2.setAttribute('onClick', 'onEditClick(parentNode)');
span2.setAttribute('title', TITLE_EDIT);
var span3 = document.createElement('span');
span3.setAttribute('class', 'close');
span3.setAttribute('onClick', 'onRemoveClick(parentNode)');
span3.setAttribute('title', TITLE_REMOVE);
var span4 = document.createElement('span');
span4.setAttribute('class', 'reload');
span4.setAttribute('onClick', 'onReloadClick(parentNode)');
span4.setAttribute('title', TITLE_RELOAD);
div.appendChild(img);
div.appendChild(img);
div.appendChild(a);
div.appendChild(span1);
div.appendChild(span2);
div.appendChild(span3);
div.appendChild(span4);
document.getElementById("quickdial").appendChild(div);
if (img_source == LOADING_IMAGE) {
external.speedDial.loadThumbnail(url, false);
}
return div;
}
function setBoxImage(id, img_source) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var img = box.getElementsByTagName('img')[0];
img.setAttribute('src', img_source + '?' + new Date());
}
function setTitleToUrl(url, title) {
var changed = false;
var boxes = document.getElementById('quickdial').getElementsByTagName('div');
for (i = 0; i < boxes.length; ++i) {
var box = boxes[i];
if (box === undefined)
continue;
var boxUrl = box.getElementsByTagName('a')[0].getAttribute('href');
if (url != boxUrl)
continue;
var span = box.getElementsByTagName('span')[0];
if (span.innerText != title) {
changed = true;
span.innerText = title;
}
}
if (changed)
emitChanged(allPages());
}
function setImageToUrl(url, img_source) {
var aElement = $('a[href="' + url + '"]');
$(aElement).each(function() {
var box = $(this).parent();
var imgElement = $(box).children("img").first();
if ($(imgElement).size() == 0)
return;
$(imgElement).attr('src', img_source/* + '?' + new Date()*/);
});
}
function setBoxUrl(id, url) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var a = box.getElementsByTagName('a')[0];
a.setAttribute('href', url);
}
function setBoxTitle(id, title) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var span = box.getElementsByTagName('span')[0];
span.innerText = title;
}
function removeBox(id) {
if (confirm("%TITLE-WARN%"))
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var url = box.getElementsByTagName('a')[0].getAttribute('href');
document.getElementById("quickdial").removeChild(box);
alignPage();
external.speedDial.removeImageForUrl(url);
emitChanged(allPages());
}
function alignPage() {
var dialHeight = Math.floor(Math.round(DIAL_WIDTH / 1.54));
$('head').append('<style>#quickdial img{height:auto;width:'+DIAL_WIDTH+'px}</style>');
$('#quickdial div.entry').css({'width' : DIAL_WIDTH + 'px',
'height' : dialHeight + 'px'});
var fullwidth = $(window).width();
var width = Math.floor(fullwidth - 76); var height = $(window).height();
var boxWidth = Math.floor(DIAL_WIDTH + 12);
var boxHeight = dialHeight + 22;
var maxBoxes = Math.floor(width / boxWidth);
if (maxBoxes > MAX_PAGES_ROW) maxBoxes = MAX_PAGES_ROW;
if (maxBoxes < 1) maxBoxes = 1;
var maxwidth = maxBoxes * boxWidth;
$("#quickdial").css('width', maxwidth + 'px');
var boxesCount = $("#quickdial").children("div").size();
var rows = Math.ceil(boxesCount / maxBoxes);
var margintop = (height - rows * boxHeight) / 2;
if (margintop < 0) margintop = 0;
$("#quickdial").css('margin-top', margintop + 'px');
$("span.boxTitle").css('font-size', ((dialHeight - DIAL_WIDTH / 1.77) / 1.5) + 'px');
if (SD_CENTER)
enableCentering();
else
disableCentering();
}
function bgImageSel() {
external.speedDial.getOpenFileName(function(arr) {
if (arr.length) {
document.getElementById('BgImgHold').value = arr[0];
document.getElementById('BgImgHoldUrl').value = arr[1];
bgImgUpdate();
}
});
}
function saveSettings() {
MAX_PAGES_ROW = $('#PgInRow').val();
DIAL_WIDTH = parseInt($('#SdSize').val());
SD_CENTER = $('#SdCntrToggle').prop('checked');
external.speedDial.setBackgroundImage($('#BgImgHoldUrl').val());
external.speedDial.setBackgroundImageSize($('#BgImgSelSiz').val());
external.speedDial.setPagesInRow(MAX_PAGES_ROW);
external.speedDial.setSdSize(DIAL_WIDTH);
external.speedDial.setSdCentered(SD_CENTER);
alignPage();
}
function bgImgToggle() {
var check = document.getElementById('BgImgToggle');
var BgImgSel = document.getElementById('BgImgSel');
var BgImgHoldUrl = document.getElementById('BgImgHoldUrl');
var BgImgSz = document.getElementById('BgImgSelSiz');
BgImgSel.disabled = (check.checked ? false : true);
BgImgHoldUrl.disabled = (check.checked ? false : true);
BgImgSz.disabled = (check.checked ? false : true);
BgImgHoldUrl.value = (check.checked ? "%URL_BACKGROUND%" : '');
if ($('#BgImgToggle').prop('checked') != true) {
$('#ImgSelectorMenu').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSel').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSelSiz').css('visibility', 'hidden');
} else {
$('#ImgSelectorMenu').css({'color' : '#eaeaea', 'text-shadow' : '1px 1px 2px #000000, 0 0 1em #000000'});
$('#BgImgSel').css({'color' : '#eaeaea', 'text-shadow' : '1px 1px 2px #000000, 0 0 1em #000000'});
$('#BgImgSelSiz').css('visibility', 'visible');
};
}
function sdSizeToggle() {
var check = document.getElementById('SdSizeToggle');
var SdSize = document.getElementById('SdSize');
var SdSizeSl = document.getElementById('sliderValueSd');
SdSize.disabled = (check.checked ? false : true);
SdSize.value = (check.checked ? SdSize.value : 240);
SdSizeSl.innerHTML = (check.checked ? DIAL_WIDTH : 240);
if ($('#SdSizeToggle').prop('checked') != true) {
$('#SdSizeStateColor').css('color', 'rgba(0,0,0, 0.0)');
} else {
$('#SdSizeStateColor').css('color', '#eaeaea')
}
}
function bgImgUpdate() {
var imgUrl = document.getElementById('BgImgHold').value;
var imgSize = document.getElementById('BgImgSelSiz').value;
var imgThumb = document.getElementById('thumb');
imgThumb.style.backgroundImage = 'url("' + imgUrl + '")';
imgThumb.title = imgUrl.substring(imgUrl.lastIndexOf('/')+1);
imgThumb.style.backgroundSize = imgSize;
document.documentElement.style.backgroundImage = 'url("' + imgUrl + '")';
document.documentElement.style.backgroundSize = imgSize;
}
function enableCentering() {
$('#quickdial div.entry').css({
float: 'none',
display: 'inline-block'
});
}
function disableCentering() {
$('#quickdial div.entry').css({
float: '%LEFT_STR%',
display: 'block'
});
}
</script>
</head>
<body>
<p hidden id="script-data"
data-img-background="%IMG_BACKGROUND%"
data-url-background="%URL_BACKGROUND%"
data-loading-image="%LOADING-IMG%"
data-left-str="%LEFT_STR%"
data-b-size="%B_SIZE%"
data-cancel="%CANCEL%"
data-url="%URL%"
data-title="%TITLE%"
data-edit="%APPLY%";
data-new-page="%NEW-PAGE%"
data-title-edit="%TITLE-EDIT%"
data-title-remove="%TITLE-REMOVE%"
data-title-reload="%TITLE-RELOAD%"
data-title-fetch-title="%TITLE-FETCHTITLE%"
data-title-warn="%TITLE-WARN%"
data-title-warn-rel="%TITLE-WARN-REL%"
data-max-pages-row="%ROW-PAGES%"
data-dial-width="%SD-SIZE%"
data-sd-center="%SD-CENTER%"
data-initial-script='%INITIAL-SCRIPT%'>
</p>
<noscript>%JAVASCRIPT-DISABLED%</noscript>
<div id="quickdial">
</div>
<a onClick="configureSpeedDial()" title="%SETTINGS-TITLE%" class="sett"></a>
<a onClick="addSpeedDial()" title="%ADD-TITLE%" class="add"></a>
<script type="text/javascript">
function init() {
%INITIAL-SCRIPT%
external.speedDial.pagesChanged.connect(function() {
if (ignoreNextChanged) {
ignoreNextChanged = false;
return;
}
window.location.reload();
});
external.speedDial.thumbnailLoaded.connect(setImageToUrl);
external.speedDial.pageTitleLoaded.connect(setTitleToUrl);
$(window).resize(function() { alignPage(); });
$("#quickdial").sortable({
revert: true,
cursor: 'move',
containment: 'document',
opacity: 0.8,
distance: 40,
start: function(event, ui) {
disableCentering();
},
stop: function(event, ui) {
if (SD_CENTER)
enableCentering();
},
update: function(event, ui) {
emitChanged(allPages());
}
});
alignPage();
}
</script>
<a id="button-configure-speed-dial" title="%SETTINGS-TITLE%" class="sett"></a>
<a id="button-add-speed-dial" title="%ADD-TITLE%" class="add"></a>
<div id="fadeOverlay2" class="overlay" style="display:none;">
<div id="settingsBox">
@ -969,32 +549,32 @@ function init() {
</div>
<div class="rowsel">
<span id="sliderValuePg"></span>
<input id="PgInRow" type="range" min="2" max="10" step="1" oninput="$('#sliderValuePg').html(this.value);" />
<input id="PgInRow" type="range" min="2" max="10" step="1" />
</div>
<div class="checkbox">
<input type="checkbox" id="SdSizeToggle" name="sdsizet" onchange="sdSizeToggle()" />
<input type="checkbox" id="SdSizeToggle" name="sdsizet" />
<label for="SdSizeToggle"></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%TXT_SDSIZE%
</div>
<div class="rowsel">
<div id="SdSizeStateColor">
<span id="sliderValueSd" color="#f00"></span>
<input id="SdSize" type="range" min="100" max="500" step="1" oninput="$('#sliderValueSd').html(this.value);" />
<input id="SdSize" type="range" min="100" max="500" step="1" />
</div>
</div>
<div id="ImgSelector">
<div id="BgImgSel" class="thumbhold" onclick="if($('#BgImgSelSiz').attr('disabled')!='disabled') {bgImageSel();}" disabled="disabled"><p id="thumb">%TXT_SELECTIMAGE%</p>
<div id="BgImgSel" class="thumbhold" disabled="disabled"><p id="thumb">%TXT_SELECTIMAGE%</p>
</div>
<p>
<input id="BgImgHold" type="hidden" value="%IMG_BACKGROUND%" />
<input id="BgImgHoldUrl" type="hidden" value="%URL_BACKGROUND%" />
</p>
<div class="checkbox" id="ImgSelectorToggle">
<input type="checkbox" id="BgImgToggle" name="sdbackimg" onchange="bgImgToggle();bgImgUpdate()" />
<input type="checkbox" id="BgImgToggle" name="sdbackimg" />
<label for="BgImgToggle"></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%TXT_NOTE%
</div>
<div id="ImgSelectorMenu">
<label for="BgImgSelSiz">%TXT_PLACEMENT%</label>
<select id="BgImgSelSiz" name="imgselsize" onchange="bgImgUpdate()">
<select id="BgImgSelSiz" name="imgselsize">
<option value="contain">&nbsp;&nbsp;%TXT_FIT%</option>
<option value="auto">&nbsp;&nbsp;%TXT_AUTO%</option>
<option value="cover">&nbsp;&nbsp;%TXT_COVER%</option>
@ -1004,20 +584,11 @@ function init() {
</div>
</div>
<div class="buttonbox">
<input type="button" value=" %CANCEL% " onClick="$('#fadeOverlay2').fadeOut('slow');location.reload();" />
<input type="button" value=" %APPLY% " onClick="saveSettings();$('#fadeOverlay2').fadeOut('slow');location.reload();"/>
<input id="button-cancel" type="button" value=" %CANCEL% " />
<input id="button-apply" type="button" value=" %APPLY% " >
</div>
</div>
</div>
</body>
<script type="text/javascript">
// ============================ Initialize =============================== //
if (window._falkon_external) {
init();
} else {
document.addEventListener('_falkon_external_created', init);
}
</script>
</html>

View File

@ -0,0 +1,502 @@
// ==UserScript==
// @name _falkon_speeddial
// @run-at document-end
// @include falkon:speeddial
// ==/UserScript==
(function() {
var scriptData = {};
var editingId = -1;
var ignoreNextChanged = false;
function emitChanged(pages)
{
ignoreNextChanged = true;
external.speedDial.changed(pages);
}
function addSpeedDial()
{
onEditClick(addBox('', scriptData.newPage , ''));
alignPage();
}
function configureSpeedDial()
{
// ====================== LOAD SETTINGS ========================= //
$('#PgInRow').val(scriptData.maxPagesRow);
$('#sliderValuePg').html(scriptData.maxPagesRow);
$('#SdSize').val(scriptData.dialWidth);
$('#SdSizeToggle').prop('checked', scriptData.dialWidth != 240);
$('#sliderValueSd').html(scriptData.dialWidth);
$('#BgImgSelSiz').val(scriptData.bSize).attr('selected', 'selected');
$('#BgImgToggle').prop('checked', scriptData.imgBackground != "");
$('#SdCntrToggle').prop('checked', scriptData.sdCenter == "true");
$('#BgImgToggle').is(':checked') ? $('#BgImgSel').removeAttr('disabled') : $('#BgImgSel').attr('disabled', 'disabled');
$('#BgImgToggle').is(':checked') ? $('#BgImgSelSiz').removeAttr('disabled') : $('#BgImgSelSiz').attr('disabled', 'disabled');
$('#SdSizeToggle').is(':checked') ? $('#SdSize').removeAttr('disabled') : $('#SdSize').attr('disabled', 'disabled');
if ($('#BgImgToggle').prop('checked') != true) {
$('#ImgSelectorMenu').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSel').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSelSiz').css('visibility', 'hidden');
}
if ($('#SdSizeToggle').prop('checked') != true)
$('#SdSizeStateColor').css('color', 'rgba(0,0,0, 0.0)');
// ======================== SHOW DIALOG ======================== //
$('#fadeOverlay2').css({'filter' : 'alpha(opacity=100)'}).fadeIn();
$('#fadeOverlay2').click(function() { $(this).fadeOut('slow'); });
$('#settingsBox').click(function(event) { event.stopPropagation(); });
}
function escapeTitle(title) {
title = title.replace(/"/g, '&quot;');
title = title.replace(/'/g, '&apos;');
return title;
}
function unescapeTitle(title) {
title = title.replace(/&quot;/g, '"');
title = title.replace(/&apos;/g, '\'');
return title;
}
function escapeUrl(url) {
url = url.replace(/"/g, '');
url = url.replace(/'/g, '');
return url;
}
function onRemoveClick(box) {
removeBox($(box).index());
}
function onFetchTitleClick(checkbox) {
var displayStyle;
checkbox.checked ? displayStyle = 'hidden' : displayStyle = 'visible';
$('#titleLine').css({'visibility' : displayStyle });
}
function hideEditBox() {
$('#fadeOverlay').fadeOut("slow", function() {$("#fadeOverlay").remove();});
}
function onEditClick(box) {
editingId = $(box).index();
var boxUrl = $(box).children('a').first().attr('href');
var boxTitle = escapeTitle($(box).children('span').first().text());
if (boxUrl === '')
boxUrl = 'http://';
$('body').append('<div id="fadeOverlay" class="overlay" style="display:none;">' +
'<div id="overlay-edit">' +
'<img src="' + $(box).children('img').first().attr('src') + '"> ' +
'<table><tr><td>' + scriptData.url + ': </td><td>' +
'<input type="text" id="formUrl" value="' + boxUrl + '"></td></tr>' +
'<tr id="titleLine"><td>' + scriptData.title + ': </td><td>' +
'<input type="text" id="formTitle" value="' + boxTitle + '"></td></tr>' +
'<tr><td></td><td><div class="checkbox"><input type="checkbox" id="fetchTitle">' +
'<label for="fetchTitle"></label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ' + scriptData.titleFetchTitle + ' </div></td></tr>' +
'</table><p class="buttonbox"><input id="cancelEditBox" type="button" value=" ' + scriptData.cancel + ' ">&nbsp;&nbsp;&nbsp;' +
'<input id="acceptEditBox" type="button" value=" ' + scriptData.edit + ' "></p>' +
'</div></div>');
$('#fetchTitle').click(function() {
onFetchTitleClick(this);
});
$('#cancelEditBox').click(function() {
hideEditBox();
location.reload();
});
$('#acceptEditBox').click(boxEdited);
$('#fadeOverlay').css({'filter' : 'alpha(opacity=100)'}).fadeIn();
$('#fadeOverlay').click(function() {hideEditBox()});
$('#overlay-edit').click(function(event) { event.stopPropagation(); });
var temp = $('#formUrl').val();
$('#formUrl').focus().val('').val(temp); // focus and move cursor to end
}
function onReloadClick(box) {
var url = $(box).children('a').first().attr('href');
var img = $(box).children('img').first();
if (url === '')
return;
$(img).attr('src', scriptData.loadingImage);
external.speedDial.loadThumbnail(url, false);
}
function boxEdited() {
if (editingId == -1)
return;
external.speedDial.urlFromUserInput($('#formUrl').val(), function(newUrl) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[editingId];
var a = box.getElementsByTagName('a')[0];
var originalUrl = a.getAttribute('href');
setBoxUrl(editingId, newUrl);
setBoxTitle(editingId, $('#formTitle').val());
var changedUrl = a.getAttribute('href');
var fetchTitleChecked = document.getElementById('fetchTitle').checked;
var pages = allPages();
if (fetchTitleChecked || (originalUrl != changedUrl && changedUrl !== '') ) {
var img = box.getElementsByTagName('img')[0];
img.setAttribute('src', scriptData.loadingImage);
$('#fadeOverlay').fadeOut("slow", function() {
$("#fadeOverlay").remove();
});
external.speedDial.loadThumbnail(a.getAttribute('href'), fetchTitleChecked);
} else {
hideEditBox();
}
emitChanged(pages);
});
}
function allPages() {
var urls = $('a[class="boxUrl"]');
var titles = $('span[class="boxTitle"]');
var value = "";
$('div.entry').each(function(i) {
var url = $(this).children('a').first().attr('href');
var title = $(this).children('span[class="boxTitle"]').first().text();
value += 'url:"' + escapeUrl(url) + '"|title:"' + escapeTitle(title) + '";';
});
return value;
}
function reloadAll() {
if (confirm(scriptData.titleWarnRel))
$('div.entry').each(function(i) {
onReloadClick($(this));
});
}
function addBox(url, title, img_source) {
var div = document.createElement('div');
div.setAttribute('class', 'entry');
var img = document.createElement('img');
img.setAttribute('src', img_source);
var a = document.createElement('a');
a.setAttribute('href', url);
a.setAttribute('class', 'boxUrl');
var span1 = document.createElement('span');
span1.setAttribute('class', 'boxTitle');
span1.setAttribute('title', unescapeTitle(title));
span1.innerText = unescapeTitle(title);
var span2 = document.createElement('span');
span2.setAttribute('class', 'edit');
span2.setAttribute('title', scriptData.titleEdit);
span2.onclick = function() {
onEditClick(div);
};
var span3 = document.createElement('span');
span3.setAttribute('class', 'close');
span3.setAttribute('title', scriptData.titleRemove);
span3.onclick = function() {
onRemoveClick(div);
};
var span4 = document.createElement('span');
span4.setAttribute('class', 'reload');
span4.setAttribute('title', scriptData.tileReload);
span4.onclick = function() {
onReloadClick(div);
};
div.appendChild(img);
div.appendChild(img);
div.appendChild(a);
div.appendChild(span1);
div.appendChild(span2);
div.appendChild(span3);
div.appendChild(span4);
document.getElementById("quickdial").appendChild(div);
if (img_source == scriptData.loadingImage) {
external.speedDial.loadThumbnail(url, false);
}
return div;
}
function setBoxImage(id, img_source) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var img = box.getElementsByTagName('img')[0];
img.setAttribute('src', img_source + '?' + new Date());
}
function setTitleToUrl(url, title) {
var changed = false;
var boxes = document.getElementById('quickdial').getElementsByTagName('div');
for (i = 0; i < boxes.length; ++i) {
var box = boxes[i];
if (box === undefined)
continue;
var boxUrl = box.getElementsByTagName('a')[0].getAttribute('href');
if (url != boxUrl)
continue;
var span = box.getElementsByTagName('span')[0];
if (span.innerText != title) {
changed = true;
span.innerText = title;
}
}
if (changed)
emitChanged(allPages());
}
function setImageToUrl(url, img_source) {
var aElement = $('a[href="' + url + '"]');
$(aElement).each(function() {
var box = $(this).parent();
var imgElement = $(box).children("img").first();
if ($(imgElement).size() == 0)
return;
$(imgElement).attr('src', img_source/* + '?' + new Date()*/);
});
}
function setBoxUrl(id, url) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var a = box.getElementsByTagName('a')[0];
a.setAttribute('href', url);
}
function setBoxTitle(id, title) {
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var span = box.getElementsByTagName('span')[0];
span.innerText = title;
}
function removeBox(id) {
if (confirm(scriptData.titleWarn))
var box = document.getElementById('quickdial').getElementsByTagName('div')[id];
if (box === undefined)
return;
var url = box.getElementsByTagName('a')[0].getAttribute('href');
document.getElementById("quickdial").removeChild(box);
alignPage();
external.speedDial.removeImageForUrl(url);
emitChanged(allPages());
}
function alignPage() {
var dialWidth = parseInt(scriptData.dialWidth);
var dialHeight = Math.floor(Math.round(dialWidth / 1.54));
$('head').append('<style>#quickdial img{height:auto;width:'+dialWidth+'px}</style>');
$('#quickdial div.entry').css({'width' : dialWidth + 'px',
'height' : dialHeight + 'px'});
var fullwidth = $(window).width();
var width = Math.floor(fullwidth - 76);
var height = $(window).height();
var boxWidth = Math.floor(dialWidth + 12);
var boxHeight = dialHeight + 22;
var maxBoxes = Math.floor(width / boxWidth);
if (maxBoxes > scriptData.maxPagesRow) maxBoxes = scriptData.maxPagesRow;
if (maxBoxes < 1) maxBoxes = 1;
var maxwidth = maxBoxes * boxWidth;
$("#quickdial").css('width', maxwidth + 'px');
var boxesCount = $("#quickdial").children("div").size();
var rows = Math.ceil(boxesCount / maxBoxes);
var margintop = (height - rows * boxHeight) / 2;
if (margintop < 0) margintop = 0;
$("#quickdial").css('margin-top', margintop + 'px');
$("span.boxTitle").css('font-size', ((dialHeight - dialWidth / 1.77) / 1.5) + 'px');
if (scriptData.sdCenter == "true") {
enableCentering();
} else {
disableCentering();
}
}
function bgImageSel() {
external.speedDial.getOpenFileName(function(arr) {
if (arr.length) {
document.getElementById('BgImgHold').value = arr[0];
document.getElementById('BgImgHoldUrl').value = arr[1];
bgImgUpdate();
}
});
}
function saveSettings() {
scriptData.maxPagesRow = $('#PgInRow').val();
scriptData.dialWidth = $('#SdSize').val();
scriptData.sdCenter = $('#SdCntrToggle').prop('checked');
external.speedDial.setBackgroundImage($('#BgImgHoldUrl').val());
external.speedDial.setBackgroundImageSize($('#BgImgSelSiz').val());
external.speedDial.setPagesInRow(scriptData.maxPagesRow);
external.speedDial.setSdSize(scriptData.dialWidth);
external.speedDial.setSdCentered(scriptData.sdCenter == "true");
alignPage();
}
function bgImgToggle() {
var check = document.getElementById('BgImgToggle');
var BgImgSel = document.getElementById('BgImgSel');
var BgImgHoldUrl = document.getElementById('BgImgHoldUrl');
var BgImgSz = document.getElementById('BgImgSelSiz');
BgImgSel.disabled = (check.checked ? false : true);
BgImgHoldUrl.disabled = (check.checked ? false : true);
BgImgSz.disabled = (check.checked ? false : true);
BgImgHoldUrl.value = (check.checked ? scriptData.urlBackground : '');
if ($('#BgImgToggle').prop('checked') != true) {
$('#ImgSelectorMenu').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSel').css({'color' : 'rgba(0,0,0, 0.0)', 'text-shadow' : 'none'});
$('#BgImgSelSiz').css('visibility', 'hidden');
} else {
$('#ImgSelectorMenu').css({'color' : '#eaeaea', 'text-shadow' : '1px 1px 2px #000000, 0 0 1em #000000'});
$('#BgImgSel').css({'color' : '#eaeaea', 'text-shadow' : '1px 1px 2px #000000, 0 0 1em #000000'});
$('#BgImgSelSiz').css('visibility', 'visible');
};
}
function sdSizeToggle() {
var check = document.getElementById('SdSizeToggle');
var SdSize = document.getElementById('SdSize');
var SdSizeSl = document.getElementById('sliderValueSd');
SdSize.disabled = (check.checked ? false : true);
SdSize.value = (check.checked ? SdSize.value : 240);
SdSizeSl.innerHTML = (check.checked ? scriptData.dialWidth : 240);
if ($('#SdSizeToggle').prop('checked') != true) {
$('#SdSizeStateColor').css('color', 'rgba(0,0,0, 0.0)');
} else {
$('#SdSizeStateColor').css('color', '#eaeaea')
}
}
function bgImgUpdate() {
var imgUrl = document.getElementById('BgImgHold').value;
var imgSize = document.getElementById('BgImgSelSiz').value;
var imgThumb = document.getElementById('thumb');
imgThumb.style.backgroundImage = 'url("' + imgUrl + '")';
imgThumb.title = imgUrl.substring(imgUrl.lastIndexOf('/')+1);
imgThumb.style.backgroundSize = imgSize;
document.documentElement.style.backgroundImage = 'url("' + imgUrl + '")';
document.documentElement.style.backgroundSize = imgSize;
}
function enableCentering() {
$('#quickdial div.entry').css({
float: 'none',
display: 'inline-block'
});
}
function disableCentering() {
$('#quickdial div.entry').css({
float: scriptData.leftStr,
display: 'block'
});
}
function init() {
scriptData = document.getElementById("script-data").dataset;
document.getElementById("button-configure-speed-dial").onclick = configureSpeedDial;
document.getElementById("button-add-speed-dial").onclick = addSpeedDial;
document.getElementById("PgInRow").oninput = function() {
$('#sliderValuePg').html(this.value);
};
document.getElementById("SdSizeToggle").onchange = sdSizeToggle;
document.getElementById("SdSize").oninput = function() {
$('#sliderValueSd').html(this.value);
};
document.getElementById("BgImgSel").onclick = function() {
if ($('#BgImgSelSiz').attr('disabled') != 'disabled') {
bgImageSel();
}
};
document.getElementById("BgImgToggle").onchange = function() {
bgImgToggle();
bgImgUpdate();
};
document.getElementById("BgImgSelSiz").onchange = bgImgUpdate;
document.getElementById("button-cancel").onclick = function() {
$('#fadeOverlay2').fadeOut('slow');
location.reload();
};
document.getElementById("button-apply").onclick = function() {
saveSettings();
$('#fadeOverlay2').fadeOut('slow');
location.reload();
};
if (scriptData.imgBackground == '') {
document.getElementById("html").style.backgroundSize = "cover";
}
$(document).keyup(function(e) {
if (editingId == -1)
return;
if (e.keyCode == 13)
boxEdited();
else if (e.keyCode == 27)
$('#fadeOverlay').click();
});
var pages = JSON.parse(scriptData.initialScript);
for (var i = 0; i < pages.length; ++i) {
var page = pages[i];
addBox(page.url, page.title, page.img);
}
external.speedDial.pagesChanged.connect(function() {
if (ignoreNextChanged) {
ignoreNextChanged = false;
return;
}
window.location.reload();
});
external.speedDial.thumbnailLoaded.connect(setImageToUrl);
external.speedDial.pageTitleLoaded.connect(setTitleToUrl);
$(window).resize(function() { alignPage(); });
$("#quickdial").sortable({
revert: true,
cursor: 'move',
containment: 'document',
opacity: 0.8,
distance: 40,
start: function(event, ui) {
disableCentering();
},
stop: function(event, ui) {
if (scriptData.sdCenter == "true")
enableCentering();
},
update: function(event, ui) {
emitChanged(allPages());
}
});
alignPage();
}
%JQUERY%
%JQUERY-UI%
// Initialize
if (window._falkon_external) {
init();
} else {
document.addEventListener("_falkon_external_created", init);
}
})();

View File

@ -203,8 +203,6 @@ QString FalkonSchemeReply::speeddialPage()
dPage.replace(QLatin1String("%IMG_CLOSE%"), QLatin1String("qrc:html/close.svg"));
dPage.replace(QLatin1String("%IMG_EDIT%"), QLatin1String("qrc:html/edit.svg"));
dPage.replace(QLatin1String("%IMG_RELOAD%"), QLatin1String("qrc:html/reload.svg"));
dPage.replace(QLatin1String("%JQUERY%"), QLatin1String("qrc:html/jquery.js"));
dPage.replace(QLatin1String("%JQUERY-UI%"), QLatin1String("qrc:html/jquery-ui.js"));
dPage.replace(QLatin1String("%LOADING-IMG%"), QLatin1String("qrc:html/loading.gif"));
dPage.replace(QLatin1String("%IMG_SETTINGS%"), QLatin1String("qrc:html/configure.svg"));

View File

@ -27,6 +27,7 @@
#include <QFileDialog>
#include <QWebEnginePage>
#include <QImage>
#include <QJsonDocument>
#define ENSURE_LOADED if (!m_loaded) loadSettings();
@ -199,6 +200,8 @@ QString SpeedDial::initialScript()
m_regenerateScript = false;
m_initialScript.clear();
QVariantList pages;
foreach (const Page &page, m_pages) {
QString imgSource = m_thumbnailsDir + QCryptographicHash::hash(page.url.toUtf8(), QCryptographicHash::Md4).toHex() + ".png";
@ -213,9 +216,14 @@ QString SpeedDial::initialScript()
imgSource = QzTools::pixmapToDataUrl(QPixmap(imgSource)).toString();
}
m_initialScript.append(QString("addBox('%1', '%2', '%3');\n").arg(page.url, page.title, imgSource));
QVariantMap map;
map[QSL("url")] = page.url;
map[QSL("title")] = page.title;
map[QSL("img")] = imgSource;
pages.append(map);
}
m_initialScript = QJsonDocument::fromVariant(pages).toJson(QJsonDocument::Compact);
return m_initialScript;
}

View File

@ -22,13 +22,10 @@
#include <QUrlQuery>
QString Scripts::setupWebChannel(quint32 worldId)
QString Scripts::setupWebChannel()
{
QString source = QL1S("// ==UserScript==\n"
"%1\n"
"// ==/UserScript==\n\n"
"(function() {"
"%2"
QString source = QL1S("(function() {"
"%1"
""
"function registerExternal(e) {"
" window.external = e;"
@ -70,13 +67,7 @@ QString Scripts::setupWebChannel(quint32 worldId)
""
"})()");
QString match;
if (worldId == WebPage::SafeJsWorld) {
match = QSL("// @exclude falkon:*\n// @exclude extension:*");
} else {
match = QSL("// @include falkon:*\n// @include extension:*");
}
return source.arg(match, QzTools::readAllFileContents(QSL(":/qtwebchannel/qwebchannel.js")));
return source.arg(QzTools::readAllFileContents(QSL(":/qtwebchannel/qwebchannel.js")));
}
QString Scripts::setupFormObserver()
@ -163,6 +154,14 @@ QString Scripts::setupWindowObject()
return source;
}
QString Scripts::setupSpeedDial()
{
QString source = QzTools::readAllFileContents(QSL(":html/speeddial.user.js"));
source.replace(QL1S("%JQUERY%"), QzTools::readAllFileContents(QSL(":html/jquery.js")));
source.replace(QL1S("%JQUERY-UI%"), QzTools::readAllFileContents(QSL(":html/jquery-ui.js")));
return source;
}
QString Scripts::setCss(const QString &css)
{
QString source = QL1S("(function() {"

View File

@ -28,9 +28,10 @@ class QWebEngineView;
class FALKON_EXPORT Scripts
{
public:
static QString setupWebChannel(quint32 worldId);
static QString setupWebChannel();
static QString setupFormObserver();
static QString setupWindowObject();
static QString setupSpeedDial();
static QString setCss(const QString &css);
static QString sendPostData(const QUrl &url, const QByteArray &data);

View File

@ -73,6 +73,10 @@ WebPage::WebPage(QObject* parent)
, m_blockAlerts(false)
, m_secureStatus(false)
{
QWebChannel *channel = new QWebChannel(this);
ExternalJsObject::setupWebChannel(channel, this);
setWebChannel(channel, SafeJsWorld);
connect(this, &QWebEnginePage::loadProgress, this, &WebPage::progress);
connect(this, &QWebEnginePage::loadFinished, this, &WebPage::finished);
connect(this, &QWebEnginePage::urlChanged, this, &WebPage::urlChanged);
@ -105,14 +109,6 @@ WebPage::WebPage(QObject* parent)
emit loadFinished(true);
}
});
// Workaround for changing webchannel world inside acceptNavigationRequest not working
m_setupChannelTimer = new QTimer(this);
m_setupChannelTimer->setSingleShot(true);
m_setupChannelTimer->setInterval(100);
connect(m_setupChannelTimer, &QTimer::timeout, this, [this]() {
setupWebChannelForUrl(m_channelUrl);
});
}
WebPage::~WebPage()
@ -372,25 +368,6 @@ void WebPage::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationSt
});
}
void WebPage::setupWebChannelForUrl(const QUrl &url)
{
QWebChannel *channel = webChannel();
if (!channel) {
channel = new QWebChannel(this);
ExternalJsObject::setupWebChannel(channel, this);
}
int worldId = -1;
if (url.scheme() == QL1S("falkon") || url.scheme() == QL1S("extension")) {
worldId = UnsafeJsWorld;
} else {
worldId = SafeJsWorld;
}
if (worldId != m_channelWorldId) {
m_channelWorldId = worldId;
setWebChannel(channel, m_channelWorldId);
}
}
bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame)
{
if (mApp->isClosing()) {
@ -418,8 +395,6 @@ bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::Navigatio
const bool isWeb = url.scheme() == QL1S("http") || url.scheme() == QL1S("https") || url.scheme() == QL1S("file");
const bool globalJsEnabled = mApp->webSettings()->testAttribute(QWebEngineSettings::JavascriptEnabled);
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, isWeb ? globalJsEnabled : true);
m_channelUrl = url;
m_setupChannelTimer->start();
}
emit navigationRequestAccepted(url, type, isMainFrame);
}

View File

@ -85,7 +85,6 @@ private Q_SLOTS:
void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode);
private:
void setupWebChannelForUrl(const QUrl &url);
bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
bool certificateError(const QWebEngineCertificateError &error) Q_DECL_OVERRIDE;
QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) Q_DECL_OVERRIDE;
@ -109,10 +108,6 @@ private:
QMetaObject::Connection m_contentsResizedConnection;
QUrl m_channelUrl;
int m_channelWorldId = -1;
QTimer *m_setupChannelTimer = nullptr;
friend class WebView;
};