Skip to content

Commit

Permalink
Set of changes to allow TM to run in the sidepanel in an iframe: New …
Browse files Browse the repository at this point in the history
…sidepanel.html/js files. BTPort connection to all bg to detect sidepanel close. sendMessage replaces window.postMessage to direct the message to content script or sidepanel container. Removed perms request for bookmarks since its no longer optional. Added perm request for sidepanel (seems to always returns granted). sidepanel.js sends initialize msg when iframe is loaded. General refactor on messaging while updating. New BTManagerHome settings, ui and config manager upates. Unrelated bug fix in column sizing where display:none was mixed with width: 5%
  • Loading branch information
tconfrey committed Nov 26, 2024
1 parent bf23337 commit 6f8f68f
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 147 deletions.
60 changes: 36 additions & 24 deletions app/BTAppNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,13 +530,13 @@ class BTAppNode extends BTNode {
showNode() {
// highlight this nodes associated tab or window
if (this.tabId)
window.postMessage(
sendMessage(
{'function' : 'showNode', 'tabId': this.tabId});
else if (this.tabGroupId)
window.postMessage(
sendMessage(
{'function' : 'showNode', 'tabGroupId': this.tabGroupId});
else if (this.windowId)
window.postMessage(
sendMessage(
{'function' : 'showNode', 'windowId': this.windowId});
}

Expand Down Expand Up @@ -590,11 +590,11 @@ class BTAppNode extends BTNode {
// if we don't care about grouping just open each tab
if (GroupingMode == 'NONE') {
const tabsToOpen = this.listOpenableTabs(); // [{nodeId, url}..}
window.postMessage({'function': 'openTabs', 'tabs': tabsToOpen, 'newWin': newWin});
sendMessage({'function': 'openTabs', 'tabs': tabsToOpen, 'newWin': newWin});
}
else { // need to open all urls in single (possibly new) window
const tabGroupsToOpen = this.listOpenableTabGroups(); // [{tg, [{id, url}]},..]
window.postMessage({'function': 'openTabGroups', 'tabGroups': tabGroupsToOpen,
sendMessage({'function': 'openTabGroups', 'tabGroups': tabGroupsToOpen,
'newWin': newWin});
}
}
Expand All @@ -614,7 +614,7 @@ class BTAppNode extends BTNode {
const index = node?.expectedTabIndex() || 0;
tabInfo.push({'nodeId': id, 'tabId': node.tabId, 'tabIndex': index});
});
window.postMessage({'function': 'groupAndPositionTabs', 'tabGroupId': this.tabGroupId,
sendMessage({'function': 'groupAndPositionTabs', 'tabGroupId': this.tabGroupId,
'windowId': this.windowId, 'tabInfo': tabInfo,
'groupName': this.topicName(), 'topicId': this.id,
});
Expand All @@ -626,15 +626,15 @@ class BTAppNode extends BTNode {
const groupName = this.isTopic() ? this.topicName() : AllNodes[this.parentId]?.topicName();
const groupId = this.isTopic() ? this.id : AllNodes[this.parentId]?.id;
const tgId = this.tabGroupId || AllNodes[this.parentId]?.tabGroupId;
window.postMessage({'function': 'groupAndPositionTabs', 'tabGroupId': tgId,
sendMessage({'function': 'groupAndPositionTabs', 'tabGroupId': tgId,
'windowId': this.windowId, 'tabInfo': [{'nodeId': this.id, 'tabId': this.tabId, 'tabIndex': this.tabIndex}],
'groupName': groupName, 'topicId': groupId,});
}

closeTab() {
// Close tabs associated w this node
if (this.tabId)
window.postMessage({'function': 'closeTab', 'tabId': this.tabId});
sendMessage({'function': 'closeTab', 'tabId': this.tabId});
this.childIds.forEach(id => {
const node = AllNodes[id];
node.closeTab();
Expand Down Expand Up @@ -663,7 +663,7 @@ class BTAppNode extends BTNode {
if (this.hasOpenChildren()) {
const openTabIds = this.childIds.flatMap(
c => AllNodes[c].tabId ? [AllNodes[c].tabId] : []);
window.postMessage({
sendMessage({
'function': 'moveOpenTabsToTG', 'groupName': this.displayTopic,
'tabIds': openTabIds, 'windowId': this.windowId
});
Expand Down Expand Up @@ -1112,12 +1112,22 @@ 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 => {
if (event.source != window || event.functionType == 'AWAIT') // async handled below
return;
console.log("BTAppNode received: ", event);
if (event.source != window && event.source != window.parent) return; // not our business
if (event?.data?.type == 'AWAIT') return; // outbound msg from callBackground
if (event?.data?.type == 'AWAIT_RESPONSE') return; // sync rsp handled below

//console.count(`BTAppNode received: [${JSON.stringify(event)}]`);
if (Handlers[event.data.function]) {
Expand All @@ -1126,23 +1136,25 @@ window.addEventListener('message', event => {
}
});

// Function to send a message to the content script and await a response
// Function to send a message to the content script or side panel and await a response
function callBackground(message) {
return new Promise((resolve) => {
// Send the message to the content script
message.type = "AWAIT";
sendMessage(message);

// Listen for the response from the content script
window.addEventListener("message", function handler(event) {
if (event.source !== window || event.type !== 'AWAIT') {
return;
}

if (event.data && event.data.type === "AWAIT_RESPONSE") {
window.removeEventListener("message", handler);
resolve(event.data.response);
}
if (event?.data?.type !== 'AWAIT_RESPONSE') return; // async handled above
if (event.source != window && event.source != window.parent) return; // not our business
window.removeEventListener("message", handler);
resolve(event.data.response);
});

// Send the message to the content script with the page's origin as targetOrigin
message.type = "AWAIT";
window.postMessage(message, window.origin);
});
}

function sendMessage(message) {
// Send message to extension via contained content script or side panel container
const dest = SidePanel ? window.parent : window;
dest.postMessage(message, '*');
}
68 changes: 42 additions & 26 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 SidePanel = false; // true if running in side panel => dictates how to send msgs

/***
*
Expand All @@ -39,7 +40,8 @@ async function launchApp(msg) {
InitialInstall = msg.initial_install;
UpgradeInstall = msg.upgrade_install; // null or value of 'previousVersion'
BTTabId = msg.BTTab; // knowledge of self

SidePanel = msg.SidePanel;

BTFileText = msg.BTFileText;
processBTFile(); // create table etc

Expand Down Expand Up @@ -240,7 +242,7 @@ async function handleInitialTabs(tabs, tgs) {
if (node) node.groupAndPosition();
});
// remember topic per window for suggestions in popup
window.postMessage({'function': 'localStore', 'data': {'mruTopics': MRUTopicPerWindow}});
sendMessage({'function': 'localStore', 'data': {'mruTopics': MRUTopicPerWindow}});
updateStatsRow();
}

Expand Down Expand Up @@ -346,8 +348,8 @@ function processBTFile(fileText = BTFileText) {
BTAppNode.generateTopics();

// Let extension know about model
window.postMessage({'function': 'localStore', 'data': {'topics': Topics}});
window.postMessage({'function': 'localStore', 'data': {'BTFileText': BTFileText}});
sendMessage({'function': 'localStore', 'data': {'topics': Topics}});
sendMessage({'function': 'localStore', 'data': {'BTFileText': BTFileText}});

// initialize ui from any pre-refresh opened state
OpenedNodes.forEach(oldNode => {
Expand Down Expand Up @@ -380,26 +382,35 @@ function processBTFile(fileText = BTFileText) {
}


// initialize column resizer on startupfunction
/**
* Column resizing functionality
**/

function initializeNotesColumn() {
// when window is too small drop the notes column, also used when set in settings
// set position of the column resizer, read from BTNotes peoperty.
// Above 95% snaps to 100% right aligned offset by 26px width, but when window is narrow thats >5% so 13px
// Called from initial settings and checkCompact after window resize
// Calls out to handleResizer,
const notesPref = configManager.getProp('BTNotes');
const percent = parseInt(notesPref);
$("#resizer").css('left', `calc(${percent}% - 13px`);
const left = (percent >= 95) ? 100 : percent;
const offset = ($(window).width() > 260) ? 26 : 13; // adjust for narrow windows
$("#resizer").css('left', `calc(${left}% - ${offset}px`);
handleResizer();
}
let Resizing = false; // set while resizing in progress to avoid processing other events
function handleResizer() {
// Resizer has been dragged, or during set up
const left = $("#resizer").position().left + 13;
const fullWidth = $(window).width();
const percent = left / fullWidth * 100;
const percent = parseInt(left / fullWidth * 100);

if (percent < 95) {
$("#content").addClass('showNotes').removeClass('hideNotes');
$("td.left").css("width", percent + "%");
$("td.right").css("width", (100 - percent) + "%");
$("td.right").css("display", "table-cell");
} else {
$("td.right").css("display", "none");
$("#content").addClass('hideNotes').removeClass('showNotes');
}
}
$("#resizer").draggable({
Expand All @@ -412,7 +423,7 @@ $("#resizer").draggable({
stop: () => setTimeout(() => {
const left = $("#resizer").position().left + 13;
const fullWidth = $(window).width();
const percent = left / fullWidth * 100;
const percent = parseInt(left / fullWidth * 100);
configManager.setProp('BTNotes', percent); // save the new width, BTNotes = NOTES, NONOTES or % width
handleResizer();
Resizing = false;
Expand All @@ -430,6 +441,10 @@ function displayNotesForSearch() {
}
}

/**
* General UI Setup
*/

function initializeUI() {
//DRY'ing up common event stuff needed whenever the tree is modified
console.log('Initializing UI');
Expand Down Expand Up @@ -662,7 +677,7 @@ function moveNode(dragNode, dropNode, oldParentId, browserAction = false) {
// update the rest of the app, backing store
saveBT();
BTAppNode.generateTopics();
window.postMessage({'function': 'localStore', 'data': {'topics': Topics }});
sendMessage({'function': 'localStore', 'data': {'topics': Topics }});
}

function positionNode(dragNode, dropParentId, dropBelow) {
Expand Down Expand Up @@ -934,9 +949,9 @@ function saveTabs(data) {
// update topic list, sync extension, reset ui and save changes.
BTAppNode.generateTopics();
let lastTopicNode = Array.from(changedTopicNodes).pop();
window.postMessage({'function': 'localStore',
sendMessage({'function': 'localStore',
'data': { 'topics': Topics, 'mruTopics': MRUTopicPerWindow, 'currentTopic': lastTopicNode?.topicName() || '', 'currentText': note}});
window.postMessage({'function' : 'brainZoom', 'tabId' : data.tabs[0].tabId});
sendMessage({'function' : 'brainZoom', 'tabId' : data.tabs[0].tabId});

initializeUI();
saveBT();
Expand Down Expand Up @@ -1070,7 +1085,7 @@ function tabActivated(data) {
m1 = {'currentTopic': '', 'currentText': '', 'currentTitle': '', 'tabNavigated': false};
clearSelected();
}
window.postMessage({'function': 'localStore', 'data': {...m1, ...m2}});
sendMessage({'function': 'localStore', 'data': {...m1, ...m2}});
}


Expand Down Expand Up @@ -1355,7 +1370,7 @@ function buttonShow(e) {
$("#buttonRow span").removeClass("wenk--right").addClass("wenk--left");

// Open/close buttons
const node = getActiveNode(e);open
const node = getActiveNode(e);
const topic = node.isTopic() ? node : AllNodes[node.parentId];
$("#openTab").hide();
$("#openWindow").hide();
Expand Down Expand Up @@ -1626,11 +1641,12 @@ function deleteNode(id) {
propogateClosed(parent.parentId); // recurse
}

// Ungroup and highlight the tab if it's open and the Topic Manager is in side panel, otherwise we leave the TMgr tab
// Highlight the tab if it's open and the Topic Manager is not TAB (jarring to swap active tabs)
// (good user experience and side effect is to update the tabs badge info
const BTHome = configManager.getProp('BTManagerHome');
if (node.tabId && (BTHome == 'TAB'))
if (node.tabId && (BTHome !== 'TAB'))
node.showNode();
// Ungroup if topic w open tabs
if (openTabs.length) {
const tabIds = openTabs.map(t => t.tabId);
callBackground({'function': 'ungroup', 'tabIds': tabIds});
Expand All @@ -1645,7 +1661,7 @@ function deleteNode(id) {
// if wasTopic remove from Topics and update extension
if (wasTopic) {
BTAppNode.generateTopics();
window.postMessage({'function': 'localStore', 'data': {'topics': Topics }});
sendMessage({'function': 'localStore', 'data': {'topics': Topics }});
}

// Update File
Expand Down Expand Up @@ -1683,7 +1699,7 @@ function updateRow() {

// Update extension
BTAppNode.generateTopics();
window.postMessage({'function': 'localStore', 'data': {'topics': Topics }});
sendMessage({'function': 'localStore', 'data': {'topics': Topics }});
console.count('BT-OUT: Topics updated to local store');

// reset ui
Expand Down Expand Up @@ -1728,7 +1744,7 @@ function promote(e) {
// save to file, update Topics etc
saveBT();
BTAppNode.generateTopics();
window.postMessage({'function': 'localStore', 'data': {'topics': Topics }});
sendMessage({'function': 'localStore', 'data': {'topics': Topics }});
}

function _displayForEdit(newNode) {
Expand Down Expand Up @@ -1807,7 +1823,7 @@ async function processImport(nodeId) {
function importBookmarks() {
// Send msg to result in subsequent loadBookmarks, set waiting status and close options pane
$('body').addClass('waiting');
window.postMessage({'function': 'getBookmarks'});
sendMessage({'function': 'getBookmarks'});
}

function loadBookmarks(msg) {
Expand Down Expand Up @@ -1884,12 +1900,12 @@ function exportBookmarks() {
return {'displayTopic': n.displayTopic, 'URL': n.URL, 'parentId': n.parentId, 'childIds': n.childIds.slice()};
});
const dateString = getDateString().replace(':', '∷'); // 12:15 => :15 is a sub topic
window.postMessage({'function': 'localStore',
sendMessage({'function': 'localStore',
'data': {'AllNodes': nodeList,
title: 'BrainTool Export ' + dateString}});

// wait briefly to allow local storage too be written before background tries to access
setTimeout(() => window.postMessage({'function': 'exportBookmarks'}), 100);
setTimeout(() => sendMessage({'function': 'exportBookmarks'}), 100);
gtag('event', 'BookmarkExport', {'event_category': 'Export'});
}

Expand All @@ -1904,7 +1920,7 @@ function groupingUpdate(from, to) {

function importSession() {
// Send msg to result in subsequent session save
window.postMessage({'function': 'saveTabs', 'type': 'Session', 'topic': '', 'from':'btwindow'});
sendMessage({'function': 'saveTabs', 'type': 'Session', 'topic': '', 'from':'btwindow'});
}

/***
Expand Down Expand Up @@ -2468,6 +2484,6 @@ function undo() {
initializeUI();
saveBT();
BTAppNode.generateTopics();
window.postMessage({'function': 'localStore', 'data': {'topics': Topics }});
sendMessage({'function': 'localStore', 'data': {'topics': Topics }});

}
Loading

0 comments on commit 6f8f68f

Please sign in to comment.