Skip to content

Commit 033c4d7

Browse files
authored
docs: write initial documentation (#21)
1 parent 465cd6d commit 033c4d7

31 files changed

+674
-3
lines changed

.github/workflows/publish_docs.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Publish xtensio docs
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- name: Configure Git Credentials
19+
run: |
20+
git config user.name github-actions[bot]
21+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
22+
23+
- uses: actions/setup-python@v5
24+
with:
25+
python-version: 3.x
26+
27+
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
28+
29+
- uses: actions/cache@v4
30+
with:
31+
key: mkdocs-material-${{ env.cache_id }}
32+
path: .cache
33+
restore-keys: |
34+
mkdocs-material-
35+
36+
- run: pip install mkdocs-material
37+
38+
- run: mkdocs gh-deploy --force

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
.build
22
node_modules
33
yarn-error.log
4-
.DS_Store
4+
.DS_Store
5+
.vscode
6+
**/xtensio-docs/site
7+
.env
8+
*.env

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"build": "yarn workspaces run build",
1010
"push": "yarn workspaces run push",
1111
"lint": "yarn workspaces run lint",
12-
"lint:fix": "yarn workspaces run lint:fix"
12+
"lint:fix": "yarn workspaces run lint:fix",
13+
"docs:serve": "yarn workspace xtensio-docs run serve"
1314
},
1415
"workspaces": [
1516
"packages/*"
@@ -18,4 +19,4 @@
1819
"devDependencies": {
1920
"husky": "^8.0.3"
2021
}
21-
}
22+
}

packages/xtensio-docs/Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FROM squidfunk/mkdocs-material
2+
RUN pip install mkdocs-git-committers-plugin-2
Loading
Loading
Loading
Loading
Loading
116 KB
Loading
27.8 KB
Loading
153 KB
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
hide:
3+
- footer
4+
---
5+
6+
<h1 align="center">
7+
<img style="margin: 50px 0px" width="400px" src="https://raw.githubusercontent.com/doc-han/xtensio/master/statics/xtensio.png" />
8+
</h1>
9+
10+
## What is xtensio?
11+
12+
**xtensio** (pronounced /**ɛkˈtɛn.ʃoʊ**/, like **"ex-TEN-see-oh"**) is javascript framework for building browser extensions. It leverages [React.js](https://reactjs.org) to provide a well-organized folder structure that supports a declarative approach, simplifying and accelerating extension development.
13+
14+
## How does it work?
15+
16+
**xtensio** provides you with a folder structure that comes with configurations already baked in. Hence, no configuration is needed to get started with your new extension project. Currently, it mainly supports React for development.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
To change icons for your extension. You just need to have them in the `public` directory and then import them into your `manifest.js` file.
2+
3+
> How to import extension icons of several dimensions
4+
5+
```ts title="manifest.js" linenums="1" hl_lines="2 3 4 5 11 12 13 14 15 16"
6+
import packageJson from "./package.json";
7+
import icon16 from "@public/icons/icon16.png";
8+
import icon32 from "@public/icons/icon32.png";
9+
import icon48 from "@public/icons/icon48.png";
10+
import icon128 from "@public/icons/icon128.png";
11+
12+
export default {
13+
name: "simple-extension", // extension name
14+
manifest_version: 3,
15+
version: packageJson.version,
16+
icons: {
17+
16: icon16,
18+
32: icon32,
19+
48: icon48,
20+
128: icon128,
21+
},
22+
};
23+
```
24+
25+
And that's it! your extension icons have been updated.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
The extension popup is the small UI that shows up when you click an extension icon. [see what it looks like](#popup_image)
2+
3+
Inside the popup folder is a file :material-language-javascript: `popup.jsx` (or :material-language-typescript: `popup.tsx` depending on what you're using) which exports a React component. This is the single entry point for your extension popup.
4+
5+
=== ":material-language-typescript: Javascript"
6+
7+
```js title="/popup/popup.jsx" linenums="1"
8+
const PopupPage = () => {
9+
return <div>This is the extension popup</div>;
10+
};
11+
12+
export default PopupPage;
13+
```
14+
15+
=== ":material-language-typescript: Typescript"
16+
17+
```ts title="/popup/popup.tsx" linenums="1"
18+
const PopupPage: React.FC = () => {
19+
return <div>This is the extension popup</div>;
20+
};
21+
22+
export default PopupPage;
23+
```
24+
25+
There's no limit to what you can do here. you can import other components and do awesome stuff.
26+
27+
## What does it look like?
28+
29+
like this!
30+
31+
<figure markdown="span" id="popup_image">
32+
![A browser extension popup](/assets/extension-popup-image.png){ width="80%" }
33+
<figcaption>A browser extension popup</figcaption>
34+
</figure>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
## What are Extension Pages?
2+
3+
Think of extension pages as webpages that are hosted by your extension. Hence, these pages are only available once a user has your extension installed.
4+
5+
## What are they for?
6+
7+
Extension Pages can be used to create configuration or settings pages, Terms of Service pages, and similar things you'll like to dedicate a page for.
8+
9+
## How to create an Extension Page
10+
11+
1. Create a `.jsx` or `.tsx` file in the `pages` directory.
12+
2. Write a React component
13+
3. Export this component as the default export
14+
15+
> An example settings page
16+
17+
=== ":material-language-javascript: Javascript"
18+
19+
```ts title="/pages/settings.jsx" linenums="1" hl_lines="18"
20+
import { useState } from "react"
21+
22+
const SettingsPage = () => {
23+
const [theme, setTheme] = useState("light");
24+
25+
const themeChangeHandler = (e)=> {
26+
setTheme(e.target.name);
27+
}
28+
29+
return <>
30+
<div>Select theme:</div>
31+
<input value={theme} type="radio" name="light" onChange={themeChangeHandler} />
32+
<input value={theme} type="radio" name="dark" onChange={themeChangeHandler} />
33+
</>
34+
};
35+
36+
// default export a react component to have a page
37+
export default SettingsPage;
38+
```
39+
40+
=== ":material-language-typescript: Typescript"
41+
42+
```ts title="/pages/settings.tsx" linenums="1" hl_lines="18"
43+
import { useState } from "react"
44+
45+
const SettingsPage: React.FC = () => {
46+
const [theme, setTheme] = useState("light");
47+
48+
const themeChangeHandler = (e: React.ChangeEvent<HTMLInputElement>)=> {
49+
setTheme(e.target.name);
50+
}
51+
52+
return <>
53+
<div>Select theme:</div>
54+
<input value={theme} type="radio" name="light" onChange={themeChangeHandler} />
55+
<input value={theme} type="radio" name="dark" onChange={themeChangeHandler} />
56+
</>
57+
};
58+
59+
// default export a react component to have a page
60+
export default SettingsPage;
61+
```
62+
63+
## How to navigate to an Extension Page
64+
65+
After creating an extension page, you should be able to navigate to it from anywhere in the extension. xtensio provides a utility function `visitPage` for that.
66+
67+
To visit a page, just call `visitPage` with the name of the page without the file extension.
68+
69+
> How to visit a page that was created at `/pages/settings.tsx`
70+
71+
```ts title="somewhere-in-your-extension" linenums="1"
72+
import { visitPage } from "xtensio"
73+
...
74+
visitPage("settings");
75+
...
76+
```
77+
78+
That's all you need to navigate to an Extension Page you've created in your extension.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Xtensio does support environment variables out of the box.
2+
3+
Create any of the below env files at the root of your project and keep some environment variables in them.
4+
5+
| Type | Filename | Description |
6+
| ----------- | ----------------------------- | --------------------------------------------------- |
7+
| Global | `.env` | used for **both development and production builds** |
8+
| Development | `.dev.env` `.development.env` | used for **only development** |
9+
| Production | `.prod.env` `.production.env` | used for **only production builds** |
10+
11+
Hence, you can have the development version of a variable in `.dev.env` and the production version of it in `.prod.env` and xtensio will know what to use when.
12+
13+
> Note: Development is when you run `yarn dev` or `npm run dev` and Production is when you run `yarn build` or `npm run build`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
welcome
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Inside the background folder is an `index.ts` or `index.js` file which serves as your single entry point for your extension's service worker or background script.
2+
3+
> You can freely create other files in the background directory and use them or import them into the `index.ts` file.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
This is the heart ❤️ of browser extension development where most of the real magic happens.
2+
3+
The primary goal of a browser extension is to change the user experience of website or to supercharge the browser. This could mean changing the looks or adding some functionalities to websites. This type of manipulation is handled by content files in xtensio.
4+
5+
## How to use contents in xtensio
6+
7+
Every content file has two parts.
8+
9+
| Part | What it does |
10+
| ----------------------------------------------------- | ------------------------------------------------------------------ |
11+
| [:link:**`config`**](#how-to-define-a-content-config) | Defines where & how a specific code should be executed |
12+
| [:link:**`code`**](#how-to-define-code) | Some code that is to be executed when conditions in config are met |
13+
14+
## How to define a content config
15+
16+
A content config is defined as an exported function with the name `getConfig` that returns an object.
17+
18+
> Below is an an example content config that runs only on google.com domains
19+
20+
=== ":material-language-javascript: Javascript"
21+
22+
```js title="/contents/google.jsx" linenums="1"
23+
export function getConfig() {
24+
return {
25+
matches: ["*://*.google.com/*"],
26+
};
27+
}
28+
```
29+
30+
=== ":material-language-typescript: Typescript"
31+
32+
```ts title="/contents/google.tsx" linenums="1"
33+
import { ContentConfig } from "xtensio"
34+
35+
export function getConfig(): ContentConfig {
36+
return {
37+
matches: ["*://*.google.com/*"],
38+
};
39+
}
40+
```
41+
42+
## How to define code
43+
44+
The code to be executed when a content config is matched can be any form of javascript. DOM manipulation, or any kind of web acceptable javascript/typescript.
45+
46+
> Below is an example content file that print "This is google" whenever you're on google.
47+
48+
=== ":material-language-javascript: Javascript"
49+
50+
```js title="/contents/google.jsx" linenums="1" hl_lines="7"
51+
export function getConfig() {
52+
return {
53+
matches: ["*://*.google.com/*"],
54+
};
55+
}
56+
57+
console.log("This is google")
58+
// you can have complex scripts here. even DOM manipulation
59+
```
60+
61+
=== ":material-language-typescript: Typescript"
62+
63+
```ts title="/contents/google.tsx" linenums="1" hl_lines="9"
64+
import { ContentConfig } from "xtensio"
65+
66+
export function getConfig(): ContentConfig {
67+
return {
68+
matches: ["*://*.google.com/*"],
69+
};
70+
}
71+
72+
console.log("This is google")
73+
// you can have complex scripts here. even DOM manipulation
74+
```
75+
76+
## Mounting UI into websites using React
77+
78+
With the use of [React.js](https://react.dev) you can mount React components on any website by just making the component the default export in the content file.
79+
80+
> An example content file that mounts UI into amazon.com using React
81+
82+
=== ":material-language-javascript: Javascript"
83+
84+
```js title="/contents/amazon.jsx" linenums="1" hl_lines="9 10 11 12 13 14"
85+
import { useState } from "react"
86+
87+
export function getConfig() {
88+
return {
89+
matches: ["*://*.amazon.com/*"],
90+
};
91+
}
92+
93+
const SomeComponent = () => {
94+
const [count, setCount] = useState(0);
95+
return <div onClick={()=> setCount(count+1)}>click to change {count}</div>
96+
}
97+
98+
export default SomeComponent;
99+
```
100+
101+
=== ":material-language-typescript: Typescript"
102+
103+
```ts title="/contents/amazon.tsx" linenums="1" hl_lines="10 11 12 13 14 15"
104+
import { useState } from "react"
105+
import { ContentConfig } from "xtensio"
106+
107+
export function getConfig(): ContentConfig {
108+
return {
109+
matches: ["*://*.amazon.com/*"],
110+
};
111+
}
112+
113+
const SomeComponent: React.FC = () => {
114+
const [count, setCount] = useState(0);
115+
return <div onClick={()=> setCount(count+1)}>click to change {count}</div>
116+
}
117+
118+
export default SomeComponent;
119+
```
120+
121+
You can now build awesome extensions that manipulate websites and provide tailored experiences for users ❤️.

0 commit comments

Comments
 (0)