├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Refined GitHub Extension ├── Info.plist ├── Refined_GitHub_Extension.entitlements ├── SafariExtensionHandler.swift ├── chrome.js ├── safari.css └── styles.js ├── Refined GitHub for Safari.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── swiftpm │ │ └── Package.resolved └── xcshareddata │ └── xcschemes │ ├── Refined GitHub for Safari Extension.xcscheme │ └── Refined GitHub for Safari.xcscheme ├── Refined GitHub ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── icon.png │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist ├── Refined_GitHub.entitlements ├── Resources │ └── Credits.html ├── Settings.swift └── ViewController.swift ├── Refined GitHubTests ├── Info.plist └── Refined_GitHubTests.swift ├── Refined GitHubUITests ├── Info.plist └── Refined_GitHubUITests.swift ├── bin ├── travis-push-submodule-update ├── travis-update-submodule ├── xcode-project-clean └── xcode-project-smudge ├── fastlane ├── Appfile ├── Fastfile ├── Pluginfile └── README.md ├── package-lock.json └── package.json /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj merge=union filter=xcode-project 2 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: macos-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | with: 12 | submodules: true 13 | - name: Use Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: 14.x 17 | - run: npm ci 18 | - run: npm run build --if-present 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | build 64 | 65 | xcuserdata/ 66 | Refined GitHub Extension/build 67 | 68 | fastlane/report.xml 69 | 70 | # Bundler configuration 71 | .bundle 72 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "refined-github"] 2 | path = refined-github 3 | url = https://github.com/sindresorhus/refined-github.git 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } 6 | 7 | gem "fastlane" 8 | 9 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 10 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 11 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.3) 5 | addressable (2.7.0) 6 | public_suffix (>= 2.0.2, < 5.0) 7 | atomos (0.1.3) 8 | aws-eventstream (1.1.0) 9 | aws-partitions (1.414.0) 10 | aws-sdk-core (3.110.0) 11 | aws-eventstream (~> 1, >= 1.0.2) 12 | aws-partitions (~> 1, >= 1.239.0) 13 | aws-sigv4 (~> 1.1) 14 | jmespath (~> 1.0) 15 | aws-sdk-kms (1.40.0) 16 | aws-sdk-core (~> 3, >= 3.109.0) 17 | aws-sigv4 (~> 1.1) 18 | aws-sdk-s3 (1.87.0) 19 | aws-sdk-core (~> 3, >= 3.109.0) 20 | aws-sdk-kms (~> 1) 21 | aws-sigv4 (~> 1.1) 22 | aws-sigv4 (1.2.2) 23 | aws-eventstream (~> 1, >= 1.0.2) 24 | babosa (1.0.4) 25 | claide (1.0.3) 26 | colored (1.2) 27 | colored2 (3.1.2) 28 | commander-fastlane (4.4.6) 29 | highline (~> 1.7.2) 30 | declarative (0.0.20) 31 | declarative-option (0.1.0) 32 | digest-crc (0.6.3) 33 | rake (>= 12.0.0, < 14.0.0) 34 | domain_name (0.5.20190701) 35 | unf (>= 0.0.5, < 1.0.0) 36 | dotenv (2.7.6) 37 | emoji_regex (3.2.1) 38 | excon (0.78.1) 39 | faraday (1.3.0) 40 | faraday-net_http (~> 1.0) 41 | multipart-post (>= 1.2, < 3) 42 | ruby2_keywords 43 | faraday-cookie_jar (0.0.7) 44 | faraday (>= 0.8.0) 45 | http-cookie (~> 1.0.0) 46 | faraday-net_http (1.0.0) 47 | faraday_middleware (1.0.0) 48 | faraday (~> 1.0) 49 | fastimage (2.2.1) 50 | fastlane (2.171.0) 51 | CFPropertyList (>= 2.3, < 4.0.0) 52 | addressable (>= 2.3, < 3.0.0) 53 | aws-sdk-s3 (~> 1.0) 54 | babosa (>= 1.0.3, < 2.0.0) 55 | bundler (>= 1.12.0, < 3.0.0) 56 | colored 57 | commander-fastlane (>= 4.4.6, < 5.0.0) 58 | dotenv (>= 2.1.1, < 3.0.0) 59 | emoji_regex (>= 0.1, < 4.0) 60 | excon (>= 0.71.0, < 1.0.0) 61 | faraday (~> 1.0) 62 | faraday-cookie_jar (~> 0.0.6) 63 | faraday_middleware (~> 1.0) 64 | fastimage (>= 2.1.0, < 3.0.0) 65 | gh_inspector (>= 1.1.2, < 2.0.0) 66 | google-api-client (>= 0.37.0, < 0.39.0) 67 | google-cloud-storage (>= 1.15.0, < 2.0.0) 68 | highline (>= 1.7.2, < 2.0.0) 69 | json (< 3.0.0) 70 | jwt (>= 2.1.0, < 3) 71 | mini_magick (>= 4.9.4, < 5.0.0) 72 | multipart-post (~> 2.0.0) 73 | plist (>= 3.1.0, < 4.0.0) 74 | rubyzip (>= 2.0.0, < 3.0.0) 75 | security (= 0.1.3) 76 | simctl (~> 1.6.3) 77 | slack-notifier (>= 2.0.0, < 3.0.0) 78 | terminal-notifier (>= 2.0.0, < 3.0.0) 79 | terminal-table (>= 1.4.5, < 2.0.0) 80 | tty-screen (>= 0.6.3, < 1.0.0) 81 | tty-spinner (>= 0.8.0, < 1.0.0) 82 | word_wrap (~> 1.0.0) 83 | xcodeproj (>= 1.13.0, < 2.0.0) 84 | xcpretty (~> 0.3.0) 85 | xcpretty-travis-formatter (>= 0.0.3) 86 | fastlane-plugin-versioning (0.4.4) 87 | gh_inspector (1.1.3) 88 | google-api-client (0.38.0) 89 | addressable (~> 2.5, >= 2.5.1) 90 | googleauth (~> 0.9) 91 | httpclient (>= 2.8.1, < 3.0) 92 | mini_mime (~> 1.0) 93 | representable (~> 3.0) 94 | retriable (>= 2.0, < 4.0) 95 | signet (~> 0.12) 96 | google-cloud-core (1.5.0) 97 | google-cloud-env (~> 1.0) 98 | google-cloud-errors (~> 1.0) 99 | google-cloud-env (1.4.0) 100 | faraday (>= 0.17.3, < 2.0) 101 | google-cloud-errors (1.0.1) 102 | google-cloud-storage (1.29.2) 103 | addressable (~> 2.5) 104 | digest-crc (~> 0.4) 105 | google-api-client (~> 0.33) 106 | google-cloud-core (~> 1.2) 107 | googleauth (~> 0.9) 108 | mini_mime (~> 1.0) 109 | googleauth (0.14.0) 110 | faraday (>= 0.17.3, < 2.0) 111 | jwt (>= 1.4, < 3.0) 112 | memoist (~> 0.16) 113 | multi_json (~> 1.11) 114 | os (>= 0.9, < 2.0) 115 | signet (~> 0.14) 116 | highline (1.7.10) 117 | http-cookie (1.0.3) 118 | domain_name (~> 0.5) 119 | httpclient (2.8.3) 120 | jmespath (1.4.0) 121 | json (2.5.1) 122 | jwt (2.2.2) 123 | memoist (0.16.2) 124 | mini_magick (4.11.0) 125 | mini_mime (1.0.2) 126 | multi_json (1.15.0) 127 | multipart-post (2.0.0) 128 | nanaimo (0.3.0) 129 | naturally (2.2.0) 130 | os (1.1.1) 131 | plist (3.6.0) 132 | public_suffix (4.0.6) 133 | rake (13.0.3) 134 | representable (3.0.4) 135 | declarative (< 0.1.0) 136 | declarative-option (< 0.2.0) 137 | uber (< 0.2.0) 138 | retriable (3.1.2) 139 | rouge (2.0.7) 140 | ruby2_keywords (0.0.2) 141 | rubyzip (2.3.0) 142 | security (0.1.3) 143 | signet (0.14.0) 144 | addressable (~> 2.3) 145 | faraday (>= 0.17.3, < 2.0) 146 | jwt (>= 1.5, < 3.0) 147 | multi_json (~> 1.10) 148 | simctl (1.6.8) 149 | CFPropertyList 150 | naturally 151 | slack-notifier (2.3.2) 152 | terminal-notifier (2.0.0) 153 | terminal-table (1.8.0) 154 | unicode-display_width (~> 1.1, >= 1.1.1) 155 | tty-cursor (0.7.1) 156 | tty-screen (0.8.1) 157 | tty-spinner (0.9.3) 158 | tty-cursor (~> 0.7) 159 | uber (0.1.0) 160 | unf (0.1.4) 161 | unf_ext 162 | unf_ext (0.0.7.7) 163 | unicode-display_width (1.7.0) 164 | word_wrap (1.0.0) 165 | xcodeproj (1.19.0) 166 | CFPropertyList (>= 2.3.3, < 4.0) 167 | atomos (~> 0.1.3) 168 | claide (>= 1.0.2, < 2.0) 169 | colored2 (~> 3.1) 170 | nanaimo (~> 0.3.0) 171 | xcpretty (0.3.0) 172 | rouge (~> 2.0.7) 173 | xcpretty-travis-formatter (1.0.1) 174 | xcpretty (~> 0.2, >= 0.0.7) 175 | 176 | PLATFORMS 177 | ruby 178 | 179 | DEPENDENCIES 180 | fastlane 181 | fastlane-plugin-versioning 182 | 183 | BUNDLED WITH 184 | 2.1.4 185 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2018, Ville Lautanala 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATED: Refined GitHub for Safari 2 | 3 | This project is no longer required. The original [Refined GitHub](https://github.com/sindresorhus/refined-github) is available on [Mac App Store](https://apps.apple.com/app/id1519867270). 4 | 5 | ## Install 6 | 7 | [Download latest release](https://github.com/lautis/refined-github-safari/releases) 8 | 9 | Or using homebrew: 10 | 11 | ```sh 12 | brew install --cask refined-github-safari 13 | ``` 14 | 15 | After this, start the app, and enable Refined Github for Safari in Safari Extensions Preferences. 16 | 17 | ## Development 18 | 19 | Before starting, git submodules should be checked out (`git submodule update --init`) and [Node](https://nodejs.org/en/) should be installed. 20 | 21 | Then, install required dependencies with 22 | 23 | ``` 24 | npm install 25 | ``` 26 | 27 | After this, running 28 | 29 | ``` 30 | npm run build 31 | ``` 32 | 33 | will build the required JS file to "Refined GitHub Extension" directory. 34 | 35 | Open Xcode and make these changes for both the application and extension targets: 36 | 37 | - In General > Identity change the bundle identifier to reverse DNS format. Make sure the extension target has the `-extension` suffix. 38 | - In General > Signing set your team. Xcode should take care of the provisioning profile and certificate automatically. 39 | 40 | Then, build Refined GitHub for Safari.app with 41 | 42 | ``` 43 | xcodebuild 44 | ``` 45 | 46 | The built app will be located in build/Release. 47 | 48 | ## Git attributes 49 | 50 | For working builds while keeping the Git repository clean, there are shell scripts to help with [Git attributes](https://git-scm.com/docs/gitattributes). 51 | 52 | Enable this with 53 | 54 | ``` 55 | git config filter.xcode-project.clean bin/xcode-project-clean DEVELOPMENT_TEAM_ID BUNDLE_IDENTIFIER 56 | git config filter.xcode-project.smudge bin/xcode-project-smudge DEVELOPMENT_TEAM_ID BUNDLE_IDENTIFIER 57 | ``` 58 | 59 | but replace the values with your Xcode Development Team id and bundle identifier. 60 | 61 | ## Alternatives 62 | 63 | This repository is not the first attempt to create a Safari version of Refined GitHub. There are at least two other similar projects: 64 | 65 | * [Safari wrapper by @fantattitude](https://github.com/fantattitude/refined-github-safari) 66 | * [Safari fork by @mathieudutour](https://github.com/mathieudutour/refined-github-safari) 67 | 68 | These are implemented as Legacy Safari Extension, and not Safari App Extensions. 69 | -------------------------------------------------------------------------------- /Refined GitHub Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Refined GitHub for Safari Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSApplicationCategoryType 24 | 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSExtension 28 | 29 | NSExtensionPointIdentifier 30 | com.apple.Safari.extension 31 | NSExtensionPrincipalClass 32 | $(PRODUCT_MODULE_NAME).SafariExtensionHandler 33 | SFSafariContentScript 34 | 35 | 36 | Script 37 | chrome.js 38 | 39 | 40 | Script 41 | build/refined-github.js 42 | 43 | 44 | Script 45 | styles.js 46 | 47 | 48 | Script 49 | build/resolve-conflicts.js 50 | 51 | 52 | SFSafariWebsiteAccess 53 | 54 | Allowed Domains 55 | 56 | github.com 57 | gist.github.com 58 | 59 | Include Secure Pages 60 | 61 | Level 62 | Some 63 | 64 | 65 | NSHumanReadableCopyright 66 | Copyright © 2019 Ville Lautanala. All rights reserved. 67 | NSHumanReadableDescription 68 | Browser extension that simplifies the GitHub interface and adds useful features. 69 | 70 | 71 | -------------------------------------------------------------------------------- /Refined GitHub Extension/Refined_GitHub_Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | keychain-access-groups 10 | 11 | $(AppIdentifierPrefix)fi.lautanala.refined-github-shared 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Refined GitHub Extension/SafariExtensionHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SafariExtensionHandler.swift 3 | // Refined GitHub for Safari Extension 4 | // 5 | // Created by Ville Lautanala on 17/02/2019. 6 | // Copyright © 2019 Ville Lautanala. All rights reserved. 7 | // 8 | 9 | import SafariServices 10 | 11 | class SafariExtensionHandler: SFSafariExtensionHandler { 12 | var syncData: [String: Any] = [ 13 | "options": [ 14 | "customCSS": "", 15 | "personalToken": Settings.shared.personalToken, 16 | "logging": true, 17 | "feature:recently-pushed-branches-enhancements": false, 18 | "feature:mark-unread": false, 19 | "feature:more-dropdown": false, 20 | "feature:pinned-issues-update-time": false, 21 | "feature:releases-tab": false, 22 | "feature:split-issue-pr-search-results": false, 23 | "feature:tags-dropdown": false, 24 | 25 | ] 26 | ]; 27 | var localData = [String: Any](); 28 | 29 | func getValues(data: [K: V], keys: [K]?) -> [K: V] { 30 | if let stringKeys = keys { 31 | return stringKeys.reduce(into: [K: V]()) { values, key in 32 | values[key] = data[key] 33 | } 34 | } else { 35 | return data 36 | } 37 | } 38 | 39 | func respondGet(userInfo: [String : Any]?, from page: SFSafariPage) { 40 | guard let payload = userInfo else { return } 41 | guard let namespace = payload["namespace"] as? String else { return } 42 | let keys = payload["keys"] as? [String] 43 | 44 | let data = self.readLocalStorage(namespace: namespace) 45 | let value = self.getValues(data: data, keys: keys) 46 | 47 | if let id = payload["id"] as? String { 48 | page.dispatchMessageToScript(withName: "get-response", userInfo: [ 49 | "id": id, 50 | "value": value 51 | ]) 52 | } 53 | } 54 | 55 | func readLocalStorage(namespace: String) -> [String: Any] { 56 | if (namespace == "sync") { 57 | return self.syncData; 58 | } else { 59 | return self.localData; 60 | } 61 | } 62 | 63 | func respondClear(userInfo: [String : Any]?, from page: SFSafariPage) { 64 | guard let message = userInfo else { return } 65 | guard let namespace = message["namespace"] as? String else { return } 66 | 67 | let oldValue = self.readLocalStorage(namespace: namespace) 68 | let newValue: [String: Any] = [:]; 69 | 70 | if (namespace == "sync") { 71 | self.syncData = newValue 72 | } else { 73 | self.localData = newValue 74 | } 75 | 76 | // TODO: all pages / windows 77 | page.dispatchMessageToScript(withName: "storage-change", userInfo: ["old": self.getValues(data: oldValue, keys: Array(oldValue.keys)), "new": newValue, namespace: namespace]) 78 | 79 | if let id = message["id"] as? String { 80 | page.dispatchMessageToScript(withName: "set-response", userInfo: [ 81 | "id": id 82 | ]) 83 | } 84 | } 85 | 86 | func respondRemove(userInfo: [String : Any]?, from page: SFSafariPage) { 87 | guard let message = userInfo else { return } 88 | guard let namespace = message["namespace"] as? String else { return } 89 | guard let values = message["values"] as? Array else { return } 90 | 91 | let oldValue = self.readLocalStorage(namespace: namespace) 92 | let newValue = oldValue.filter({ values.contains($0.0) }); 93 | 94 | if (namespace == "sync") { 95 | self.syncData = newValue 96 | } else { 97 | self.localData = newValue 98 | } 99 | 100 | // TODO: all pages / windows 101 | page.dispatchMessageToScript(withName: "storage-change", userInfo: ["old": self.getValues(data: oldValue, keys: Array(values)), "new": values, namespace: namespace]) 102 | 103 | if let id = message["id"] as? String { 104 | page.dispatchMessageToScript(withName: "set-response", userInfo: [ 105 | "id": id 106 | ]) 107 | } 108 | } 109 | 110 | func respondSet(userInfo: [String : Any]?, from page: SFSafariPage) { 111 | guard let message = userInfo else { return } 112 | guard let namespace = message["namespace"] as? String else { return } 113 | guard let values = message["values"] as? Dictionary else { return } 114 | 115 | let oldValue = self.readLocalStorage(namespace: namespace) 116 | let newValue = oldValue.merging(values) { (_, last) in last } 117 | 118 | if (namespace == "sync") { 119 | self.syncData = newValue 120 | } else { 121 | self.localData = newValue 122 | } 123 | 124 | // TODO: all pages / windows 125 | page.dispatchMessageToScript(withName: "storage-change", userInfo: ["old": self.getValues(data: oldValue, keys: Array(values.keys)), "new": values, namespace: namespace]) 126 | 127 | if let id = message["id"] as? String { 128 | page.dispatchMessageToScript(withName: "set-response", userInfo: [ 129 | "id": id 130 | ]) 131 | } 132 | } 133 | func respondMessage(userInfo: [String : Any]?, from page: SFSafariPage) { 134 | guard let payload = userInfo else { return } 135 | guard let payloadUrls = payload["openUrls"] as? [String] else { return } 136 | 137 | let urls = payloadUrls.compactMap { URL(string: $0) } 138 | 139 | SFSafariApplication.getActiveWindow { (activeWindow) in 140 | urls.forEach({ (url) in activeWindow?.openTab(with: url, makeActiveIfPossible: false) }) 141 | } 142 | } 143 | 144 | override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) { 145 | 146 | switch (messageName) { 147 | case "clear": 148 | self.respondClear(userInfo: userInfo, from: page) 149 | case "get": 150 | self.respondGet(userInfo: userInfo, from: page) 151 | case "remove": 152 | self.respondRemove(userInfo: userInfo, from: page) 153 | case "set": 154 | self.respondSet(userInfo: userInfo, from: page) 155 | case "message": 156 | self.respondMessage(userInfo: userInfo, from: page) 157 | default: 158 | NSLog("Received unkown message with userInfo (\(userInfo ?? [:]))") 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /Refined GitHub Extension/chrome.js: -------------------------------------------------------------------------------- 1 | // Mock chrome.storage API for Safari 2 | const uniqueId = () => 3 | Math.random() 4 | .toString(36) 5 | .replace(/[^a-z]+/g, "") 6 | .substr(2, 10); 7 | 8 | const storageCalls = new Map(); 9 | const storageChangeListeners = []; 10 | 11 | const changes = (oldValue, newValue) => { 12 | return Object.keys(newValue).reduce((diff, key) => { 13 | if (oldValue[key] === newValue[key]) { 14 | return diff; 15 | } 16 | 17 | return { 18 | ...diff, 19 | [key]: { oldValue: oldValue[key], newValue: newValue[key] } 20 | }; 21 | }, {}); 22 | }; 23 | 24 | 25 | const respondToMessage = event => { 26 | if (event.name === "get-response") { 27 | const resolver = storageCalls.get(event.message.id); 28 | if (resolver) { 29 | resolver(event.message.value); 30 | storageCalls.delete(event.message.id); 31 | } 32 | } else if (event.name === "storage-change") { 33 | storageChangeListeners.forEach(listener => 34 | listener(changes(event.message.old, event.message.new), event.message.namespace) 35 | ); 36 | } 37 | }; 38 | 39 | safari.self.addEventListener("message", respondToMessage); 40 | 41 | const storage = namespace => { 42 | return { 43 | clear(callback) { 44 | safari.extension.dispatchMessage("clear", { namespace }); 45 | if (callback) callback(); 46 | return Promise.resolve(); 47 | }, 48 | get(keys, callback) { 49 | const transformResponse = (response) => { 50 | if (Array.isArray(keys)) { 51 | return keys 52 | .map(key => [key, data[key]]) 53 | .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {}); 54 | } else if (typeof keys === "object") { 55 | return Object.entries(keys) 56 | .map(([key, value]) => [key, response[key] || value]) 57 | .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {}); 58 | } else { 59 | return response; 60 | } 61 | } 62 | 63 | const normalizeKeys = () => { 64 | if (typeof keys === "string") { 65 | return [keys]; 66 | } else if (Array.isArray(keys)) { 67 | return keys; 68 | } else if (typeof keys === "object") { 69 | return Object.keys(keys); 70 | } else { 71 | return undefined; 72 | } 73 | } 74 | 75 | const id = uniqueId(); 76 | return new Promise(resolve => { 77 | storageCalls.set(id, response => { 78 | const value = transformResponse(response); 79 | resolve(value); 80 | if (callback) { 81 | callback(value); 82 | } 83 | }); 84 | safari.extension.dispatchMessage("get", { id, keys: normalizeKeys(keys), namespace }); 85 | }); 86 | }, 87 | remove(values, callback) { 88 | safari.extension.dispatchMessage("remove", { values, namespace }); 89 | if (callback) callback(); 90 | return Promise.resolve(); 91 | }, 92 | set(values, callback) { 93 | safari.extension.dispatchMessage("set", { values, namespace }); 94 | if (callback) callback(); 95 | return Promise.resolve(); 96 | } 97 | }; 98 | }; 99 | 100 | browser = chrome = { 101 | runtime: { 102 | getManifest() { 103 | return { 104 | name: "Refined Github for Safari" 105 | } 106 | }, 107 | getURL(file) { 108 | return safari.extension.baseURI + name; 109 | }, 110 | onMessage: { 111 | addListener: () => null 112 | }, 113 | sendMessage(message) { 114 | safari.extension.dispatchMessage("message", message); 115 | }, 116 | lastError: null 117 | }, 118 | storage: { 119 | onChanged: { 120 | addListener(listener) { 121 | storageChangeListeners.push(listener); 122 | } 123 | }, 124 | local: storage("local"), 125 | sync: storage("sync") 126 | } 127 | }; 128 | -------------------------------------------------------------------------------- /Refined GitHub Extension/safari.css: -------------------------------------------------------------------------------- 1 | .subnav-search-context .dropdown-caret { 2 | position: relative; 3 | top: -0.8em; 4 | margin-bottom: -4px; 5 | } 6 | -------------------------------------------------------------------------------- /Refined GitHub Extension/styles.js: -------------------------------------------------------------------------------- 1 | function addStylesheet(name) { 2 | const link = document.createElement("link"); 3 | link.type = "text/css"; 4 | link.rel = "stylesheet"; 5 | link.href = safari.extension.baseURI + name; 6 | document.head.appendChild(link); 7 | } 8 | 9 | const observer = new MutationObserver(() => { 10 | if (document.body) { 11 | addStylesheet("build/refined-github.css"); 12 | addStylesheet("safari.css"); 13 | observer.disconnect(); 14 | } 15 | }); 16 | observer.observe(document, {childList: true, subtree: true}) 17 | -------------------------------------------------------------------------------- /Refined GitHub for Safari.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 767D0346222184FA0025A3B7 /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = 767D0345222184FA0025A3B7 /* Credits.html */; }; 11 | 768006A22482C8EB002B7FC1 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 768006A12482C8EB002B7FC1 /* SwiftPackageProductDependency */; }; 12 | 768006A42482C909002B7FC1 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 768006A32482C909002B7FC1 /* Settings.swift */; }; 13 | 768006A52482C909002B7FC1 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 768006A32482C909002B7FC1 /* Settings.swift */; }; 14 | 768006A72482CABB002B7FC1 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 768006A62482CABB002B7FC1 /* SwiftPackageProductDependency */; }; 15 | 7685136E253B3B7C00AC6073 /* build in Resources */ = {isa = PBXBuildFile; fileRef = 7685135D253B3A5400AC6073 /* build */; }; 16 | 76E22A4A221A414C00C30087 /* Refined_GitHub.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = 76E22A49221A414C00C30087 /* Refined_GitHub.entitlements */; }; 17 | 76E22A4C221A414C00C30087 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E22A4B221A414C00C30087 /* AppDelegate.swift */; }; 18 | 76E22A4F221A414C00C30087 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 76E22A4D221A414C00C30087 /* Main.storyboard */; }; 19 | 76E22A51221A414C00C30087 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E22A50221A414C00C30087 /* ViewController.swift */; }; 20 | 76E22A53221A414E00C30087 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 76E22A52221A414E00C30087 /* Assets.xcassets */; }; 21 | 76E22A5E221A414E00C30087 /* Refined_GitHubTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E22A5D221A414E00C30087 /* Refined_GitHubTests.swift */; }; 22 | 76E22A69221A414E00C30087 /* Refined_GitHubUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E22A68221A414E00C30087 /* Refined_GitHubUITests.swift */; }; 23 | 76E22A70221A414E00C30087 /* Refined GitHub for Safari Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 76E22A6F221A414E00C30087 /* Refined GitHub for Safari Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 24 | 76E22A75221A414E00C30087 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 76E22A74221A414E00C30087 /* Cocoa.framework */; }; 25 | 76E22A78221A414E00C30087 /* SafariExtensionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76E22A77221A414E00C30087 /* SafariExtensionHandler.swift */; }; 26 | 76E22A9C221B9A5E00C30087 /* styles.js in Resources */ = {isa = PBXBuildFile; fileRef = 76E22A9B221B9A5E00C30087 /* styles.js */; }; 27 | 76E22AA0221B9AC800C30087 /* chrome.js in Resources */ = {isa = PBXBuildFile; fileRef = 76E22A9F221B9AC800C30087 /* chrome.js */; }; 28 | 76E86690229AA18C00B9041C /* safari.css in Resources */ = {isa = PBXBuildFile; fileRef = 76E8668F229AA18C00B9041C /* safari.css */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 76E22A5A221A414E00C30087 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 76E22A3E221A414B00C30087 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 76E22A45221A414B00C30087; 37 | remoteInfo = "Refined GitHub for Safari"; 38 | }; 39 | 76E22A65221A414E00C30087 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = 76E22A3E221A414B00C30087 /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = 76E22A45221A414B00C30087; 44 | remoteInfo = "Refined GitHub for Safari"; 45 | }; 46 | 76E22A71221A414E00C30087 /* PBXContainerItemProxy */ = { 47 | isa = PBXContainerItemProxy; 48 | containerPortal = 76E22A3E221A414B00C30087 /* Project object */; 49 | proxyType = 1; 50 | remoteGlobalIDString = 76E22A6E221A414E00C30087; 51 | remoteInfo = "Refined GitHub for Safari Extension"; 52 | }; 53 | /* End PBXContainerItemProxy section */ 54 | 55 | /* Begin PBXCopyFilesBuildPhase section */ 56 | 76E22A89221A414E00C30087 /* Embed App Extensions */ = { 57 | isa = PBXCopyFilesBuildPhase; 58 | buildActionMask = 2147483647; 59 | dstPath = ""; 60 | dstSubfolderSpec = 13; 61 | files = ( 62 | 76E22A70221A414E00C30087 /* Refined GitHub for Safari Extension.appex in Embed App Extensions */, 63 | ); 64 | name = "Embed App Extensions"; 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXCopyFilesBuildPhase section */ 68 | 69 | /* Begin PBXFileReference section */ 70 | 767D0345222184FA0025A3B7 /* Credits.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = Credits.html; sourceTree = ""; }; 71 | 768006A32482C909002B7FC1 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; 72 | 7685135D253B3A5400AC6073 /* build */ = {isa = PBXFileReference; lastKnownFileType = folder; path = build; sourceTree = ""; }; 73 | 76E22A46221A414C00C30087 /* Refined GitHub for Safari.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Refined GitHub for Safari.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 76E22A49221A414C00C30087 /* Refined_GitHub.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Refined_GitHub.entitlements; sourceTree = ""; }; 75 | 76E22A4B221A414C00C30087 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 76 | 76E22A4E221A414C00C30087 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 77 | 76E22A50221A414C00C30087 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 78 | 76E22A52221A414E00C30087 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 79 | 76E22A54221A414E00C30087 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 80 | 76E22A59221A414E00C30087 /* Refined GitHubTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Refined GitHubTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | 76E22A5D221A414E00C30087 /* Refined_GitHubTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Refined_GitHubTests.swift; sourceTree = ""; }; 82 | 76E22A5F221A414E00C30087 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 83 | 76E22A64221A414E00C30087 /* Refined GitHubUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Refined GitHubUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | 76E22A68221A414E00C30087 /* Refined_GitHubUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Refined_GitHubUITests.swift; sourceTree = ""; }; 85 | 76E22A6A221A414E00C30087 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 86 | 76E22A6F221A414E00C30087 /* Refined GitHub for Safari Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Refined GitHub for Safari Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 87 | 76E22A74221A414E00C30087 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 88 | 76E22A77221A414E00C30087 /* SafariExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariExtensionHandler.swift; sourceTree = ""; }; 89 | 76E22A7E221A414E00C30087 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 90 | 76E22A83221A414E00C30087 /* Refined_GitHub_Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Refined_GitHub_Extension.entitlements; sourceTree = ""; }; 91 | 76E22A9B221B9A5E00C30087 /* styles.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = styles.js; sourceTree = ""; }; 92 | 76E22A9F221B9AC800C30087 /* chrome.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = chrome.js; sourceTree = ""; }; 93 | 76E8668F229AA18C00B9041C /* safari.css */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text.css; path = safari.css; sourceTree = ""; tabWidth = 2; usesTabs = 0; }; 94 | /* End PBXFileReference section */ 95 | 96 | /* Begin PBXFrameworksBuildPhase section */ 97 | 76E22A43221A414B00C30087 /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | 768006A22482C8EB002B7FC1 /* BuildFile in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | 76E22A56221A414E00C30087 /* Frameworks */ = { 106 | isa = PBXFrameworksBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | ); 110 | runOnlyForDeploymentPostprocessing = 0; 111 | }; 112 | 76E22A61221A414E00C30087 /* Frameworks */ = { 113 | isa = PBXFrameworksBuildPhase; 114 | buildActionMask = 2147483647; 115 | files = ( 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | 76E22A6C221A414E00C30087 /* Frameworks */ = { 120 | isa = PBXFrameworksBuildPhase; 121 | buildActionMask = 2147483647; 122 | files = ( 123 | 768006A72482CABB002B7FC1 /* BuildFile in Frameworks */, 124 | 76E22A75221A414E00C30087 /* Cocoa.framework in Frameworks */, 125 | ); 126 | runOnlyForDeploymentPostprocessing = 0; 127 | }; 128 | /* End PBXFrameworksBuildPhase section */ 129 | 130 | /* Begin PBXGroup section */ 131 | 767D0344222184810025A3B7 /* Resources */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 767D0345222184FA0025A3B7 /* Credits.html */, 135 | ); 136 | path = Resources; 137 | sourceTree = ""; 138 | }; 139 | 76E22A3D221A414B00C30087 = { 140 | isa = PBXGroup; 141 | children = ( 142 | 76E22A48221A414C00C30087 /* Refined GitHub */, 143 | 76E22A5C221A414E00C30087 /* Refined GitHubTests */, 144 | 76E22A67221A414E00C30087 /* Refined GitHubUITests */, 145 | 76E22A76221A414E00C30087 /* Refined GitHub Extension */, 146 | 76E22A73221A414E00C30087 /* Frameworks */, 147 | 76E22A47221A414C00C30087 /* Products */, 148 | ); 149 | sourceTree = ""; 150 | }; 151 | 76E22A47221A414C00C30087 /* Products */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 76E22A46221A414C00C30087 /* Refined GitHub for Safari.app */, 155 | 76E22A59221A414E00C30087 /* Refined GitHubTests.xctest */, 156 | 76E22A64221A414E00C30087 /* Refined GitHubUITests.xctest */, 157 | 76E22A6F221A414E00C30087 /* Refined GitHub for Safari Extension.appex */, 158 | ); 159 | name = Products; 160 | sourceTree = ""; 161 | }; 162 | 76E22A48221A414C00C30087 /* Refined GitHub */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 767D0344222184810025A3B7 /* Resources */, 166 | 76E22A49221A414C00C30087 /* Refined_GitHub.entitlements */, 167 | 76E22A4B221A414C00C30087 /* AppDelegate.swift */, 168 | 76E22A4D221A414C00C30087 /* Main.storyboard */, 169 | 76E22A50221A414C00C30087 /* ViewController.swift */, 170 | 76E22A52221A414E00C30087 /* Assets.xcassets */, 171 | 76E22A54221A414E00C30087 /* Info.plist */, 172 | 768006A32482C909002B7FC1 /* Settings.swift */, 173 | ); 174 | path = "Refined GitHub"; 175 | sourceTree = ""; 176 | }; 177 | 76E22A5C221A414E00C30087 /* Refined GitHubTests */ = { 178 | isa = PBXGroup; 179 | children = ( 180 | 76E22A5D221A414E00C30087 /* Refined_GitHubTests.swift */, 181 | 76E22A5F221A414E00C30087 /* Info.plist */, 182 | ); 183 | path = "Refined GitHubTests"; 184 | sourceTree = ""; 185 | }; 186 | 76E22A67221A414E00C30087 /* Refined GitHubUITests */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | 76E22A68221A414E00C30087 /* Refined_GitHubUITests.swift */, 190 | 76E22A6A221A414E00C30087 /* Info.plist */, 191 | ); 192 | path = "Refined GitHubUITests"; 193 | sourceTree = ""; 194 | }; 195 | 76E22A73221A414E00C30087 /* Frameworks */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | 76E22A74221A414E00C30087 /* Cocoa.framework */, 199 | ); 200 | name = Frameworks; 201 | sourceTree = ""; 202 | }; 203 | 76E22A76221A414E00C30087 /* Refined GitHub Extension */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | 7685135D253B3A5400AC6073 /* build */, 207 | 76E22A9F221B9AC800C30087 /* chrome.js */, 208 | 76E22A9B221B9A5E00C30087 /* styles.js */, 209 | 76E8668F229AA18C00B9041C /* safari.css */, 210 | 76E22A77221A414E00C30087 /* SafariExtensionHandler.swift */, 211 | 76E22A7E221A414E00C30087 /* Info.plist */, 212 | 76E22A83221A414E00C30087 /* Refined_GitHub_Extension.entitlements */, 213 | ); 214 | path = "Refined GitHub Extension"; 215 | sourceTree = ""; 216 | }; 217 | /* End PBXGroup section */ 218 | 219 | /* Begin PBXNativeTarget section */ 220 | 76E22A45221A414B00C30087 /* Refined GitHub for Safari */ = { 221 | isa = PBXNativeTarget; 222 | buildConfigurationList = 76E22A8A221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHub for Safari" */; 223 | buildPhases = ( 224 | 76E22A42221A414B00C30087 /* Sources */, 225 | 76E22A43221A414B00C30087 /* Frameworks */, 226 | 76E22A44221A414B00C30087 /* Resources */, 227 | 76E22A89221A414E00C30087 /* Embed App Extensions */, 228 | ); 229 | buildRules = ( 230 | ); 231 | dependencies = ( 232 | 76E22A72221A414E00C30087 /* PBXTargetDependency */, 233 | ); 234 | name = "Refined GitHub for Safari"; 235 | packageProductDependencies = ( 236 | 768006A12482C8EB002B7FC1 /* SwiftPackageProductDependency */, 237 | ); 238 | productName = "Refined GitHub for Safari"; 239 | productReference = 76E22A46221A414C00C30087 /* Refined GitHub for Safari.app */; 240 | productType = "com.apple.product-type.application"; 241 | }; 242 | 76E22A58221A414E00C30087 /* Refined GitHubTests */ = { 243 | isa = PBXNativeTarget; 244 | buildConfigurationList = 76E22A8D221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHubTests" */; 245 | buildPhases = ( 246 | 76E22A55221A414E00C30087 /* Sources */, 247 | 76E22A56221A414E00C30087 /* Frameworks */, 248 | 76E22A57221A414E00C30087 /* Resources */, 249 | ); 250 | buildRules = ( 251 | ); 252 | dependencies = ( 253 | 76E22A5B221A414E00C30087 /* PBXTargetDependency */, 254 | ); 255 | name = "Refined GitHubTests"; 256 | productName = "Refined GitHubTests"; 257 | productReference = 76E22A59221A414E00C30087 /* Refined GitHubTests.xctest */; 258 | productType = "com.apple.product-type.bundle.unit-test"; 259 | }; 260 | 76E22A63221A414E00C30087 /* Refined GitHubUITests */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = 76E22A90221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHubUITests" */; 263 | buildPhases = ( 264 | 76E22A60221A414E00C30087 /* Sources */, 265 | 76E22A61221A414E00C30087 /* Frameworks */, 266 | 76E22A62221A414E00C30087 /* Resources */, 267 | ); 268 | buildRules = ( 269 | ); 270 | dependencies = ( 271 | 76E22A66221A414E00C30087 /* PBXTargetDependency */, 272 | ); 273 | name = "Refined GitHubUITests"; 274 | productName = "Refined GitHubUITests"; 275 | productReference = 76E22A64221A414E00C30087 /* Refined GitHubUITests.xctest */; 276 | productType = "com.apple.product-type.bundle.ui-testing"; 277 | }; 278 | 76E22A6E221A414E00C30087 /* Refined GitHub for Safari Extension */ = { 279 | isa = PBXNativeTarget; 280 | buildConfigurationList = 76E22A86221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHub for Safari Extension" */; 281 | buildPhases = ( 282 | 76E22A6B221A414E00C30087 /* Sources */, 283 | 76E22A6C221A414E00C30087 /* Frameworks */, 284 | 76E22A6D221A414E00C30087 /* Resources */, 285 | ); 286 | buildRules = ( 287 | ); 288 | dependencies = ( 289 | ); 290 | name = "Refined GitHub for Safari Extension"; 291 | packageProductDependencies = ( 292 | 768006A62482CABB002B7FC1 /* SwiftPackageProductDependency */, 293 | ); 294 | productName = "Refined GitHub for Safari Extension"; 295 | productReference = 76E22A6F221A414E00C30087 /* Refined GitHub for Safari Extension.appex */; 296 | productType = "com.apple.product-type.app-extension"; 297 | }; 298 | /* End PBXNativeTarget section */ 299 | 300 | /* Begin PBXProject section */ 301 | 76E22A3E221A414B00C30087 /* Project object */ = { 302 | isa = PBXProject; 303 | attributes = { 304 | LastSwiftUpdateCheck = 1010; 305 | LastUpgradeCheck = 1200; 306 | ORGANIZATIONNAME = "Ville Lautanala"; 307 | TargetAttributes = { 308 | 76E22A45221A414B00C30087 = { 309 | CreatedOnToolsVersion = 10.1; 310 | SystemCapabilities = { 311 | com.apple.HardenedRuntime = { 312 | enabled = 1; 313 | }; 314 | }; 315 | }; 316 | 76E22A58221A414E00C30087 = { 317 | CreatedOnToolsVersion = 10.1; 318 | TestTargetID = 76E22A45221A414B00C30087; 319 | }; 320 | 76E22A63221A414E00C30087 = { 321 | CreatedOnToolsVersion = 10.1; 322 | TestTargetID = 76E22A45221A414B00C30087; 323 | }; 324 | 76E22A6E221A414E00C30087 = { 325 | CreatedOnToolsVersion = 10.1; 326 | SystemCapabilities = { 327 | com.apple.HardenedRuntime = { 328 | enabled = 1; 329 | }; 330 | }; 331 | }; 332 | }; 333 | }; 334 | buildConfigurationList = 76E22A41221A414B00C30087 /* Build configuration list for PBXProject "Refined GitHub for Safari" */; 335 | compatibilityVersion = "Xcode 12.0"; 336 | developmentRegion = en; 337 | hasScannedForEncodings = 0; 338 | knownRegions = ( 339 | en, 340 | Base, 341 | ); 342 | mainGroup = 76E22A3D221A414B00C30087; 343 | packageReferences = ( 344 | 768006A02482C8EB002B7FC1 /* RemoteSwiftPackageReference */, 345 | ); 346 | productRefGroup = 76E22A47221A414C00C30087 /* Products */; 347 | projectDirPath = ""; 348 | projectRoot = ""; 349 | targets = ( 350 | 76E22A45221A414B00C30087 /* Refined GitHub for Safari */, 351 | 76E22A58221A414E00C30087 /* Refined GitHubTests */, 352 | 76E22A63221A414E00C30087 /* Refined GitHubUITests */, 353 | 76E22A6E221A414E00C30087 /* Refined GitHub for Safari Extension */, 354 | ); 355 | }; 356 | /* End PBXProject section */ 357 | 358 | /* Begin PBXResourcesBuildPhase section */ 359 | 76E22A44221A414B00C30087 /* Resources */ = { 360 | isa = PBXResourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | 76E22A4A221A414C00C30087 /* Refined_GitHub.entitlements in Resources */, 364 | 767D0346222184FA0025A3B7 /* Credits.html in Resources */, 365 | 76E22A53221A414E00C30087 /* Assets.xcassets in Resources */, 366 | 76E22A4F221A414C00C30087 /* Main.storyboard in Resources */, 367 | ); 368 | runOnlyForDeploymentPostprocessing = 0; 369 | }; 370 | 76E22A57221A414E00C30087 /* Resources */ = { 371 | isa = PBXResourcesBuildPhase; 372 | buildActionMask = 2147483647; 373 | files = ( 374 | ); 375 | runOnlyForDeploymentPostprocessing = 0; 376 | }; 377 | 76E22A62221A414E00C30087 /* Resources */ = { 378 | isa = PBXResourcesBuildPhase; 379 | buildActionMask = 2147483647; 380 | files = ( 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | 76E22A6D221A414E00C30087 /* Resources */ = { 385 | isa = PBXResourcesBuildPhase; 386 | buildActionMask = 2147483647; 387 | files = ( 388 | 76E22A9C221B9A5E00C30087 /* styles.js in Resources */, 389 | 7685136E253B3B7C00AC6073 /* build in Resources */, 390 | 76E86690229AA18C00B9041C /* safari.css in Resources */, 391 | 76E22AA0221B9AC800C30087 /* chrome.js in Resources */, 392 | ); 393 | runOnlyForDeploymentPostprocessing = 0; 394 | }; 395 | /* End PBXResourcesBuildPhase section */ 396 | 397 | /* Begin PBXSourcesBuildPhase section */ 398 | 76E22A42221A414B00C30087 /* Sources */ = { 399 | isa = PBXSourcesBuildPhase; 400 | buildActionMask = 2147483647; 401 | files = ( 402 | 768006A42482C909002B7FC1 /* Settings.swift in Sources */, 403 | 76E22A51221A414C00C30087 /* ViewController.swift in Sources */, 404 | 76E22A4C221A414C00C30087 /* AppDelegate.swift in Sources */, 405 | ); 406 | runOnlyForDeploymentPostprocessing = 0; 407 | }; 408 | 76E22A55221A414E00C30087 /* Sources */ = { 409 | isa = PBXSourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | 76E22A5E221A414E00C30087 /* Refined_GitHubTests.swift in Sources */, 413 | ); 414 | runOnlyForDeploymentPostprocessing = 0; 415 | }; 416 | 76E22A60221A414E00C30087 /* Sources */ = { 417 | isa = PBXSourcesBuildPhase; 418 | buildActionMask = 2147483647; 419 | files = ( 420 | 76E22A69221A414E00C30087 /* Refined_GitHubUITests.swift in Sources */, 421 | ); 422 | runOnlyForDeploymentPostprocessing = 0; 423 | }; 424 | 76E22A6B221A414E00C30087 /* Sources */ = { 425 | isa = PBXSourcesBuildPhase; 426 | buildActionMask = 2147483647; 427 | files = ( 428 | 768006A52482C909002B7FC1 /* Settings.swift in Sources */, 429 | 76E22A78221A414E00C30087 /* SafariExtensionHandler.swift in Sources */, 430 | ); 431 | runOnlyForDeploymentPostprocessing = 0; 432 | }; 433 | /* End PBXSourcesBuildPhase section */ 434 | 435 | /* Begin PBXTargetDependency section */ 436 | 76E22A5B221A414E00C30087 /* PBXTargetDependency */ = { 437 | isa = PBXTargetDependency; 438 | target = 76E22A45221A414B00C30087 /* Refined GitHub for Safari */; 439 | targetProxy = 76E22A5A221A414E00C30087 /* PBXContainerItemProxy */; 440 | }; 441 | 76E22A66221A414E00C30087 /* PBXTargetDependency */ = { 442 | isa = PBXTargetDependency; 443 | target = 76E22A45221A414B00C30087 /* Refined GitHub for Safari */; 444 | targetProxy = 76E22A65221A414E00C30087 /* PBXContainerItemProxy */; 445 | }; 446 | 76E22A72221A414E00C30087 /* PBXTargetDependency */ = { 447 | isa = PBXTargetDependency; 448 | target = 76E22A6E221A414E00C30087 /* Refined GitHub for Safari Extension */; 449 | targetProxy = 76E22A71221A414E00C30087 /* PBXContainerItemProxy */; 450 | }; 451 | /* End PBXTargetDependency section */ 452 | 453 | /* Begin PBXVariantGroup section */ 454 | 76E22A4D221A414C00C30087 /* Main.storyboard */ = { 455 | isa = PBXVariantGroup; 456 | children = ( 457 | 76E22A4E221A414C00C30087 /* Base */, 458 | ); 459 | name = Main.storyboard; 460 | sourceTree = ""; 461 | }; 462 | /* End PBXVariantGroup section */ 463 | 464 | /* Begin XCBuildConfiguration section */ 465 | 76E22A84221A414E00C30087 /* Debug */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ALWAYS_SEARCH_USER_PATHS = NO; 469 | CLANG_ANALYZER_NONNULL = YES; 470 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 471 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 472 | CLANG_CXX_LIBRARY = "libc++"; 473 | CLANG_ENABLE_MODULES = YES; 474 | CLANG_ENABLE_OBJC_ARC = YES; 475 | CLANG_ENABLE_OBJC_WEAK = YES; 476 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 477 | CLANG_WARN_BOOL_CONVERSION = YES; 478 | CLANG_WARN_COMMA = YES; 479 | CLANG_WARN_CONSTANT_CONVERSION = YES; 480 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 481 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 482 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 483 | CLANG_WARN_EMPTY_BODY = YES; 484 | CLANG_WARN_ENUM_CONVERSION = YES; 485 | CLANG_WARN_INFINITE_RECURSION = YES; 486 | CLANG_WARN_INT_CONVERSION = YES; 487 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 488 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 489 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 490 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 491 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 492 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 493 | CLANG_WARN_STRICT_PROTOTYPES = YES; 494 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 495 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 496 | CLANG_WARN_UNREACHABLE_CODE = YES; 497 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 498 | CODE_SIGN_IDENTITY = "-"; 499 | COPY_PHASE_STRIP = NO; 500 | DEBUG_INFORMATION_FORMAT = dwarf; 501 | ENABLE_STRICT_OBJC_MSGSEND = YES; 502 | ENABLE_TESTABILITY = YES; 503 | GCC_C_LANGUAGE_STANDARD = gnu11; 504 | GCC_DYNAMIC_NO_PIC = NO; 505 | GCC_NO_COMMON_BLOCKS = YES; 506 | GCC_OPTIMIZATION_LEVEL = 0; 507 | GCC_PREPROCESSOR_DEFINITIONS = ( 508 | "DEBUG=1", 509 | "$(inherited)", 510 | ); 511 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 512 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 513 | GCC_WARN_UNDECLARED_SELECTOR = YES; 514 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 515 | GCC_WARN_UNUSED_FUNCTION = YES; 516 | GCC_WARN_UNUSED_VARIABLE = YES; 517 | MACOSX_DEPLOYMENT_TARGET = 10.14; 518 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 519 | MTL_FAST_MATH = YES; 520 | ONLY_ACTIVE_ARCH = YES; 521 | SDKROOT = macosx; 522 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 523 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 524 | }; 525 | name = Debug; 526 | }; 527 | 76E22A85221A414E00C30087 /* Release */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ALWAYS_SEARCH_USER_PATHS = NO; 531 | CLANG_ANALYZER_NONNULL = YES; 532 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 533 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 534 | CLANG_CXX_LIBRARY = "libc++"; 535 | CLANG_ENABLE_MODULES = YES; 536 | CLANG_ENABLE_OBJC_ARC = YES; 537 | CLANG_ENABLE_OBJC_WEAK = YES; 538 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 539 | CLANG_WARN_BOOL_CONVERSION = YES; 540 | CLANG_WARN_COMMA = YES; 541 | CLANG_WARN_CONSTANT_CONVERSION = YES; 542 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 543 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 544 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 545 | CLANG_WARN_EMPTY_BODY = YES; 546 | CLANG_WARN_ENUM_CONVERSION = YES; 547 | CLANG_WARN_INFINITE_RECURSION = YES; 548 | CLANG_WARN_INT_CONVERSION = YES; 549 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 550 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 551 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 552 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 553 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 554 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 555 | CLANG_WARN_STRICT_PROTOTYPES = YES; 556 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 557 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 558 | CLANG_WARN_UNREACHABLE_CODE = YES; 559 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 560 | CODE_SIGN_IDENTITY = "-"; 561 | COPY_PHASE_STRIP = NO; 562 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 563 | ENABLE_NS_ASSERTIONS = NO; 564 | ENABLE_STRICT_OBJC_MSGSEND = YES; 565 | GCC_C_LANGUAGE_STANDARD = gnu11; 566 | GCC_NO_COMMON_BLOCKS = YES; 567 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 568 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 569 | GCC_WARN_UNDECLARED_SELECTOR = YES; 570 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 571 | GCC_WARN_UNUSED_FUNCTION = YES; 572 | GCC_WARN_UNUSED_VARIABLE = YES; 573 | MACOSX_DEPLOYMENT_TARGET = 10.14; 574 | MTL_ENABLE_DEBUG_INFO = NO; 575 | MTL_FAST_MATH = YES; 576 | SDKROOT = macosx; 577 | SWIFT_COMPILATION_MODE = wholemodule; 578 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 579 | }; 580 | name = Release; 581 | }; 582 | 76E22A87221A414E00C30087 /* Debug */ = { 583 | isa = XCBuildConfiguration; 584 | buildSettings = { 585 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 586 | CODE_SIGN_ENTITLEMENTS = "Refined GitHub Extension/Refined_GitHub_Extension.entitlements"; 587 | CODE_SIGN_IDENTITY = "Mac Developer"; 588 | CODE_SIGN_STYLE = Automatic; 589 | CURRENT_PROJECT_VERSION = 79; 590 | DEVELOPMENT_TEAM = ""; 591 | ENABLE_HARDENED_RUNTIME = YES; 592 | INFOPLIST_FILE = "Refined GitHub Extension/Info.plist"; 593 | LD_RUNPATH_SEARCH_PATHS = ( 594 | "$(inherited)", 595 | "@executable_path/../Frameworks", 596 | "@executable_path/../../../../Frameworks", 597 | ); 598 | MARKETING_VERSION = 2.1.30; 599 | PRODUCT_BUNDLE_IDENTIFIER = "refined-github-extension"; 600 | PRODUCT_NAME = "$(TARGET_NAME)"; 601 | PROVISIONING_PROFILE_SPECIFIER = ""; 602 | SKIP_INSTALL = YES; 603 | SWIFT_VERSION = 5.0; 604 | }; 605 | name = Debug; 606 | }; 607 | 76E22A88221A414E00C30087 /* Release */ = { 608 | isa = XCBuildConfiguration; 609 | buildSettings = { 610 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 611 | CODE_SIGN_ENTITLEMENTS = "Refined GitHub Extension/Refined_GitHub_Extension.entitlements"; 612 | CODE_SIGN_IDENTITY = "Mac Developer"; 613 | CODE_SIGN_STYLE = Automatic; 614 | CURRENT_PROJECT_VERSION = 79; 615 | DEVELOPMENT_TEAM = ""; 616 | ENABLE_HARDENED_RUNTIME = YES; 617 | INFOPLIST_FILE = "Refined GitHub Extension/Info.plist"; 618 | LD_RUNPATH_SEARCH_PATHS = ( 619 | "$(inherited)", 620 | "@executable_path/../Frameworks", 621 | "@executable_path/../../../../Frameworks", 622 | ); 623 | MARKETING_VERSION = 2.1.30; 624 | PRODUCT_BUNDLE_IDENTIFIER = "refined-github-extension"; 625 | PRODUCT_NAME = "$(TARGET_NAME)"; 626 | PROVISIONING_PROFILE_SPECIFIER = ""; 627 | SKIP_INSTALL = YES; 628 | SWIFT_VERSION = 5.0; 629 | }; 630 | name = Release; 631 | }; 632 | 76E22A8B221A414E00C30087 /* Debug */ = { 633 | isa = XCBuildConfiguration; 634 | buildSettings = { 635 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 636 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 637 | CODE_SIGN_ENTITLEMENTS = "Refined GitHub/Refined_GitHub.entitlements"; 638 | CODE_SIGN_IDENTITY = "Mac Developer"; 639 | CODE_SIGN_STYLE = Automatic; 640 | COMBINE_HIDPI_IMAGES = YES; 641 | CURRENT_PROJECT_VERSION = 79; 642 | DEVELOPMENT_TEAM = ""; 643 | ENABLE_HARDENED_RUNTIME = YES; 644 | INFOPLIST_FILE = "Refined GitHub/Info.plist"; 645 | LD_RUNPATH_SEARCH_PATHS = ( 646 | "$(inherited)", 647 | "@executable_path/../Frameworks", 648 | ); 649 | MARKETING_VERSION = 2.1.30; 650 | PRODUCT_BUNDLE_IDENTIFIER = "refined-github"; 651 | PRODUCT_NAME = "$(TARGET_NAME)"; 652 | PROVISIONING_PROFILE_SPECIFIER = ""; 653 | SWIFT_VERSION = 5.0; 654 | }; 655 | name = Debug; 656 | }; 657 | 76E22A8C221A414E00C30087 /* Release */ = { 658 | isa = XCBuildConfiguration; 659 | buildSettings = { 660 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 661 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 662 | CODE_SIGN_ENTITLEMENTS = "Refined GitHub/Refined_GitHub.entitlements"; 663 | CODE_SIGN_IDENTITY = "Mac Developer"; 664 | CODE_SIGN_STYLE = Automatic; 665 | COMBINE_HIDPI_IMAGES = YES; 666 | CURRENT_PROJECT_VERSION = 79; 667 | DEVELOPMENT_TEAM = ""; 668 | ENABLE_HARDENED_RUNTIME = YES; 669 | INFOPLIST_FILE = "Refined GitHub/Info.plist"; 670 | LD_RUNPATH_SEARCH_PATHS = ( 671 | "$(inherited)", 672 | "@executable_path/../Frameworks", 673 | ); 674 | MARKETING_VERSION = 2.1.30; 675 | PRODUCT_BUNDLE_IDENTIFIER = "refined-github"; 676 | PRODUCT_NAME = "$(TARGET_NAME)"; 677 | PROVISIONING_PROFILE_SPECIFIER = ""; 678 | SWIFT_VERSION = 5.0; 679 | }; 680 | name = Release; 681 | }; 682 | 76E22A8E221A414E00C30087 /* Debug */ = { 683 | isa = XCBuildConfiguration; 684 | buildSettings = { 685 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 686 | BUNDLE_LOADER = "$(TEST_HOST)"; 687 | CODE_SIGN_STYLE = Automatic; 688 | COMBINE_HIDPI_IMAGES = YES; 689 | CURRENT_PROJECT_VERSION = 79; 690 | INFOPLIST_FILE = "Refined GitHubTests/Info.plist"; 691 | LD_RUNPATH_SEARCH_PATHS = ( 692 | "$(inherited)", 693 | "@executable_path/../Frameworks", 694 | "@loader_path/../Frameworks", 695 | ); 696 | PRODUCT_BUNDLE_IDENTIFIER = "fi.lautanala.Refined-GitHubTests"; 697 | PRODUCT_NAME = "$(TARGET_NAME)"; 698 | SWIFT_VERSION = 5.0; 699 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Refined GitHub.app/Contents/MacOS/Refined GitHub for Safari"; 700 | }; 701 | name = Debug; 702 | }; 703 | 76E22A8F221A414E00C30087 /* Release */ = { 704 | isa = XCBuildConfiguration; 705 | buildSettings = { 706 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 707 | BUNDLE_LOADER = "$(TEST_HOST)"; 708 | CODE_SIGN_STYLE = Automatic; 709 | COMBINE_HIDPI_IMAGES = YES; 710 | CURRENT_PROJECT_VERSION = 79; 711 | INFOPLIST_FILE = "Refined GitHubTests/Info.plist"; 712 | LD_RUNPATH_SEARCH_PATHS = ( 713 | "$(inherited)", 714 | "@executable_path/../Frameworks", 715 | "@loader_path/../Frameworks", 716 | ); 717 | PRODUCT_BUNDLE_IDENTIFIER = "fi.lautanala.Refined-GitHubTests"; 718 | PRODUCT_NAME = "$(TARGET_NAME)"; 719 | SWIFT_VERSION = 5.0; 720 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Refined GitHub.app/Contents/MacOS/Refined GitHub for Safari"; 721 | }; 722 | name = Release; 723 | }; 724 | 76E22A91221A414E00C30087 /* Debug */ = { 725 | isa = XCBuildConfiguration; 726 | buildSettings = { 727 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 728 | CODE_SIGN_STYLE = Automatic; 729 | COMBINE_HIDPI_IMAGES = YES; 730 | CURRENT_PROJECT_VERSION = 79; 731 | INFOPLIST_FILE = "Refined GitHubUITests/Info.plist"; 732 | LD_RUNPATH_SEARCH_PATHS = ( 733 | "$(inherited)", 734 | "@executable_path/../Frameworks", 735 | "@loader_path/../Frameworks", 736 | ); 737 | PRODUCT_BUNDLE_IDENTIFIER = "fi.lautanala.Refined-GitHubUITests"; 738 | PRODUCT_NAME = "$(TARGET_NAME)"; 739 | SWIFT_VERSION = 5.0; 740 | TEST_TARGET_NAME = "Refined GitHub for Safari"; 741 | }; 742 | name = Debug; 743 | }; 744 | 76E22A92221A414E00C30087 /* Release */ = { 745 | isa = XCBuildConfiguration; 746 | buildSettings = { 747 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 748 | CODE_SIGN_STYLE = Automatic; 749 | COMBINE_HIDPI_IMAGES = YES; 750 | CURRENT_PROJECT_VERSION = 79; 751 | INFOPLIST_FILE = "Refined GitHubUITests/Info.plist"; 752 | LD_RUNPATH_SEARCH_PATHS = ( 753 | "$(inherited)", 754 | "@executable_path/../Frameworks", 755 | "@loader_path/../Frameworks", 756 | ); 757 | PRODUCT_BUNDLE_IDENTIFIER = "fi.lautanala.Refined-GitHubUITests"; 758 | PRODUCT_NAME = "$(TARGET_NAME)"; 759 | SWIFT_VERSION = 5.0; 760 | TEST_TARGET_NAME = "Refined GitHub for Safari"; 761 | }; 762 | name = Release; 763 | }; 764 | /* End XCBuildConfiguration section */ 765 | 766 | /* Begin XCConfigurationList section */ 767 | 76E22A41221A414B00C30087 /* Build configuration list for PBXProject "Refined GitHub for Safari" */ = { 768 | isa = XCConfigurationList; 769 | buildConfigurations = ( 770 | 76E22A84221A414E00C30087 /* Debug */, 771 | 76E22A85221A414E00C30087 /* Release */, 772 | ); 773 | defaultConfigurationIsVisible = 0; 774 | defaultConfigurationName = Release; 775 | }; 776 | 76E22A86221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHub for Safari Extension" */ = { 777 | isa = XCConfigurationList; 778 | buildConfigurations = ( 779 | 76E22A87221A414E00C30087 /* Debug */, 780 | 76E22A88221A414E00C30087 /* Release */, 781 | ); 782 | defaultConfigurationIsVisible = 0; 783 | defaultConfigurationName = Release; 784 | }; 785 | 76E22A8A221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHub for Safari" */ = { 786 | isa = XCConfigurationList; 787 | buildConfigurations = ( 788 | 76E22A8B221A414E00C30087 /* Debug */, 789 | 76E22A8C221A414E00C30087 /* Release */, 790 | ); 791 | defaultConfigurationIsVisible = 0; 792 | defaultConfigurationName = Release; 793 | }; 794 | 76E22A8D221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHubTests" */ = { 795 | isa = XCConfigurationList; 796 | buildConfigurations = ( 797 | 76E22A8E221A414E00C30087 /* Debug */, 798 | 76E22A8F221A414E00C30087 /* Release */, 799 | ); 800 | defaultConfigurationIsVisible = 0; 801 | defaultConfigurationName = Release; 802 | }; 803 | 76E22A90221A414E00C30087 /* Build configuration list for PBXNativeTarget "Refined GitHubUITests" */ = { 804 | isa = XCConfigurationList; 805 | buildConfigurations = ( 806 | 76E22A91221A414E00C30087 /* Debug */, 807 | 76E22A92221A414E00C30087 /* Release */, 808 | ); 809 | defaultConfigurationIsVisible = 0; 810 | defaultConfigurationName = Release; 811 | }; 812 | /* End XCConfigurationList section */ 813 | 814 | /* Begin XCRemoteSwiftPackageReference section */ 815 | 768006A02482C8EB002B7FC1 /* RemoteSwiftPackageReference */ = { 816 | isa = XCRemoteSwiftPackageReference; 817 | repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess"; 818 | requirement = { 819 | kind = upToNextMajorVersion; 820 | minimumVersion = 4.2.0; 821 | }; 822 | }; 823 | /* End XCRemoteSwiftPackageReference section */ 824 | 825 | /* Begin XCSwiftPackageProductDependency section */ 826 | 768006A12482C8EB002B7FC1 /* SwiftPackageProductDependency */ = { 827 | isa = XCSwiftPackageProductDependency; 828 | package = 768006A02482C8EB002B7FC1 /* RemoteSwiftPackageReference */; 829 | productName = KeychainAccess; 830 | }; 831 | 768006A62482CABB002B7FC1 /* SwiftPackageProductDependency */ = { 832 | isa = XCSwiftPackageProductDependency; 833 | package = 768006A02482C8EB002B7FC1 /* RemoteSwiftPackageReference */; 834 | productName = KeychainAccess; 835 | }; 836 | /* End XCSwiftPackageProductDependency section */ 837 | }; 838 | rootObject = 76E22A3E221A414B00C30087 /* Project object */; 839 | } 840 | -------------------------------------------------------------------------------- /Refined GitHub for Safari.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Refined GitHub for Safari.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Refined GitHub for Safari.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "object": { 3 | "pins": [ 4 | { 5 | "package": "KeychainAccess", 6 | "repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess", 7 | "state": { 8 | "branch": null, 9 | "revision": "3d0ea2c0806791abcc5d7f0d9f62f1cfd4a7264d", 10 | "version": "4.2.0" 11 | } 12 | } 13 | ] 14 | }, 15 | "version": 1 16 | } 17 | -------------------------------------------------------------------------------- /Refined GitHub for Safari.xcodeproj/xcshareddata/xcschemes/Refined GitHub for Safari Extension.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 6 | 9 | 10 | 16 | 22 | 23 | 24 | 30 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 69 | 73 | 74 | 75 | 81 | 82 | 83 | 84 | 91 | 93 | 99 | 100 | 101 | 102 | 104 | 105 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /Refined GitHub for Safari.xcodeproj/xcshareddata/xcschemes/Refined GitHub for Safari.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 42 | 48 | 49 | 50 | 52 | 58 | 59 | 60 | 61 | 62 | 72 | 74 | 80 | 81 | 82 | 83 | 89 | 91 | 97 | 98 | 99 | 100 | 102 | 103 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /Refined GitHub/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Refined GitHub for Safari 4 | // 5 | // Created by Ville Lautanala on 17/02/2019. 6 | // Copyright © 2019 Ville Lautanala. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | func applicationDidFinishLaunching(_ aNotification: Notification) { 15 | // Insert code here to initialize your application 16 | } 17 | 18 | func applicationWillTerminate(_ aNotification: Notification) { 19 | // Insert code here to tear down your application 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Refined GitHub/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "128x128", 25 | "idiom" : "mac", 26 | "filename" : "icon.png", 27 | "scale" : "1x" 28 | }, 29 | { 30 | "idiom" : "mac", 31 | "size" : "128x128", 32 | "scale" : "2x" 33 | }, 34 | { 35 | "idiom" : "mac", 36 | "size" : "256x256", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "idiom" : "mac", 41 | "size" : "256x256", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "idiom" : "mac", 46 | "size" : "512x512", 47 | "scale" : "1x" 48 | }, 49 | { 50 | "idiom" : "mac", 51 | "size" : "512x512", 52 | "scale" : "2x" 53 | } 54 | ], 55 | "info" : { 56 | "version" : 1, 57 | "author" : "xcode" 58 | } 59 | } -------------------------------------------------------------------------------- /Refined GitHub/Assets.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lautis/refined-github-safari/aac8bba5c3a219d84a0009f35af0dc55911ffdfd/Refined GitHub/Assets.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /Refined GitHub/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Refined GitHub/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | NSAllRomanInputSourcesLocaleIdentifier 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | -------------------------------------------------------------------------------- /Refined GitHub/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | LSApplicationCategoryType 24 | public.app-category.developer-tools 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2019 Ville Lautanala. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Refined GitHub/Refined_GitHub.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | keychain-access-groups 10 | 11 | $(AppIdentifierPrefix)fi.lautanala.refined-github-shared 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Refined GitHub/Resources/Credits.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 20 | 21 |
22 | Copyright (c) 2019 Ville Lautanala
23 | 
24 | Permission to use, copy, modify, and/or distribute this software for any
25 | purpose with or without fee is hereby granted, provided that the above
26 | copyright notice and this permission notice appear in all copies.
27 | 
28 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
29 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
30 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
31 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
32 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
33 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
34 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35 | 
36 | 37 |

This app includes portions of the following copyrighted material:

38 | 39 |

refined-github

40 | 41 |

MIT License

42 | 43 |

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)

44 | 45 |

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

46 | 47 |

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

48 | 49 |

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

50 |

51 | 52 | 53 |

intersection-observer

54 | 55 |

This work is being provided by the copyright holders under the following license.

56 | 57 |

Notice

58 | 59 |

By obtaining and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions.

60 |

Permission to copy, modify, and distribute this work, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the work or portions thereof, including modifications:

61 | 62 |

63 |

    64 |
  • The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.
  • 65 |
  • Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the W3C Software and Document Short Notice should be included.
  • 66 |
  • Notice of any changes or modifications, through a copyright statement on the new code or document such as "This software or document includes material copied from or derived from [title and URI of the W3C document]. Copyright © [YEAR] W3C® (MIT, ERCIM, Keio, Beihang)."
  • 67 |
68 |

69 | 70 |

Disclaimers

71 | 72 |

THIS WORK IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENT WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

73 | 74 |

COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENT.

75 | 76 |

The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the work without specific, written prior permission. Title to copyright in this work will at all times remain with copyright holders.

77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /Refined GitHub/Settings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Settings.swift 3 | // Refined GitHub for Safari 4 | // 5 | // Created by Ville Lautanala on 30.5.2020. 6 | // Copyright © 2020 Ville Lautanala. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import KeychainAccess 11 | 12 | class Settings { 13 | 14 | static let shared = Settings() 15 | private init() {} 16 | 17 | let personalTokenKey = "refinedGitHubForSafariPersonalToken" 18 | 19 | func bundleIdentifier() -> String { 20 | let bundleIdentifier = Bundle.main.bundleIdentifier ?? "" 21 | if bundleIdentifier.hasSuffix("-extension") { 22 | return String(bundleIdentifier.dropLast("-extension".count)) + "-shared" 23 | } else { 24 | return bundleIdentifier + "-shared"; 25 | } 26 | } 27 | 28 | func keychain() -> Keychain { 29 | Keychain(service: bundleIdentifier()) 30 | } 31 | 32 | var personalToken: String { 33 | get { 34 | if let token = try? keychain().getString(personalTokenKey) { 35 | return token 36 | } else { 37 | return "" 38 | } 39 | } 40 | set(value) { 41 | do { 42 | try keychain() 43 | .label("Refined GitHub for Safari GitHub Access Token") 44 | .synchronizable(true) 45 | .set(value, key: personalTokenKey) 46 | } catch let error { 47 | NSLog("error: \(error)") 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Refined GitHub/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Refined GitHub for Safari 4 | // 5 | // Created by Ville Lautanala on 17/02/2019. 6 | // Copyright © 2019 Ville Lautanala. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import SafariServices.SFSafariApplication 11 | 12 | class ViewController: NSViewController { 13 | 14 | @IBOutlet var appNameLabel: NSTextField! 15 | @IBOutlet var personalTokenInput: NSSecureTextField!; 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | self.appNameLabel.stringValue = "Refined GitHub for Safari"; 20 | self.personalTokenInput.stringValue = Settings.shared.personalToken; 21 | } 22 | 23 | @IBAction func openSafariExtensionPreferences(_ sender: AnyObject?) { 24 | let bundlePrefix = Bundle(for: ViewController.self).bundleIdentifier ?? "" 25 | SFSafariApplication.showPreferencesForExtension(withIdentifier: "\(bundlePrefix)-extension") { error in 26 | if let _ = error { 27 | // Insert code to inform the user that something went wrong. 28 | 29 | } 30 | } 31 | } 32 | 33 | @IBAction func personalTokenDidChange(_ notification: AnyObject?) { 34 | Settings.shared.personalToken = self.personalTokenInput.stringValue; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Refined GitHubTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Refined GitHubTests/Refined_GitHubTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Refined_GitHubTests.swift 3 | // Refined GitHubTests 4 | // 5 | // Created by Ville Lautanala on 17/02/2019. 6 | // Copyright © 2019 Ville Lautanala. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Refined_GitHub_for_Safari 11 | 12 | class Refined_GitHubTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Refined GitHubUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Refined GitHubUITests/Refined_GitHubUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Refined_GitHubUITests.swift 3 | // Refined GitHubUITests 4 | // 5 | // Created by Ville Lautanala on 17/02/2019. 6 | // Copyright © 2019 Ville Lautanala. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class Refined_GitHubUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | 16 | // In UI tests it is usually best to stop immediately when a failure occurs. 17 | continueAfterFailure = false 18 | 19 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 20 | XCUIApplication().launch() 21 | 22 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 23 | } 24 | 25 | override func tearDown() { 26 | // Put teardown code here. This method is called after the invocation of each test method in the class. 27 | } 28 | 29 | func testExample() { 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /bin/travis-push-submodule-update: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [[ "$TRAVIS_EVENT_TYPE" != "cron" ]]; then 4 | exit 0 5 | fi 6 | 7 | export GIT_AUTHOR_NAME="Submodule Updater" 8 | export GIT_AUTHOR_EMAIL="submodule-updater@lautanala.fi" 9 | export GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME 10 | export GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL 11 | 12 | if ! $(git diff --quiet && git diff --cached --quiet) ; then 13 | eval "$(ssh-agent -s)" 14 | chmod 600 .travis/deploy-key 15 | ssh-add .travis/deploy-key 16 | 17 | git add refined-github 18 | git commit -m "Update refined-github" 19 | 20 | git --no-pager log -1 21 | 22 | git remote add deploy git@github.com:lautis/refined-github-safari.git 23 | git push deploy HEAD:master 24 | fi 25 | -------------------------------------------------------------------------------- /bin/travis-update-submodule: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [[ "$TRAVIS_EVENT_TYPE" != "cron" ]]; then 4 | exit 0 5 | fi 6 | 7 | npm run refined-github:update 8 | -------------------------------------------------------------------------------- /bin/xcode-project-clean: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sed -e "s/DEVELOPMENT_TEAM = [[:alnum:]]\{1,\};/DEVELOPMENT_TEAM = \"\";/g" | 3 | sed -e "s/PRODUCT_BUNDLE_IDENTIFIER = \"$2\";/PRODUCT_BUNDLE_IDENTIFIER = \"refined-github\";/g" | 4 | sed -e "s/PRODUCT_BUNDLE_IDENTIFIER = \"$2-extension\";/PRODUCT_BUNDLE_IDENTIFIER = \"refined-github-extension\";/g" 5 | -------------------------------------------------------------------------------- /bin/xcode-project-smudge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sed -e "s/DEVELOPMENT_TEAM = \"\";/DEVELOPMENT_TEAM = $1;/g" | 3 | sed -e "s/PRODUCT_BUNDLE_IDENTIFIER = \"refined-github\";/PRODUCT_BUNDLE_IDENTIFIER = \"$2\";/g" | 4 | sed -e "s/PRODUCT_BUNDLE_IDENTIFIER = \"refined-github-extension\";/PRODUCT_BUNDLE_IDENTIFIER = \"$2-extension\";/g" 5 | -------------------------------------------------------------------------------- /fastlane/Appfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | app_identifier 'fi.lautanala.refined-github' 4 | apple_id 'lautis@gmail.com' 5 | team_id 'KETPJB4C67' 6 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Uncomment the line if you want fastlane to automatically update itself 4 | # update_fastlane 5 | 6 | default_platform(:mac) 7 | 8 | def build_js 9 | sh 'npm run build' 10 | end 11 | 12 | APP_NAME = 'Refined GitHub for Safari' 13 | BUILD_DIR = 'build' 14 | 15 | def archive_path 16 | "#{BUILD_DIR}/#{APP_NAME}.xcarchive" 17 | end 18 | 19 | def app_path 20 | File.expand_path("../#{BUILD_DIR}/Refined GitHub for Safari.app", __dir__) 21 | end 22 | 23 | def refined_github_path 24 | File.expand_path('../refined-github', __dir__) 25 | end 26 | 27 | def project_path 28 | File.expand_path('../', __dir__) 29 | end 30 | 31 | def zip_path 32 | File.join(BUILD_DIR, 'Refined-GitHub-for-Safari.zip') 33 | end 34 | 35 | def marketing_version_number 36 | get_version_number(target: APP_NAME) 37 | end 38 | 39 | def silent_sh(*args) 40 | `#{Shellwords.join(args)}` 41 | end 42 | 43 | platform :mac do 44 | desc 'Build app' 45 | lane :build do 46 | build_js 47 | update_code_signing_settings(code_sign_identity: '-') 48 | xcodebuild(archive: true, scheme: 'Refined GitHub for Safari') 49 | end 50 | 51 | lane :export_archive do 52 | xcarchive( 53 | export_archive: true, 54 | archive_path: archive_path, 55 | export_path: BUILD_DIR, 56 | export_options_plist: { 57 | destination: 'export', 58 | method: 'developer-id', 59 | signing_style: 'automatic', 60 | team_id: CredentialsManager::AppfileConfig.try_fetch_value(:team_id) 61 | } 62 | ) 63 | end 64 | 65 | lane :archive do 66 | FileUtils.mkdir_p File.expand_path("../#{BUILD_DIR}", __dir__) 67 | xcbuild(archive: true, archive_path: archive_path, scheme: 'Refined GitHub for Safari') 68 | end 69 | 70 | lane :notarize_app do 71 | notarize( 72 | package: app_path, 73 | username: CredentialsManager::AppfileConfig.try_fetch_value(:apple_id), 74 | print_log: true 75 | ) 76 | end 77 | 78 | lane :zip_app do 79 | zip( 80 | path: app_path, 81 | output_path: zip_path, 82 | verbose: false, 83 | symlinks: true 84 | ) 85 | end 86 | 87 | lane :set_team do 88 | update_project_team( 89 | path: 'Refined GitHub for Safari.xcodeproj', 90 | teamid: CredentialsManager::AppfileConfig.try_fetch_value(:team_id) 91 | ) 92 | end 93 | 94 | lane :build_release do 95 | build_js 96 | archive 97 | export_archive 98 | notarize_app 99 | zip_app 100 | end 101 | 102 | lane :bump_version do 103 | increment_build_number_in_xcodeproj 104 | [APP_NAME, "#{APP_NAME} Extension"].each do |target| 105 | increment_version_number_in_xcodeproj( 106 | bump_type: ENV.fetch('BUMP_TYPE', 'patch'), 107 | target: target 108 | ) 109 | end 110 | commit_version_bump( 111 | message: "Version #{marketing_version_number}", 112 | xcodeproj: 'Refined GitHub for Safari.xcodeproj' 113 | ) 114 | end 115 | 116 | lane :github_release do 117 | set_github_release( 118 | repository_name: 'lautis/refined-github-safari', 119 | api_token: ENV['GITHUB_TOKEN'], 120 | name: "v#{marketing_version_number}", 121 | tag_name: "v#{marketing_version_number}", 122 | description: "Version #{marketing_version_number}", 123 | commitish: last_git_commit[:commit_hash], 124 | upload_assets: [zip_path] 125 | ) 126 | end 127 | 128 | lane :release do 129 | bump_version 130 | build_release 131 | push_to_git_remote 132 | github_release 133 | end 134 | 135 | lane :update_refined_github do 136 | git_submodule_update 137 | sh('git', '-C', refined_github_path, 'fetch', '--tags') 138 | commitish = silent_sh('git', '-C', refined_github_path, 'rev-list', '--tags', '--max-count=1').chomp 139 | latest_tag = silent_sh('git', '-C', refined_github_path, 'describe', '--tags', commitish).chomp 140 | silent_sh('git', '-C', refined_github_path, 'checkout', latest_tag) 141 | if silent_sh('git', '-C', project_path, 'diff', 'refined-github').empty? 142 | UI.error('refined-github already up-to-date') 143 | else 144 | build_js 145 | UI.success("Updated refined-github to #{latest_tag}") 146 | git_commit(path: 'refined-github', message: "Update refined-github to #{latest_tag}") 147 | end 148 | end 149 | end 150 | -------------------------------------------------------------------------------- /fastlane/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-versioning' 6 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew install fastlane` 16 | 17 | # Available Actions 18 | ## Mac 19 | ### mac build 20 | ``` 21 | fastlane mac build 22 | ``` 23 | Build app 24 | ### mac export_archive 25 | ``` 26 | fastlane mac export_archive 27 | ``` 28 | 29 | ### mac archive 30 | ``` 31 | fastlane mac archive 32 | ``` 33 | 34 | ### mac notarize_app 35 | ``` 36 | fastlane mac notarize_app 37 | ``` 38 | 39 | ### mac zip_app 40 | ``` 41 | fastlane mac zip_app 42 | ``` 43 | 44 | ### mac set_team 45 | ``` 46 | fastlane mac set_team 47 | ``` 48 | 49 | ### mac build_release 50 | ``` 51 | fastlane mac build_release 52 | ``` 53 | 54 | ### mac bump_version 55 | ``` 56 | fastlane mac bump_version 57 | ``` 58 | 59 | ### mac github_release 60 | ``` 61 | fastlane mac github_release 62 | ``` 63 | 64 | ### mac release 65 | ``` 66 | fastlane mac release 67 | ``` 68 | 69 | ### mac update_refined_github 70 | ``` 71 | fastlane mac update_refined_github 72 | ``` 73 | 74 | 75 | ---- 76 | 77 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 78 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 79 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 80 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "refined-github-safari", 3 | "version": "2.0.5", 4 | "lockfileVersion": 1 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "refined-github-safari", 3 | "version": "2.0.5", 4 | "description": "Safari port of refined-github", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "npm run refined-github", 8 | "postinstall": "npm run refined-github:install", 9 | "refined-github": "npm run refined-github:install && npm run refined-github:build && npm run refined-github:copy && npm run refined-github:restore", 10 | "refined-github:install": "cd refined-github && npm install --frozen-lockfile", 11 | "refined-github:build": "cd refined-github && npm run build", 12 | "refined-github:copy": "rm -r Refined\\ GitHub\\ Extension/build;cp -R refined-github/distribution/build/ Refined\\ GitHub\\ Extension/build/", 13 | "refined-github:restore": "cd refined-github && git reset --hard" 14 | }, 15 | "author": "Ville Lautanala ", 16 | "license": "ISC", 17 | "dependencies": {}, 18 | "devDependencies": {} 19 | } 20 | --------------------------------------------------------------------------------