-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import chrome extension source code to container-timing (#10)
* Add demo chrome extension Copy contents of the Chrome Extension from jdapena/container-timing-extension moving them to the main container-timing repository. * Fix paths for building chrome extension * Remove package-lock.json * chrome-extension: updated README.md Removed references to the old way to use the extension, in an independent repository.
- Loading branch information
Showing
16 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
|
||
npm-debug.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"type": "npm", | ||
"script": "build", | ||
"group": { | ||
"kind": "build", | ||
"isDefault": true | ||
}, | ||
"problemMatcher": [], | ||
"label": "npm: build (Production)", | ||
"detail": "node ./build.mjs --production" | ||
}, | ||
{ | ||
"type": "npm", | ||
"script": "build:container-timing-polyfill", | ||
"group": { | ||
"kind": "build", | ||
"isDefault": "container-timing/**" | ||
}, | ||
"problemMatcher": [], | ||
"label": "npm: build container timing polyfill", | ||
"detail": "npm build:container-timing-polyfill" | ||
}, | ||
{ | ||
"type": "npm", | ||
"script": "watch", | ||
"group": { | ||
"kind": "build", | ||
"isDefault": false | ||
}, | ||
"problemMatcher": [], | ||
"label": "npm: watch", | ||
"detail": "node ./build.mjs --watch" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# <img src="public/icons/icon_48.png" width="45" align="left"> Container Timing | ||
|
||
Chrome extension that sets the attribute `containertiming` to the HTML node of | ||
the loaded documents, and registers an observer that dumps the `container` entries | ||
to `console.log`. | ||
|
||
|
||
## Prerequisites | ||
|
||
You will need a version of node.js on you machine, preferably v20+. | ||
|
||
## Install | ||
|
||
The steps to setup this project are: | ||
|
||
1. `npm i` | ||
1. `npm run install-container-timing-polyfill` | ||
1. `npm run build`. | ||
1. Run Chromium with `--enable-blink-features=ContainerTiming --load-extension=PATH_TO_EXTENSION/build/ | ||
|
||
## Contribution | ||
|
||
Suggestions and pull requests are welcomed!. | ||
|
||
--- | ||
|
||
This folder was bootstrapped with [Chrome Extension CLI](https://github.com/dutiyesh/chrome-extension-cli) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import esbuild from "esbuild"; | ||
import { copy } from "esbuild-plugin-copy"; | ||
const watch = process.argv[2] === "--watch"; | ||
const production = process.argv[2] === "--production"; | ||
|
||
const context = await esbuild | ||
.context({ | ||
entryPoints: ["./src/content.js", "./src/content.css"], | ||
bundle: true, | ||
outdir: "build", | ||
format: "iife", | ||
sourcemap: !production, | ||
minify: production, | ||
platform: "browser", | ||
target: "ES2022", | ||
plugins: [ | ||
copy({ | ||
resolveFrom: 'cwd', | ||
assets: [{ | ||
from: ["./public/**/*"], | ||
to: ["./build"] | ||
}, { | ||
from: ["../polyfill/polyfill.js"], | ||
to: ["./build"] | ||
}, | ||
{ | ||
from: ["./src/setVars.js"], | ||
to: ["./build"] | ||
} | ||
], | ||
watch | ||
|
||
}) | ||
] | ||
}) | ||
.catch((e) => { | ||
console.error(e); | ||
process.exit(1); | ||
}); | ||
|
||
if (watch) { | ||
await context.watch(); | ||
} else { | ||
context.rebuild(); | ||
context.dispose(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "container-timing", | ||
"version": "0.1.0", | ||
"description": "My Chrome Extension", | ||
"private": true, | ||
"scripts": { | ||
"watch": "node ./build.mjs --watch", | ||
"build": "npm run build:container-timing-polyfill && node ./build.mjs --production", | ||
"build:container-timing-polyfill": "npm run build --prefix ../polyfill", | ||
"install-container-timing-polyfill": "npm i --prefix ../polyfill" | ||
}, | ||
"devDependencies": { | ||
"esbuild": "^0.24.0", | ||
"esbuild-plugin-copy": "^2.1.1" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"manifest_version": 3, | ||
"name": "Container Timing demo", | ||
"$schema": "https://json.schemastore.org/chrome-manifest.json", | ||
"version": "0.1.0", | ||
"description": "Use Container Timing to provide hints of when first paints happen in a specific web page subtree", | ||
"icons": { | ||
"16": "icons/icon_16.png", | ||
"32": "icons/icon_32.png", | ||
"48": "icons/icon_48.png", | ||
"128": "icons/icon_128.png" | ||
}, | ||
"permissions": [ | ||
"storage" | ||
], | ||
"options_page": "options.html", | ||
"content_scripts": [ | ||
{ | ||
"matches": [ | ||
"*://*/*" | ||
], | ||
"css": [ | ||
"content.css" | ||
], | ||
"js": [ | ||
"setVars.js", | ||
"polyfill.js", | ||
"content.js" | ||
], | ||
"run_at": "document_start", | ||
"all_frames": true | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Container Timing: Options</title> | ||
</head> | ||
<body> | ||
<label> | ||
<input type="text" id="selector" /> | ||
selector (defaults to html) | ||
</label> | ||
|
||
<div id="status"></div> | ||
<button id="save">Save</button> | ||
|
||
<script src="options.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Saves options to chrome.storage | ||
const saveOptions = () => { | ||
const selector = document.getElementById('selector').value ?? 'html'; | ||
console.log(selector); | ||
|
||
chrome.storage.sync.set( | ||
{ selector }, | ||
() => { | ||
// Update status to let user know options were saved. | ||
const status = document.getElementById('status'); | ||
status.textContent = 'Options saved.'; | ||
setTimeout(() => { | ||
status.textContent = ''; | ||
}, 1000); | ||
} | ||
); | ||
}; | ||
|
||
// Restores select box and checkbox state using the preferences | ||
// stored in chrome.storage. | ||
const restoreOptions = () => { | ||
chrome.storage.sync.get( | ||
{selector: 'html'}, | ||
(items) => { | ||
console.log(items); | ||
// When selector hasn't been set it's not false or empty, but just an empty object (I don't know why) | ||
document.getElementById('selector').value = items.selector; | ||
} | ||
); | ||
}; | ||
|
||
document.addEventListener('DOMContentLoaded', restoreOptions); | ||
document.getElementById('save').addEventListener('click', saveOptions); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Welcome to your Chrome Extension | ||
|
||
## What's in this directory | ||
* `public/`: HTML files for the override page. | ||
* `manifest.json`: Extension [configuration](https://developer.chrome.com/docs/extensions/mv2/manifest/). | ||
* `src/`: Source files for the override page. See [chrome docs](https://developer.chrome.com/docs/extensions/mv3/override/#manifest) for more details. | ||
* `.gitignore`: Lists files to be ignored in your Git repo. | ||
* `package.json`: Contains project configuration, scripts, and dependencies. | ||
|
||
## Test the extension | ||
1. `npm run watch` | ||
2. Open [chrome://extensions](chrome://extensions). | ||
3. Enable developer mode (top right of page). | ||
4. Click "Load unpacked extension" (top left page). | ||
5. Select this directory. | ||
|
||
## Bundle the extension | ||
To package the source code into static files for the Chrome webstore, execute `npm run build`. | ||
|
||
## Documentation | ||
Refer to [the Chrome developer documentation](https://developer.chrome.com/docs/extensions/mv3/getstarted/) to get started. | ||
|
||
## VSCode developer tools | ||
Refer to [github.com/gadhagod/vscode-chrome-extension-developer-tools/blob/master/README.md#commands](https://github.com/gadhagod/vscode-chrome-extension-developer-tools/blob/master/README.md#commands). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.overlay { | ||
position:absolute; | ||
background-color: #0000FF64; | ||
} | ||
|
||
.boundingRect { | ||
position: absolute; | ||
border: 3px dashed #ff0000a8; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Don't re-run operation after selector has been seen | ||
let flag = false; | ||
// Default selector | ||
let selector = 'html'; | ||
// Container Timing element we've found | ||
let elm; | ||
|
||
// Pull the selector out of the settings | ||
chrome.storage.sync.get( | ||
{ selector: 'html' }, | ||
(items) => { | ||
selector = items.selector || 'html'; | ||
} | ||
); | ||
|
||
|
||
const observer = new MutationObserver(() => { | ||
if ((elm = document.querySelector(selector)) && !flag) { | ||
startPerformanceObserve(elm) | ||
} | ||
}); | ||
|
||
observer.observe(document.documentElement, { attributes: false, childList: true, characterData: false, subtree: true }); | ||
|
||
function startPerformanceObserve(elm) { | ||
const href = document.location.href | ||
const nativeObserver = new PerformanceObserver((list) => { | ||
console.log("Container timing entries from " + href) | ||
list.getEntries().forEach((list) => { | ||
clearRects(); | ||
showRectsOnScreen(list.damagedRects); | ||
showBoundingRect(list.intersectionRect); | ||
clearRects(true) | ||
}) | ||
// Now hide the rects so they're not in the way | ||
|
||
}); | ||
nativeObserver.observe({ type: "container", buffered: true }); | ||
console.debug("Registered observer for " + href) | ||
|
||
elm.setAttribute("containertiming", "") | ||
console.debug("Added containertiming attribute") | ||
flag = true; | ||
} | ||
|
||
function showRectsOnScreen(rects) { | ||
// TODO We may want to batch these DOM updates | ||
rects.forEach((rect) => { | ||
const div = document.createElement('div'); | ||
div.classList.add('overlay'); | ||
div.style.left = `${rect.left}px`; | ||
div.style.top = `${rect.top}px`; | ||
div.style.width = `${rect.width}px`; | ||
div.style.height = `${rect.height}px`; | ||
document.body.appendChild(div); | ||
}); | ||
} | ||
|
||
function showBoundingRect(rect) { | ||
const div = document.createElement('div'); | ||
div.classList.add('boundingRect'); | ||
div.style.left = `${rect.left}px`; | ||
div.style.top = `${rect.top}px`; | ||
div.style.width = `${rect.width}px`; | ||
div.style.height = `${rect.height}px`; | ||
document.body.appendChild(div); | ||
} | ||
|
||
function clearRects(withDelay = false) { | ||
if (withDelay) { | ||
return setTimeout(() => { | ||
document.querySelectorAll('.overlay').forEach(elm => elm.remove()); | ||
document.querySelectorAll('.boundingRect').forEach(elm => elm.remove()); | ||
}, 5000); | ||
} | ||
|
||
document.querySelectorAll('.overlay').forEach(elm => elm.remove()); | ||
document.querySelectorAll('.boundingRect').forEach(elm => elm.remove()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
window.ctDebug = true; |