@khanacademy/perseus 19.1.3 → 19.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/components/graphie.d.ts +9 -1
- package/dist/es/index.js +275 -174
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +289 -158
- package/dist/index.js.map +1 -1
- package/dist/interactive2/interactive-util.d.ts +2 -2
- package/dist/interactive2/movable-point-options.d.ts +5 -4
- package/dist/interactive2/movable.d.ts +98 -2
- package/dist/interactive2/types.d.ts +6 -0
- package/dist/util/graphie.d.ts +6 -1
- package/dist/widgets/expression.d.ts +4 -4
- package/package.json +3 -3
- package/src/components/graphie.tsx +9 -1
- package/src/interactive2/__tests__/movable-mock.ts +43 -30
- package/src/interactive2/interactive-util.test.ts +93 -0
- package/src/interactive2/interactive-util.ts +19 -15
- package/src/interactive2/movable-helper-methods.ts +7 -2
- package/src/interactive2/movable-line.ts +1 -12
- package/src/interactive2/movable-point-options.ts +31 -19
- package/src/interactive2/movable-point.tsx +1 -9
- package/src/interactive2/movable-polygon.ts +1 -9
- package/src/interactive2/movable.test.ts +249 -0
- package/src/interactive2/movable.ts +313 -150
- package/src/interactive2/types.ts +15 -0
- package/src/interactive2.ts +1 -1
- package/src/util/graphie.ts +13 -1
- package/src/util/interactive.ts +4 -2
- package/tsconfig-build.tsbuildinfo +1 -1
package/dist/index.js
CHANGED
|
@@ -3999,18 +3999,23 @@ class FixedToResponsive extends React__namespace.Component {
|
|
|
3999
3999
|
|
|
4000
4000
|
/* Local helper methods. */
|
|
4001
4001
|
|
|
4002
|
-
function getKey(eventName, id) {
|
|
4002
|
+
function getKey$1(eventName, id) {
|
|
4003
4003
|
return eventName + ":" + id;
|
|
4004
4004
|
}
|
|
4005
|
-
function getEventName(key) {
|
|
4005
|
+
function getEventName$1(key) {
|
|
4006
4006
|
return key.split(":")[0];
|
|
4007
4007
|
}
|
|
4008
4008
|
const MovableHelperMethods = {
|
|
4009
4009
|
/**
|
|
4010
4010
|
* Fire an onSomething type event to all functions in listeners
|
|
4011
4011
|
*/
|
|
4012
|
-
_fireEvent: function (listeners
|
|
4013
|
-
|
|
4012
|
+
_fireEvent: function (listeners) {
|
|
4013
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
4014
|
+
args[_key - 1] = arguments[_key];
|
|
4015
|
+
}
|
|
4016
|
+
for (const listener of listeners) {
|
|
4017
|
+
listener.call(this, ...args);
|
|
4018
|
+
}
|
|
4014
4019
|
},
|
|
4015
4020
|
/**
|
|
4016
4021
|
* Combine the array of constraints functions
|
|
@@ -4078,7 +4083,7 @@ const MovableHelperMethods = {
|
|
|
4078
4083
|
|
|
4079
4084
|
// If there's an existing handler, replace it by using its index in
|
|
4080
4085
|
// `this.state[eventName]`; otherwise, add this handler to the end
|
|
4081
|
-
const key = getKey(eventName, id);
|
|
4086
|
+
const key = getKey$1(eventName, id);
|
|
4082
4087
|
const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
|
|
4083
4088
|
this.state[eventName][index] = func;
|
|
4084
4089
|
},
|
|
@@ -4090,7 +4095,7 @@ const MovableHelperMethods = {
|
|
|
4090
4095
|
*/
|
|
4091
4096
|
unlisten: function (eventName, id) {
|
|
4092
4097
|
this._listenerMap = this._listenerMap || {};
|
|
4093
|
-
const key = getKey(eventName, id);
|
|
4098
|
+
const key = getKey$1(eventName, id);
|
|
4094
4099
|
const index = this._listenerMap[key];
|
|
4095
4100
|
if (index !== undefined) {
|
|
4096
4101
|
// Remove handler from list of event handlers and listenerMap
|
|
@@ -4100,7 +4105,7 @@ const MovableHelperMethods = {
|
|
|
4100
4105
|
// Re-index existing events: if they occur after `index`, decrement
|
|
4101
4106
|
const keys = ___default["default"].keys(this._listenerMap);
|
|
4102
4107
|
___default["default"].each(keys, function (key) {
|
|
4103
|
-
if (getEventName(key) === eventName &&
|
|
4108
|
+
if (getEventName$1(key) === eventName &&
|
|
4104
4109
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
4105
4110
|
this._listenerMap[key] > index) {
|
|
4106
4111
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -4148,6 +4153,7 @@ function computeCanUse3dTransform() {
|
|
|
4148
4153
|
// @ts-expect-error - TS2538 - Type 'null' cannot be used as an index type. | TS2538 - Type 'undefined' cannot be used as an index type.
|
|
4149
4154
|
return !!el.style[prefix];
|
|
4150
4155
|
}
|
|
4156
|
+
const FUNCTION_ARRAY_OPTIONS = ["add", "modify", "draw", "remove", "constraints", "onMoveStart", "onMove", "onMoveEnd", "onClick"];
|
|
4151
4157
|
const InteractiveUtil = {
|
|
4152
4158
|
assert: function (isTrue, message) {
|
|
4153
4159
|
if (!isTrue) {
|
|
@@ -4191,21 +4197,16 @@ const InteractiveUtil = {
|
|
|
4191
4197
|
/**
|
|
4192
4198
|
* Convert all function-or-array arguments to arrays of functions
|
|
4193
4199
|
*/
|
|
4194
|
-
normalizeOptions: function (
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
// normalizeOptions once in this.modify
|
|
4200
|
-
const result = ___default["default"].clone(options);
|
|
4201
|
-
___default["default"].each(arrayOptionNames, function (eventName) {
|
|
4202
|
-
const funcOrArray = options[eventName];
|
|
4200
|
+
normalizeOptions: function (options) {
|
|
4201
|
+
const result = {
|
|
4202
|
+
...options
|
|
4203
|
+
};
|
|
4204
|
+
FUNCTION_ARRAY_OPTIONS.forEach(function (eventName) {
|
|
4203
4205
|
// Only propagate values which were set; not present values
|
|
4204
4206
|
// shouldn't be added to options because we'd like them to
|
|
4205
4207
|
// fall through to defaults
|
|
4206
|
-
if (
|
|
4207
|
-
|
|
4208
|
-
result[eventName] = funcArray;
|
|
4208
|
+
if (options[eventName] !== undefined) {
|
|
4209
|
+
result[eventName] = InteractiveUtil.arrayify(options[eventName]);
|
|
4209
4210
|
}
|
|
4210
4211
|
});
|
|
4211
4212
|
return result;
|
|
@@ -8706,6 +8707,9 @@ class Graphie$1 {
|
|
|
8706
8707
|
// TODO(benchristel): xpixels and ypixels are never used by this class, but
|
|
8707
8708
|
// other code reaches in to access them :(
|
|
8708
8709
|
// Refactor to accessor methods that look at this.dimensions.
|
|
8710
|
+
// set by Movables
|
|
8711
|
+
// TODO(benchristel): consider putting this state on the Movable instead of
|
|
8712
|
+
// on the Graphie
|
|
8709
8713
|
constructor(el) {
|
|
8710
8714
|
this.el = el;
|
|
8711
8715
|
$__default["default"](el).css("position", "relative");
|
|
@@ -8717,6 +8721,9 @@ class Graphie$1 {
|
|
|
8717
8721
|
init(options) {
|
|
8718
8722
|
let scale = options.scale || [40, 40];
|
|
8719
8723
|
scale = typeof scale === "number" ? [scale, scale] : scale;
|
|
8724
|
+
|
|
8725
|
+
// TODO(jeremy): This can be removed once we're confident that callers
|
|
8726
|
+
// obey the Typescript types.
|
|
8720
8727
|
if (options.range == null) {
|
|
8721
8728
|
throw new PerseusError("range should be specified in graph init", Errors.Internal);
|
|
8722
8729
|
}
|
|
@@ -9534,6 +9541,11 @@ class Graphie$1 {
|
|
|
9534
9541
|
});
|
|
9535
9542
|
return processed;
|
|
9536
9543
|
}
|
|
9544
|
+
|
|
9545
|
+
// This is a stub that's overridden in interactive.ts
|
|
9546
|
+
getMouseCoord(event) {
|
|
9547
|
+
throw new Error("getMouseCoord is a stub, and is not implemented");
|
|
9548
|
+
}
|
|
9537
9549
|
}
|
|
9538
9550
|
const labelDirections = {
|
|
9539
9551
|
center: [-0.5, -0.5],
|
|
@@ -13742,12 +13754,7 @@ var GraphieClasses = {
|
|
|
13742
13754
|
const normalizeOptions$3 = InteractiveUtil.normalizeOptions;
|
|
13743
13755
|
const assert$8 = InteractiveUtil.assert;
|
|
13744
13756
|
|
|
13745
|
-
//
|
|
13746
|
-
// functions
|
|
13747
|
-
const FUNCTION_ARRAY_OPTIONS$3 = ["add", "modify", "draw", "remove", "onMoveStart", "onMove", "onMoveEnd", "onClick"];
|
|
13748
|
-
|
|
13749
|
-
// Default "props" and "state". Both are added to this.state and
|
|
13750
|
-
// receive magic getter methods (this.isHovering() etc).
|
|
13757
|
+
// Default "props" and "state". Both are added to this.state.
|
|
13751
13758
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
13752
13759
|
// while those in DEFAULT_STATE persist and are not updated.
|
|
13753
13760
|
// Things that the user might want to change should be on "props",
|
|
@@ -13762,28 +13769,27 @@ const DEFAULT_STATE$3 = {
|
|
|
13762
13769
|
isDragging: false,
|
|
13763
13770
|
mouseTarget: null
|
|
13764
13771
|
};
|
|
13765
|
-
|
|
13766
|
-
//
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
13772
|
+
class Movable {
|
|
13773
|
+
// TODO(benchristel): delete _listenerMap; it's unused
|
|
13774
|
+
_listenerMap = {};
|
|
13775
|
+
constructor(graphie, options) {
|
|
13776
|
+
this.graphie = graphie;
|
|
13777
|
+
this.state = {
|
|
13771
13778
|
id: ___default["default"].uniqueId("movable")
|
|
13772
|
-
}
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
return ___default["default"].extend({
|
|
13779
|
+
};
|
|
13780
|
+
this.modify({
|
|
13781
|
+
...DEFAULT_STATE$3,
|
|
13782
|
+
...options
|
|
13783
|
+
});
|
|
13784
|
+
}
|
|
13785
|
+
modify(options) {
|
|
13786
|
+
this.update({
|
|
13787
|
+
...this._createDefaultState(),
|
|
13788
|
+
...options
|
|
13789
|
+
});
|
|
13790
|
+
}
|
|
13791
|
+
_createDefaultState() {
|
|
13792
|
+
return {
|
|
13787
13793
|
id: this.state.id,
|
|
13788
13794
|
add: [],
|
|
13789
13795
|
modify: [],
|
|
@@ -13792,68 +13798,16 @@ ___default["default"].extend(Movable.prototype, {
|
|
|
13792
13798
|
onMoveStart: [],
|
|
13793
13799
|
onMove: [],
|
|
13794
13800
|
onMoveEnd: [],
|
|
13795
|
-
onClick: []
|
|
13796
|
-
|
|
13801
|
+
onClick: [],
|
|
13797
13802
|
// We only update props here, because we want things on state to
|
|
13798
13803
|
// be persistent, and updated appropriately in modify()
|
|
13799
|
-
|
|
13800
|
-
},
|
|
13801
|
-
/**
|
|
13802
|
-
* Resets the object to its state as if it were constructed with
|
|
13803
|
-
* `options` originally. The only state maintained is `state.id`
|
|
13804
|
-
*
|
|
13805
|
-
* Analogous to React.js's replaceProps
|
|
13806
|
-
*/
|
|
13807
|
-
modify: function (options) {
|
|
13808
|
-
this.update(___default["default"].extend({}, this._createDefaultState(), options));
|
|
13809
|
-
},
|
|
13810
|
-
/**
|
|
13811
|
-
* Simulates a mouse grab event on the movable object.
|
|
13812
|
-
*/
|
|
13813
|
-
grab: function (coord) {
|
|
13814
|
-
assert$8(kmath.point.is(coord));
|
|
13815
|
-
const self = this;
|
|
13816
|
-
const graphie = self.graphie;
|
|
13817
|
-
const state = self.state;
|
|
13818
|
-
state.isHovering = true;
|
|
13819
|
-
state.isDragging = true;
|
|
13820
|
-
graphie.isDragging = true;
|
|
13821
|
-
const startMouseCoord = coord;
|
|
13822
|
-
let prevMouseCoord = startMouseCoord;
|
|
13823
|
-
self._fireEvent(state.onMoveStart, startMouseCoord, startMouseCoord);
|
|
13824
|
-
const moveHandler = function (e) {
|
|
13825
|
-
e.preventDefault();
|
|
13826
|
-
const mouseCoord = graphie.getMouseCoord(e);
|
|
13827
|
-
self._fireEvent(state.onMove, mouseCoord, prevMouseCoord);
|
|
13828
|
-
self.draw();
|
|
13829
|
-
prevMouseCoord = mouseCoord;
|
|
13804
|
+
...DEFAULT_PROPS$3
|
|
13830
13805
|
};
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
}
|
|
13837
|
-
state.isHovering = self.state.isMouseOver;
|
|
13838
|
-
state.isDragging = false;
|
|
13839
|
-
graphie.isDragging = false;
|
|
13840
|
-
self._fireEvent(state.onMoveEnd, prevMouseCoord, startMouseCoord);
|
|
13841
|
-
self.draw();
|
|
13842
|
-
};
|
|
13843
|
-
$__default["default"](document).bind("vmousemove", moveHandler);
|
|
13844
|
-
$__default["default"](document).bind("vmouseup", upHandler);
|
|
13845
|
-
},
|
|
13846
|
-
/**
|
|
13847
|
-
* Adjusts constructor parameters without changing previous settings
|
|
13848
|
-
* for any option not specified
|
|
13849
|
-
*
|
|
13850
|
-
* Analogous to React.js's setProps
|
|
13851
|
-
*/
|
|
13852
|
-
update: function (options) {
|
|
13853
|
-
const self = this;
|
|
13854
|
-
const graphie = self.graphie;
|
|
13855
|
-
const prevState = self.cloneState();
|
|
13856
|
-
const state = ___default["default"].extend(self.state, normalizeOptions$3(FUNCTION_ARRAY_OPTIONS$3, options));
|
|
13806
|
+
}
|
|
13807
|
+
update(options) {
|
|
13808
|
+
const graphie = this.graphie;
|
|
13809
|
+
const prevState = this.cloneState();
|
|
13810
|
+
const state = Object.assign(this.state, normalizeOptions$3(options));
|
|
13857
13811
|
|
|
13858
13812
|
// the invisible shape in front of the point that gets mouse events
|
|
13859
13813
|
if (state.mouseTarget && !prevState.mouseTarget) {
|
|
@@ -13865,24 +13819,24 @@ ___default["default"].extend(Movable.prototype, {
|
|
|
13865
13819
|
}
|
|
13866
13820
|
const isMouse = !("ontouchstart" in window);
|
|
13867
13821
|
if (isMouse) {
|
|
13868
|
-
$mouseTarget.on("vmouseover",
|
|
13822
|
+
$mouseTarget.on("vmouseover", () => {
|
|
13869
13823
|
state.isMouseOver = true;
|
|
13870
13824
|
if (!graphie.isDragging) {
|
|
13871
13825
|
state.isHovering = true;
|
|
13872
13826
|
}
|
|
13873
|
-
if (
|
|
13827
|
+
if (this.state.added) {
|
|
13874
13828
|
// Avoid drawing if the point has been removed
|
|
13875
|
-
|
|
13829
|
+
this.draw();
|
|
13876
13830
|
}
|
|
13877
13831
|
});
|
|
13878
|
-
$mouseTarget.on("vmouseout",
|
|
13832
|
+
$mouseTarget.on("vmouseout", () => {
|
|
13879
13833
|
state.isMouseOver = false;
|
|
13880
13834
|
if (!state.isDragging) {
|
|
13881
13835
|
state.isHovering = false;
|
|
13882
13836
|
}
|
|
13883
|
-
if (
|
|
13837
|
+
if (this.state.added) {
|
|
13884
13838
|
// Avoid drawing if the point has been removed
|
|
13885
|
-
|
|
13839
|
+
this.draw();
|
|
13886
13840
|
}
|
|
13887
13841
|
});
|
|
13888
13842
|
}
|
|
@@ -13894,13 +13848,13 @@ ___default["default"].extend(Movable.prototype, {
|
|
|
13894
13848
|
}, {
|
|
13895
13849
|
passive: false
|
|
13896
13850
|
});
|
|
13897
|
-
$mouseTarget.on("vmousedown",
|
|
13851
|
+
$mouseTarget.on("vmousedown", e => {
|
|
13898
13852
|
if (e.which !== 0 && e.which !== 1) {
|
|
13899
13853
|
return;
|
|
13900
13854
|
}
|
|
13901
13855
|
e.preventDefault();
|
|
13902
13856
|
const mouseCoord = graphie.getMouseCoord(e);
|
|
13903
|
-
|
|
13857
|
+
this.grab(mouseCoord);
|
|
13904
13858
|
});
|
|
13905
13859
|
}
|
|
13906
13860
|
if (state.mouseTarget && state.cursor !== undefined) {
|
|
@@ -13917,39 +13871,217 @@ ___default["default"].extend(Movable.prototype, {
|
|
|
13917
13871
|
|
|
13918
13872
|
// Trigger an add event if this hasn't been added before
|
|
13919
13873
|
if (!state.added) {
|
|
13920
|
-
|
|
13874
|
+
// TODO(benchristel): No one seems to handle the modify event. Can
|
|
13875
|
+
// we delete this?
|
|
13876
|
+
// @ts-expect-error - TS2345: Argument of type '{}' is not assignable to parameter of type 'State'.
|
|
13877
|
+
this._fireEvent(state.modify, this.cloneState(), {});
|
|
13921
13878
|
state.added = true;
|
|
13922
13879
|
|
|
13923
13880
|
// Update the state for `added` and in case the add event
|
|
13924
13881
|
// changed it
|
|
13925
|
-
|
|
13882
|
+
this.prevState = this.cloneState();
|
|
13926
13883
|
}
|
|
13927
13884
|
|
|
13928
13885
|
// Trigger a modify event
|
|
13929
|
-
|
|
13930
|
-
}
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13934
|
-
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13886
|
+
this._fireEvent(state.modify, this.cloneState(), this.prevState);
|
|
13887
|
+
}
|
|
13888
|
+
cloneState() {
|
|
13889
|
+
return {
|
|
13890
|
+
...this.state
|
|
13891
|
+
};
|
|
13892
|
+
}
|
|
13893
|
+
|
|
13894
|
+
/**
|
|
13895
|
+
* Fire an onSomething type event to all functions in listeners
|
|
13896
|
+
*/
|
|
13897
|
+
_fireEvent(listeners) {
|
|
13898
|
+
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
13899
|
+
args[_key - 1] = arguments[_key];
|
|
13938
13900
|
}
|
|
13939
|
-
|
|
13901
|
+
if (listeners == null) {
|
|
13902
|
+
return;
|
|
13903
|
+
}
|
|
13904
|
+
for (const listener of listeners) {
|
|
13905
|
+
listener.call(this, ...args);
|
|
13906
|
+
}
|
|
13907
|
+
}
|
|
13908
|
+
|
|
13909
|
+
/**
|
|
13910
|
+
* Call all draw functions, and update our prevState for the next
|
|
13911
|
+
* draw function
|
|
13912
|
+
*/
|
|
13913
|
+
draw() {
|
|
13914
|
+
const currState = this.cloneState();
|
|
13915
|
+
this._fireEvent(this.state.draw, currState, this.prevState);
|
|
13916
|
+
this.prevState = currState;
|
|
13917
|
+
}
|
|
13918
|
+
|
|
13919
|
+
/**
|
|
13920
|
+
* Simulates a mouse grab event on the movable object.
|
|
13921
|
+
*/
|
|
13922
|
+
grab(coord) {
|
|
13923
|
+
assert$8(kmath.point.is(coord));
|
|
13924
|
+
const graphie = this.graphie;
|
|
13925
|
+
const state = this.state;
|
|
13926
|
+
state.isHovering = true;
|
|
13927
|
+
state.isDragging = true;
|
|
13928
|
+
graphie.isDragging = true;
|
|
13929
|
+
const startMouseCoord = coord;
|
|
13930
|
+
let prevMouseCoord = startMouseCoord;
|
|
13931
|
+
this._fireEvent(state.onMoveStart, startMouseCoord, startMouseCoord);
|
|
13932
|
+
const moveHandler = e => {
|
|
13933
|
+
e.preventDefault();
|
|
13934
|
+
const mouseCoord = graphie.getMouseCoord(e);
|
|
13935
|
+
this._fireEvent(state.onMove, mouseCoord, prevMouseCoord);
|
|
13936
|
+
this.draw();
|
|
13937
|
+
prevMouseCoord = mouseCoord;
|
|
13938
|
+
};
|
|
13939
|
+
const upHandler = () => {
|
|
13940
|
+
$__default["default"](document).unbind("vmousemove", moveHandler);
|
|
13941
|
+
$__default["default"](document).unbind("vmouseup", upHandler);
|
|
13942
|
+
if (state.isHovering) {
|
|
13943
|
+
this._fireEvent(state.onClick, prevMouseCoord, startMouseCoord);
|
|
13944
|
+
}
|
|
13945
|
+
state.isHovering = this.state.isMouseOver;
|
|
13946
|
+
state.isDragging = false;
|
|
13947
|
+
graphie.isDragging = false;
|
|
13948
|
+
this._fireEvent(state.onMoveEnd, prevMouseCoord, startMouseCoord);
|
|
13949
|
+
this.draw();
|
|
13950
|
+
};
|
|
13951
|
+
$__default["default"](document).bind("vmousemove", moveHandler);
|
|
13952
|
+
$__default["default"](document).bind("vmouseup", upHandler);
|
|
13953
|
+
}
|
|
13954
|
+
_applyConstraints(current, previous, extraOptions) {
|
|
13955
|
+
let skipRemaining = false;
|
|
13956
|
+
return (this.state.constraints ?? []).reduce((memo, constraint) => {
|
|
13957
|
+
// A move that has been cancelled won't be propagated to later
|
|
13958
|
+
// constraints calls
|
|
13959
|
+
if (memo === false) {
|
|
13960
|
+
return false;
|
|
13961
|
+
}
|
|
13962
|
+
if (skipRemaining) {
|
|
13963
|
+
return memo;
|
|
13964
|
+
}
|
|
13965
|
+
const result = constraint.call(this, memo, previous, {
|
|
13966
|
+
onSkipRemaining: () => {
|
|
13967
|
+
skipRemaining = true;
|
|
13968
|
+
},
|
|
13969
|
+
...extraOptions
|
|
13970
|
+
});
|
|
13971
|
+
if (result === false) {
|
|
13972
|
+
// Returning false cancels the move
|
|
13973
|
+
return false;
|
|
13974
|
+
}
|
|
13975
|
+
if (kmath.point.is(result, 2)) {
|
|
13976
|
+
// Returning a coord from constraints overrides the move
|
|
13977
|
+
return result;
|
|
13978
|
+
}
|
|
13979
|
+
if (result === true || result == null) {
|
|
13980
|
+
// Returning true or undefined allow the move to occur
|
|
13981
|
+
return memo;
|
|
13982
|
+
}
|
|
13983
|
+
// Anything else is an error
|
|
13984
|
+
throw new PerseusError("Constraint returned invalid result: " + result, Errors.Internal);
|
|
13985
|
+
}, current);
|
|
13986
|
+
}
|
|
13987
|
+
|
|
13940
13988
|
// Change z-order to back
|
|
13941
|
-
toBack
|
|
13989
|
+
toBack() {
|
|
13942
13990
|
if (this.state.mouseTarget) {
|
|
13943
13991
|
this.state.mouseTarget.toBack();
|
|
13944
13992
|
}
|
|
13945
|
-
}
|
|
13993
|
+
}
|
|
13994
|
+
|
|
13946
13995
|
// Change z-order to front
|
|
13947
|
-
toFront
|
|
13996
|
+
toFront() {
|
|
13948
13997
|
if (this.state.mouseTarget) {
|
|
13949
13998
|
this.state.mouseTarget.toFront();
|
|
13950
13999
|
}
|
|
13951
14000
|
}
|
|
13952
|
-
|
|
14001
|
+
|
|
14002
|
+
/**
|
|
14003
|
+
* Add a listener to any event: startMove, constraints, onMove, onMoveEnd,
|
|
14004
|
+
* etc. If a listener is already bound to the given eventName and id, then
|
|
14005
|
+
* it is overwritten by func.
|
|
14006
|
+
*
|
|
14007
|
+
* eventName: the string name of the event to listen to. one of:
|
|
14008
|
+
* "onMoveStart", "onMove", "onMoveEnd", "draw", "remove"
|
|
14009
|
+
*
|
|
14010
|
+
* id: a string id that can be used to remove this event at a later time
|
|
14011
|
+
* note: adding multiple listeners with the same id is undefined behavior
|
|
14012
|
+
*
|
|
14013
|
+
* func: the function to call when the event happens, which is called
|
|
14014
|
+
* with the event's standard parameters [usually (coord, prevCoord) or
|
|
14015
|
+
* (state, prevState)]
|
|
14016
|
+
*/
|
|
14017
|
+
listen(eventName, id, func) {
|
|
14018
|
+
this._listenerMap = this._listenerMap || {};
|
|
14019
|
+
|
|
14020
|
+
// If there's an existing handler, replace it by using its index in
|
|
14021
|
+
// `this.state[eventName]`; otherwise, add this handler to the end
|
|
14022
|
+
const key = getKey(eventName, id);
|
|
14023
|
+
const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
|
|
14024
|
+
this.state[eventName][index] = func;
|
|
14025
|
+
}
|
|
14026
|
+
|
|
14027
|
+
/**
|
|
14028
|
+
* Remove a previously added listener, by the id specified in the
|
|
14029
|
+
* corresponding listen() call
|
|
14030
|
+
*
|
|
14031
|
+
* If the given id has not been registered already, this is a no-op
|
|
14032
|
+
*/
|
|
14033
|
+
unlisten(eventName, id) {
|
|
14034
|
+
this._listenerMap = this._listenerMap || {};
|
|
14035
|
+
const key = getKey(eventName, id);
|
|
14036
|
+
const index = this._listenerMap[key];
|
|
14037
|
+
if (index !== undefined) {
|
|
14038
|
+
// Remove handler from list of event handlers and listenerMap
|
|
14039
|
+
this.state[eventName].splice(index, 1);
|
|
14040
|
+
delete this._listenerMap[key];
|
|
14041
|
+
|
|
14042
|
+
// Re-index existing events: if they occur after `index`, decrement
|
|
14043
|
+
const keys = ___default["default"].keys(this._listenerMap);
|
|
14044
|
+
keys.forEach(key => {
|
|
14045
|
+
if (getEventName(key) === eventName && this._listenerMap[key] > index) {
|
|
14046
|
+
this._listenerMap[key]--;
|
|
14047
|
+
}
|
|
14048
|
+
});
|
|
14049
|
+
}
|
|
14050
|
+
}
|
|
14051
|
+
remove() {
|
|
14052
|
+
this.state.added = false;
|
|
14053
|
+
this._fireEvent(this.state.remove);
|
|
14054
|
+
if (this.state.mouseTarget) {
|
|
14055
|
+
$__default["default"](this.state.mouseTarget).off();
|
|
14056
|
+
this.state.mouseTarget.remove();
|
|
14057
|
+
this.state.mouseTarget = null;
|
|
14058
|
+
}
|
|
14059
|
+
}
|
|
14060
|
+
cursor() {
|
|
14061
|
+
return this.state.cursor;
|
|
14062
|
+
}
|
|
14063
|
+
added() {
|
|
14064
|
+
return this.state.added;
|
|
14065
|
+
}
|
|
14066
|
+
isHovering() {
|
|
14067
|
+
return this.state.isHovering;
|
|
14068
|
+
}
|
|
14069
|
+
isMouseOver() {
|
|
14070
|
+
return this.state.isMouseOver;
|
|
14071
|
+
}
|
|
14072
|
+
isDragging() {
|
|
14073
|
+
return this.state.isDragging;
|
|
14074
|
+
}
|
|
14075
|
+
mouseTarget() {
|
|
14076
|
+
return this.state.mouseTarget;
|
|
14077
|
+
}
|
|
14078
|
+
}
|
|
14079
|
+
function getKey(eventName, id) {
|
|
14080
|
+
return eventName + ":" + id;
|
|
14081
|
+
}
|
|
14082
|
+
function getEventName(key) {
|
|
14083
|
+
return key.split(":")[0];
|
|
14084
|
+
}
|
|
13953
14085
|
|
|
13954
14086
|
/* eslint-disable @babel/no-invalid-this */
|
|
13955
14087
|
/**
|
|
@@ -14279,7 +14411,6 @@ var MovableLineOptions = {
|
|
|
14279
14411
|
*/
|
|
14280
14412
|
const assert$7 = InteractiveUtil.assert;
|
|
14281
14413
|
const normalizeOptions$2 = InteractiveUtil.normalizeOptions;
|
|
14282
|
-
const FUNCTION_ARRAY_OPTIONS$2 = ["add", "draw", "remove", "onMoveStart", "constraints", "onMove", "onMoveEnd"];
|
|
14283
14414
|
|
|
14284
14415
|
// Default "props" and "state". Both are added to this.state and
|
|
14285
14416
|
// receive magic getter methods (this.cursor() etc).
|
|
@@ -14332,7 +14463,7 @@ ___default["default"].extend(MovableLine$4.prototype, {
|
|
|
14332
14463
|
_createDefaultState: function () {
|
|
14333
14464
|
return ___default["default"].extend({
|
|
14334
14465
|
id: this.state.id
|
|
14335
|
-
}, normalizeOptions$2(
|
|
14466
|
+
}, normalizeOptions$2(
|
|
14336
14467
|
// Defaults are copied from MovableLineOptions.*.standard
|
|
14337
14468
|
// These defaults are set here instead of DEFAULT_PROPS/STATE
|
|
14338
14469
|
// because they:
|
|
@@ -14359,7 +14490,7 @@ ___default["default"].extend(MovableLine$4.prototype, {
|
|
|
14359
14490
|
update: function (options) {
|
|
14360
14491
|
const self = this;
|
|
14361
14492
|
const graphie = this.graphie;
|
|
14362
|
-
const state = self.state = ___default["default"].extend(self.state, normalizeOptions$2(
|
|
14493
|
+
const state = self.state = ___default["default"].extend(self.state, normalizeOptions$2(options));
|
|
14363
14494
|
|
|
14364
14495
|
// Default things inside the state.normalStyle object, because
|
|
14365
14496
|
// _.extend is not deep.
|
|
@@ -14796,31 +14927,39 @@ const constraints$1 = {
|
|
|
14796
14927
|
snap: function (snap) {
|
|
14797
14928
|
return function (coord) {
|
|
14798
14929
|
if (snap === null) {
|
|
14799
|
-
// NOTE(kevinb): this should probably return
|
|
14930
|
+
// TODO(benchristel), NOTE(kevinb): this should probably return
|
|
14931
|
+
// the original point
|
|
14800
14932
|
return true;
|
|
14801
14933
|
}
|
|
14802
|
-
// @ts-expect-error -
|
|
14803
|
-
|
|
14804
|
-
return kmath.point.roundTo(coord, snap);
|
|
14934
|
+
// @ts-expect-error - TS2339: Property 'snap' does not exist on type 'Graphie'.
|
|
14935
|
+
return kmath.point.roundTo(coord, snap || this.graphie.snap);
|
|
14805
14936
|
};
|
|
14806
14937
|
},
|
|
14807
|
-
bound: function (range, snap,
|
|
14808
|
-
|
|
14809
|
-
if (
|
|
14810
|
-
|
|
14938
|
+
bound: function (range, snap, optionalPaddingPx) {
|
|
14939
|
+
const paddingPx = (() => {
|
|
14940
|
+
if (optionalPaddingPx === undefined) {
|
|
14941
|
+
if (range === undefined) {
|
|
14942
|
+
return 10;
|
|
14943
|
+
} else {
|
|
14944
|
+
return 0;
|
|
14945
|
+
}
|
|
14811
14946
|
} else {
|
|
14812
|
-
|
|
14947
|
+
return optionalPaddingPx;
|
|
14813
14948
|
}
|
|
14814
|
-
}
|
|
14949
|
+
})();
|
|
14815
14950
|
return function (coord, prev, options) {
|
|
14816
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14817
14951
|
const graphie = this.graphie;
|
|
14818
14952
|
range = range || graphie.range;
|
|
14819
14953
|
if (snap === undefined) {
|
|
14954
|
+
// @ts-expect-error - Property 'snap' does not exist on type 'Graphie'.
|
|
14820
14955
|
snap = graphie.snap;
|
|
14821
14956
|
}
|
|
14822
|
-
let lower = graphie.unscalePoint([paddingPx,
|
|
14823
|
-
|
|
14957
|
+
let lower = graphie.unscalePoint([paddingPx,
|
|
14958
|
+
// @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
|
|
14959
|
+
graphie.ypixels - paddingPx]);
|
|
14960
|
+
let upper = graphie.unscalePoint([
|
|
14961
|
+
// @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
|
|
14962
|
+
graphie.xpixels - paddingPx, paddingPx]);
|
|
14824
14963
|
if (snap) {
|
|
14825
14964
|
lower = kmath.point.ceilTo(lower, snap);
|
|
14826
14965
|
upper = kmath.point.floorTo(upper, snap);
|
|
@@ -14867,10 +15006,6 @@ const {
|
|
|
14867
15006
|
processMath
|
|
14868
15007
|
} = Tex$1;
|
|
14869
15008
|
|
|
14870
|
-
// State parameters that should be converted into an array of
|
|
14871
|
-
// functions
|
|
14872
|
-
const FUNCTION_ARRAY_OPTIONS$1 = ___default["default"].keys(MovablePointOptions);
|
|
14873
|
-
|
|
14874
15009
|
// Default "props" and "state". Both are added to this.state and
|
|
14875
15010
|
// receive magic getter methods (this.coord() etc).
|
|
14876
15011
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
@@ -14923,7 +15058,7 @@ ___default["default"].extend(MovablePoint$5.prototype, {
|
|
|
14923
15058
|
_createDefaultState: function () {
|
|
14924
15059
|
return ___default["default"].extend({
|
|
14925
15060
|
id: this.state.id
|
|
14926
|
-
}, normalizeOptions$1(
|
|
15061
|
+
}, normalizeOptions$1(
|
|
14927
15062
|
// Defaults are copied from MovablePointOptions.*.standard
|
|
14928
15063
|
// These defaults are set here instead of DEFAULT_PROPS/STATE
|
|
14929
15064
|
// because they:
|
|
@@ -14996,7 +15131,7 @@ ___default["default"].extend(MovablePoint$5.prototype, {
|
|
|
14996
15131
|
update: function (options) {
|
|
14997
15132
|
const self = this;
|
|
14998
15133
|
const graphie = self.graphie;
|
|
14999
|
-
const state = ___default["default"].extend(self.state, normalizeOptions$1(
|
|
15134
|
+
const state = ___default["default"].extend(self.state, normalizeOptions$1(options));
|
|
15000
15135
|
assert$6(kmath.point.is(state.coord));
|
|
15001
15136
|
|
|
15002
15137
|
// Default things inside the state.normalStyle object, because
|
|
@@ -15603,10 +15738,6 @@ var MovablePolygonOptions = {
|
|
|
15603
15738
|
const assert$5 = InteractiveUtil.assert;
|
|
15604
15739
|
const normalizeOptions = InteractiveUtil.normalizeOptions;
|
|
15605
15740
|
|
|
15606
|
-
// State parameters that should be converted into an array of
|
|
15607
|
-
// functions
|
|
15608
|
-
const FUNCTION_ARRAY_OPTIONS = ___default["default"].keys(MovablePolygonOptions);
|
|
15609
|
-
|
|
15610
15741
|
// Default "props" and "state". Both are added to this.state and
|
|
15611
15742
|
// receive magic getter methods (this.points() etc).
|
|
15612
15743
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
@@ -15666,7 +15797,7 @@ ___default["default"].extend(MovablePolygon.prototype, {
|
|
|
15666
15797
|
_createDefaultState: function () {
|
|
15667
15798
|
return ___default["default"].extend({
|
|
15668
15799
|
id: this.state.id
|
|
15669
|
-
}, normalizeOptions(
|
|
15800
|
+
}, normalizeOptions(
|
|
15670
15801
|
// Defaults are copied from MovablePolygonOptions.*.standard
|
|
15671
15802
|
// These defaults are set here instead of DEFAULT_PROPS/STATE
|
|
15672
15803
|
// because they:
|
|
@@ -15697,7 +15828,7 @@ ___default["default"].extend(MovablePolygon.prototype, {
|
|
|
15697
15828
|
update: function (options) {
|
|
15698
15829
|
const self = this;
|
|
15699
15830
|
const graphie = self.graphie;
|
|
15700
|
-
const state = ___default["default"].extend(self.state, normalizeOptions(
|
|
15831
|
+
const state = ___default["default"].extend(self.state, normalizeOptions(options));
|
|
15701
15832
|
|
|
15702
15833
|
// Default things inside the state.normalStyle object, because
|
|
15703
15834
|
// _.extend is not deep.
|
|
@@ -41615,7 +41746,7 @@ const init = function (options) {
|
|
|
41615
41746
|
|
|
41616
41747
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41617
41748
|
const libName = "@khanacademy/perseus";
|
|
41618
|
-
const libVersion = "19.1.
|
|
41749
|
+
const libVersion = "19.1.5";
|
|
41619
41750
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41620
41751
|
|
|
41621
41752
|
const apiVersion = {
|