mirror of
https://github.com/SolninjaA/Chhoto-URL-Extension.git
synced 2025-02-27 10:19:33 +10:00
Convert extension to manifest v3. Still under testing
This commit is contained in:
parent
9aef574167
commit
35120f752a
4
lib/browser-polyfill.min.js
vendored
4
lib/browser-polyfill.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"manifest_version": 3,
|
||||
"name": "Chhoto URL",
|
||||
"version": "1.3.1",
|
||||
"description": "An unofficial extension for shortening URLs using the Chhoto URL API. Requires a Chhoto URL instance.",
|
||||
@ -16,13 +16,16 @@
|
||||
"notifications",
|
||||
"clipboardWrite",
|
||||
"storage",
|
||||
"https://*/*",
|
||||
"contextMenus"
|
||||
"contextMenus",
|
||||
"offscreen"
|
||||
],
|
||||
"host_permissions": [
|
||||
"https://*/*"
|
||||
],
|
||||
"options_ui": {
|
||||
"page": "options/options.html"
|
||||
},
|
||||
"browser_action": {
|
||||
"action": {
|
||||
"default_icon": {
|
||||
"16": "icons/chhoto-url-16.png",
|
||||
"48": "icons/chhoto-url-48.png",
|
||||
@ -34,9 +37,13 @@
|
||||
"default_title": "Generate a Chhoto URL!"
|
||||
},
|
||||
"background": {
|
||||
"scripts": [
|
||||
"lib/browser-polyfill.min.js",
|
||||
"background/background.js"
|
||||
]
|
||||
"service_worker": "service_worker.js",
|
||||
"type": "module",
|
||||
"scripts": ["lib/browser-polyfill.min.js", "service_worker.js"]
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "{49edc8ea-f91d-4510-8710-e0e807ad5842}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
3
offscreen/offscreen.html
Normal file
3
offscreen/offscreen.html
Normal file
@ -0,0 +1,3 @@
|
||||
<!doctype html>
|
||||
<textarea id="text"></textarea>
|
||||
<script src="offscreen.js"></script>
|
87
offscreen/offscreen.js
Normal file
87
offscreen/offscreen.js
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* COPYRIGHT NOTICE
|
||||
* THIS FILE WAS INSPIRED FROM: https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/functional-samples/cookbook.offscreen-clipboard-write
|
||||
* THE BASE CODE IS LICENSED UNDER THE APACHE 2 LICENSE
|
||||
* (https://www.apache.org/licenses/LICENSE-2.0)
|
||||
*/
|
||||
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* COPYRIGHT NOTICE
|
||||
* ALL PERSONAL **MODIFICATIONS** ARE LICENSED UNDER THE GNU GENEARL PUBLIC LICENSE VERSION 3
|
||||
* YOU MAY FIND THIS LICENSE IN THE "LICENSE.md" FILE.
|
||||
* IF NOT, SEE https://www.gnu.org/licenses
|
||||
* */
|
||||
|
||||
/*
|
||||
* An unofficial extension for easy link shortening using the Chhoto URL API.
|
||||
* Copyright (C) 2025 Solomon Tech
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Get element
|
||||
const textEle = document.querySelector("#text");
|
||||
|
||||
// Function which actually copies the link
|
||||
async function copy(link) {
|
||||
try {
|
||||
// If the link is not a string
|
||||
if (typeof link !== 'string') {
|
||||
// Return an error
|
||||
throw new TypeError(`The shortened URL's type must be a 'string', not "${typeof link}"`);
|
||||
}
|
||||
|
||||
// Set the value of the text element
|
||||
textEle.value = link;
|
||||
|
||||
// Select the element
|
||||
textEle.select();
|
||||
|
||||
// Copy to the clipboard
|
||||
document.execCommand('copy');
|
||||
} finally {
|
||||
// Close the offscreen document
|
||||
window.close();
|
||||
}
|
||||
};
|
||||
|
||||
// Ensures the message was meant for this message handler
|
||||
async function handleMessages(message) {
|
||||
// Only activate if the received message was intended for the offscreen handler
|
||||
if (message.type === 'clipboard') {
|
||||
// Call the copy function and pass the link
|
||||
copy(message.link);
|
||||
} else {
|
||||
// Return, if the message wasn't intended for the offscreen handler
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
// Listen for runtime messages
|
||||
chrome.runtime.onMessage.addListener(handleMessages);
|
@ -52,7 +52,9 @@ const requestParams = new URLSearchParams(window.location.search);
|
||||
const requestValue = requestParams.get('url');
|
||||
|
||||
// Get the background page, and call the sendRequest function (which is in this script)
|
||||
const backgroundFunc = browser.runtime.getBackgroundPage();
|
||||
if (typeof chrome === undefined) {
|
||||
const backgroundFunc = browser.runtime.getBackgroundPage();
|
||||
};
|
||||
|
||||
/**
|
||||
* Functions
|
||||
@ -136,7 +138,12 @@ function deleteLink(host, link) {
|
||||
deleteErrorEle.classList.remove("warning");
|
||||
|
||||
// Send request to function which handles requests to the background page
|
||||
if (typeof chrome !== undefined) {
|
||||
browser.runtime.sendMessage({type: "generate-via-popup", longurl: longurl, shorturl: shorturl});
|
||||
} else {
|
||||
backgroundFunc.then(sendRequest, onError);
|
||||
};
|
||||
|
||||
} else if (result.json.error) {
|
||||
// Set error message
|
||||
deleteErrorMessageEle.innerText = `Error (${result.status}): ${result.json.reason}`;
|
||||
@ -224,7 +231,12 @@ generateEle.addEventListener("submit", (event) => {
|
||||
message3Ele.classList.remove("warning");
|
||||
|
||||
// Send request to function which handles requests to the background page
|
||||
if (typeof chrome !== undefined) {
|
||||
browser.runtime.sendMessage({type: "generate-via-popup", longurl: longurl, shorturl: shorturl});
|
||||
} else {
|
||||
backgroundFunc.then(sendRequest, onError);
|
||||
};
|
||||
|
||||
} else {
|
||||
// Add the warning class
|
||||
message3Ele.classList.add("warning");
|
||||
|
@ -28,6 +28,25 @@
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
|
||||
"use strict";
|
||||
|
||||
// Import polyfill
|
||||
import "/lib/browser-polyfill.min.js";
|
||||
|
||||
// Create a context menu
|
||||
browser.runtime.onInstalled.addListener(() => {
|
||||
browser.contextMenus.create({
|
||||
title: "Manually generate a Chhoto URL",
|
||||
contexts: ["all"],
|
||||
id: "generate-chhoto-url"
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Run code when the context menu is clicked
|
||||
browser.contextMenus.onClicked.addListener( (info) => {
|
||||
browser.windows.create({url: `/popup/popup.html?url=${info.pageUrl}`, type: "popup"});
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* Type Definitions
|
||||
*/
|
||||
@ -81,6 +100,12 @@
|
||||
* @returns {!Promise<[URL, string, string], Error>}
|
||||
*/
|
||||
function validateURL(url, title, type) {
|
||||
// Define a new URL object, in case the url was collected from a runtime message
|
||||
// In which case, the URL object wouldn't be preserved
|
||||
if (type === "popup") {
|
||||
url = new URL(url);
|
||||
}
|
||||
|
||||
return browser.storage.local.get("allowedProtocols").then(({ allowedProtocols }) => {
|
||||
// Initialize a list of protocols that are allowed if unset.
|
||||
// This needs to be synced with the initialization code in options.js.
|
||||
@ -269,23 +294,25 @@ function validateChhotoResponse(httpResp) {
|
||||
* @returns {!Promise<ChhotoJSON, Error>} `ChhotoJSON`, unmodified, on
|
||||
* success, or an error indicating that we failed to copy to the clipboard.
|
||||
*/
|
||||
function copyLinkToClipboard(chhotoResp) {
|
||||
async function copyLinkToClipboard(chhotoResp) {
|
||||
// Send finished message
|
||||
browser.runtime.sendMessage({message: "finished"});
|
||||
|
||||
// Chrome requires this hacky workaround :(
|
||||
if (typeof chrome !== "undefined") {
|
||||
const prevSelected = document.activeElement;
|
||||
const tempEle = document.createElement("input");
|
||||
document.body.appendChild(tempEle);
|
||||
tempEle.value = chhotoResp.shorturl;
|
||||
tempEle.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(tempEle);
|
||||
// Depending on what was previously selected, we might not be able to select the text.
|
||||
if (prevSelected?.select) {
|
||||
prevSelected.select();
|
||||
}
|
||||
// Currently the "getBrowserInfo" function is only available on Firefox browsers
|
||||
// So, we can partially detect the type of the browser
|
||||
// This check may change in the future
|
||||
if (typeof browser.runtime.getBrowserInfo !== "function") {
|
||||
// Create an offscreen document
|
||||
await browser.offscreen.createDocument({
|
||||
url: "/offscreen/offscreen.html",
|
||||
reasons: [chrome.offscreen.Reason.CLIPBOARD],
|
||||
justification: "Copy the shortened URL to the clipboard"
|
||||
});
|
||||
|
||||
// Send a runtime message to the offscreen page
|
||||
browser.runtime.sendMessage({type: "clipboard", link: chhotoResp.shorturl});
|
||||
|
||||
return Promise.resolve(chhotoResp);
|
||||
} else {
|
||||
return navigator.clipboard
|
||||
@ -360,17 +387,27 @@ function popupGenerateChhoto(url, title) {
|
||||
.catch(notifyError);
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to handle messages
|
||||
* */
|
||||
async function handleMessages(message) {
|
||||
// Only activate if the messge was intended for the background page
|
||||
if (message.type === "generate-via-popup") {
|
||||
if (typeof message.longurl !== 'string' && typeof message.shorturl !== 'string') {
|
||||
throw new TypeError(`The long URL and short URL's type must be a 'string', got "${typeof message.longurl}" and "${typeof message.shorturl} respectively."`)
|
||||
};
|
||||
|
||||
// Generate
|
||||
console.log(message.longurl);
|
||||
popupGenerateChhoto(message.longurl, message.shorturl);
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// When the extension icon is clicked, call the function above
|
||||
browser.browserAction.onClicked.addListener(generateChhoto);
|
||||
browser.action.onClicked.addListener(generateChhoto);
|
||||
|
||||
// Create a context menu
|
||||
browser.contextMenus.removeAll();
|
||||
browser.contextMenus.create({
|
||||
title: "Manually generate a Chhoto URL",
|
||||
contexts: ["all"]
|
||||
});
|
||||
|
||||
// Run code when the context menu is clicked
|
||||
browser.contextMenus.onClicked.addListener( (info) => {
|
||||
browser.windows.create({url: `/popup/popup.html?url=${info.pageUrl}`, type: "popup"});
|
||||
});
|
||||
// When a message is sent
|
||||
browser.runtime.onMessage.addListener(handleMessages);
|
Loading…
Reference in New Issue
Block a user