adaptable ebrowser links
[uweb.git] / misc / ebrowser / index.html
blobc5447addb20be9c3669c74a351c5be96693624c2
1 <!DOCTYPE html><html><head><meta charset="UTF-8">
2 <style>
3 html{
4 height: 100%;
5 overflow: hidden;
7 body{
8 display: flex;
9 flex-direction: column;
10 height: 100%;
12 div.webviews{
13 display: flex;
14 flex-direction: column;
15 flex-grow:1;
17 webview{display: none;width:100%;height:100%}
18 .curWV{display: inherit !important;}
19 </style>
20 <script>
21 const fs = require('fs');
22 const path = require('path');
23 const readline = require('readline');
24 var iTab = 0;
25 var tabs;
26 var engines = {};
27 var mapKeys = {};
28 var defaultSE = "https://www.bing.com/search?q=";
29 let lastKeys;
30 let lastKeys_millis = 0;
32 fs.readFile(path.join(__dirname,'search.json'), 'utf8', (err, jsonString) => {
33 if (err) return;
34 initSearchEngines(jsonString,false);
35 });
36 fs.readFile(path.join(__dirname,'mapkeys.json'), 'utf8', (err, jsonStr) => {
37 if (err) return;
38 try {
39 mapKeys = JSON.parse(jsonStr);
40 }catch(e){}
41 });
42 appendAutoc_rec(path.join(__dirname,'default.autoc'),null);
43 appendAutoc_rec(path.join(__dirname,'bookmark.rec'),' ');
45 function initSearchEngines(jsonStr){
46 try{
47 let val1st;
48 engines=JSON.parse(jsonStr, (key, value)=>{
49 if(!val1st && !(/^\d+$/u.test(key))) val1st=value;
50 return value;
51 });
52 if(val1st) defaultSE=val1st;
53 }catch(e){}
55 function save(filePath, u8array){
56 //alert(Object.prototype.toString.call(u8array))
57 fs.writeFile (filePath, u8array, (err) => {
58 if (err) {
59 console.error (err);
60 return;
62 });
64 function print2PDF(filePath, options){
65 tabs.children[iTab].printToPDF(options)
66 .then(u8array=>save(filePath,u8array));
68 function bookmark(args){//b [filenamestem] url title :bookmark
69 let bmFileName = "bookmark.rec";
70 let tab = tabs.children[iTab];
71 let url = tab.getURL();
72 if(args.length>1)
73 bmFileName = args[1]+".rec";
74 let title = tab.getTitle();
75 let line = title + " " + url + "\n";
76 fs.appendFile(path.join(__dirname,bmFileName), line, (err)=>{});
78 function switchTab(i){
79 let tab = tabs.children[iTab];
80 if(document.activeElement == tab) tab.blur();
81 tab.classList.remove('curWV');
82 iTab = i;
83 tabs.children[iTab].classList.add('curWV');
85 function newTab(){
86 var tab = document.createElement('webview');
87 tab.allowpopups = true;
88 tabs.appendChild(tab);
90 function tabInc(num){
91 let nTabs = tabs.children.length;
92 if(nTabs<2) return;
93 let i = iTab +num;
94 if(i>=nTabs) i=0;
95 switchTab(i);
97 function tabDec(num){
98 let nTabs = tabs.children.length;
99 if(nTabs<2) return;
100 let i = iTab +num;
101 if(i<0) i=nTabs-1;
102 switchTab(i);
104 function tabClose(){
105 let nTabs = tabs.children.length;
106 if(nTabs<2) return "";//no remain tab
107 let tab = tabs.children[iTab];
108 if(document.activeElement == tab) tab.blur();
109 tabs.removeChild(tab);
110 nTabs--;
111 if(iTab>=nTabs) iTab=iTab-1;
112 tabs.children[iTab].classList.add('curWV');
113 return getWinTitle();
115 function getWinTitle(){
116 let t=tabs.children[iTab];
117 let title = (iTab+1) + '/' + tabs.children.length;
118 try{title=title+' '+t.getTitle()+' '+t.getURL()}catch(e){}
119 return title
121 async function appendAutoc_rec(filename, delimit){
122 try{
123 const readInterface = readline.createInterface ({
124 input: fs.createReadStream (filename, 'utf8'),
127 for await (const line of readInterface) {
128 let opt = document.createElement('option');
129 let iS;
130 if(delimit && (iS=line.lastIndexOf(delimit))>0){
131 opt.value = line.substring(iS+delimit.length);
132 opt.textContent = line.substring(0,iS);
133 }else
134 opt.value = line;
135 document.forms[0].children[0].appendChild(opt);
137 }catch(e){return;}
139 function keyPress(e){
140 var inputE = document.forms[0].q;
141 if (e.altKey||e.metaKey)
142 return;
143 var key = e.key;
144 if(e.ctrlKey){
145 switch(key){
146 case "Home":
147 tabs.children[iTab].src = "javascript:window.scrollTo(0,0)";
148 return;
149 case "End":
150 tabs.children[iTab].src="javascript:window.scrollTo(0,document.body.scrollHeight)"
151 return;
154 return;
156 switch(key){
157 case "PageDown":
158 tabs.children[iTab].src =
159 "javascript:window.scrollBy(0,3*document.documentElement.clientHeight/4)";
160 return;
161 case "PageUp":
162 tabs.children[iTab].src = "javascript:window.scrollBy(0,-3*document.documentElement.clientHeight/4)";
163 return;
164 case "ArrowDown":
165 tabs.children[iTab].src="javascript:window.scrollBy(0,32)";
166 return;
167 case "ArrowUp":
168 tabs.children[iTab].src="javascript:window.scrollBy(0,-32)";
169 return;
172 if(inputE === document.activeElement) return;
173 if(1!=key.length) return;
174 var curMillis = Date.now();
175 if(curMillis-lastKeys_millis>500)
176 lastKeys = null;
177 lastKeys_millis = curMillis;
179 switch (key) {
180 case "!":
181 inputE.value = ":";
182 inputE.focus();
183 lastKeys = null;
184 return;
185 case "/":
186 case ":":
187 inputE.value = "";
188 inputE.focus();
189 lastKeys = null;
190 return;
192 if(!lastKeys) {
193 lastKeys = key;
194 return;
196 lastKeys = lastKeys + key;
197 let cmds = mapKeys[lastKeys];
198 if(cmds){
199 lastKeys = null;
200 for(var cmd of cmds.split("\n"))
201 handleQuery(cmd);
204 function getQ(){return document.forms[0].q.value;}
205 function bang(query, iSpace){
206 if(iSpace>0){
207 let name = query.slice(0,iSpace);
208 let engine = engines[name];
209 if(engine)
210 return engine+query.substring(iSpace+1);
212 return defaultSE+query;
214 function coloncommand(q){
215 document.title = q;
217 function coloncommand_render(cmd){
218 args = cmd.substring(1).split(/\s+/);
219 switch(args[0]){
220 case "autoc":
221 autoc(args);
222 return;
223 case "b":
224 bookmark(args);
225 return;
226 case "bml":
227 bml(args);
228 return;
229 case "pdf":
230 savePdf(args);
231 return;
235 function autoc(args){
236 if(2!=args.length) return;
237 appendAutoc_rec(path.join(__dirname,args[1]+".rec"),' ');
239 function bml(args){
240 if(2!=args.length) return;
241 let filename = args[1]+".js";
242 fs.readFile(path.join(__dirname,filename), 'utf8', (err,str) => {
243 if (err) return;
244 tabs.children[iTab].executeJavaScript(str,false);
247 function savePdf(args){
248 let filename = "ebrowser.pdf";
249 let options = {};
250 if(1<args.length){
251 let c0 = args[1].charCodeAt(0);
252 let i = 1;
253 if(123!=c0){//not '{' options then it is filename
254 filename = args[1] + ".pdf";
255 i = 2;
257 if(i==args.length-1){//:Pdf [filename] {...}
258 if(2==args[i].length){// '{}'
259 let width = document.body.clientWidth/96;
260 tabs.children[iTab].executeJavaScript("document.documentElement.scrollHeight",
261 false).then((h)=>{
262 let opts = {
263 printBackground:true,
264 pageSize:{width:width,height:h/96}};
265 print2PDF(filename,opts);
267 return;
268 }else{
269 try {
270 options = JSON.parse(args[i]);
271 }catch(e){};
275 print2PDF(filename,options);
278 function handleQuery(q){
279 if(q.length>1){
280 let c0=q.charCodeAt(0);
281 switch(c0){
282 case 47://"/"
283 tabs.children[iTab].findInPage(q.substring(1));
284 return;
285 case 58://':'
286 let c1=q.charCodeAt(1);
287 if(c1>98 && 112!=c1)
288 coloncommand(q);
289 else
290 coloncommand_render(q);
291 return;
294 var url=q;
295 do {
296 if(q.length>7){
297 let c6 = q.charCodeAt(6);
298 if(47==c6){// '/'
299 let c5 = q.charCodeAt(5);
300 if(47==c5 && 58==q.charCodeAt(4))//http/file urls
301 break;
302 if(58==c5 && 47==q.charCodeAt(7))//https://
303 break;
304 }else if(q.startsWith("javascript:")){
305 tabs.children[iTab].executeJavaScript(q.substring(11),false);
306 return;
309 let iS = q.indexOf(' ');
310 if(iS<0){
311 if(q.length>5){
312 if(58==q.charCodeAt(5))
313 break;
315 if(q.indexOf('.')>0){
316 url = 'https://'+q;
317 break;
320 url = bang(q, iS);
321 }while(false);
322 tabs.children[iTab].src=url;
324 </script>
325 </head>
326 <body>
327 <form action="javascript:handleQuery(getQ())">
328 <datalist id="autoc"></datalist>
329 <input type="text" list="autoc" name=q style="width:100%" autofocus></form>
330 <div class="webviews">
331 <webview class="curWV" allowpopups></webview>
332 </div>
333 <script>
334 tabs = document.body.children[1];
335 document.addEventListener('keydown', keyPress);
336 </script>
337 </body></html>