Implemented Unflow for plaintext content
This commit is contained in:
@@ -61,7 +61,7 @@ Note that currently, Kopher and hi01379.js assume that the search request from a
|
|||||||
- Minimalistic but easy and quick WAP-like navigation (see "Controls")
|
- Minimalistic but easy and quick WAP-like navigation (see "Controls")
|
||||||
- The `gopher://` scheme is assumed by default (no need to enter it manually), same for the port 70
|
- The `gopher://` scheme is assumed by default (no need to enter it manually), same for the port 70
|
||||||
- One-key light/dark theme toggle
|
- One-key light/dark theme toggle
|
||||||
- One-key switching the line wrapping mode between off (default) and on (for comfortable reading)
|
- One-key switching the line wrapping mode between off (default) and on (for comfortable reading even the hard-wrapped documents)
|
||||||
- Unlimited navigation history (doesn't persist between sessions)
|
- Unlimited navigation history (doesn't persist between sessions)
|
||||||
- Up to 10 numbered bookmarks plus customizable homepage
|
- Up to 10 numbered bookmarks plus customizable homepage
|
||||||
- Binary blob downloads (see "Downloads")
|
- Binary blob downloads (see "Downloads")
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ addEventListener('DOMContentLoaded', function() {
|
|||||||
return bmArray[index]
|
return bmArray[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var activeContent={'prop': 'textContent', 'nowrap': '', 'wrap': ''} // placeholder to hold the wrapped and non-wrapped content
|
||||||
|
|
||||||
function loadURL(url, noNavUpdate) { // wrapper to openURL that actually updates all the UI and history
|
function loadURL(url, noNavUpdate) { // wrapper to openURL that actually updates all the UI and history
|
||||||
logoStatus.textContent = logoLoadingChar
|
logoStatus.textContent = logoLoadingChar
|
||||||
statusBar.textContent = 'Loading ' + url
|
statusBar.textContent = 'Loading ' + url
|
||||||
@@ -108,14 +110,18 @@ addEventListener('DOMContentLoaded', function() {
|
|||||||
var updateHistory = !('updateAddr' in res && res.updateAddr === false), // true by default
|
var updateHistory = !('updateAddr' in res && res.updateAddr === false), // true by default
|
||||||
updateContent = !(res.content === null) // true by default
|
updateContent = !(res.content === null) // true by default
|
||||||
if(updateContent) { // update the content zone
|
if(updateContent) { // update the content zone
|
||||||
|
activeContent.nowrap = res.content
|
||||||
|
activeContent.wrap = res.contentWf || res.content
|
||||||
contentZone.innerHTML = ''
|
contentZone.innerHTML = ''
|
||||||
contentZone.textContent = ''
|
contentZone.textContent = ''
|
||||||
contentZone.dataset.wrap = 0 // reset line wrapping
|
contentZone.dataset.wrap = 0 // reset line wrapping
|
||||||
if(res.contentType === 'text/plain') {
|
if(res.contentType === 'text/plain') {
|
||||||
|
activeContent.prop = 'textContent'
|
||||||
contentZone.dataset.format='plain'
|
contentZone.dataset.format='plain'
|
||||||
contentZone.textContent = res.content
|
contentZone.textContent = activeContent.nowrap
|
||||||
} else {
|
} else {
|
||||||
contentZone.dataset.format='native'
|
contentZone.dataset.format='native'
|
||||||
|
activeContent.prop='innerHTML'
|
||||||
contentZone.innerHTML = res.content
|
contentZone.innerHTML = res.content
|
||||||
var contentLinks = contentZone.querySelectorAll('a'), l = contentLinks.length, i
|
var contentLinks = contentZone.querySelectorAll('a'), l = contentLinks.length, i
|
||||||
for(i=0;i<l;i++) { // dynamically index all the links in the rendered content
|
for(i=0;i<l;i++) { // dynamically index all the links in the rendered content
|
||||||
@@ -203,6 +209,8 @@ addEventListener('DOMContentLoaded', function() {
|
|||||||
break
|
break
|
||||||
case '6': // toggle line wrapping
|
case '6': // toggle line wrapping
|
||||||
contentZone.dataset.wrap = 1 - parseInt(contentZone.dataset.wrap)
|
contentZone.dataset.wrap = 1 - parseInt(contentZone.dataset.wrap)
|
||||||
|
if(activeContent.wrap != activeContent.nowrap) // only update contentZone if they differ
|
||||||
|
contentZone[activeContent.prop] = activeContent[parseInt(contentZone.dataset.wrap) ? 'wrap' : 'nowrap']
|
||||||
break
|
break
|
||||||
case 'Call': // refresh
|
case 'Call': // refresh
|
||||||
loadURL(currentUrl, true)
|
loadURL(currentUrl, true)
|
||||||
|
|||||||
+23
-1
@@ -10,6 +10,24 @@ Hi01379 = (function(psGopherRequest) {
|
|||||||
return str.replace(/[&<>]/g, function(tag) {return tagsToReplace[tag] || tag})
|
return str.replace(/[&<>]/g, function(tag) {return tagsToReplace[tag] || tag})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function unphlow(str) { // Unphlow algorithm implementation
|
||||||
|
var lines=str.split('\n'), line, l = lines.length, i, buf = '', out = []
|
||||||
|
for(i=0;i<l;i++) {
|
||||||
|
line = lines[i].trim() // remove all leading/trailing whitespace-class chars
|
||||||
|
if(line.length) // if the line is not empty, just append it and a whitespace to the buffer
|
||||||
|
buf += line + ' '
|
||||||
|
else { // output logic
|
||||||
|
out.push(buf, '')
|
||||||
|
buf = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(buf.length) // process the remaining output
|
||||||
|
out.push(buf)
|
||||||
|
return out.map(function(s) { // final whitespace sanitation
|
||||||
|
return s.replace(/\s+/g, ' ').trim()
|
||||||
|
}).join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
function gophermapToHTML(gmap, chost, cport) {
|
function gophermapToHTML(gmap, chost, cport) {
|
||||||
if(!cport) cport = 70
|
if(!cport) cport = 70
|
||||||
if(!chost) chost = 'localhost'
|
if(!chost) chost = 'localhost'
|
||||||
@@ -98,13 +116,17 @@ Hi01379 = (function(psGopherRequest) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
else { // assuming text content otherwise
|
else { // assuming text content otherwise
|
||||||
var output = (new TextDecoder).decode(rawdata), ctype = 'text/plain' // defaulting to type 0
|
var output = (new TextDecoder).decode(rawdata), ctype = 'text/plain', // defaulting to type 0
|
||||||
|
wo = '' // wrapper-friendly output
|
||||||
if(type == '1' || type == '7') { // gophermap
|
if(type == '1' || type == '7') { // gophermap
|
||||||
output = gophermapToHTML(output, resource[2], resource[3])
|
output = gophermapToHTML(output, resource[2], resource[3])
|
||||||
ctype = 'text/html'
|
ctype = 'text/html'
|
||||||
|
wo = output
|
||||||
}
|
}
|
||||||
|
else wo = unphlow(output)
|
||||||
successCb({
|
successCb({
|
||||||
content: output,
|
content: output,
|
||||||
|
contentWf: wo,
|
||||||
contentType: ctype,
|
contentType: ctype,
|
||||||
serviceMsg: type + ' ' + resource[1]
|
serviceMsg: type + ' ' + resource[1]
|
||||||
})
|
})
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.0.3",
|
"version": "0.0.4",
|
||||||
"name": "Kopher",
|
"name": "Kopher",
|
||||||
"description": "A Gopher client for KaiOS",
|
"description": "A Gopher client for KaiOS",
|
||||||
"launch_path": "/index.html",
|
"launch_path": "/index.html",
|
||||||
|
|||||||
Reference in New Issue
Block a user