mirror of
https://github.com/torappinfo/uweb.git
synced 2024-08-14 23:54:59 +00:00
adaptable ebrowser links
This commit is contained in:
parent
8eb8e9e41f
commit
7eccedfecc
19 changed files with 1066 additions and 32 deletions
|
@ -41,7 +41,7 @@ Custom paper size PDF export and long vector screenshot, TTS, text reflow, resou
|
|||
![](https://i.postimg.cc/XJ58ysdN/option1.png)
|
||||
![](https://i.postimg.cc/0NFnQT6H/option2.png)
|
||||
|
||||
#### [Ebrowser](https://github.com/torappinfo/ebrowser) for Windows, MacOS and Linux
|
||||
#### <a href="ebrowser.md" onclick="if(notRepo()){location='../../en/ebrowserreadme/index.html#';return false;}">Ebrowser</a> for Windows, MacOS and Linux
|
||||
Ebrowser is a simple verison of uweb browser on the desktop.
|
||||
- Fully open source.
|
||||
- Capture long screenshot as vector graphics.
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
配套安装uWeb定制Termux应用,可用地址栏作图(类似matlab功能)、超级计算器(无限精度/π的前万位或更多、无限函数、无限常量)、符号演算(解方程、分解因式、求积分导数)、离线字典查找等。譬如地址栏输入sin(x)**5就直接得到函数图形。利用好第三方代码,才能真正发挥出uWeb的潜能。
|
||||
|
||||
#### [Ebrowser](https://github.com/torappinfo/ebrowser) for Windows, MacOS and Linux
|
||||
#### <a href="ebrowser.md" onclick="if(notRepo()){location='../../en/ebrowserreadme/index.html#';return false;}">Ebrowser</a> for Windows, MacOS and Linux
|
||||
可看作超微浏览器台式机简易版,用于弥补普通浏览器访问痛点。
|
||||
- 支持网站自动镜像,可以使用国内镜像自动访问github等网站,可与国际搜索引擎无缝衔接。
|
||||
- 同样允许直接访问英文技术网站。
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
配套安装uWeb定制Termux应用,可用地址栏作图(类似matlab功能)、超级计算器(无限精度/π的前万位或更多、无限函数、无限常量)、符号演算(解方程、分解因式、求积分导数)、离线字典查找等。譬如地址栏输入sin(x)**5就直接得到函数图形。利用好第三方代码,才能真正发挥出uWeb的潜能。
|
||||
|
||||
#### [Ebrowser](https://github.com/torappinfo/ebrowser) for Windows, MacOS and Linux
|
||||
#### <a href="ebrowser.md" onclick="if(notRepo()){location='../../en/ebrowserreadme/index.html#';return false;}">Ebrowser</a> for Windows, MacOS and Linux
|
||||
可看作超微浏览器台式机简易版,用于弥补普通浏览器访问痛点。
|
||||
- 支持网站自动镜像,可以使用国内镜像自动访问github等网站,可与国际搜索引擎无缝衔接。
|
||||
- 同样允许直接访问英文技术网站。
|
||||
|
|
83
ebrowser.md
Normal file
83
ebrowser.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
### [Ebrowser](https://github.com/torappinfo/ebrowser) as alternative to [uweb browser](https://github.com/torappinfo/uweb)
|
||||
Ebrowser is the minimal browser with the philosophy of [Android uweb browser](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 (command line) friendly.
|
||||
- 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.
|
||||
|
||||
#### Install (for Windows, macOS and Linux)
|
||||
Install ebrowser with nodejs installed
|
||||
|
||||
npm install ebrowser
|
||||
|
||||
Run ebrowser
|
||||
|
||||
electron ~/node_modules/ebrowser
|
||||
|
||||
#### Key shortcuts
|
||||
- CTRL+G: address bar to show page url
|
||||
- CTRL+L: focus to address bar
|
||||
- CTRL+T: new Tab
|
||||
- CTRL+TAB: switch to next tab
|
||||
- CTRL+SHIFT+TAB: switch to previous tab
|
||||
- CTRL+W: close Tab
|
||||
- CTRL+<-: go backward
|
||||
- CTRL+->: go forward
|
||||
- CTRL+SHIFT+R: enable global redirection ("gredirect.json")
|
||||
- CTRL+R: disable global redirection
|
||||
- ESC: remove focus. similar to vi normal mode.
|
||||
- F5: page refresh/reload
|
||||
- F12: devtools
|
||||
- ":" for address bar commands
|
||||
- "/" for find-in-page with address bar
|
||||
- "!" for ":!" address bar commands
|
||||
|
||||
#### Address bar commands
|
||||
- "/" for find-in-page
|
||||
- ":" for address bar commands
|
||||
- autoc [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.
|
||||
- ext [extension path]: load unpacked Chrome extension.
|
||||
- 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].
|
||||
- ua [useragentName] : set user agent for future tabs. default user agent w/o arguments.
|
||||
- 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
|
||||
|
||||
#### Commands in no-focus mode (this mode is similar to vi Normal mode)
|
||||
Pressing "ESC" to enter no-focus mode if not sure.
|
||||
The 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
|
||||
|
||||
#### 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.
|
|
@ -6,7 +6,7 @@
|
|||
<description>Recent content in _Posts on uweb browser: unlimited power</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en</language>
|
||||
<lastBuildDate>Fri, 24 May 2024 09:50:14 +0800</lastBuildDate>
|
||||
<lastBuildDate>Tue, 11 Jun 2024 08:12:27 +0800</lastBuildDate>
|
||||
<atom:link href="/en/_posts/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title>Text selection/processing</title>
|
||||
|
@ -111,7 +111,7 @@
|
|||
<link>/en/bookmarklet/</link>
|
||||
<pubDate>Fri, 24 Jun 2022 00:00:00 +0000</pubDate>
|
||||
<guid>/en/bookmarklet/</guid>
|
||||
<description>With a href=&quot;../index.html#&quot;&gt;uweb browser, long pressing any bookmarklet link, click &quot;Open in new tab&quot;, the bookmarklet will be run on the last other tab.
List all script urls
User agent
Cookie
Source code
Last modified date
Eruda: mobile console
QR code generation
Use &quot;GET&quot; method for &quot;POST&quot;
Shows all form elements
Enables all form elements
Toggle checkboxes
Check all checkboxes
Uncheck all checkboxes
Toggle all checkboxes in forms
Enable selection</description>
|
||||
<description>With uweb browser, long pressing any bookmarklet link, click &quot;Open in new tab&quot;, the bookmarklet will be run on the last other tab.
List all script urls
User agent
Cookie
Source code
Last modified date
Eruda: mobile console
QR code generation
Use &quot;GET&quot; method for &quot;POST&quot;
Shows all form elements
Enables all form elements
Toggle checkboxes
Check all checkboxes
Uncheck all checkboxes
Toggle all checkboxes in forms
Enable selection
Restore context menu</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>CSS styles</title>
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<li><a href="../tags/javascript/index.html#">javascript</a> </li>
|
||||
|
||||
</ul>
|
||||
<p>With a href="../index.html#">uweb browser</a>, long pressing any bookmarklet link, click "Open in new tab", the bookmarklet will be run on the last other tab.</p>
|
||||
<p>With <a href="../index.html#">uweb browser</a>, long pressing any bookmarklet link, click "Open in new tab", the bookmarklet will be run on the last other tab.</p>
|
||||
<p><a href="javascript:{let es=document.getElementsByTagName('script');let urls='';for(let i=0;i<es.length;i++){if(es[i].src)urls+=es[i].src+'<br>';}let w=window.open(''),s=w.document;s.write(urls);s.close();w.location.href='i:631:';}">List all script urls</a></p>
|
||||
<p><a target="_self" href="javascript:alert(navigator.userAgent)">User agent</a><br>
|
||||
<a href="javascript:(function(){var w=window.open(''),s=w.document;s.write('<html><body></body></html>');s.close();var pre=s.body.appendChild(s.createElement('pre'));pre.style.overflow='auto';pre.style.whiteSpace='pre-wrap';pre.appendChild(s.createTextNode(document.cookie))})()">Cookie</a><br>
|
||||
|
@ -71,8 +71,8 @@
|
|||
<p><a href="javascript: (function() { var url = ('http://www.bugmenot.com/view/' + escape(location.hostname)); w = open(url, 'w', 'location=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,width=500,height=400,modal=yes,dependent=yes'); if (w) { setTimeout('w.focus()', 1000) } else { location = url } })();">BugMeNot</a></p>
|
||||
|
||||
</div>
|
||||
<p>Last Modified: 2 April 2024<br>
|
||||
add js function in README<br>
|
||||
<p>Last Modified: 11 June 2024<br>
|
||||
fix typos<br>
|
||||
<pre></pre>
|
||||
</p>
|
||||
|
||||
|
|
178
en/ebrowserreadme/index.html
Normal file
178
en/ebrowserreadme/index.html
Normal file
|
@ -0,0 +1,178 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<link rel="stylesheet" href="../style.css#" type="text/css" />
|
||||
<title></title>
|
||||
<script type="text/javascript">
|
||||
function findLang(){
|
||||
let href = location.href;
|
||||
for(let i=href.length-1;i>0;i--){
|
||||
if('/'==href.charAt(i) && '/'==href.charAt(i-3))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function nav2(page){
|
||||
let i = findLang();
|
||||
location.href = location.href.substring(0,i+1)+page;
|
||||
}
|
||||
function nav2Lang(lang){
|
||||
let i = findLang();
|
||||
let href = location.href;
|
||||
location.href = location.href.substring(0,i-2)+lang+location.href.substring(i);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class='header'>
|
||||
<a class="logo" href="javascript:void(0)" onclick="return nav2('index.html#')">Home</a> <a class="logo" href="javascript:void(0)" onclick="return nav2('tags/index.html#')">Tags</a>
|
||||
|
||||
<nav>
|
||||
</nav>
|
||||
</header>
|
||||
<br />
|
||||
|
||||
<div class="container">
|
||||
<h1 class="title">
|
||||
<br>
|
||||
<span class="subtitle"></span>
|
||||
</h1>
|
||||
<ul class="tags">
|
||||
|
||||
</ul>
|
||||
<h3 id="ebrowserhttpsgithubcomtorappinfoebrowser-as-alternative-to-uweb-browserhttpsgithubcomtorappinfouweb"><a href="https://github.com/torappinfo/ebrowser">Ebrowser</a> as alternative to <a href="https://github.com/torappinfo/uweb">uweb browser</a></h3>
|
||||
<p>Ebrowser is the minimal browser with the philosophy of <a href="https://gitlab.com/jamesfengcao/uweb">Android uweb browser</a>.</p>
|
||||
<ul>
|
||||
<li>lightweight (less than 20k bytes) without bundled electron.</li>
|
||||
<li>much less memory footprint than edge/chrome browser and highly performant.</li>
|
||||
<li>keyboard (command line) friendly.</li>
|
||||
<li>customizable.</li>
|
||||
</ul>
|
||||
<p>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.</p>
|
||||
<h4 id="install-for-windows-macos-and-linux">Install (for Windows, macOS and Linux)</h4>
|
||||
<p>Install ebrowser with nodejs installed</p>
|
||||
<pre><code>npm install ebrowser
|
||||
</code></pre>
|
||||
<p>Run ebrowser</p>
|
||||
<pre><code>electron ~/node_modules/ebrowser
|
||||
</code></pre>
|
||||
<h4 id="key-shortcuts">Key shortcuts</h4>
|
||||
<ul>
|
||||
<li>CTRL+G: address bar to show page url</li>
|
||||
<li>CTRL+L: focus to address bar</li>
|
||||
<li>CTRL+T: new Tab</li>
|
||||
<li>CTRL+TAB: switch to next tab</li>
|
||||
<li>CTRL+SHIFT+TAB: switch to previous tab</li>
|
||||
<li>CTRL+W: close Tab</li>
|
||||
<li>CTRL+<-: go backward</li>
|
||||
<li>CTRL+->: go forward</li>
|
||||
<li>CTRL+SHIFT+R: enable global redirection ("gredirect.json")</li>
|
||||
<li>CTRL+R: disable global redirection</li>
|
||||
<li>ESC: remove focus. similar to vi normal mode.</li>
|
||||
<li>F5: page refresh/reload</li>
|
||||
<li>F12: devtools</li>
|
||||
<li>":" for address bar commands</li>
|
||||
<li>"/" for find-in-page with address bar</li>
|
||||
<li>"!" for ":!" address bar commands</li>
|
||||
</ul>
|
||||
<h4 id="address-bar-commands">Address bar commands</h4>
|
||||
<ul>
|
||||
<li>"/" for find-in-page</li>
|
||||
<li>":" for address bar commands
|
||||
<ul>
|
||||
<li>autoc [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>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>clear : the arguments could be
|
||||
<ul>
|
||||
<li>cache : clear cache</li>
|
||||
<li>dns : clear dns cache</li>
|
||||
<li>storage: clear site storage data.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>ext [extension path]: load unpacked Chrome extension.</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>np : no proxy</li>
|
||||
<li>up [proxyName] : use proxy. privous proxy or the first proxy in proxy.json w/o [proxyName].</li>
|
||||
<li>ua [useragentName] : set user agent for future tabs. default user agent w/o arguments.</li>
|
||||
<li>pdf [filename w/o extension] {<a href="https://www.electronjs.org/docs/latest/api/web-contents#contentsprinttopdfoptions">options</a>} : print to PDF file. All arguments are optional; empty option "{}" to capture long screenshot as vector graphics.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>":!" address bar commands</li>
|
||||
</ul>
|
||||
<h4 id="commands-in-no-focus-mode-this-mode-is-similar-to-vi-normal-mode">Commands in no-focus mode (this mode is similar to vi Normal mode)</h4>
|
||||
<p>Pressing "ESC" to enter no-focus mode if not sure.<br>
|
||||
The commands are defined in "mapkeys.json", which will map keys to address bar commands.</p>
|
||||
<h4 id="configuration-files">Configuration files</h4>
|
||||
<ul>
|
||||
<li>"config": lines of address bar commands.</li>
|
||||
<li>"search.json": search engines as shortcut-queryUrl pairs.</li>
|
||||
<li>"default.autoc": predefined strings for address bar auto completion.</li>
|
||||
<li>"gredirect.json": global redirection urls as array of urls</li>
|
||||
<li>"redirect.json": domain-replacementDomain pairs, default to be applied.</li>
|
||||
<li>"mapkeys.json": keys-addressbarCommands pairs. The addressbar commands are multiple lines of address bar command separated by "\n".</li>
|
||||
<li>"proxy.json": name-<a href="https://www.electronjs.org/docs/latest/api/structures/proxy-config">ProxyConfig</a> pairs</li>
|
||||
<li>"uas.json" : name-useragent pairs</li>
|
||||
</ul>
|
||||
<h4 id="new-usages">New usages</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Vector designing with web tech to replace Adobe Illustrator/Inkscape.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>Design with web tech.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Printing to pdf with customized paper size.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>Magnify the pdf paper size to the required size.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>OR</p>
|
||||
<ul>
|
||||
<li>Adjust window width and use addressbar command line ":Pdf {}" to export vector graphics.</li>
|
||||
<li>Use imageMagick to convert to any other vector graphics format.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<p>Last Modified: 11 June 2024<br>
|
||||
<br>
|
||||
<pre></pre>
|
||||
</p>
|
||||
|
||||
<script id='jsgiscus'
|
||||
src='https://giscus.app/client.js'
|
||||
data-repo="torappinfo/uweb"
|
||||
data-repo-id="MDEwOlJlcG9zaXRvcnkzMDIyMDU3MjE="
|
||||
data-category="Announcements"
|
||||
data-category-id="DIC_kwDOEgNLGc4CQjsh"
|
||||
data-mapping="title"
|
||||
data-strict="0"
|
||||
data-reactions-enabled="1"
|
||||
data-emit-metadata="0"
|
||||
data-input-position="top"
|
||||
data-theme="light"
|
||||
data-lang="en"
|
||||
data-loading="lazy"
|
||||
crossorigin="anonymous" async>
|
||||
</script>
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="container">
|
||||
© 2018-2024 Richard H. Cao
|
||||
</div>
|
||||
</footer>
|
||||
<!-- This document is licensed under the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is available at <https://www.gnu.org/licenses/>. -->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
11
en/index.xml
11
en/index.xml
|
@ -6,7 +6,7 @@
|
|||
<description>Recent content on uweb browser: unlimited power</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en</language>
|
||||
<lastBuildDate>Mon, 10 Jun 2024 17:27:55 +0800</lastBuildDate>
|
||||
<lastBuildDate>Tue, 11 Jun 2024 18:34:35 +0800</lastBuildDate>
|
||||
<atom:link href="/en/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title>Text selection/processing</title>
|
||||
|
@ -132,7 +132,7 @@
|
|||
<link>/en/bookmarklet/</link>
|
||||
<pubDate>Fri, 24 Jun 2022 00:00:00 +0000</pubDate>
|
||||
<guid>/en/bookmarklet/</guid>
|
||||
<description>With a href=&quot;../index.html#&quot;&gt;uweb browser, long pressing any bookmarklet link, click &quot;Open in new tab&quot;, the bookmarklet will be run on the last other tab.
List all script urls
User agent
Cookie
Source code
Last modified date
Eruda: mobile console
QR code generation
Use &quot;GET&quot; method for &quot;POST&quot;
Shows all form elements
Enables all form elements
Toggle checkboxes
Check all checkboxes
Uncheck all checkboxes
Toggle all checkboxes in forms
Enable selection</description>
|
||||
<description>With uweb browser, long pressing any bookmarklet link, click &quot;Open in new tab&quot;, the bookmarklet will be run on the last other tab.
List all script urls
User agent
Cookie
Source code
Last modified date
Eruda: mobile console
QR code generation
Use &quot;GET&quot; method for &quot;POST&quot;
Shows all form elements
Enables all form elements
Toggle checkboxes
Check all checkboxes
Uncheck all checkboxes
Toggle all checkboxes in forms
Enable selection
Restore context menu</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Url services</title>
|
||||
|
@ -211,6 +211,13 @@
|
|||
<guid>/en/gesture/</guid>
|
||||
<description>Swipe down from the top to show the address bar; swipe up to the top to hide the address bar. Swipe down to the bottom to hide the toolbar with option &quot;swipe to hide tools&quot;; swipe on the bottom corners to show the toolbar.
Swipe left/right near the toolbar to switch window; fling left/right to switch to the last/first window.
Swiping on the top part of content window (near the top address bar by default) triggers corresponding link in the file &quot;default.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title></title>
|
||||
<link>/en/ebrowserreadme/</link>
|
||||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||||
<guid>/en/ebrowserreadme/</guid>
|
||||
<description>Ebrowser as alternative to uweb browser Ebrowser is the minimal browser with the philosophy of Android uweb browser.
lightweight (less than 20k bytes) without bundled electron. much less memory footprint than edge/chrome browser and highly performant. keyboard (command line) friendly. 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.
Install (for Windows, macOS and Linux) Install ebrowser with nodejs installed</description>
|
||||
</item>
|
||||
<item>
|
||||
<title></title>
|
||||
<link>/en/mirrors/</link>
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<img src="https://i.postimg.cc/HLV3TYLy/longclick.png"><br>
|
||||
<img src="https://i.postimg.cc/XJ58ysdN/option1.png"><br>
|
||||
<img src="https://i.postimg.cc/0NFnQT6H/option2.png"></p>
|
||||
<h4 id="ebrowserhttpsgithubcomtorappinfoebrowser-for-windows-macos-and-linux"><a href="https://github.com/torappinfo/ebrowser">Ebrowser</a> for Windows, MacOS and Linux</h4>
|
||||
<h4 id="a-hrefebrowsermd--onclickifnotrepolocationenebrowserreadmeindexhtmlreturn-falseebrowsera-for-windows-macos-and-linux"><a href="ebrowser.md" onclick="if(notRepo()){location='../../en/ebrowserreadme/index.html#';return false;}">Ebrowser</a> for Windows, MacOS and Linux</h4>
|
||||
<p>Ebrowser is a simple verison of uweb browser on the desktop.</p>
|
||||
<ul>
|
||||
<li>Fully open source.</li>
|
||||
|
@ -106,8 +106,8 @@
|
|||
</ul>
|
||||
|
||||
</div>
|
||||
<p>Last Modified: 10 June 2024<br>
|
||||
rename eweb to ebrowser<br>
|
||||
<p>Last Modified: 11 June 2024<br>
|
||||
use adaptable ebrowser links<br>
|
||||
<pre></pre>
|
||||
</p>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
<url>
|
||||
<loc>/en/_posts/</loc>
|
||||
<lastmod>2024-05-24T09:50:14+08:00</lastmod>
|
||||
<lastmod>2024-06-11T08:12:27+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
@ -32,7 +32,7 @@
|
|||
/>
|
||||
</url><url>
|
||||
<loc>/en/tags/</loc>
|
||||
<lastmod>2024-05-24T09:50:14+08:00</lastmod>
|
||||
<lastmod>2024-06-11T08:12:27+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
@ -71,7 +71,7 @@
|
|||
/>
|
||||
</url><url>
|
||||
<loc>/en/</loc>
|
||||
<lastmod>2024-06-10T17:27:55+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:34:35+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
@ -207,7 +207,7 @@
|
|||
/>
|
||||
</url><url>
|
||||
<loc>/en/tags/javascript/</loc>
|
||||
<lastmod>2024-04-02T11:45:19+08:00</lastmod>
|
||||
<lastmod>2024-06-11T08:12:27+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
@ -320,7 +320,7 @@
|
|||
/>
|
||||
</url><url>
|
||||
<loc>/en/bookmarklet/</loc>
|
||||
<lastmod>2024-04-02T11:45:19+08:00</lastmod>
|
||||
<lastmod>2024-06-11T08:12:27+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
@ -506,12 +506,15 @@
|
|||
hreflang="en"
|
||||
href="/en/gesture/"
|
||||
/>
|
||||
</url><url>
|
||||
<loc>/en/ebrowserreadme/</loc>
|
||||
<lastmod>2024-06-11T18:18:13+08:00</lastmod>
|
||||
</url><url>
|
||||
<loc>/en/mirrors/</loc>
|
||||
<lastmod>2024-04-06T10:20:49+08:00</lastmod>
|
||||
</url><url>
|
||||
<loc>/en/readme/</loc>
|
||||
<lastmod>2024-06-10T17:27:55+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:34:35+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
@ -536,7 +539,7 @@
|
|||
/>
|
||||
</url><url>
|
||||
<loc>/en/unlist/</loc>
|
||||
<lastmod>2024-06-10T17:27:55+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:34:35+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="zh"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<description>Recent content in Tags on uweb browser: unlimited power</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en</language>
|
||||
<lastBuildDate>Fri, 24 May 2024 09:50:14 +0800</lastBuildDate>
|
||||
<lastBuildDate>Tue, 11 Jun 2024 08:12:27 +0800</lastBuildDate>
|
||||
<atom:link href="/en/tags/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title>Clipboard</title>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<description>Recent content in Javascript on uweb browser: unlimited power</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>en</language>
|
||||
<lastBuildDate>Tue, 02 Apr 2024 11:45:19 +0800</lastBuildDate>
|
||||
<lastBuildDate>Tue, 11 Jun 2024 08:12:27 +0800</lastBuildDate>
|
||||
<atom:link href="/en/tags/javascript/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title>JS/CSS/HTML/preprocessing for domains</title>
|
||||
|
@ -20,7 +20,7 @@
|
|||
<link>/en/bookmarklet/</link>
|
||||
<pubDate>Fri, 24 Jun 2022 00:00:00 +0000</pubDate>
|
||||
<guid>/en/bookmarklet/</guid>
|
||||
<description>With a href=&quot;../index.html#&quot;&gt;uweb browser, long pressing any bookmarklet link, click &quot;Open in new tab&quot;, the bookmarklet will be run on the last other tab.
List all script urls
User agent
Cookie
Source code
Last modified date
Eruda: mobile console
QR code generation
Use &quot;GET&quot; method for &quot;POST&quot;
Shows all form elements
Enables all form elements
Toggle checkboxes
Check all checkboxes
Uncheck all checkboxes
Toggle all checkboxes in forms
Enable selection</description>
|
||||
<description>With uweb browser, long pressing any bookmarklet link, click &quot;Open in new tab&quot;, the bookmarklet will be run on the last other tab.
List all script urls
User agent
Cookie
Source code
Last modified date
Eruda: mobile console
QR code generation
Use &quot;GET&quot; method for &quot;POST&quot;
Shows all form elements
Enables all form elements
Toggle checkboxes
Check all checkboxes
Uncheck all checkboxes
Toggle all checkboxes in forms
Enable selection
Restore context menu</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Long pressed link menu</title>
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
<generator>Hugo</generator>
|
||||
<language>en</language>
|
||||
<atom:link href="/en/unlist/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title></title>
|
||||
<link>/en/ebrowserreadme/</link>
|
||||
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
|
||||
<guid>/en/ebrowserreadme/</guid>
|
||||
<description>Ebrowser as alternative to uweb browser Ebrowser is the minimal browser with the philosophy of Android uweb browser.
lightweight (less than 20k bytes) without bundled electron. much less memory footprint than edge/chrome browser and highly performant. keyboard (command line) friendly. 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.
Install (for Windows, macOS and Linux) Install ebrowser with nodejs installed</description>
|
||||
</item>
|
||||
<item>
|
||||
<title></title>
|
||||
<link>/en/mirrors/</link>
|
||||
|
|
337
misc/ebrowser/index.html
Normal file
337
misc/ebrowser/index.html
Normal file
|
@ -0,0 +1,337 @@
|
|||
<!DOCTYPE html><html><head><meta charset="UTF-8">
|
||||
<style>
|
||||
html{
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
body{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
div.webviews{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow:1;
|
||||
}
|
||||
webview{display: none;width:100%;height:100%}
|
||||
.curWV{display: inherit !important;}
|
||||
</style>
|
||||
<script>
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const readline = require('readline');
|
||||
var iTab = 0;
|
||||
var tabs;
|
||||
var engines = {};
|
||||
var mapKeys = {};
|
||||
var defaultSE = "https://www.bing.com/search?q=";
|
||||
let lastKeys;
|
||||
let lastKeys_millis = 0;
|
||||
|
||||
fs.readFile(path.join(__dirname,'search.json'), 'utf8', (err, jsonString) => {
|
||||
if (err) return;
|
||||
initSearchEngines(jsonString,false);
|
||||
});
|
||||
fs.readFile(path.join(__dirname,'mapkeys.json'), 'utf8', (err, jsonStr) => {
|
||||
if (err) return;
|
||||
try {
|
||||
mapKeys = JSON.parse(jsonStr);
|
||||
}catch(e){}
|
||||
});
|
||||
appendAutoc_rec(path.join(__dirname,'default.autoc'),null);
|
||||
appendAutoc_rec(path.join(__dirname,'bookmark.rec'),' ');
|
||||
|
||||
function initSearchEngines(jsonStr){
|
||||
try{
|
||||
let val1st;
|
||||
engines=JSON.parse(jsonStr, (key, value)=>{
|
||||
if(!val1st && !(/^\d+$/u.test(key))) val1st=value;
|
||||
return value;
|
||||
});
|
||||
if(val1st) defaultSE=val1st;
|
||||
}catch(e){}
|
||||
}
|
||||
function save(filePath, u8array){
|
||||
//alert(Object.prototype.toString.call(u8array))
|
||||
fs.writeFile (filePath, u8array, (err) => {
|
||||
if (err) {
|
||||
console.error (err);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
function print2PDF(filePath, options){
|
||||
tabs.children[iTab].printToPDF(options)
|
||||
.then(u8array=>save(filePath,u8array));
|
||||
}
|
||||
function bookmark(args){//b [filenamestem] url title :bookmark
|
||||
let bmFileName = "bookmark.rec";
|
||||
let tab = tabs.children[iTab];
|
||||
let url = tab.getURL();
|
||||
if(args.length>1)
|
||||
bmFileName = args[1]+".rec";
|
||||
let title = tab.getTitle();
|
||||
let line = title + " " + url + "\n";
|
||||
fs.appendFile(path.join(__dirname,bmFileName), line, (err)=>{});
|
||||
}
|
||||
function switchTab(i){
|
||||
let tab = tabs.children[iTab];
|
||||
if(document.activeElement == tab) tab.blur();
|
||||
tab.classList.remove('curWV');
|
||||
iTab = i;
|
||||
tabs.children[iTab].classList.add('curWV');
|
||||
}
|
||||
function newTab(){
|
||||
var tab = document.createElement('webview');
|
||||
tab.allowpopups = true;
|
||||
tabs.appendChild(tab);
|
||||
}
|
||||
function tabInc(num){
|
||||
let nTabs = tabs.children.length;
|
||||
if(nTabs<2) return;
|
||||
let i = iTab +num;
|
||||
if(i>=nTabs) i=0;
|
||||
switchTab(i);
|
||||
}
|
||||
function tabDec(num){
|
||||
let nTabs = tabs.children.length;
|
||||
if(nTabs<2) return;
|
||||
let i = iTab +num;
|
||||
if(i<0) i=nTabs-1;
|
||||
switchTab(i);
|
||||
}
|
||||
function tabClose(){
|
||||
let nTabs = tabs.children.length;
|
||||
if(nTabs<2) return "";//no remain tab
|
||||
let tab = tabs.children[iTab];
|
||||
if(document.activeElement == tab) tab.blur();
|
||||
tabs.removeChild(tab);
|
||||
nTabs--;
|
||||
if(iTab>=nTabs) iTab=iTab-1;
|
||||
tabs.children[iTab].classList.add('curWV');
|
||||
return getWinTitle();
|
||||
}
|
||||
function getWinTitle(){
|
||||
let t=tabs.children[iTab];
|
||||
let title = (iTab+1) + '/' + tabs.children.length;
|
||||
try{title=title+' '+t.getTitle()+' '+t.getURL()}catch(e){}
|
||||
return title
|
||||
}
|
||||
async function appendAutoc_rec(filename, delimit){
|
||||
try{
|
||||
const readInterface = readline.createInterface ({
|
||||
input: fs.createReadStream (filename, 'utf8'),
|
||||
});
|
||||
|
||||
for await (const line of readInterface) {
|
||||
let opt = document.createElement('option');
|
||||
let iS;
|
||||
if(delimit && (iS=line.lastIndexOf(delimit))>0){
|
||||
opt.value = line.substring(iS+delimit.length);
|
||||
opt.textContent = line.substring(0,iS);
|
||||
}else
|
||||
opt.value = line;
|
||||
document.forms[0].children[0].appendChild(opt);
|
||||
}
|
||||
}catch(e){return;}
|
||||
}
|
||||
function keyPress(e){
|
||||
var inputE = document.forms[0].q;
|
||||
if (e.altKey||e.metaKey)
|
||||
return;
|
||||
var key = e.key;
|
||||
if(e.ctrlKey){
|
||||
switch(key){
|
||||
case "Home":
|
||||
tabs.children[iTab].src = "javascript:window.scrollTo(0,0)";
|
||||
return;
|
||||
case "End":
|
||||
tabs.children[iTab].src="javascript:window.scrollTo(0,document.body.scrollHeight)"
|
||||
return;
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch(key){
|
||||
case "PageDown":
|
||||
tabs.children[iTab].src =
|
||||
"javascript:window.scrollBy(0,3*document.documentElement.clientHeight/4)";
|
||||
return;
|
||||
case "PageUp":
|
||||
tabs.children[iTab].src = "javascript:window.scrollBy(0,-3*document.documentElement.clientHeight/4)";
|
||||
return;
|
||||
case "ArrowDown":
|
||||
tabs.children[iTab].src="javascript:window.scrollBy(0,32)";
|
||||
return;
|
||||
case "ArrowUp":
|
||||
tabs.children[iTab].src="javascript:window.scrollBy(0,-32)";
|
||||
return;
|
||||
|
||||
}
|
||||
if(inputE === document.activeElement) return;
|
||||
if(1!=key.length) return;
|
||||
var curMillis = Date.now();
|
||||
if(curMillis-lastKeys_millis>500)
|
||||
lastKeys = null;
|
||||
lastKeys_millis = curMillis;
|
||||
|
||||
switch (key) {
|
||||
case "!":
|
||||
inputE.value = ":";
|
||||
inputE.focus();
|
||||
lastKeys = null;
|
||||
return;
|
||||
case "/":
|
||||
case ":":
|
||||
inputE.value = "";
|
||||
inputE.focus();
|
||||
lastKeys = null;
|
||||
return;
|
||||
}
|
||||
if(!lastKeys) {
|
||||
lastKeys = key;
|
||||
return;
|
||||
}
|
||||
lastKeys = lastKeys + key;
|
||||
let cmds = mapKeys[lastKeys];
|
||||
if(cmds){
|
||||
lastKeys = null;
|
||||
for(var cmd of cmds.split("\n"))
|
||||
handleQuery(cmd);
|
||||
}
|
||||
}
|
||||
function getQ(){return document.forms[0].q.value;}
|
||||
function bang(query, iSpace){
|
||||
if(iSpace>0){
|
||||
let name = query.slice(0,iSpace);
|
||||
let engine = engines[name];
|
||||
if(engine)
|
||||
return engine+query.substring(iSpace+1);
|
||||
}
|
||||
return defaultSE+query;
|
||||
}
|
||||
function coloncommand(q){
|
||||
document.title = q;
|
||||
}
|
||||
function coloncommand_render(cmd){
|
||||
args = cmd.substring(1).split(/\s+/);
|
||||
switch(args[0]){
|
||||
case "autoc":
|
||||
autoc(args);
|
||||
return;
|
||||
case "b":
|
||||
bookmark(args);
|
||||
return;
|
||||
case "bml":
|
||||
bml(args);
|
||||
return;
|
||||
case "pdf":
|
||||
savePdf(args);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
function autoc(args){
|
||||
if(2!=args.length) return;
|
||||
appendAutoc_rec(path.join(__dirname,args[1]+".rec"),' ');
|
||||
}
|
||||
function bml(args){
|
||||
if(2!=args.length) return;
|
||||
let filename = args[1]+".js";
|
||||
fs.readFile(path.join(__dirname,filename), 'utf8', (err,str) => {
|
||||
if (err) return;
|
||||
tabs.children[iTab].executeJavaScript(str,false);
|
||||
});
|
||||
}
|
||||
function savePdf(args){
|
||||
let filename = "ebrowser.pdf";
|
||||
let options = {};
|
||||
if(1<args.length){
|
||||
let c0 = args[1].charCodeAt(0);
|
||||
let i = 1;
|
||||
if(123!=c0){//not '{' options then it is filename
|
||||
filename = args[1] + ".pdf";
|
||||
i = 2;
|
||||
}
|
||||
if(i==args.length-1){//:Pdf [filename] {...}
|
||||
if(2==args[i].length){// '{}'
|
||||
let width = document.body.clientWidth/96;
|
||||
tabs.children[iTab].executeJavaScript("document.documentElement.scrollHeight",
|
||||
false).then((h)=>{
|
||||
let opts = {
|
||||
printBackground:true,
|
||||
pageSize:{width:width,height:h/96}};
|
||||
print2PDF(filename,opts);
|
||||
});
|
||||
return;
|
||||
}else{
|
||||
try {
|
||||
options = JSON.parse(args[i]);
|
||||
}catch(e){};
|
||||
}
|
||||
}
|
||||
}
|
||||
print2PDF(filename,options);
|
||||
}
|
||||
|
||||
function handleQuery(q){
|
||||
if(q.length>1){
|
||||
let c0=q.charCodeAt(0);
|
||||
switch(c0){
|
||||
case 47://"/"
|
||||
tabs.children[iTab].findInPage(q.substring(1));
|
||||
return;
|
||||
case 58://':'
|
||||
let c1=q.charCodeAt(1);
|
||||
if(c1>98 && 112!=c1)
|
||||
coloncommand(q);
|
||||
else
|
||||
coloncommand_render(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
var url=q;
|
||||
do {
|
||||
if(q.length>7){
|
||||
let c6 = q.charCodeAt(6);
|
||||
if(47==c6){// '/'
|
||||
let c5 = q.charCodeAt(5);
|
||||
if(47==c5 && 58==q.charCodeAt(4))//http/file urls
|
||||
break;
|
||||
if(58==c5 && 47==q.charCodeAt(7))//https://
|
||||
break;
|
||||
}else if(q.startsWith("javascript:")){
|
||||
tabs.children[iTab].executeJavaScript(q.substring(11),false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let iS = q.indexOf(' ');
|
||||
if(iS<0){
|
||||
if(q.length>5){
|
||||
if(58==q.charCodeAt(5))
|
||||
break;
|
||||
}
|
||||
if(q.indexOf('.')>0){
|
||||
url = 'https://'+q;
|
||||
break;
|
||||
}
|
||||
}
|
||||
url = bang(q, iS);
|
||||
}while(false);
|
||||
tabs.children[iTab].src=url;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<form action="javascript:handleQuery(getQ())">
|
||||
<datalist id="autoc"></datalist>
|
||||
<input type="text" list="autoc" name=q style="width:100%" autofocus></form>
|
||||
<div class="webviews">
|
||||
<webview class="curWV" allowpopups></webview>
|
||||
</div>
|
||||
<script>
|
||||
tabs = document.body.children[1];
|
||||
document.addEventListener('keydown', keyPress);
|
||||
</script>
|
||||
</body></html>
|
419
misc/ebrowser/webview.js
Normal file
419
misc/ebrowser/webview.js
Normal file
|
@ -0,0 +1,419 @@
|
|||
const {
|
||||
app, BrowserWindow, Menu, shell, clipboard,
|
||||
session, protocol, net} = require('electron')
|
||||
let win;
|
||||
|
||||
if(!app.requestSingleInstanceLock())
|
||||
app.quit()
|
||||
else {
|
||||
app.on('ready', createWindow);
|
||||
app.on('second-instance', (event, args, cwd) => {
|
||||
// 当已经有运行的实例时,我们激活窗口而不是创建新的窗口
|
||||
if (win) {
|
||||
if (win.isMinimized()) {
|
||||
win.restore()
|
||||
}
|
||||
win.show()
|
||||
win.focus()
|
||||
cmdlineProcess(args,cwd,1);
|
||||
}else
|
||||
createWindow();
|
||||
})
|
||||
}
|
||||
topMenu();
|
||||
|
||||
const fs = require('fs');
|
||||
const readline = require('readline');
|
||||
const path = require('path')
|
||||
const process = require('process')
|
||||
var gredirects = [];
|
||||
var gredirect;
|
||||
var redirects;
|
||||
var bRedirect = true;
|
||||
var bJS = true;
|
||||
var bHistory = false;
|
||||
var proxies = {};
|
||||
var proxy;
|
||||
var useragents = {};
|
||||
var defaultUA =
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" +
|
||||
process.versions.chrome +" Safari/537.36";
|
||||
app.userAgentFallback = defaultUA;
|
||||
var historyFile = path.join(__dirname,'history.rec');
|
||||
|
||||
fs.readFile(path.join(__dirname,'redirect.json'), 'utf8', (err, jsonString) => {
|
||||
if (err) return;
|
||||
try {
|
||||
redirects = JSON.parse(jsonString);
|
||||
} catch (e){}
|
||||
});
|
||||
|
||||
async function createWindow () {
|
||||
let json = await fs.promises.readFile(path.join(__dirname,'uas.json'), 'utf8');
|
||||
try {
|
||||
useragents = JSON.parse(json);
|
||||
} catch (e){}
|
||||
|
||||
await (async ()=>{
|
||||
try{
|
||||
const readInterface = readline.createInterface ({
|
||||
input: fs.createReadStream (path.join(__dirname,'config'), 'utf8'),
|
||||
});
|
||||
|
||||
for await (const line of readInterface) {
|
||||
addrCommand(line);
|
||||
}
|
||||
}catch(e){return;}
|
||||
})();
|
||||
|
||||
win = new BrowserWindow(
|
||||
{width: 800, height: 600,autoHideMenuBar: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
webviewTag: true,
|
||||
}});
|
||||
win.setMenuBarVisibility(false);
|
||||
win.on('closed', function () {
|
||||
win = null
|
||||
})
|
||||
|
||||
win.loadFile('index.html');
|
||||
fs.readFile(path.join(__dirname,'gredirect.json'), 'utf8', (err, jsonString) => {
|
||||
if (err) return;
|
||||
try {
|
||||
gredirects = JSON.parse(jsonString);
|
||||
} catch (e){}
|
||||
});
|
||||
|
||||
fs.readFile(path.join(__dirname,'proxy.json'), 'utf8', (err, jsonString) => {
|
||||
if (err) return;
|
||||
try {
|
||||
proxies = JSON.parse(jsonString, (key,val)=>{
|
||||
if(!proxy && key==="proxyRules"){
|
||||
proxy = {proxyRules:val};
|
||||
}
|
||||
return val;
|
||||
});
|
||||
} catch (e){}
|
||||
});
|
||||
|
||||
cmdlineProcess(process.argv, process.cwd(), 0);
|
||||
//app.commandLine.appendSwitch ('trace-warnings');
|
||||
|
||||
win.webContents.on('page-title-updated',(event,cmd)=>{
|
||||
addrCommand(cmd);
|
||||
});
|
||||
|
||||
win.webContents.on('console-message',cbConsoleMsg);
|
||||
//protocol.handle("https",cbScheme_https);
|
||||
}
|
||||
|
||||
app.on('window-all-closed', function () {
|
||||
app.quit()
|
||||
})
|
||||
|
||||
app.on('activate', function () {
|
||||
if (win === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('will-quit', () => {
|
||||
})
|
||||
|
||||
app.on ('web-contents-created', (event, contents) => {
|
||||
if (contents.getType () === 'webview') {
|
||||
contents.setWindowOpenHandler(cbWindowOpenHandler);
|
||||
contents.on('context-menu',onContextMenu);
|
||||
contents.on('page-title-updated',cbTitleUpdate);
|
||||
//contents.on('console-message',cbConsoleMsg);
|
||||
//contents.on('focus', ()=>{cbFocus(contents)});
|
||||
//contents.on('blur',()=>{cbBlur()});
|
||||
contents.session.webRequest.onBeforeRequest(interceptRequest);
|
||||
contents.on('did-finish-load',()=>{cbFinishLoad(contents)});
|
||||
}
|
||||
});
|
||||
|
||||
function addrCommand(cmd){
|
||||
if(cmd.length<3) return;
|
||||
let c0 = cmd.charCodeAt(0);
|
||||
switch(c0){
|
||||
case 58: //':'
|
||||
args = cmd.substring(1).split(/\s+/);
|
||||
switch(args[0]){
|
||||
case "cert":
|
||||
if(args.length==1)
|
||||
session.defaultSession.setCertificateVerifyProc((request, callback) => {
|
||||
callback(0);
|
||||
});
|
||||
else
|
||||
session.defaultSession.setCertificateVerifyProc(null);
|
||||
return;
|
||||
case "clear":
|
||||
if(args.length==1){
|
||||
return;
|
||||
}
|
||||
switch(args[1]){
|
||||
case "cache":
|
||||
session.defaultSession.clearCache();
|
||||
return;
|
||||
case "dns":
|
||||
session.defaultSession.clearHostResolverCache();
|
||||
return;
|
||||
case "storage":
|
||||
session.defaultSession.clearStorageData();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
case "ext":
|
||||
session.defaultSession.loadExtension(args[1]);
|
||||
return;
|
||||
case "nh":
|
||||
bHistory = false; return;
|
||||
case "uh":
|
||||
bHistory = true; return;
|
||||
case "nj":
|
||||
bJS = false; return;
|
||||
case "uj":
|
||||
bJS = true; return;
|
||||
case "np":
|
||||
session.defaultSession.setProxy ({mode:"direct"});
|
||||
return;
|
||||
case "up":
|
||||
if(args.length>1)
|
||||
proxy = proxies[args[1]]; //retrieve proxy
|
||||
if(proxy)
|
||||
session.defaultSession.setProxy(proxy);
|
||||
bRedirect = false;
|
||||
return;
|
||||
case "nr":
|
||||
bRedirect = false; return;
|
||||
case "ur":
|
||||
bRedirect = true; return;
|
||||
case "ua":
|
||||
if(args.length==2)
|
||||
session.defaultSession.setUserAgent(useragents[args[1]]);
|
||||
else
|
||||
session.defaultSession.setUserAgent(defaultUA);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cbConsoleMsg(e, level, msg, line, sourceid){
|
||||
console.log(line);
|
||||
console.log(sourceid);
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
function cbFinishLoad(webContents){
|
||||
if(!bHistory) return;
|
||||
let histItem = webContents.getTitle()+" "+webContents.getURL()+"\n";
|
||||
fs.appendFile(historyFile, histItem, (err) => {});
|
||||
}
|
||||
|
||||
function cbFocus(webContents){
|
||||
let js = "if(focusMesg){let m=focusMesg;focusMesg=null;m}";
|
||||
win.webContents.executeJavaScript(js,false).then((r)=>{
|
||||
//focusMesg as js code
|
||||
console.log(r);
|
||||
if(r) webContents.executeJavaScript(r,false);
|
||||
});
|
||||
}
|
||||
|
||||
function interceptRequest(details, callback){
|
||||
if(!bJS && details.url.endsWith(".js")){
|
||||
callback({ cancel: true });
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if(gredirect){
|
||||
if(!details.url.startsWith("http")) break;
|
||||
if(!details.url.startsWith(gredirect)){
|
||||
if(details.resourceType === 'mainFrame'){
|
||||
let wc = details.webContents;
|
||||
let url = details.url;
|
||||
if(wc){
|
||||
let nUrl = gredirect+url;
|
||||
fetch(nUrl).then(res=>{
|
||||
if(res.ok) return res.arrayBuffer();
|
||||
throw new Error(`Err: ${res.status} - ${res.statusText}`);
|
||||
}).then(aBuf=>{
|
||||
const u8 = new Uint8Array(aBuf);
|
||||
const b64 = Buffer.from (u8).toString('base64');
|
||||
const dataUrl = `data:text/html;base64,${b64}`;
|
||||
wc.loadURL(dataUrl,{baseURLForDataURL:url});
|
||||
}).catch(e=>{
|
||||
console.log(nUrl+" err:",e);
|
||||
});
|
||||
callback({ cancel: true });
|
||||
return;
|
||||
}
|
||||
}
|
||||
let newUrl = gredirect + details.url;
|
||||
callback({ cancel: false, redirectURL: newUrl });
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bRedirect ||(details.resourceType !== 'mainFrame' &&
|
||||
details.resourceType !== 'subFrame')) break;
|
||||
let oURL = new URL(details.url);
|
||||
let domain = oURL.hostname;
|
||||
let newUrl;
|
||||
try{
|
||||
let newDomain = redirects[domain];
|
||||
if(!newDomain) break;
|
||||
newUrl = "https://"+newDomain+oURL.pathname+oURL.search+oURL.hash;
|
||||
}catch(e){break;}
|
||||
callback({ cancel: false, redirectURL: newUrl });
|
||||
return;
|
||||
}while(false);
|
||||
callback({ cancel: false });
|
||||
}
|
||||
|
||||
function cbWindowOpenHandler(details){
|
||||
let url = details.url;
|
||||
let js = "newTab();tabs.children[tabs.children.length-1].src='"+
|
||||
url+"';";
|
||||
switch(details.disposition){
|
||||
case "foreground-tab":
|
||||
case "new-window":
|
||||
js = js + "switchTab(tabs.children.length-1)";
|
||||
}
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
return { action: "deny" };
|
||||
}
|
||||
function cbTitleUpdate(event,title){
|
||||
win.setTitle(title);
|
||||
}
|
||||
function menuArray(labelprefix, linkUrl){
|
||||
const menuTemplate = [
|
||||
{
|
||||
label: labelprefix+'Open Link',
|
||||
click: () => {
|
||||
shell.openExternal(linkUrl);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: labelprefix+'Copy Link',
|
||||
click: () => {
|
||||
clipboard.writeText(linkUrl);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: labelprefix+'Download',
|
||||
click: () => {
|
||||
win.contentView.children[i].webContents.downloadURL(linkUrl);
|
||||
}
|
||||
},
|
||||
];
|
||||
return menuTemplate;
|
||||
}
|
||||
|
||||
function onContextMenu(event, params){
|
||||
let url = params.linkURL;
|
||||
let mTemplate = [];
|
||||
if (url) {
|
||||
mTemplate.push({label:url,enabled:false});
|
||||
mTemplate.push.apply(mTemplate,menuArray("",url));
|
||||
if((url=params.srcURL))
|
||||
mTemplate.push.apply(mTemplate,menuArray("src: ",url));
|
||||
}else if((url=params.srcURL)){
|
||||
mTemplate.push({label:url,enabled:false});
|
||||
mTemplate.push.apply(mTemplate,menuArray("src: ",url));
|
||||
}else
|
||||
return;
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate(mTemplate);
|
||||
contextMenu.popup();
|
||||
}
|
||||
|
||||
function topMenu(){
|
||||
const menuTemplate = [
|
||||
{
|
||||
label: '',
|
||||
submenu: [
|
||||
{ label: '', accelerator: 'Ctrl+G', click: ()=>{
|
||||
let js="{let q=document.forms[0].q;q.focus();q.value=tabs.children[iTab].src}"
|
||||
win.webContents.executeJavaScript(js,false)
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+L', click:()=>{
|
||||
win.webContents.executeJavaScript("document.forms[0].q.select()",false);
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+T', click:()=>{
|
||||
let js = "newTab();document.forms[0].q.select();switchTab(tabs.children.length-1)";
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+R', click: ()=>{
|
||||
gredirect=null;
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+Shift+R', click: ()=>{
|
||||
if(0==gredirects.length) return;
|
||||
gredirect=gredirects[0];
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+W', click: ()=>{
|
||||
win.webContents.executeJavaScript("tabClose()",false).then((r)=>{
|
||||
if(""===r) win.close();
|
||||
else win.setTitle(r);
|
||||
});
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+Tab', click: ()=>{
|
||||
let js="tabInc(1);getWinTitle()";
|
||||
win.webContents.executeJavaScript(js,false).then((r)=>{
|
||||
win.setTitle(r);
|
||||
});
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+Shift+Tab', click: ()=>{
|
||||
let js="tabDec(-1);getWinTitle()";
|
||||
win.webContents.executeJavaScript(js,false).then((r)=>{
|
||||
win.setTitle(r);
|
||||
});
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+Left', click: ()=>{
|
||||
let js="tabs.children[iTab].goBack()";
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
}},
|
||||
{ label: '', accelerator: 'Ctrl+Right', click: ()=>{
|
||||
let js="tabs.children[iTab].goForward()";
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
}},
|
||||
{ label: '', accelerator: 'Esc', click: ()=>{
|
||||
let js = `{let e=document.activeElement;
|
||||
if(e)e.blur();try{tabs.children[iTab].stopFindInPage('clearSelection')}catch(er){}}`;
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
}},
|
||||
{ label: '', accelerator: 'F5', click: ()=>{
|
||||
win.webContents.executeJavaScript("tabs.children[iTab].reload()",false);
|
||||
}},
|
||||
{ label: '', accelerator: 'F12', click: ()=>{
|
||||
let js = "try{tabs.children[iTab].openDevTools()}catch(e){console.log(e)}";
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
}},
|
||||
|
||||
],
|
||||
},
|
||||
];
|
||||
const menu = Menu.buildFromTemplate(menuTemplate);
|
||||
Menu.setApplicationMenu(menu);
|
||||
}
|
||||
|
||||
function cmdlineProcess(argv,cwd,extra){
|
||||
let i1st = 2+extra; //index for the first query item
|
||||
if(argv.length>i1st){
|
||||
if(i1st+1==argv.length){//local file
|
||||
let fname = path.join(cwd, argv[i1st]);
|
||||
if(fs.existsSync(fname)){
|
||||
let js = "tabs.children[iTab].src='file://"+fname+"'";
|
||||
win.webContents.executeJavaScript(js,false);
|
||||
win.setTitle(argv[i1st]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let url=argv.slice(i1st).join(" ");
|
||||
win.webContents.executeJavaScript("handleQuery(`"+url+"`)",false);
|
||||
win.setTitle(url);
|
||||
}
|
||||
}
|
|
@ -4,14 +4,14 @@
|
|||
<sitemap>
|
||||
<loc>/en/sitemap.xml</loc>
|
||||
|
||||
<lastmod>2024-06-10T17:27:55+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:34:35+08:00</lastmod>
|
||||
|
||||
</sitemap>
|
||||
|
||||
<sitemap>
|
||||
<loc>/zh/sitemap.xml</loc>
|
||||
|
||||
<lastmod>2024-06-10T17:28:20+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:37:58+08:00</lastmod>
|
||||
|
||||
</sitemap>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<description>Recent content on 超微浏览器: 威、快、高效、极致优化</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>zh</language>
|
||||
<lastBuildDate>Mon, 10 Jun 2024 17:28:20 +0800</lastBuildDate>
|
||||
<lastBuildDate>Tue, 11 Jun 2024 18:37:58 +0800</lastBuildDate>
|
||||
<atom:link href="/zh/index.xml" rel="self" type="application/rss+xml" />
|
||||
<item>
|
||||
<title>操作选中(富)文本/元素</title>
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<p>支持网址特定脚本/样式,可轻松支持百万以上不同脚本。</p>
|
||||
<p>支持自定义任意多个搜索引擎; 支持执行用户提供任何js文件; 支持用户定义任意多个useragent; 长按链接支持运行第三方程序; 长按链接支持运行用户js文件。</p>
|
||||
<p>配套安装uWeb定制Termux应用,可用地址栏作图(类似matlab功能)、超级计算器(无限精度/π的前万位或更多、无限函数、无限常量)、符号演算(解方程、分解因式、求积分导数)、离线字典查找等。譬如地址栏输入sin(x)**5就直接得到函数图形。利用好第三方代码,才能真正发挥出uWeb的潜能。</p>
|
||||
<h4 id="ebrowserhttpsgithubcomtorappinfoebrowser-for-windows-macos-and-linux"><a href="https://github.com/torappinfo/ebrowser">Ebrowser</a> for Windows, MacOS and Linux</h4>
|
||||
<h4 id="a-hrefebrowsermd--onclickifnotrepolocationenebrowserreadmeindexhtmlreturn-falseebrowsera-for-windows-macos-and-linux"><a href="ebrowser.md" onclick="if(notRepo()){location='../../en/ebrowserreadme/index.html#';return false;}">Ebrowser</a> for Windows, MacOS and Linux</h4>
|
||||
<p>可看作超微浏览器台式机简易版,用于弥补普通浏览器访问痛点。</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
@ -119,8 +119,8 @@
|
|||
</ul>
|
||||
|
||||
</div>
|
||||
<p>Last Modified: 10 June 2024<br>
|
||||
rename eweb to ebrowser<br>
|
||||
<p>Last Modified: 11 June 2024<br>
|
||||
use adaptable ebrowser links<br>
|
||||
<pre></pre>
|
||||
</p>
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
/>
|
||||
</url><url>
|
||||
<loc>/zh/</loc>
|
||||
<lastmod>2024-06-10T17:28:20+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:37:58+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="en"
|
||||
|
@ -483,7 +483,7 @@
|
|||
<lastmod>2024-04-02T11:46:25+08:00</lastmod>
|
||||
</url><url>
|
||||
<loc>/zh/readme/</loc>
|
||||
<lastmod>2024-06-10T17:28:20+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:37:58+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="en"
|
||||
|
@ -511,7 +511,7 @@
|
|||
<lastmod>2024-04-02T11:46:25+08:00</lastmod>
|
||||
</url><url>
|
||||
<loc>/zh/unlist/</loc>
|
||||
<lastmod>2024-06-10T17:28:20+08:00</lastmod>
|
||||
<lastmod>2024-06-11T18:37:58+08:00</lastmod>
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="en"
|
||||
|
|
Loading…
Reference in a new issue