mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-16 06:18:35 +02:00
Selfify example (#251)
* Selfify example for how to access files article * Restored selfify.js and updated choose_file.js as suggested by Luca * Updated comments * Updates for feedback from Will * Updates from the second round of feedback * removed activetab from manifest, removed document.body.appendChild(info);, renamed the content script (selfify > content), renamed the listener (selfify > injectImage) and moved example to imagify folder. * Correctly renamed folder and update manifest.json
This commit is contained in:
26
imagify/README.md
Normal file
26
imagify/README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# imagify
|
||||||
|
|
||||||
|
**This add-on injects JavaScript into web pages. The `addons.mozilla.org` domain disallows this operation, so this add-on will not work properly when it's run on pages in the `addons.mozilla.org` domain.**
|
||||||
|
|
||||||
|
## What it does ##
|
||||||
|
|
||||||
|
The extension includes:
|
||||||
|
|
||||||
|
* a sidebar including HTML, CSS, and JavaScript
|
||||||
|
* a content script
|
||||||
|
* a web page template, packaged as web accessible resources
|
||||||
|
|
||||||
|
When the extension loads the user is offered a file picker and drop zone as methods to choose an image file.
|
||||||
|
|
||||||
|
Once an image file has been chosen, the extension injects the content script into the active tab, and sends the content script a message containing the URL of the chosen image.
|
||||||
|
|
||||||
|
When the content script receives this message, it replaces the current page content with the chosen image file.
|
||||||
|
|
||||||
|
## What it shows ##
|
||||||
|
|
||||||
|
How to:
|
||||||
|
* write a sidebar
|
||||||
|
* implement a file picker and drag and drop zone
|
||||||
|
* give a sidebar style and behavior using CSS and JavaScript
|
||||||
|
* inject a content script programmatically using `tabs.executeScript()`
|
||||||
|
* send a message from the main extension to a content script
|
||||||
47
imagify/content_scripts/content.js
Normal file
47
imagify/content_scripts/content.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
(function() {
|
||||||
|
/*
|
||||||
|
Check and set a global guard variable.
|
||||||
|
If this content script is injected into the same page again,
|
||||||
|
it will do nothing next time.
|
||||||
|
*/
|
||||||
|
if (window.hasRun) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.hasRun = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add the image to the web page by:
|
||||||
|
* Removing every node in the document.body
|
||||||
|
* Inserting the selected image
|
||||||
|
*/
|
||||||
|
function injectImage(request, sender, sendResponse) {
|
||||||
|
removeEverything();
|
||||||
|
insertImage(request.imageURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove every node under document.body
|
||||||
|
*/
|
||||||
|
function removeEverything() {
|
||||||
|
while (document.body.firstChild) {
|
||||||
|
document.body.firstChild.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Given a URL to an image, create and style an iframe containing an
|
||||||
|
IMG node pointing to that image, then insert the node into the document.
|
||||||
|
*/
|
||||||
|
function insertImage(imageURL) {
|
||||||
|
const insertImage = document.createElement("iframe");
|
||||||
|
insertImage.setAttribute("src", browser.extension.getURL(`/viewer.html?blobURL=${imageURL}`));
|
||||||
|
insertImage.setAttribute("style", "width: 100vw; height: 100vh;");
|
||||||
|
document.body.appendChild(insertImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Assign injectImage() as a listener for messages from the extension.
|
||||||
|
*/
|
||||||
|
browser.runtime.onMessage.addListener(injectImage);
|
||||||
|
|
||||||
|
})();
|
||||||
22
imagify/manifest.json
Normal file
22
imagify/manifest.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"description": "Adds a sidebar offerin a file picker and drap and drop zone. When an image file is chosen the active tab's body content is replaced with file selected. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#imagify",
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Imagify",
|
||||||
|
"version": "1.0",
|
||||||
|
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/imagify",
|
||||||
|
|
||||||
|
"permissions": [
|
||||||
|
"tabs",
|
||||||
|
"<all_urls>"
|
||||||
|
],
|
||||||
|
|
||||||
|
"sidebar_action": {
|
||||||
|
"default_title": "Imagify",
|
||||||
|
"default_panel": "sidebar/sidebar.html"
|
||||||
|
},
|
||||||
|
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"/viewer.html"
|
||||||
|
]
|
||||||
|
}
|
||||||
63
imagify/sidebar/choose_file.js
Normal file
63
imagify/sidebar/choose_file.js
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
Listens for a file being selected, creates a ObjectURL for the chosen file, injects a
|
||||||
|
content script into the active tab then passes the image URL through a message to the
|
||||||
|
active tab ID.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Listen for a file being selected through the file picker
|
||||||
|
const inputElement = document.getElementById("input");
|
||||||
|
inputElement.addEventListener("change", handlePicked, false);
|
||||||
|
|
||||||
|
// Listen for a file being dropped into the drop zone
|
||||||
|
const dropbox = document.getElementById("drop_zone");
|
||||||
|
dropbox.addEventListener("dragenter", dragenter, false);
|
||||||
|
dropbox.addEventListener("dragover", dragover, false);
|
||||||
|
dropbox.addEventListener("drop", drop, false);
|
||||||
|
|
||||||
|
// Get the image file if it was chosen from the pick list
|
||||||
|
function handlePicked() {
|
||||||
|
displayFile(this.files);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the image file if it was dragged into the sidebar drop zone
|
||||||
|
function drop(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
displayFile(e.dataTransfer.files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Insert the content script and send the image file ObjectURL to the content script using a
|
||||||
|
message.
|
||||||
|
*/
|
||||||
|
function displayFile(fileList) {
|
||||||
|
const imageURL = window.URL.createObjectURL(fileList[0]);
|
||||||
|
|
||||||
|
browser.tabs.executeScript({
|
||||||
|
file: "/content_scripts/content.js"
|
||||||
|
}).then(messageContent)
|
||||||
|
.catch(reportError);
|
||||||
|
|
||||||
|
function messageContent() {
|
||||||
|
const gettingActiveTab = browser.tabs.query({active: true, currentWindow: true});
|
||||||
|
gettingActiveTab.then((tabs) => {
|
||||||
|
browser.tabs.sendMessage(tabs[0].id, {imageURL});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function reportError(error) {
|
||||||
|
console.error(`Could not inject content script: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the drag enter event - not used in this extension
|
||||||
|
function dragenter(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the drag over event - not used in this extension
|
||||||
|
function dragover(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
15
imagify/sidebar/sidebar.css
Normal file
15
imagify/sidebar/sidebar.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
html, body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#drop_zone {
|
||||||
|
border: 5px solid blue;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#drop_zone_label {
|
||||||
|
margin: 1em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
24
imagify/sidebar/sidebar.html
Normal file
24
imagify/sidebar/sidebar.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="sidebar.css"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="picker_zone" style="margin:20px ;color:blue">
|
||||||
|
<input type="file" accept="image/*" id="input">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="drop_zone">
|
||||||
|
<strong id="drop_zone_label">Drag an image file into this Drop Zone ...</strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="choose_file.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
8
imagify/viewer.css
Normal file
8
imagify/viewer.css
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
17
imagify/viewer.html
Normal file
17
imagify/viewer.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="viewer.css"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<img src="about:blank">
|
||||||
|
<script src="viewer.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
3
imagify/viewer.js
Normal file
3
imagify/viewer.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
const imageBlobURL = params.get("blobURL");
|
||||||
|
document.querySelector("img").setAttribute("src", imageBlobURL);
|
||||||
Reference in New Issue
Block a user