Skip to content

Commit

Permalink
- fixed bug whereby importBookmarks was getting called twice per click
Browse files Browse the repository at this point in the history
- changed popup (and sidepanel) to use the url from the manifest rather than hard coding in multiple places
- updated intro slides to fit in sidepanel
- fix from 1.1 where sometimes findTopicChild sometimes returned a non-topic
- made sidepanel a non-optional permission (there's no warning anyway) and removed prevoiusly added perm request
- squeezed iframe in sidepanel narrower to allow for mouse out event to be caught
- added msg listener in panel so extension and popup can ask if its open
- corrected background handling of sidepanel. Listen on port for close and update action button and try to reestablish connection to panl on startup.
- added pane w button in popup to open sidepanel in corner case where worker was suspended when panel was closed.
- since sidepanel doesn't get focus, handle case where sidepanel window gets focus and check for file version.
  • Loading branch information
tconfrey committed Dec 6, 2024
1 parent 40ff860 commit 3185626
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 99 deletions.
16 changes: 4 additions & 12 deletions app/BTAppNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ class BTAppNode extends BTNode {
const topTopic = (components && components.length) ? components[0] : topic;

// Find or create top node
let topNode = AllNodes.find(node => node && node.topicName() == topTopic);
let topNode = AllNodes.find(node => node && (node.topicName() == topTopic) && (node.isTopic()));
if (!topNode) {
topNode = new BTAppNode(topTopic, null, "", 1);
topNode.createDisplayNode();
Expand All @@ -1014,16 +1014,16 @@ class BTAppNode extends BTNode {
components.shift();
components.forEach((t) => {
let node = currentNode;
currentNode = currentNode.findChild(t);
currentNode = currentNode.findTopicChild(t);
if (!currentNode) {
currentNode = new BTAppNode(t, node.id, "", node.level + 1);
currentNode.createDisplayNode();
}
});

// finally find or create the leaf node
if (currentNode.findChild(topic))
return currentNode.findChild(topic);
if (currentNode.findTopicChild(topic))
return currentNode.findTopicChild(topic);
let newLeaf = new BTAppNode(topic, currentNode.id, "", currentNode.level + 1);
newLeaf.createDisplayNode();
topNode.redisplay(); // since new nodes created
Expand Down Expand Up @@ -1112,16 +1112,8 @@ const Handlers = {
"tabGroupCreated": tabGroupCreated,
"tabGroupUpdated": tabGroupUpdated,
"noSuchNode": noSuchNode, // bg is letting us know we requested action on a non-existent tab or tg
"sidePanelPermission": sidePanelPermission,
};

function sidePanelPermission(data) {
// bg is letting us know if we have permission to open the side panel
if (data.granted) return;
// Not granted, so set the radio button to WINDOW
$('#panelToggle :radio[name=location]').filter(`[value='WINDOW']`).prop('checked', true);
}

// Set handler for extension messaging
window.addEventListener('message', event => {
console.log("BTAppNode received: ", event);
Expand Down
4 changes: 2 additions & 2 deletions app/BTNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ class BTNode {
this._childIds.splice(index, 1);
}

findChild(childTopic) {
findTopicChild(childTopic) {
// does this topic node have this sub topic
const childId = this.childIds.find(id => AllNodes[id].topicName() == childTopic);
const childId = this.childIds.find(id => (AllNodes[id].isTopic () && (AllNodes[id].topicName() == childTopic)));
return childId ? AllNodes[childId] : null;
}

Expand Down
9 changes: 6 additions & 3 deletions app/bt.css
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ a:link {
a:hover {
text-decoration: underline;
}
a:hover.wenk--bottom {
text-decoration: none;
}

html {
background: var(--btEmptyBackground);
Expand Down Expand Up @@ -840,11 +843,11 @@ textarea:focus, input[type="text"]:focus {
#introNext- {
/* caret >> indicator png */
position: relative;
left: 45px;
left: 30px;
}
#introPrev- {
position: relative;
left: -105px;
left: -90px;
}


Expand Down Expand Up @@ -885,7 +888,7 @@ textarea:focus, input[type="text"]:focus {
}
#dontShow {
position: relative;
top: 5px;
top: 3px;
display: none;
}

Expand Down
16 changes: 12 additions & 4 deletions app/bt.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var UpgradeInstall = false;
var GroupingMode = 'TABGROUP'; // or 'NONE'
var MRUTopicPerWindow = {}; // map winId to mru topic
var BTTabId = null; // tabId of BT
var BTWinId = null; // winId of BT
var SidePanel = false; // true if running in side panel => dictates how to send msgs

/***
Expand All @@ -40,6 +41,7 @@ async function launchApp(msg) {
InitialInstall = msg.initial_install;
UpgradeInstall = msg.upgrade_install; // null or value of 'previousVersion'
BTTabId = msg.BTTab; // knowledge of self
BTWinId = msg.BTWin; // got mad knowledge of self
SidePanel = msg.SidePanel;

BTFileText = msg.BTFileText;
Expand Down Expand Up @@ -170,7 +172,7 @@ function updateStats() {
function handleFocus(e) {
// BTTab comes to top

document.activeElement.blur(); // Links w focus interfere w BTs selection so remove
document.activeElement.blur(); // Links w focus interfere w BTs selection so remove
const deletions = handlePendingDeletions(); // handle any pending deletions
if (!deletions) warnBTFileVersion(e); // check file version, warn if stale, NB if deletions then save will overwrite
}
Expand Down Expand Up @@ -1063,13 +1065,13 @@ function tabActivated(data) {
// user switched to a new tab or win, fill in storage for popup's use and select in ui

const tabId = data['tabId'];
const winId = data['windowId'];

if (tabId == BTTabId) {
handleFocus({'reason': 'BTTab activated'}); // special case when the tab is us!
return;
}

const winId = data['windowId'];
const groupId = data['groupId'];
const node = BTAppNode.findFromTab(tabId);
const winNode = BTAppNode.findFromWindow(winId);
Expand All @@ -1086,6 +1088,11 @@ function tabActivated(data) {
clearSelected();
}
sendMessage({'function': 'localStore', 'data': {...m1, ...m2}});

if (SidePanel && (winId == BTWinId)) {
handleFocus({'reason': 'BTTab activated'}); // window w BT Sidepanel got focus
return;
}
}


Expand Down Expand Up @@ -1371,15 +1378,16 @@ function buttonShow(e) {

// Open/close buttons
const node = getActiveNode(e);
if (!node) return;
const topic = node.isTopic() ? node : AllNodes[node.parentId];
$("#openTab").hide();
$("#openWindow").hide();
$("#closeRow").hide();
if (node && node.countOpenableTabs()){
if (node.countOpenableTabs()){
$("#openTab").show();
if (!topic?.hasOpenChildren() || (GroupingMode != 'TABGROUP')) $("#openWindow").show(); // only allow opening in new window if not already in a TG, or not using TGs
}
if (node && node.countClosableTabs()) {
if (node.countClosableTabs()) {
$("#closeRow").show();
}

Expand Down
2 changes: 0 additions & 2 deletions app/configManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,6 @@ const configManager = (() => {
$(document).ready(function () {
$('#panelToggle :radio').change(function () {
const newHome = $(this).val();
if (newHome == 'SIDEPANEL')
sendMessage({'function': 'allowSidePanel'});
configManager.setProp('BTManagerHome', newHome);
// Let extension know
sendMessage({'function': 'localStore', 'data': {'BTManagerHome': newHome}});
Expand Down
2 changes: 1 addition & 1 deletion app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@
<div class="dropdown_content">
<div onClick="importBookmarks()">
<label for="import_bookmarks" class="button_text">Browser Bookmarks</label>
<input id="import_bookmarks" type="button" style="display:none">
<input id="import_bookmarks" type="button" style="display:none" onClick="event.stopPropagation()">
</div>

<div style="border-top: solid 1px #ddd" onClick="$('#org_upload').val('');">
Expand Down
79 changes: 49 additions & 30 deletions extension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@

'use strict';

var Keys;
let Keys;
try {
importScripts('config.js');
} catch (e) {
console.log(e);
Keys = {CLIENT_ID: '', API_KEY: '', FB_KEY: '', STRIPE_KEY: ''};
}

var LocalTest = false; // control code path during unit testing
var InitialInstall = false; // should we serve up the welcome page
var UpdateInstall = false; // or the release notes page
let LocalTest = false; // control code path during unit testing
let InitialInstall = false; // should we serve up the welcome page
let UpdateInstall = false; // or the release notes page
let BTPort = null; // port to side panel
let BTManagerHome = 'WINDOW'; // default to Window

async function btSendMessage(msg) {
// send message to Topic Manager in window, tab or side panel
Expand Down Expand Up @@ -64,6 +65,36 @@ chrome.runtime.onConnect.addListener((port) => {
});
});

function setUpSidepanel() {
// Called at startup and on suspend to set the icon bahavior (panel can only open on 'user action')
if (BTManagerHome === 'SIDEPANEL') {
chrome.action.setPopup({popup: ''});
chrome.action.onClicked.addListener((tab) => {
chrome.sidePanel.open({windowId: tab.windowId});
chrome.action.setPopup({popup: 'popup.html'});
});
}
if (BTManagerHome === 'WINDOW' || BTManagerHome === 'TAB') {
chrome.action.setPopup({popup: 'popup.html'});
}
}
// Immediately executing fn to re-setup side panel after worker suspension
(async function () {
const mHome = await chrome.storage.local.get(['BTManagerHome']);
BTManagerHome = mHome.BTManagerHome || 'WINDOW';
if (BTManagerHome !== 'SIDEPANEL') return;
console.log('asking sidepanel to connect...');
try {
const rsp = await chrome.runtime.sendMessage({'function': 'reconnect'});
console.log('sidepanel connection:', rsp);
if (typeof rsp === 'undefined') setUpSidepanel();
}
catch (e) {
console.log('NA, setting up sidepanel');
setUpSidepanel();
}
})();

async function getBTTabWin(reset = false) {
// read from local storage then cached. reset => topic mgr exit
if (reset) {
Expand Down Expand Up @@ -174,22 +205,13 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {

// NB workaround for bug in Chrome, see https://stackoverflow.com/questions/71520198/manifestv3-new-promise-error-the-message-port-closed-before-a-response-was-rece/71520415#71520415
sendResponse();

console.log(`Background received: [${msg.function}]: ${JSON.stringify(msg)}`);
if (Handlers[msg.function]) {
console.log("Background dispatching to ", msg.function);
Handlers[msg.function](msg, sender);
return;
}
if (msg.function == 'allowSidePanel') {
// request sidebar permission
// NB not using the dispatch cos that loses that its user triggered and Chrome prevents
chrome.permissions.request(
{permissions: ['sidePanel']}, granted => {
btSendMessage({'function': 'sidePanelPermission', 'granted': granted});
});
return;
}

if (msg.type == 'LOCALTEST') {
// Running under test so there is no external BT top level window
chrome.tabs.query({'url' : '*://localhost/test*'}, tabs => {
Expand Down Expand Up @@ -288,8 +310,7 @@ chrome.tabs.onActivated.addListener(logEventWrapper("tabs.onActivated", async (i
chrome.tabs.get(info.tabId, tab => {
check();
if (!tab) return;
btSendMessage({ 'function': 'tabActivated', 'tabId': info.tabId,
'windowId': tab.windowId, 'groupId': tab.groupId});
btSendMessage({ 'function': 'tabActivated', 'tabId': info.tabId, 'groupId': tab.groupId});
setTimeout(function() {setBadge(info.tabId);}, 250);
});
}));
Expand Down Expand Up @@ -349,7 +370,7 @@ chrome.windows.onFocusChanged.addListener(logEventWrapper("windows.onFocusChange
chrome.tabs.query({'active': true, 'windowId': windowId},tabs => {
check();
if (!tabs?.length) return;
btSendMessage({'function': 'tabActivated', 'tabId': tabs[0].id});
btSendMessage({'function': 'tabActivated', 'tabId': tabs[0].id, 'windowId': windowId});
setTimeout(function() {setBadge(tabs[0].id);}, 200);
});
}));
Expand Down Expand Up @@ -447,7 +468,7 @@ async function initializeExtension(msg, sender) {
btSendMessage(
{'function': 'launchApp', 'client_id': Keys.CLIENT_ID,
'api_key': Keys.API_KEY, 'fb_key': Keys.FB_KEY,
'stripe_key': Keys.STRIPE_KEY, 'BTTab': BTTab,
'stripe_key': Keys.STRIPE_KEY, 'BTTab': BTTab, 'BTWin': BTWin,
'initial_install': InitialInstall, 'upgrade_install': UpdateInstall, 'BTVersion': BTVersion,
'all_tabs': allTabs, 'all_tgs': allTGs});

Expand All @@ -458,26 +479,24 @@ async function initializeExtension(msg, sender) {
'https://braintool.org/support/releaseNotes';
chrome.tabs.create({'url': welcomePage},
() => {
chrome.windows.update(BTWin,
{'focused' : true},
() => check());
BTWin && chrome.windows.update(BTWin, {'focused' : true}, () => check());
});
InitialInstall = null; UpdateInstall = null;
}
updateBTIcon('', 'BrainTool', '#59718C'); // was #5E954E
chrome.action.setIcon({'path': 'images/BrainTool128.png'});
if (BTPort)
// if panel is open, turn off close-on-click behavior
chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: false});
}

function suspendExtension() {
// called when the BTWin/BTTab is detected to have been closed
async function suspendExtension() {
// called when the BTWin/BTTab/Sidepanel is detected to have been closed
console.log("suspending service worker");

// re query BTManagerHome, might have changed
const mHome = await chrome.storage.local.get(['BTManagerHome']);
BTManagerHome = mHome.BTManagerHome || 'WINDOW';

setUpSidepanel(); // reset sidepanel to default behavior

chrome.storage.local.get(['BTManagerHome'], async val => {
if (val.BTManagerHome == 'SIDEPANEL')
chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true}); // open side panel on next icon click
});
chrome.storage.local.set({'BTTab': 0, 'BTWin': 0});
getBTTabWin(true); // clear cache
BTPort = null;
Expand Down
2 changes: 0 additions & 2 deletions extension/btContentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ chrome.runtime.onMessage.addListener((msg, sender, response) => {
msg.data = data;
msg["from"] = "btextension";
sendMessage(msg);
/* !!!!!!!!!!!! Release Candidate debugging change. Undo in 1.0 release !!!!!!!!!!!!!
chrome.storage.local.remove('bookmarks'); // clean up space
*/
});
break;
case 'launchApp': // set up btfiletext etc before passing on to app, see below
Expand Down
7 changes: 3 additions & 4 deletions extension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@
"description": "__MSG_appDesc__",
"default_locale": "en",
"version": "1.2",
"permissions": ["tabs", "storage", "tabGroups", "webNavigation", "bookmarks"],
"optional_permissions": ["sidePanel"],
"permissions": ["tabs", "storage", "tabGroups", "webNavigation", "bookmarks", "sidePanel"],

"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"othermatches": ["https://BrainTool.org/app/*"],
"matches": ["http://localhost:8000/*"],
"matches": ["http://localhost:8000/app/*"],
"run_at" : "document_idle",
"js": ["btContentScript.js"]
}
Expand Down
3 changes: 3 additions & 0 deletions extension/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
<p id="upgradeMessage">
<b>Upgrading to BrainTool <span id="upgradeVersion"></span>. <br/>Restart is required. <br/>Release Notes will open with details after restart.</b>
</p>
<p id="sidepanelMessage">
<b>Open BrainTool in the sidepanel?</b>
</p>
<img id="introImage" src="resources/intro.png" width="400"/>
<img id="openingImage" src="resources/opening.png"/>
<button id="okButton">OK</button>
Expand Down
Loading

0 comments on commit 3185626

Please sign in to comment.