diff --git a/css/about.css b/css/about.css index e2ffdbe..bb8fc30 100755 --- a/css/about.css +++ b/css/about.css @@ -102,6 +102,7 @@ body { margin-top: 32px; border-bottom: 1px solid var(--color-border); padding: 4px; + padding-bottom: 8px; } .block-title img, .block-title label { @@ -117,7 +118,7 @@ body { position: absolute; left: 0; top: 33px; - width: 40%; + width: 37%; bottom: 0; border-right: 1px solid var(--color-border); } @@ -128,7 +129,7 @@ body { position: absolute; right: 0; top: 33px; - width: 60%; + width: 63%; bottom: 0; overflow-y: auto; } @@ -137,10 +138,20 @@ label { color: var(--color-top); } -.nav-btn, .link { +.nav-btn { width: calc(100% - 4px); } +.nav-label { + padding: 2px; + margin: 2px; + display: inline-block; +} + +.nav-label.mini { + font-size: 12px; +} + /* theme icon */ .theme-icon { opacity: 0; diff --git a/css/modules/checkbox.css b/css/modules/checkbox.css index cf02852..b4bf091 100755 --- a/css/modules/checkbox.css +++ b/css/modules/checkbox.css @@ -15,7 +15,7 @@ input[type=checkbox] { -webkit-appearance: none; appearance: none; outline: none; - border-radius: var(--px-radius); + border-radius: calc(var(--px-radius) + 4px); width: 40px; height: 24px; position: relative; @@ -41,7 +41,7 @@ input[type=checkbox]::after { height: 14px; content: ""; background-color: var(--color-border); - border-radius: calc(var(--px-radius) - 4px); + border-radius: var(--px-radius); transition: 0.25s; } diff --git a/css/modules/radio.css b/css/modules/radio.css index f1bf231..c6bd764 100755 --- a/css/modules/radio.css +++ b/css/modules/radio.css @@ -4,7 +4,7 @@ input[type=radio] { -webkit-appearance: none; appearance: none; outline: none; - border-radius: var(--px-radius); + border-radius: calc(var(--px-radius) + 4px); width: 24px; height: 24px; position: relative; @@ -30,7 +30,7 @@ input[type=radio]::after { height: 14px; content: ""; background-color: var(--color-border); - border-radius: calc(var(--px-radius) - 4px); + border-radius: var(--px-radius); transition: 0.25s; } diff --git a/css/overlay.css b/css/overlay.css index 1ca1950..31dd3ed 100755 --- a/css/overlay.css +++ b/css/overlay.css @@ -399,11 +399,11 @@ main { } .folder-editor { - margin-bottom: 4px; + margin-bottom: -1px; border: 1px solid var(--color-border); background-color: var(--color-back); padding: 2px; - border-radius: calc(var(--px-radius) + 4px); + border-radius: calc(var(--px-radius) + 4px) calc(var(--px-radius) + 4px) 0 0; text-align: center; } @@ -581,7 +581,7 @@ main { outline: none; position: relative; text-align: left; - height: 46px; + height: 62px; display: inline-block; vertical-align: top; color: var(--color-top); @@ -651,7 +651,20 @@ main { text-overflow: ellipsis; font-size: 10px; opacity: var(--opacity-over); - margin-bottom: 16px; + margin-bottom: 32px; +} + +.history-time { + position: absolute; + top: 42px; + right: 7px; + left: 7px; + overflow: hidden; + white-space: nowrap; + word-break: keep-all; + text-overflow: ellipsis; + font-size: 10px; + opacity: var(--opacity-over); } .history-title { diff --git a/html/about.html b/html/about.html index 3bd6282..c36b7c0 100755 --- a/html/about.html +++ b/html/about.html @@ -28,6 +28,16 @@
+
+ + +
+ +
@@ -38,8 +48,10 @@ + +
@@ -48,6 +60,9 @@ + + +
@@ -58,8 +73,9 @@ +
@@ -72,15 +88,17 @@ +
- - + +
diff --git a/html/browser.html b/html/browser.html index aff911b..30f6edd 100755 --- a/html/browser.html +++ b/html/browser.html @@ -14,7 +14,7 @@
- + diff --git a/imgs/icons16/swipe-both.png b/imgs/icons16/swipe-both.png new file mode 100644 index 0000000..06eda4e Binary files /dev/null and b/imgs/icons16/swipe-both.png differ diff --git a/js/about.js b/js/about.js index b68708e..89e0cf3 100755 --- a/js/about.js +++ b/js/about.js @@ -90,6 +90,10 @@ function openDiscordPage() { ipcRenderer.send("tabManager-addTab", "https://discord.gg/9q4D8SJ", true); } +function openLicensePage() { + ipcRenderer.send("tabManager-addTab", "https://github.com/ModuleArt/ferny/blob/master/LICENSE", true); +} + function checkForUpdates() { ipcRenderer.send("main-checkForUpdates"); } diff --git a/js/browser.js b/js/browser.js index 7ed6a4f..f398874 100755 --- a/js/browser.js +++ b/js/browser.js @@ -168,6 +168,10 @@ function bookmarkAllTabs() { // }); } +function popupTabHistory() { + ipcRenderer.send("tabManager-popupTabHistory"); +} + /* ###### # # # # #### #### # # ###### ##### # ## # # # # # ## # # # # # # # # # # # # # # # diff --git a/main.js b/main.js index d1a7cdd..3ac4807 100755 --- a/main.js +++ b/main.js @@ -194,6 +194,7 @@ app.on("ready", function() { }); loadDownloadCounter(); + loadDownloadsFolder(); showMainWindow(); // loadWelcome(); }); @@ -582,6 +583,12 @@ ipcMain.on("tabManager-zoomToActualSize", (event) => { } }); +ipcMain.on("tabManager-popupTabHistory", (event) => { + if(tabManager.hasActiveTab()) { + tabManager.getActiveTab().popupTabHistory(); + } +}); + /* ###### # # # # #### #### # # ###### ##### # ## # # # # # ## # # # # # # # # # # # # # # # @@ -686,6 +693,18 @@ function initTabManager() { # #### # # #### ##### #### # # # # ###### #### # # ##### #### */ +function loadDownloadsFolder() { + try { + fs.readFile(ppath + "/json/downloads/downloads-folder.json", (err, data) => { + if(!err) { + downloadsFolder = data.toString(); + } + }); + } catch (e) { + + } +} + function loadDownloadCounter() { try { fs.readFile(ppath + "/json/downloads/download-counter.json", (err, data) => { @@ -1063,7 +1082,7 @@ function initMenu() { tabManager.getActiveTab().closeToTheRight(); } } }, { - label: "Close others", accelerator: "CmdOrCtrl+Shift+W", click: () => { + label: "Close others", icon: app.getAppPath() + "/imgs/icons16/swipe-both.png", accelerator: "CmdOrCtrl+Shift+W", click: () => { if(tabManager.hasActiveTab()) { tabManager.getActiveTab().closeOthers(); } @@ -1202,7 +1221,7 @@ function initMenu() { enabled: false, label: "Clear browsing data", icon: app.getAppPath() + "/imgs/icons16/broom.png", accelerator: "CmdOrCtrl+Shift+Delete", click: () => { // overlay.openSettings('clear-browsing-data'); } }, { type: "separator" }, { - label: "Show overlay", icon: app.getAppPath() + "/imgs/icons16/details.png", accelerator: "F3", click: () => { + label: "Show overlay", icon: app.getAppPath() + "/imgs/icons16/details.png", accelerator: "F1", click: () => { overlay.show(); } }, { label: "Open search", icon: app.getAppPath() + "/imgs/icons16/zoom.png", accelerator: "F6", click: () => { diff --git a/modules/BookmarkManager/Bookmark.js b/modules/BookmarkManager/Bookmark.js index 0998c06..0dae900 100755 --- a/modules/BookmarkManager/Bookmark.js +++ b/modules/BookmarkManager/Bookmark.js @@ -25,12 +25,24 @@ class Bookmark extends EventEmitter { this.node.name = id; this.node.position = position; this.node.innerHTML = ` - `; - let color = new GetAvColor(this.node.getElementsByTagName("img")[0]); + + let bookmarkIcon = document.createElement("img"); + bookmarkIcon.classList.add("bookmark-icon"); + bookmarkIcon.src = "http://www.google.com/s2/favicons?domain=" + url; + bookmarkIcon.onerror = () => { + bookmarkIcon.src = __dirname + "/../../imgs/icons16/star.png"; + let color = new GetAvColor(bookmarkIcon); + color.mostUsed(result => { + this.node.style.backgroundColor = rgbToRgbaString(result[0]); + }); + }; + this.node.appendChild(bookmarkIcon); + + let color = new GetAvColor(bookmarkIcon); color.mostUsed(result => { this.node.style.backgroundColor = rgbToRgbaString(result[0]); }); diff --git a/modules/BookmarkManager/BookmarkManager.js b/modules/BookmarkManager/BookmarkManager.js index 2f3dd4d..baf6e85 100755 --- a/modules/BookmarkManager/BookmarkManager.js +++ b/modules/BookmarkManager/BookmarkManager.js @@ -56,7 +56,10 @@ class BookmarkManager extends EventEmitter { } addFolder(name) { - this.appendFolder(new Folder(this.folderCounter++, name, true)); + let folder = new Folder(this.folderCounter++, name, true); + this.appendFolder(folder); + folder.toggleEditor(); + this.updateFoldersPositions().then(() => { this.saveFolders(); }); @@ -178,7 +181,9 @@ class BookmarkManager extends EventEmitter { } addBookmarkToFolder(folder, bookmarkName, bookmarkURL) { - folder.appendBookmark(new Bookmark(this.bookmarkCounter++, bookmarkName, bookmarkURL)); + let bookmark = new Bookmark(this.bookmarkCounter++, bookmarkName, bookmarkURL); + folder.appendBookmark(bookmark); + bookmark.toggleEditor(); } moveBookmark(fromFolderId, toFolderId, bookmarkId) { diff --git a/modules/BookmarkManager/Folder.js b/modules/BookmarkManager/Folder.js index bbe824c..fa173ac 100755 --- a/modules/BookmarkManager/Folder.js +++ b/modules/BookmarkManager/Folder.js @@ -156,7 +156,7 @@ class Folder extends EventEmitter { getBookmarkById(id) { for(let i = 0; i < this.bookmarks.length; i++) { - if(id === this.bookmarks[i].getId()) { + if(id == this.bookmarks[i].getId()) { return this.bookmarks[i]; } } @@ -204,6 +204,8 @@ class Folder extends EventEmitter { toggleEditor() { let folderEditor = this.node.getElementsByClassName("folder-editor")[0]; if(folderEditor == null) { + this.node.getElementsByClassName("folder-header")[0].style.display = "none"; + folderEditor = document.createElement("div"); folderEditor.classList.add("folder-editor"); this.node.insertBefore(folderEditor, this.node.firstChild); @@ -240,6 +242,8 @@ class Folder extends EventEmitter { } folderEditor.appendChild(deleteBtn); } else { + this.node.getElementsByClassName("folder-header")[0].style.display = ""; + this.node.removeChild(folderEditor); } diff --git a/modules/HistoryManager/HistoryItem.js b/modules/HistoryManager/HistoryItem.js index 142cef1..9c45b39 100644 --- a/modules/HistoryManager/HistoryItem.js +++ b/modules/HistoryManager/HistoryItem.js @@ -7,6 +7,8 @@ const fileExtension = require("file-extension"); const extToImagePath = require(__dirname + "/../extToImagePath.js"); const rgbToRgbaString = require(__dirname + "/../rgbToRgbaString.js"); +const epochToDate = require(__dirname + "/../epochToDate.js"); +const epochToTime = require(__dirname + "/../epochToTime.js"); class HistoryItem extends EventEmitter { history = []; @@ -29,8 +31,9 @@ class HistoryItem extends EventEmitter { this.node.name = id; this.node.id = "history-" + id; this.node.innerHTML = ` - - + + + `; this.node.onclick = () => { this.open(); diff --git a/modules/Overlay/Overlay.js b/modules/Overlay/Overlay.js index 976ec3a..ecab89f 100755 --- a/modules/Overlay/Overlay.js +++ b/modules/Overlay/Overlay.js @@ -1,5 +1,5 @@ const EventEmitter = require("events"); -const { BrowserView, Menu } = require('electron'); +const { BrowserView, Menu, MenuItem, clipboard } = require('electron'); class Overlay extends EventEmitter { window = null; @@ -26,6 +26,7 @@ class Overlay extends EventEmitter { this.view.webContents.loadFile(this.appPath + "/html/overlay.html"); this.view.webContents.on("context-menu", (event, params) => { + console.log(params); if(params.isEditable) { let editMenu = Menu.buildFromTemplate([{ label: "Cut", icon: this.appPath + "/imgs/icons16/cut.png", accelerator: "CmdOrCtrl+X", enabled: params.editFlags.canCut, click: () => { @@ -50,6 +51,22 @@ class Overlay extends EventEmitter { this.view.webContents.delete(); } } ]); + + if(params.y < 200) { + let mi = new MenuItem({ + label: "Paste and search", + icon: appPath + "/imgs/icons16/zoom.png", + enabled: params.editFlags.canPaste, + click: () => { + this.performSearch(clipboard.readText()); } + }); + let sep = new MenuItem({ + type: "separator" + }); + editMenu.insert(4, mi); + editMenu.insert(5, sep); + } + editMenu.popup(this.window); } }); @@ -58,12 +75,12 @@ class Overlay extends EventEmitter { } refreshBounds() { - let size = this.window.getBounds(); + let size = this.window.getSize(); this.view.setBounds({ x: 0, y: this.top, - width: size.width, - height: size.height - this.top + width: size[0], + height: size[1] - this.top }); } diff --git a/modules/TabManager/Tab.js b/modules/TabManager/Tab.js index 9e55749..c9fb194 100755 --- a/modules/TabManager/Tab.js +++ b/modules/TabManager/Tab.js @@ -390,7 +390,7 @@ class Tab extends EventEmitter { label: "Close to the right", icon: this.appPath + "/imgs/icons16/swipe-right.png", click: () => { this.closeToTheRight(); } }, { - label: "Close others", accelerator: "CmdOrCtrl+Shift+W", click: () => { + label: "Close others", icon: this.appPath + "/imgs/icons16/swipe-both.png", accelerator: "CmdOrCtrl+Shift+W", click: () => { this.closeOthers(); } }, { label: "Close tab", icon: this.appPath + "/imgs/icons16/close.png", accelerator: "CmdOrCtrl+W", click: () => { @@ -517,6 +517,23 @@ class Tab extends EventEmitter { moveToEnd() { this.window.webContents.send("tabRenderer-moveTabToEnd", this.id); } + + popupTabHistory() { + let tabHistory = Menu.buildFromTemplate([]); + + this.view.webContents.history.forEach((value, index) => { + let historyItem = new MenuItem({ + label: value.split("/")[2].replace("www.", ""), + sublabel: value, + click: () => { + this.navigate(value); + }, + icon: this.appPath + "/imgs/icons16/link.png" + }); + tabHistory.append(historyItem); + }); + tabHistory.popup(this.window); + } } module.exports = Tab; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d119513..18ab595 100755 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ferny", - "version": "3.0.2", + "version": "3.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -32,9 +32,9 @@ "dev": true }, "@types/node": { - "version": "10.14.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.19.tgz", - "integrity": "sha512-j6Sqt38ssdMKutXBUuAcmWF8QtHW1Fwz/mz4Y+Wd9mzpBiVFirjpNQf363hG5itkG+yGaD+oiLyb50HxJ36l9Q==", + "version": "10.14.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.21.tgz", + "integrity": "sha512-nuFlRdBiqbF+PJIEVxm2jLFcQWN7q7iWEJGsBV4n7v1dbI9qXB8im2pMMKMCUZe092sQb5SQft2DHfuQGK5hqQ==", "dev": true }, "JSONStream": { @@ -1749,9 +1749,9 @@ "dev": true }, "electron": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/electron/-/electron-6.0.11.tgz", - "integrity": "sha512-mi1oHmeFIQrg+CDQ6lbugZAloOxuWPm/ecEKYe1230PGlDoWND7SYStiWQ2eI4YXAEOL/NvuY88ogemu1qhdBg==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/electron/-/electron-6.0.12.tgz", + "integrity": "sha512-70ODZa1RP6K0gE9IV9YLCXPSyhLjXksCuYSSPb3MljbfwfHo5uE6X0CGxzm+54YuPdE2e7EPnWZxOOsJYrS5iQ==", "dev": true, "requires": { "@types/node": "^10.12.18", diff --git a/package.json b/package.json index 7a705d5..37090c3 100755 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "validate.io-uri": "^1.0.0" }, "devDependencies": { - "electron": "^6.0.11", + "electron": "^6.0.12", "electron-builder": "^20.44.4" }, "build": { diff --git a/themes/10-twitchy-dark.json b/themes/10-twitchy-dark.json new file mode 100755 index 0000000..da542ba --- /dev/null +++ b/themes/10-twitchy-dark.json @@ -0,0 +1,13 @@ +{ + "name": "Twitchy", + "type": "Dark", + "icons": "white", + "colorBack": "#161121", + "colorElement": "#2F194F", + "colorBorder": "#1D132E", + "colorSecond": "#351A5C", + "colorTop": "#FFFFFF", + "shadowFocus": "inset 0 0 4px rgba(190, 147, 254, 0.5)", + "opacityOver": "0.5", + "pxRadius": "16px" +} diff --git a/themes/11-contrast-light.json b/themes/11-contrast-light.json new file mode 100755 index 0000000..c45b78e --- /dev/null +++ b/themes/11-contrast-light.json @@ -0,0 +1,13 @@ +{ + "name": "Contrast", + "type": "Light", + "icons": "black", + "colorBack": "#FFFFFF", + "colorElement": "#FFFFFF", + "colorBorder": "#888888", + "colorSecond": "#AAAAAA", + "colorTop": "#000000", + "shadowFocus": "inset 0 0 4px rgba(0, 0, 0, 0.5)", + "opacityOver": "0.5", + "pxRadius": "4px" +}