├── .eslintignore ├── .eslintrc.js ├── .github ├── CODEOWNERS └── dependabot.yml ├── .gitignore ├── .stylelintrc ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── babel.config.js ├── doc └── extension_development.md ├── gulpfile.mjs ├── package.json ├── src ├── COPYING ├── chrome.manifest ├── content │ ├── bindings.xml │ ├── browserOverlay.xul │ ├── firstRunWizard.js │ ├── firstRunWizard.xul │ ├── settings.js │ ├── settings.xul │ ├── tabkit.css │ ├── tabkit.ts │ ├── ua.css │ └── variable.css ├── defaults │ └── preferences │ │ └── defaults.js ├── icon.png ├── install.rdf ├── locale │ └── en-US │ │ ├── firstRunWizard.dtd │ │ ├── overlay.dtd │ │ ├── settings.dtd │ │ └── tabkit.properties └── skin │ └── classic │ ├── Secure.png │ ├── multiRowTabs.png │ ├── normalTabs.png │ ├── prefs-advanced.png │ ├── prefs-controls.png │ ├── prefs-experimental.png │ ├── prefs-grouping.png │ ├── prefs-tabbar.png │ ├── prefs-tabs.png │ ├── tab-active-bkgnd.png │ ├── tab-bkgnd.png │ ├── tab-hover-bkgnd.png │ ├── tabkit.png │ ├── tabkit2-logo.png │ ├── treeTabs.png │ └── twisty-clsd.png ├── tsconfig.json ├── types └── firefox-45-x.d.ts ├── versions └── beta_release │ ├── install.example.rdf │ └── install.rdf └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | /build/** 2 | /node_modules/** 3 | /flow-typed/** 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "parser": "@typescript-eslint/parser", 3 | "plugins": [ 4 | "@typescript-eslint", 5 | ], 6 | "env": { 7 | "browser": true, 8 | "commonjs": true, 9 | "es6": true, 10 | }, 11 | "extends": [ 12 | "eslint:recommended", 13 | "plugin:@typescript-eslint/recommended", 14 | ], 15 | "parserOptions": { 16 | "sourceType": "script", 17 | }, 18 | "rules": { 19 | // Incorrect for TS 20 | // eslint-disable-next-line 21 | "indent": "off", 22 | "@typescript-eslint/indent": [ 23 | "warn", 24 | 2, 25 | { 26 | "MemberExpression": 0, 27 | "SwitchCase": 1, 28 | "VariableDeclarator": { "var": 2, "let": 2, "const": 3 }, 29 | "CallExpression": {"arguments": "first"}, 30 | "ArrayExpression": 1, 31 | "ObjectExpression": 1, 32 | "ImportDeclaration": 1, 33 | }, 34 | ], 35 | 36 | "quotes": [ 37 | "warn", 38 | "double", 39 | ], 40 | "semi": [ 41 | "warn", 42 | "never", 43 | ], 44 | "key-spacing": [ 45 | "warn", 46 | { 47 | "afterColon": true, 48 | "mode": "minimum", 49 | }, 50 | ], 51 | "strict": [ 52 | "warn", 53 | "safe", 54 | ], 55 | "no-new-require": [ 56 | "warn", 57 | ], 58 | "global-require": [ 59 | "warn", 60 | ], 61 | "no-template-curly-in-string": [ 62 | "warn", 63 | ], 64 | "no-unsafe-negation": [ 65 | "warn", 66 | ], 67 | "block-scoped-var": [ 68 | "warn", 69 | ], 70 | "func-call-spacing": [ 71 | "warn", 72 | "never", 73 | ], 74 | "no-extra-semi": [ 75 | "warn", 76 | ], 77 | "no-empty-function": [ 78 | "warn", 79 | ], 80 | "no-eval": [ 81 | "warn", 82 | ], 83 | "no-extend-native": [ 84 | "warn", 85 | ], 86 | "no-floating-decimal": [ 87 | "warn", 88 | ], 89 | "no-global-assign": [ 90 | "warn", 91 | ], 92 | "no-implied-eval": [ 93 | "warn", 94 | ], 95 | "no-lone-blocks": [ 96 | "warn", 97 | ], 98 | "no-loop-func": [ 99 | "warn", 100 | ], 101 | "no-param-reassign": [ 102 | "warn", 103 | { 104 | "props": false, 105 | }, 106 | ], 107 | "no-return-assign": [ 108 | "warn", 109 | ], 110 | "no-self-compare": [ 111 | "warn", 112 | ], 113 | "no-sequences": [ 114 | "warn", 115 | ], 116 | "no-throw-literal": [ 117 | "warn", 118 | ], 119 | "no-useless-escape": [ 120 | "warn", 121 | ], 122 | "no-void": [ 123 | "warn", 124 | ], 125 | "no-with": [ 126 | "warn", 127 | ], 128 | "vars-on-top": [ 129 | "warn", 130 | ], 131 | "no-catch-shadow": [ 132 | "warn", 133 | ], 134 | "no-label-var": [ 135 | "warn", 136 | ], 137 | "no-shadow-restricted-names": [ 138 | "warn", 139 | ], 140 | 141 | "no-shadow": "off", 142 | "@typescript-eslint/no-shadow": ["warn"], 143 | 144 | "no-undef-init": [ 145 | "warn", 146 | ], 147 | "no-undefined": [ 148 | "warn", 149 | ], 150 | "no-use-before-define": [ 151 | "warn", 152 | { 153 | "functions": false, 154 | "classes": true, 155 | }, 156 | ], 157 | "comma-dangle": [ 158 | "warn", 159 | "always-multiline", 160 | ], 161 | 162 | // Incompatible with TypeScript 163 | // eslint-disable-next-line 164 | "no-unused-vars": "off", 165 | "@typescript-eslint/no-unused-vars": [ 166 | "warn", 167 | { 168 | "vars": "all", 169 | "args": "after-used", 170 | "argsIgnorePattern": "^_", 171 | }, 172 | ], 173 | 174 | "no-console": [ 175 | "warn", 176 | { 177 | "allow": ["warn", "error"], 178 | }, 179 | ], 180 | }, 181 | "settings": { 182 | }, 183 | } 184 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in the repo. 5 | * @PikachuEXE 6 | 7 | # Order is important. The last matching pattern has the most precedence. 8 | # So if a pull request only touches javascript files, only these owners 9 | # will be requested to review. 10 | # *.rb @PikachuEXE 11 | 12 | # You can also use email addresses if you prefer. 13 | # docs/* docs@example.com 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: npm 5 | directory: "/" 6 | schedule: 7 | interval: monthly 8 | time: "06:00" 9 | timezone: Asia/Hong_Kong 10 | open-pull-requests-limit: 10 11 | labels: 12 | - "dependencies" 13 | groups: 14 | babel: 15 | patterns: 16 | - "@babel/*" 17 | - "babel-*" 18 | eslint: 19 | patterns: 20 | - "eslint" 21 | - "eslint-*" 22 | - "@eslint/*" 23 | stylelint: 24 | patterns: 25 | - "stylelint" 26 | - "stylelint-*" 27 | 28 | - package-ecosystem: github-actions 29 | directory: "/" 30 | schedule: 31 | interval: monthly 32 | time: "06:00" 33 | timezone: Asia/Hong_Kong 34 | open-pull-requests-limit: 10 35 | labels: 36 | - "dependencies" 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | product/* 2 | Gemfile.lock 3 | node_modules/* 4 | build/* 5 | .idea/* 6 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "stylelint-order", 4 | "stylelint-csstree-validator" 5 | ], 6 | "rules": { 7 | "color-hex-case": "lower", 8 | "color-hex-length": "long", 9 | "color-no-invalid-hex": true, 10 | 11 | "font-family-name-quotes": "always-where-recommended", 12 | 13 | "number-leading-zero": "always", 14 | "number-no-trailing-zeros": true, 15 | 16 | "string-no-newline": true, 17 | "string-quotes": "double", 18 | 19 | "length-zero-no-unit": true, 20 | 21 | "time-min-milliseconds": 100, 22 | 23 | "unit-case": "lower", 24 | "unit-no-unknown": true, 25 | "unit-whitelist": ["px", "em", "rem", "%", "s", "deg", "rad", "grad", "turn", "pc", "dppx"], 26 | 27 | "value-keyword-case": "lower", 28 | 29 | "shorthand-property-no-redundant-values": null, 30 | 31 | "property-case": "lower", 32 | 33 | "declaration-bang-space-after": "never", 34 | "declaration-bang-space-before": "always", 35 | "declaration-colon-space-after": null, 36 | "declaration-block-no-duplicate-properties": [ 37 | true, 38 | { 39 | "ignore": ["consecutive-duplicates"], 40 | "ignoreProperties": ["/^\\*/"] 41 | } 42 | ], 43 | "declaration-block-no-shorthand-property-overrides": true, 44 | "declaration-block-semicolon-newline-after": "always", 45 | "declaration-block-semicolon-newline-before": "never-multi-line", 46 | "declaration-block-semicolon-space-after": null, 47 | "declaration-block-semicolon-space-before": "never", 48 | "declaration-block-single-line-max-declarations": 1, 49 | "declaration-block-trailing-semicolon": "always", 50 | 51 | "block-closing-brace-newline-after": "always", 52 | "block-closing-brace-space-before": "always-single-line", 53 | "block-no-empty": null, 54 | "block-opening-brace-newline-after": "always", 55 | "block-closing-brace-newline-before": "always", 56 | "block-opening-brace-space-after": "always-single-line", 57 | "block-opening-brace-space-before": "always", 58 | 59 | "selector-combinator-space-after": "always", 60 | "selector-combinator-space-before": "always", 61 | "selector-descendant-combinator-no-non-space": true, 62 | "csstree/validator": true, 63 | "selector-pseudo-class-case": "lower", 64 | "selector-pseudo-class-no-unknown": true, 65 | "selector-pseudo-element-case": "lower", 66 | "selector-pseudo-element-no-unknown": true, 67 | "selector-type-case": "lower", 68 | "selector-max-empty-lines": 0, 69 | 70 | "comment-no-empty": true, 71 | 72 | "indentation": [ 73 | 2, 74 | { 75 | "ignore": ["inside-parens"] 76 | } 77 | ], 78 | 79 | "no-empty-source": true, 80 | "no-eol-whitespace": true, 81 | "no-extra-semicolons": true, 82 | 83 | "order/order": [ 84 | "dollar-variables", 85 | "declarations", 86 | "rules" 87 | ], 88 | 89 | "order/properties-order": [ 90 | { 91 | "groupName": "positioning", 92 | "emptyLineBefore": "always", 93 | "properties": [ 94 | "position", 95 | "top", 96 | "bottom", 97 | "left", 98 | "right", 99 | "z-index" 100 | ], 101 | "order": "flexible", 102 | "noEmptyLineBetween": true 103 | }, 104 | 105 | { 106 | "groupName": "spacing", 107 | "emptyLineBefore": "always", 108 | "properties": [ 109 | "margin", 110 | "margin-top", 111 | "margin-bottom", 112 | "margin-left", 113 | "margin-right", 114 | "border", 115 | "border-top", 116 | "border-bottom", 117 | "border-left", 118 | "border-right", 119 | "border-width", 120 | "border-style", 121 | "border-color", 122 | "border-radius", 123 | "padding", 124 | "padding-top", 125 | "padding-bottom", 126 | "padding-left", 127 | "padding-right" 128 | ], 129 | "noEmptyLineBetween": true 130 | }, 131 | 132 | { 133 | "groupName": "dimensions", 134 | "emptyLineBefore": "always", 135 | "properties": [ 136 | "display", 137 | "overflow", 138 | 139 | "height", 140 | "width", 141 | "min-height", 142 | "min-width", 143 | "max-height", 144 | "max-width", 145 | 146 | "box-sizing", 147 | 148 | "flex", 149 | "flex-basis", 150 | "flex-direction", 151 | "flex-flow", 152 | "flex-grow", 153 | "flex-shrink", 154 | "flex-wrap", 155 | "align-content", 156 | "align-items", 157 | "align-self", 158 | "justify-content", 159 | "order" 160 | ], 161 | "order": "flexible", 162 | "noEmptyLineBetween": true 163 | }, 164 | 165 | { 166 | "groupName": "coloring", 167 | "emptyLineBefore": "always", 168 | "properties": [ 169 | "color", 170 | "background-color" 171 | ], 172 | "noEmptyLineBetween": true 173 | }, 174 | 175 | { 176 | "groupName": "font", 177 | "emptyLineBefore": "always", 178 | "properties": [ 179 | "font-family", 180 | "font-size", 181 | "font-weight", 182 | "text-decoration", 183 | "line-height", 184 | "text-align", 185 | "text-transform" 186 | ], 187 | "order": "flexible", 188 | "noEmptyLineBetween": true 189 | } 190 | ] 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project does NOT adhere to [Semantic Versioning](http://semver.org/) YET (Will do so after rewrite). 4 | 5 | 6 | ## [Unreleased][unreleased] - YYYY-MM-DD 7 | 8 | ### Added 9 | - Nothing 10 | 11 | ### Changed 12 | - Nothing 13 | 14 | ### Fixed 15 | - Nothing 16 | 17 | 18 | ## [0.15.0][0.15.0] - 2021-12-13 19 | 20 | 21 | ### Added 22 | - Implement close button visibility 23 | https://github.com/tabkit/tabkit2/pull/198 24 | The option was there but the feature was not 25 | 26 | ### Changed 27 | - Update text for preference panel 28 | https://github.com/tabkit/tabkit2/pull/200 29 | 30 | ### Fixed 31 | - Workaround tab disappearing issue 32 | https://github.com/tabkit/tabkit2/pull/210 33 | 34 | ### Dev 35 | - Converted JS Source Code from Flow to TypeScript 36 | https://github.com/tabkit/tabkit2/pull/192 37 | - Added doc for extension development 38 | https://github.com/tabkit/tabkit2#extension-development 39 | 40 | 41 | ## [0.14.0][0.14.0] - 2018-12-30 42 | 43 | ### Added 44 | - Add API for other extensions to call for compatibility([#151](https://github.com/tabkit/tabkit2/pull/151)) 45 | 46 | 47 | ## [0.13.3][0.13.3] - 2018-08-18 48 | 49 | ### Fixed 50 | - Workaround the webpage "frame" being collapsed with the tab bar on fullscreen 51 | 52 | 53 | ## [0.13.2][0.13.2] - 2018-06-10 54 | 55 | ### Fixed 56 | - Add back fullscreen mode related preference for PaleMoon 28 57 | 58 | 59 | ## [0.13.1][0.13.1] - 2018-04-05 60 | 61 | ### Fixed 62 | - Fix vertical tab bar not hiding in fullscreen mode 63 | 64 | 65 | ## [0.13.0][0.13.0] - 2017-12-28 66 | 67 | ### Changed 68 | - Declare extension as written for Pale Moon 69 | 70 | ### Fixed 71 | - Fix some bugs when using this extension on Pale Moon 72 | 73 | 74 | ## [0.12.17][0.12.17] - 2017-05-29 75 | 76 | ### Fixed 77 | - Fix scrollbar malfunctioning due to usage of deprecated event 78 | 79 | 80 | ## [0.12.16][0.12.16] - 2017-03-12 81 | 82 | ### Changed 83 | - Declare as compatible with 52.x 84 | FF 45.x should just use old versions 85 | 86 | ### Fixed 87 | - Not working on FF 52 88 | 89 | 90 | ## [0.12.15][0.12.15] - 2016-06-19 91 | 92 | ### Changed 93 | - Declare as compatible with 38.x (PikachuEXE is still using 38.x) 94 | 95 | ### Fixed 96 | - Try to fix multiple screen issue by removing DPI related stuff 97 | 98 | 99 | ## [0.12.14][0.12.14] - 2016-05-22 100 | 101 | ### Fixed 102 | - Fix selected tab was always changed even after closing an inactive tab 103 | (caused by incorrect conversion of old way method patch to new way) 104 | 105 | 106 | ## [0.12.13][0.12.13] - 2016-05-15 107 | 108 | ### Fixed 109 | - Fix items in bookmark / history sidebar or window could not be opened due to incorrect method patching 110 | - Fix drop indicator not positioned correctly in multi-row mode 111 | 112 | 113 | ## [0.12.12][0.12.12] - 2016-05-08 114 | 115 | ### Fixed 116 | - Fix tabs open by opening single bookmark entry were always unrelated even user prefers them to be opened as related 117 | - Fix tabs opened by bookmark groups (a set of bookmark entries) were not positioned according preference 118 | - Fix extension malfunctioning if browser starts without search bar in layout 119 | 120 | 121 | ## [0.12.11][0.12.11] - 2016-05-02 122 | 123 | ### Fixed 124 | - [Regression] Fix duplicate tab function in FF 45.x (again) 125 | 126 | 127 | ## [0.12.10][0.12.10] - 2016-05-02 128 | 129 | ### Changed 130 | - Many Many Many code patching using `eval` which is considered as a security issue has been changed to use "the new way" 131 | (with property replacing + `function#apply`) 132 | This *might* bring some regressions 133 | (I have tested briefly for each place changed to use "the new way", but don't trust my testing) 134 | 135 | ### Fixed 136 | - Scrollbar will now return to pre-collapse position after collapsed (vertical) tab bar expanded 137 | 138 | 139 | ## [0.12.9][0.12.9] - 2016-04-24 140 | 141 | ### Fixed 142 | - [Regression] New tabs opened by search text box (in browser menu bar) are now placed properly 143 | 144 | 145 | ## [0.12.8][0.12.8] - 2016-04-17 146 | 147 | ### Fixed 148 | - Remove an old "workaround" that causes more unexpected issues, including "forever hidden tabs" ([Issue 71][issue_71]) 149 | Again (2nd time) 150 | - Fix duplicate tab function in FF 45.x, but not tested in 38.x yet 151 | 152 | 153 | ## [0.12.7][0.12.7] - 2016-04-02 154 | 155 | ### Fixed 156 | - Fix new tab behaviour when opening a new tab with new tab button of Ctrl+T keyboard shortcut 157 | - Fix feature "open new tab from address bar" broken in last version due to usage of new "patches" 158 | 159 | 160 | ## [0.12.6][0.12.6] - 2016-03-30 161 | 162 | ### Changed 163 | - Only allow 45.x to install this version, since FF 38.x can use last version without problem 164 | - Disable tab duplicating feature since it's still buggy on FF 45.x 165 | It will be fixed soon 166 | 167 | ### Fixed 168 | - Fix tab coloring for FF 45.x 169 | - Fix new tab behaviour (maybe partially) for FF 45.x 170 | 171 | 172 | ## [0.12.5][0.12.5] - 2016-02-12 173 | 174 | ### Fixed 175 | - Add new preference to allow users to fix [#96][issue_96] in different versions of Firefox 176 | Tested with 38.6.0 and 44.0.1 which behave differently 177 | 178 | 179 | ## [0.12.4][0.12.4] - 2016-01-10 180 | 181 | ### Fixed 182 | - Workaround [#92][issue_92] by adding back the workaround removed in last version ([0.12.3][0.12.3]) 183 | This will cause [#71][issue_71] again, but that issue was less serious 184 | The workaround will be kept until a permanent fix is developed 185 | 186 | 187 | ## [0.12.3][0.12.3] - 2015-10-11 188 | 189 | ### Added 190 | - Add new preference to allow hiding the vertical tab bar splitter on fullscreen 191 | See "Tab Bar" in options 192 | 193 | ### Fixed 194 | - Remove an old "workaround" that causes more unexpected issues, including "forever hidden tabs" ([Issue 71][issue_71]) 195 | No regression is found with the "workaround" removed. 196 | - Disable window dragging by dragging the scrollbar on tab bar which makes the scrollbar difficult to use. ([Issue 87][issue_87]) 197 | 198 | 199 | ## 0.12.2 200 | 201 | ### Enhancements 202 | - "Close Tabs From Here To Current" now does NOT close selected tab 203 | - Add new functions "Protect All Tabs in Group" & "Unprotect All Tabs in Group" for tab groups with menu items 204 | 205 | 206 | ## 0.12.1 207 | 208 | ### Bug Fix 209 | - Fix fullscreen vertical tab bar behaviour (#80) 210 | 211 | 212 | ## 0.12.0 213 | 214 | ### Changes 215 | 216 | - Only support Firefox 31 ESR 217 | (Firefox of other versions can still install the extension, but issues for those will be ignored) 218 | 219 | ### New Features 220 | - Add "Flatten Sub Group" 221 | 222 | ### Enhancements 223 | - Bind hotkey to "Flatten Sub Group" instead of "Flatten Group" to be safe 224 | 225 | ### Bug Fix 226 | - Fix "Splitter cannot be dragged when vertical tabbar has a small width" (#65) 227 | - Fix "Vertical Tab Bar Has Horizontal Tabs Jammed In" (#58) by removing a "fix" that is no longer needed by OSX 228 | - No longer remove the original tab when copying a single tab to a different browser window 229 | - Fix moving group to a new window 230 | - Fix strange sidebar arrangement when using with extension "All-In-One Sidebar" 231 | 232 | 233 | ## 0.11.2 234 | 235 | ### Bug Fix 236 | - Fix tabbar left right are reversed in Firefox 29 (Tested with Classic Theme Restorer 1.1.9) 237 | - Fix vertical tabbar splitter not showing on Firefox 29 on startup 238 | 239 | ### Known Bugs 240 | - Due to the bug fix above, the tab bar position is reversed on Firefox 28 or below (Won't fix) 241 | 242 | 243 | ## 0.11.1 244 | 245 | ### Bug Fix 246 | - Fix "Protect Tab" functionality on Firefox 29 247 | 248 | 249 | ## 0.11.0 250 | 251 | ### Changes 252 | 253 | - Compatible with Firefox 29 254 | - Now requires [Classic Theme Restorer](https://addons.mozilla.org/en-US/firefox/addon/classicthemerestorer/) Extension 255 | Required options for `Classic Theme Restorer`: 256 | - Select `Tabs not on Top`: should fix the vertical tabbar direction 257 | - Uncheck `Tabs in title bar`: should fix the totally unusable layout 258 | 259 | 260 | ## 0.10.6 261 | 262 | ### Enhancements 263 | - Add option to toggle "force disable TabsOnTop" (Options -> Tab Bar) 264 | 265 | 266 | ## 0.10.5 267 | 268 | ### New Features 269 | - Open clipboard URIs in group (right click -> Tab Kit) 270 | 271 | ### Enhancements 272 | - When closing multiple tabs, close from the right/bottom first, so that the parent can be restored first 273 | - Remove access key for ungrouping tab groups to avoid accidents 274 | - Disallow "Pin Tab" in vertical mode (but allow in horizontal mode) 275 | - Add option to enable Panorama (Options -> Experimental) 276 | 277 | ### Changes 278 | - Always disable TabsOnTop to avoid layout issue 279 | 280 | ### Bug Fix 281 | - Moving tab across window will now close the original one from old window 282 | 283 | 284 | ## 0.10.4 285 | - Add: Menu item for closing tabs from target tab to current tab 286 | - Change: Recoloring a single group now ignores the surrounding groups (otherwise it might have too little effect) 287 | 288 | 289 | ## 0.10.3 290 | - Add: Menu items for re-coloring a group and all groups (Right click on a group) 291 | - Change: Minimal tab width can now be set down to 50px (per request in review) 292 | - Fix: Changing minimal tab width now has effect again (no error report before) 293 | 294 | 295 | ## 0.10.2 296 | - Remove: Warning message and Firefox built-in protection when using "Close tabs left/right/above/below" 297 | 298 | 299 | ## 0.10.1 300 | - Change: Some Grouping coloring options no longer require restart 301 | - Change: Change and cleanup some code to work with Tab Kit - Tab Highlighter 0.2.1 302 | 303 | 304 | ## 0.10.0 305 | - Add: Copy group URLs, separated by newlines (#4) 306 | - Remove: Some coloring features extracted into [Tab Kit - Tab Highlighter](https://github.com/tabkit/tab-highlighter) 307 | - Remove: Some mouse gesture features extracted into [Tab Kit - Mouse Gestures](https://github.com/tabkit/mouse-gestures) 308 | - Fix: Groups and sub-groups can be dragged across windows again (#3) 309 | - Fix: Tab search box (if enabled) will auto-collapse in horizontal mode again (#13) 310 | 311 | 312 | ## 0.9.10 313 | - Fix: Bookmark and History opened in new tab not working (#23) 314 | - Change: Several options does not cache per window anymore, Not sure if this will cause bugs 315 | 316 | 317 | [unreleased]: https://github.com/tabkit/tabkit2/compare/v0.15.0...HEAD 318 | [0.15.0]: https://github.com/tabkit/tabkit2/compare/v0.14.0...v0.15.0 319 | [0.14.0]: https://github.com/tabkit/tabkit2/compare/v0.13.3...v0.14.0 320 | [0.13.3]: https://github.com/tabkit/tabkit2/compare/v0.13.2...v0.13.3 321 | [0.13.2]: https://github.com/tabkit/tabkit2/compare/v0.13.1...v0.13.2 322 | [0.13.1]: https://github.com/tabkit/tabkit2/compare/v0.13.0...v0.13.1 323 | [0.13.0]: https://github.com/tabkit/tabkit2/compare/v0.12.17...v0.13.0 324 | [0.12.17]: https://github.com/tabkit/tabkit2/compare/v0.12.16...v0.12.17 325 | [0.12.16]: https://github.com/tabkit/tabkit2/compare/v0.12.15...v0.12.16 326 | [0.12.15]: https://github.com/tabkit/tabkit2/compare/v0.12.14...v0.12.15 327 | [0.12.14]: https://github.com/tabkit/tabkit2/compare/v0.12.13...v0.12.14 328 | [0.12.13]: https://github.com/tabkit/tabkit2/compare/v0.12.12...v0.12.13 329 | [0.12.12]: https://github.com/tabkit/tabkit2/compare/v0.12.11...v0.12.12 330 | [0.12.11]: https://github.com/tabkit/tabkit2/compare/v0.12.10...v0.12.11 331 | [0.12.10]: https://github.com/tabkit/tabkit2/compare/v0.12.9...v0.12.10 332 | [0.12.9]: https://github.com/tabkit/tabkit2/compare/v0.12.8...v0.12.9 333 | [0.12.8]: https://github.com/tabkit/tabkit2/compare/v0.12.7...v0.12.8 334 | [0.12.7]: https://github.com/tabkit/tabkit2/compare/v0.12.6...v0.12.7 335 | [0.12.6]: https://github.com/tabkit/tabkit2/compare/v0.12.5...v0.12.6 336 | [0.12.5]: https://github.com/tabkit/tabkit2/compare/v0.12.4...v0.12.5 337 | [0.12.4]: https://github.com/tabkit/tabkit2/compare/v0.12.3...v0.12.4 338 | [0.12.3]: https://github.com/tabkit/tabkit2/compare/v0.12.2...v0.12.3 339 | 340 | [issue_96]: https://github.com/tabkit/tabkit2/issues/96 341 | [issue_92]: https://github.com/tabkit/tabkit2/issues/92 342 | [issue_87]: https://github.com/tabkit/tabkit2/issues/87 343 | [issue_71]: https://github.com/tabkit/tabkit2/issues/71 344 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tab Kit 2 2 | 3 | This project aims to make the original [Tab Kit(TK)](https://addons.mozilla.org/en-us/firefox/addon/tab-kit/) Pale Moon compatible. 4 | 5 | 6 | ## Firefox Support Is Gone, Welcome Pale Moon 7 | Since Firefox 57+ only supports their new kind of extension ("WebExtensions"), supporting it would require a complete rewrite. 8 | With the time (I got a day job) and the knowledge (WebExtensions is completely different in code layout, functionality support) I have, 9 | I decide to switch to support Pale Moon. It supports XUL extensions (the "old" extension type) like DownThemAll forever. 10 | 11 | You have several altermatives here: 12 | - Pale Moon with Tab Kit 2 (download from below, don't use the Firefox one!) 13 | - Vivaldi (Chromium based browser with vertical tab + another kind of tab grouping) 14 | - Firefox with another extension with tab tree support 15 | 16 | I am using Pale Moon + Vivaldi myself. 17 | 18 | 19 | ## Description from original Tab Kit (modified) 20 | Tab Kit makes tabs more efficient for power users, allowing a wide variety of tweaks, all of which are optional, notably: 21 | 22 | - Group tabs, by domain or opener (parent) tab, manually or automatically 23 | - Vertical tab tree (with splitter), like Tree Style Tab 24 | - Multi-row tabs 25 | - Sort tabs, by address, last loaded, last viewed, order of creation, origin or title 26 | - Control new tab position and close order 27 | - Easily duplicate tabs and groups and copy/move them between windows by dragging 28 | - Scrollwheel tab switch (Extracted to [Tab Kit - Mouse Gestures](https://github.com/tabkit/mouse-gestures)) 29 | - 'Mouse rocker' to go back/forward in history (Extracted to [Tab Kit - Mouse Gestures](https://github.com/tabkit/mouse-gestures)) 30 | - Highlight unread tabs (and emphasise current tab) (Extracted to [Tab Kit - Tab Highlighter](https://github.com/tabkit/tab-highlighter)) 31 | - Scrollbar instead of scroll arrows in over-long Bookmarks and All Tabs popups 32 | - Open Selected Links feature 33 | - Switch tabs on hover (Extracted to [Tab Kit - Mouse Gestures](https://github.com/tabkit/mouse-gestures)) 34 | - Options for urls, searches and/or bookmarks to open in new tabs by default 35 | 36 | 37 | ## Download / Installation 38 | - [Tab Kit 2 on Palemoon Addon website](http://addons.palemoon.org/addon/tabkit2/) 39 | - [More Palemoon Add-ons](http://addons.palemoon.org/extensions/) 40 | 41 | 42 | ## Extra Extensions 43 | 44 | Some features are extracted into other extensions (which can be used separately): 45 | - Some coloring features extracted into **Tab Kit - Tab Highlighter**([Download](http://addons.palemoon.org/addon/tabkit-tab-highlighter/), [Code Repo](https://github.com/tabkit/tab-highlighter)) 46 | - Some mouse gesture features extracted into **Tab Kit - Mouse Gestures**([Download](http://addons.palemoon.org/addon/tabkit-mouse-gestures/), [Code Repo](https://github.com/tabkit/mouse-gestures)) 47 | 48 | ### Examples 49 | 50 | ### Q: How can I have a plain gray tab bar background? ([Source](https://github.com/tabkit/tabkit2/issues/142#issuecomment-379464167)) 51 | 52 | Install [Tab Kit - Tab Highlighter](https://github.com/tabkit/tab-highlighter) 53 | 54 | ![a](https://user-images.githubusercontent.com/1018543/40882958-1295bef6-6724-11e8-8bda-bd3c03efd83f.png) 55 | 56 | 57 | ## Issue 58 | - [Github (here)](https://github.com/tabkit/tabkit2/issues) 59 | I have moved a few issues from Google Code, move more if you think it's necessary 60 | 61 | 62 | ## Changes 63 | See https://github.com/tabkit/tabkit2/blob/master/CHANGELOG.md 64 | 65 | 66 | ## Tab Kit Series Extensions 67 | - [Tab Kit 2](https://github.com/tabkit/tabkit2) 68 | - [Tab Kit - Tab Highlighter](https://github.com/tabkit/tab-highlighter) 69 | - [Tab Kit - Mouse Gestures](https://github.com/tabkit/mouse-gestures) 70 | 71 | 72 | ## Collaboration 73 | Since we are on GitHub 74 | Just fork, change and send pull request 75 | I will check frequently (since I also use GitHub at work) 76 | 77 | ### Extension Development 78 | See [Extension Development](doc/extension_development.md) 79 | 80 | 81 | ## License 82 | 83 | Tab Kit 2 84 | 85 | Copyright (c) 2011-2017 Leung Ho Kuen 86 | 87 | This file is part of Tab Kit 2. 88 | Tab Kit is free software; you can redistribute it and/or 89 | modify it under the terms of the GNU General Public License 90 | as published by the Free Software Foundation; either version 2 91 | of the License, or (at your option) any later version. 92 | 93 | Tab Kit 2 is distributed in the hope that it will be useful, 94 | but WITHOUT ANY WARRANTY; without even the implied warranty of 95 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 96 | GNU General Public License for more details. 97 | 98 | You should have received a copy of the GNU General Public License 99 | along with this program; if not, write to the Free Software 100 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 101 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function config(api) { 2 | // Cache the returned value forever and don't call this function again. 3 | api.cache(true) 4 | 5 | // Don't cache at all. Not recommended because it will be very slow. 6 | // api.cache(false) 7 | 8 | // Cached based on the value of some function. If this function returns a value different from 9 | // a previously-encountered value, the plugins will re-evaluate. 10 | // var env = api.cache(() => process.env.NODE_ENV) 11 | 12 | // If testing for a specific env, we recommend specifics to avoid instantiating a plugin for 13 | // any possible NODE_ENV value that might come up during plugin execution. 14 | // var isProd = api.cache(() => process.env.NODE_ENV === "production") 15 | 16 | // .cache(fn) will perform a linear search though instances to find the matching plugin based 17 | // based on previous instantiated plugins. If you want to recreate the plugin and discard the 18 | // previous instance whenever something changes, you may use: 19 | // var isProd = api.cache.invalidate(() => process.env.NODE_ENV === "production") 20 | 21 | 22 | return { 23 | "comments": false, 24 | "retainLines": true, 25 | "presets": [ 26 | "@babel/typescript", 27 | ], 28 | "plugins": [ 29 | "@babel/plugin-transform-class-properties", 30 | "@babel/plugin-transform-object-rest-spread", 31 | ], 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /doc/extension_development.md: -------------------------------------------------------------------------------- 1 | # Extension Development 2 | This document will explain stuff required to develop this extension. 3 | 4 | ## Environments 5 | 6 | ### Browser 7 | You should have 8 | - [Palemoon](https://www.palemoon.org/download.shtml) (Windows/Linux) - the latest version this extension supports 9 | Portable Version Recommended (for extension development) 10 | - [White Star](https://dbsoft.org/whitestar.php) (MacOS) - the latest version this extension supports 11 | 12 | ### Version Control System - Git 13 | - [Git for Windows](https://gitforwindows.org) 14 | - [Git for Windows but from Git Official Website](https://git-scm.com/download/windows) 15 | - [Git for Mac via Homebrew](https://formulae.brew.sh/formula/git) 16 | 17 | ### Git GUI (Optional) 18 | I use [Source Tree](https://www.sourcetreeapp.com) personally 19 | but feel free to use other GUI or simply stick to command line. 20 | 21 | ### Command Line App 22 | For MacOS, `Terminal` works but I use `iTerms` personally. 23 | Up to you to pick what you want to use. 24 | 25 | For Windows I use [Cmder](https://cmder.net) 26 | Let me know if you think there is a better choice 27 | 28 | ### Node JS + Yarn 29 | [Node.js](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com) 30 | I think both Windows and MacOS should be able to install the above 31 | 32 | 33 | ## Browser Setup 34 | 35 | ### Profile Creation 36 | You probably want to use a different profile than the default one for extension development. 37 | This can be done via 38 | - Install [Profile Switcher](https://addons.palemoon.org/addon/profile-switcher/) 39 | - Start the application with arguments 40 | - (MacOS) `open White\ Star.app --args --ProfileManager` 41 | - (Windows) `PaleMoon.exe --ProfileManager` (I haven't tested this so might be wrong) 42 | - (Linux) I have no idea 43 | - Create a new profile 44 | 45 | ### Project Setup 1 46 | Then you will have to clone the project code to your local computer first 47 | It would be something like `git pull` (Or just use the GUI) 48 | More steps before we really setup the browser: 49 | - Enter the project folder 50 | - Create a folder `build` (if it doesn't exist) 51 | - Copy the full path to that folder `build` (We will refer it as `Path A` later) 52 | 53 | ### Profile Setup 54 | Now we can setup the created profile: 55 | - Locate the folder for the created profile 56 | - (Windows) For portable it should be the `Data` folder, dig around until you find `Profiles` 57 | - (MacOS) `~/Library/Application Support/Pale Moon/Profiles/{Profile-Folder-Name}` 58 | - In **profile folder** (The one with unique name under `Profiles`) 59 | - Create folder `extensions` if it doesn't exist, and enter it 60 | - Create an empty file named `tabkit2@pikachuexe.amateur.hk` (the ID for this extension) 61 | - Edit the created file and input `Path A`, and **Save the file** 62 | 63 | ### Project Setup 2 64 | - Open "Command Line App" 65 | - Enter the project folder (`cd`?) 66 | - `yarn` 67 | - `npm run dev` (This will run a foreground process, blocking your input until you press Ctrl+C) 68 | - You can `Ctrl+C` to exit before testing the environment 69 | 70 | ### Testing 71 | - Start Palemoon/White Star 72 | - Choose the profile created/setup 73 | - Install Tab Kit (it should prompt you to install) 74 | 75 | 76 | ## Development 77 | Every time you want to make changes and preview, you need to 78 | - Update code in `src` (**Not** `build` which stores processed files generated from `src`) 79 | - Run `npm run dev` and **do not exit** (so that it keeps `build` updated when anything in `src` changed) 80 | - Start Palemoon/White Star with correct profile to preview changes 81 | 82 | 83 | ## Release 84 | This should probably be done by project owner(s) 85 | In case you want to try building your own: 86 | - Update version number and/or other stuff in `src/install.rdf` 87 | - `npm run release` 88 | - Find the built XPI file(s) in folder `product` 89 | - Upload via https://addons.palemoon.org/panel/ 90 | 91 | -------------------------------------------------------------------------------- /gulpfile.mjs: -------------------------------------------------------------------------------- 1 | // Code modified from 2 | // https://60devs.com/development-of-cross-browser-browser-extensions-using-es6-babeljs.html 3 | 4 | "use strict" 5 | 6 | import gulp from "gulp" 7 | import { deleteAsync } from "del" 8 | import babel from "gulp-babel" 9 | import zip from "gulp-zip" 10 | import dateFormat from "dateformat" 11 | 12 | import fs from "node:fs/promises" 13 | import fileExists from "file-exists" 14 | 15 | 16 | const build_path = "./build/" 17 | 18 | // watch is helpful for development 19 | function watch() { 20 | build_src() 21 | gulp.watch("./src/**/*.{js,ts}", build_src_js) 22 | gulp.watch("./src/**/*.css", build_src_css) 23 | gulp.watch( 24 | [ 25 | "./src/**/*", 26 | "!./src/**/*.{js,ts}", 27 | "!./src/**/*.css", 28 | ], 29 | build_src_static_files, 30 | ) 31 | } 32 | 33 | function clean_build() { 34 | return deleteAsync([ 35 | build_path, 36 | ]) 37 | } 38 | 39 | // we"re building js for ff 40 | function build_src_js() { 41 | return gulp.src([ 42 | "./src/**/*.{js,ts}", 43 | ]) 44 | .pipe(babel()) 45 | .on("error", console.error.bind(console)) 46 | .pipe(gulp.dest(build_path)) 47 | } 48 | 49 | // we can tweak our css. E.g. auto-prefix it but 50 | // here we just copy it 51 | function build_src_css() { 52 | return gulp.src([ 53 | "./src/**/*.css", 54 | ]) 55 | .on("error", console.error.bind(console)) 56 | .pipe(gulp.dest(build_path)) 57 | } 58 | 59 | function build_src_static_files() { 60 | return gulp.src([ 61 | "./src/**/*", 62 | "!./src/**/*.{js,ts}", 63 | "!./src/**/*.css", 64 | ]) 65 | .on("error", console.error.bind(console)) 66 | .pipe(gulp.dest(build_path)) 67 | } 68 | 69 | // a single command for each piece 70 | const build_src = gulp.series( 71 | clean_build, 72 | gulp.parallel( 73 | build_src_js, 74 | build_src_css, 75 | build_src_static_files, 76 | ), 77 | ) 78 | 79 | 80 | function build_xpi_official_release_impl() { 81 | const final_install_rdf_path = "./src/install.rdf" 82 | const product_path = "./product" 83 | const product_ext = ".xpi" 84 | 85 | return fs.readFile(final_install_rdf_path, {encoding: "utf8"}) 86 | .then(function (content) { 87 | const matchData = /(.+)<\/em:version>/i.exec(content) 88 | return matchData[1] 89 | }) 90 | .then(function (version_string) { 91 | if (typeof version_string !== "string" || version_string.length === 0) { 92 | throw new Error("Something is wrong, version is nil") 93 | } 94 | 95 | let product_filename = `tabkit2_${version_string}` 96 | 97 | if (fileExists.sync(`${product_path}/${product_filename}${product_ext}`)) { 98 | let now = new Date() 99 | product_filename = `${product_filename}-${dateFormat(now, "yyyy-mm-dd-hhMMss")}` 100 | } 101 | 102 | return gulp.src(`${build_path}/**/*`) 103 | .pipe(zip(`${product_filename}${product_ext}`)) 104 | .pipe(gulp.dest(product_path)) 105 | }) 106 | } 107 | 108 | const build_xpi_official_release = gulp.series( 109 | build_src, 110 | build_xpi_official_release_impl, 111 | ) 112 | 113 | gulp.task("default", () => watch()) 114 | gulp.task("clean_build", () => clean_build()) 115 | gulp.task("watch", () => watch()) 116 | gulp.task("build_xpi_official_release", () => build_xpi_official_release()) 117 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tabkit2", 3 | "version": "0.0.0", 4 | "description": "", 5 | "author": "", 6 | "scripts": { 7 | "dev": "gulp watch", 8 | "release": "gulp build_xpi_official_release" 9 | }, 10 | "devDependencies": { 11 | "@babel/core": "^7.27.4", 12 | "@babel/plugin-transform-class-properties": "^7.27.1", 13 | "@babel/plugin-transform-object-rest-spread": "^7.27.3", 14 | "@babel/preset-typescript": "^7.27.1", 15 | "@typescript-eslint/eslint-plugin": "^4.33.0", 16 | "@typescript-eslint/parser": "^4.33.0", 17 | "babel-eslint": ">= 7.1.1", 18 | "babelify": ">= 7.3.0", 19 | "bluebird": ">= 3.5.0", 20 | "dateformat": "4.6.3", 21 | "del": ">= 8.0.0", 22 | "eslint": ">= 9.28.0", 23 | "file-exists": ">= 3.0.2", 24 | "gulp": ">= 5.0.0", 25 | "gulp-babel": ">= 6.1.2", 26 | "gulp-cli": ">= 1.2.2", 27 | "gulp-zip": ">= 6.1.0", 28 | "mz": ">= 2.6.0", 29 | "stylelint": ">= 16.20.0", 30 | "stylelint-csstree-validator": ">= 3.0.0", 31 | "stylelint-order": ">= 7.0.0", 32 | "typescript": "^5.8.3" 33 | }, 34 | "license": "GPL-2.0+" 35 | } 36 | -------------------------------------------------------------------------------- /src/COPYING: -------------------------------------------------------------------------------- 1 | Tab Kit - http://code.google.com/p/tabkit 2 | Copyright (c) 2007-2010 John Mellor 3 | 4 | This Firefox extension, Tab Kit, is free software; you can 5 | redistribute it and/or modify it under the terms of the GNU 6 | General Public License as published by the Free Software 7 | Foundation; either version 2 of the License, or (at your 8 | option) any later version. 9 | 10 | Tab Kit is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . -------------------------------------------------------------------------------- /src/chrome.manifest: -------------------------------------------------------------------------------- 1 | content tabkit content/ 2 | 3 | overlay chrome://browser/content/browser.xul chrome://tabkit/content/browserOverlay.xul 4 | 5 | locale tabkit en-US locale/en-US/ 6 | 7 | skin tabkit classic/1.0 skin/classic/ 8 | 9 | style chrome://browser/content/browser.xul chrome://tabkit/content/variable.css 10 | -------------------------------------------------------------------------------- /src/content/bindings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 10 | 11 | 12 | 18 | 19 | 20 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/content/browserOverlay.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |