├── LICENSE.md ├── README.md ├── Syndicate.safariextension ├── Icon-128.png ├── Icon-64.png ├── Icon.png ├── Info.plist ├── Settings.plist ├── assets │ ├── icon.png │ ├── icon@2x.png │ └── styles.css ├── endScript.js ├── global.html └── popover.html └── updates.plist /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2015 Reda Lemeden. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the “Software”), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Syndicate 2 | 3 | Safari extension that brings the RSS button back to the toolbar. 4 | 5 | #### Develop 6 | 1. Enable developer mode in Safari. 7 | 2. In the menu: *Develop* > *Show Extension Builder*. 8 | 3. Click the `+` button then navigate to `Syndicate.safariextension`. 9 | 4. Click *Install* in the Extension Builder to test. 10 | 5. Make changes in your editor. 11 | 6. Reload by clicking the *Reload* button in the Extension Builder. 12 | 13 | #### License 14 | See `LICENSE.md`. 15 | -------------------------------------------------------------------------------- /Syndicate.safariextension/Icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaishin/syndicate/bf7f23bb1c78401124ff54dd78ec8a796e01f95d/Syndicate.safariextension/Icon-128.png -------------------------------------------------------------------------------- /Syndicate.safariextension/Icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaishin/syndicate/bf7f23bb1c78401124ff54dd78ec8a796e01f95d/Syndicate.safariextension/Icon-64.png -------------------------------------------------------------------------------- /Syndicate.safariextension/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaishin/syndicate/bf7f23bb1c78401124ff54dd78ec8a796e01f95d/Syndicate.safariextension/Icon.png -------------------------------------------------------------------------------- /Syndicate.safariextension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Author 6 | Reda Lemeden 7 | Builder Version 8 | 11601.3.9 9 | CFBundleDisplayName 10 | Syndicate 11 | CFBundleIdentifier 12 | co.kaishin.syndicate 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleShortVersionString 16 | 1.0.1 17 | CFBundleVersion 18 | 2 19 | Chrome 20 | 21 | Global Page 22 | global.html 23 | Popovers 24 | 25 | 26 | Filename 27 | popover.html 28 | Height 29 | 30 | Identifier 31 | mainPopover 32 | Width 33 | 34 | 35 | 36 | Toolbar Items 37 | 38 | 39 | Identifier 40 | menuButton 41 | Image 42 | assets/icon.png 43 | Label 44 | Subscribe 45 | Popover 46 | mainPopover 47 | Tool Tip 48 | Subscribe via RSS 49 | 50 | 51 | 52 | Content 53 | 54 | Scripts 55 | 56 | End 57 | 58 | endScript.js 59 | 60 | 61 | 62 | Description 63 | Brings the RSS button back to the toolbar 64 | DeveloperIdentifier 65 | 5G38N4D8G2 66 | ExtensionInfoDictionaryVersion 67 | 1.0 68 | Permissions 69 | 70 | Website Access 71 | 72 | Include Secure Pages 73 | 74 | Level 75 | All 76 | 77 | 78 | Update Manifest URL 79 | https://raw.githubusercontent.com/kaishin/syndicate/master/updates.plist 80 | Website 81 | https://redalemeden.com/syndicate 82 | 83 | 84 | -------------------------------------------------------------------------------- /Syndicate.safariextension/Settings.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | DefaultValue 7 | 8 | Key 9 | googleFeedEnabled 10 | Title 11 | Display feed titles using Google Feed API (Always disabled in Private Browsing) 12 | Type 13 | CheckBox 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Syndicate.safariextension/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaishin/syndicate/bf7f23bb1c78401124ff54dd78ec8a796e01f95d/Syndicate.safariextension/assets/icon.png -------------------------------------------------------------------------------- /Syndicate.safariextension/assets/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaishin/syndicate/bf7f23bb1c78401124ff54dd78ec8a796e01f95d/Syndicate.safariextension/assets/icon@2x.png -------------------------------------------------------------------------------- /Syndicate.safariextension/assets/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | font-family: -apple-system, "Helvetica Neue"; 7 | overflow-x: hidden; 8 | padding-left: 5px; 9 | padding-right: 5px; 10 | } 11 | 12 | ul { 13 | margin: 0; 14 | padding: 0; 15 | } 16 | 17 | 18 | .feed-cell { 19 | display: table; 20 | width: 100%; 21 | } 22 | 23 | .feed-cell { 24 | border-bottom: 1px solid rgba(0, 0, 0, 0.1); 25 | display: table; 26 | list-style: none; 27 | padding: 10px 0; 28 | width: 100%; 29 | } 30 | 31 | .feed-cell:first-of-type { 32 | padding-top: 2px; 33 | } 34 | 35 | .feed-cell:last-of-type { 36 | border-bottom: none; 37 | padding-bottom: 5px; 38 | } 39 | 40 | .controls, 41 | .feed-info { 42 | display: table-cell; 43 | vertical-align: middle; 44 | } 45 | 46 | .feed-name { 47 | -webkit-user-select: none; 48 | display: block; 49 | font-size: 14px; 50 | font-weight: normal; 51 | letter-spacing: 0.05em; 52 | overflow: hidden; 53 | text-overflow: ellipsis; 54 | white-space: nowrap; 55 | width: 230px; 56 | } 57 | 58 | .url-field { 59 | -webkit-mask-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 1)), color-stop(0.9, rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0))); 60 | background: transparent; 61 | border: none; 62 | color: #000; 63 | display: block; 64 | margin: 2px 0 0; 65 | opacity: 0.7; 66 | padding: 0; 67 | width: 230px; 68 | } 69 | 70 | form { 71 | float: right; 72 | } 73 | 74 | [type=submit] { 75 | font-size: 18px; 76 | color: #AAA; 77 | } 78 | 79 | [type=submit]:active { 80 | font-size: 18px; 81 | color: white; 82 | } 83 | -------------------------------------------------------------------------------- /Syndicate.safariextension/endScript.js: -------------------------------------------------------------------------------- 1 | function extractPageFeeds() { 2 | var feeds = {}; 3 | 4 | feeds["site"] = window.location.href; 5 | if (feeds["site"] === "favorites://") { return }; 6 | 7 | feeds["list"] = []; 8 | var headLinks = document.getElementsByTagName("head")[0].getElementsByTagName("link"); 9 | 10 | for (var i = 0; i < headLinks.length; i++) { 11 | var link = headLinks[i]; 12 | 13 | if (link.attributes.getNamedItem("rel") !== null && link.attributes.getNamedItem("rel").value == "alternate") { 14 | var type = link.attributes.getNamedItem("type"); 15 | 16 | if (type !== null) { 17 | var typeValue = type.value; 18 | 19 | if (typeValue === "application/rss+xml" || typeValue === "application/atom+xml" || typeValue === "text/xml") { 20 | var href = link.attributes.getNamedItem("href").value; 21 | 22 | if (href) { 23 | feeds["list"].push({url: _fullUrl(href), title: titleFromType(typeValue), type: typeFromString(typeValue)}); 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | safari.self.tab.dispatchMessage("extractedFeeds", feeds); 31 | } 32 | 33 | function protocol(url) { 34 | return url.split(":")[0]; 35 | } 36 | 37 | function typeFromString(string) { 38 | if (string.indexOf("rss") != -1) { 39 | return "RSS"; 40 | } else if (string.indexOf("atom") != -1) { 41 | return "Atom"; 42 | } else { 43 | return "Unknown"; 44 | } 45 | } 46 | 47 | function titleFromType(type) { 48 | if (type.indexOf("rss") != -1) { 49 | return "RSS Feed"; 50 | } else if (type.indexOf("atom") != -1) { 51 | return "Atom Feed"; 52 | } else { 53 | return "Feed"; 54 | } 55 | } 56 | 57 | function toTitleCase(str) { 58 | return str.replace(/\w\S*/g, function(txt) { 59 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); 60 | }); 61 | } 62 | 63 | function _getBaseUrl() { 64 | var head = document.getElementsByTagName("head")[0]; 65 | var baseLinks = head.getElementsByTagName("base"); 66 | var baseUrl; 67 | 68 | for (var i=0; i < baseLinks.length; i++) { 69 | var link = baseLinks[i]; 70 | 71 | if (link.attributes.getNamedItem("href") !== null) { 72 | url = link.attributes.getNamedItem("href").value; 73 | 74 | if (url.charAt(url.length - 1) != "/") { 75 | url += "/"; 76 | } 77 | 78 | baseUrl = url; 79 | break; 80 | } 81 | } 82 | 83 | if (baseUrl === undefined) { 84 | baseUrl = protocol(document.URL) + "://" + document.domain + "/" 85 | } 86 | 87 | return baseUrl; 88 | } 89 | 90 | function _fullUrl(url) { 91 | var trimmedUrl = url.trim(); 92 | var protocol = trimmedUrl.substr(0,4); 93 | 94 | if (protocol !== "http" && protocol !== "feed") { 95 | if (trimmedUrl[0] == "/") { 96 | trimmedUrl = trimmedUrl.slice(1); 97 | } 98 | 99 | trimmedUrl = _getBaseUrl() + trimmedUrl; 100 | } 101 | 102 | return trimmedUrl; 103 | } 104 | 105 | if (window.top === window) { 106 | if (document.domain !== "undefined") { 107 | extractPageFeeds(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Syndicate.safariextension/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /Syndicate.safariextension/popover.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /updates.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Extension Updates 6 | 7 | 8 | CFBundleIdentifier 9 | co.kaishin.syndicate 10 | Developer Identifier 11 | 5G38N4D8G2 12 | CFBundleVersion 13 | 2 14 | CFBundleShortVersionString 15 | 1.0.1 16 | URL 17 | https://github.com/kaishin/syndicate/releases/download/v1.0.1/Syndicate.safariextz 18 | 19 | 20 | CFBundleIdentifier 21 | co.kaishin.syndicate 22 | Developer Identifier 23 | U8WP333PAE 24 | CFBundleVersion 25 | 1 26 | CFBundleShortVersionString 27 | 1.0 28 | URL 29 | https://github.com/kaishin/syndicate/releases/download/v1.0.0/Syndicate.safariextz 30 | 31 | 32 | 33 | 34 | --------------------------------------------------------------------------------