mirror of
https://github.com/torappinfo/uweb.git
synced 2024-08-14 23:54:59 +00:00
ebrowser 1.0.33
This commit is contained in:
parent
536ff07ffa
commit
1577313e59
9 changed files with 98 additions and 184 deletions
116
ebrowser.md
116
ebrowser.md
|
@ -1,116 +0,0 @@
|
||||||
### [Ebrowser](https://github.com/torappinfo/ebrowser): keyboard-friendly minimal suckless web browser
|
|
||||||
Ebrowser is designed with the philosophy of [Android uweb browser](https://github.com/torappinfo/uweb) ([gitlab](https://gitlab.com/jamesfengcao/uweb)).
|
|
||||||
|
|
||||||
- lightweight (less than 20k bytes) without bundled electron.
|
|
||||||
- much less memory footprint than edge/chrome browser and highly performant.
|
|
||||||
- keyboard friendly with vim-style keymaps and command line support in address bar.
|
|
||||||
- [global redirection](https://uweb.surge.sh/en/redirect/index.html#) to bypass censorship.
|
|
||||||
- user scripts at will. Ex. pressing "tr" to translate the page (need mapkeys.json config).
|
|
||||||
- customizable.
|
|
||||||
|
|
||||||
Note: Usually electron apps are heavyweight as they use browsers for simple things. Ebrowser uses core chromium effectively and very lightweight. Recommend to install electron separately.
|
|
||||||
|
|
||||||
#### Installing (for Windows, MacOS and Linux)
|
|
||||||
##### Install with prebuilt binaries
|
|
||||||
You can find prebuilt binaries [here](https://github.com/torappinfo/ebrowser/releases).
|
|
||||||
|
|
||||||
##### Install with nodejs
|
|
||||||
|
|
||||||
npm install electron
|
|
||||||
npm install ebrowser
|
|
||||||
|
|
||||||
Run ebrowser
|
|
||||||
|
|
||||||
electron ~/node_modules/ebrowser
|
|
||||||
|
|
||||||
Later on, you can run "npm install electron" to update electron/chromium or "npm install ebrowser" to update ebrowser independently.
|
|
||||||
|
|
||||||
##### Update app quickly without updating chromium
|
|
||||||
Pressing "Alt" to show the menu bar and choose "Check for updates" under "Help". OR
|
|
||||||
|
|
||||||
Type ":update" in the address bar and press "enter" key to update.
|
|
||||||
|
|
||||||
Mirror urls could be used like ":update https://uwebzh.netlify.app/misc/ebrowser". All the mirrors listed on [uweb browser](https://uwebzh.netlify.app/en/readme/index.html) could be used. The update url needs to be changed accordingly to be the folder "misc/ebrowser" under the mirror site root url.
|
|
||||||
|
|
||||||
#### Key shortcuts
|
|
||||||
- CTRL+C: stop loading
|
|
||||||
- CTRL+G: address bar to show page url
|
|
||||||
- CTRL+L: focus to address bar
|
|
||||||
- CTRL+T: new Tab
|
|
||||||
- CTRL+SHIFT+T: restore closed Tab
|
|
||||||
- CTRL+TAB: switch to next tab
|
|
||||||
- CTRL+SHIFT+TAB: switch to previous tab
|
|
||||||
- CTRL+W: close Tab
|
|
||||||
- ALT+<-: go backward
|
|
||||||
- ALT+->: go forward
|
|
||||||
- CTRL+SHIFT+R: enable global redirection ("gredirect.json")
|
|
||||||
- CTRL+R: disable global redirection
|
|
||||||
- ESC: remove focus. similar to vi normal mode.
|
|
||||||
- F1: Help
|
|
||||||
- F5: page refresh/reload
|
|
||||||
- F12: devtools
|
|
||||||
|
|
||||||
#### Address bar commands
|
|
||||||
- "/" for find-in-page
|
|
||||||
- ":" for address bar commands
|
|
||||||
- ac [bookmark/history path w/o ext] : load ".rec" file for autocomplete.
|
|
||||||
- b [bookmarkfilename w/o ext] : bookmark current page in file.
|
|
||||||
- bml [filename w/o extension]: load/execute the javascript file.
|
|
||||||
- cert : allow invalid certificates w/o arguments, otherwise restore to default.
|
|
||||||
- clear : the arguments could be
|
|
||||||
- cache : clear cache
|
|
||||||
- dns : clear dns cache
|
|
||||||
- storage: clear site storage data.
|
|
||||||
- {[options](https://www.electronjs.org/docs/latest/api/session#sescleardataoptions)}
|
|
||||||
- ext [extension path]: load unpacked Chrome extension.
|
|
||||||
- gr [gredirect index]: global redirection with corresponding index. Use the first global redirection url if no argument. Disable global redirection with any index out of the range.
|
|
||||||
- js [js code] : execute JS code at OS level. Note: "javascript:..." is special url and thus works in the current web page, while ":js ..." commands can do any OS operations.
|
|
||||||
- nc/uc : No Cookie forwarding/Use Cookie forwarding with global redirection.
|
|
||||||
- nh/uh for No/Use url history.
|
|
||||||
- nj/uj for No/Use external Javascript files.
|
|
||||||
- nr/ur for No/Use "redirect.json" for domain redirection.
|
|
||||||
- np : no proxy.
|
|
||||||
- up [proxyName] : use proxy. privous proxy or the first proxy in proxy.json w/o [proxyName]. ":up" command also disables global and domain redirections, which are not restored by ":np".
|
|
||||||
- ua [useragentName] : set user agent for future tabs. default user agent w/o arguments.
|
|
||||||
- update [updateurl] : update the app. updateurl is optional.
|
|
||||||
- pdf [filename w/o extension] {[options](https://www.electronjs.org/docs/latest/api/web-contents#contentsprinttopdfoptions)} : print to PDF file. All arguments are optional; empty option "{}" to capture long screenshot as vector graphics.
|
|
||||||
- "!" address bar commands
|
|
||||||
"!xx ..." evaluates "xx.js" with the whole text as arguments[0].
|
|
||||||
|
|
||||||
#### Commands in no-focus mode (this mode is similar to vi Normal mode)
|
|
||||||
Pressing "ESC" to enter no-focus mode if not sure.
|
|
||||||
- ":" for address bar commands
|
|
||||||
- "/" for find-in-page with address bar
|
|
||||||
- "!" for "!" address bar commands
|
|
||||||
|
|
||||||
The other commands are defined in "mapkeys.json", which will map keys to address bar commands.
|
|
||||||
|
|
||||||
#### Configuration files
|
|
||||||
- "config": lines of address bar commands.
|
|
||||||
- "search.json": search engines as shortcut-queryUrl pairs.
|
|
||||||
- "default.autoc": predefined strings for address bar auto completion.
|
|
||||||
- "gredirect.json": global redirection urls as array of urls
|
|
||||||
- "redirect.json": domain-replacementDomain pairs, default to be applied.
|
|
||||||
- "mapkeys.json": keys-addressbarCommands pairs. The addressbar commands are multiple lines of address bar command separated by "\n".
|
|
||||||
- "proxy.json": name-[ProxyConfig](https://www.electronjs.org/docs/latest/api/structures/proxy-config) pairs
|
|
||||||
- "uas.json" : name-useragent pairs
|
|
||||||
|
|
||||||
#### Javascript at three levels
|
|
||||||
- Web page: urls like "javascript:" or bookmarklet command ":bml" run in web page.
|
|
||||||
- Browser (or renderer process) : "!xx" evaluates "xx.js", which could manipulate address bar etc.
|
|
||||||
- OS level (or main process) : ":js" to execute the following js code with all OS APIs available.
|
|
||||||
|
|
||||||
#### New usages
|
|
||||||
- Vector designing with web tech to replace Adobe Illustrator/Inkscape.
|
|
||||||
- Design with web tech.
|
|
||||||
|
|
||||||
- Printing to pdf with customized paper size.
|
|
||||||
- Magnify the pdf paper size to the required size.
|
|
||||||
|
|
||||||
OR
|
|
||||||
|
|
||||||
- Adjust window width and use addressbar command line ":Pdf {}" to export vector graphics.
|
|
||||||
- Use imageMagick to convert to any other vector graphics format.
|
|
||||||
|
|
||||||
#### License
|
|
||||||
You can copy or modify the code/program under the terms of the GPL3.0 or later versions.
|
|
|
@ -95,6 +95,7 @@ npm install ebrowser
|
||||||
<ul>
|
<ul>
|
||||||
<li>ac [bookmark/history path w/o ext] : load ".rec" file for autocomplete.</li>
|
<li>ac [bookmark/history path w/o ext] : load ".rec" file for autocomplete.</li>
|
||||||
<li>b [bookmarkfilename w/o ext] : bookmark current page in file.</li>
|
<li>b [bookmarkfilename w/o ext] : bookmark current page in file.</li>
|
||||||
|
<li>bjs : Browser-level JavaScript execution.</li>
|
||||||
<li>bml [filename w/o extension]: load/execute the javascript file.</li>
|
<li>bml [filename w/o extension]: load/execute the javascript file.</li>
|
||||||
<li>cert : allow invalid certificates w/o arguments, otherwise restore to default.</li>
|
<li>cert : allow invalid certificates w/o arguments, otherwise restore to default.</li>
|
||||||
<li>clear : the arguments could be
|
<li>clear : the arguments could be
|
||||||
|
@ -109,8 +110,6 @@ npm install ebrowser
|
||||||
<li>gr [gredirect index]: global redirection with corresponding index. Use the first global redirection url if no argument. Disable global redirection with any index out of the range.</li>
|
<li>gr [gredirect index]: global redirection with corresponding index. Use the first global redirection url if no argument. Disable global redirection with any index out of the range.</li>
|
||||||
<li>js [js code] : execute JS code at OS level. Note: "javascript:..." is special url and thus works in the current web page, while ":js ..." commands can do any OS operations.</li>
|
<li>js [js code] : execute JS code at OS level. Note: "javascript:..." is special url and thus works in the current web page, while ":js ..." commands can do any OS operations.</li>
|
||||||
<li>nc/uc : No Cookie forwarding/Use Cookie forwarding with global redirection.</li>
|
<li>nc/uc : No Cookie forwarding/Use Cookie forwarding with global redirection.</li>
|
||||||
<li>nh/uh for No/Use url history.</li>
|
|
||||||
<li>nj/uj for No/Use external Javascript files.</li>
|
|
||||||
<li>nr/ur for No/Use "redirect.json" for domain redirection.</li>
|
<li>nr/ur for No/Use "redirect.json" for domain redirection.</li>
|
||||||
<li>np : no proxy.</li>
|
<li>np : no proxy.</li>
|
||||||
<li>up [proxyName] : use proxy. privous proxy or the first proxy in proxy.json w/o [proxyName]. ":up" command also disables global and domain redirections, which are not restored by ":np".</li>
|
<li>up [proxyName] : use proxy. privous proxy or the first proxy in proxy.json w/o [proxyName]. ":up" command also disables global and domain redirections, which are not restored by ":np".</li>
|
||||||
|
@ -144,9 +143,20 @@ npm install ebrowser
|
||||||
<h4 id="javascript-at-three-levels">Javascript at three levels</h4>
|
<h4 id="javascript-at-three-levels">Javascript at three levels</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Web page: urls like "javascript:" or bookmarklet command ":bml" run in web page.</li>
|
<li>Web page: urls like "javascript:" or bookmarklet command ":bml" run in web page.</li>
|
||||||
<li>Browser (or renderer process) : "!xx" evaluates "xx.js", which could manipulate address bar etc.</li>
|
<li>Browser (or renderer process) :
|
||||||
|
<ul>
|
||||||
|
<li>":bjs" to execute the following js code at browser level.</li>
|
||||||
|
<li>"!xx" evaluates "xx.js", which could manipulate address bar etc.</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li>OS level (or main process) : ":js" to execute the following js code with all OS APIs available.</li>
|
<li>OS level (or main process) : ":js" to execute the following js code with all OS APIs available.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<h5 id="examples-for-jsbjs-commands">examples for ":js"/":bjs" commands</h5>
|
||||||
|
<pre><code>:js bJS=true //allow external Javascript files for web pages
|
||||||
|
:js bJS=false //disallow external Javascript files for web pages
|
||||||
|
:bjs bHistory=true //to record url history
|
||||||
|
:bjs bQueryHistory=true //to record query/command history
|
||||||
|
</code></pre>
|
||||||
<h4 id="new-usages">New usages</h4>
|
<h4 id="new-usages">New usages</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<description>Recent content on uweb browser: unlimited power</description>
|
<description>Recent content on uweb browser: unlimited power</description>
|
||||||
<generator>Hugo</generator>
|
<generator>Hugo</generator>
|
||||||
<language>en</language>
|
<language>en</language>
|
||||||
<lastBuildDate>Mon, 24 Jun 2024 10:28:02 +0800</lastBuildDate>
|
<lastBuildDate>Mon, 24 Jun 2024 19:36:44 +0800</lastBuildDate>
|
||||||
<atom:link href="/en/index.xml" rel="self" type="application/rss+xml" />
|
<atom:link href="/en/index.xml" rel="self" type="application/rss+xml" />
|
||||||
<item>
|
<item>
|
||||||
<title>Text selection/processing</title>
|
<title>Text selection/processing</title>
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
/>
|
/>
|
||||||
</url><url>
|
</url><url>
|
||||||
<loc>/en/</loc>
|
<loc>/en/</loc>
|
||||||
<lastmod>2024-06-24T10:28:02+08:00</lastmod>
|
<lastmod>2024-06-24T19:36:44+08:00</lastmod>
|
||||||
<xhtml:link
|
<xhtml:link
|
||||||
rel="alternate"
|
rel="alternate"
|
||||||
hreflang="zh"
|
hreflang="zh"
|
||||||
|
@ -508,7 +508,7 @@
|
||||||
/>
|
/>
|
||||||
</url><url>
|
</url><url>
|
||||||
<loc>/en/ebrowserreadme/</loc>
|
<loc>/en/ebrowserreadme/</loc>
|
||||||
<lastmod>2024-06-24T09:46:43+08:00</lastmod>
|
<lastmod>2024-06-24T19:36:44+08:00</lastmod>
|
||||||
</url><url>
|
</url><url>
|
||||||
<loc>/en/mirrors/</loc>
|
<loc>/en/mirrors/</loc>
|
||||||
<lastmod>2024-06-18T23:17:17+08:00</lastmod>
|
<lastmod>2024-06-18T23:17:17+08:00</lastmod>
|
||||||
|
@ -539,7 +539,7 @@
|
||||||
/>
|
/>
|
||||||
</url><url>
|
</url><url>
|
||||||
<loc>/en/unlist/</loc>
|
<loc>/en/unlist/</loc>
|
||||||
<lastmod>2024-06-24T10:28:02+08:00</lastmod>
|
<lastmod>2024-06-24T19:36:44+08:00</lastmod>
|
||||||
<xhtml:link
|
<xhtml:link
|
||||||
rel="alternate"
|
rel="alternate"
|
||||||
hreflang="zh"
|
hreflang="zh"
|
||||||
|
|
|
@ -55,6 +55,7 @@ Mirror urls could be used like ":update https://uwebzh.netlify.app/misc/ebrowser
|
||||||
- ":" for address bar commands
|
- ":" for address bar commands
|
||||||
- ac [bookmark/history path w/o ext] : load ".rec" file for autocomplete.
|
- ac [bookmark/history path w/o ext] : load ".rec" file for autocomplete.
|
||||||
- b [bookmarkfilename w/o ext] : bookmark current page in file.
|
- b [bookmarkfilename w/o ext] : bookmark current page in file.
|
||||||
|
- bjs : Browser-level JavaScript execution.
|
||||||
- bml [filename w/o extension]: load/execute the javascript file.
|
- bml [filename w/o extension]: load/execute the javascript file.
|
||||||
- cert : allow invalid certificates w/o arguments, otherwise restore to default.
|
- cert : allow invalid certificates w/o arguments, otherwise restore to default.
|
||||||
- clear : the arguments could be
|
- clear : the arguments could be
|
||||||
|
@ -66,8 +67,6 @@ Mirror urls could be used like ":update https://uwebzh.netlify.app/misc/ebrowser
|
||||||
- gr [gredirect index]: global redirection with corresponding index. Use the first global redirection url if no argument. Disable global redirection with any index out of the range.
|
- gr [gredirect index]: global redirection with corresponding index. Use the first global redirection url if no argument. Disable global redirection with any index out of the range.
|
||||||
- js [js code] : execute JS code at OS level. Note: "javascript:..." is special url and thus works in the current web page, while ":js ..." commands can do any OS operations.
|
- js [js code] : execute JS code at OS level. Note: "javascript:..." is special url and thus works in the current web page, while ":js ..." commands can do any OS operations.
|
||||||
- nc/uc : No Cookie forwarding/Use Cookie forwarding with global redirection.
|
- nc/uc : No Cookie forwarding/Use Cookie forwarding with global redirection.
|
||||||
- nh/uh for No/Use url history.
|
|
||||||
- nj/uj for No/Use external Javascript files.
|
|
||||||
- nr/ur for No/Use "redirect.json" for domain redirection.
|
- nr/ur for No/Use "redirect.json" for domain redirection.
|
||||||
- np : no proxy.
|
- np : no proxy.
|
||||||
- up [proxyName] : use proxy. privous proxy or the first proxy in proxy.json w/o [proxyName]. ":up" command also disables global and domain redirections, which are not restored by ":np".
|
- up [proxyName] : use proxy. privous proxy or the first proxy in proxy.json w/o [proxyName]. ":up" command also disables global and domain redirections, which are not restored by ":np".
|
||||||
|
@ -97,9 +96,18 @@ The other commands are defined in "mapkeys.json", which will map keys to address
|
||||||
|
|
||||||
#### Javascript at three levels
|
#### Javascript at three levels
|
||||||
- Web page: urls like "javascript:" or bookmarklet command ":bml" run in web page.
|
- Web page: urls like "javascript:" or bookmarklet command ":bml" run in web page.
|
||||||
- Browser (or renderer process) : "!xx" evaluates "xx.js", which could manipulate address bar etc.
|
- Browser (or renderer process) :
|
||||||
|
- ":bjs" to execute the following js code at browser level.
|
||||||
|
- "!xx" evaluates "xx.js", which could manipulate address bar etc.
|
||||||
- OS level (or main process) : ":js" to execute the following js code with all OS APIs available.
|
- OS level (or main process) : ":js" to execute the following js code with all OS APIs available.
|
||||||
|
|
||||||
|
##### examples for ":js"/":bjs" commands
|
||||||
|
|
||||||
|
:js bJS=true //allow external Javascript files for web pages
|
||||||
|
:js bJS=false //disallow external Javascript files for web pages
|
||||||
|
:bjs bHistory=true //to record url history
|
||||||
|
:bjs bQueryHistory=true //to record query/command history
|
||||||
|
|
||||||
#### New usages
|
#### New usages
|
||||||
- Vector designing with web tech to replace Adobe Illustrator/Inkscape.
|
- Vector designing with web tech to replace Adobe Illustrator/Inkscape.
|
||||||
- Design with web tech.
|
- Design with web tech.
|
||||||
|
|
|
@ -49,6 +49,7 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
}
|
}
|
||||||
.autocomplete-items div {
|
.autocomplete-items div {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
.autocomplete-items div:hover {
|
.autocomplete-items div:hover {
|
||||||
background-color: #e9e9e9;
|
background-color: #e9e9e9;
|
||||||
|
@ -65,8 +66,13 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
var closedUrls = [];
|
var closedUrls = [];
|
||||||
var autocStrArray = [];
|
var autocStrArray = [];
|
||||||
var defaultSE = "https://www.bing.com/search?q=%s";
|
var defaultSE = "https://www.bing.com/search?q=%s";
|
||||||
|
var historyFile = path.join(__dirname,'history.rec');
|
||||||
|
var bHistory = false;
|
||||||
var bQueryHistory = false;
|
var bQueryHistory = false;
|
||||||
var autocMode = 0; //0 for substring, 1 for startsWith
|
var autocMode = 0; //0 for substring, 1 for startsWith
|
||||||
|
const JSPREFIX_LOAD = "(async ()=>{let d=document;async function _loadJs(u){var a=d.createElement('script');a.type='text/javascript';a.async=false;a.src=u;d.body.appendChild(a);await new Promise(resolve=>a.onload=resolve)}";
|
||||||
|
const BML_md = JSPREFIX_LOAD + "await _loadJs('https://cdn.jsdelivr.net/npm/marked@12.0.2/marked.min.js');let b=d.body;b.innerHTML=marked.parse(b.textContent)})()";
|
||||||
|
|
||||||
let lastKeys;
|
let lastKeys;
|
||||||
let lastKeys_millis = 0;
|
let lastKeys_millis = 0;
|
||||||
|
|
||||||
|
@ -78,7 +84,10 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
initSearchEngines(jsonString,false);
|
initSearchEngines(jsonString,false);
|
||||||
});
|
});
|
||||||
fs.readFile(path.join(__dirname,'mapkeys.json'), 'utf8', (err, jsonStr) => {
|
fs.readFile(path.join(__dirname,'mapkeys.json'), 'utf8', (err, jsonStr) => {
|
||||||
if (err) return;
|
if (err) {
|
||||||
|
coloncommand(":js fetch2file(repositoryurl,'mapkeys.json')");
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
mapKeys = JSON.parse(jsonStr);
|
mapKeys = JSON.parse(jsonStr);
|
||||||
}catch(e){}
|
}catch(e){}
|
||||||
|
@ -126,9 +135,24 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
iTab = i;
|
iTab = i;
|
||||||
tabs.children[iTab].classList.add('curWV');
|
tabs.children[iTab].classList.add('curWV');
|
||||||
}
|
}
|
||||||
|
function cbFinishLoad(e){
|
||||||
|
let tab = e.target;
|
||||||
|
let js = tab.dataset.jsonce;
|
||||||
|
if(js){
|
||||||
|
tab.dataset.jsonce = null;
|
||||||
|
tab.executeJavaScript(js,false);
|
||||||
|
}
|
||||||
|
if(!bHistory) return;
|
||||||
|
let histItem = tab.getTitle()+" "+tab.getURL()+"\n";
|
||||||
|
fs.appendFile(historyFile, histItem, (err) => {});
|
||||||
|
}
|
||||||
|
function initTab(tab){
|
||||||
|
tab.allowpopups = true;
|
||||||
|
tab.addEventListener('did-finish-load',cbFinishLoad);
|
||||||
|
}
|
||||||
function newTab(){
|
function newTab(){
|
||||||
var tab = document.createElement('webview');
|
var tab = document.createElement('webview');
|
||||||
tab.allowpopups = true;
|
initTab(tab);
|
||||||
tabs.appendChild(tab);
|
tabs.appendChild(tab);
|
||||||
}
|
}
|
||||||
function tabInc(num){
|
function tabInc(num){
|
||||||
|
@ -195,24 +219,36 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SCROLL: do {
|
||||||
|
let h = -32;
|
||||||
switch(key){
|
switch(key){
|
||||||
case "PageDown":
|
case " ":
|
||||||
tabs.children[iTab].src =
|
if(inputE === document.activeElement) return;
|
||||||
"javascript:window.scrollBy(0,3*document.documentElement.clientHeight/4)";
|
if(e.shiftKey){
|
||||||
return;
|
h = -3*document.documentElement.clientHeight/4;
|
||||||
case "PageUp":
|
break;
|
||||||
tabs.children[iTab].src = "javascript:window.scrollBy(0,-3*document.documentElement.clientHeight/4)";
|
|
||||||
return;
|
|
||||||
case "ArrowDown":
|
|
||||||
if(inputE !== document.activeElement || 0==inputE.nextElementSibling.children.length)
|
|
||||||
tabs.children[iTab].src="javascript:window.scrollBy(0,32)";
|
|
||||||
return;
|
|
||||||
case "ArrowUp":
|
|
||||||
if(inputE !== document.activeElement || 0==inputE.nextElementSibling.children.length)
|
|
||||||
tabs.children[iTab].src="javascript:window.scrollBy(0,-32)";
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
case "PageDown":
|
||||||
|
h = 3*document.documentElement.clientHeight/4;
|
||||||
|
break;
|
||||||
|
case "PageUp":
|
||||||
|
h = -3*document.documentElement.clientHeight/4;
|
||||||
|
break;
|
||||||
|
case "ArrowDown":
|
||||||
|
h = 32;
|
||||||
|
case "ArrowUp":
|
||||||
|
if(inputE === document.activeElement &&
|
||||||
|
0!==inputE.nextElementSibling.children.length)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break SCROLL;
|
||||||
|
}
|
||||||
|
let js = `javascript:window.scrollBy(0,${h})`;
|
||||||
|
tabs.children[iTab].src = js;
|
||||||
|
return;
|
||||||
|
}while(false);
|
||||||
|
|
||||||
if(inputE === document.activeElement){
|
if(inputE === document.activeElement){
|
||||||
if (9===e.keyCode){//tab completion
|
if (9===e.keyCode){//tab completion
|
||||||
}
|
}
|
||||||
|
@ -269,6 +305,9 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
case "b":
|
case "b":
|
||||||
bookmark(args);
|
bookmark(args);
|
||||||
return;
|
return;
|
||||||
|
case "bjs":
|
||||||
|
eval(cmd.slice(5));
|
||||||
|
return;
|
||||||
case "bml":
|
case "bml":
|
||||||
bml(args);
|
bml(args);
|
||||||
return;
|
return;
|
||||||
|
@ -375,15 +414,16 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var url=q;
|
var url=q;
|
||||||
|
NOREC: do{
|
||||||
do {
|
do {
|
||||||
if(q.length>12){
|
if(q.length>12){
|
||||||
let c6 = q.charCodeAt(6);
|
let c6 = q.charCodeAt(6);
|
||||||
if(47===c6){// '/'
|
if(47===c6){// '/'
|
||||||
let c5 = q.charCodeAt(5);
|
let c5 = q.charCodeAt(5);
|
||||||
if(47===c5 && 58===q.charCodeAt(4))//http/file urls
|
if(47===c5 && 58===q.charCodeAt(4))//http/file urls
|
||||||
break;
|
break NOREC;
|
||||||
if(58===c5 && 47===q.charCodeAt(7))//https://
|
if(58===c5 && 47===q.charCodeAt(7))//https://
|
||||||
break;
|
break NOREC;
|
||||||
}else if(q.startsWith("javascript:")){
|
}else if(q.startsWith("javascript:")){
|
||||||
tabs.children[iTab].executeJavaScript(q.substring(11),false);
|
tabs.children[iTab].executeJavaScript(q.substring(11),false);
|
||||||
recQueryHistory(q);
|
recQueryHistory(q);
|
||||||
|
@ -398,13 +438,13 @@ You should have received a copy of the GNU General Public License along with thi
|
||||||
}
|
}
|
||||||
if(q.indexOf('.')>0){
|
if(q.indexOf('.')>0){
|
||||||
url = 'https://'+q;
|
url = 'https://'+q;
|
||||||
break;
|
break NOREC;
|
||||||
}
|
}
|
||||||
url = defaultSE.replace('%s',q);
|
url = defaultSE.replace('%s',q);
|
||||||
recQueryHistory(q);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
url = bang(q, iS);
|
url = bang(q, iS);
|
||||||
|
}while(false);
|
||||||
recQueryHistory(q);
|
recQueryHistory(q);
|
||||||
}while(false);
|
}while(false);
|
||||||
tabs.children[iTab].src=url;
|
tabs.children[iTab].src=url;
|
||||||
|
@ -501,6 +541,7 @@ function autocomplete(inp,container,arr) {
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
tabs = document.body.children[1];
|
tabs = document.body.children[1];
|
||||||
|
initTab(tabs.children[0]);
|
||||||
{
|
{
|
||||||
let inp = document.forms[0].q;
|
let inp = document.forms[0].q;
|
||||||
autocomplete(inp,inp.nextElementSibling,autocStrArray);
|
autocomplete(inp,inp.nextElementSibling,autocStrArray);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{"version":"1.0.31",
|
{"version":"1.0.33",
|
||||||
"name": "ebrowser",
|
"name": "ebrowser",
|
||||||
"description": "The keyboard-friendly minimal suckless web browser",
|
"description": "The keyboard-friendly minimal suckless web browser",
|
||||||
"main": "webview.js",
|
"main": "webview.js",
|
||||||
|
@ -6,7 +6,8 @@
|
||||||
"webview.js",
|
"webview.js",
|
||||||
"index.html",
|
"index.html",
|
||||||
"package.json",
|
"package.json",
|
||||||
"README.md"
|
"README.md",
|
||||||
|
"mapkeys.json"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"release": "electron-builder"
|
"release": "electron-builder"
|
||||||
|
|
|
@ -39,7 +39,6 @@ var gredirect;
|
||||||
var redirects;
|
var redirects;
|
||||||
var bRedirect = true;
|
var bRedirect = true;
|
||||||
var bJS = true;
|
var bJS = true;
|
||||||
var bHistory = false;
|
|
||||||
var bForwardCookie = false;
|
var bForwardCookie = false;
|
||||||
var proxies = {};
|
var proxies = {};
|
||||||
var proxy;
|
var proxy;
|
||||||
|
@ -48,7 +47,6 @@ var defaultUA =
|
||||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" +
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" +
|
||||||
process.versions.chrome +" Safari/537.36";
|
process.versions.chrome +" Safari/537.36";
|
||||||
app.userAgentFallback = defaultUA;
|
app.userAgentFallback = defaultUA;
|
||||||
var historyFile = path.join(__dirname,'history.rec');
|
|
||||||
|
|
||||||
fs.readFile(path.join(__dirname,'redirect.json'), 'utf8', (err, jsonString) => {
|
fs.readFile(path.join(__dirname,'redirect.json'), 'utf8', (err, jsonString) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
|
@ -139,7 +137,7 @@ app.on ('web-contents-created', (event, contents) => {
|
||||||
//contents.on('focus', ()=>{cbFocus(contents)});
|
//contents.on('focus', ()=>{cbFocus(contents)});
|
||||||
//contents.on('blur',()=>{cbBlur()});
|
//contents.on('blur',()=>{cbBlur()});
|
||||||
contents.session.webRequest.onBeforeRequest(interceptRequest);
|
contents.session.webRequest.onBeforeRequest(interceptRequest);
|
||||||
contents.on('did-finish-load',()=>{cbFinishLoad(contents)});
|
//contents.on('did-finish-load',()=>{cbFinishLoad(contents)});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -194,7 +192,7 @@ function addrCommand(cmd){
|
||||||
else
|
else
|
||||||
gredirect_disable();
|
gredirect_disable();
|
||||||
return;
|
return;
|
||||||
case "js"://exetute js
|
case "js"://execute js
|
||||||
eval(cmd.slice(4));
|
eval(cmd.slice(4));
|
||||||
return;
|
return;
|
||||||
case "nc":
|
case "nc":
|
||||||
|
@ -208,18 +206,6 @@ function addrCommand(cmd){
|
||||||
}
|
}
|
||||||
forwardCookie();
|
forwardCookie();
|
||||||
return;
|
return;
|
||||||
case "nh":
|
|
||||||
bHistory = false;
|
|
||||||
win.webContents.executeJavaScript("bQueryHistory=false",false);
|
|
||||||
return;
|
|
||||||
case "uh":
|
|
||||||
bHistory = true;
|
|
||||||
win.webContents.executeJavaScript("bQueryHistory=true",false);
|
|
||||||
return;
|
|
||||||
case "nj":
|
|
||||||
bJS = false; return;
|
|
||||||
case "uj":
|
|
||||||
bJS = true; return;
|
|
||||||
case "np":
|
case "np":
|
||||||
session.defaultSession.setProxy ({mode:"direct"});
|
session.defaultSession.setProxy ({mode:"direct"});
|
||||||
bRedirect = true;
|
bRedirect = true;
|
||||||
|
@ -275,12 +261,6 @@ function cbConsoleMsg(e, level, msg, line, sourceid){
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cbFinishLoad(webContents){
|
|
||||||
if(!bHistory) return;
|
|
||||||
let histItem = webContents.getTitle()+" "+webContents.getURL()+"\n";
|
|
||||||
fs.appendFile(historyFile, histItem, (err) => {});
|
|
||||||
}
|
|
||||||
|
|
||||||
function cbFocus(webContents){
|
function cbFocus(webContents){
|
||||||
let js = "if(focusMesg){let m=focusMesg;focusMesg=null;m}";
|
let js = "if(focusMesg){let m=focusMesg;focusMesg=null;m}";
|
||||||
win.webContents.executeJavaScript(js,false).then((r)=>{
|
win.webContents.executeJavaScript(js,false).then((r)=>{
|
||||||
|
@ -393,7 +373,7 @@ function topMenu(){
|
||||||
win.webContents.executeJavaScript(js,false)
|
win.webContents.executeJavaScript(js,false)
|
||||||
}},
|
}},
|
||||||
{ label: 'getURL', accelerator: 'Ctrl+G', click: ()=>{
|
{ label: 'getURL', accelerator: 'Ctrl+G', click: ()=>{
|
||||||
let js="{let q=document.forms[0].q;q.focus();q.value=tabs.children[iTab].src}"
|
let js="{let q=document.forms[0].q;q.focus();q.value=tabs.children[iTab].getURL()}"
|
||||||
win.webContents.executeJavaScript(js,false)
|
win.webContents.executeJavaScript(js,false)
|
||||||
}},
|
}},
|
||||||
{ label: 'Select', accelerator: 'Ctrl+L', click:()=>{
|
{ label: 'Select', accelerator: 'Ctrl+L', click:()=>{
|
||||||
|
@ -457,7 +437,7 @@ if(e)e.blur();try{tabs.children[iTab].stopFindInPage('clearSelection')}catch(er)
|
||||||
win.webContents.executeJavaScript(js,false);
|
win.webContents.executeJavaScript(js,false);
|
||||||
}},
|
}},
|
||||||
{ label: 'Reload', accelerator: 'F5', click: ()=>{
|
{ label: 'Reload', accelerator: 'F5', click: ()=>{
|
||||||
win.webContents.executeJavaScript("tabs.children[iTab].reload()",false);
|
win.webContents.executeJavaScript("tabs.children[iTab].reloadIgnoringCache()",false);
|
||||||
}},
|
}},
|
||||||
{ label: 'Devtools', accelerator: 'F12', click: ()=>{
|
{ label: 'Devtools', accelerator: 'F12', click: ()=>{
|
||||||
let js = "try{tabs.children[iTab].openDevTools()}catch(e){console.log(e)}";
|
let js = "try{tabs.children[iTab].openDevTools()}catch(e){console.log(e)}";
|
||||||
|
@ -612,17 +592,7 @@ async function writeFile(filename, str){
|
||||||
|
|
||||||
function help(){
|
function help(){
|
||||||
const readme = "README.md";
|
const readme = "README.md";
|
||||||
const htmlFN = path.join(__dirname,readme+".html");
|
const htmlFN = path.join(__dirname,readme);
|
||||||
if(!fs.existsSync(htmlFN)){
|
let js=`{let t=tabs.children[iTab];t.dataset.jsonce=BML_md;t.src="file://${htmlFN}"}`;
|
||||||
const readmeP = path.join(__dirname,readme);
|
|
||||||
try {
|
|
||||||
fs.copyFileSync(readmeP, htmlFN);
|
|
||||||
const postscript ="<script src='https://cdn.jsdelivr.net/npm/marked@12.0.2/marked.min.js'></script><script>var d=document;var b=d.body;var t=b.textContent;t=t.slice(0,t.length-253);b.innerHTML=marked.parse(t);d.title=d.title||b.firstElementChild.innerText.trim();</script>";
|
|
||||||
fs.appendFileSync(htmlFN,postscript);
|
|
||||||
}catch(e){
|
|
||||||
htmlFN = readmeP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let js=`tabs.children[iTab].src="file://${htmlFN}"`;
|
|
||||||
win.webContents.executeJavaScript(js,false)
|
win.webContents.executeJavaScript(js,false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<sitemap>
|
<sitemap>
|
||||||
<loc>/en/sitemap.xml</loc>
|
<loc>/en/sitemap.xml</loc>
|
||||||
|
|
||||||
<lastmod>2024-06-24T10:28:02+08:00</lastmod>
|
<lastmod>2024-06-24T19:36:44+08:00</lastmod>
|
||||||
|
|
||||||
</sitemap>
|
</sitemap>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue