From 674537ec13f543b6532ad02994396fa22f6bb6eb Mon Sep 17 00:00:00 2001 From: John Rogers Date: Tue, 3 Sep 2024 17:46:35 +0100 Subject: [PATCH 1/5] fixed linting errors --- src/components/App.js | 4 +--- src/components/Upload.js | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/components/App.js b/src/components/App.js index 2afe226..f4da970 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -35,10 +35,8 @@ import MakeMeJSON from "./MakeMeJSON.js"; import "react-toastify/dist/ReactToastify.css"; import YouTube from "react-youtube"; import "../css/youtube.css"; -import { useHistory } from "react-router-dom"; function App() { - const history = useHistory(); const [fullscreen, setFullscreen] = useState(false); const [existingInstruments, setExistingInstruments] = useState([]); const [apiData, setApiData] = useState({}); @@ -154,7 +152,7 @@ function App() { setApiData(simpleApi); }); }, - [history, fileInfos] + [match, fileInfos] ); useEffect(() => { diff --git a/src/components/Upload.js b/src/components/Upload.js index ab55f98..ea42b74 100644 --- a/src/components/Upload.js +++ b/src/components/Upload.js @@ -35,11 +35,9 @@ import { import { useHistory } from "react-router-dom"; import InlineFeedback from "./InlineFeedback"; import ExistingInstruments from "./ExistingInstruments"; -import { simplifyApi } from "../utilities/simplifyApi"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import pdfTableExtractor from "../utilities/pdf-table-extractor"; -import { useAuth } from "../contexts/AuthContext"; import { Base64 } from "js-base64"; export default function Upload({ @@ -49,7 +47,6 @@ export default function Upload({ existingInstruments, ReactGA, }) { - const { currentUser } = useAuth(); const [loading, setLoading] = useState(false); const [parseError, setParseError] = useState(false); const [matchError, setMatchError] = useState(false); @@ -59,7 +56,7 @@ export default function Upload({ const dirty = useRef(false); const localFileInfos = useRef(); const history = useHistory(); - const { match, parse, getSharedInstrument } = useData(); + const { parse, getSharedInstrument } = useData(); const { importId } = useParams(); ReactGA.send({ From a037269c3476fabe53deb61b6d216dbbbe8c384d Mon Sep 17 00:00:00 2001 From: John Rogers Date: Tue, 10 Dec 2024 23:29:30 +0000 Subject: [PATCH 2/5] update main to staging API --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index 82490c4..c017fb8 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -REACT_APP_API_URL=https://api.harmonydata.ac.uk +REACT_APP_API_URL=https://harmonystagingtmp.azurewebsites.net/ REACT_APP_API_EXAMPLES=$REACT_APP_API_URL/text/examples REACT_APP_API_PARSE=$REACT_APP_API_URL/text/parse REACT_APP_API_MATCH=$REACT_APP_API_URL/text/match From db5652c49f92c32e011757e943ddc6a9d9a42b0b Mon Sep 17 00:00:00 2001 From: John Rogers Date: Fri, 13 Dec 2024 22:38:18 +0000 Subject: [PATCH 3/5] revert to main API --- .env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env b/.env index c017fb8..82490c4 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -REACT_APP_API_URL=https://harmonystagingtmp.azurewebsites.net/ +REACT_APP_API_URL=https://api.harmonydata.ac.uk REACT_APP_API_EXAMPLES=$REACT_APP_API_URL/text/examples REACT_APP_API_PARSE=$REACT_APP_API_URL/text/parse REACT_APP_API_MATCH=$REACT_APP_API_URL/text/match From f0c20533d69e9c221d211d43ed3d6616b42d9d24 Mon Sep 17 00:00:00 2001 From: John Rogers Date: Fri, 31 Jan 2025 22:26:36 +0000 Subject: [PATCH 4/5] initial check in of chrome plugin --- .DS_Store | Bin 6148 -> 6148 bytes plugin/.DS_Store | Bin 0 -> 6148 bytes plugin/background.js | 169 ++++++++++++++++++ plugin/content.js | 20 +++ plugin/icons/128.png | Bin 0 -> 7762 bytes plugin/icons/16.png | Bin 0 -> 518 bytes plugin/icons/48.png | Bin 0 -> 2559 bytes plugin/icons/Thumbs.db | Bin 0 -> 7680 bytes plugin/js-base64/LICENSE.md | 27 +++ plugin/js-base64/README.md | 169 ++++++++++++++++++ plugin/js-base64/base64.d.mts | 135 +++++++++++++++ plugin/js-base64/base64.d.ts | 135 +++++++++++++++ plugin/js-base64/base64.js | 314 ++++++++++++++++++++++++++++++++++ plugin/js-base64/base64.mjs | 294 +++++++++++++++++++++++++++++++ plugin/js-base64/package.json | 43 +++++ plugin/manifest.json | 45 +++++ plugin/popup.html | 75 ++++++++ plugin/popup.js | 65 +++++++ 18 files changed, 1491 insertions(+) create mode 100644 plugin/.DS_Store create mode 100644 plugin/background.js create mode 100644 plugin/content.js create mode 100644 plugin/icons/128.png create mode 100644 plugin/icons/16.png create mode 100644 plugin/icons/48.png create mode 100644 plugin/icons/Thumbs.db create mode 100644 plugin/js-base64/LICENSE.md create mode 100644 plugin/js-base64/README.md create mode 100644 plugin/js-base64/base64.d.mts create mode 100644 plugin/js-base64/base64.d.ts create mode 100644 plugin/js-base64/base64.js create mode 100644 plugin/js-base64/base64.mjs create mode 100644 plugin/js-base64/package.json create mode 100644 plugin/manifest.json create mode 100644 plugin/popup.html create mode 100644 plugin/popup.js diff --git a/.DS_Store b/.DS_Store index 819bd07544391e12a6c852f5e2b70daed698fefc..4837e51188ce9279a5c030feed3490afac158c13 100644 GIT binary patch delta 185 zcmZoMXfc=|#>B)qu~2NHo+2*`0|Nsi1A_nqLncGs#F+Jq1(+CRL4s@y1q?Y1r3~pH ziKO!4f~1`MB%t{A$r_A>YU0(^7Unt%h9>5B`mu~2NHo+2+30|Nsi1A_nqLncG=#F+Jy4MbQb|6`iMXuNqca|z2P jmiLUC**W+*fI2pRWd6=PnP0?`1E>e2iD`3y$QEV*G)WVL diff --git a/plugin/.DS_Store b/plugin/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d8d844af3d0e5ad8739cc0c55cf1aa5c1b2c9724 GIT binary patch literal 6148 zcmeHKI|>3Z5S{S@f{mqRuHX%V=n1@lpdf;*plH37=kjR2`83O7r-kwcCNG)HOUNsB zc0@#%xBWt7CL$BKp*(Epo9&zTY>*KJ!g0p+zPU7~b93nBz6%(4EJxYNS(*;tc4$<9 z3Qz$mKn1A4rxnNwJDGm^V4g<>sKC!FVBd!VH>`Bxq5@RluN2VHYO`A6Nm*NakF#1^;9I!mJmF@TI|YN6W1yE~EUX;QJt^{v&9Pq- U+d!uy?sOo3222+k75KISFBrfS)c^nh literal 0 HcmV?d00001 diff --git a/plugin/background.js b/plugin/background.js new file mode 100644 index 0000000..9ce29e6 --- /dev/null +++ b/plugin/background.js @@ -0,0 +1,169 @@ +importScripts("./js-base64/base64.js"); + +const harmonyURL = "https://harmonydata.ac.uk/app/#/"; + +const createHarmonyUrl = ({ questions, instrument_name }) => { + if ( + Array.isArray(questions) && + questions.length && + questions.every( + (q) => + typeof q === "string" || + q instanceof String || + (q.question_text && + (typeof q.question_text === "string" || + q.question_text instanceof String)) + ) + ) { + const qArray = questions.map((q, i) => { + return { + question_no: q.question_no || i, + question_text: q.question_text || q, + }; + }); + const iArray = { instrument_name: instrument_name, questions: qArray }; + return harmonyURL + "import/" + Base64.encode(JSON.stringify(iArray), true); + } else { + throw new Error( + "questions is not properly formatted - it must be an array of question texts, or an array of objects which each must have a question_text property" + ); + } +}; + +// Create context menu item +chrome.runtime.onInstalled.addListener(() => { + chrome.contextMenus.create({ + id: "sendToHarmony", + title: "Send to Harmony", + contexts: ["selection"], + }); + // Initialize history in storage + chrome.storage.local.set({ history: [] }); +}); + +// Function to find or create Harmony tab +async function findOrCreateHarmonyTab(url) { + // First, try to find an existing tab with our target name in the URL + const tabs = await chrome.tabs.query({}); + const harmonyTab = tabs.find( + (tab) => tab.url && tab.url.includes(harmonyURL) + ); + + if (harmonyTab) { + // Update existing tab + await chrome.tabs.update(harmonyTab.id, { url: url, active: true }); + await chrome.windows.update(harmonyTab.windowId, { focused: true }); + } else { + // Create new tab + await chrome.tabs.create({ url: url }); + } +} + +// Listen for messages from popup +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.action === "openHarmonyUrl") { + findOrCreateHarmonyTab(request.url); + return true; + } + if (request.action === "returnCopied") { + findOrCreateHarmonyTab(request.url); + return true; + } +}); + +chrome.contextMenus.onClicked.addListener(function (info, tab) { + if (info.menuItemId === "sendToHarmony") { + if (tab?.id > -1) { + chrome.scripting + .executeScript({ + target: { tabId: tab.id }, + function: () => { + const selection = document.getSelection(); + return selection ? selection.toString() : ""; + }, + }) + .then((resultArray) => { + const result = resultArray[0]; + const selectedText = + result && result && result.result ? result.result : ""; // Handle various result possibilities + processSelection(selectedText, tab); + }) + .catch((error) => { + console.error("Error getting selected text:", error); + }); + } else { + // If tab.id is null (eg in a PDF), trigger the copy command and then read from clipboard + chrome.tabs + .sendMessage({ + action: "copySelection", + }) + .then((response) => { + if (response?.success) { + try { + navigator.clipboard + .readText() + .then((selectedText) => processSelection(selectedText, tab)); + } catch (err) { + console.error("Failed to read clipboard contents: ", err); + } + } + }) + .catch((error) => { + console.error("Error executing copy command:", error); + }); + } + } +}); + +async function processSelection(selectedText, tab) { + if (!selectedText) { + return; // Handle cases where no text is selected + } + + // Process the selected text here... + const questionsArray = selectedText + .split(/\r?\n|\s*/i) + .filter((line) => line.trim() !== ""); + + try { + // Create the Harmony URL with the selected text as a question + const harmonyUrl = createHarmonyUrl({ + questions: questionsArray, + instrument_name: `Imported from ${tab.title} ${tab.url}`, + }); + + // Store in history + chrome.storage.local.get(["history"], function (result) { + const history = result.history || []; + history.unshift({ + text: + selectedText.substring(0, 100) + + (selectedText.length > 100 ? "..." : ""), + url: tab.url, + timestamp: new Date().toISOString(), + harmonyUrl: harmonyUrl, + }); + // Keep only last 10 items + if (history.length > 10) history.pop(); + chrome.storage.local.set({ history: history }); + }); + + // Open or update the Harmony tab + await findOrCreateHarmonyTab(harmonyUrl); + + // Show success notification + chrome.action.setBadgeText({ text: "✓" }); + chrome.action.setBadgeBackgroundColor({ color: "#4CAF50" }); + setTimeout(() => { + chrome.action.setBadgeText({ text: "" }); + }, 2000); + } catch (error) { + // Show error notification + chrome.action.setBadgeText({ text: "!" }); + chrome.action.setBadgeBackgroundColor({ color: "#F44336" }); + setTimeout(() => { + chrome.action.setBadgeText({ text: "" }); + }, 2000); + console.error("Error:", error); + } +} diff --git a/plugin/content.js b/plugin/content.js new file mode 100644 index 0000000..50d4522 --- /dev/null +++ b/plugin/content.js @@ -0,0 +1,20 @@ +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.action === "copySelection") { + try { + // Execute the copy command + document.execCommand("copy"); + navigator.clipboard.readText().then((selection) => { + console.log("selectedText", selection); + sendResponse({ + action: "returnCopied", + success: true, + selection: selection, + }); + }); + } catch (error) { + console.error("Error executing copy command:", error); + sendResponse({ success: false, error: error.message }); + } + } + return true; +}); diff --git a/plugin/icons/128.png b/plugin/icons/128.png new file mode 100644 index 0000000000000000000000000000000000000000..b96668161c1ac1e599333e7b1b95e309cefb9cf8 GIT binary patch literal 7762 zcma)hWl)?^v*rsETxNja?hxD)+$~6e;O-ED1$Pe;2m>LwYjAfB76J@z!3K8*cLJMl zZ`D@qR&CvTtgHGtPxp^L-9Ju8zf)7d!6d^3002ixQC9Px4F1nXNBwv9iJOo76Ev2J znyLWc%k)nl4gmN6!S?{bgBt)2%m6?*6#$4`GTSsn{{g5LZxv*L=l{&y&XRBcG-&Qh zs&Z)iNYq%w1ailP!T>vY&FEy#?`<6*J< zQZO=f0WXrH15E&1Q~)hHpAsryT~iccQr{IH+DZ%*iDV|P?sJ!*xHEtZr_=wf?v?}Eae#SY=$e_GB%mT-e3lZp6sBd z0E8v!Y={XDqxuU%uX7~mDQLj*E~h78C(iD1DX75wt~ztIae6E$38_J9zE{GQ=_vhE z%UBzJttxfVEBydl?mj=h(ki}aZ&U^lgJdFrA&F13*yzYwXstag`|!ko1)xq>I}V=2;TC z{uQ8+fdXjs>1I50bflxx^e^1AOxtPI#IOPr<}LQ_SFafApG%2960hKte*jn9^Okts zHJnnL1DpBIG{;rcy|1`JwY3lznG%OcR71CK><7IeT1riadtJjohv_{T7$n$sEfj$=!x<85P@@Ktc82i3wuVLCP^seuE|q5#Batb+X>V_ zrqZ9T%b?s0v*8SCwEG}AYx*>@56yfj_K5)s_W&~X_QUV)(Ew|YvO;~ z9Rrl%NE2vrvWsrjHs99UD7MU)A^bl5J z9m_07xzj+UdFlGWU{#UB5~v#w7`A^yS^SH%CurVM@otA7YNLW`X;N|p*|b-=QM-

7sRSvQUuufBr~88pD_`3>_*i8 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 IM6N<$f;HR#SpWb4 literal 0 HcmV?d00001 diff --git a/plugin/icons/48.png b/plugin/icons/48.png new file mode 100644 index 0000000000000000000000000000000000000000..3473e60ee2e26cbe08df8ff6327661d5710ef121 GIT binary patch literal 2559 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 CK$Ow| literal 0 HcmV?d00001 diff --git a/plugin/icons/Thumbs.db b/plugin/icons/Thumbs.db new file mode 100644 index 0000000000000000000000000000000000000000..cba85a47d1ffed6937546ca86e65f013deb5e664 GIT binary patch literal 7680 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 P|N3+E`ya0Vr<{KS{RJto literal 0 HcmV?d00001 diff --git a/plugin/js-base64/LICENSE.md b/plugin/js-base64/LICENSE.md new file mode 100644 index 0000000..fd579a4 --- /dev/null +++ b/plugin/js-base64/LICENSE.md @@ -0,0 +1,27 @@ +Copyright (c) 2014, Dan Kogai +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of {{{project}}} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugin/js-base64/README.md b/plugin/js-base64/README.md new file mode 100644 index 0000000..19b0709 --- /dev/null +++ b/plugin/js-base64/README.md @@ -0,0 +1,169 @@ +[![CI via GitHub Actions](https://github.com/dankogai/js-base64/actions/workflows/node.js.yml/badge.svg)](https://github.com/dankogai/js-base64/actions/workflows/node.js.yml) + +# base64.js + +Yet another [Base64] transcoder. + +[Base64]: http://en.wikipedia.org/wiki/Base64 + +## Install + +```shell +$ npm install --save js-base64 +``` + +## Usage + +### In Browser + +Locally… + +```html + +``` + +… or Directly from CDN. In which case you don't even need to install. + +```html + +``` + +This good old way loads `Base64` in the global context (`window`). Though `Base64.noConflict()` is made available, you should consider using ES6 Module to avoid tainting `window`. + +### As an ES6 Module + +locally… + +```javascript +import { Base64 } from 'js-base64'; +``` + +```javascript +// or if you prefer no Base64 namespace +import { encode, decode } from 'js-base64'; +``` + +or even remotely. + +```html + +``` + +```html + +``` + +### node.js (commonjs) + +```javascript +const {Base64} = require('js-base64'); +``` + +Unlike the case above, the global context is no longer modified. + +You can also use [esm] to `import` instead of `require`. + +[esm]: https://github.com/standard-things/esm + +```javascript +require=require('esm')(module); +import {Base64} from 'js-base64'; +``` + +## SYNOPSIS + +```javascript +let latin = 'dankogai'; +let utf8 = '小飼弾' +let u8s = new Uint8Array([100,97,110,107,111,103,97,105]); +Base64.encode(latin); // ZGFua29nYWk= +Base64.encode(latin, true); // ZGFua29nYWk skips padding +Base64.encodeURI(latin); // ZGFua29nYWk +Base64.btoa(latin); // ZGFua29nYWk= +Base64.btoa(utf8); // raises exception +Base64.fromUint8Array(u8s); // ZGFua29nYWk= +Base64.fromUint8Array(u8s, true); // ZGFua29nYW which is URI safe +Base64.encode(utf8); // 5bCP6aO85by+ +Base64.encode(utf8, true) // 5bCP6aO85by- +Base64.encodeURI(utf8); // 5bCP6aO85by- +``` + +```javascript +Base64.decode( 'ZGFua29nYWk=');// dankogai +Base64.decode( 'ZGFua29nYWk'); // dankogai +Base64.atob( 'ZGFua29nYWk=');// dankogai +Base64.atob( '5bCP6aO85by+');// '小飼弾' which is nonsense +Base64.toUint8Array('ZGFua29nYWk=');// u8s above +Base64.decode( '5bCP6aO85by+');// 小飼弾 +// note .decodeURI() is unnecessary since it accepts both flavors +Base64.decode( '5bCP6aO85by-');// 小飼弾 +``` + +```javascript +Base64.isValid(0); // false: 0 is not string +Base64.isValid(''); // true: a valid Base64-encoded empty byte +Base64.isValid('ZA=='); // true: a valid Base64-encoded 'd' +Base64.isValid('Z A='); // true: whitespaces are okay +Base64.isValid('ZA'); // true: padding ='s can be omitted +Base64.isValid('++'); // true: can be non URL-safe +Base64.isValid('--'); // true: or URL-safe +Base64.isValid('+-'); // false: can't mix both +``` + +### Built-in Extensions + +By default `Base64` leaves built-in prototypes untouched. But you can extend them as below. + +```javascript +// you have to explicitly extend String.prototype +Base64.extendString(); +// once extended, you can do the following +'dankogai'.toBase64(); // ZGFua29nYWk= +'小飼弾'.toBase64(); // 5bCP6aO85by+ +'小飼弾'.toBase64(true); // 5bCP6aO85by- +'小飼弾'.toBase64URI(); // 5bCP6aO85by- ab alias of .toBase64(true) +'小飼弾'.toBase64URL(); // 5bCP6aO85by- an alias of .toBase64URI() +'ZGFua29nYWk='.fromBase64(); // dankogai +'5bCP6aO85by+'.fromBase64(); // 小飼弾 +'5bCP6aO85by-'.fromBase64(); // 小飼弾 +'5bCP6aO85by-'.toUint8Array();// u8s above +``` + +```javascript +// you have to explicitly extend Uint8Array.prototype +Base64.extendUint8Array(); +// once extended, you can do the following +u8s.toBase64(); // 'ZGFua29nYWk=' +u8s.toBase64URI(); // 'ZGFua29nYWk' +u8s.toBase64URL(); // 'ZGFua29nYWk' an alias of .toBase64URI() +``` + +```javascript +// extend all at once +Base64.extendBuiltins() +``` + +## `.decode()` vs `.atob` (and `.encode()` vs `btoa()`) + +Suppose you have: + +``` +var pngBase64 = + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="; +``` + +Which is a Base64-encoded 1x1 transparent PNG, **DO NOT USE** `Base64.decode(pngBase64)`.  Use `Base64.atob(pngBase64)` instead.  `Base64.decode()` decodes to UTF-8 string while `Base64.atob()` decodes to bytes, which is compatible to browser built-in `atob()` (Which is absent in node.js).  The same rule applies to the opposite direction. + +Or even better, `Base64.toUint8Array(pngBase64)`. + +## Brief History + +* Since version 3.3 it is written in TypeScript. Now `base64.mjs` is compiled from `base64.ts` then `base64.js` is generated from `base64.mjs`. +* Since version 3.7 `base64.js` is ES5-compatible again (hence IE11-compatible). +* Since 3.0 `js-base64` switch to ES2015 module so it is no longer compatible with legacy browsers like IE (see above) diff --git a/plugin/js-base64/base64.d.mts b/plugin/js-base64/base64.d.mts new file mode 100644 index 0000000..e44249c --- /dev/null +++ b/plugin/js-base64/base64.d.mts @@ -0,0 +1,135 @@ +/** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ +declare const version = "3.7.7"; +/** + * @deprecated use lowercase `version`. + */ +declare const VERSION = "3.7.7"; +/** + * polyfill version of `btoa` + */ +declare const btoaPolyfill: (bin: string) => string; +/** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ +declare const _btoa: (bin: string) => string; +/** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ +declare const fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ +declare const utob: (u: string) => string; +/** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ +declare const encode: (src: string, urlsafe?: boolean) => string; +/** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ +declare const encodeURI: (src: string) => string; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ +declare const btou: (b: string) => string; +/** + * polyfill version of `atob` + */ +declare const atobPolyfill: (asc: string) => string; +/** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ +declare const _atob: (asc: string) => string; +/** + * converts a Base64 string to a Uint8Array. + */ +declare const toUint8Array: (a: string) => Uint8Array; +/** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ +declare const decode: (src: string) => string; +/** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ +declare const isValid: (src: any) => boolean; +/** + * extend String.prototype with relevant methods + */ +declare const extendString: () => void; +/** + * extend Uint8Array.prototype with relevant methods + */ +declare const extendUint8Array: () => void; +/** + * extend Builtin prototypes with relevant methods + */ +declare const extendBuiltins: () => void; +declare const gBase64: { + version: string; + VERSION: string; + atob: (asc: string) => string; + atobPolyfill: (asc: string) => string; + btoa: (bin: string) => string; + btoaPolyfill: (bin: string) => string; + fromBase64: (src: string) => string; + toBase64: (src: string, urlsafe?: boolean) => string; + encode: (src: string, urlsafe?: boolean) => string; + encodeURI: (src: string) => string; + encodeURL: (src: string) => string; + utob: (u: string) => string; + btou: (b: string) => string; + decode: (src: string) => string; + isValid: (src: any) => boolean; + fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; + toUint8Array: (a: string) => Uint8Array; + extendString: () => void; + extendUint8Array: () => void; + extendBuiltins: () => void; +}; +export { version }; +export { VERSION }; +export { _atob as atob }; +export { atobPolyfill }; +export { _btoa as btoa }; +export { btoaPolyfill }; +export { decode as fromBase64 }; +export { encode as toBase64 }; +export { utob }; +export { encode }; +export { encodeURI }; +export { encodeURI as encodeURL }; +export { btou }; +export { decode }; +export { isValid }; +export { fromUint8Array }; +export { toUint8Array }; +export { extendString }; +export { extendUint8Array }; +export { extendBuiltins }; +export { gBase64 as Base64 }; diff --git a/plugin/js-base64/base64.d.ts b/plugin/js-base64/base64.d.ts new file mode 100644 index 0000000..e44249c --- /dev/null +++ b/plugin/js-base64/base64.d.ts @@ -0,0 +1,135 @@ +/** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ +declare const version = "3.7.7"; +/** + * @deprecated use lowercase `version`. + */ +declare const VERSION = "3.7.7"; +/** + * polyfill version of `btoa` + */ +declare const btoaPolyfill: (bin: string) => string; +/** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ +declare const _btoa: (bin: string) => string; +/** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ +declare const fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ +declare const utob: (u: string) => string; +/** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ +declare const encode: (src: string, urlsafe?: boolean) => string; +/** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ +declare const encodeURI: (src: string) => string; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ +declare const btou: (b: string) => string; +/** + * polyfill version of `atob` + */ +declare const atobPolyfill: (asc: string) => string; +/** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ +declare const _atob: (asc: string) => string; +/** + * converts a Base64 string to a Uint8Array. + */ +declare const toUint8Array: (a: string) => Uint8Array; +/** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ +declare const decode: (src: string) => string; +/** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ +declare const isValid: (src: any) => boolean; +/** + * extend String.prototype with relevant methods + */ +declare const extendString: () => void; +/** + * extend Uint8Array.prototype with relevant methods + */ +declare const extendUint8Array: () => void; +/** + * extend Builtin prototypes with relevant methods + */ +declare const extendBuiltins: () => void; +declare const gBase64: { + version: string; + VERSION: string; + atob: (asc: string) => string; + atobPolyfill: (asc: string) => string; + btoa: (bin: string) => string; + btoaPolyfill: (bin: string) => string; + fromBase64: (src: string) => string; + toBase64: (src: string, urlsafe?: boolean) => string; + encode: (src: string, urlsafe?: boolean) => string; + encodeURI: (src: string) => string; + encodeURL: (src: string) => string; + utob: (u: string) => string; + btou: (b: string) => string; + decode: (src: string) => string; + isValid: (src: any) => boolean; + fromUint8Array: (u8a: Uint8Array, urlsafe?: boolean) => string; + toUint8Array: (a: string) => Uint8Array; + extendString: () => void; + extendUint8Array: () => void; + extendBuiltins: () => void; +}; +export { version }; +export { VERSION }; +export { _atob as atob }; +export { atobPolyfill }; +export { _btoa as btoa }; +export { btoaPolyfill }; +export { decode as fromBase64 }; +export { encode as toBase64 }; +export { utob }; +export { encode }; +export { encodeURI }; +export { encodeURI as encodeURL }; +export { btou }; +export { decode }; +export { isValid }; +export { fromUint8Array }; +export { toUint8Array }; +export { extendString }; +export { extendUint8Array }; +export { extendBuiltins }; +export { gBase64 as Base64 }; diff --git a/plugin/js-base64/base64.js b/plugin/js-base64/base64.js new file mode 100644 index 0000000..dc837a7 --- /dev/null +++ b/plugin/js-base64/base64.js @@ -0,0 +1,314 @@ +// +// THIS FILE IS AUTOMATICALLY GENERATED! DO NOT EDIT BY HAND! +// +; +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? module.exports = factory() + : typeof define === 'function' && define.amd + ? define(factory) : + // cf. https://github.com/dankogai/js-base64/issues/119 + (function () { + // existing version for noConflict() + var _Base64 = global.Base64; + var gBase64 = factory(); + gBase64.noConflict = function () { + global.Base64 = _Base64; + return gBase64; + }; + if (global.Meteor) { // Meteor.js + Base64 = gBase64; + } + global.Base64 = gBase64; + })(); +}((typeof self !== 'undefined' ? self + : typeof window !== 'undefined' ? window + : typeof global !== 'undefined' ? global + : this), function () { + 'use strict'; + /** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ + var version = '3.7.7'; + /** + * @deprecated use lowercase `version`. + */ + var VERSION = version; + var _hasBuffer = typeof Buffer === 'function'; + var _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined; + var _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined; + var b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + var b64chs = Array.prototype.slice.call(b64ch); + var b64tab = (function (a) { + var tab = {}; + a.forEach(function (c, i) { return tab[c] = i; }); + return tab; + })(b64chs); + var b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; + var _fromCC = String.fromCharCode.bind(String); + var _U8Afrom = typeof Uint8Array.from === 'function' + ? Uint8Array.from.bind(Uint8Array) + : function (it) { return new Uint8Array(Array.prototype.slice.call(it, 0)); }; + var _mkUriSafe = function (src) { return src + .replace(/=/g, '').replace(/[+\/]/g, function (m0) { return m0 == '+' ? '-' : '_'; }); }; + var _tidyB64 = function (s) { return s.replace(/[^A-Za-z0-9\+\/]/g, ''); }; + /** + * polyfill version of `btoa` + */ + var btoaPolyfill = function (bin) { + // console.log('polyfilled'); + var u32, c0, c1, c2, asc = ''; + var pad = bin.length % 3; + for (var i = 0; i < bin.length;) { + if ((c0 = bin.charCodeAt(i++)) > 255 || + (c1 = bin.charCodeAt(i++)) > 255 || + (c2 = bin.charCodeAt(i++)) > 255) + throw new TypeError('invalid character found'); + u32 = (c0 << 16) | (c1 << 8) | c2; + asc += b64chs[u32 >> 18 & 63] + + b64chs[u32 >> 12 & 63] + + b64chs[u32 >> 6 & 63] + + b64chs[u32 & 63]; + } + return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; + }; + /** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ + var _btoa = typeof btoa === 'function' ? function (bin) { return btoa(bin); } + : _hasBuffer ? function (bin) { return Buffer.from(bin, 'binary').toString('base64'); } + : btoaPolyfill; + var _fromUint8Array = _hasBuffer + ? function (u8a) { return Buffer.from(u8a).toString('base64'); } + : function (u8a) { + // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 + var maxargs = 0x1000; + var strs = []; + for (var i = 0, l = u8a.length; i < l; i += maxargs) { + strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs))); + } + return _btoa(strs.join('')); + }; + /** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ + var fromUint8Array = function (u8a, urlsafe) { + if (urlsafe === void 0) { urlsafe = false; } + return urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); + }; + // This trick is found broken https://github.com/dankogai/js-base64/issues/130 + // const utob = (src: string) => unescape(encodeURIComponent(src)); + // reverting good old fationed regexp + var cb_utob = function (c) { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c + : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6)) + + _fromCC(0x80 | (cc & 0x3f))) + : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } + else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (_fromCC(0xf0 | ((cc >>> 18) & 0x07)) + + _fromCC(0x80 | ((cc >>> 12) & 0x3f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } + }; + var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; + /** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ + var utob = function (u) { return u.replace(re_utob, cb_utob); }; + // + var _encode = _hasBuffer + ? function (s) { return Buffer.from(s, 'utf8').toString('base64'); } + : _TE + ? function (s) { return _fromUint8Array(_TE.encode(s)); } + : function (s) { return _btoa(utob(s)); }; + /** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ + var encode = function (src, urlsafe) { + if (urlsafe === void 0) { urlsafe = false; } + return urlsafe + ? _mkUriSafe(_encode(src)) + : _encode(src); + }; + /** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ + var encodeURI = function (src) { return encode(src, true); }; + // This trick is found broken https://github.com/dankogai/js-base64/issues/130 + // const btou = (src: string) => decodeURIComponent(escape(src)); + // reverting good old fationed regexp + var re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; + var cb_btou = function (cccc) { + switch (cccc.length) { + case 4: + var cp = ((0x07 & cccc.charCodeAt(0)) << 18) + | ((0x3f & cccc.charCodeAt(1)) << 12) + | ((0x3f & cccc.charCodeAt(2)) << 6) + | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; + return (_fromCC((offset >>> 10) + 0xD800) + + _fromCC((offset & 0x3FF) + 0xDC00)); + case 3: + return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12) + | ((0x3f & cccc.charCodeAt(1)) << 6) + | (0x3f & cccc.charCodeAt(2))); + default: + return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6) + | (0x3f & cccc.charCodeAt(1))); + } + }; + /** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ + var btou = function (b) { return b.replace(re_btou, cb_btou); }; + /** + * polyfill version of `atob` + */ + var atobPolyfill = function (asc) { + // console.log('polyfilled'); + asc = asc.replace(/\s+/g, ''); + if (!b64re.test(asc)) + throw new TypeError('malformed base64.'); + asc += '=='.slice(2 - (asc.length & 3)); + var u24, bin = '', r1, r2; + for (var i = 0; i < asc.length;) { + u24 = b64tab[asc.charAt(i++)] << 18 + | b64tab[asc.charAt(i++)] << 12 + | (r1 = b64tab[asc.charAt(i++)]) << 6 + | (r2 = b64tab[asc.charAt(i++)]); + bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) + : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) + : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); + } + return bin; + }; + /** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ + var _atob = typeof atob === 'function' ? function (asc) { return atob(_tidyB64(asc)); } + : _hasBuffer ? function (asc) { return Buffer.from(asc, 'base64').toString('binary'); } + : atobPolyfill; + // + var _toUint8Array = _hasBuffer + ? function (a) { return _U8Afrom(Buffer.from(a, 'base64')); } + : function (a) { return _U8Afrom(_atob(a).split('').map(function (c) { return c.charCodeAt(0); })); }; + /** + * converts a Base64 string to a Uint8Array. + */ + var toUint8Array = function (a) { return _toUint8Array(_unURI(a)); }; + // + var _decode = _hasBuffer + ? function (a) { return Buffer.from(a, 'base64').toString('utf8'); } + : _TD + ? function (a) { return _TD.decode(_toUint8Array(a)); } + : function (a) { return btou(_atob(a)); }; + var _unURI = function (a) { return _tidyB64(a.replace(/[-_]/g, function (m0) { return m0 == '-' ? '+' : '/'; })); }; + /** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ + var decode = function (src) { return _decode(_unURI(src)); }; + /** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ + var isValid = function (src) { + if (typeof src !== 'string') + return false; + var s = src.replace(/\s+/g, '').replace(/={0,2}$/, ''); + return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); + }; + // + var _noEnum = function (v) { + return { + value: v, enumerable: false, writable: true, configurable: true + }; + }; + /** + * extend String.prototype with relevant methods + */ + var extendString = function () { + var _add = function (name, body) { return Object.defineProperty(String.prototype, name, _noEnum(body)); }; + _add('fromBase64', function () { return decode(this); }); + _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); + _add('toBase64URI', function () { return encode(this, true); }); + _add('toBase64URL', function () { return encode(this, true); }); + _add('toUint8Array', function () { return toUint8Array(this); }); + }; + /** + * extend Uint8Array.prototype with relevant methods + */ + var extendUint8Array = function () { + var _add = function (name, body) { return Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); }; + _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); + _add('toBase64URI', function () { return fromUint8Array(this, true); }); + _add('toBase64URL', function () { return fromUint8Array(this, true); }); + }; + /** + * extend Builtin prototypes with relevant methods + */ + var extendBuiltins = function () { + extendString(); + extendUint8Array(); + }; + var gBase64 = { + version: version, + VERSION: VERSION, + atob: _atob, + atobPolyfill: atobPolyfill, + btoa: _btoa, + btoaPolyfill: btoaPolyfill, + fromBase64: decode, + toBase64: encode, + encode: encode, + encodeURI: encodeURI, + encodeURL: encodeURI, + utob: utob, + btou: btou, + decode: decode, + isValid: isValid, + fromUint8Array: fromUint8Array, + toUint8Array: toUint8Array, + extendString: extendString, + extendUint8Array: extendUint8Array, + extendBuiltins: extendBuiltins + }; + // + // export Base64 to the namespace + // + // ES5 is yet to have Object.assign() that may make transpilers unhappy. + // gBase64.Base64 = Object.assign({}, gBase64); + gBase64.Base64 = {}; + Object.keys(gBase64).forEach(function (k) { return gBase64.Base64[k] = gBase64[k]; }); + return gBase64; +})); diff --git a/plugin/js-base64/base64.mjs b/plugin/js-base64/base64.mjs new file mode 100644 index 0000000..fe9cfa5 --- /dev/null +++ b/plugin/js-base64/base64.mjs @@ -0,0 +1,294 @@ +/** + * base64.ts + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + * + * @author Dan Kogai (https://github.com/dankogai) + */ +const version = '3.7.7'; +/** + * @deprecated use lowercase `version`. + */ +const VERSION = version; +const _hasBuffer = typeof Buffer === 'function'; +const _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined; +const _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined; +const b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64chs = Array.prototype.slice.call(b64ch); +const b64tab = ((a) => { + let tab = {}; + a.forEach((c, i) => tab[c] = i); + return tab; +})(b64chs); +const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; +const _fromCC = String.fromCharCode.bind(String); +const _U8Afrom = typeof Uint8Array.from === 'function' + ? Uint8Array.from.bind(Uint8Array) + : (it) => new Uint8Array(Array.prototype.slice.call(it, 0)); +const _mkUriSafe = (src) => src + .replace(/=/g, '').replace(/[+\/]/g, (m0) => m0 == '+' ? '-' : '_'); +const _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, ''); +/** + * polyfill version of `btoa` + */ +const btoaPolyfill = (bin) => { + // console.log('polyfilled'); + let u32, c0, c1, c2, asc = ''; + const pad = bin.length % 3; + for (let i = 0; i < bin.length;) { + if ((c0 = bin.charCodeAt(i++)) > 255 || + (c1 = bin.charCodeAt(i++)) > 255 || + (c2 = bin.charCodeAt(i++)) > 255) + throw new TypeError('invalid character found'); + u32 = (c0 << 16) | (c1 << 8) | c2; + asc += b64chs[u32 >> 18 & 63] + + b64chs[u32 >> 12 & 63] + + b64chs[u32 >> 6 & 63] + + b64chs[u32 & 63]; + } + return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc; +}; +/** + * does what `window.btoa` of web browsers do. + * @param {String} bin binary string + * @returns {string} Base64-encoded string + */ +const _btoa = typeof btoa === 'function' ? (bin) => btoa(bin) + : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64') + : btoaPolyfill; +const _fromUint8Array = _hasBuffer + ? (u8a) => Buffer.from(u8a).toString('base64') + : (u8a) => { + // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326 + const maxargs = 0x1000; + let strs = []; + for (let i = 0, l = u8a.length; i < l; i += maxargs) { + strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs))); + } + return _btoa(strs.join('')); + }; +/** + * converts a Uint8Array to a Base64 string. + * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 §5 + * @returns {string} Base64 string + */ +const fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a); +// This trick is found broken https://github.com/dankogai/js-base64/issues/130 +// const utob = (src: string) => unescape(encodeURIComponent(src)); +// reverting good old fationed regexp +const cb_utob = (c) => { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c + : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6)) + + _fromCC(0x80 | (cc & 0x3f))) + : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } + else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (_fromCC(0xf0 | ((cc >>> 18) & 0x07)) + + _fromCC(0x80 | ((cc >>> 12) & 0x3f)) + + _fromCC(0x80 | ((cc >>> 6) & 0x3f)) + + _fromCC(0x80 | (cc & 0x3f))); + } +}; +const re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-8 string + * @returns {string} UTF-16 string + */ +const utob = (u) => u.replace(re_utob, cb_utob); +// +const _encode = _hasBuffer + ? (s) => Buffer.from(s, 'utf8').toString('base64') + : _TE + ? (s) => _fromUint8Array(_TE.encode(s)) + : (s) => _btoa(utob(s)); +/** + * converts a UTF-8-encoded string to a Base64 string. + * @param {boolean} [urlsafe] if `true` make the result URL-safe + * @returns {string} Base64 string + */ +const encode = (src, urlsafe = false) => urlsafe + ? _mkUriSafe(_encode(src)) + : _encode(src); +/** + * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 §5. + * @returns {string} Base64 string + */ +const encodeURI = (src) => encode(src, true); +// This trick is found broken https://github.com/dankogai/js-base64/issues/130 +// const btou = (src: string) => decodeURIComponent(escape(src)); +// reverting good old fationed regexp +const re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g; +const cb_btou = (cccc) => { + switch (cccc.length) { + case 4: + var cp = ((0x07 & cccc.charCodeAt(0)) << 18) + | ((0x3f & cccc.charCodeAt(1)) << 12) + | ((0x3f & cccc.charCodeAt(2)) << 6) + | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000; + return (_fromCC((offset >>> 10) + 0xD800) + + _fromCC((offset & 0x3FF) + 0xDC00)); + case 3: + return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12) + | ((0x3f & cccc.charCodeAt(1)) << 6) + | (0x3f & cccc.charCodeAt(2))); + default: + return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6) + | (0x3f & cccc.charCodeAt(1))); + } +}; +/** + * @deprecated should have been internal use only. + * @param {string} src UTF-16 string + * @returns {string} UTF-8 string + */ +const btou = (b) => b.replace(re_btou, cb_btou); +/** + * polyfill version of `atob` + */ +const atobPolyfill = (asc) => { + // console.log('polyfilled'); + asc = asc.replace(/\s+/g, ''); + if (!b64re.test(asc)) + throw new TypeError('malformed base64.'); + asc += '=='.slice(2 - (asc.length & 3)); + let u24, bin = '', r1, r2; + for (let i = 0; i < asc.length;) { + u24 = b64tab[asc.charAt(i++)] << 18 + | b64tab[asc.charAt(i++)] << 12 + | (r1 = b64tab[asc.charAt(i++)]) << 6 + | (r2 = b64tab[asc.charAt(i++)]); + bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) + : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) + : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255); + } + return bin; +}; +/** + * does what `window.atob` of web browsers do. + * @param {String} asc Base64-encoded string + * @returns {string} binary string + */ +const _atob = typeof atob === 'function' ? (asc) => atob(_tidyB64(asc)) + : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary') + : atobPolyfill; +// +const _toUint8Array = _hasBuffer + ? (a) => _U8Afrom(Buffer.from(a, 'base64')) + : (a) => _U8Afrom(_atob(a).split('').map(c => c.charCodeAt(0))); +/** + * converts a Base64 string to a Uint8Array. + */ +const toUint8Array = (a) => _toUint8Array(_unURI(a)); +// +const _decode = _hasBuffer + ? (a) => Buffer.from(a, 'base64').toString('utf8') + : _TD + ? (a) => _TD.decode(_toUint8Array(a)) + : (a) => btou(_atob(a)); +const _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/')); +/** + * converts a Base64 string to a UTF-8 string. + * @param {String} src Base64 string. Both normal and URL-safe are supported + * @returns {string} UTF-8 string + */ +const decode = (src) => _decode(_unURI(src)); +/** + * check if a value is a valid Base64 string + * @param {String} src a value to check + */ +const isValid = (src) => { + if (typeof src !== 'string') + return false; + const s = src.replace(/\s+/g, '').replace(/={0,2}$/, ''); + return !/[^\s0-9a-zA-Z\+/]/.test(s) || !/[^\s0-9a-zA-Z\-_]/.test(s); +}; +// +const _noEnum = (v) => { + return { + value: v, enumerable: false, writable: true, configurable: true + }; +}; +/** + * extend String.prototype with relevant methods + */ +const extendString = function () { + const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body)); + _add('fromBase64', function () { return decode(this); }); + _add('toBase64', function (urlsafe) { return encode(this, urlsafe); }); + _add('toBase64URI', function () { return encode(this, true); }); + _add('toBase64URL', function () { return encode(this, true); }); + _add('toUint8Array', function () { return toUint8Array(this); }); +}; +/** + * extend Uint8Array.prototype with relevant methods + */ +const extendUint8Array = function () { + const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body)); + _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); }); + _add('toBase64URI', function () { return fromUint8Array(this, true); }); + _add('toBase64URL', function () { return fromUint8Array(this, true); }); +}; +/** + * extend Builtin prototypes with relevant methods + */ +const extendBuiltins = () => { + extendString(); + extendUint8Array(); +}; +const gBase64 = { + version: version, + VERSION: VERSION, + atob: _atob, + atobPolyfill: atobPolyfill, + btoa: _btoa, + btoaPolyfill: btoaPolyfill, + fromBase64: decode, + toBase64: encode, + encode: encode, + encodeURI: encodeURI, + encodeURL: encodeURI, + utob: utob, + btou: btou, + decode: decode, + isValid: isValid, + fromUint8Array: fromUint8Array, + toUint8Array: toUint8Array, + extendString: extendString, + extendUint8Array: extendUint8Array, + extendBuiltins: extendBuiltins +}; +// makecjs:CUT // +export { version }; +export { VERSION }; +export { _atob as atob }; +export { atobPolyfill }; +export { _btoa as btoa }; +export { btoaPolyfill }; +export { decode as fromBase64 }; +export { encode as toBase64 }; +export { utob }; +export { encode }; +export { encodeURI }; +export { encodeURI as encodeURL }; +export { btou }; +export { decode }; +export { isValid }; +export { fromUint8Array }; +export { toUint8Array }; +export { extendString }; +export { extendUint8Array }; +export { extendBuiltins }; +// and finally, +export { gBase64 as Base64 }; diff --git a/plugin/js-base64/package.json b/plugin/js-base64/package.json new file mode 100644 index 0000000..477bbc5 --- /dev/null +++ b/plugin/js-base64/package.json @@ -0,0 +1,43 @@ +{ + "name": "js-base64", + "version": "3.7.7", + "description": "Yet another Base64 transcoder in pure-JS", + "main": "base64.js", + "module": "base64.mjs", + "types": "base64.d.ts", + "sideEffects": false, + "files": [ + "base64.js", + "base64.mjs", + "base64.d.ts", + "base64.d.mts" + ], + "exports": { + ".": { + "import": { + "types": "./base64.d.mts", + "default": "./base64.mjs" + }, + "require": { + "types": "./base64.d.ts", + "default": "./base64.js" + } + }, + "./package.json": "./package.json" + }, + "scripts": { + "test": "make clean && make test" + }, + "devDependencies": { + "@types/node": "^20.11.5", + "mocha": "^10.2.0", + "typescript": "^5.3.3" + }, + "repository": "git+https://github.com/dankogai/js-base64.git", + "keywords": [ + "base64", + "binary" + ], + "author": "Dan Kogai", + "license": "BSD-3-Clause" +} diff --git a/plugin/manifest.json b/plugin/manifest.json new file mode 100644 index 0000000..fbee0fc --- /dev/null +++ b/plugin/manifest.json @@ -0,0 +1,45 @@ +{ + "manifest_version": 3, + "name": "Send to Harmony", + "version": "1.0", + "description": "Send selected text to Harmony with a right-click", + "permissions": [ + "contextMenus", + "storage", + "scripting", + "activeTab", + "tabs", + "clipboardRead" + ], + "icons": { + "16": "icons/16.png", + "48": "icons/48.png", + "128": "icons/128.png" + }, + "background": { + "service_worker": "background.js" + }, + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icons/16.png", + "48": "icons/48.png", + "128": "icons/128.png" + }, + "context_menus": [ + { + "id": "sendToHarmony", + "title": "Send to Harmony", + "contexts": ["selection"] + } + ] + }, + "host_permissions": ["*://*/*.pdf", "*://*/*pdf*"], + "content_scripts": [ + { + "matches": ["*://*/*.pdf", "*://*/*pdf*"], + "js": ["content.js"], + "all_frames": true + } + ] +} diff --git a/plugin/popup.html b/plugin/popup.html new file mode 100644 index 0000000..1c85e4f --- /dev/null +++ b/plugin/popup.html @@ -0,0 +1,75 @@ + + + + Send to Harmony + + + +

+ +

Send to Harmony

+

+ Select text you would like to harmonise, right-click, and choose "Send + to Harmony". +

+

+ Harmony will open in a new tab with your items ready to harmonise, vist + other websites to add further items to your harmonisation. +

+ +
+

Recent Imports

+
+
No imports yet
+
+
+
+ + + diff --git a/plugin/popup.js b/plugin/popup.js new file mode 100644 index 0000000..ee06fe9 --- /dev/null +++ b/plugin/popup.js @@ -0,0 +1,65 @@ +// Function to format relative time +function getRelativeTime(timestamp) { + const now = new Date(); + const past = new Date(timestamp); + const diffInSeconds = Math.floor((now - past) / 1000); + + if (diffInSeconds < 60) { + return "just now"; + } else if (diffInSeconds < 3600) { + const minutes = Math.floor(diffInSeconds / 60); + return `${minutes} minute${minutes > 1 ? "s" : ""} ago`; + } else if (diffInSeconds < 86400) { + const hours = Math.floor(diffInSeconds / 3600); + return `${hours} hour${hours > 1 ? "s" : ""} ago`; + } else { + const days = Math.floor(diffInSeconds / 86400); + return `${days} day${days > 1 ? "s" : ""} ago`; + } +} + +// Update history list +function updateHistory() { + chrome.storage.local.get(["history"], function (result) { + const historyList = document.getElementById("historyList"); + const history = result.history || []; + + if (history.length === 0) { + historyList.innerHTML = '
No imports yet
'; + return; + } + + historyList.innerHTML = history + .map( + (item) => ` +
+
${item.text}
+
From: ${item.url}
+
${getRelativeTime(item.timestamp)}
+
+ ` + ) + .join(""); + + // Make history items clickable to reopen in Harmony + const historyItems = historyList.getElementsByClassName("history-item"); + Array.from(historyItems).forEach((item, index) => { + item.style.cursor = "pointer"; + item.addEventListener("click", () => { + // Send message to background script to open URL + chrome.runtime.sendMessage({ + action: "openHarmonyUrl", + url: history[index].harmonyUrl, + }); + // Close the popup + window.close(); + }); + }); + }); +} + +// Update history when popup opens +document.addEventListener("DOMContentLoaded", updateHistory); + +// Update history every minute to refresh relative times +setInterval(updateHistory, 60000); From 552f8fc8a2d0b6f1b8cae7afeedc5c0135cbda1a Mon Sep 17 00:00:00 2001 From: John Rogers Date: Sat, 1 Feb 2025 23:56:48 +0000 Subject: [PATCH 5/5] the pdf copy route was not reliably working on all pdf hosted sites - and was requiring extensive permissions - reworked to bring permissions down significantly and provide instructions for the user to copy and paste (Ctrl-c Ctrl-v) directly into the popup window to submit if the tab has no ID --- plugin/Screenshot 640.png | Bin 0 -> 117833 bytes plugin/background.js | 90 ++++++++++++++------------------------ plugin/content.js | 20 --------- plugin/manifest.json | 20 ++------- plugin/popup.html | 34 ++++++++++++++ plugin/popup.js | 24 ++++++++++ 6 files changed, 94 insertions(+), 94 deletions(-) create mode 100644 plugin/Screenshot 640.png delete mode 100644 plugin/content.js diff --git a/plugin/Screenshot 640.png b/plugin/Screenshot 640.png new file mode 100644 index 0000000000000000000000000000000000000000..4f76bf58e81f65b3ec16f3629baa802a844cc2ce GIT binary patch literal 117833 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ⅆ8SkkAd*j-!T5H$)KlO4`#dfr&nyE=BEa})Z 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 E01T@id;kCd literal 0 HcmV?d00001 diff --git a/plugin/background.js b/plugin/background.js index 9ce29e6..61e00f1 100644 --- a/plugin/background.js +++ b/plugin/background.js @@ -32,6 +32,7 @@ const createHarmonyUrl = ({ questions, instrument_name }) => { // Create context menu item chrome.runtime.onInstalled.addListener(() => { + // Create different menu items for PDFs and regular pages chrome.contextMenus.create({ id: "sendToHarmony", title: "Send to Harmony", @@ -41,22 +42,9 @@ chrome.runtime.onInstalled.addListener(() => { chrome.storage.local.set({ history: [] }); }); -// Function to find or create Harmony tab -async function findOrCreateHarmonyTab(url) { - // First, try to find an existing tab with our target name in the URL - const tabs = await chrome.tabs.query({}); - const harmonyTab = tabs.find( - (tab) => tab.url && tab.url.includes(harmonyURL) - ); - - if (harmonyTab) { - // Update existing tab - await chrome.tabs.update(harmonyTab.id, { url: url, active: true }); - await chrome.windows.update(harmonyTab.windowId, { focused: true }); - } else { - // Create new tab - await chrome.tabs.create({ url: url }); - } +// Function to open Harmony URL in new tab +function openHarmonyTab(url) { + chrome.tabs.create({ url: url }); } // Listen for messages from popup @@ -65,52 +53,40 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { findOrCreateHarmonyTab(request.url); return true; } - if (request.action === "returnCopied") { - findOrCreateHarmonyTab(request.url); + if (request.action === "processPdfText") { + processSelection(request.text, request.tab); return true; } }); -chrome.contextMenus.onClicked.addListener(function (info, tab) { +chrome.contextMenus.onClicked.addListener(async function (info, tab) { if (info.menuItemId === "sendToHarmony") { - if (tab?.id > -1) { - chrome.scripting - .executeScript({ - target: { tabId: tab.id }, - function: () => { - const selection = document.getSelection(); - return selection ? selection.toString() : ""; - }, - }) - .then((resultArray) => { - const result = resultArray[0]; - const selectedText = - result && result && result.result ? result.result : ""; // Handle various result possibilities - processSelection(selectedText, tab); - }) - .catch((error) => { - console.error("Error getting selected text:", error); - }); - } else { - // If tab.id is null (eg in a PDF), trigger the copy command and then read from clipboard - chrome.tabs - .sendMessage({ - action: "copySelection", - }) - .then((response) => { - if (response?.success) { - try { - navigator.clipboard - .readText() - .then((selectedText) => processSelection(selectedText, tab)); - } catch (err) { - console.error("Failed to read clipboard contents: ", err); - } - } - }) - .catch((error) => { - console.error("Error executing copy command:", error); - }); + if (tab?.id === -1 || tab?.url?.toLowerCase().includes("pdf")) { + // For PDF tabs, show popup + chrome.action.openPopup(); + return; + } + + // For non-PDF tabs, use scripting API + try { + const resultArray = await chrome.scripting.executeScript({ + target: { tabId: tab.id }, + function: () => { + const selection = document.getSelection(); + return selection ? selection.toString() : ""; + }, + }); + const selectedText = resultArray[0]?.result || ""; + if (selectedText) { + processSelection(selectedText, tab); + } + } catch (error) { + console.error("Error getting selected text:", error); + chrome.action.setBadgeText({ text: "!" }); + chrome.action.setBadgeBackgroundColor({ color: "#F44336" }); + setTimeout(() => { + chrome.action.setBadgeText({ text: "" }); + }, 2000); } } }); diff --git a/plugin/content.js b/plugin/content.js deleted file mode 100644 index 50d4522..0000000 --- a/plugin/content.js +++ /dev/null @@ -1,20 +0,0 @@ -chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { - if (request.action === "copySelection") { - try { - // Execute the copy command - document.execCommand("copy"); - navigator.clipboard.readText().then((selection) => { - console.log("selectedText", selection); - sendResponse({ - action: "returnCopied", - success: true, - selection: selection, - }); - }); - } catch (error) { - console.error("Error executing copy command:", error); - sendResponse({ success: false, error: error.message }); - } - } - return true; -}); diff --git a/plugin/manifest.json b/plugin/manifest.json index fbee0fc..c549681 100644 --- a/plugin/manifest.json +++ b/plugin/manifest.json @@ -2,15 +2,8 @@ "manifest_version": 3, "name": "Send to Harmony", "version": "1.0", - "description": "Send selected text to Harmony with a right-click", - "permissions": [ - "contextMenus", - "storage", - "scripting", - "activeTab", - "tabs", - "clipboardRead" - ], + "description": "Send selected text to Harmony with a right-click. For PDFs, use the popup to paste your selected text.", + "permissions": ["contextMenus", "storage", "scripting", "activeTab", "tabs"], "icons": { "16": "icons/16.png", "48": "icons/48.png", @@ -34,12 +27,5 @@ } ] }, - "host_permissions": ["*://*/*.pdf", "*://*/*pdf*"], - "content_scripts": [ - { - "matches": ["*://*/*.pdf", "*://*/*pdf*"], - "js": ["content.js"], - "all_frames": true - } - ] + "host_permissions": [] } diff --git a/plugin/popup.html b/plugin/popup.html index 1c85e4f..ac4e106 100644 --- a/plugin/popup.html +++ b/plugin/popup.html @@ -63,6 +63,40 @@

Send to Harmony

other websites to add further items to your harmonisation.

+ +

Recent Imports

diff --git a/plugin/popup.js b/plugin/popup.js index ee06fe9..1ef2f02 100644 --- a/plugin/popup.js +++ b/plugin/popup.js @@ -1,3 +1,27 @@ +// Check if we're dealing with a PDF tab +chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { + const currentTab = tabs[0]; + if (currentTab?.id === -1 || currentTab?.url?.toLowerCase().includes("pdf")) { + document.getElementById("pdfInput").style.display = "block"; + } +}); + +// Handle PDF text submission +document.getElementById("submitPdf").addEventListener("click", function () { + const text = document.getElementById("pdfText").value; + if (text) { + chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { + const currentTab = tabs[0]; + chrome.runtime.sendMessage({ + action: "processPdfText", + text: text, + tab: currentTab, + }); + window.close(); + }); + } +}); + // Function to format relative time function getRelativeTime(timestamp) { const now = new Date();