mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-01 13:32:44 +02:00
safari: checkpoint as I try to get the terrible wiring right
This commit is contained in:
parent
f5b00deb7e
commit
a465ad6a8f
|
@ -673,6 +673,10 @@ function findRoute(path) {
|
|||
|
||||
let port;
|
||||
async function onMessage(req) {
|
||||
// Safari / Safari extension app API forces you to adopt their
|
||||
// {name, userInfo} structure for the request.
|
||||
if (req.name === 'ToSafari') req = req.userInfo;
|
||||
|
||||
if (req.buf) req.buf = atob(req.buf);
|
||||
console.log('req', req);
|
||||
|
||||
|
@ -712,6 +716,16 @@ function tryConnect() {
|
|||
port = chrome.runtime.connectNative('com.rsnous.tabfs');
|
||||
port.onMessage.addListener(onMessage);
|
||||
port.onDisconnect.addListener(p => {console.log('disconnect', p)});
|
||||
|
||||
// Safari is very weird -- it has this native app that we have to talk to,
|
||||
// so we poke that app to wake it up, get it to start the TabFS process,
|
||||
// and get it to start calling us whenever TabFS wants to do an FS call.
|
||||
// Is there a better way to do this?
|
||||
if (chrome.runtime.getURL('/').startsWith('safari-web-extension://')) { // Safari-only
|
||||
chrome.runtime.sendNativeMessage('com.rsnous.tabfs', {op: 'safari_did_connect'}, function(resp) {
|
||||
console.log(resp);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!TESTING) {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// FSProcessManager.swift
|
||||
// TabFS
|
||||
//
|
||||
// Created by Omar Rizwan on 1/31/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import SafariServices.SFSafariApplication
|
||||
|
||||
let extensionBundleIdentifier = "com.rsnous.TabFS-Extension"
|
||||
|
||||
class FSProcessManager {
|
||||
static let shared = FSProcessManager()
|
||||
|
||||
// FIXME: should accept XPC connection to extension
|
||||
// so it can get replies (??)
|
||||
|
||||
var fs: Process!
|
||||
var fsInput: FileHandle!
|
||||
var fsOutput: FileHandle!
|
||||
|
||||
func start() {
|
||||
fs = Process()
|
||||
fs.executableURL = URL(fileURLWithPath: "/Users/osnr/Code/tabfs/fs/tabfs")
|
||||
fs.arguments = []
|
||||
|
||||
let inputPipe = Pipe(), outputPipe = Pipe()
|
||||
fs.standardInput = inputPipe
|
||||
fs.standardOutput = outputPipe
|
||||
|
||||
try! fs.run()
|
||||
|
||||
fsInput = inputPipe.fileHandleForWriting
|
||||
fsOutput = outputPipe.fileHandleForReading
|
||||
//
|
||||
// SFSafariApplication.dispatchMessage(
|
||||
// withName: "ToSafari",
|
||||
// toExtensionWithIdentifier: extensionBundleIdentifier,
|
||||
// userInfo: [:]
|
||||
// ) { error in
|
||||
// debugPrint("Message attempted. Error info: \(String.init(describing: error))")
|
||||
// }
|
||||
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
while true {
|
||||
let req = self.awaitRequest()
|
||||
|
||||
SFSafariApplication.dispatchMessage(
|
||||
withName: "ToSafari",
|
||||
toExtensionWithIdentifier: extensionBundleIdentifier,
|
||||
userInfo: req
|
||||
) { error in
|
||||
debugPrint("Message attempted. Error info: \(String.init(describing: error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func awaitRequest() -> [String: Any] {
|
||||
let length = fsOutput.readData(ofLength: 4).withUnsafeBytes {
|
||||
$0.load(as: UInt32.self)
|
||||
}
|
||||
let data = fsOutput.readData(ofLength: Int(length))
|
||||
return try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
|
||||
}
|
||||
|
||||
func respond(_ resp: [AnyHashable: Any]) {
|
||||
try! fsInput.write(JSONSerialization.data(withJSONObject: resp, options: []))
|
||||
}
|
||||
}
|
|
@ -6,21 +6,38 @@
|
|||
//
|
||||
|
||||
import SafariServices
|
||||
import SafariServices.SFSafariApplication
|
||||
import os.log
|
||||
|
||||
let SFExtensionMessageKey = "message"
|
||||
|
||||
class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {
|
||||
|
||||
|
||||
func beginRequest(with context: NSExtensionContext) {
|
||||
|
||||
os_log(.default, "Received message from browser.runtime.sendNativefffMessage: %@", context as! CVarArg)
|
||||
|
||||
let item = context.inputItems[0] as! NSExtensionItem
|
||||
let message = item.userInfo?[SFExtensionMessageKey]
|
||||
os_log(.default, "Received message from browser.runtime.sendNativeMessage: %@", message as! CVarArg)
|
||||
|
||||
let response = NSExtensionItem()
|
||||
response.userInfo = [ SFExtensionMessageKey: [ "Response to": message ] ]
|
||||
|
||||
context.completeRequest(returningItems: [response], completionHandler: nil)
|
||||
guard let message = item.userInfo?["message"] as? [AnyHashable: Any] else { return }
|
||||
|
||||
if message["op"] as! String == "safari_did_connect" {
|
||||
FSProcessManager.shared.start()
|
||||
|
||||
let response = NSExtensionItem()
|
||||
response.userInfo = [ "message": [ "aResponse to": "moop" ] ]
|
||||
context.completeRequest(returningItems: [response], completionHandler: nil)
|
||||
|
||||
return
|
||||
}
|
||||
//
|
||||
// os_log(.default, "Received message from browser.runtime.sendNativeMessage: %@", op as! CVarArg)
|
||||
|
||||
FSProcessManager.shared.respond(message)
|
||||
//
|
||||
// let response = NSExtensionItem()
|
||||
// response.userInfo = [ "message": [ "Response to": op ] ]
|
||||
//
|
||||
// // How do I get too the app????
|
||||
//
|
||||
// context.completeRequest(returningItems: [response], completionHandler: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
F0442A1E25C7507500D998A5 /* safari in Resources */ = {isa = PBXBuildFile; fileRef = F0442A1A25C7507500D998A5 /* safari */; };
|
||||
F0442A1F25C7507500D998A5 /* manifest.json in Resources */ = {isa = PBXBuildFile; fileRef = F0442A1B25C7507500D998A5 /* manifest.json */; };
|
||||
F0442A2025C7507500D998A5 /* vendor in Resources */ = {isa = PBXBuildFile; fileRef = F0442A1C25C7507500D998A5 /* vendor */; };
|
||||
F068D65625C7C66700DB3AB5 /* FSProcessManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F068D65225C77F7600DB3AB5 /* FSProcessManager.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
@ -61,6 +62,7 @@
|
|||
F0442A1A25C7507500D998A5 /* safari */ = {isa = PBXFileReference; lastKnownFileType = folder; name = safari; path = ../..; sourceTree = "<group>"; };
|
||||
F0442A1B25C7507500D998A5 /* manifest.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = manifest.json; path = ../../../manifest.json; sourceTree = "<group>"; };
|
||||
F0442A1C25C7507500D998A5 /* vendor */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vendor; path = ../../../vendor; sourceTree = "<group>"; };
|
||||
F068D65225C77F7600DB3AB5 /* FSProcessManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FSProcessManager.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -125,6 +127,7 @@
|
|||
F0442A0A25C7507400D998A5 /* TabFS Extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F068D65225C77F7600DB3AB5 /* FSProcessManager.swift */,
|
||||
F0442A1825C7507500D998A5 /* Resources */,
|
||||
F0442A0B25C7507400D998A5 /* SafariWebExtensionHandler.swift */,
|
||||
F0442A0D25C7507400D998A5 /* Info.plist */,
|
||||
|
@ -257,6 +260,7 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F068D65625C7C66700DB3AB5 /* FSProcessManager.swift in Sources */,
|
||||
F0442A0C25C7507400D998A5 /* SafariWebExtensionHandler.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
Binary file not shown.
|
@ -8,9 +8,57 @@
|
|||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "62A8B265-14D3-4F90-9C2B-6F38280A1C0A"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TabFS Extension/SafariWebExtensionHandler.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "18"
|
||||
endingLineNumber = "18"
|
||||
landmarkName = "beginRequest(with:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "171B952C-1DD2-4555-B565-AF63FA641791"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TabFS Extension/FSProcessManager.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "25"
|
||||
endingLineNumber = "25"
|
||||
landmarkName = "start()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "C3177652-3D89-4E01-8BF5-03C666008BDB"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TabFS Extension/SafariWebExtensionHandler.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "19"
|
||||
endingLineNumber = "19"
|
||||
landmarkName = "beginRequest(with:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "111CBF7A-E3E9-4303-9961-9812F8781A39"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "TabFS Extension/SafariWebExtensionHandler.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="16085" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16085"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17156"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -66,7 +67,7 @@
|
|||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
||||
</connections>
|
||||
</application>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider="target"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="TabFS" customModuleProvider="target"/>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
|
@ -97,18 +98,28 @@
|
|||
<!--View Controller-->
|
||||
<scene sceneID="hIz-AP-VOD">
|
||||
<objects>
|
||||
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController id="XfG-lQ-9wD" customClass="ViewController" customModule="TabFS" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="344"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="407"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<stackView distribution="fill" orientation="vertical" alignment="centerX" spacing="42" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZLV-xE-AGT">
|
||||
<rect key="frame" x="0.0" y="34" width="480" height="265"/>
|
||||
<rect key="frame" x="0.0" y="34" width="480" height="328"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="FWV-e2-WQh" userLabel="IconView">
|
||||
<rect key="frame" x="176" y="137" width="128" height="128"/>
|
||||
<rect key="frame" x="176" y="200" width="128" height="128"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" image="AppIcon" id="Hhb-TZ-Dhg"/>
|
||||
</imageView>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LPN-IP-tY1">
|
||||
<rect key="frame" x="144" y="130" width="192" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="Start TabFS and Connect" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="OYN-4O-IVc">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="startTabFSAndConnect:" target="XfG-lQ-9wD" id="ECW-0t-4uE"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="EB0-ac-UZR">
|
||||
<rect key="frame" x="38" y="63" width="404" height="32"/>
|
||||
<constraints>
|
||||
|
@ -138,11 +149,13 @@ DQ
|
|||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
<integer value="1000"/>
|
||||
</visibilityPriorities>
|
||||
<customSpacing>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
</stackView>
|
||||
</subviews>
|
||||
|
|
|
@ -48,4 +48,7 @@ class ViewController: NSViewController {
|
|||
}
|
||||
}
|
||||
|
||||
@IBAction func startTabFSAndConnect(_ sender: Any) {
|
||||
// FSProcessManager.start()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue