2020-10-01 20:57:23 +09:00
|
|
|
/* Copyright 2020 Mozilla Foundation
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class Event {
|
|
|
|
constructor(data) {
|
|
|
|
this.change = data.change || "";
|
|
|
|
this.changeEx = data.changeEx || null;
|
|
|
|
this.commitKey = data.commitKey || 0;
|
|
|
|
this.fieldFull = data.fieldFull || false;
|
|
|
|
this.keyDown = data.keyDown || false;
|
|
|
|
this.modifier = data.modifier || false;
|
|
|
|
this.name = data.name;
|
|
|
|
this.rc = true;
|
|
|
|
this.richChange = data.richChange || [];
|
|
|
|
this.richChangeEx = data.richChangeEx || [];
|
|
|
|
this.richValue = data.richValue || [];
|
2020-11-04 03:24:07 +09:00
|
|
|
this.selEnd = data.selEnd || -1;
|
|
|
|
this.selStart = data.selStart || -1;
|
2020-10-01 20:57:23 +09:00
|
|
|
this.shift = data.shift || false;
|
|
|
|
this.source = data.source || null;
|
|
|
|
this.target = data.target || null;
|
2020-11-04 03:24:07 +09:00
|
|
|
this.targetName = "";
|
2020-10-01 20:57:23 +09:00
|
|
|
this.type = "Field";
|
2020-11-04 03:24:07 +09:00
|
|
|
this.value = data.value || "";
|
2020-10-01 20:57:23 +09:00
|
|
|
this.willCommit = data.willCommit || false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class EventDispatcher {
|
|
|
|
constructor(document, calculationOrder, objects) {
|
|
|
|
this._document = document;
|
|
|
|
this._calculationOrder = calculationOrder;
|
|
|
|
this._objects = objects;
|
|
|
|
|
|
|
|
this._document.obj._eventDispatcher = this;
|
|
|
|
}
|
|
|
|
|
2020-11-04 03:24:07 +09:00
|
|
|
mergeChange(event) {
|
|
|
|
let value = event.value;
|
|
|
|
if (typeof value !== "string") {
|
|
|
|
value = value.toString();
|
|
|
|
}
|
|
|
|
const prefix =
|
|
|
|
event.selStart >= 0 ? value.substring(0, event.selStart) : "";
|
|
|
|
const postfix =
|
|
|
|
event.selEnd >= 0 && event.selEnd <= value.length
|
|
|
|
? value.substring(event.selEnd)
|
|
|
|
: "";
|
|
|
|
|
|
|
|
return `${prefix}${event.change}${postfix}`;
|
|
|
|
}
|
|
|
|
|
2020-10-01 20:57:23 +09:00
|
|
|
dispatch(baseEvent) {
|
|
|
|
const id = baseEvent.id;
|
|
|
|
if (!(id in this._objects)) {
|
2020-12-08 03:22:14 +09:00
|
|
|
let event;
|
|
|
|
if (id === "doc" || id === "page") {
|
|
|
|
event = globalThis.event = new Event(baseEvent);
|
|
|
|
event.source = event.target = this._document.wrapped;
|
|
|
|
event.name = baseEvent.name;
|
|
|
|
}
|
|
|
|
if (id === "doc") {
|
|
|
|
this._document.obj._dispatchDocEvent(event.name);
|
2021-01-05 23:53:30 +09:00
|
|
|
} else if (id === "page") {
|
2020-12-08 03:22:14 +09:00
|
|
|
this._document.obj._dispatchPageEvent(
|
|
|
|
event.name,
|
2021-01-05 23:53:30 +09:00
|
|
|
baseEvent.actions,
|
2020-12-08 03:22:14 +09:00
|
|
|
baseEvent.pageNumber
|
|
|
|
);
|
|
|
|
}
|
2020-10-01 20:57:23 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-01-24 03:09:26 +09:00
|
|
|
const name = baseEvent.name;
|
2020-10-01 20:57:23 +09:00
|
|
|
const source = this._objects[id];
|
2020-12-08 03:22:14 +09:00
|
|
|
const event = (globalThis.event = new Event(baseEvent));
|
2020-11-04 03:24:07 +09:00
|
|
|
let savedChange;
|
|
|
|
|
|
|
|
if (source.obj._isButton()) {
|
|
|
|
source.obj._id = id;
|
|
|
|
event.value = source.obj._getExportValue(event.value);
|
2020-11-19 02:54:26 +09:00
|
|
|
if (name === "Action") {
|
|
|
|
source.obj._value = event.value;
|
|
|
|
}
|
2020-11-04 03:24:07 +09:00
|
|
|
}
|
|
|
|
|
2021-04-21 02:21:52 +09:00
|
|
|
switch (name) {
|
|
|
|
case "Keystroke":
|
|
|
|
savedChange = {
|
|
|
|
value: event.value,
|
|
|
|
change: event.change,
|
|
|
|
selStart: event.selStart,
|
|
|
|
selEnd: event.selEnd,
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
case "Blur":
|
|
|
|
case "Focus":
|
|
|
|
Object.defineProperty(event, "value", {
|
|
|
|
configurable: false,
|
|
|
|
writable: false,
|
|
|
|
enumerable: true,
|
|
|
|
value: event.value,
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
case "Validate":
|
|
|
|
this.runValidation(source, event);
|
|
|
|
return;
|
|
|
|
case "Action":
|
|
|
|
this.runActions(source, source, event, name);
|
|
|
|
if (this._document.obj.calculate) {
|
|
|
|
this.runCalculate(source, event);
|
|
|
|
}
|
|
|
|
return;
|
2020-11-04 03:24:07 +09:00
|
|
|
}
|
2020-10-01 20:57:23 +09:00
|
|
|
|
|
|
|
this.runActions(source, source, event, name);
|
2020-11-04 03:24:07 +09:00
|
|
|
|
|
|
|
if (name === "Keystroke") {
|
|
|
|
if (event.rc) {
|
|
|
|
if (event.willCommit) {
|
|
|
|
this.runValidation(source, event);
|
|
|
|
} else if (
|
|
|
|
event.change !== savedChange.change ||
|
|
|
|
event.selStart !== savedChange.selStart ||
|
|
|
|
event.selEnd !== savedChange.selEnd
|
|
|
|
) {
|
|
|
|
source.wrapped.value = this.mergeChange(event);
|
|
|
|
}
|
|
|
|
} else if (!event.willCommit) {
|
|
|
|
source.obj._send({
|
|
|
|
id: source.obj._id,
|
|
|
|
value: savedChange.value,
|
|
|
|
selRange: [savedChange.selStart, savedChange.selEnd],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
runValidation(source, event) {
|
|
|
|
const hasRan = this.runActions(source, source, event, "Validate");
|
|
|
|
if (event.rc) {
|
|
|
|
if (hasRan) {
|
|
|
|
source.wrapped.value = event.value;
|
2021-04-21 02:21:52 +09:00
|
|
|
source.wrapped.valueAsString = event.value;
|
2020-11-04 03:24:07 +09:00
|
|
|
} else {
|
|
|
|
source.obj.value = event.value;
|
2021-04-21 02:21:52 +09:00
|
|
|
source.obj.valueAsString = event.value;
|
2020-11-04 03:24:07 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this._document.obj.calculate) {
|
|
|
|
this.runCalculate(source, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
event.value = source.obj.value;
|
|
|
|
this.runActions(source, source, event, "Format");
|
|
|
|
source.wrapped.valueAsString = event.value;
|
2020-10-01 20:57:23 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
runActions(source, target, event, eventName) {
|
|
|
|
event.source = source.wrapped;
|
|
|
|
event.target = target.wrapped;
|
|
|
|
event.name = eventName;
|
2020-11-04 03:24:07 +09:00
|
|
|
event.targetName = target.obj.name;
|
2020-10-01 20:57:23 +09:00
|
|
|
event.rc = true;
|
2020-11-04 03:24:07 +09:00
|
|
|
|
|
|
|
return target.obj._runActions(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
calculateNow() {
|
2020-12-11 00:02:11 +09:00
|
|
|
if (!this._calculationOrder) {
|
2020-11-04 03:24:07 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
const first = this._calculationOrder[0];
|
|
|
|
const source = this._objects[first];
|
2020-12-16 22:04:22 +09:00
|
|
|
globalThis.event = new Event({});
|
2020-12-08 03:22:14 +09:00
|
|
|
this.runCalculate(source, globalThis.event);
|
2020-11-04 03:24:07 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
runCalculate(source, event) {
|
2020-12-11 00:02:11 +09:00
|
|
|
if (!this._calculationOrder) {
|
2020-11-04 03:24:07 +09:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const targetId of this._calculationOrder) {
|
|
|
|
if (!(targetId in this._objects)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-04-21 02:21:52 +09:00
|
|
|
if (!this._document.obj.calculate) {
|
|
|
|
// An action may have changed calculate value.
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-03-31 00:50:35 +09:00
|
|
|
event.value = null;
|
2020-11-04 03:24:07 +09:00
|
|
|
const target = this._objects[targetId];
|
|
|
|
this.runActions(source, target, event, "Calculate");
|
2021-03-31 00:50:35 +09:00
|
|
|
if (!event.rc) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (event.value !== null) {
|
|
|
|
target.wrapped.value = event.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
event.value = target.obj.value;
|
2020-11-04 03:24:07 +09:00
|
|
|
this.runActions(target, target, event, "Validate");
|
|
|
|
if (!event.rc) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-03-31 00:50:35 +09:00
|
|
|
event.value = target.obj.value;
|
2020-11-04 03:24:07 +09:00
|
|
|
this.runActions(target, target, event, "Format");
|
2021-03-31 00:50:35 +09:00
|
|
|
if (event.value !== null) {
|
|
|
|
target.wrapped.valueAsString = event.value;
|
|
|
|
}
|
2020-10-01 20:57:23 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export { Event, EventDispatcher };
|