editable-text: Make dropping text work when field is unfocused (#3730)
This commit is contained in:
parent
5489b6cc4b
commit
c31a40c749
3 changed files with 52 additions and 8 deletions
|
@ -114,9 +114,13 @@
|
||||||
|
|
||||||
let abstract = this.item.getField('abstractNote');
|
let abstract = this.item.getField('abstractNote');
|
||||||
this._section.summary = abstract;
|
this._section.summary = abstract;
|
||||||
if (!this._abstractField.initialValue || this._abstractField.initialValue !== abstract) {
|
// If focused, update the value that will be restored on Escape;
|
||||||
|
// otherwise, update the displayed value
|
||||||
|
if (this._abstractField.focused) {
|
||||||
|
this._abstractField.initialValue = abstract;
|
||||||
|
}
|
||||||
|
else {
|
||||||
this._abstractField.value = abstract;
|
this._abstractField.value = abstract;
|
||||||
this._abstractField.initialValue = '';
|
|
||||||
}
|
}
|
||||||
this._abstractField.readOnly = this._mode == 'view';
|
this._abstractField.readOnly = this._mode == 'view';
|
||||||
this._abstractField.setAttribute('aria-label', Zotero.ItemFields.getLocalizedString('abstractNote'));
|
this._abstractField.setAttribute('aria-label', Zotero.ItemFields.getLocalizedString('abstractNote'));
|
||||||
|
|
|
@ -109,11 +109,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
get initialValue() {
|
get initialValue() {
|
||||||
return this._input?.dataset.initialValue || '';
|
return this._input?.dataset.initialValue ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
set initialValue(initialValue) {
|
set initialValue(initialValue) {
|
||||||
this._input.dataset.initialValue = initialValue || '';
|
this._input.dataset.initialValue = initialValue ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
get autocomplete() {
|
get autocomplete() {
|
||||||
|
@ -204,7 +204,7 @@
|
||||||
input.addEventListener('change', handleChange);
|
input.addEventListener('change', handleChange);
|
||||||
input.addEventListener('focus', () => {
|
input.addEventListener('focus', () => {
|
||||||
// If the last blur was ignored because it was caused by the window becoming inactive,
|
// If the last blur was ignored because it was caused by the window becoming inactive,
|
||||||
// ignore this focus event as well, so we don't reset initialValue
|
// ignore this focus event as well
|
||||||
if (this._ignoredWindowInactiveBlur) {
|
if (this._ignoredWindowInactiveBlur) {
|
||||||
this._ignoredWindowInactiveBlur = false;
|
this._ignoredWindowInactiveBlur = false;
|
||||||
return;
|
return;
|
||||||
|
@ -216,7 +216,9 @@
|
||||||
if (!this.getAttribute("mousedown")) {
|
if (!this.getAttribute("mousedown")) {
|
||||||
this._input.setSelectionRange(0, this._input.value.length, "backward");
|
this._input.setSelectionRange(0, this._input.value.length, "backward");
|
||||||
}
|
}
|
||||||
this._input.dataset.initialValue = this._input.value;
|
if (!('initialValue' in this._input.dataset)) {
|
||||||
|
this._input.dataset.initialValue = this._input.value;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
input.addEventListener('blur', () => {
|
input.addEventListener('blur', () => {
|
||||||
// Ignore this blur if it was caused by the window becoming inactive (see above)
|
// Ignore this blur if it was caused by the window becoming inactive (see above)
|
||||||
|
@ -255,6 +257,31 @@
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
input.addEventListener('dragover', (event) => {
|
||||||
|
// If the input is not focused, override the default drop behavior
|
||||||
|
if ((document.activeElement !== this._input || Services.focus.activeWindow !== window)
|
||||||
|
&& event.dataTransfer.getData('text/plain')) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
input.addEventListener('drop', (event) => {
|
||||||
|
let text = event.dataTransfer.getData('text/plain');
|
||||||
|
// If the input is not focused, replace its entire value with the dropped text
|
||||||
|
// Otherwise, the normal drop effect takes place and the text is inserted at the cursor
|
||||||
|
if ((document.activeElement !== this._input || Services.focus.activeWindow !== window)
|
||||||
|
&& text) {
|
||||||
|
event.preventDefault();
|
||||||
|
document.activeElement?.blur();
|
||||||
|
// Wait a tick to work around an apparent Firefox bug where the cursor stays inside the old
|
||||||
|
// input even though the new input becomes visually focused
|
||||||
|
setTimeout(() => {
|
||||||
|
this.focus();
|
||||||
|
this._input.value = text;
|
||||||
|
handleInput();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let focused = false;
|
let focused = false;
|
||||||
let selectionStart = this._input?.selectionStart;
|
let selectionStart = this._input?.selectionStart;
|
||||||
|
@ -340,12 +367,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
focus(options) {
|
focus(options) {
|
||||||
|
// If the window isn't active, the focus event won't fire yet,
|
||||||
|
// so store the initial value now
|
||||||
|
if (this._input && Services.focus.activeWindow !== window && !('initialValue' in this._input.dataset)) {
|
||||||
|
this._input.dataset.initialValue = this._input.value;
|
||||||
|
}
|
||||||
this._input?.focus(options);
|
this._input?.focus(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
blur() {
|
blur() {
|
||||||
this._input?.blur();
|
this._input?.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get focused() {
|
||||||
|
return this._input && document.activeElement === this._input;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
customElements.define("editable-text", EditableText);
|
customElements.define("editable-text", EditableText);
|
||||||
|
|
||||||
|
|
|
@ -142,9 +142,13 @@
|
||||||
this._titleFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(this.item.itemTypeID, 'title');
|
this._titleFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(this.item.itemTypeID, 'title');
|
||||||
|
|
||||||
let title = this.item.getField(this._titleFieldID);
|
let title = this.item.getField(this._titleFieldID);
|
||||||
if (!this.titleField.initialValue || this.titleField.initialValue !== title) {
|
// If focused, update the value that will be restored on Escape;
|
||||||
|
// otherwise, update the displayed value
|
||||||
|
if (this.titleField.focused) {
|
||||||
|
this.titleField.initialValue = title;
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.titleField.value = title;
|
this.titleField.value = title;
|
||||||
this.titleField.initialValue = '';
|
|
||||||
}
|
}
|
||||||
this.titleField.readOnly = this._mode == 'view';
|
this.titleField.readOnly = this._mode == 'view';
|
||||||
if (this._titleFieldID) {
|
if (this._titleFieldID) {
|
||||||
|
|
Loading…
Reference in a new issue