Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions src/page/Components/Editor/Editor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Loader from "../../../shared/Components/Loader.svelte";
import IconButton from "../../../shared/Components/IconButton.svelte";
import Tag from "../../../shared/Components/Tag.svelte";
import {formatDate} from "../../../shared/utils.js";
import {formatDate, downloadToFile} from "../../../shared/utils.js";
import CodeMirror, {cmChanged, cmGetInstance, cmSetSavedCode} from "./CodeMirror.svelte";
import iconDownload from "../../../shared/img/icon-download.svg?raw";
import iconTrash from "../../../shared/img/icon-trash.svg?raw";
Expand Down Expand Up @@ -85,15 +85,7 @@
const discard = () => codemirror.discardChanges();

function download() {
const link = document.createElement("a");
const content = codemirror.getValue();
const filename = activeItem.filename;
link.setAttribute("href", `data:text/plain;charset=utf-8,${encodeURIComponent(content)}`);
link.setAttribute("download", filename);
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
downloadToFile(activeItem.filename, codemirror.getValue());
}

async function update() {
Expand Down
11 changes: 10 additions & 1 deletion src/page/Components/Settings.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script>
import {fade, fly} from "svelte/transition";
import {settings, state, log} from "../store.js";
import {openInBlank} from "../../shared/utils.js";
import IconButton from "../../shared/Components/IconButton.svelte";
import Toggle from "../../shared/Components/Toggle.svelte";
import iconLoader from "../../shared/img/icon-loader.svg?raw";
Expand Down Expand Up @@ -172,7 +173,15 @@
<div class="modal__section">
<div class="modal__title">Information</div>
<p>
Userscripts Safari Version {$settings.version} ({$settings.build})<br><br>You can review the documentation, report bugs and get more information about this extension by visiting <a href="https://github.com/quoid/userscripts">the code repository.</a><br><br>If you enjoy using this extension, please consider <a href="https://apps.apple.com/us/app/userscripts/id1463298887">leaving a review</a> on the App Store or <a href="https://github.com/quoid/userscripts#support">supporting the project</a>.
Userscripts Safari Version {$settings.version} ({$settings.build})
<br><br>
You can review the documentation, report bugs and get more information about this extension by visiting
<button class="link" on:click={() => openInBlank("https://github.com/quoid/userscripts")}>the code repository.</button>
<br><br>
If you enjoy using this extension, please consider
<button class="link" on:click={() => openInBlank("https://geo.itunes.apple.com/app/id1463298887")}>leaving a review</button>
on the App Store or
<button class="link" on:click={() => openInBlank("https://github.com/quoid/userscripts#support")}>supporting the project.</button>
</p>
</div>
</div>
Expand Down
52 changes: 52 additions & 0 deletions src/shared/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,55 @@ export async function openExtensionPage() {
browser.tabs.update(tab.id, {active: true});
browser.windows.update(tab.windowId, {focused: true});
}

// Safari currently does not honor the target attribute of <a> elements in extension contexts
export async function openInBlank(url) {
browser.tabs.create({url});
}

// Safari currently does not honor the download attribute of <a> elements in extension contexts
// Also not support https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/download
export async function downloadToFile(filename, content, type = "text/plain") {
const url = "https://quoid.github.io/userscripts/serve/download.html";
const tab = await browser.tabs.create({url});
const exchange = {filename, content, type};
const exscript = o => {
// make sure executed only once
if (window.US_DOWNLOAD === 1) return; window.US_DOWNLOAD = 1;
window.stop();
document.body.textContent = "Download is starting...";
const a = document.createElement("a");
a.download = o.filename;
a.href = URL.createObjectURL(new Blob([o.content], {type: o.type}));
a.click();
document.body.innerHTML += "<br>The download should have started.<br>";
a.textContent = o.filename;
document.body.append(a);
};
// Safari currently unable to stably executeScript on tab loading status
try {
await browser.tabs.executeScript(tab.id, {
code: `(${exscript})(${JSON.stringify(exchange)});`
});
} catch {
const handleUpdated = async tabId => {
if (tabId !== tab.id) return;
try {
await browser.tabs.executeScript(tabId, {
code: `(${exscript})(${JSON.stringify(exchange)});`
});
console.info(`[${filename}] Download is starting...`);
} catch {
console.info(`[${filename}] Start download failed, retrying...`);
}
};
browser.tabs.onUpdated.addListener(handleUpdated);
// Remove the listener when tab closing
const handleRemoved = tabId => {
if (tabId !== tab.id) return;
browser.tabs.onUpdated.removeListener(handleUpdated);
browser.tabs.onRemoved.removeListener(handleRemoved);
};
browser.tabs.onRemoved.addListener(handleRemoved);
}
}