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
14 changes: 14 additions & 0 deletions src/background/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {openExtensionPage} from "../shared/utils.js";
// import * as settingsStorage from "../shared/settings.js";

// first sorts files by run-at value, then by weight value
Expand Down Expand Up @@ -458,3 +459,16 @@ browser.runtime.onMessage.addListener(handleMessage);
browser.tabs.onActivated.addListener(setBadgeCount);
browser.windows.onFocusChanged.addListener(setBadgeCount);
browser.webNavigation.onCompleted.addListener(setBadgeCount);

// handle native app messages
const port = browser.runtime.connectNative();
port.onMessage.addListener(message => {
// console.info(message); // DEBUG
if (message.name === "SAVE_LOCATION_CHANGED") {
openExtensionPage();
if (message?.userInfo?.returnApp === true) browser.runtime.sendNativeMessage({name: "OPEN_APP"});
}
// if (message.name === "OPEN_EXTENSION_PAGE") {
// openExtensionPage();
// }
});
9 changes: 9 additions & 0 deletions src/page/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@
items.set(files);
state.remove("items-loading");
});

// handle native app messages
const port = browser.runtime.connectNative();
port.onMessage.addListener(message => {
// console.info(message); // DEBUG
if (message.name === "SAVE_LOCATION_CHANGED") {
window.location.reload();
}
});
</script>

<svelte:window on:keydown={preventKeyCommands} on:resize={windowResize}/>
Expand Down
10 changes: 1 addition & 9 deletions src/page/Components/Settings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,7 @@

// called when the user clicks the icon next to the save location link
async function changeSaveLocation() {
const m = "Changing the save location requires all instances of the extension to be closed and the host application to be opened. This will be automatically attempted.\n\nDo you wish to continue?";
if (!window.confirm(m)) return;
window.open("userscriptsurlscheme://changesavelocation");
// close all open extension pages
const url = window.location.href;
const close = [];
const tabs = await browser.tabs.query({});
tabs.forEach(tab => tab.url === url && close.push(tab.id));
if (close.length > 0) browser.tabs.remove(close);
browser.runtime.sendNativeMessage({name: "CHANGE_SAVE_LOCATION"});
}
</script>

Expand Down
30 changes: 13 additions & 17 deletions src/popup/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import iconUpdate from "../shared/img/icon-update.svg?raw";
import iconClear from "../shared/img/icon-clear.svg?raw";
import iconRefresh from "../shared/img/icon-refresh.svg?raw";
import {extensionPaths, openExtensionPage} from "../shared/utils.js";
import * as settingsStorage from "../shared/settings.js";

const extensionPageUrl = browser.runtime.getURL("dist/entry-page.html");
let errorNotification;
let active = true;
let loading = true;
Expand Down Expand Up @@ -149,19 +149,6 @@
initialize();
}

async function openExtensionPage() {
const tabs = await browser.tabs.query({});
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].url === extensionPageUrl) {
await browser.windows.update(tabs[i].windowId, {focused: true});
await browser.tabs.update(tabs[i].id, {active: true});
window.close();
return;
}
}
await browser.tabs.create({url: extensionPageUrl});
}

async function shouldCheckForUpdates() {
// if there's no network connectivity, do not check for updates
if (!window || !window.navigator || !window.navigator.onLine) {
Expand Down Expand Up @@ -281,7 +268,9 @@
disabled = false;
return;
}
if (url === extensionPageUrl) {
// strip fragments and query params
const strippedUrl = url.split(/[?#]/)[0];
if (strippedUrl === browser.runtime.getURL(extensionPaths.page)) {
// disable popup on extension page
inactive = true;
loading = false;
Expand Down Expand Up @@ -343,8 +332,6 @@
}

// check if current page url is a userscript
// strip fragments and query params
const strippedUrl = url.split(/[?#]/)[0];
if (strippedUrl.endsWith(".user.js")) {
// if it does, send message to content script
// context script will check the document contentType
Expand Down Expand Up @@ -464,6 +451,15 @@
// run resize again for good measure
resize();
});

// handle native app messages
const port = browser.runtime.connectNative();
port.onMessage.addListener(message => {
// console.info(message); // DEBUG
if (message.name === "SAVE_LOCATION_CHANGED") {
window.location.reload();
}
});
</script>

<svelte:window on:resize={resize}/>
Expand Down
7 changes: 6 additions & 1 deletion src/shared/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,12 @@ const _browser = {
});
}
setTimeout(() => responseCallback(response), _browser.delay);
}
},
connectNative: () => ({
onMessage: {
addListener: () => console.info("connectNative - addListener")
}
})
},
tabs: {
getCurrent(/* responseCallback */) {
Expand Down
18 changes: 18 additions & 0 deletions src/shared/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,21 @@ export const validMetaKeys = new Set([
"version",
"weight"
]);

export const extensionPaths = {
page: "/dist/entry-page.html",
popup: "/dist/entry-popup.html"
};

export async function openExtensionPage() {
const extensionPageUrl = browser.runtime.getURL(extensionPaths.page);
const tabs = await browser.tabs.query({});
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].url === extensionPageUrl) {
await browser.windows.update(tabs[i].windowId, {focused: true});
await browser.tabs.update(tabs[i].id, {active: true});
return;
}
}
await browser.tabs.create({url: extensionPageUrl});
}
2 changes: 2 additions & 0 deletions xcode/Shared.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Foundation
import SafariServices
import os

let extensionIdentifier = "com.userscripts.macos.Userscripts-Extension"

struct SharedDefaults {
// https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_application-groups
#if os(iOS)
Expand Down
17 changes: 15 additions & 2 deletions xcode/Userscripts Extension/SafariWebExtensionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
// these if/else if statement are formatted so that they can be neatly collapsed in Xcode
// typically the "else if" would be on the same line as the preceding statements close bracket
// ie. } else if {
if name == "REQ_PLATFORM" {
if name == "OPEN_APP" {
if let url = URL(string: "userscriptsurlscheme://") {
NSWorkspace.shared.open(url)
}
}
else if name == "REQ_PLATFORM" {
let platform = getPlatform()
response.userInfo = [SFExtensionMessageKey: ["platform": platform]]
} else if name == "REQ_USERSCRIPTS" {
}
else if name == "REQ_USERSCRIPTS" {
if let url = message?["url"] as? String, let isTop = message?["isTop"] as? Bool {
if
let matches = getInjectionFilenames(url),
Expand Down Expand Up @@ -162,6 +168,13 @@ class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
}
#endif
}
else if name == "CHANGE_SAVE_LOCATION" {
#if os(macOS)
if let url = URL(string: "userscriptsurlscheme://changesavelocation") {
NSWorkspace.shared.open(url)
}
#endif
}
else if name == "USERSCRIPT_INSTALL_00" {
if
let content = message?["content"] as? String,
Expand Down
16 changes: 16 additions & 0 deletions xcode/Userscripts.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
0336619F294DF7C900CFE179 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0336619E294DF7C900CFE179 /* Functions.swift */; };
033661A529510B7900CFE179 /* View.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 033661A329510B7900CFE179 /* View.storyboard */; };
03E20D06291E170000B4F692 /* dist in Resources */ = {isa = PBXBuildFile; fileRef = 03E20D05291E170000B4F692 /* dist */; };
03E20D07291E170000B4F692 /* dist in Resources */ = {isa = PBXBuildFile; fileRef = 03E20D05291E170000B4F692 /* dist */; };
4A143AAC279DE6FF0029BFD0 /* UserscriptsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A143AAB279DE6FF0029BFD0 /* UserscriptsTests.swift */; };
Expand Down Expand Up @@ -95,6 +97,8 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
0336619E294DF7C900CFE179 /* Functions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = "<group>"; };
033661A429510B7900CFE179 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/View.storyboard; sourceTree = "<group>"; };
03E20D05291E170000B4F692 /* dist */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dist; sourceTree = "<group>"; };
4A143AA9279DE6FF0029BFD0 /* UserscriptsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UserscriptsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4A143AAB279DE6FF0029BFD0 /* UserscriptsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserscriptsTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -247,8 +251,10 @@
4A57B9F1227235CD008A9763 /* AppDelegate.swift */,
4A57B9F3227235CD008A9763 /* Main.storyboard */,
4A57B9F6227235CD008A9763 /* ViewController.swift */,
033661A329510B7900CFE179 /* View.storyboard */,
4A57B9F8227235CE008A9763 /* Assets.xcassets */,
4A57B9FA227235CE008A9763 /* Info.plist */,
0336619E294DF7C900CFE179 /* Functions.swift */,
);
path = Userscripts;
sourceTree = "<group>";
Expand Down Expand Up @@ -470,6 +476,7 @@
buildActionMask = 2147483647;
files = (
4A57B9F9227235CE008A9763 /* Assets.xcassets in Resources */,
033661A529510B7900CFE179 /* View.storyboard in Resources */,
4A57B9F5227235CD008A9763 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -527,6 +534,7 @@
4A6E19EE268CC84A00E0270C /* Shared.swift in Sources */,
4A57B9F7227235CD008A9763 /* ViewController.swift in Sources */,
4A57B9F2227235CD008A9763 /* AppDelegate.swift in Sources */,
0336619F294DF7C900CFE179 /* Functions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -561,6 +569,14 @@
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
033661A329510B7900CFE179 /* View.storyboard */ = {
isa = PBXVariantGroup;
children = (
033661A429510B7900CFE179 /* Base */,
);
name = View.storyboard;
sourceTree = "<group>";
};
4A4CF6E0270A38BD00111584 /* Main.html */ = {
isa = PBXVariantGroup;
children = (
Expand Down
34 changes: 33 additions & 1 deletion xcode/Userscripts/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,40 @@ import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

private var window: NSWindow!
private var windowForego = false
private var windowLoaded = false

func application(_ application: NSApplication, open urls: [URL]) {
// if open panel is already open, stop processing the URL scheme
if NSApplication.shared.keyWindow?.accessibilityIdentifier() == "open-panel" { return }
for url in urls {
if url.host == "changesavelocation" {
// avoid opening the panel repeatedly and playing unnecessary warning sounds
if NSApplication.shared.keyWindow?.identifier?.rawValue == "changeSaveLocation" { continue }
if windowLoaded {
let viewController = window.contentViewController as? ViewController
viewController?.changeSaveLocation(nil)
} else {
windowForego = true
schemeChangeSaveLocation()
}
}
}
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
if windowForego { return }
let storyboard = NSStoryboard(name: "View", bundle: Bundle.main)
let windowController = storyboard.instantiateInitialController() as! NSWindowController
// let viewController = windowController.contentViewController as! ViewController
window = windowController.window
window.setIsVisible(true)
windowLoaded = true
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
return true
}

func applicationWillTerminate(_ aNotification: Notification) {
Expand Down
Loading