Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 76 additions & 55 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 + '<br>');
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)}
Expand Down Expand Up @@ -174,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() {

Expand Down Expand Up @@ -206,14 +208,15 @@ 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 {
storageError();
}
})
} else {
log('Launcher settings unavailable - using defaults', mDbug);
$('bpc-port').value = defaultPort;
$('bpc-url').value = defaultURL;
$('sm0').value = defaultSM0;
Expand All @@ -222,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();
}
Expand Down Expand Up @@ -319,16 +322,29 @@ document.addEventListener('DOMContentLoaded', function() {
setTimeout(connect, 500);
});

function updatePreferredPort(port) {
// Remember new preferred port (if not null)
if (port && port !== preferredPort.name) {
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();
}
function updatePreferredPort(port, socket) {
/* Remember new preferred port (if not null).
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() {
Expand All @@ -338,7 +354,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() {
Expand Down Expand Up @@ -401,16 +417,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);
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);
Expand Down Expand Up @@ -448,9 +464,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: {name: storedPreferredPort, exists: false}})-1);
}

function startPortListerScanner(idx) {
Expand Down Expand Up @@ -577,10 +593,10 @@ function scanWXPorts() {
}

function sendPortList(socket) {
/* Send current list of 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.*/
/* Send list of current communication ports to browser via socket.
(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)
let pp = []; // Peferred port name (qty 0 or 1)
let nwp = []; // New wired port name list (often qty 0 or 1)
Expand All @@ -589,34 +605,39 @@ function sendPortList(socket) {
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)}
//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)
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 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
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)}
}
}


Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -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",

Expand Down