From a3a8dab3cfbb4516cb8779e8aaf042dfed6e98c4 Mon Sep 17 00:00:00 2001 From: quoid Date: Mon, 10 May 2021 22:40:04 -0400 Subject: [PATCH 01/12] added readme faq about csps - #106 --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 1a059dfd..36a69825 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,14 @@ Once the host app is open, you will see a button called "Change save location". ## FAQs +**"Refused to execute a script" error(s), what should I do!?** + +> You are seeing this error because of the website's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP). Currently there is no way to allow extension content scripts to bypass CSPs in Safari. +> +> Automatically, the extension will attempt to circumvent strict CSPs, but if you are still experiencing issues, trying setting the userscript metadata key/val `// @inject-into auto` or `// @inject-into content`. +> +> You can read more about this in [this issue](https://github.com/quoid/userscripts/issues/106#issuecomment-797320450). + **Do I need to use the extension's editor to create new userscripts or to edit existing?** > You can use your own editor to update and manage your files. As long as you are saving the files to the save location, and they are properly formatted, they should be injected. However, you **must open the extension page** beforehand. That means, if you create a new userscript and save it to the save location, before injection will occur properly, the extension page must be open by clicking the extension button in Safari. From 7a7b609055a32e055d4a36fe1544ec0ee237f581 Mon Sep 17 00:00:00 2001 From: quoid Date: Mon, 10 May 2021 22:40:30 -0400 Subject: [PATCH 02/12] update build and version numbers --- extension/Userscripts.xcodeproj/project.pbxproj | 16 ++++++++-------- src/dev.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/extension/Userscripts.xcodeproj/project.pbxproj b/extension/Userscripts.xcodeproj/project.pbxproj index 322a32d8..65250c84 100644 --- a/extension/Userscripts.xcodeproj/project.pbxproj +++ b/extension/Userscripts.xcodeproj/project.pbxproj @@ -417,7 +417,7 @@ CODE_SIGN_ENTITLEMENTS = "Userscripts Extension/Userscripts Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 26; DEVELOPMENT_TEAM = J74Q8V8V8N; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = "Userscripts Extension/Info.plist"; @@ -426,7 +426,7 @@ "@executable_path/../Frameworks", "@executable_path/../../../../Frameworks", ); - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = "com.userscripts.macos.Userscripts-Extension"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -440,7 +440,7 @@ CODE_SIGN_ENTITLEMENTS = "Userscripts Extension/Userscripts Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 26; DEVELOPMENT_TEAM = J74Q8V8V8N; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = "Userscripts Extension/Info.plist"; @@ -449,7 +449,7 @@ "@executable_path/../Frameworks", "@executable_path/../../../../Frameworks", ); - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = "com.userscripts.macos.Userscripts-Extension"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -466,7 +466,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 26; DEVELOPMENT_TEAM = J74Q8V8V8N; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Userscripts/Info.plist; @@ -474,7 +474,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.userscripts.macos; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -490,7 +490,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 26; DEVELOPMENT_TEAM = J74Q8V8V8N; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = Userscripts/Info.plist; @@ -498,7 +498,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 3.1.0; + MARKETING_VERSION = 3.2.0; PRODUCT_BUNDLE_IDENTIFIER = com.userscripts.macos; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/src/dev.js b/src/dev.js index 1b00290d..a297f2aa 100644 --- a/src/dev.js +++ b/src/dev.js @@ -18,7 +18,7 @@ const defaultSettings = { showCount: "false", sortOrder: "lastModifiedDesc", tabSize: "4", - version: "3.1.0" + version: "3.2.0" }; // example file contents From 623741d82a8fdd05821705bd63c22c096835ea84 Mon Sep 17 00:00:00 2001 From: quoid Date: Mon, 10 May 2021 22:44:54 -0400 Subject: [PATCH 03/12] simplify CSP fallback #125 --- extension/Userscripts Extension/UserscriptsSafari.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/extension/Userscripts Extension/UserscriptsSafari.js b/extension/Userscripts Extension/UserscriptsSafari.js index 9b80d6c7..a801830f 100644 --- a/extension/Userscripts Extension/UserscriptsSafari.js +++ b/extension/Userscripts Extension/UserscriptsSafari.js @@ -121,10 +121,12 @@ function parseCode(data, fallback = false) { } function cspFallback(e) { - const src = e.sourceFile.toUpperCase(); - const ext = safari.extension.baseURI.toUpperCase(); - // ensure that violation came from the extension - if ((ext.startsWith(src) || src.startsWith(ext))) { + // if a security policy violation event has occurred, and the directive is script-src + // it's fair to assume that there is a strict CSP for scripts + // if there's a strict CSP for scripts, it's unlikely this extension uri is whitelisted + // when any script-src violation is detected, re-attempt injection + // since it's fair to assume injection was blocked for extension's content script + if (e.effectiveDirective === "script-src") { // get all "auto" code if (Object.keys(data.js.auto).length != 0 && cspFallbackAttempted < 1) { let n = {"js": {"auto": {}}}; From 9d1c64c26c85ffe9e9039754057bfe47fb60172d Mon Sep 17 00:00:00 2001 From: quoid Date: Tue, 18 May 2021 15:54:57 -0400 Subject: [PATCH 04/12] rebuild html --- extension/Userscripts Extension/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/Userscripts Extension/index.html b/extension/Userscripts Extension/index.html index fe297c65..283965b7 100644 --- a/extension/Userscripts Extension/index.html +++ b/extension/Userscripts Extension/index.html @@ -1 +1 @@ -Userscripts Safari
\ No newline at end of file +Userscripts Safari
\ No newline at end of file From 160c1e48ba401c0793a239ea487f4c8e79dc9418 Mon Sep 17 00:00:00 2001 From: quoid Date: Tue, 18 May 2021 15:56:24 -0400 Subject: [PATCH 05/12] refactor container app ui, #120 --- .../Userscripts/Base.lproj/Main.storyboard | 6 +-- extension/Userscripts/ViewController.swift | 47 ++++++++----------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/extension/Userscripts/Base.lproj/Main.storyboard b/extension/Userscripts/Base.lproj/Main.storyboard index 438d7f81..e0d73a36 100644 --- a/extension/Userscripts/Base.lproj/Main.storyboard +++ b/extension/Userscripts/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -143,7 +143,7 @@ - + diff --git a/extension/Userscripts/ViewController.swift b/extension/Userscripts/ViewController.swift index 8d97ab1d..e967da7e 100644 --- a/extension/Userscripts/ViewController.swift +++ b/extension/Userscripts/ViewController.swift @@ -7,18 +7,17 @@ class ViewController: NSViewController { @IBOutlet var saveLocation: NSTextField! @IBOutlet weak var enabledText: NSTextField! @IBOutlet weak var enabledIcon: NSView! - - let extensionBundleIdentifier = "com.userscripts.macos.Userscripts-Extension" - + + let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String + let hostID = Bundle.main.bundleIdentifier! + let extensionID = "com.userscripts.macos.Userscripts-Extension" + let documentsDirectory = getDocumentsDirectory().appendingPathComponent("scripts").absoluteString + override func viewDidLoad() { super.viewDidLoad() - let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String - self.appName.stringValue = "Userscripts Safari Version \(appVersion)" - // seems like a lot of work to id path for another target's documents directory - let hostID = Bundle.main.bundleIdentifier! - let extensionID = "com.userscripts.macos.Userscripts-Extension" - let documentsDirectory = getDocumentsDirectory().appendingPathComponent("scripts").absoluteString let location = documentsDirectory.replacingOccurrences(of: hostID, with: extensionID) + self.appName.stringValue = "Userscripts Safari Version \(appVersion)" + setExtensionState() // check if bookmark data exists guard let sharedBookmark = UserDefaults(suiteName: SharedDefaults.suiteName)?.data(forKey: SharedDefaults.keyName), @@ -34,22 +33,22 @@ class ViewController: NSViewController { return } self.saveLocation.stringValue = url.absoluteString - // set extension state - SFSafariExtensionManager.getStateOfSafariExtension(withIdentifier: extensionBundleIdentifier) { (state, error) in + NotificationCenter.default.addObserver(self, selector: #selector(setExtensionState), name: NSApplication.didBecomeActiveNotification, object: nil) + } + + @objc func setExtensionState() { + SFSafariExtensionManager.getStateOfSafariExtension(withIdentifier: extensionID) { (state, error) in guard let state = state, error == nil else { - // Insert code to inform the user that something went wrong. + self.enabledText.stringValue = "Safari Extension State Unknown" return } - DispatchQueue.main.async { - if (state.isEnabled) { - self.enabledIcon.layer?.backgroundColor = NSColor.green.cgColor - self.enabledText.stringValue = "Safari Extension Enabled" - } + self.enabledIcon.layer?.backgroundColor = state.isEnabled ? NSColor.green.cgColor : NSColor.red.cgColor + self.enabledText.stringValue = state.isEnabled ? "Safari Extension Enabled" : "Safari Extension Disabled" } } } - + @IBAction func changeSaveLocation(_ sender: NSButton) { guard let window = self.view.window else { return } let panel = NSOpenPanel() @@ -76,16 +75,8 @@ class ViewController: NSViewController { } }) } - + @IBAction func openSafariExtensionPreferences(_ sender: AnyObject?) { - SFSafariApplication.showPreferencesForExtension(withIdentifier: extensionBundleIdentifier) { error in - guard error == nil else { - // Insert code to inform the user that something went wrong. - return - } - DispatchQueue.main.async { - NSApplication.shared.terminate(nil) - } - } + SFSafariApplication.showPreferencesForExtension(withIdentifier: extensionID) } } From 5a733cb218b1928e24c03bc45a7b367d6249b8fc Mon Sep 17 00:00:00 2001 From: quoid Date: Tue, 18 May 2021 16:39:17 -0400 Subject: [PATCH 06/12] neatly truncate long item names --- src/Components/Sidebar/Item.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Components/Sidebar/Item.svelte b/src/Components/Sidebar/Item.svelte index 84aab051..a7f8ecd6 100644 --- a/src/Components/Sidebar/Item.svelte +++ b/src/Components/Sidebar/Item.svelte @@ -47,6 +47,7 @@ flex: 1 0 0; font-weight: 500; letter-spacing: var(--letter-spacing-default); + padding-right: 0.25rem; } .item__description { @@ -78,7 +79,7 @@ >
-
{data.name}
+
{data.name}
toggle(e, data)} From f4d5eac3365dde24c52633b4027df02879d3f96a Mon Sep 17 00:00:00 2001 From: quoid Date: Tue, 18 May 2021 16:40:07 -0400 Subject: [PATCH 07/12] refactor so truncate works on names, #129 --- src/Components/Editor/Editor.svelte | 65 ++++++++++++++++++----------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/src/Components/Editor/Editor.svelte b/src/Components/Editor/Editor.svelte index 98a007f9..06974b21 100644 --- a/src/Components/Editor/Editor.svelte +++ b/src/Components/Editor/Editor.svelte @@ -206,16 +206,21 @@ padding: 1rem 0.5rem 1rem 1.5rem; } - :global(.editor__header > button:nth-of-type(2)) { - margin: 0 1.5rem; - } - .editor__header__content { align-items: center; display: flex; flex-grow: 1; flex-wrap: wrap; font: var(--text-large); + min-width: 0; /* needed for .truncate on .title */ + } + + /* element needed so that .truncate works on .title */ + .editor__header__content > div { + align-items: center; + display: flex; + max-width: 100%; + padding-right: 1rem; } .editor__title { @@ -239,6 +244,14 @@ position: relative; } + .editor__header__buttons { + display: flex; + } + + :global(.editor__header__buttons > button:nth-of-type(2)) { + margin: 0 1.5rem; + } + .editor__footer { background: rgba(50, 54, 57, 0.65); border-radius: var(--border-radius); @@ -279,8 +292,10 @@ {/if}
- -
{name}
+
+ +
{name}
+
{#if $state.includes("saving")} Saving... @@ -297,24 +312,26 @@ {/if}
- - - +
+ + + +
Date: Tue, 18 May 2021 16:42:31 -0400 Subject: [PATCH 08/12] rebuild html --- extension/Userscripts Extension/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/Userscripts Extension/index.html b/extension/Userscripts Extension/index.html index 283965b7..2ca4472c 100644 --- a/extension/Userscripts Extension/index.html +++ b/extension/Userscripts Extension/index.html @@ -1 +1 @@ -Userscripts Safari
\ No newline at end of file +Userscripts Safari
\ No newline at end of file From 89616a82b87f38bbbc8afeae404979fd0a94545d Mon Sep 17 00:00:00 2001 From: quoid Date: Sat, 29 May 2021 14:19:03 -0400 Subject: [PATCH 09/12] improve matching #107, #108 --- .../Userscripts Extension/Functions.swift | 103 ++++++++++++++++-- .../SafariExtensionHandler.swift | 4 +- .../UserscriptsSafari.js | 6 +- 3 files changed, 97 insertions(+), 16 deletions(-) diff --git a/extension/Userscripts Extension/Functions.swift b/extension/Userscripts Extension/Functions.swift index 3ce02b3a..3756e82f 100644 --- a/extension/Userscripts Extension/Functions.swift +++ b/extension/Userscripts Extension/Functions.swift @@ -129,11 +129,6 @@ func unsanitize(_ str: String) -> String { return s } -func patternMatch(_ string: String,_ pattern: String) -> Bool { - let predicate = NSPredicate(format: "self LIKE %@", pattern) - return !NSArray(object: string).filtered(using: predicate).isEmpty -} - func normalizeWeight(_ weight: String) -> String { if let w = Int(weight) { if w > 999 { @@ -1022,15 +1017,25 @@ func getRequiredCode(_ filename: String, _ resources: [String], _ fileType: Stri } // injection -func getMatchedFiles(_ url: String) -> [String]? { +func getMatchedFiles(_ location: [String: Any]) -> [String]? { // get the manifest data guard let manifestKeys = getManifestKeys(), let active = manifestKeys.settings["active"] else { - err("could not read manifest when attempting to get page script count") + err("could not read manifest when attempting to get matched files") + return nil + } + // get the protocol, host, pathname + guard + let ptcl = location["protocol"] as? String, + let host = location["host"] as? String, + let path = location["pathname"] as? String + else { + err("could not get values from location object when attempting to get matched files") return nil } + // domains where loading is excluded for file var excludedFilenames:[String] = [] // when code is loaded from a file, it's filename will be populated in the below array, to avoid duplication @@ -1048,7 +1053,7 @@ func getMatchedFiles(_ url: String) -> [String]? { // url matches a pattern in blacklist // essentially all scripts are disabled, there are 0 active scripts for url for pattern in manifestKeys.blacklist { - if patternMatch(url, pattern) { + if match(ptcl, host, path, pattern) { return matchedFilenames } } @@ -1059,7 +1064,7 @@ func getMatchedFiles(_ url: String) -> [String]? { // loop through exclude patterns and see if any match against page url for pattern in excludePatterns { // if pattern matches page url, add filenames from page url to excludes array, code from those filenames won't be loaded - if patternMatch(url, pattern) { + if match(ptcl, host, path, pattern) { guard let filenames = manifestKeys.exclude[pattern] else { err("error parsing manifest.keys when attempting to get code for injected script") continue @@ -1074,7 +1079,7 @@ func getMatchedFiles(_ url: String) -> [String]? { // loop through all match patterns from manifest to see if they match against the current page url for pattern in matchPatterns { - if patternMatch(url, pattern) { + if match(ptcl, host, path, pattern) { // the filenames listed for the pattern that match page url guard let filenames = manifestKeys.match[pattern] else { err("error parsing manifestKets.match when attempting to get code for injected script") @@ -1205,6 +1210,77 @@ func getCode(_ filenames: [String], _ isTop: Bool)-> [String: [String: [String: return allFiles } +// matching +func getURLProps(_ url: String) -> [String: String]? { + let pattern = #"^(.*:)\/\/((?:\*\.)?(?:[a-z0-9-]+\.)+(?:[a-z0-9]+))(\/.*)?$"# + let regex = try! NSRegularExpression(pattern: pattern, options: .caseInsensitive) + guard + let result = regex.firstMatch(in: url, options: [], range: NSMakeRange(0, url.utf16.count)), + let ptclRange = Range(result.range(at: 1), in: url), + let hostRange = Range(result.range(at: 2), in: url) + else { + return nil + } + let ptcl = String(url[ptclRange]) + let host = String(url[hostRange]) + var path = "/" + if let pathRange = Range(result.range(at: 3), in: url) { + path = String(url[pathRange]) + } + return ["protocol": ptcl, "host": host, "pathname": path] +} + +func stringToRegex(_ stringPattern: String) -> NSRegularExpression? { + let pattern = #"[\.|\?|\^|\$|\+|\{|\}|\[|\]|\||\\(|\)|\/]"# + var patternReplace = "^\(stringPattern.replacingOccurrences(of: pattern, with: #"\\$0"#, options: .regularExpression))$" + patternReplace = patternReplace.replacingOccurrences(of: "*", with: ".*") + guard let regex = try? NSRegularExpression(pattern: patternReplace, options: .caseInsensitive) else { + return nil + } + return regex +} + +func match(_ ptcl: String,_ host: String,_ path: String,_ matchPattern: String) -> Bool { + // matchPattern is the value from metatdata key @match or @exclude-match + if (matchPattern == "") { + return true + } + // currently only http/s supported + if (ptcl != "http:" && ptcl != "https:") { + return false + } + let partsPattern = #"^(http:|https:|\*:)\/\/((?:\*\.)?(?:[a-z0-9-]+\.)+(?:[a-z0-9]+)|\*\.[a-z]+|\*)(\/[^\s]*)$"# + let partsPatternReg = try! NSRegularExpression(pattern: partsPattern, options: .caseInsensitive) + let range = NSMakeRange(0, matchPattern.utf16.count) + guard let parts = partsPatternReg.firstMatch(in: matchPattern, options: [], range: range) else { + err("malformed regex match pattern") + return false + } + // construct host regex from matchPattern + let matchPatternHost = matchPattern[Range(parts.range(at: 2), in: matchPattern)!] + var hostPattern = "^\(matchPatternHost.replacingOccurrences(of: ".", with: "\\."))$" + hostPattern = hostPattern.replacingOccurrences(of: "^*$", with: ".*") + hostPattern = hostPattern.replacingOccurrences(of: "*\\.", with: "(.*\\.)?") + guard let hostRegEx = try? NSRegularExpression(pattern: hostPattern, options: .caseInsensitive) else { + err("invalid host regex") + return false + } + // contruct path regex from matchPattern + let matchPatternPath = matchPattern[Range(parts.range(at: 3), in: matchPattern)!] + guard let pathRegEx = stringToRegex(String(matchPatternPath)) else { + err("invalid path regex") + return false + } + guard + (hostRegEx.firstMatch(in: host, options: [], range: NSMakeRange(0, host.utf16.count)) != nil), + (pathRegEx.firstMatch(in: path, options: [], range: NSMakeRange(0, path.utf16.count)) != nil) + else { + return false + } + + return true +} + // popover func updateBadgeCount(_ frames: [[String : Any]]) { guard @@ -1222,7 +1298,12 @@ func updateBadgeCount(_ frames: [[String : Any]]) { urls.append(url) } for url in urls { - guard let m = getMatchedFiles(url) else { return } + guard + let parts = getURLProps(url), + let m = getMatchedFiles(parts) + else { + return + } // add values not already present in the matched array matched.append(contentsOf: m.filter{!matched.contains($0)}) } diff --git a/extension/Userscripts Extension/SafariExtensionHandler.swift b/extension/Userscripts Extension/SafariExtensionHandler.swift index d4f1a1ec..157eefd0 100644 --- a/extension/Userscripts Extension/SafariExtensionHandler.swift +++ b/extension/Userscripts Extension/SafariExtensionHandler.swift @@ -99,10 +99,10 @@ class SafariExtensionHandler: SFSafariExtensionHandler { responseName = "RESP_USERSCRIPTS" if let data = userInfo, - let url = data["url"] as? String, + let location = data["location"] as? [String: Any], let isTop = data["top"] as? Bool, let id = data["id"] as? String, - let matched = getMatchedFiles(url), + let matched = getMatchedFiles(location), let code = getCode(matched, isTop) { responseData = ["code": code, "id": id] diff --git a/extension/Userscripts Extension/UserscriptsSafari.js b/extension/Userscripts Extension/UserscriptsSafari.js index a801830f..48af4fa9 100644 --- a/extension/Userscripts Extension/UserscriptsSafari.js +++ b/extension/Userscripts Extension/UserscriptsSafari.js @@ -3,8 +3,8 @@ let data; // determines whether strict csp injection has already run (JS only) let cspFallbackAttempted = 0; -// send the url to swift side for fetching applicable code -const url = window.location.href; +// send the location object to swift side for fetching applicable code +const loc = window.location; // tell swift side if requester is window.top, needed to filter code for @noframes const isTop = window === window.top; // unique id per requester to avoid repeat execution @@ -173,4 +173,4 @@ document.addEventListener("securitypolicyviolation", cspFallback); // event listener to handle messages safari.self.addEventListener("message", handleMessage); // request code for page url -safari.extension.dispatchMessage("REQ_USERSCRIPTS", {id: id, top: isTop, url: url}); +safari.extension.dispatchMessage("REQ_USERSCRIPTS", {id: id, top: isTop, location: loc}); From 74d8faece5587ee1c90778dcd995f5695fe0452d Mon Sep 17 00:00:00 2001 From: quoid Date: Sat, 29 May 2021 14:47:35 -0400 Subject: [PATCH 10/12] fix typo, make toolbar count on by defualt --- extension/Userscripts Extension/Functions.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extension/Userscripts Extension/Functions.swift b/extension/Userscripts Extension/Functions.swift index 3756e82f..fbe62b0f 100644 --- a/extension/Userscripts Extension/Functions.swift +++ b/extension/Userscripts Extension/Functions.swift @@ -256,7 +256,7 @@ let defaultSettings = [ "lint": "false", "log": "false", "sortOrder": "lastModifiedDesc", - "showCount": "false", + "showCount": "true", "showInvisibles": "true", "tabSize": "4" ] @@ -598,7 +598,7 @@ func getInitData() -> [String: Any]? { } } - // check if default save location directory exists, if not create it + // check if default require location directory exists, if not create it if !FileManager.default.fileExists(atPath: requireLocation.path) { do { try FileManager.default.createDirectory(at: requireLocation, withIntermediateDirectories: false) From ef7651694fff0c93ab03f8149824dadbd991c34a Mon Sep 17 00:00:00 2001 From: quoid Date: Sun, 30 May 2021 14:23:58 -0400 Subject: [PATCH 11/12] readme update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 36a69825..218b22a4 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Userscripts Safari currently supports the following userscript metadata: - `@name` - This will be the name that displays in the sidebar and be used as the filename - you can *not* use the same name for multiple files of the same type - `@description`- Use this to describe what your userscript does - this will be displayed in the sidebar - there is a setting to hide descriptions - `@match` - Domain match patterns - you can use several instances of this field if you'd like multiple domain matches - view [this article for more information on constructing patterns](https://developer.chrome.com/extensions/match_patterns) + - **Note:** this extension only supports `http/s` - `@exclude-match` - Domain patterns where you do *not* want the script to run - `@include` - An alias for `@match` - functions exactly like `@match` - `@exclude` - An alias for `@exclude-match` - functions exactly like `@exclude-match` From 2c8445b08c6dbd6f5a12ec861471e012cd81d2eb Mon Sep 17 00:00:00 2001 From: quoid Date: Sun, 30 May 2021 14:26:23 -0400 Subject: [PATCH 12/12] formatting --- rollup.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/rollup.config.js b/rollup.config.js index 80add7e2..b3e38a94 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,4 +1,3 @@ -// install eslint import svelte from "rollup-plugin-svelte"; import resolve from "@rollup/plugin-node-resolve"; import commonjs from "@rollup/plugin-commonjs";