From 4a191e8036581893bf5f4cfb284770d1bfe9a807 Mon Sep 17 00:00:00 2001 From: Ruben Beltran del Rio Date: Wed, 13 Sep 2023 18:39:01 +0200 Subject: Add safari code --- safari/Junction/AppDelegate.swift | 21 ++++ .../AccentColor.colorset/Contents.json | 11 ++ .../AppIcon.appiconset/Contents.json | 68 +++++++++++ .../AppIcon.appiconset/icon_128x128.png | Bin 0 -> 8943 bytes .../AppIcon.appiconset/icon_128x128@2x.png | Bin 0 -> 20517 bytes .../AppIcon.appiconset/icon_16x16.png | Bin 0 -> 761 bytes .../AppIcon.appiconset/icon_16x16@2x.png | Bin 0 -> 1719 bytes .../AppIcon.appiconset/icon_256x256.png | Bin 0 -> 19842 bytes .../AppIcon.appiconset/icon_256x256@2x.png | Bin 0 -> 46067 bytes .../AppIcon.appiconset/icon_32x32.png | Bin 0 -> 1719 bytes .../AppIcon.appiconset/icon_32x32@2x.png | Bin 0 -> 3463 bytes .../AppIcon.appiconset/icon_512x512.png | Bin 0 -> 46067 bytes .../AppIcon.appiconset/icon_512x512@2x.png | Bin 0 -> 107660 bytes safari/Junction/Assets.xcassets/Contents.json | 6 + .../LargeIcon.imageset/Contents.json | 20 ++++ safari/Junction/Base.lproj/Main.html | 19 ++++ safari/Junction/Base.lproj/Main.storyboard | 124 +++++++++++++++++++++ safari/Junction/Junction.entitlements | 12 ++ safari/Junction/Resources/Icon.png | Bin 0 -> 107660 bytes safari/Junction/Resources/Script.js | 22 ++++ safari/Junction/Resources/Style.css | 45 ++++++++ safari/Junction/ViewController.swift | 57 ++++++++++ 22 files changed, 405 insertions(+) create mode 100644 safari/Junction/AppDelegate.swift create mode 100644 safari/Junction/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512.png create mode 100644 safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png create mode 100644 safari/Junction/Assets.xcassets/Contents.json create mode 100644 safari/Junction/Assets.xcassets/LargeIcon.imageset/Contents.json create mode 100644 safari/Junction/Base.lproj/Main.html create mode 100644 safari/Junction/Base.lproj/Main.storyboard create mode 100644 safari/Junction/Junction.entitlements create mode 100644 safari/Junction/Resources/Icon.png create mode 100644 safari/Junction/Resources/Script.js create mode 100644 safari/Junction/Resources/Style.css create mode 100644 safari/Junction/ViewController.swift (limited to 'safari/Junction') diff --git a/safari/Junction/AppDelegate.swift b/safari/Junction/AppDelegate.swift new file mode 100644 index 0000000..0e990a0 --- /dev/null +++ b/safari/Junction/AppDelegate.swift @@ -0,0 +1,21 @@ +// +// AppDelegate.swift +// Junction +// +// Created by Ruben Beltran del Rio on 9/13/23. +// + +import Cocoa + +@main +class AppDelegate: NSObject, NSApplicationDelegate { + + func applicationDidFinishLaunching(_ notification: Notification) { + // Override point for customization after application launch. + } + + func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + +} diff --git a/safari/Junction/Assets.xcassets/AccentColor.colorset/Contents.json b/safari/Junction/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/safari/Junction/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/Contents.json b/safari/Junction/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..64dc11e --- /dev/null +++ b/safari/Junction/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "filename" : "icon_16x16.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "filename" : "icon_16x16@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "filename" : "icon_32x32.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "filename" : "icon_32x32@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "filename" : "icon_128x128.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "filename" : "icon_128x128@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "filename" : "icon_256x256.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "filename" : "icon_256x256@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "filename" : "icon_512x512.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "filename" : "icon_512x512@2x.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128.png new file mode 100644 index 0000000..0bcb999 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png new file mode 100644 index 0000000..a45aa17 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16.png new file mode 100644 index 0000000..737d986 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png new file mode 100644 index 0000000..b748f7b Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256.png new file mode 100644 index 0000000..59d8be3 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png new file mode 100644 index 0000000..2f37b07 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32.png new file mode 100644 index 0000000..b748f7b Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png new file mode 100644 index 0000000..b0cf195 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512.png new file mode 100644 index 0000000..2f37b07 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512.png differ diff --git a/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png new file mode 100644 index 0000000..f056447 Binary files /dev/null and b/safari/Junction/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png differ diff --git a/safari/Junction/Assets.xcassets/Contents.json b/safari/Junction/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/safari/Junction/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/safari/Junction/Assets.xcassets/LargeIcon.imageset/Contents.json b/safari/Junction/Assets.xcassets/LargeIcon.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/safari/Junction/Assets.xcassets/LargeIcon.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/safari/Junction/Base.lproj/Main.html b/safari/Junction/Base.lproj/Main.html new file mode 100644 index 0000000..081cc41 --- /dev/null +++ b/safari/Junction/Base.lproj/Main.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + Junction Icon +

You can turn on Junction’s extension in Safari Extensions preferences.

+

Junction’s extension is currently on. You can turn it off in Safari Extensions preferences.

+

Junction’s extension is currently off. You can turn it on in Safari Extensions preferences.

+ + + diff --git a/safari/Junction/Base.lproj/Main.storyboard b/safari/Junction/Base.lproj/Main.storyboard new file mode 100644 index 0000000..6de6cf1 --- /dev/null +++ b/safari/Junction/Base.lproj/Main.storyboard @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/safari/Junction/Junction.entitlements b/safari/Junction/Junction.entitlements new file mode 100644 index 0000000..625af03 --- /dev/null +++ b/safari/Junction/Junction.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + com.apple.security.network.client + + + diff --git a/safari/Junction/Resources/Icon.png b/safari/Junction/Resources/Icon.png new file mode 100644 index 0000000..f056447 Binary files /dev/null and b/safari/Junction/Resources/Icon.png differ diff --git a/safari/Junction/Resources/Script.js b/safari/Junction/Resources/Script.js new file mode 100644 index 0000000..f551e6b --- /dev/null +++ b/safari/Junction/Resources/Script.js @@ -0,0 +1,22 @@ +function show(enabled, useSettingsInsteadOfPreferences) { + if (useSettingsInsteadOfPreferences) { + document.getElementsByClassName('state-on')[0].innerText = "Junction’s extension is currently on. You can turn it off in the Extensions section of Safari Settings."; + document.getElementsByClassName('state-off')[0].innerText = "Junction’s extension is currently off. You can turn it on in the Extensions section of Safari Settings."; + document.getElementsByClassName('state-unknown')[0].innerText = "You can turn on Junction’s extension in the Extensions section of Safari Settings."; + document.getElementsByClassName('open-preferences')[0].innerText = "Quit and Open Safari Settings…"; + } + + if (typeof enabled === "boolean") { + document.body.classList.toggle(`state-on`, enabled); + document.body.classList.toggle(`state-off`, !enabled); + } else { + document.body.classList.remove(`state-on`); + document.body.classList.remove(`state-off`); + } +} + +function openPreferences() { + webkit.messageHandlers.controller.postMessage("open-preferences"); +} + +document.querySelector("button.open-preferences").addEventListener("click", openPreferences); diff --git a/safari/Junction/Resources/Style.css b/safari/Junction/Resources/Style.css new file mode 100644 index 0000000..cbde9e6 --- /dev/null +++ b/safari/Junction/Resources/Style.css @@ -0,0 +1,45 @@ +* { + -webkit-user-select: none; + -webkit-user-drag: none; + cursor: default; +} + +:root { + color-scheme: light dark; + + --spacing: 20px; +} + +html { + height: 100%; +} + +body { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + + gap: var(--spacing); + margin: 0 calc(var(--spacing) * 2); + height: 100%; + + font: -apple-system-short-body; + text-align: center; +} + +body:not(.state-on, .state-off) :is(.state-on, .state-off) { + display: none; +} + +body.state-on :is(.state-off, .state-unknown) { + display: none; +} + +body.state-off :is(.state-on, .state-unknown) { + display: none; +} + +button { + font-size: 1em; +} diff --git a/safari/Junction/ViewController.swift b/safari/Junction/ViewController.swift new file mode 100644 index 0000000..91f4596 --- /dev/null +++ b/safari/Junction/ViewController.swift @@ -0,0 +1,57 @@ +// +// ViewController.swift +// Junction +// +// Created by Ruben Beltran del Rio on 9/13/23. +// + +import Cocoa +import SafariServices +import WebKit + +let extensionBundleIdentifier = "systems.tranquil.Junction.Extension" + +class ViewController: NSViewController, WKNavigationDelegate, WKScriptMessageHandler { + + @IBOutlet var webView: WKWebView! + + override func viewDidLoad() { + super.viewDidLoad() + + self.webView.navigationDelegate = self + + self.webView.configuration.userContentController.add(self, name: "controller") + + self.webView.loadFileURL(Bundle.main.url(forResource: "Main", withExtension: "html")!, allowingReadAccessTo: Bundle.main.resourceURL!) + } + + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + SFSafariExtensionManager.getStateOfSafariExtension(withIdentifier: extensionBundleIdentifier) { (state, error) in + guard let state = state, error == nil else { + // Insert code to inform the user that something went wrong. + return + } + + DispatchQueue.main.async { + if #available(macOS 13, *) { + webView.evaluateJavaScript("show(\(state.isEnabled), true)") + } else { + webView.evaluateJavaScript("show(\(state.isEnabled), false)") + } + } + } + } + + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + if (message.body as! String != "open-preferences") { + return; + } + + SFSafariApplication.showPreferencesForExtension(withIdentifier: extensionBundleIdentifier) { error in + DispatchQueue.main.async { + NSApplication.shared.terminate(nil) + } + } + } + +} -- cgit