1
0
mirror of https://github.com/MatMoul/quickdial-webext.git synced 2025-12-16 08:53:13 +00:00

26 Commits

Author SHA1 Message Date
121da31400 Version 0.1.4 2017-10-15 13:58:41 +02:00
7c9a1bb624 Project: Update TODO, README, Screenshots 2017-10-15 13:42:06 +02:00
550757a186 Bug: Prevent dragdrop on back node 2017-10-15 13:20:18 +02:00
dbe7751b77 Improvement: Old styles and old grid are removed after redrawing the new 2017-10-15 12:18:10 +02:00
957f468c59 Improvement: Add bookmark without sheme add http:// 2017-10-15 12:04:40 +02:00
325fdc8c83 Bug: Add to Quick Dial menu is missing 2017-10-15 11:53:33 +02:00
245d70a6eb Bug: Somme node are empty and make data unusable 2017-10-15 11:28:21 +02:00
4a3072bbdc Version 0.1.3 2017-10-15 01:14:23 +02:00
9c907f37e0 Improvement: Update thumbnails when url has changed 2017-10-15 00:51:50 +02:00
39f96b015b Feature: Add Default button on node properties 2017-10-15 00:25:12 +02:00
d3cc6cf68f Bug: Custom image are not displayed in properties window 2017-10-15 00:10:53 +02:00
b91255375f Bug: Custom image are not displayed in properties window 2017-10-15 00:02:41 +02:00
c00b227599 Version 0.1.2 2017-10-14 23:12:38 +02:00
73152dedd0 Feature: Add settings to set custom image on nodes 2017-10-14 23:11:33 +02:00
0f956667a0 Code: Rename var core to app 2017-10-14 22:43:48 +02:00
feafd8449e Feature: Add first support to editing nodes 2017-10-14 22:41:28 +02:00
20ca231945 Feature: Add Capture in a new Tab support for folder 2017-10-14 20:51:38 +02:00
30b432d1b8 Features: Add toolbar button 2017-10-14 19:33:20 +02:00
7e11b0b7da Stability: Encode url path 2017-10-14 19:00:15 +02:00
420f356136 Bug reported by Scienmind: Background color flickering on subfolder 2017-10-14 18:53:59 +02:00
d6ee45da30 Version 0.1.1 2017-10-14 17:20:59 +02:00
45a5bd5d44 Bug: Sync from bookmark is disabed 2017-10-14 17:13:57 +02:00
55521d2d53 Improvement: Speed start 2017-10-14 16:51:39 +02:00
1dd5409dd0 Version 0.1.0 2017-10-14 12:57:14 +02:00
039c3566ea Bug reported by Scienmind and Acid Crash: Private Window and Contextual Identities don't work 2017-10-14 12:44:56 +02:00
1413464149 Update screenshot 2017-10-08 19:10:46 +02:00
18 changed files with 950 additions and 459 deletions

View File

@@ -1,2 +1,9 @@
# quickdial-webext # quickdial-webext
QuickDial is a WebExt Dial page for Firefox QuickDial is a WebExt Dial page for Firefox
[QuickDial on addons.mozilla.org](https://addons.mozilla.org/fr/firefox/addon/quick-dial/?src=search)
## Contribute and evolution :</br>
* [CONTRIBUTING.md](https://github.com/MatMoul/quickdial-webext/blob/develop/CONTRIBUTING.md)

5
TODO
View File

@@ -1,6 +1,7 @@
Add node settings popup
Add custom image (thumbnails)
Create style for popup Create style for popup
Add a setting to customize bookmark root folder
Add a setting to lock title from update
Add a visual hint for multipage
Need a best solution to update folder and bookmark when it are updated from Firefox Need a best solution to update folder and bookmark when it are updated from Firefox
Improve screenshot result Improve screenshot result
Add favicon support Add favicon support

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

After

Width:  |  Height:  |  Size: 535 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 335 KiB

After

Width:  |  Height:  |  Size: 532 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

After

Width:  |  Height:  |  Size: 430 KiB

View File

@@ -34,6 +34,11 @@
"description": "Text of the add folder prompt." "description": "Text of the add folder prompt."
}, },
"menuProperties": {
"message": "Properties",
"description": "Text of properties menu item."
},
"menuRefreshItem": { "menuRefreshItem": {
"message": "Refresh", "message": "Refresh",
"description": "Text of refresh menu item." "description": "Text of refresh menu item."

View File

@@ -34,6 +34,11 @@
"description": "Text of the add folder prompt." "description": "Text of the add folder prompt."
}, },
"menuProperties": {
"message": "Propriétés",
"description": "Text of properties menu item."
},
"menuRefreshItem": { "menuRefreshItem": {
"message": "Actualiser", "message": "Actualiser",
"description": "Text of refresh menu item." "description": "Text of refresh menu item."

View File

@@ -1 +1 @@
<!DOCTYPE html><html><head id="head"><meta charset="utf-8" /><link rel="shortcut icon" type="image/png" href="img/24.png" /><title id="title"></title><script type="text/javascript" src="js/dial.js"></script></head><body id="body"></body></html> <!DOCTYPE html><html><head><meta charset="utf-8" /><link rel="shortcut icon" type="image/png" href="img/24.png" /><script type="text/javascript" src="js/dial.js"></script></head><body></body></html>

72
src/html/properties.html Normal file
View File

@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" type="image/png" href="img/24.png" />
<title id="title">Quick Dial Node Propoerties</title>
<script type="text/javascript" src="/js/properties.js"></script>
<style>
body { margin: 0px; padding: 4px; font-family: Arial, Helvetica, sans-serif; font-size: 10pt; }
h1 { font-size: 11pt; text-decoration: underline; }
input[type=number] { width: 56px; }
input[type=color] { width: 60px; }
.hidden { display: none; }
.Tab>table { width: 100%; border-collapse: collapse; }
.Tab .TabSpace { width: 100%; border-bottom: solid 1px #505050; }
.Tab .TabButton { border: solid 1px #505050; padding: 2px 6px 2px 6px; cursor: default; }
.Tab .TabButtonActive { border: solid 1px #505050; border-bottom: none; padding: 2px 6px 2px 6px; cursor: default; }
.Tab>div { padding: 8px; height: 330px; border-left: solid 1px #505050; border-bottom: solid 1px #505050; border-right: solid 1px #505050; }
</style>
</head>
<body>
<div id="Tabs" class="Tab">
<table>
<tr>
<td class="TabButtonActive">Main</td>
<td class="TabButton" style="display:none">Temp</td>
<td class="TabSpace"></td>
</tr>
</table>
<div>
<div>
<table style="width:100%">
<tr>
<td><span>Title :</span></td>
<td><input id="Title" type="text" style="width:100%"></td>
</tr>
<tr>
<td><span>Url :</span></td>
<td><input id="Url" type="text" style="width:100%"></td>
</tr>
<tr>
<td><span>Image :</span></td>
<td>
<button id="ImageReset">Reset</button>
<button id="ImageDefault">Default</button>
<button class="hidden" id="ImageRefresh">Refresh</button>
<button class="hidden" id="ImageCapture">Capture</button>
<input id="ImageFile" type="file" style="width:180px;">
</td>
</tr>
<tr>
<td></td>
<td><div id="ImagePreview" style="width: 300px; height: 180px;"></div></td>
</tr>
</table>
</div>
<div class="hidden">
</div>
</div>
</div>
<div style="text-align: right; margin-top: 14px;">
<button id="BtnOk">OK</button>
<button id="BtnApply">Apply</button>
<button id="BtnCancel">Cancel</button>
</div>
</body>
</html>

View File

@@ -1,105 +1,216 @@
var core = {}; // Main app object in background.js var app = {}; // App object
var app = {}; // Shared app object with pages
core.init = function(){ // Init module app.init = function(){ // Init module
core.Settings.load(function(){ app.Settings.init(function(){
core.GridNodes.sync(app.settings.grid.node, app.settings.grid.root, function(){ // Sync bookmarks with stored data app.Messages.init();
core.ContextMenus.initMenu(); browser.runtime.sendMessage({ cmd: app.Messages.Commands.settingsChanged });
core.Bookmarks.initListener(); browser.browserAction.onClicked.addListener(function(){
browser.tabs.create({});
});
app.GridNodes.sync(app.node, app.settings.grid.root, function(){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.gridNodesLoaded });
app.Bookmarks.initListener();
app.ContextMenus.initMenu();
}); });
}); });
} };
core.Settings = {}; // Settings helper object app.Messages = {}; // Messages helper object
core.Settings.load = function(callback){ // Load settings app.Messages.Commands = {
browser.storage.local.get({ getSettings: 0,
version: 2, setSettings: 1,
backgroundColor: '#3c4048', getNode: 2,
backgroundImage: null, getNodeByID: 3,
grid: { updateNode: 4,
margin: 10, setNodeIndex: 5,
rows: 4, createBookmark: 6,
columns: 5, createFolder: 7,
backNode: true, deleteNode: 8,
backIcon: 'url(/img/back.png)', refreshNode: 9,
folderIcon: 'url(/img/folder.png)', capturePage: 10,
loadingIcon: 'url(/img/throbber.gif)', settingsChanged: 100,
cells: { gridNodesLoaded: 101
margin: 4, };
marginHover: 4, app.Messages.init = function(){ // Init Messages Listeners
ratioX: 4, browser.runtime.onMessage.addListener(function(request, sender, sendResponse){
ratioY: 3, switch(request.cmd){
backgroundColor: null, case app.Messages.Commands.getSettings:
backgroundColorHover: null, sendResponse(app.settings);
borderColor: '#333333', break;
borderColorHover: '#a9a9a9', case app.Messages.Commands.setSettings:
borderRadius: 4, app.settings = request.settings;
borderRadiusHover: 4, app.Settings.save();
title: true, sendResponse(app.settings);
titleHeight: 16, browser.runtime.sendMessage( { cmd: app.Messages.Commands.settingsChanged } );
titleFontSize: 10, browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
titleFont: 'Arial, Verdana, Sans-serif', break;
titleColor: '#ffffff', case app.Messages.Commands.getNodeByID:
titleColorHover: '#33ccff', var nodes = app.GridNodes.getNodeWithParents(request.id);
titleBackgroundColor: null, if(nodes) sendResponse(nodes[nodes.length-1]);
titleBackgroundColorHover: null else sendResponse(null);
}, break;
root: 'Quick Dial', case app.Messages.Commands.updateNode:
node: { children: [] } app.GridNodes.updateNode(app.GridNodes.getNodeById(request.id), request.value, function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
case app.Messages.Commands.getNode:
sendResponse(app.GridNodes.getNode(app.node, request.path.substr(1)));
break;
case app.Messages.Commands.setNodeIndex:
app.GridNodes.setNodeIndex(app.GridNodes.getNode(app.node, request.path.substr(1)), request.index, request.newIndex, function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
case app.Messages.Commands.createBookmark:
app.GridNodes.createBookmark(app.GridNodes.getNode(app.node, request.path.substr(1)), request.url, request.title, function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
case app.Messages.Commands.createFolder:
app.GridNodes.createFolder(app.GridNodes.getNode(app.node, request.path.substr(1)), request.name, function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
case app.Messages.Commands.deleteNode:
app.GridNodes.deleteNode(app.GridNodes.getNode(app.node, request.path.substr(1)), request.id, function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
case app.Messages.Commands.refreshNode:
app.GridNodes.refreshNode(app.GridNodes.getChildNode(app.GridNodes.getNode(app.node, request.path.substr(1)), request.id), function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
case app.Messages.Commands.capturePage:
app.GridNodes.capturePage(app.GridNodes.getChildNode(app.GridNodes.getNode(app.node, request.path.substr(1)), request.id), function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
break;
} }
}).then(function(obj){
if(obj.grid.cells.backIcon){ // Upgrade Data Version
obj.version = 2;
obj.grid.backNode = true;
obj.grid.backIcon = 'url(/img/back.png)';
obj.grid.folderIcon = 'url(/img/folder.png)';
obj.grid.loadingIcon = 'url(/img/throbber.gif)';
obj.grid.cells.backgroundColor = null;
obj.grid.cells.backgroundColorHover = null;
obj.grid.cells.titleBackgroundColor = null;
obj.grid.cells.titleBackgroundColorHover = null;
delete obj.grid.cells.backIcon;
delete obj.grid.cells.folderIcon;
delete obj.grid.cells.loadingIcon;
delete obj.grid.cells.backPanel;
}
app.settings = obj;
if(callback) callback();
}); });
} };
core.Settings.save = function(){ // Save settings
browser.storage.local.set(app.settings); app.Settings = {}; // Settings helper object
browser.runtime.sendMessage({ command: 'SettingsChanged' }); app.Settings.init = function(callback){ // Load settings and nodes
browser.storage.local.get().then(function(data){
if(Object.keys(data).length == 0) {
data = {
version: 3,
settings: {
backgroundColor: '#3c4048',
backgroundImage: null,
grid: {
margin: 10,
rows: 4,
columns: 5,
backNode: true,
backIcon: 'url(/img/back.png)',
folderIcon: 'url(/img/folder.png)',
loadingIcon: 'url(/img/throbber.gif)',
cells: {
margin: 4,
marginHover: 4,
backgroundColor: null,
backgroundColorHover: null,
borderColor: '#333333',
borderColorHover: '#a9a9a9',
borderRadius: 4,
borderRadiusHover: 4,
title: true,
titleHeight: 16,
titleFontSize: 10,
titleFont: 'Arial, Verdana, Sans-serif',
titleColor: '#ffffff',
titleColorHover: '#33ccff',
titleBackgroundColor: null,
titleBackgroundColorHover: null,
previewWidth: 1200,
previewHeight: 710
},
root: 'Quick Dial',
}
},
node: { children: [] }
}
}
if(!data.version){ // Upgrade Data Version
data.version = 2;
data.grid.backNode = true;
data.grid.backIcon = 'url(/img/back.png)';
data.grid.folderIcon = 'url(/img/folder.png)';
data.grid.loadingIcon = 'url(/img/throbber.gif)';
data.grid.cells.backgroundColor = null;
data.grid.cells.backgroundColorHover = null;
data.grid.cells.titleBackgroundColor = null;
data.grid.cells.titleBackgroundColorHover = null;
delete data.grid.cells.backIcon;
delete data.grid.cells.folderIcon;
delete data.grid.cells.loadingIcon;
delete data.grid.cells.backPanel;
}
if(data.version == 2){ // Upgrade Data Version
var oldData = data;
data = {};
data.version = 3;
data.settings = oldData;
data.node = oldData.grid.node;
delete data.settings.version;
delete data.settings.grid.node;
app.settings = data.settings;
app.node = data.node;
browser.storage.local.clear().then(function(){
app.Settings.save();
});
}
app.settings = data.settings;
app.node = data.node;
if(callback) callback();
}, function(){ console.log('Error loading data'); });
};
app.Settings.update = function(settings, callback){ // Save new settings
app.settings = settings;
app.Settings.save(callback);
};
app.Settings.save = function(callback){ // Save settings
var data = { version: 3 };
data.settings = app.settings;
data.node = app.node;
browser.storage.local.set(data).then(function(){
if(callback) callback();
}, function(){ console.log('Error saving settings'); });
} }
core.init(); app.init();
core.ContextMenus = {} // ContextMenu helper Object app.ContextMenus = {} // ContextMenu helper Object
core.ContextMenus.initMenu = function(){ // (Called from core.init) Init context menu in all pages app.ContextMenus.initMenu = function(){ // (Called from app.init) Init context menu in all pages
browser.contextMenus.create({ // Create Context menu browser.contextMenus.create({ // Create Context menu
id: 'AddToQuickDial', id: 'AddToQuickDial',
title: browser.i18n.getMessage("menuAddToQuickDial"), title: browser.i18n.getMessage("menuAddToQuickDial"),
contexts: ["all"], contexts: ["all"],
documentUrlPatterns: [ 'http://*/*', 'https://*/*', 'file://*/*' ] documentUrlPatterns: [ 'http://*/*', 'https://*/*', 'file://*/*', 'ftp://*/*' ]
}, function(){}); }, function(){});
browser.contextMenus.onClicked.addListener(function(info, tab) { // Context menu click event browser.contextMenus.onClicked.addListener(function(info, tab) { // Context menu click event
if (info.menuItemId == "AddToQuickDial") if (info.menuItemId == "AddToQuickDial")
core.GridNodes.createBookmark(app.settings.grid.node, info.pageUrl, tab.title, function(){}); app.GridNodes.createBookmark(app.node, info.pageUrl, tab.title, function(){
browser.runtime.sendMessage( { cmd: app.Messages.Commands.gridNodesLoaded } );
});
}); });
} }
core.Bookmarks = {} // Bookmarks helper object app.Bookmarks = {} // Bookmarks helper object
core.Bookmarks._onCreated = function(){ core.GridNodes.sync(app.settings.grid.node, app.settings.grid.root); } app.Bookmarks._onCreated = function(){ app.GridNodes.sync(app.node, app.settings.grid.root, function(){ browser.runtime.sendMessage({ cmd: app.Messages.Commands.gridNodesLoaded }); }); }
core.Bookmarks._onChanged = function(){ core.GridNodes.sync(app.settings.grid.node, app.settings.grid.root); } app.Bookmarks._onChanged = function(){ app.GridNodes.sync(app.node, app.settings.grid.root, function(){ browser.runtime.sendMessage({ cmd: app.Messages.Commands.gridNodesLoaded }); }); }
core.Bookmarks._onMoved = function(){ core.GridNodes.sync(app.settings.grid.node, app.settings.grid.root); } app.Bookmarks._onMoved = function(){ app.GridNodes.sync(app.node, app.settings.grid.root, function(){ browser.runtime.sendMessage({ cmd: app.Messages.Commands.gridNodesLoaded }); }); }
core.Bookmarks._onRemoved = function(){ core.GridNodes.sync(app.settings.grid.node, app.settings.grid.root); } app.Bookmarks._onRemoved = function(){ app.GridNodes.sync(app.node, app.settings.grid.root, function(){ browser.runtime.sendMessage({ cmd: app.Messages.Commands.gridNodesLoaded }); }); }
core.Bookmarks.initListener = function(){ // (Called from core.init) (/!\ Need filter to root tree only) Init listener of bookmarks app.Bookmarks.initListener = function(){ // (Called from app.init) (/!\ Need filter to root tree only) Init listener of bookmarks
browser.bookmarks.onCreated.addListener(core.Bookmarks._onCreated); browser.bookmarks.onCreated.addListener(app.Bookmarks._onCreated);
//browser.bookmarks.onChanged.addListener(core.Bookmarks._onChanged); //browser.bookmarks.onChanged.addListener(app.Bookmarks._onChanged);
browser.bookmarks.onMoved.addListener(core.Bookmarks._onMoved); browser.bookmarks.onMoved.addListener(app.Bookmarks._onMoved);
browser.bookmarks.onRemoved.addListener(core.Bookmarks._onRemoved); browser.bookmarks.onRemoved.addListener(app.Bookmarks._onRemoved);
} }
core.Bookmarks.load = function(rootPath, callback){ // Load root bookmark and create it if not exist app.Bookmarks.load = function(rootPath, callback){ // Load root bookmark and create it if not exist
if(!callback) return; if(!callback) return;
browser.bookmarks.getSubTree('menu________').then(function(bookmarkItems){ browser.bookmarks.getSubTree('menu________').then(function(bookmarkItems){
function getChildItem(bookmarkItem, path, callback){ function getChildItem(bookmarkItem, path, callback){
@@ -121,31 +232,8 @@ core.Bookmarks.load = function(rootPath, callback){ // Load root bookmark and cr
}, function(){ callback(); }); }, function(){ callback(); });
} }
core.SiteInfos = {} // Siteinfos helper object app.SiteInfos = {} // Siteinfos helper object
core.SiteInfos.fromTab = function(callback){ // Retrieve infos from current tab. callback( { url, title, icon, screenshot } || error: callback() ) app.SiteInfos.fromNewTab = function(url, callback){ // Retrieve infos from a new tab. callback( { url, title, icon, screenshot } || error: callback() )
browser.tabs.getCurrent().then(function(tab){
function whaitLoaded(){
browser.tabs.get(tab.id).then(function(tab){
if(tab.status == 'loading') setTimeout(whaitLoaded, 300);
else {
browser.tabs.update(tab.id, {active: true}).then(function(){
setTimeout(function(){
browser.tabs.captureVisibleTab().then(function(img){
browser.tabs.remove(tab.id);
if(callback) callback( { url: tab.url, title: tab.title, icon: tab.favIconUrl, screenshot: img } );
}, function(){
browser.tabs.remove(tab.id);
if(callback) callback();
});
}, 300);
}, function(){ if(callback) callback(); });
}
}, function(){ if(callback) callback(); });
}
setTimeout(whaitLoaded, 300);
}, function(){ if(callback) callback(); });
}
core.SiteInfos.fromNewTab = function(url, callback){ // Retrieve infos from a new tab. callback( { url, title, icon, screenshot } || error: callback() )
browser.tabs.create({url: url, active: false}).then(function(tab){ browser.tabs.create({url: url, active: false}).then(function(tab){
browser.tabs.update(tab.id, {muted: true}).then(); browser.tabs.update(tab.id, {muted: true}).then();
function whaitLoaded(){ function whaitLoaded(){
@@ -185,12 +273,12 @@ core.SiteInfos.fromNewTab = function(url, callback){ // Retrieve infos from a n
ctx.restore(); ctx.restore();
img = canvas.toDataURL(); img = canvas.toDataURL();
if(callback) callback( { url: tab.url, title: tab.title, icon: tab.favIconUrl, screenshot: img } ); if(callback) callback( { url: tab.url, title: tab.title, icon: tab.favIconUrl, screenshot: img } );
}, 1); }, 100);
}, function(){ }, function(){
browser.tabs.remove(tab.id); browser.tabs.remove(tab.id);
if(callback) callback(); if(callback) callback();
}); });
}, 300); }, 500);
}, function(){ if(callback) callback(); }); }, function(){ if(callback) callback(); });
} }
}, function(){ if(callback) callback(); }); }, function(){ if(callback) callback(); });
@@ -198,7 +286,7 @@ core.SiteInfos.fromNewTab = function(url, callback){ // Retrieve infos from a n
setTimeout(whaitLoaded, 300); setTimeout(whaitLoaded, 300);
}, function(){ if(callback) callback(); }); }, function(){ if(callback) callback(); });
} }
core.SiteInfos.fromFrame = function(url, callback){ // Retrieve infos from an iframe. callback( { url, title, (/!\ Not handled now)icon, screenshot } || error: callback() ) app.SiteInfos.fromFrame = function(url, callback){ // Retrieve infos from an iframe. callback( { url, title, (/!\ Not handled now)icon, screenshot } || error: callback() )
function pageLoaded(){ function pageLoaded(){
if(!iframe) return; if(!iframe) return;
var docTitle = iframe.contentWindow.document.title; var docTitle = iframe.contentWindow.document.title;
@@ -248,47 +336,35 @@ core.SiteInfos.fromFrame = function(url, callback){ // Retrieve infos from an if
xmlHttp.onerror = function(){ if(callback) callback(); } xmlHttp.onerror = function(){ if(callback) callback(); }
xmlHttp.ontimeout = function(){ if(callback) callback(); } xmlHttp.ontimeout = function(){ if(callback) callback(); }
xmlHttp.send(); xmlHttp.send();
} }
core.SiteInfos.fromWS = function(url, callback){ // Retrieve infos from a Web Service. callback( { url, title, (/!\ Not handled now)icon, screenshot } || error: callback() ) app.SiteInfos.fromWS = function(url, callback){ // Retrieve infos from a Web Service. callback( { url, title, (/!\ Not handled now)icon, screenshot } || error: callback() )
console.log('Not implemented'); console.log('Not implemented');
return core.SiteInfos.fromFrame(url, callback); return app.SiteInfos.fromFrame(url, callback);
} }
/* app.GridNodes = {}; // GridNodes helper object
core.GridNodes.GridNode = function(){ app.GridNodes.GridNodeType = { // GridNodeType
this.id = null; // 0
//this.lastUpdate = new Date(0);
this.type = core.GridNodes.GridNodeType.empty;
//this.path = '';
this.title = null; // ''
this.icon = null; // ''
this.image = null; // ''
this.url = null; // ''
this.children = null; // []
}
*/
core.GridNodes = {}; // GridNodes helper object
core.GridNodes.GridNodeType = { // GridNodeType
back: -1, back: -1,
empty: 0, empty: 0,
folder: 1, folder: 1,
bookmark: 2 bookmark: 2
} }
core.GridNodes.sync = function(gridNode, rootPath, callback){ // Sync GridNodes with Bookmarks app.GridNodes.sync = function(gridNode, rootPath, callback){ // Sync GridNodes with Bookmarks
core.Bookmarks.load(rootPath, function(bookmarkItem){ app.Bookmarks.load(rootPath, function(bookmarkItem){
function syncNode(gridNode, bookmarkItem){ function syncNode(gridNode, bookmarkItem){
gridNode.id = bookmarkItem.id; gridNode.id = bookmarkItem.id;
if(!gridNode.title) gridNode.title = bookmarkItem.title; if(!gridNode.title) gridNode.title = bookmarkItem.title;
if(bookmarkItem.url){ if(bookmarkItem.url){
gridNode.type = core.GridNodes.GridNodeType.bookmark; gridNode.type = app.GridNodes.GridNodeType.bookmark;
if(!gridNode.url) gridNode.url = bookmarkItem.url; if(!gridNode.url) gridNode.url = bookmarkItem.url;
} else if(bookmarkItem.children){ } else if(bookmarkItem.children){
gridNode.type = core.GridNodes.GridNodeType.folder; gridNode.type = app.GridNodes.GridNodeType.folder;
var EmptyNodes = []; var EmptyNodes = [];
if(! gridNode.children) gridNode.children = []; if(! gridNode.children) gridNode.children = [];
else { else {
for(var i=gridNode.children.length-1; i>=0; i--){ for(var i=gridNode.children.length-1; i>=0; i--){
if(gridNode.children[i].type==core.GridNodes.GridNodeType.empty){ if(!gridNode.children[i]) gridNode.children[i] = { type: app.GridNodes.GridNodeType.empty };
if(gridNode.children[i].type==app.GridNodes.GridNodeType.empty){
EmptyNodes.unshift(gridNode.children[i]); EmptyNodes.unshift(gridNode.children[i]);
} else { } else {
var found = false; var found = false;
@@ -300,7 +376,7 @@ core.GridNodes.sync = function(gridNode, rootPath, callback){ // Sync GridNodes
} }
if(! found){ if(! found){
if(i<gridNode.children.length - 1){ if(i<gridNode.children.length - 1){
gridNode.children[i] = { type: core.GridNodes.GridNodeType.empty }; gridNode.children[i] = { type: app.GridNodes.GridNodeType.empty };
EmptyNodes.unshift(gridNode.children[i]); EmptyNodes.unshift(gridNode.children[i]);
} else { } else {
gridNode.children.pop(); gridNode.children.pop();
@@ -310,7 +386,7 @@ core.GridNodes.sync = function(gridNode, rootPath, callback){ // Sync GridNodes
} }
} }
for(var child of bookmarkItem.children){ for(var child of bookmarkItem.children){
var childGridNode = core.GridNodes.getChildNode(gridNode, child.id); var childGridNode = app.GridNodes.getChildNode(gridNode, child.id);
if(!childGridNode){ if(!childGridNode){
if(EmptyNodes.length>0){ if(EmptyNodes.length>0){
childGridNode = EmptyNodes[0]; childGridNode = EmptyNodes[0];
@@ -324,152 +400,221 @@ core.GridNodes.sync = function(gridNode, rootPath, callback){ // Sync GridNodes
} }
EmptyNodes.length = 0; EmptyNodes.length = 0;
} else { } else {
gridNode.type = core.GridNodes.GridNodeType.empty; gridNode.type = app.GridNodes.GridNodeType.empty;
} }
} }
syncNode(gridNode, bookmarkItem); syncNode(gridNode, bookmarkItem);
core.GridNodes.save(); app.GridNodes.save();
if(callback) callback(); if(callback) callback();
}); });
} }
core.GridNodes.save = function(){ // Save GridNode app.GridNodes.save = function(callback){ // Save GridNodes
browser.storage.local.set(app.settings); app.Settings.save(callback);
browser.runtime.sendMessage({ command: 'GridNodesSaved'});
} }
core.GridNodes.getNode = function(gridNode, path){ // Return GridNode from RootGridNode path app.GridNodes.getNode = function(gridNode, path){ // Return GridNode from RootGridNode path
if(path.length == 0 || path == '/') return gridNode; if(path.length == 0 || path == '/') return gridNode;
for(var child of gridNode.children) for(var child of gridNode.children)
if(path.startsWith(child.title + '/')) if(path.startsWith(child.title + '/'))
return core.GridNodes.getNode(child, path.substr(child.title.length + 1)); return app.GridNodes.getNode(child, path.substr(child.title.length + 1));
return null; return null;
} }
core.GridNodes.getChildNode = function(gridNode, id){ // Return child node by ID app.GridNodes.getNodeById = function(id){
var nodes = app.GridNodes.getNodeWithParents(id);
if(nodes) return nodes[nodes.length-1];
return null;
}
app.GridNodes.getNodeWithParents = function(id){
var parents = [];
function findNode(gridNode){
if(gridNode.id == id){
parents.unshift(gridNode);
return gridNode;
}
if(gridNode.children){
for(var i=0; i<gridNode.children.length; i++){
var result = findNode(gridNode.children[i]);
if(result){
parents.unshift(gridNode);
return result;
}
}
}
return null;
}
findNode(app.node, id);
if(parents.length>0) return parents;
return null;
}
app.GridNodes.updateNode = function(gridNode, value, callback){
if(value){
if(value.title) gridNode.title = value.title;
if(value.image) gridNode.image = value.image;
else delete gridNode.image;
if(gridNode.type == app.GridNodes.GridNodeType.bookmark && value.url && gridNode.url != value.url){
gridNode.url = value.url;
app.GridNodes.refreshNode(gridNode, function(){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.gridNodesLoaded });
});
}
app.GridNodes.saveNode(gridNode);
}
if(callback) callback(gridNode);
}
app.GridNodes.getChildNode = function(gridNode, id){ // Return child node by ID
for(var child of gridNode.children) if(child.id == id) return child; for(var child of gridNode.children) if(child.id == id) return child;
return null; return null;
} }
core.GridNodes.saveNode = function(gridNode){ // Save GridNode app.GridNodes.saveNode = function(gridNode, callback){ // Save GridNode
browser.storage.local.set(app.settings); app.Settings.save(callback);
browser.runtime.sendMessage({ command: 'GridNodeSaved', gridNode: gridNode });
} }
core.GridNodes.setNodeIndex = function(gridNode, index, newIndex, callback){ // Set Child GridNodeIndex. callback(gridNode, node1, node2) app.GridNodes.setNodeIndex = function(gridNode, index, newIndex, callback){ // Set Child GridNodeIndex. callback(gridNode, node1, node2)
while(newIndex>=gridNode.children.length) while(newIndex>=gridNode.children.length)
gridNode.children.push({ type: core.GridNodes.GridNodeType.empty }); gridNode.children.push({ type: app.GridNodes.GridNodeType.empty });
var node1 = gridNode.children[index]; var node1 = gridNode.children[index];
var node2 = gridNode.children[newIndex]; var node2 = gridNode.children[newIndex];
gridNode.children[index] = node2; gridNode.children[index] = node2;
gridNode.children[newIndex] = node1; gridNode.children[newIndex] = node1;
for(var i=gridNode.children.length-1; i>=0; i--){ for(var i=gridNode.children.length-1; i>=0; i--){
if(gridNode.children[i].type != core.GridNodes.GridNodeType.empty) break; if(gridNode.children[i].type != app.GridNodes.GridNodeType.empty) break;
gridNode.children.pop(); gridNode.children.pop();
} }
core.GridNodes.saveNode(gridNode); app.GridNodes.saveNode(gridNode);
if(callback) callback(gridNode, node1, node2); if(callback) callback(gridNode, node1, node2);
} }
core.GridNodes.createFolder = function(gridNode, name, callback){ // Create a new folder in a GridNode. callback(gridNode, newGridNode) app.GridNodes.createBookmark = function(gridNode, url, title, callback){ // Create a new Bookmark in a GridNode. callback(gridNode, newGridNode)
browser.bookmarks.onCreated.removeListener(core.Bookmarks._onCreated); browser.bookmarks.onCreated.removeListener(app.Bookmarks._onCreated);
var prefix = '';
if(url.indexOf('://')<0) prefix = 'http://';
browser.bookmarks.create({
parentId: gridNode.id,
title: title || url,
url: prefix + url
}).then(function(bookmarkItem){
if(!gridNode) return; // ??? Why this method are called a second time with gridNode = null ???
browser.bookmarks.onCreated.addListener(app.Bookmarks._onCreated);
var newGridNode = { id: bookmarkItem.id, type: app.GridNodes.GridNodeType.bookmark, url: prefix + url, title };
var EmptyCellFound = false;
for(var i=0; i<gridNode.children.length; i++){
if(gridNode.children[i].type == app.GridNodes.GridNodeType.empty){
EmptyCellFound = true;
gridNode.children[i] = newGridNode;
break;
}
}
if(EmptyCellFound == false) gridNode.children.push(newGridNode);
app.GridNodes.saveNode(newGridNode);
if(callback) callback(gridNode, newGridNode);
}, function(){
browser.bookmarks.onCreated.addListener(app.Bookmarks._onCreated);
});
}
app.GridNodes.createFolder = function(gridNode, name, callback){ // Create a new folder in a GridNode. callback(gridNode, newGridNode)
browser.bookmarks.onCreated.removeListener(app.Bookmarks._onCreated);
browser.bookmarks.create({ browser.bookmarks.create({
parentId: gridNode.id, parentId: gridNode.id,
title: name title: name
}).then(function(bookmarkItem){ }).then(function(bookmarkItem){
if(!gridNode) return; // ??? Why this method are called a second time with gridNode = null ??? if(!gridNode) return; // ??? Why this method are called a second time with gridNode = null ???
browser.bookmarks.onCreated.addListener(core.Bookmarks._onCreated); browser.bookmarks.onCreated.addListener(app.Bookmarks._onCreated);
var newGridNode = { id: bookmarkItem.id, type: core.GridNodes.GridNodeType.folder, title: name, children: [] }; var newGridNode = { id: bookmarkItem.id, type: app.GridNodes.GridNodeType.folder, title: name, children: [] };
var EmptyCellFound = false; var EmptyCellFound = false;
for(var i=0; i<gridNode.children.length; i++){ for(var i=0; i<gridNode.children.length; i++){
if(gridNode.children[i].type == core.GridNodes.GridNodeType.empty){ if(gridNode.children[i].type == app.GridNodes.GridNodeType.empty){
EmptyCellFound = true; EmptyCellFound = true;
gridNode.children[i] = newGridNode; gridNode.children[i] = newGridNode;
break; break;
} }
} }
if(EmptyCellFound == false) gridNode.children.push(newGridNode); if(EmptyCellFound == false) gridNode.children.push(newGridNode);
core.GridNodes.saveNode(newGridNode); app.GridNodes.saveNode(newGridNode);
if(callback) callback(gridNode, newGridNode); if(callback) callback(gridNode, newGridNode);
}, function(){ }, function(){
browser.bookmarks.onCreated.addListener(core.Bookmarks._onCreated); browser.bookmarks.onCreated.addListener(app.Bookmarks._onCreated);
}); });
} }
core.GridNodes.createBookmark = function(gridNode, url, title, callback){ // Create a new Bookmark in a GridNode. callback(gridNode, newGridNode) app.GridNodes.deleteNode = function(gridNode, id, callback){ // Delete a GridNode. callback(gridNode, id)
browser.bookmarks.onCreated.removeListener(core.Bookmarks._onCreated);
browser.bookmarks.create({
parentId: gridNode.id,
title: title || url,
url: url
}).then(function(bookmarkItem){
if(!gridNode) return; // ??? Why this method are called a second time with gridNode = null ???
browser.bookmarks.onCreated.addListener(core.Bookmarks._onCreated);
var newGridNode = { id: bookmarkItem.id, type: core.GridNodes.GridNodeType.bookmark, url: url, title };
var EmptyCellFound = false;
for(var i=0; i<gridNode.children.length; i++){
if(gridNode.children[i].type == core.GridNodes.GridNodeType.empty){
EmptyCellFound = true;
gridNode.children[i] = newGridNode;
break;
}
}
if(EmptyCellFound == false) gridNode.children.push(newGridNode);
core.GridNodes.saveNode(newGridNode);
if(callback) callback(gridNode, newGridNode);
}, function(){
browser.bookmarks.onCreated.addListener(core.Bookmarks._onCreated);
});
}
core.GridNodes.deleteNode = function(gridNode, id, callback){ // Delete a GridNode. callback(gridNode, id)
for(var i=0; i<gridNode.children.length; i++){ for(var i=0; i<gridNode.children.length; i++){
if(gridNode.children[i].id == id){ if(gridNode.children[i].id == id){
gridNode.children[i] = { type: core.GridNodes.GridNodeType.empty }; gridNode.children[i] = { type: app.GridNodes.GridNodeType.empty };
core.GridNodes.saveNode(gridNode); app.GridNodes.saveNode(gridNode);
break; break;
} }
} }
for(var i=gridNode.children.length-1; i>=0; i--){ for(var i=gridNode.children.length-1; i>=0; i--){
if(gridNode.children[i].type != core.GridNodes.GridNodeType.empty) break; if(gridNode.children[i].type != app.GridNodes.GridNodeType.empty) break;
gridNode.children.pop(); gridNode.children.pop();
} }
browser.bookmarks.onRemoved.removeListener(core.Bookmarks._onRemoved); browser.bookmarks.onRemoved.removeListener(app.Bookmarks._onRemoved);
browser.bookmarks.removeTree(id).then(function(){ browser.bookmarks.removeTree(id).then(function(){
browser.bookmarks.onRemoved.addListener(core.Bookmarks._onRemoved); browser.bookmarks.onRemoved.addListener(app.Bookmarks._onRemoved);
}, function(){ }, function(){
browser.bookmarks.onRemoved.addListener(core.Bookmarks._onRemoved); browser.bookmarks.onRemoved.addListener(app.Bookmarks._onRemoved);
}); });
if(callback) callback(gridNode, id); if(callback) callback(gridNode, id);
} }
core.GridNodes.refreshNode = function(gridNode, callback){ // Refresh content of a GridNode app.GridNodes.refreshNode = function(gridNode, callback){ // Refresh content of a GridNode
if(gridNode.__isLoading == true) return; if(gridNode.__isLoading == true) return;
gridNode.__isLoading = true; gridNode.__isLoading = true;
core.SiteInfos.fromFrame(gridNode.url, function(infos){ switch(gridNode.type){
if(infos){ case app.GridNodes.GridNodeType.folder:
gridNode.title = infos.title; delete gridNode.image;
gridNode.image = infos.screenshot;
delete gridNode.__isLoading; delete gridNode.__isLoading;
core.GridNodes.saveNode(gridNode); app.GridNodes.saveNode(gridNode);
} else delete gridNode.__isLoading; if(callback) callback({ title: gridNode.title, screenshot: gridNode.image });
if(callback) callback(infos); break;
}); case app.GridNodes.GridNodeType.bookmark:
app.SiteInfos.fromFrame(gridNode.url, function(infos){
if(infos){
gridNode.title = infos.title;
gridNode.image = infos.screenshot;
} else {
gridNode.image = '0';
}
delete gridNode.__isLoading;
app.GridNodes.saveNode(gridNode);
if(callback) callback(infos);
});
break;
}
} }
core.GridNodes.capturePage = function(gridNode, callback){ app.GridNodes.capturePage = function(gridNode, callback){
if(gridNode.__isLoading == true) return; if(gridNode.__isLoading == true) return;
gridNode.__isLoading = true; gridNode.__isLoading = true;
core.SiteInfos.fromNewTab(gridNode.url, function(infos){ switch(gridNode.type){
if(infos){ case app.GridNodes.GridNodeType.folder:
gridNode.title = infos.title; var nodes = app.GridNodes.getNodeWithParents(gridNode.id);
gridNode.image = infos.screenshot; if(nodes){
delete gridNode.__isLoading; var path = '';
core.GridNodes.saveNode(gridNode); for(var i=1; i<nodes.length; i++) path = path + '/' + nodes[i].title;
} else delete gridNode.__isLoading; app.SiteInfos.fromNewTab('/dial?path=' + path, function(infos){
if(callback) callback(infos); if(infos){
}); gridNode.image = infos.screenshot;
} else {
delete gridNode.image;
}
delete gridNode.__isLoading;
app.GridNodes.saveNode(gridNode);
if(callback) callback({ title: gridNode.title, screenshot: gridNode.image });
});
}
break;
case app.GridNodes.GridNodeType.bookmark:
app.SiteInfos.fromNewTab(gridNode.url, function(infos){
if(infos){
gridNode.title = infos.title;
gridNode.image = infos.screenshot;
} else {
gridNode.image = '0';
}
delete gridNode.__isLoading;
app.GridNodes.saveNode(gridNode);
if(callback) callback(infos);
});
break;
}
} }
// Public members
app.GridNodeType = core.GridNodes.GridNodeType;
app.refreshNode = core.GridNodes.refreshNode;
app.getNode = core.GridNodes.getNode;
app.createFolder = core.GridNodes.createFolder;
app.createBookmark = core.GridNodes.createBookmark;
app.deleteNode = core.GridNodes.deleteNode;
app.setNodeIndex = core.GridNodes.setNodeIndex;
app.capturePage = core.GridNodes.capturePage;
app.saveSettings = core.Settings.save;

View File

@@ -1,94 +1,218 @@
var app = {} var utils = {};
var dial = { var app = {};
styles: {}, var dial = {
page: 1, page: 1,
maxpage: 1 maxpage: 1
}; };
window.onload = function(){ document.addEventListener("DOMContentLoaded", function(event) {
function initPage(){ document.body.style.backgroundColor = utils.getBackgroundColor();
browser.runtime.getBackgroundPage().then(function(page){ app.init();
if(page.app.settings){ dial.init();
app = page.app; });
dial.initUI();
browser.runtime.onMessage.addListener(function(request, sender, sendResponse){
switch(request.command){
case 'SettingsChanged':
if(app.settings){
dial.Head.removeChild(dial.Style);
dial.Body.removeChild(dial.Grid);
dial.initStyles();
dial.Grid = dial.initGrid('Grid', app.settings.grid, dial.Body);
var url = new URL(window.location);
dial.path = url.searchParams.get('path');
if(url.searchParams.get('path')) {
dial.Node = app.getNode(app.settings.grid.node, dial.path + '/');
} else {
dial.Node = app.getNode(app.settings.grid.node, '/');
}
dial.Title.innerText = dial.Node.title;
dial.populateGrid(dial.Grid, app.settings.grid, dial.Node);
}
break;
case 'GridNodesSaved':
if(app.settings) dial.populateGrid(dial.Grid, app.settings.grid, dial.Node);
break;
case 'GridNodeSaved':
// request.gridNode
if(app.settings) dial.populateGrid(dial.Grid, app.settings.grid, dial.Node);
break;
}
});
} else{
setTimeout(initPage, 100);
}
}, function(){});
}
initPage();
}
window.onresize = function(){ window.onresize = function(){
if(app && app.settings) dial.updateGridLayout(dial.Grid, app.settings.grid, dial.styles.grid); if(app && app.settings) dial.updateGridLayout();
} }
window.onwheel = function(ev){ window.onwheel = function(ev){
if(app && app.settings){ if(app && app.settings){
if(ev.deltaY > 0){ if(ev.deltaY > 0){
if(dial.page < dial.maxpage){ if(dial.page < dial.maxpage){
dial.page += 1; dial.page += 1;
dial.populateGrid(dial.Grid, app.settings.grid, dial.Node); dial.populateGrid();
} }
} else if(ev.deltaY < 0){ } else if(ev.deltaY < 0){
if(dial.page > 1){ if(dial.page > 1){
dial.page -= 1; dial.page -= 1;
dial.populateGrid(dial.Grid, app.settings.grid, dial.Node); dial.populateGrid();
} }
} }
} }
} }
dial.initUI = function(){
dial.Head = document.getElementById('head'); utils.getBackgroundColor = function(){
dial.Title = document.getElementById('title'); return new URL(window.location).searchParams.get('bg');
dial.Body = document.getElementById('body'); };
dial.Body.setAttribute('contextmenu', 'page'); utils.getPath = function(){
dial.Body.setAttribute('contextmenu', 'page'); var path = new URL(window.location).searchParams.get('path');
dial.initStyles(); if(path) return path + '/';
dial.initMenus(); else return '/';
dial.Grid = dial.initGrid('Grid', app.settings.grid, dial.Body); };
var url = new URL(window.location);
dial.path = url.searchParams.get('path'); app.init = function(){
if(url.searchParams.get('path')) { app.Messages.getSettings(function(settings){
dial.Node = app.getNode(app.settings.grid.node, dial.path + '/'); if(settings && settings.grid) app.Settings._changed(settings);
} else { dial.path = utils.getPath();
dial.Node = app.getNode(app.settings.grid.node, '/'); app.Messages.getNode(dial.path, app.GridNodes._changed);
} app.Messages.init();
dial.Title.innerText = dial.Node.title; });
dial.populateGrid(dial.Grid, app.settings.grid, dial.Node); };
app.Messages = {};
app.Messages.Commands = {
getSettings: 0,
setSettings: 1,
getNode: 2,
getNodeByID: 3,
updateNode: 4,
setNodeIndex: 5,
createBookmark: 6,
createFolder: 7,
deleteNode: 8,
refreshNode: 9,
capturePage: 10,
settingsChanged: 100,
gridNodesLoaded: 101
};
app.Messages.init = function(){
browser.runtime.onMessage.addListener(function(request, sender, sendResponse){
switch(request.cmd){
case app.Messages.Commands.settingsChanged:
app.Messages.getSettings(app.Settings._changed);
break;
case app.Messages.Commands.gridNodesLoaded:
app.Messages.getNode(dial.path, app.GridNodes._changed);
break;
}
});
};
app.Messages.getSettings = function(callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.getSettings }).then(callback, callback);
};
app.Messages.getNode = function(path, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.getNode, path: path }).then(callback);
};
app.Messages.setNodeIndex = function(index, newIndex, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.setNodeIndex, path: dial.path, index: index, newIndex: newIndex }).then(callback);
};
app.Messages.createBookmark = function(url, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.createBookmark, path: dial.path, url: url, title: url }).then(callback);
};
app.Messages.createFolder = function(name, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.createFolder, path: dial.path, name: name }).then(callback);
};
app.Messages.deleteNode = function(id, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.deleteNode, path: dial.path, id: id }).then(callback);
};
app.Messages.refreshNode = function(id, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.refreshNode, path: dial.path, id: id }).then(callback);
}
app.Messages.capturePage = function(id, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.capturePage, path: dial.path, id: id }).then(callback);
} }
app.Settings = {};
app.Settings._changed = function(settings){
app.settings = settings;
dial.initStyles();
dial.initGrid();
};
app.GridNodes = {};
app.GridNodes.GridNodeType = { // GridNodeType
back: -1,
empty: 0,
folder: 1,
bookmark: 2
}
app.GridNodes._changed = function(node){
app.node = node;
dial.Title.innerText = app.node.title;
dial.populateGrid();
};
dial.init = function(){
dial.initMenus();
dial.Title = document.createElement('title');
document.head.appendChild(dial.Title);
};
dial.initMenus = function(){
document.body.setAttribute('contextmenu', 'page');
dial.PageMenu = document.createElement('menu');
dial.PageMenu.type = 'context';
dial.PageMenu.id = 'page'
dial.PageMenuNew = document.createElement('menu');
dial.PageMenuNew.label = browser.i18n.getMessage("menuNew");
dial.PageMenuCreateBookmark = document.createElement('menuitem');
dial.PageMenuCreateBookmark.label = browser.i18n.getMessage("menuNewBookmark");
dial.PageMenuCreateBookmark.onclick = dial.createBookmark;
dial.PageMenuCreateFolder = document.createElement('menuitem');
dial.PageMenuCreateFolder.label = browser.i18n.getMessage("menuNewFolder");
dial.PageMenuCreateFolder.onclick = dial.createFolder;
dial.PageMenuSettings = document.createElement('menuitem');
dial.PageMenuSettings.label = browser.i18n.getMessage("menuSettings");
dial.PageMenuSettings.onclick = dial.editSettings;
dial.PageMenu.appendChild(dial.PageMenuNew);
dial.PageMenuNew.appendChild(dial.PageMenuCreateBookmark);
dial.PageMenuNew.appendChild(dial.PageMenuCreateFolder);
dial.PageMenu.appendChild(document.createElement('hr'));
dial.PageMenu.appendChild(dial.PageMenuSettings);
document.body.appendChild(dial.PageMenu);
dial.ItemMenu = document.createElement('menu');
dial.ItemMenu.type = 'context';
dial.ItemMenu.id = 'item'
dial.ItemMenuNew = document.createElement('menu');
dial.ItemMenuNew.label = browser.i18n.getMessage("menuNew");
dial.ItemMenuCreateBookmark = document.createElement('menuitem');
dial.ItemMenuCreateBookmark.label = browser.i18n.getMessage("menuNewBookmark");
dial.ItemMenuCreateBookmark.onclick = dial.createBookmark;
dial.ItemMenuCreateFolder = document.createElement('menuitem');
dial.ItemMenuCreateFolder.label = browser.i18n.getMessage("menuNewFolder");
dial.ItemMenuCreateFolder.onclick = dial.createFolder;
dial.ItemMenuProperties = document.createElement('menuitem');
dial.ItemMenuProperties.label = browser.i18n.getMessage("menuProperties");
dial.ItemMenuProperties.onclick = function(){
dial.editProperties(dial._selectedItem);
};
dial.ItemMenuRefresh = document.createElement('menuitem');
dial.ItemMenuRefresh.label = browser.i18n.getMessage("menuRefreshItem");
dial.ItemMenuRefresh.onclick = function(){
dial.refreshNode(dial._selectedItem);
};
dial.ItemMenuCapture = document.createElement('menuitem');
dial.ItemMenuCapture.label = browser.i18n.getMessage("menuCapturePage");
dial.ItemMenuCapture.onclick = function(){
dial.capturePage(dial._selectedItem);
};
dial.ItemMenuDelete = document.createElement('menuitem');
dial.ItemMenuDelete.label = browser.i18n.getMessage("menuDeleteItem");
dial.ItemMenuDelete.onclick = dial.deleteNode;
dial.ItemMenuSettings = document.createElement('menuitem');
dial.ItemMenuSettings.label = browser.i18n.getMessage("menuSettings");
dial.ItemMenuSettings.onclick = dial.editSettings;
dial.ItemMenu.appendChild(dial.ItemMenuNew);
dial.ItemMenuNew.appendChild(dial.ItemMenuCreateBookmark);
dial.ItemMenuNew.appendChild(dial.ItemMenuCreateFolder);
dial.ItemMenu.appendChild(document.createElement('hr'));
dial.ItemMenu.appendChild(dial.ItemMenuProperties);
dial.ItemMenu.appendChild(dial.ItemMenuRefresh);
dial.ItemMenu.appendChild(dial.ItemMenuCapture);
dial.ItemMenu.appendChild(dial.ItemMenuDelete);
dial.ItemMenu.appendChild(document.createElement('hr'));
dial.ItemMenu.appendChild(dial.ItemMenuSettings);
document.body.appendChild(dial.ItemMenu);
}
dial.initStyles = function(){ dial.initStyles = function(){
var oldStyle = dial.Style;
dial.Style = document.createElement('style'), StyleSheet; dial.Style = document.createElement('style'), StyleSheet;
document.head.appendChild(dial.Style); document.head.appendChild(dial.Style);
dial.styles = {};
dial.styles.html = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('html { height: 100%; }')].style; dial.styles.html = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('html { height: 100%; }')].style;
dial.styles.body = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('body { user-select: none; -moz-user-select: none; display: flex; width: 100%; height: 100%; margin: 0px; padding: 0px; background-color: ' + app.settings.backgroundColor + '; background-image: ' + app.settings.backgroundImage + '; background-repeat: no-repeat; background-size: 100% 100%; }')].style; dial.styles.body = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('body { user-select: none; -moz-user-select: none; display: flex; width: 100%; height: 100%; margin: 0px; padding: 0px; background-color: ' + app.settings.backgroundColor + '; background-image: ' + app.settings.backgroundImage + '; background-repeat: no-repeat; background-size: 100% 100%; }')].style;
dial.styles.grid = {}; dial.styles.grid = {};
@@ -110,105 +234,49 @@ dial.initStyles = function(){
dial.styles.grid.linkFolder = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('.Grid td>a.Folder :first-child { background-image: ' + app.settings.grid.folderIcon + '; background-repeat: no-repeat; background-size: 100% 100%; }')].style; dial.styles.grid.linkFolder = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('.Grid td>a.Folder :first-child { background-image: ' + app.settings.grid.folderIcon + '; background-repeat: no-repeat; background-size: 100% 100%; }')].style;
dial.styles.grid.linkBookmark = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('.Grid td>a.Bookmark :first-child { background-repeat: no-repeat; background-size: 100% 100%; }')].style; dial.styles.grid.linkBookmark = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('.Grid td>a.Bookmark :first-child { background-repeat: no-repeat; background-size: 100% 100%; }')].style;
dial.styles.grid.linkBookmarkLoading = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('.Grid td>a.BookmarkLoading :first-child { background-image: url("' + app.settings.grid.cells.loadingIcon + '"); background-repeat: no-repeat; background-position: center center; }')].style; dial.styles.grid.linkBookmarkLoading = dial.Style.sheet.cssRules[dial.Style.sheet.insertRule('.Grid td>a.BookmarkLoading :first-child { background-image: url("' + app.settings.grid.cells.loadingIcon + '"); background-repeat: no-repeat; background-position: center center; }')].style;
} if(oldStyle) document.head.removeChild(oldStyle);
};
dial.initMenus = function(){ dial.initGrid = function(){
dial.PageMenu = document.createElement('menu'); var oldGrid = dial.Grid;
dial.PageMenu.type = 'context'; dial.Grid = document.createElement('table');
dial.PageMenu.id = 'page'
dial.PageMenuNew = document.createElement('menu');
dial.PageMenuNew.label = browser.i18n.getMessage("menuNew");
dial.PageMenuCreateBookmark = document.createElement('menuitem');
dial.PageMenuCreateBookmark.label = browser.i18n.getMessage("menuNewBookmark");
dial.PageMenuCreateBookmark.onclick = dial.createBookmark;
dial.PageMenuCreateFolder = document.createElement('menuitem');
dial.PageMenuCreateFolder.label = browser.i18n.getMessage("menuNewFolder");
dial.PageMenuCreateFolder.onclick = dial.createFolder;
dial.PageMenuSettings = document.createElement('menuitem');
dial.PageMenuSettings.label = browser.i18n.getMessage("menuSettings");
dial.PageMenuSettings.onclick = dial.editSettings;
dial.PageMenu.appendChild(dial.PageMenuNew);
dial.PageMenuNew.appendChild(dial.PageMenuCreateBookmark);
dial.PageMenuNew.appendChild(dial.PageMenuCreateFolder);
dial.PageMenu.appendChild(document.createElement('hr'));
dial.PageMenu.appendChild(dial.PageMenuSettings);
dial.Body.appendChild(dial.PageMenu);
dial.ItemMenu = document.createElement('menu');
dial.ItemMenu.type = 'context';
dial.ItemMenu.id = 'item'
dial.ItemMenuNew = document.createElement('menu');
dial.ItemMenuNew.label = browser.i18n.getMessage("menuNew");
dial.ItemMenuCreateBookmark = document.createElement('menuitem');
dial.ItemMenuCreateBookmark.label = browser.i18n.getMessage("menuNewBookmark");
dial.ItemMenuCreateBookmark.onclick = dial.createBookmark;
dial.ItemMenuCreateFolder = document.createElement('menuitem');
dial.ItemMenuCreateFolder.label = browser.i18n.getMessage("menuNewFolder");
dial.ItemMenuCreateFolder.onclick = dial.createFolder;
/*
dial.ItemMenuEdit = document.createElement('menuitem');
dial.ItemMenuEdit.label = 'Edit';
//dial.ItemMenuEdit.onclick = dial.test;
*/
dial.ItemMenuRefresh = document.createElement('menuitem');
dial.ItemMenuRefresh.label = browser.i18n.getMessage("menuRefreshItem");
dial.ItemMenuRefresh.onclick = dial.refreshNode;
dial.ItemMenuCapture = document.createElement('menuitem');
dial.ItemMenuCapture.label = browser.i18n.getMessage("menuCapturePage");
dial.ItemMenuCapture.onclick = dial.capturePage;
dial.ItemMenuDelete = document.createElement('menuitem');
dial.ItemMenuDelete.label = browser.i18n.getMessage("menuDeleteItem");
dial.ItemMenuDelete.onclick = dial.deleteNode;
dial.ItemMenuSettings = document.createElement('menuitem');
dial.ItemMenuSettings.label = browser.i18n.getMessage("menuSettings");
dial.ItemMenuSettings.onclick = dial.editSettings;
dial.ItemMenu.appendChild(dial.ItemMenuNew);
dial.ItemMenuNew.appendChild(dial.ItemMenuCreateBookmark);
dial.ItemMenuNew.appendChild(dial.ItemMenuCreateFolder);
dial.ItemMenu.appendChild(document.createElement('hr'));
//dial.ItemMenu.appendChild(dial.ItemMenuEdit);
dial.ItemMenu.appendChild(dial.ItemMenuRefresh);
dial.ItemMenu.appendChild(dial.ItemMenuCapture);
dial.ItemMenu.appendChild(dial.ItemMenuDelete);
dial.ItemMenu.appendChild(document.createElement('hr'));
dial.ItemMenu.appendChild(dial.ItemMenuSettings);
dial.Body.appendChild(dial.ItemMenu);
}
dial.initGrid = function(name, settings, container){
var grid = document.createElement('table'); var grid = document.createElement('table');
grid.className = name; dial.Grid.className = 'Grid';
grid.getLink = function(index){ dial.Grid.getLink = function(index){
var num_columns = grid.rows[0].cells.length; var num_columns = dial.Grid.rows[0].cells.length;
return grid.rows[Math.floor(index/num_columns)].cells[index % num_columns].childNodes[0]; return dial.Grid.rows[Math.floor(index/num_columns)].cells[index % num_columns].childNodes[0];
} }
for(var i=0; i<settings.rows; i++){ for(var i=0; i<app.settings.grid.rows; i++){
var row = grid.insertRow(); var row = dial.Grid.insertRow();
for(var j=0; j<settings.columns; j++){ for(var j=0; j<app.settings.grid.columns; j++){
var cell = row.insertCell(); var cell = row.insertCell();
var link = document.createElement('a'); var link = document.createElement('a');
cell.setAttribute('gridindex', (i * settings.columns + j)); cell.setAttribute('gridindex', (i * app.settings.grid.columns + j));
cell.appendChild(link); cell.appendChild(link);
link.className = 'Empty';
link.appendChild(document.createElement('div')); link.appendChild(document.createElement('div'));
link.appendChild(document.createElement('div')); link.appendChild(document.createElement('div'));
link.onmousedown = function(){ dial._selectedItem = this; }; link.onmousedown = function(){ dial._selectedItem = this; };
function dragstart_handler(ev) { function dragstart_handler(ev) {
if(!ev.target.Node){
ev.preventDefault();
return;
}
var index = (dial.page - 1) * (app.settings.grid.rows * app.settings.grid.columns) + +(ev.target.parentElement.getAttribute('gridindex')); var index = (dial.page - 1) * (app.settings.grid.rows * app.settings.grid.columns) + +(ev.target.parentElement.getAttribute('gridindex'));
if(settings.backNode && dial.path) index -= dial.page; if(app.settings.grid.backNode && dial.path != '/') index -= dial.page;
console.log(index);
ev.dataTransfer.setData("text/plain", index); ev.dataTransfer.setData("text/plain", index);
} }
function dragover_handler(ev) { function dragover_handler(ev) {
ev.preventDefault(); ev.preventDefault();
ev.dataTransfer.dropEffect = "move" if(app.settings.grid.backNode && dial.path != '/'){
var gridIndex = 0;
if(ev.target.tagName == 'DIV') gridIndex = +(ev.target.parentElement.parentElement.getAttribute('gridindex'));
else gridIndex = +(ev.target.getAttribute('gridindex'));
if(gridIndex==0) ev.dataTransfer.dropEffect = "none";
else ev.dataTransfer.dropEffect = "move";
} else {
ev.dataTransfer.dropEffect = "move";
}
} }
function drop_handler(ev) { function drop_handler(ev) {
ev.preventDefault(); ev.preventDefault();
@@ -218,44 +286,42 @@ dial.initGrid = function(name, settings, container){
if(ev.target.tagName == 'DIV'){ if(ev.target.tagName == 'DIV'){
EndIndex = (dial.page - 1) * (app.settings.grid.rows * app.settings.grid.columns) + +(ev.target.parentElement.parentElement.getAttribute('gridindex')); EndIndex = (dial.page - 1) * (app.settings.grid.rows * app.settings.grid.columns) + +(ev.target.parentElement.parentElement.getAttribute('gridindex'));
} else{ } else{
EndIndex =(dial.page - 1) * (app.settings.grid.rows * app.settings.grid.columns) + +(ev.target.getAttribute('gridindex')); EndIndex = (dial.page - 1) * (app.settings.grid.rows * app.settings.grid.columns) + +(ev.target.getAttribute('gridindex'));
} }
if(settings.backNode && dial.path) EndIndex -= dial.page; if(app.settings.grid.backNode && dial.path != '/') EndIndex -= dial.page;
app.setNodeIndex(dial.Node, StartIndex, EndIndex); app.Messages.setNodeIndex(StartIndex, EndIndex);
} }
link.draggable = true; link.draggable = true;
link.ondragstart = dragstart_handler; link.ondragstart = dragstart_handler;
cell.ondragover = dragover_handler; cell.ondragover = dragover_handler;
cell.ondrop = drop_handler; cell.ondrop = drop_handler;
} }
} }
container.appendChild(grid); document.body.appendChild(dial.Grid);
dial.updateGridLayout(grid, settings, dial.styles.grid); dial.updateGridLayout();
return grid; if(oldGrid) document.body.removeChild(oldGrid);
} return dial.Grid;
};
dial.updateGridLayout = function(grid, settings, styles){ dial.updateGridLayout = function(){
var fullWidth = grid.parentElement.offsetWidth - 2 * settings.margin; var fullWidth = dial.Grid.parentElement.offsetWidth - 2 * app.settings.grid.margin;
var fullHeight = grid.parentElement.offsetHeight - 2 * settings.margin; var fullHeight = dial.Grid.parentElement.offsetHeight - 2 * app.settings.grid.margin;
var linkWidth = fullWidth / settings.columns; var linkWidth = fullWidth / app.settings.grid.columns;
var linkHeight = fullHeight / settings.rows; var linkHeight = fullHeight / app.settings.grid.rows;
if(linkWidth <= linkHeight * settings.cells.ratioX / settings.cells.ratioY) linkHeight = linkWidth / settings.cells.ratioX * settings.cells.ratioY; if(linkWidth <= linkHeight * 4 / 3) linkHeight = linkWidth / 4 * 3;
else linkWidth = linkHeight / settings.cells.ratioY * settings.cells.ratioX; else linkWidth = linkHeight / 3 * 4;
styles.cell.width = linkWidth.toString() + 'px'; dial.styles.grid.cell.width = linkWidth.toString() + 'px';
styles.cell.height = linkHeight.toString() + 'px'; dial.styles.grid.cell.height = linkHeight.toString() + 'px';
linkWidth = linkWidth - 2 * (settings.cells.margin + 1); linkWidth = linkWidth - 2 * (app.settings.grid.cells.margin + 1);
linkHeight = linkHeight - 2 * (settings.cells.margin + 1); linkHeight = linkHeight - 2 * (app.settings.grid.cells.margin + 1);
styles.link.width = linkWidth.toString() + 'px'; dial.styles.grid.link.width = linkWidth.toString() + 'px';
styles.link.height = linkHeight.toString() + 'px'; dial.styles.grid.link.height = linkHeight.toString() + 'px';
if(settings.cells.title) styles.linkPanel.height = (linkHeight - settings.cells.titleHeight - 1).toString() + 'px'; if(app.settings.grid.cells.title) dial.styles.grid.linkPanel.height = (linkHeight - app.settings.grid.cells.titleHeight - 1).toString() + 'px';
else styles.linkPanel.height = linkHeight.toString() + 'px'; else dial.styles.grid.linkPanel.height = linkHeight.toString() + 'px';
} };
dial.populateGrid = function(){
dial.populateGrid = function(grid, settings, node){
populateEmpty = function(link){ populateEmpty = function(link){
link.Node = null; link.Node = null;
link.className = 'Empty'; link.className = 'Empty';
@@ -276,10 +342,11 @@ dial.populateGrid = function(grid, settings, node){
populateFolder = function(link, node){ populateFolder = function(link, node){
link.Node = node; link.Node = node;
link.className = 'Folder'; link.className = 'Folder';
link.childNodes[0].style.backgroundImage = ''; if(node.image) link.childNodes[0].style.backgroundImage = 'url(' + node.image + ')';
else link.childNodes[0].style.backgroundImage = '';
link.childNodes[1].innerText = node.title; link.childNodes[1].innerText = node.title;
if(dial.path) link.href = '?path=' + dial.path + '/' + node.title; if(dial.path) link.href = '?' + 'bg=' + encodeURIComponent(app.settings.backgroundColor) + '&path=' + encodeURIComponent(dial.path + node.title);
else link.href = '?path=' + node.title; else link.href = '?' + 'bg=' + encodeURIComponent(app.settings.backgroundColor) + '&path=' + encodeURIComponent(node.title);
link.onclick = null; link.onclick = null;
link.setAttribute('contextmenu', 'item'); link.setAttribute('contextmenu', 'item');
} }
@@ -291,11 +358,7 @@ dial.populateGrid = function(grid, settings, node){
} else { } else {
link.className = 'BookmarkLoading'; link.className = 'BookmarkLoading';
link.childNodes[0].style.backgroundImage = ''; link.childNodes[0].style.backgroundImage = '';
app.refreshNode(node, function(){ dial.refreshNode(link);
link.className = 'Bookmark';
link.childNodes[0].style.backgroundImage = 'url(' + node.image + ')';
link.childNodes[1].innerText = node.title;
});
} }
link.childNodes[1].innerText = node.title; link.childNodes[1].innerText = node.title;
link.href = node.url; link.href = node.url;
@@ -305,69 +368,59 @@ dial.populateGrid = function(grid, settings, node){
var iBase = 0; var iBase = 0;
var linkItem = 0; var linkItem = 0;
var allCells = settings.rows * settings.columns; var allCells = app.settings.grid.rows * app.settings.grid.columns;
var maxCells = allCells; var maxCells = allCells;
if(settings.backNode && dial.path){ if(app.settings.grid.backNode && dial.path != '/'){
populateBack(grid.getLink(linkItem)); populateBack(dial.Grid.getLink(linkItem));
linkItem++; linkItem++;
maxCells -= 1; maxCells -= 1;
} }
dial.maxpage = Math.floor(node.children.length / maxCells); dial.maxpage = Math.floor(app.node.children.length / maxCells);
if(dial.maxpage != node.children.length / maxCells) dial.maxpage += 1; if(dial.maxpage != app.node.children.length / maxCells) dial.maxpage += 1;
if(dial.page > dial.maxpage) dial.page = dial.maxpage; if(dial.page > dial.maxpage) dial.page = dial.maxpage;
if(dial.page > 1) iBase = (dial.page -1) * maxCells; if(dial.page > 1) iBase = (dial.page -1) * maxCells;
for(var i = iBase; i<node.children.length && i<maxCells + iBase; i++) { for(var i = iBase; i<app.node.children.length && i<maxCells + iBase; i++) {
switch(node.children[i].type){ switch(app.node.children[i].type){
case app.GridNodeType.empty: case app.GridNodes.GridNodeType.empty:
populateEmpty(grid.getLink(linkItem)); populateEmpty(dial.Grid.getLink(linkItem));
break; break;
case app.GridNodeType.folder: case app.GridNodes.GridNodeType.folder:
populateFolder(grid.getLink(linkItem), node.children[i]); populateFolder(dial.Grid.getLink(linkItem), app.node.children[i]);
break; break;
case app.GridNodeType.bookmark: case app.GridNodes.GridNodeType.bookmark:
populateBookmark(grid.getLink(linkItem), node.children[i]); populateBookmark(dial.Grid.getLink(linkItem), app.node.children[i]);
break; break;
} }
linkItem++; linkItem++;
} }
while(linkItem<allCells){ while(linkItem<allCells){
populateEmpty(grid.getLink(linkItem)); populateEmpty(dial.Grid.getLink(linkItem));
linkItem++; linkItem++;
} }
} };
dial.createBookmark = function(){ dial.createBookmark = function(){
var url = prompt(browser.i18n.getMessage("AddBookmarkPrompt"), 'https://'); var url = prompt(browser.i18n.getMessage("AddBookmarkPrompt"), 'https://');
if(url) app.createBookmark(dial.Node, url); if(url) app.Messages.createBookmark(url);
}; };
dial.createFolder = function(){ dial.createFolder = function(){
var name = prompt(browser.i18n.getMessage("AddFolderPrompt"), 'New Folder'); var name = prompt(browser.i18n.getMessage("AddFolderPrompt"), 'New Folder');
if(name) app.createFolder(dial.Node, name); if(name) app.Messages.createFolder(name);
}; };
dial.refreshNode = function(){
if(dial._selectedItem.Node.type == app.GridNodeType.bookmark){
var link = dial._selectedItem;
link.className = 'BookmarkLoading';
link.childNodes[0].style.backgroundImage = '';
app.refreshNode(link.Node, function(){
link.className = 'Bookmark';
link.childNodes[0].style.backgroundImage = 'url(' + link.Node.image + ')';
link.childNodes[1].innerText = link.Node.title;
});
}
}
dial.deleteNode = function(){ dial.deleteNode = function(){
if(confirm(browser.i18n.getMessage("deleteItemConfimation", dial._selectedItem.Node.title))) if(confirm(browser.i18n.getMessage("deleteItemConfimation", dial._selectedItem.Node.title)))
app.deleteNode(dial.Node, dial._selectedItem.Node.id); app.Messages.deleteNode(dial._selectedItem.Node.id);
}
dial.refreshNode = function(selectedItem){
selectedItem.className = 'BookmarkLoading';
selectedItem.childNodes[0].style.backgroundImage = app.settings.grid.loadingIcon;
app.Messages.refreshNode(selectedItem.Node.id);
}
dial.capturePage = function(selectedItem){
selectedItem.className = 'BookmarkLoading';
selectedItem.childNodes[0].style.backgroundImage = app.settings.grid.loadingIcon;
app.Messages.capturePage(selectedItem.Node.id);
} }
dial.capturePage = function(){
if(dial._selectedItem.Node.type == app.GridNodeType.bookmark)
app.capturePage(dial._selectedItem.Node);
}
@@ -399,20 +452,20 @@ dial.PopupPanel = function(width, height, modal){ // PopupPanel Object
this._contextMenuHandler = function(e){ e.preventDefault(); } this._contextMenuHandler = function(e){ e.preventDefault(); }
this.popup = function(){ this.popup = function(){
window.addEventListener('contextmenu', this._contextMenuHandler, false); window.addEventListener('contextmenu', this._contextMenuHandler, false);
dial.Body.appendChild(this.modal); document.body.appendChild(this.modal);
dial.Body.appendChild(this.panelContainer); document.body.appendChild(this.panelContainer);
} }
this.close = function(){ this.close = function(){
dial.Body.removeChild(this.modal); document.body.removeChild(this.modal);
dial.Body.removeChild(this.panelContainer); document.body.removeChild(this.panelContainer);
window.removeEventListener('contextmenu', this._contextMenuHandler, false); window.removeEventListener('contextmenu', this._contextMenuHandler, false);
} }
} else { } else {
this.popup = function(){ this.popup = function(){
dial.Body.appendChild(this.panelContainer); document.body.appendChild(this.panelContainer);
} }
this.close = function(){ this.close = function(){
dialBody.removeChild(this.panelContainer); document.body.removeChild(this.panelContainer);
} }
} }
} }
@@ -431,3 +484,18 @@ dial.editSettings = function(){
iframe.popup = popup; iframe.popup = popup;
popup.popup(); popup.popup();
} }
dial.editProperties = function(selectedItem){
var popup = new dial.PopupPanel(500, 420, true);
var iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.style.backgroundColor = 'transparent';
iframe.style.border = '0px none transparent';
iframe.style.padding = '0px';
iframe.style.overflow = 'hidden';
popup.frame.appendChild(iframe);
iframe.src = '/html/properties.html?id=' + selectedItem.Node.id;
iframe.popup = popup;
popup.popup();
}

151
src/js/properties.js Normal file
View File

@@ -0,0 +1,151 @@
var app = {};
var Image = null;
document.addEventListener("DOMContentLoaded", function(event) {
app.init();
});
app.init = function(){
app.Messages.getSettings(function(settings){
app.settings = settings;
app.Messages.getNodeByID(new URL(window.location).searchParams.get('id'), function(node){
app.node = node;
Title.value = node.title;
ImagePreview.style.backgroundRepeat = 'no-repeat';
ImagePreview.style.backgroundSize = '100% 100%';
switch(node.type){
case app.GridNodes.GridNodeType.folder:
Url.parentNode.parentNode.style.display = 'none';
if(node.image){
if(node.image.indexOf('url(')>0) Image = node.image;
else Image = 'url(' + node.image + ')';
} else Image = null;
if(Image==null) ImagePreview.style.backgroundImage = app.settings.grid.folderIcon;
else ImagePreview.style.backgroundImage = Image;
break;
case app.GridNodes.GridNodeType.bookmark:
ImageDefault.style.display = 'none';
Url.value = node.url;
Image = 'url(' + node.image + ')';
ImagePreview.style.backgroundImage = Image;
break;
}
ImageReset.onclick = function(){
switch(node.type){
case app.GridNodes.GridNodeType.folder:
if(node.image){
Image = node.image;
ImagePreview.style.backgroundImage = 'url(' + Image + ')';
} else {
Image = null;
ImagePreview.style.backgroundImage = app.settings.grid.folderIcon;
}
break;
case app.GridNodes.GridNodeType.bookmark:
Image = node.image;
ImagePreview.style.backgroundImage = 'url(' + Image + ')';
break;
}
};
ImageDefault.onclick = function(){
switch(node.type){
case app.GridNodes.GridNodeType.folder:
Image = null;
ImagePreview.style.backgroundImage = app.settings.grid.folderIcon;
break;
case app.GridNodes.GridNodeType.bookmark:
break;
}
};
ImageFile.onclick = function(){
this.value = null;
}
ImageFile.onchange = function(){
var fileReader = new FileReader();
fileReader.onload = function(e){
Image = e.target.result;
ImageFile.value = null;
ImagePreview.style.backgroundImage = 'url(' + Image + ')';
}
fileReader.readAsDataURL(ImageFile.files[0]);
}
});
});
BtnOk.onclick = function(){
BtnApply.onclick();
window.frameElement.popup.close();
}
BtnApply.onclick = function(){
switch(app.node.type){
case app.GridNodes.GridNodeType.folder:
app.Messages.updateNode(app.node.id, { title: Title.value, image: Image })
break;
case app.GridNodes.GridNodeType.bookmark:
app.Messages.updateNode(app.node.id, { title: Title.value, url: Url.value, image: Image })
break;
}
}
BtnCancel.onclick = function(){
window.frameElement.popup.close();
}
var tabButtons = Tabs.children[0].children[0].children[0];
for(var i=0; i<tabButtons.children.length-1; i++){
tabButtons.children[i].index = i;
tabButtons.children[i].onclick = function(){
for(var j=0; j<tabButtons.children.length-1; j++){
if(j==this.index){
tabButtons.children[j].className = 'TabButtonActive';
Tabs.children[1].children[j].className = '';
} else {
tabButtons.children[j].className = 'TabButton';
Tabs.children[1].children[j].className = 'hidden';
}
}
}
}
};
app.Messages = {};
app.Messages.Commands = {
getSettings: 0,
setSettings: 1,
getNode: 2,
getNodeByID: 3,
updateNode: 4,
setNodeIndex: 5,
createBookmark: 6,
createFolder: 7,
deleteNode: 8,
refreshNode: 9,
capturePage: 10,
settingsChanged: 100,
gridNodesLoaded: 101
};
app.Messages.getSettings = function(callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.getSettings }).then(callback);
};
app.Messages.getNodeByID = function(id, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.getNodeByID, id: id }).then(callback);
};
app.Messages.updateNode = function(id, value, callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.updateNode, id: id, value: value }).then(callback);
};
app.GridNodes = {};
app.GridNodes.GridNodeType = { // GridNodeType
back: -1,
empty: 0,
folder: 1,
bookmark: 2
}

View File

@@ -1,10 +1,17 @@
var app = {};
var BackgroundImage = null; var BackgroundImage = null;
var GridBackImage = null; var GridBackImage = null;
var GridFolderImage = null; var GridFolderImage = null;
window.onload = function(){ document.addEventListener("DOMContentLoaded", function(event) {
browser.runtime.getBackgroundPage().then(function(page){ app.init();
app = page.app; });
app.init = function(){
app.Messages.getSettings(function(settings){
app.settings = settings;
BackgroundColor.value = app.settings.backgroundColor; BackgroundColor.value = app.settings.backgroundColor;
BackgroundImage = app.settings.backgroundImage; BackgroundImage = app.settings.backgroundImage;
BackgroundPreview.style.backgroundColor = app.settings.backgroundColor; BackgroundPreview.style.backgroundColor = app.settings.backgroundColor;
@@ -77,7 +84,7 @@ window.onload = function(){
else app.settings.grid.cells.titleBackgroundColor = GridCellsTitleBackgroundColor.value; else app.settings.grid.cells.titleBackgroundColor = GridCellsTitleBackgroundColor.value;
if(GridCellsTitleBackgroundTransparentHover.checked == true) app.settings.grid.cells.titleBackgroundColorHover = null; if(GridCellsTitleBackgroundTransparentHover.checked == true) app.settings.grid.cells.titleBackgroundColorHover = null;
else app.settings.grid.cells.titleBackgroundColorHover = GridCellsTitleBackgroundColorHover.value; else app.settings.grid.cells.titleBackgroundColorHover = GridCellsTitleBackgroundColorHover.value;
app.saveSettings(); browser.runtime.sendMessage( { cmd: app.Messages.Commands.setSettings, settings: app.settings } );
} }
BtnCancel.onclick = function(){ BtnCancel.onclick = function(){
window.frameElement.popup.close(); window.frameElement.popup.close();
@@ -152,5 +159,28 @@ window.onload = function(){
} }
fileReader.readAsDataURL(GridFolderImageFile.files[0]); fileReader.readAsDataURL(GridFolderImageFile.files[0]);
} }
};
}
app.Messages = {};
app.Messages.Commands = {
getSettings: 0,
setSettings: 1,
getNode: 2,
getNodeByID: 3,
updateNode: 4,
setNodeIndex: 5,
createBookmark: 6,
createFolder: 7,
deleteNode: 8,
refreshNode: 9,
capturePage: 10,
settingsChanged: 100,
gridNodesLoaded: 101
};
app.Messages.getSettings = function(callback){
browser.runtime.sendMessage({ cmd: app.Messages.Commands.getSettings }).then(callback);
};

View File

@@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"name": "Quick Dial", "name": "Quick Dial",
"version": "0.0.4", "version": "0.1.4",
"author": "MatMoul", "author": "MatMoul",
"homepage_url": "https://github.com/MatMoul/quickdial-webext", "homepage_url": "https://github.com/MatMoul/quickdial-webext",
"developer": { "developer": {
@@ -28,6 +28,13 @@
"scripts": ["js/background.js"] "scripts": ["js/background.js"]
}, },
"browser_action": {
"default_icon": {
"24": "img/24.png",
"32": "img/32.png"
}
},
"chrome_url_overrides" : { "chrome_url_overrides" : {
"newtab": "dial" "newtab": "dial"
}, },