logseq / logseq/db-test

Copy/Cut broken in Firefox: XSLTProcessor failure + invalid clipboard-write permission + custom MIME type rejected

Open
#918 0 comments 0 reactions 1 assignee View on GitHub

@RCmerci is already working on this.

Since Aug 7, 2026.

Dominant language
No language data
Stars
28
Forks
2
PR merge metrics
No merged PRs in 30d

Description

### Search first

- [x] I searched and no similar issues were found

### What Happened?

Copy and Cut operations (via keyboard shortcut and context menu) are broken in Firefox.
No content is written to the clipboard, making Paste a no-op after Copy,
and Cut deletes the selection without saving it to the clipboard.

The following errors appear in the browser console:

1. `XSLTProcessor.importStylesheet()` throws `NS_ERROR_FAILURE (0x80600001)`.
Although Logseq has a `parseerror` fallback in the XSLT path, the exception
is uncaught before reaching it.

2. `navigator.permissions.query({ name: 'clipboard-write' })` throws a TypeError
because Firefox does not recognise `'clipboard-write'` as a valid `PermissionName`.
This prevents execution from reaching `clipboard.write()` at all.

3. Even when (2) is bypassed, `clipboard.write()` fails with:
`NotAllowedError: Type 'web application/logseq' not supported for write`
because Firefox rejects non-standard MIME types in `ClipboardItem`.

Firefox has also announced that `XSLTProcessor` will be removed entirely
in a future release: https://github.com/mozilla/standards-positions/issues/1287

**Workaround** (paste into the browser console after page load):

```js
(function () {
// Fix 1: Replace XSLTProcessor with a stub that returns a parseerror document,
// triggering Logseq's own fallback to the raw HTML string.
// Also future-proof against Firefox's planned removal of XSLTProcessor.
window.XSLTProcessor = class {
importStylesheet() {}
transformToDocument() {
return new DOMParser().parseFromString("", "application/xml");
}
};

// Fix 2: Firefox does not recognise 'clipboard-write' as a valid PermissionName.
const _permQuery = navigator.permissions.query.bind(navigator.permissions);
navigator.permissions.query = function (desc) {
if (desc?.name === "clipboard-write" || desc?.name === "clipboard-read")
return Promise.resolve({ state: "granted", onchange: null });
return _permQuery(desc);
};

// Fix 3: Firefox rejects custom MIME types in ClipboardItem; fall back to writeText.
const _write = navigator.clipboard.write.bind(navigator.clipboard);
const _writeText = navigator.clipboard.writeText.bind(navigator.clipboard);

navigator.clipboard.write = async function (items) {
try { return await _write(items); } catch (_) {}

for (const type of ["text/plain", "text/html"]) {
for (const item of items) {
if (!item.types.includes(type)) continue;
try {
const text = await item.getType(type).then(b => b.text());
if (text) return await _writeText(text);
} catch (_) {}
}
}
};
})();
```

With this workaround applied, Copy and Cut work correctly (content is written as `text/plain`).

### Reproduce the Bug

1. Open Logseq DB in Firefox (tested on Firefox 150.0.1).
2. Open any page that contains blocks.
3. Select one or more blocks.
4. Press Ctrl+C (Copy) or use the context menu → Copy.
5. Open a text editor outside Logseq and press Ctrl+V.

→ Nothing is pasted.

Alternatively:
4. Press Ctrl+X (Cut) or use the context menu → Cut.

→ The selection is deleted from Logseq, but nothing is available to paste.

Console errors observed (in order):
- `Uncaught NS_ERROR_FAILURE` at `XSLTProcessor.importStylesheet()` (utils.js)
- `TypeError: 'clipboard-write' is not a valid value for enumeration PermissionName` (util.cljc)

Not reproducible in Chromium-based browsers.

### Expected Behavior

Copy should write the selected block content to the system clipboard so that
it can be pasted both inside Logseq and in external applications.

Cut should do the same and additionally remove the selection from the document.

Both operations work correctly in Chromium. Firefox compatibility requires:

1. Avoiding `XSLTProcessor` (or guarding against its failure/absence), given
that Firefox is deprecating and planning to remove it entirely.
2. Not calling `navigator.permissions.query({ name: 'clipboard-write' })`,
which is not a valid permission name in Firefox.
3. Avoiding non-standard MIME types (e.g. `application/logseq`) in `ClipboardItem`,
and falling back to `text/plain` or `text/html` when `clipboard.write()` fails.

### Screenshots

_No response_

### Files

_No response_

### Browser, Desktop or Mobile Platform Information

Firefox 150.0.1
https://test.logseq.com/ (2026-06-04)

### Additional Context

_No response_

### Are you willing to submit a PR? If you know how to fix the bug.

- [ ] I'm willing to submit a PR (Thank you!)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.