extension-develop 2.0.0-alpha.8 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/ensure-hmr-for-scripts.js +2 -2
  2. package/dist/extensions/chrome-manager-extension/manifest.json +3 -3
  3. package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/manifest.json +3 -3
  4. package/dist/extensions/chromium-based-manager-extension/pages/welcome.html +49 -0
  5. package/dist/extensions/edge-manager-extension/manifest.json +3 -3
  6. package/dist/extensions/edge-manager-extension/pages/welcome.html +1 -1
  7. package/dist/extensions/firefox-manager-extension/manifest.json +3 -3
  8. package/dist/extensions/firefox-manager-extension/pages/welcome.html +1 -1
  9. package/dist/extensions/gecko-based-manager-extension/background.js +57 -0
  10. package/dist/extensions/gecko-based-manager-extension/define-initial-tab.js +62 -0
  11. package/dist/extensions/gecko-based-manager-extension/images/logo.png +0 -0
  12. package/dist/extensions/gecko-based-manager-extension/manifest.json +16 -0
  13. package/dist/extensions/gecko-based-manager-extension/pages/sakura-dark.css +268 -0
  14. package/dist/extensions/gecko-based-manager-extension/pages/sakura.css +267 -0
  15. package/dist/extensions/{chromium-manager-extension → gecko-based-manager-extension}/pages/welcome.html +1 -1
  16. package/dist/extensions/gecko-based-manager-extension/pages/welcome.js +34 -0
  17. package/dist/extensions/gecko-based-manager-extension/reload-service.js +130 -0
  18. package/dist/inject-chromium-client-loader.js +2 -2
  19. package/dist/inject-content-css-during-dev.js +3 -3
  20. package/dist/inject-firefox-client-loader.js +9 -2
  21. package/dist/module.d.ts +33 -6
  22. package/dist/module.js +112 -127
  23. package/dist/resolver-loader.js +1 -1
  24. package/dist/resolver-module.mjs +1 -0
  25. package/package.json +21 -25
  26. package/dist/add-query-param-to-imported-css.js +0 -1
  27. package/dist/resolver-module.js +0 -1
  28. /package/dist/extensions/chrome-manager-extension/{public → images}/logo.png +0 -0
  29. /package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/background.js +0 -0
  30. /package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/define-initial-tab.js +0 -0
  31. /package/dist/extensions/{chromium-manager-extension/public → chromium-based-manager-extension/images}/logo.png +0 -0
  32. /package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/pages/sakura-dark.css +0 -0
  33. /package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/pages/sakura.css +0 -0
  34. /package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/pages/welcome.js +0 -0
  35. /package/dist/extensions/{chromium-manager-extension → chromium-based-manager-extension}/reload-service.js +0 -0
  36. /package/dist/extensions/edge-manager-extension/{public → images}/logo.png +0 -0
  37. /package/dist/extensions/firefox-manager-extension/{public → images}/logo.png +0 -0
@@ -1,3 +1,3 @@
1
- "use strict";var D=Object.create;var m=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var U=(t,n)=>{for(var s in n)m(t,s,{get:n[s],enumerable:!0})},b=(t,n,s,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of _(n))!C.call(t,r)&&r!==s&&m(t,r,{get:()=>n[r],enumerable:!(e=A(n,r))||e.enumerable});return t};var a=(t,n,s)=>(s=t!=null?D(P(t)):{},b(n||!t||!t.__esModule?m(s,"default",{value:t,enumerable:!0}):s,t)),L=t=>b(m({},"__esModule",{value:!0}),t);var Y={};U(Y,{default:()=>k});module.exports=L(Y);var x=a(require("path")),S=a(require("fs")),T=require("loader-utils"),M=require("schema-utils");var v=a(require("fs")),d=a(require("path")),E=a(require("parse5-utils"));var p=a(require("parse5-utils"));function g(t){try{return new URL(t),!0}catch{return!1}}function h(t,n){let{childNodes:s=[]}=t;for(let e of s)if(e.nodeName==="script"){let r=p.default.getAttribute(e,"src");if(!r||g(r))continue;n({filePath:r,childNode:e,assetType:"script"})}else if(e.nodeName==="link"){let r=p.default.getAttribute(e,"href"),o=p.default.getAttribute(e,"rel");if(!r||g(r))continue;n(o==="dns-prefetch"||o==="icon"||o==="manifest"||o==="modulepreload"||o==="preconnect"||o==="prefetch"||o==="preload"||o==="prerender"?{filePath:r,childNode:e,assetType:"staticHref"}:{filePath:r,childNode:e,assetType:"css"})}else if(e.nodeName==="a"||e.nodeName==="area"){let r=p.default.getAttribute(e,"href");if(!r||g(r))continue;n({filePath:r,childNode:e,assetType:"staticHref"})}else if(e.nodeName==="audio"||e.nodeName==="embed"||e.nodeName==="iframe"||e.nodeName==="img"||e.nodeName==="input"||e.nodeName==="source"||e.nodeName==="track"||e.nodeName==="video"){let r=p.default.getAttribute(e,"src");if(!r||g(r))continue;n({filePath:r,childNode:e,assetType:"staticSrc"})}else h(e,n)}function N(t,n){let s={css:[],js:[],static:[]};if(!t)return s;let e=n||v.default.readFileSync(t,{encoding:"utf8"}),r=E.default.parse(e),o=(i,c)=>d.default.join(d.default.dirname(i),c.startsWith("/")?d.default.relative(d.default.dirname(i),c):c);for(let i of r.childNodes)if(i.nodeName==="html"){for(let c of i.childNodes)(c.nodeName==="head"||c.nodeName==="body")&&h(c,({filePath:u,assetType:y})=>{let f=o(t,u);switch(y){case"script":s.js?.push(f);break;case"css":s.css?.push(f);break;case"staticSrc":case"staticHref":if(u.startsWith("#"))break;s.static?.push(f);break;default:break}});return{css:s.css,js:s.js,static:s.static}}}var O=a(require("path")),$=a(require("fs")),z=require("child_process"),J=require("detect-package-manager");var q=a(require("path")),l=require("@colors/colors/safe");var j=a(require("path")),H=j.default.join(process.cwd(),"node_modules/extension-develop/dist/certs"),F=["chrome","edge"],W=["firefox"],Z=[...F,...W];function w(t){let n=O.default.join(t,"package.json");if(!$.default.existsSync(n))return!1;let s=JSON.parse($.default.readFileSync(n,"utf-8")),e=["react","vue","@angular/core","svelte","solid-js","preact"],r=s.dependencies||{},o=s.devDependencies||{};for(let i of e)if(r[i]||o[i])return!0;return!1}var V={type:"object",properties:{test:{type:"string"},manifestPath:{type:"string"},includeList:{type:"object"},excludeList:{type:"object"}}};function k(t){let n=this.getOptions(),s=n.manifestPath,e=x.default.dirname(s);(0,M.validate)(V,n,{name:"html:ensure-hmr-for-scripts",baseDataPath:"options"});let r=(0,T.urlToRequest)(this.resourcePath),o=`
1
+ "use strict";var R=Object.create;var m=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var U=(t,n)=>{for(var s in n)m(t,s,{get:n[s],enumerable:!0})},b=(t,n,s,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of A(n))!C.call(t,r)&&r!==s&&m(t,r,{get:()=>n[r],enumerable:!(e=_(n,r))||e.enumerable});return t};var a=(t,n,s)=>(s=t!=null?R(P(t)):{},b(n||!t||!t.__esModule?m(s,"default",{value:t,enumerable:!0}):s,t)),L=t=>b(m({},"__esModule",{value:!0}),t);var K={};U(K,{default:()=>k});module.exports=L(K);var x=a(require("path")),w=a(require("fs")),S=require("loader-utils"),M=require("schema-utils");var v=a(require("fs")),d=a(require("path")),N=a(require("parse5-utils"));var p=a(require("parse5-utils"));function g(t){try{return new URL(t),!0}catch{return!1}}function h(t,n){let{childNodes:s=[]}=t;for(let e of s)if(e.nodeName==="script"){let r=p.default.getAttribute(e,"src");if(!r||g(r))continue;n({filePath:r,childNode:e,assetType:"script"})}else if(e.nodeName==="link"){let r=p.default.getAttribute(e,"href"),o=p.default.getAttribute(e,"rel");if(!r||g(r))continue;n(o==="dns-prefetch"||o==="icon"||o==="manifest"||o==="modulepreload"||o==="preconnect"||o==="prefetch"||o==="preload"||o==="prerender"?{filePath:r,childNode:e,assetType:"staticHref"}:{filePath:r,childNode:e,assetType:"css"})}else if(e.nodeName==="a"||e.nodeName==="area"){let r=p.default.getAttribute(e,"href");if(!r||g(r))continue;n({filePath:r,childNode:e,assetType:"staticHref"})}else if(e.nodeName==="audio"||e.nodeName==="embed"||e.nodeName==="iframe"||e.nodeName==="img"||e.nodeName==="input"||e.nodeName==="source"||e.nodeName==="track"||e.nodeName==="video"){let r=p.default.getAttribute(e,"src");if(!r||g(r))continue;n({filePath:r,childNode:e,assetType:"staticSrc"})}else h(e,n)}function j(t,n){let s={css:[],js:[],static:[]};if(!t)return s;let e=n||v.default.readFileSync(t,{encoding:"utf8"}),r=N.default.parse(e),o=(i,c)=>d.default.join(d.default.dirname(i),c.startsWith("/")?d.default.relative(d.default.dirname(i),c):c);for(let i of r.childNodes)if(i.nodeName==="html"){for(let c of i.childNodes)(c.nodeName==="head"||c.nodeName==="body")&&h(c,({filePath:u,assetType:y})=>{let f=o(t,u);switch(y){case"script":s.js?.push(f);break;case"css":s.css?.push(f);break;case"staticSrc":case"staticHref":if(u.startsWith("#"))break;s.static?.push(f);break;default:break}});return{css:s.css,js:s.js,static:s.static}}}var O=a(require("path")),$=a(require("fs")),J=require("child_process"),V=require("package-manager-detector");var q=a(require("path")),l=require("@colors/colors/safe");var E=a(require("path")),H=E.default.join(process.cwd(),"node_modules/extension-develop/dist/certs"),F=["chrome","edge"],W=["firefox"],ee=[...F,...W];var z=require("console");function T(t){let n=O.default.join(t,"package.json");if(!$.default.existsSync(n))return!1;let s=JSON.parse($.default.readFileSync(n,"utf-8")),e=["react","vue","@angular/core","svelte","solid-js","preact"],r=s.dependencies||{},o=s.devDependencies||{};for(let i of e)if(r[i]||o[i])return!0;return!1}var G={type:"object",properties:{test:{type:"string"},manifestPath:{type:"string"},includeList:{type:"object"},excludeList:{type:"object"}}};function k(t){let n=this.getOptions(),s=n.manifestPath,e=x.default.dirname(s);(0,M.validate)(G,n,{name:"html:ensure-hmr-for-scripts",baseDataPath:"options"});let r=(0,S.urlToRequest)(this.resourcePath),o=`
2
2
  if (import.meta.webpackHot) { import.meta.webpackHot.accept() };
3
- `;if(w(e))return t;let i=n.includeList||{};for(let c of Object.entries(i)){let[,u]=c;if(u){if(!S.default.existsSync(u))return;let f=N(u)?.js||[];for(let R of f){let I=x.default.resolve(e,R);if(r.includes(I))return`${o}${t}`}}}return t}
3
+ `;if(T(e))return t;let i=n.includeList||{};for(let c of Object.entries(i)){let[,u]=c;if(u){if(!w.default.existsSync(u))return;let f=j(u)?.js||[];for(let D of f){let I=x.default.resolve(e,D);if(r.includes(I))return`${o}${t}`}}}return t}
@@ -9,9 +9,9 @@
9
9
  "type": "module"
10
10
  },
11
11
  "icons": {
12
- "16": "./public/logo.png",
13
- "48": "./public/logo.png",
14
- "128": "./public/logo.png"
12
+ "16": "images/logo.png",
13
+ "48": "images/logo.png",
14
+ "128": "images/logo.png"
15
15
  },
16
16
  "permissions": ["management", "tabs", "storage"]
17
17
  }
@@ -9,9 +9,9 @@
9
9
  "type": "module"
10
10
  },
11
11
  "icons": {
12
- "16": "./public/logo.png",
13
- "48": "./public/logo.png",
14
- "128": "./public/logo.png"
12
+ "16": "images/logo.png",
13
+ "48": "images/logo.png",
14
+ "128": "images/logo.png"
15
15
  },
16
16
  "permissions": ["management", "tabs", "storage"]
17
17
  }
@@ -0,0 +1,49 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Welcome!</title>
5
+ <meta charset="UTF-8" />
6
+ <link
7
+ rel="icon"
8
+ href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🧩</text></svg>"
9
+ />
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
+ <link rel="stylesheet" href="./sakura.css" media="screen" />
12
+ <link
13
+ rel="stylesheet"
14
+ href="./sakura-dark.css"
15
+ media="screen and (prefers-color-scheme: dark)"
16
+ />
17
+ <style>
18
+ .center-middle {
19
+ display: flex;
20
+ flex-direction: column;
21
+ justify-content: center;
22
+ height: 100vh;
23
+ padding: 0;
24
+ margin: 0;
25
+ }
26
+ </style>
27
+ </head>
28
+ <body>
29
+ <div class="center-middle">
30
+ <h1 style="font-size: 4.2em">
31
+ Chromium-based Extension<br />
32
+ <a href="#"><span id="extensionName"></span></a><br />
33
+ ready.
34
+ </h1>
35
+ <p id="extensionDescription"></p>
36
+ <p>
37
+ <a target="_blank" href="https://github.com/cezaraugusto/extension"
38
+ >🧩 Extension.js</a
39
+ >
40
+ is a development tool for browser extensions with built-in support for
41
+ TypeScript, WebAssembly, React, and modern JavaScript.
42
+ </p>
43
+ <button id="learnMore">
44
+ 🧩 Learn more about developing cross-browser extensions
45
+ </button>
46
+ </div>
47
+ <script src="welcome.js"></script>
48
+ </body>
49
+ </html>
@@ -9,9 +9,9 @@
9
9
  "type": "module"
10
10
  },
11
11
  "icons": {
12
- "16": "./public/logo.png",
13
- "48": "./public/logo.png",
14
- "128": "./public/logo.png"
12
+ "16": "images/logo.png",
13
+ "48": "images/logo.png",
14
+ "128": "images/logo.png"
15
15
  },
16
16
  "permissions": ["management", "tabs", "storage"]
17
17
  }
@@ -28,7 +28,7 @@
28
28
  <body>
29
29
  <div class="center-middle">
30
30
  <h1 style="font-size: 4.2em">
31
- Chrome Extension<br />
31
+ Edge Extension<br />
32
32
  <a href="#"><span id="extensionName"></span></a><br />
33
33
  ready.
34
34
  </h1>
@@ -8,9 +8,9 @@
8
8
  "type": "module"
9
9
  },
10
10
  "icons": {
11
- "16": "./public/logo.png",
12
- "48": "./public/logo.png",
13
- "128": "./public/logo.png"
11
+ "16": "images/logo.png",
12
+ "48": "images/logo.png",
13
+ "128": "images/logo.png"
14
14
  },
15
15
  "permissions": ["management", "tabs", "storage"]
16
16
  }
@@ -28,7 +28,7 @@
28
28
  <body>
29
29
  <div class="center-middle">
30
30
  <h1 style="font-size: 4.2em">
31
- Chrome Extension<br />
31
+ Mozilla Add-on<br />
32
32
  <a href="#"><span id="extensionName"></span></a><br />
33
33
  ready.
34
34
  </h1>
@@ -0,0 +1,57 @@
1
+ import {handleFirstRun} from './define-initial-tab.js'
2
+ import {connect, disconnect} from './reload-service.js'
3
+
4
+ function bgGreen(str) {
5
+ return `background: #0A0C10; color: #26FFB8; ${str}`
6
+ }
7
+
8
+ async function handleTabOnExtensionLoad() {
9
+ console.log(
10
+ `%c
11
+ ██████████████████████████████████████████████████████████
12
+ ██████████████████████████████████████████████████████████
13
+ ████████████████████████████ ██████████████████████████
14
+ █████████████████████████ ██████ ███████████████
15
+ ███████████████████████ ███ ███ ████████████
16
+ ██████████████████████ ██████ ███ ███████████
17
+ ███████████████████████ ██████ ██████ ███████████
18
+ ████████████████ ██████ ██████████████ ███████████
19
+ █████████████ ████ ████████████ ████████████
20
+ ███████████ ██ █████████████ ███████████████
21
+ ██████████ ██████ █████████████████ █████████████
22
+ ███████████ ████████████████████████████ ███████████
23
+ █████████████ █████████████████ ██████ ██████████
24
+ ███████████████ ██████████████ ██ ██████████
25
+ ████████████ ████████████ ████ █████████████
26
+ ███████████ █████████████ ██████ ███████████████
27
+ ███████████ ██████ ██████ ███████████████████████
28
+ ███████████ ████ ██████ ██████████████████████
29
+ ████████████ ██ ███ ███████████████████████
30
+ ███████████████ ██████ █████████████████████████
31
+ ██████████████████████████ ████████████████████████████
32
+ ██████████████████████████████████████████████████████████
33
+ ██████████████████████████████████████████████████████████
34
+ MIT (c) ${new Date().getFullYear()} - Cezar Augusto and the Extension.js Authors.
35
+ `,
36
+ bgGreen('')
37
+ )
38
+
39
+ try {
40
+ await handleFirstRun()
41
+ } catch (error) {
42
+ console.error('Error handling tabs on extension load:', error)
43
+ }
44
+ }
45
+
46
+ browser.runtime.onInstalled.addListener(async () => {
47
+ await handleTabOnExtensionLoad()
48
+
49
+ let isConnected = false
50
+
51
+ if (isConnected) {
52
+ disconnect()
53
+ } else {
54
+ await connect()
55
+ isConnected = true
56
+ }
57
+ })
@@ -0,0 +1,62 @@
1
+ async function getDevExtension() {
2
+ const allExtensions = await browser.management.getAll()
3
+
4
+ return allExtensions.filter((extension) => {
5
+ return (
6
+ // Reload extension
7
+ extension.name !== 'Extension Manager' &&
8
+ // Show only unpackaged extensions
9
+ extension.installType === 'development'
10
+ )
11
+ })[0]
12
+ }
13
+
14
+ // Create a new tab and set it to background.
15
+ export async function createFirefoxAddonsTab(initialTab, url) {
16
+ try {
17
+ // Check if an about:blank tab is already open
18
+ const tabs = await browser.tabs.query({url: 'about:blank'})
19
+ const addonsTabExist = tabs.length > 0
20
+
21
+ // Return if url exists, meaning about:blank tab is already open
22
+ if (addonsTabExist) return
23
+
24
+ // Create an inactive about:blank tab
25
+ const addonsTab = await browser.tabs.create({url, active: false})
26
+
27
+ // Get the initial page tab and move the new addons tab to the first position.
28
+ // This will auto-activate the initial page tab because we set the addons tab to inactive
29
+ await browser.tabs.move(addonsTab.id, {index: 0})
30
+
31
+ // Reactivate the user-selected initial page tab
32
+ await browser.tabs.update(initialTab.id, {active: true})
33
+ } catch (error) {
34
+ console.error('Error creating and manipulating tabs:', error)
35
+ }
36
+ }
37
+
38
+ // Function to handle first run logic
39
+ export async function handleFirstRun() {
40
+ try {
41
+ const devExtension = await getDevExtension()
42
+
43
+ if (!devExtension) {
44
+ console.warn('No development extensions found')
45
+ return
46
+ }
47
+
48
+ const result = await browser.storage.local.get(devExtension.id)
49
+
50
+ if (result[devExtension.id] && result[devExtension.id].didRun) {
51
+ return
52
+ }
53
+
54
+ // Open the welcome page
55
+ await browser.tabs.create({url: './pages/welcome.html'})
56
+
57
+ // Ensure the welcome page shows only once per extension installation
58
+ await browser.storage.local.set({[devExtension.id]: {didRun: true}})
59
+ } catch (error) {
60
+ console.error('Error handling tabs on extension load:', error)
61
+ }
62
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "Extension Manager",
3
+ "description": "Extension.js developer tools for tabs and reload management.",
4
+ "version": "1.0",
5
+ "manifest_version": 2,
6
+ "background": {
7
+ "scripts": ["background.js"],
8
+ "type": "module"
9
+ },
10
+ "icons": {
11
+ "16": "images/logo.png",
12
+ "48": "images/logo.png",
13
+ "128": "images/logo.png"
14
+ },
15
+ "permissions": ["management", "tabs", "storage"]
16
+ }
@@ -0,0 +1,268 @@
1
+ /* $color-text: #dedce5; */
2
+ /* Sakura.css v1.5.0
3
+ * ================
4
+ * Minimal css theme.
5
+ * Project: https://github.com/oxalorg/sakura/
6
+ */
7
+ /* Body */
8
+ html {
9
+ font-size: 62.5%;
10
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
11
+ 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
12
+ }
13
+
14
+ body {
15
+ font-size: 1.8rem;
16
+ line-height: 1.618;
17
+ max-width: 38em;
18
+ margin: auto;
19
+ color: #c9c9c9;
20
+ background-color: #222222;
21
+ padding: 13px;
22
+ }
23
+
24
+ @media (max-width: 684px) {
25
+ body {
26
+ font-size: 1.53rem;
27
+ }
28
+ }
29
+ @media (max-width: 382px) {
30
+ body {
31
+ font-size: 1.35rem;
32
+ }
33
+ }
34
+ h1,
35
+ h2,
36
+ h3,
37
+ h4,
38
+ h5,
39
+ h6 {
40
+ line-height: 1.1;
41
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
42
+ 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
43
+ font-weight: 700;
44
+ margin-top: 3rem;
45
+ margin-bottom: 1.5rem;
46
+ overflow-wrap: break-word;
47
+ word-wrap: break-word;
48
+ -ms-word-break: break-all;
49
+ word-break: break-word;
50
+ }
51
+
52
+ h1 {
53
+ font-size: 2.35em;
54
+ }
55
+
56
+ h2 {
57
+ font-size: 2em;
58
+ }
59
+
60
+ h3 {
61
+ font-size: 1.75em;
62
+ }
63
+
64
+ h4 {
65
+ font-size: 1.5em;
66
+ }
67
+
68
+ h5 {
69
+ font-size: 1.25em;
70
+ }
71
+
72
+ h6 {
73
+ font-size: 1em;
74
+ }
75
+
76
+ p {
77
+ margin-top: 0px;
78
+ margin-bottom: 2.5rem;
79
+ }
80
+
81
+ small,
82
+ sub,
83
+ sup {
84
+ font-size: 75%;
85
+ }
86
+
87
+ hr {
88
+ border-color: #ffffff;
89
+ }
90
+
91
+ a {
92
+ text-decoration: none;
93
+ color: #ffffff;
94
+ }
95
+ a:visited {
96
+ color: #e6e6e6;
97
+ }
98
+ a:hover {
99
+ color: #c9c9c9;
100
+ border-bottom: 2px solid #c9c9c9;
101
+ }
102
+
103
+ ul {
104
+ padding-left: 1.4em;
105
+ margin-top: 0px;
106
+ margin-bottom: 2.5rem;
107
+ }
108
+
109
+ li {
110
+ margin-bottom: 0.4em;
111
+ }
112
+
113
+ blockquote {
114
+ margin-left: 0px;
115
+ margin-right: 0px;
116
+ padding-left: 1em;
117
+ padding-top: 0.8em;
118
+ padding-bottom: 0.8em;
119
+ padding-right: 0.8em;
120
+ border-left: 5px solid #ffffff;
121
+ margin-bottom: 2.5rem;
122
+ background-color: #4a4a4a;
123
+ }
124
+
125
+ blockquote p {
126
+ margin-bottom: 0;
127
+ }
128
+
129
+ img,
130
+ video {
131
+ height: auto;
132
+ max-width: 100%;
133
+ margin-top: 0px;
134
+ margin-bottom: 2.5rem;
135
+ }
136
+
137
+ /* Pre and Code */
138
+ pre {
139
+ background-color: #4a4a4a;
140
+ display: block;
141
+ padding: 1em;
142
+ overflow-x: auto;
143
+ margin-top: 0px;
144
+ margin-bottom: 2.5rem;
145
+ font-size: 0.9em;
146
+ }
147
+
148
+ code,
149
+ kbd,
150
+ samp {
151
+ font-size: 0.9em;
152
+ padding: 0 0.5em;
153
+ background-color: #4a4a4a;
154
+ white-space: pre-wrap;
155
+ }
156
+
157
+ pre > code {
158
+ padding: 0;
159
+ background-color: transparent;
160
+ white-space: pre;
161
+ font-size: 1em;
162
+ }
163
+
164
+ /* Tables */
165
+ table {
166
+ text-align: justify;
167
+ width: 100%;
168
+ border-collapse: collapse;
169
+ margin-bottom: 2rem;
170
+ }
171
+
172
+ td,
173
+ th {
174
+ padding: 0.5em;
175
+ border-bottom: 1px solid #4a4a4a;
176
+ }
177
+
178
+ /* Buttons, forms and input */
179
+ input,
180
+ textarea {
181
+ border: 1px solid #c9c9c9;
182
+ }
183
+ input:focus,
184
+ textarea:focus {
185
+ border: 1px solid #ffffff;
186
+ }
187
+
188
+ textarea {
189
+ width: 100%;
190
+ }
191
+
192
+ .button,
193
+ button,
194
+ input[type='submit'],
195
+ input[type='reset'],
196
+ input[type='button'],
197
+ input[type='file']::file-selector-button {
198
+ display: inline-block;
199
+ padding: 5px 10px;
200
+ text-align: center;
201
+ text-decoration: none;
202
+ white-space: nowrap;
203
+ background-color: #ffffff;
204
+ color: #222222;
205
+ border-radius: 1px;
206
+ border: 1px solid #ffffff;
207
+ cursor: pointer;
208
+ box-sizing: border-box;
209
+ }
210
+ .button[disabled],
211
+ button[disabled],
212
+ input[type='submit'][disabled],
213
+ input[type='reset'][disabled],
214
+ input[type='button'][disabled],
215
+ input[type='file']::file-selector-button[disabled] {
216
+ cursor: default;
217
+ opacity: 0.5;
218
+ }
219
+ .button:hover,
220
+ button:hover,
221
+ input[type='submit']:hover,
222
+ input[type='reset']:hover,
223
+ input[type='button']:hover,
224
+ input[type='file']::file-selector-button:hover {
225
+ background-color: #c9c9c9;
226
+ color: #222222;
227
+ outline: 0;
228
+ }
229
+ .button:focus-visible,
230
+ button:focus-visible,
231
+ input[type='submit']:focus-visible,
232
+ input[type='reset']:focus-visible,
233
+ input[type='button']:focus-visible,
234
+ input[type='file']::file-selector-button:focus-visible {
235
+ outline-style: solid;
236
+ outline-width: 2px;
237
+ }
238
+
239
+ textarea,
240
+ select,
241
+ input {
242
+ color: #c9c9c9;
243
+ padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
244
+ margin-bottom: 10px;
245
+ background-color: #4a4a4a;
246
+ border: 1px solid #4a4a4a;
247
+ border-radius: 4px;
248
+ box-shadow: none;
249
+ box-sizing: border-box;
250
+ }
251
+ textarea:focus,
252
+ select:focus,
253
+ input:focus {
254
+ border: 1px solid #ffffff;
255
+ outline: 0;
256
+ }
257
+
258
+ input[type='checkbox']:focus {
259
+ outline: 1px dotted #ffffff;
260
+ }
261
+
262
+ label,
263
+ legend,
264
+ fieldset {
265
+ display: block;
266
+ margin-bottom: 0.5rem;
267
+ font-weight: 600;
268
+ }