Prototype: Chrome extension to facilitate viewer context

Challenge

Automations are unaware of viewer context (user viewing, entity being viewed), apart from ‘user who clicked button’ or ‘user who triggered rule’. Even when the user is identified, the currently viewed entity is unknown. Also, with multiple panels open this is an issue. However, if we could include viewer context it would open up many possibilities.

Can Fibery integrate it so we don’t need a browser extension?

Yes. But its not done yet, likely because of prioritization of Fibery’s product goals, and incorporating real-time, context-aware features into an existing platform can be technically challenging, requiring changes to the backend infrastructure, frontend UI, and possibly the data model.

Strategy

What comes closest to having viewer context, is the event of displaying a new entity, either through opening it single panel or as right panel, or as new browser window. We make the extension click a button when we navigate to a new entity. The button class as well as the active panel its class is identified. Approach:

  1. Dynamic DOM handling for Fibery’s multi-panel pages
  2. Real-time updates synchronization
  3. Cross-origin communication management
  4. Event detection and handling, including panel expansions
  5. MutationObserver usage for DOM changes
  6. Integration of background script for page navigation

Relation

Button automation

Prototype chrome extension (working)

manifest.json

  • Defines extension metadata: name, version, permissions.
  • Lists permissions: activeTab, tabs, <all_urls>, webNavigation for broad access and control.
  • Specifies content_scripts to run content.js on pages matching https://cce.fibery.io/*.
  • Declares background.js as the service worker for handling background tasks.

content.js

  • Executes in the context of web pages matching specified patterns.
  • Tracks URL changes to detect navigation to new panels within Fibery.
  • Searches for and clicks a specific button when a new panel is detected, automating user interaction.
  • Utilizes MutationObserver to monitor DOM changes for real-time response to page updates.

background.js

  • Operates in the background, across all browser tabs.
  • Utilizes chrome.webNavigation.onHistoryStateUpdated to listen for SPA navigation events (like URL changes without page reloads).
  • Sends messages to content.js in response to detected navigation events, coordinating actions based on global browser activity.
  • Essential for actions requiring broader permissions and for maintaining state or performing complex logic independently of page content.

manifest.json

{
    "manifest_version": 3,
    "name": "Push Viewer Button",
    "version": "1.0",
    "permissions": ["activeTab", "tabs", "<all_urls>", "webNavigation"],
    "content_scripts": [
        {
            "matches": ["https://cce.fibery.io/*"],
            "js": ["content.js"]
        }
    ],
    "background": {
        "service_worker": "background.js"
    }
}

content.js

console.log("Extension's content script running.");

let lastUrl = window.location.href; // Track the last URL to detect changes.

// Function to perform the action of clicking the button
function clickButton() {
    const currentUrl = window.location.href;

    // Find the button in the right panel using the unique class 'pm4e4im'.
    const buttonElement = document.querySelector('.pm4e4im .b1vmzo6x.UserButton.button.ssfkgvv.button_base.s1gbjppn');

    // Check if the button exists and the URL has changed, indicating a new panel.
    if (buttonElement && lastUrl !== currentUrl) {
        console.log("New panel detected and button found. Clicking...");
        buttonElement.click();
        lastUrl = currentUrl; // Update the last URL to the current one.
    } else if (!buttonElement) {
        console.log("Button not found in the right panel.");
    } else {
        console.log("No significant change detected. No click performed.");
    }
}

// Use a MutationObserver to detect when changes occur in the DOM.
function initObserver() {
    const observer = new MutationObserver((mutations) => {
        clickButton(); // Attempt to click the button upon detecting mutations.
    });

    const config = { childList: true, subtree: true };
    observer.observe(document.body, config);
    console.log("MutationObserver initialized to monitor DOM changes.");
}

initObserver();

background.js

// background.js
chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
    console.log('Page uses History API and we heard a pushState/replaceState.', details);
    // Send a message to the content script
    chrome.tabs.sendMessage(details.tabId, { action: "navigate" });
}, {url: [{urlMatches : 'https://cce.fibery.io/'}]});

The result

chrome_OXUCQOlofL

3 Likes

Thanks for sharing this. Been meaning to look into what it takes to build a Chrome Extension since I already have made a handful of userscripts.

Pretty much everything I’ve wanted in Fibery has been added except for customizable entity views (see Airtable interface designer). Entity views are currently a major weak point IMO.

1 Like

They’re coming :crossed_fingers:

5 Likes