From 333f7de339f2e98ae3b9cfc64cf03f48c8bd7560 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Thu, 28 May 2020 13:52:58 -0700 Subject: [PATCH 1/4] Maintain scroll position (by fixed amount) or auto-scroll as needed. This is a functional hack that needs improvement later. --- index.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 0e81dec..2faa147 100644 --- a/index.js +++ b/index.js @@ -116,14 +116,16 @@ function log(text = "", type = mStat, socket = null, direction = 0) { if (type & mdLog) { //Send to Launcher log view let logView = $('log'); - //Note scroll position (to see if user has scrolled up), append message, then auto-scroll (down) if bottom was previously in view -// console.log(logView.scrollTop); - let scrollTop = logView.scrollTop; - let scroll = (scrollTop+1 >= logView.scrollHeight-logView.clientHeight); + //Note scroll position to maintain current view (user-set or auto-scroll) + let scrollPosition = logView.scrollTop; + let autoScroll = (scrollPosition+1 >= logView.scrollHeight-logView.clientHeight); + //Add log message, delete oldest (if necessary), update display, and reposition view (if necessary) logLines.push(stamp(verboseLogging) + text + '
'); - if (logLines.length > 250) {logLines.shift()} + let logIsMax = logLines.length > 250; + //TODO adjust scrollPosition by calculated line height + if (logIsMax) {logLines.shift(); scrollPosition -= 12;} logView.innerHTML = logLines.join(''); - if (scroll) {logView.scrollTo(0, logView.scrollHeight)} //else {if (scrollTop !== logView.ScrollTop) {logView.scrollTo(0, scrollTop-(logView.scrollTop-scrollTop))}} + if (autoScroll) {logView.scrollTo(0, logView.scrollHeight)} else {if (logIsMax) {logView.scrollTo(0, scrollPosition)}} } //Send to Launcher console window if (type & mdConsole) {console.log(stamp(true) + text)} @@ -214,6 +216,7 @@ document.addEventListener('DOMContentLoaded', function() { } }) } else { + log('Launcher settings unavailable - using defaults', mDbug); $('bpc-port').value = defaultPort; $('bpc-url').value = defaultURL; $('sm0').value = defaultSM0; @@ -338,7 +341,7 @@ function sm32bit() { function storageError() { // Log Chrome Storage error - log("Settings Error: " + chrome.runtime.lastError, mDbug); + log("Launcher Settings Error: " + chrome.runtime.lastError, mDbug); } function connect() { From 9d7c01df643e4a01257fb03abc2e0882134f0175 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 30 May 2020 09:10:20 -0700 Subject: [PATCH 2/4] Partial implementation of socket-specific preferred port setting and send-on-pref-port message. --- index.js | 84 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/index.js b/index.js index 2faa147..892d651 100644 --- a/index.js +++ b/index.js @@ -322,9 +322,12 @@ document.addEventListener('DOMContentLoaded', function() { setTimeout(connect, 500); }); -function updatePreferredPort(port) { -// Remember new preferred port (if not null) - if (port && port !== preferredPort.name) { +function updatePreferredPort(port, socket) { +/* Remember new preferred port (if not null). + Returns true if port is new; false otherwise. + socket is the sender associated with this request. */ + let isNewPort = (port) && (port !== preferredPort.name); + if (isNewPort) { preferredPort.name = port; if (chrome.storage) { chrome.storage.sync.set({'pref_port': preferredPort.name}, function () {if (chrome.runtime.lastError) {storageError()}}); @@ -332,6 +335,7 @@ function updatePreferredPort(port) { // A "new" port selection was made; set all existing ports to non-new status clearNewPortStatus(); } + return isNewPort; } function sm32bit() { @@ -404,16 +408,16 @@ function connect_ws(ws_port, url_path) { if (ws_msg.type === "load-prop") { // load the propeller log('Received Propeller Application for ' + ws_msg.action, mDbug, socket, 1); - updatePreferredPort(ws_msg.portPath); + updatePreferredPort(ws_msg.portPath, socket); setTimeout(function() {loadPropeller(socket, ws_msg.portPath, ws_msg.action, ws_msg.payload, ws_msg.debug)}, 10); // success is a JSON that the browser generates and expects back to know if the load was successful or not } else if (ws_msg.type === "serial-terminal") { // open or close the serial port for terminal/debug - updatePreferredPort(ws_msg.portPath); + updatePreferredPort(ws_msg.portPath, socket); serialTerminal(socket, ws_msg.action, ws_msg.portPath, ws_msg.baudrate, ws_msg.msg); // action is "open", "close" or "msg" } else if (ws_msg.type === "pref-port") { // user selected a new preferred port - updatePreferredPort(ws_msg.portPath); log('User selected preferred port: ' + ws_msg.portPath, mDbug, socket, 1); + updatePreferredPort(ws_msg.portPath, socket); } else if (ws_msg.type === "port-list-request") { // send an updated port list (and continue on scheduled interval) log('Site requested port list', mDbug, socket, 1); @@ -451,9 +455,9 @@ function connect_ws(ws_port, url_path) { // Port Lister management functions // The Port Lister items are timers (and sockets) to automatically send wired/wireless port updates to connected browser sockets function addPortLister(socket) { -//Create new port lister (to send port lists to browser on a timed interval). +//Create new port lister (to send port lists to browser on a timed interval) using last saved preferred port as the default. //socket is the browser socket to send updates to. - startPortListerScanner(portLister.push({socket: socket})-1); + startPortListerScanner(portLister.push({socket: socket, prefPort: preferredPort})-1); } function startPortListerScanner(idx) { @@ -580,10 +584,10 @@ function scanWXPorts() { } function sendPortList(socket) { -/* Send current list of communication ports to browser via socket. +/* Send list of current communication ports to browser via socket. (See "Launcher Communication Port Rules," above, for detailed rules and scenarios this function (and ports.js and index.js) implements.) - List is ordered as: blank (rarely) or preferred (if any) followed by sorted... new wired, old wired, new wireless, then old wireless ports. - New means newly-arrived (since last port selection changed); old means existing since before last port selection changed.*/ + List is ordered as: blank (rarely) or preferred (if any) followed by individually sorted groups of new wired, old wired, new wireless, then old wireless ports. + "New" means newly-arrived (since last port selection changed); "old" means existing since before last port selection changed.*/ let bp = []; // Either empty (common) or blank string (rarely) let pp = []; // Peferred port name (qty 0 or 1) let nwp = []; // New wired port name list (often qty 0 or 1) @@ -591,35 +595,39 @@ function sendPortList(socket) { let nwlp = []; // New wireless port name list (=> 0) let owlp = []; // Old Wireless port (=> 0) let qty = 0; // Quantity of ports found - - // gather separated port lists (preferred port (if any), new wired/wireless ports (if any), old wired/wireless ports, then sort them) - ports.forEach(function(p) { - if (p.name === preferredPort.name) { - pp.push(p.name) - } else { - if (p.isWired) { - if (p.new) {nwp.push(p.name)} else {owp.push(p.name)} + let lister = portLister.find(function(p) {return p.socket === socket}); //Find the portLister object that belongs to this socket + + if (lister) { + // Found our required lister object + // gather separated port lists (preferred port (if any), new wired/wireless ports (if any), old wired/wireless ports, then sort them) + ports.forEach(function(p) { + if (p.name === lister.prefPort.name) { + pp.push(p.name) } else { - if (p.new) {nwlp.push(p.name)} else {owlp.push(p.name)} + if (p.isWired) { + if (p.new) {nwp.push(p.name)} else {owp.push(p.name)} + } else { + if (p.new) {nwlp.push(p.name)} else {owlp.push(p.name)} + } } - } - }); - nwp.sort(); - owp.sort(); - nwlp.sort(); - owlp.sort(); - qty = pp.length+nwp.length+owp.length+nwlp.length+owlp.length; - - // Remember when the preferredPort exists; otherwise if preferredPort just disappeared, clear all "new" port statuses - we only care about new-arrivals since last preferred port selection - if (pp.length) {preferredPort.exists = true} else {if (preferredPort.exists) {preferredPort.exists = false; clearNewPortStatus();}} - - // report back to editor; blank (rarely), preferred port first (if any), new wired ports (if any), old wired ports, new wireless ports (if any), and finally old wireless ports - if (qty && !pp.length && !nwp.length) {bp.push("")} // Send leading blank port only if > 0 ports found, none match the preferred port, and there are no new wired ports - var msg_to_send = {type:'port-list',ports:bp.concat(pp.concat(nwp.concat(owp.concat(nwlp.concat(owlp)))))}; - - log('Sending port list' + (!verboseLogging ? ' (qty '+qty+')' : ': ' + msg_to_send.ports.toString()), mDbug, socket, -1); - socket.send(JSON.stringify(msg_to_send)); - if (chrome.runtime.lastError) {log(chrome.runtime.lastError, mDbug)} + }); + nwp.sort(); + owp.sort(); + nwlp.sort(); + owlp.sort(); + qty = pp.length+nwp.length+owp.length+nwlp.length+owlp.length; + + // Remember when the preferredPort exists; otherwise if preferredPort just disappeared, clear all "new" port statuses - we only care about new-arrivals since last preferred port selection + if (pp.length) {preferredPort.exists = true} else {if (preferredPort.exists) {preferredPort.exists = false; clearNewPortStatus();}} + + // report back to editor; blank (rarely), preferred port first (if any), new wired ports (if any), old wired ports, new wireless ports (if any), and finally old wireless ports + if (qty && !pp.length && !nwp.length) {bp.push("")} // Send leading blank port only if > 0 ports found, none match the preferred port, and there are no new wired ports + var msg_to_send = {type:'port-list',ports:bp.concat(pp.concat(nwp.concat(owp.concat(nwlp.concat(owlp)))))}; + + log('Sending port list' + (!verboseLogging ? ' (qty '+qty+')' : ': ' + msg_to_send.ports.toString()), mDbug, lister.socket, -1); + lister.socket.send(JSON.stringify(msg_to_send)); + if (chrome.runtime.lastError) {log(chrome.runtime.lastError, mDbug)} + } } From 4b4cd8dad8f3b775d936bd03f6a2e533b8291ffc Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 30 May 2020 11:24:11 -0700 Subject: [PATCH 3/4] Finalized socket-specific preferred port setting and send-port-list-on-new-pref-port-message feature. --- index.js | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/index.js b/index.js index 892d651..61c895c 100644 --- a/index.js +++ b/index.js @@ -176,7 +176,7 @@ var wxEnableDelay = null; // Default logging and preferred port (could be overridden by stored setting) var verboseLogging = defaultVerboseLogging; -var preferredPort = [{name: '', exists: false}]; +var storedPreferredPort = ''; document.addEventListener('DOMContentLoaded', function() { @@ -208,7 +208,7 @@ document.addEventListener('DOMContentLoaded', function() { $('wx-allow').checked = (result.en_wx !== undefined) ? result.en_wx : defaultWX; verboseLogging = (result.en_vlog !== undefined) ? result.en_vlog : defaultVerboseLogging; $('verbose-logging').checked = verboseLogging; - preferredPort.name = (result.pref_port !== undefined) ? result.pref_port : ''; + storedPreferredPort = (result.pref_port !== undefined) ? result.pref_port : ''; // Save subnet mask for future comparison (must be done here because chrome.storage.sync is asynchronous) sm = sm32bit(); } else { @@ -225,7 +225,7 @@ document.addEventListener('DOMContentLoaded', function() { $('sm3').value = defaultSM3; $('wx-allow').checked = defaultWX; $('verbose-logging').checked = defaultVerboseLogging; - preferredPort.name = ''; + storedPreferredPort = ''; // Save subnet mask for future comparison sm = sm32bit(); } @@ -324,18 +324,27 @@ document.addEventListener('DOMContentLoaded', function() { function updatePreferredPort(port, socket) { /* Remember new preferred port (if not null). - Returns true if port is new; false otherwise. - socket is the sender associated with this request. */ - let isNewPort = (port) && (port !== preferredPort.name); - if (isNewPort) { - preferredPort.name = port; - if (chrome.storage) { - chrome.storage.sync.set({'pref_port': preferredPort.name}, function () {if (chrome.runtime.lastError) {storageError()}}); - } - // A "new" port selection was made; set all existing ports to non-new status - clearNewPortStatus(); - } - return isNewPort; + Returns true if port is new (to this socket); false otherwise. + socket (required) is the sender associated with this request. */ + let isNewPort = false; + if (port) { + // First, store in settings if new + if (port !== storedPreferredPort) { + storedPreferredPort = port; + if (chrome.storage) { + chrome.storage.sync.set({'pref_port': storedPreferredPort}, function () {if (chrome.runtime.lastError) {storageError()}}); + } + } + // Next, set as preferred for this socket, if new (for this socket) + let lister = portLister.find(function(p) {return p.socket === socket}); //Find the portLister object that belongs to this socket + isNewPort = (lister) && (lister.prefPort.name !== port); + if (isNewPort) { + lister.prefPort = {name: port, exists: true}; + // Since a new port selection was made, set all existing ports to non-new status - applies globally to all connected browsers (sockets) + clearNewPortStatus(); + } + } + return isNewPort; } function sm32bit() { @@ -417,7 +426,7 @@ function connect_ws(ws_port, url_path) { } else if (ws_msg.type === "pref-port") { // user selected a new preferred port log('User selected preferred port: ' + ws_msg.portPath, mDbug, socket, 1); - updatePreferredPort(ws_msg.portPath, socket); + if (updatePreferredPort(ws_msg.portPath, socket)) {sendPortList(socket)}; } else if (ws_msg.type === "port-list-request") { // send an updated port list (and continue on scheduled interval) log('Site requested port list', mDbug, socket, 1); @@ -457,7 +466,7 @@ function connect_ws(ws_port, url_path) { function addPortLister(socket) { //Create new port lister (to send port lists to browser on a timed interval) using last saved preferred port as the default. //socket is the browser socket to send updates to. - startPortListerScanner(portLister.push({socket: socket, prefPort: preferredPort})-1); + startPortListerScanner(portLister.push({socket: socket, prefPort: {name: storedPreferredPort, exists: false}})-1); } function startPortListerScanner(idx) { @@ -585,7 +594,7 @@ function scanWXPorts() { function sendPortList(socket) { /* Send list of current communication ports to browser via socket. - (See "Launcher Communication Port Rules," above, for detailed rules and scenarios this function (and ports.js and index.js) implements.) + (See "Launcher Communication Port Rules," above, for detailed rules and scenarios that this function (and ports.js and index.js) implements.) List is ordered as: blank (rarely) or preferred (if any) followed by individually sorted groups of new wired, old wired, new wireless, then old wireless ports. "New" means newly-arrived (since last port selection changed); "old" means existing since before last port selection changed.*/ let bp = []; // Either empty (common) or blank string (rarely) @@ -595,8 +604,9 @@ function sendPortList(socket) { let nwlp = []; // New wireless port name list (=> 0) let owlp = []; // Old Wireless port (=> 0) let qty = 0; // Quantity of ports found - let lister = portLister.find(function(p) {return p.socket === socket}); //Find the portLister object that belongs to this socket + //Find the portLister object that belongs to this socket + let lister = portLister.find(function(p) {return p.socket === socket}); if (lister) { // Found our required lister object // gather separated port lists (preferred port (if any), new wired/wireless ports (if any), old wired/wireless ports, then sort them) @@ -617,8 +627,8 @@ function sendPortList(socket) { owlp.sort(); qty = pp.length+nwp.length+owp.length+nwlp.length+owlp.length; - // Remember when the preferredPort exists; otherwise if preferredPort just disappeared, clear all "new" port statuses - we only care about new-arrivals since last preferred port selection - if (pp.length) {preferredPort.exists = true} else {if (preferredPort.exists) {preferredPort.exists = false; clearNewPortStatus();}} + // Remember when the preferred port exists; otherwise if preferred port just disappeared, clear all "new" port statuses - we only care about new-arrivals since last preferred port selection + if (pp.length) {lister.prefPort.exists = true} else {if (lister.prefPort.exists) {lister.prefPort.exists = false; clearNewPortStatus();}} // report back to editor; blank (rarely), preferred port first (if any), new wired ports (if any), old wired ports, new wireless ports (if any), and finally old wireless ports if (qty && !pp.length && !nwp.length) {bp.push("")} // Send leading blank port only if > 0 ports found, none match the preferred port, and there are no new wired ports From 8c86afb8136e883c6e7ab5ee99649d51f83d2edc Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 30 May 2020 11:31:20 -0700 Subject: [PATCH 4/4] Bumped to v1.0.4 --- manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.json b/manifest.json index 22ceec2..662351a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "BlocklyProp Launcher", "description": "A Chrome application that connects your Propeller-Powered Hardware to the BlocklyProp website.", - "version": "1.0.3", + "version": "1.0.4", "manifest_version": 2, "minimum_chrome_version": "45",