Skip to content

Instantly share code, notes, and snippets.

@andreubotella
Last active January 27, 2022 13:44
Show Gist options
  • Save andreubotella/2c84ba2a92d004cc2e9c5e8d3692343b to your computer and use it in GitHub Desktop.
Save andreubotella/2c84ba2a92d004cc2e9c5e8d3692343b to your computer and use it in GitHub Desktop.
bbContextMenu details
// If a text field or textarea's contents are selected, Chromium treats the
// document's selection as if it was a caret selection immediately before the
// text field. This function detects that and returns the text field.
function followedByTextField(range) {
if (!range.collapsed) return null;
const node = range.startContainer.childNodes[range.startOffset];
// Only input and textarea elements have the selectionStart property, and it's
// only non-null for text fields.
// Double-equals to match null or undefined.
if (node?.selectionStart == null) {
return null;
} else {
return node;
}
}
// The deepest element that contains the entirety of the given range.
// (`range.commonAncestorContainer` might be a Text node, for example.)
function commonAncestorElement(range) {
let container = range.commonAncestorContainer;
while (!(container instanceof Element)) {
container = container.parentNode;
}
return container;
}
function getBbContextMenuDetails() {
const selection = window.getSelection();
if (selection.rangeCount === 0) {
return {
canCopy: false,
canCut: false,
canPaste: false,
selectedText: "",
};
}
// There is at most one selection, so 0 is the one we want.
const range = selection.getRangeAt(0);
let collapsed, canEdit;
const textField = followedByTextField(range);
if (textField) {
collapsed = textField.selectionStart === textField.selectionEnd;
canEdit = !textField.disabled && !textField.readOnly;
} else {
collapsed = range.collapsed;
canEdit = commonAncestorElement(range).isContentEditable;
}
return {
canCopy: !collapsed,
canCut: !collapsed && canEdit,
canPaste: canEdit,
selectedText: selection.toString(),
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment