mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-22 16:18:08 +02:00
[JS] Handle correctly choice widgets where the display and the export values are different (issue #15815)
This commit is contained in:
parent
64786b4c93
commit
0c1ec946aa
8 changed files with 155 additions and 30 deletions
|
@ -1978,7 +1978,15 @@ class WidgetAnnotation extends Annotation {
|
|||
|
||||
assert(typeof value === "string", "Expected `value` to be a string.");
|
||||
|
||||
value = value.trim();
|
||||
if (!this.data.combo) {
|
||||
value = value.trim();
|
||||
} else {
|
||||
// The value is supposed to be one of the exportValue.
|
||||
const option =
|
||||
this.data.options.find(({ exportValue }) => value === exportValue) ||
|
||||
this.data.options[0];
|
||||
value = (option && option.displayValue) || "";
|
||||
}
|
||||
|
||||
if (value === "") {
|
||||
// the field is empty: nothing to render
|
||||
|
|
|
@ -1612,10 +1612,10 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
selectElement.addEventListener("input", removeEmptyEntry);
|
||||
}
|
||||
|
||||
const getValue = (event, isExport) => {
|
||||
const getValue = isExport => {
|
||||
const name = isExport ? "value" : "textContent";
|
||||
const options = event.target.options;
|
||||
if (!event.target.multiple) {
|
||||
const { options, multiple } = selectElement;
|
||||
if (!multiple) {
|
||||
return options.selectedIndex === -1
|
||||
? null
|
||||
: options[options.selectedIndex][name];
|
||||
|
@ -1625,6 +1625,8 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
.map(option => option[name]);
|
||||
};
|
||||
|
||||
let selectedValues = getValue(/* isExport */ false);
|
||||
|
||||
const getItems = event => {
|
||||
const options = event.target.options;
|
||||
return Array.prototype.map.call(options, option => {
|
||||
|
@ -1643,8 +1645,9 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
option.selected = values.has(option.value);
|
||||
}
|
||||
storage.setValue(id, {
|
||||
value: getValue(event, /* isExport */ true),
|
||||
value: getValue(/* isExport */ true),
|
||||
});
|
||||
selectedValues = getValue(/* isExport */ false);
|
||||
},
|
||||
multipleSelection(event) {
|
||||
selectElement.multiple = true;
|
||||
|
@ -1664,15 +1667,17 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
}
|
||||
}
|
||||
storage.setValue(id, {
|
||||
value: getValue(event, /* isExport */ true),
|
||||
value: getValue(/* isExport */ true),
|
||||
items: getItems(event),
|
||||
});
|
||||
selectedValues = getValue(/* isExport */ false);
|
||||
},
|
||||
clear(event) {
|
||||
while (selectElement.length !== 0) {
|
||||
selectElement.remove(0);
|
||||
}
|
||||
storage.setValue(id, { value: null, items: [] });
|
||||
selectedValues = getValue(/* isExport */ false);
|
||||
},
|
||||
insert(event) {
|
||||
const { index, displayValue, exportValue } = event.detail.insert;
|
||||
|
@ -1687,9 +1692,10 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
selectElement.append(optionElement);
|
||||
}
|
||||
storage.setValue(id, {
|
||||
value: getValue(event, /* isExport */ true),
|
||||
value: getValue(/* isExport */ true),
|
||||
items: getItems(event),
|
||||
});
|
||||
selectedValues = getValue(/* isExport */ false);
|
||||
},
|
||||
items(event) {
|
||||
const { items } = event.detail;
|
||||
|
@ -1707,9 +1713,10 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
selectElement.options[0].selected = true;
|
||||
}
|
||||
storage.setValue(id, {
|
||||
value: getValue(event, /* isExport */ true),
|
||||
value: getValue(/* isExport */ true),
|
||||
items: getItems(event),
|
||||
});
|
||||
selectedValues = getValue(/* isExport */ false);
|
||||
},
|
||||
indices(event) {
|
||||
const indices = new Set(event.detail.indices);
|
||||
|
@ -1717,8 +1724,9 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
option.selected = indices.has(option.index);
|
||||
}
|
||||
storage.setValue(id, {
|
||||
value: getValue(event, /* isExport */ true),
|
||||
value: getValue(/* isExport */ true),
|
||||
});
|
||||
selectedValues = getValue(/* isExport */ false);
|
||||
},
|
||||
editable(event) {
|
||||
event.target.disabled = !event.detail.editable;
|
||||
|
@ -1728,18 +1736,19 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
});
|
||||
|
||||
selectElement.addEventListener("input", event => {
|
||||
const exportValue = getValue(event, /* isExport */ true);
|
||||
const value = getValue(event, /* isExport */ false);
|
||||
const exportValue = getValue(/* isExport */ true);
|
||||
storage.setValue(id, { value: exportValue });
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.linkService.eventBus?.dispatch("dispatcheventinsandbox", {
|
||||
source: this,
|
||||
detail: {
|
||||
id,
|
||||
name: "Keystroke",
|
||||
value,
|
||||
value: selectedValues,
|
||||
changeEx: exportValue,
|
||||
willCommit: true,
|
||||
willCommit: false,
|
||||
commitKey: 1,
|
||||
keyDown: false,
|
||||
},
|
||||
|
@ -1761,7 +1770,7 @@ class ChoiceWidgetAnnotationElement extends WidgetAnnotationElement {
|
|||
);
|
||||
} else {
|
||||
selectElement.addEventListener("input", function (event) {
|
||||
storage.setValue(id, { value: getValue(event, /* isExport */ true) });
|
||||
storage.setValue(id, { value: getValue(/* isExport */ true) });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ class EventDispatcher {
|
|||
case "Keystroke":
|
||||
savedChange = {
|
||||
value: event.value,
|
||||
changeEx: event.changeEx,
|
||||
change: event.change,
|
||||
selStart: event.selStart,
|
||||
selEnd: event.selEnd,
|
||||
|
@ -170,6 +171,16 @@ class EventDispatcher {
|
|||
if (event.willCommit) {
|
||||
this.runValidation(source, event);
|
||||
} else {
|
||||
if (source.obj._isChoice) {
|
||||
source.obj.value = savedChange.changeEx;
|
||||
source.obj._send({
|
||||
id: source.obj._id,
|
||||
siblings: source.obj._siblings,
|
||||
value: source.obj.value,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const value = (source.obj.value = this.mergeChange(event));
|
||||
let selStart, selEnd;
|
||||
if (
|
||||
|
|
|
@ -242,6 +242,11 @@ class Field extends PDFObject {
|
|||
}
|
||||
|
||||
set value(value) {
|
||||
if (this._isChoice) {
|
||||
this._setChoiceValue(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value === "") {
|
||||
this._value = "";
|
||||
} else if (typeof value === "string") {
|
||||
|
@ -260,23 +265,37 @@ class Field extends PDFObject {
|
|||
} else {
|
||||
this._value = value;
|
||||
}
|
||||
if (this._isChoice) {
|
||||
if (this.multipleSelection) {
|
||||
const values = new Set(value);
|
||||
if (Array.isArray(this._currentValueIndices)) {
|
||||
this._currentValueIndices.length = 0;
|
||||
} else {
|
||||
this._currentValueIndices = [];
|
||||
}
|
||||
this._items.forEach(({ displayValue }, i) => {
|
||||
if (values.has(displayValue)) {
|
||||
this._currentValueIndices.push(i);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_setChoiceValue(value) {
|
||||
if (this.multipleSelection) {
|
||||
if (!Array.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
const values = new Set(value);
|
||||
if (Array.isArray(this._currentValueIndices)) {
|
||||
this._currentValueIndices.length = 0;
|
||||
this._value.length = 0;
|
||||
} else {
|
||||
this._currentValueIndices = this._items.findIndex(
|
||||
({ displayValue }) => value === displayValue
|
||||
);
|
||||
this._currentValueIndices = [];
|
||||
this._value = [];
|
||||
}
|
||||
this._items.forEach((item, i) => {
|
||||
if (values.has(item.exportValue)) {
|
||||
this._currentValueIndices.push(i);
|
||||
this._value.push(item.exportValue);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (Array.isArray(value)) {
|
||||
value = value[0];
|
||||
}
|
||||
const index = this._items.findIndex(
|
||||
({ exportValue }) => value === exportValue
|
||||
);
|
||||
if (index !== -1) {
|
||||
this._currentValueIndices = index;
|
||||
this._value = this._items[index].exportValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue