commit 28359eb8894be37d43b66c16fd119c5a67fe963b
parent 5ce5069a70685d5789a3eb5a530b8f8cb1c29139
Author: Luxferre <lux@ferre>
Date: Sat, 1 Apr 2023 15:08:55 +0300
Implemented Unflow for plaintext content
Diffstat:
4 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
@@ -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")
- 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 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)
- Up to 10 numbered bookmarks plus customizable homepage
- Binary blob downloads (see "Downloads")
diff --git a/js/app.js b/js/app.js
@@ -99,6 +99,8 @@ addEventListener('DOMContentLoaded', function() {
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
logoStatus.textContent = logoLoadingChar
statusBar.textContent = 'Loading ' + url
@@ -108,14 +110,18 @@ addEventListener('DOMContentLoaded', function() {
var updateHistory = !('updateAddr' in res && res.updateAddr === false), // true by default
updateContent = !(res.content === null) // true by default
if(updateContent) { // update the content zone
+ activeContent.nowrap = res.content
+ activeContent.wrap = res.contentWf || res.content
contentZone.innerHTML = ''
contentZone.textContent = ''
contentZone.dataset.wrap = 0 // reset line wrapping
if(res.contentType === 'text/plain') {
+ activeContent.prop = 'textContent'
contentZone.dataset.format='plain'
- contentZone.textContent = res.content
+ contentZone.textContent = activeContent.nowrap
} else {
contentZone.dataset.format='native'
+ activeContent.prop='innerHTML'
contentZone.innerHTML = res.content
var contentLinks = contentZone.querySelectorAll('a'), l = contentLinks.length, i
for(i=0;i<l;i++) { // dynamically index all the links in the rendered content
@@ -203,6 +209,8 @@ addEventListener('DOMContentLoaded', function() {
break
case '6': // toggle line wrapping
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
case 'Call': // refresh
loadURL(currentUrl, true)
diff --git a/js/hi01379.js b/js/hi01379.js
@@ -10,6 +10,24 @@ Hi01379 = (function(psGopherRequest) {
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) {
if(!cport) cport = 70
if(!chost) chost = 'localhost'
@@ -98,13 +116,17 @@ Hi01379 = (function(psGopherRequest) {
})
}
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
output = gophermapToHTML(output, resource[2], resource[3])
ctype = 'text/html'
+ wo = output
}
+ else wo = unphlow(output)
successCb({
content: output,
+ contentWf: wo,
contentType: ctype,
serviceMsg: type + ' ' + resource[1]
})
diff --git a/manifest.webapp b/manifest.webapp
@@ -1,5 +1,5 @@
{
- "version": "0.0.3",
+ "version": "0.0.4",
"name": "Kopher",
"description": "A Gopher client for KaiOS",
"launch_path": "/index.html",