@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/es/index.js
CHANGED
|
@@ -3975,18 +3975,20 @@ FixedToResponsive.defaultProps = {
|
|
|
3975
3975
|
|
|
3976
3976
|
/* Local helper methods. */
|
|
3977
3977
|
|
|
3978
|
-
function getKey(eventName, id) {
|
|
3978
|
+
function getKey$1(eventName, id) {
|
|
3979
3979
|
return eventName + ":" + id;
|
|
3980
3980
|
}
|
|
3981
|
-
function getEventName(key) {
|
|
3981
|
+
function getEventName$1(key) {
|
|
3982
3982
|
return key.split(":")[0];
|
|
3983
3983
|
}
|
|
3984
3984
|
const MovableHelperMethods = {
|
|
3985
3985
|
/**
|
|
3986
3986
|
* Fire an onSomething type event to all functions in listeners
|
|
3987
3987
|
*/
|
|
3988
|
-
_fireEvent: function (listeners,
|
|
3989
|
-
|
|
3988
|
+
_fireEvent: function (listeners, ...args) {
|
|
3989
|
+
for (const listener of listeners) {
|
|
3990
|
+
listener.call(this, ...args);
|
|
3991
|
+
}
|
|
3990
3992
|
},
|
|
3991
3993
|
/**
|
|
3992
3994
|
* Combine the array of constraints functions
|
|
@@ -4053,7 +4055,7 @@ const MovableHelperMethods = {
|
|
|
4053
4055
|
|
|
4054
4056
|
// If there's an existing handler, replace it by using its index in
|
|
4055
4057
|
// `this.state[eventName]`; otherwise, add this handler to the end
|
|
4056
|
-
const key = getKey(eventName, id);
|
|
4058
|
+
const key = getKey$1(eventName, id);
|
|
4057
4059
|
const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
|
|
4058
4060
|
this.state[eventName][index] = func;
|
|
4059
4061
|
},
|
|
@@ -4065,7 +4067,7 @@ const MovableHelperMethods = {
|
|
|
4065
4067
|
*/
|
|
4066
4068
|
unlisten: function (eventName, id) {
|
|
4067
4069
|
this._listenerMap = this._listenerMap || {};
|
|
4068
|
-
const key = getKey(eventName, id);
|
|
4070
|
+
const key = getKey$1(eventName, id);
|
|
4069
4071
|
const index = this._listenerMap[key];
|
|
4070
4072
|
if (index !== undefined) {
|
|
4071
4073
|
// Remove handler from list of event handlers and listenerMap
|
|
@@ -4075,7 +4077,7 @@ const MovableHelperMethods = {
|
|
|
4075
4077
|
// Re-index existing events: if they occur after `index`, decrement
|
|
4076
4078
|
const keys = _.keys(this._listenerMap);
|
|
4077
4079
|
_.each(keys, function (key) {
|
|
4078
|
-
if (getEventName(key) === eventName &&
|
|
4080
|
+
if (getEventName$1(key) === eventName &&
|
|
4079
4081
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
4080
4082
|
this._listenerMap[key] > index) {
|
|
4081
4083
|
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
@@ -4086,10 +4088,6 @@ const MovableHelperMethods = {
|
|
|
4086
4088
|
}
|
|
4087
4089
|
};
|
|
4088
4090
|
|
|
4089
|
-
/**
|
|
4090
|
-
* Utility functions for writing Interactive2 movablethings
|
|
4091
|
-
*/
|
|
4092
|
-
|
|
4093
4091
|
/**
|
|
4094
4092
|
* Compute the correct vendor-prefixed `transform`.
|
|
4095
4093
|
*/
|
|
@@ -4123,6 +4121,7 @@ function computeCanUse3dTransform() {
|
|
|
4123
4121
|
// @ts-expect-error - TS2538 - Type 'null' cannot be used as an index type. | TS2538 - Type 'undefined' cannot be used as an index type.
|
|
4124
4122
|
return !!el.style[prefix];
|
|
4125
4123
|
}
|
|
4124
|
+
const FUNCTION_ARRAY_OPTIONS = ["add", "modify", "draw", "remove", "constraints", "onMoveStart", "onMove", "onMoveEnd", "onClick"];
|
|
4126
4125
|
const InteractiveUtil = {
|
|
4127
4126
|
assert: function (isTrue, message) {
|
|
4128
4127
|
if (!isTrue) {
|
|
@@ -4166,21 +4165,14 @@ const InteractiveUtil = {
|
|
|
4166
4165
|
/**
|
|
4167
4166
|
* Convert all function-or-array arguments to arrays of functions
|
|
4168
4167
|
*/
|
|
4169
|
-
normalizeOptions: function (
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
// (and maybe be a function on MovableHelperMethods to get access
|
|
4173
|
-
// to this.state), which would also be nicer because we could
|
|
4174
|
-
// normalizeOptions once in this.modify
|
|
4175
|
-
const result = _.clone(options);
|
|
4176
|
-
_.each(arrayOptionNames, function (eventName) {
|
|
4177
|
-
const funcOrArray = options[eventName];
|
|
4168
|
+
normalizeOptions: function (options) {
|
|
4169
|
+
const result = _extends({}, options);
|
|
4170
|
+
FUNCTION_ARRAY_OPTIONS.forEach(function (eventName) {
|
|
4178
4171
|
// Only propagate values which were set; not present values
|
|
4179
4172
|
// shouldn't be added to options because we'd like them to
|
|
4180
4173
|
// fall through to defaults
|
|
4181
|
-
if (
|
|
4182
|
-
|
|
4183
|
-
result[eventName] = funcArray;
|
|
4174
|
+
if (options[eventName] !== undefined) {
|
|
4175
|
+
result[eventName] = InteractiveUtil.arrayify(options[eventName]);
|
|
4184
4176
|
}
|
|
4185
4177
|
});
|
|
4186
4178
|
return result;
|
|
@@ -8713,6 +8705,10 @@ class Graphie$1 {
|
|
|
8713
8705
|
// Refactor to accessor methods that look at this.dimensions.
|
|
8714
8706
|
this.xpixels = void 0;
|
|
8715
8707
|
this.ypixels = void 0;
|
|
8708
|
+
// set by Movables
|
|
8709
|
+
// TODO(benchristel): consider putting this state on the Movable instead of
|
|
8710
|
+
// on the Graphie
|
|
8711
|
+
this.isDragging = void 0;
|
|
8716
8712
|
this.label = (point, text, direction, arg4, arg5) => {
|
|
8717
8713
|
const style = typeof arg4 === "object" ? arg4 : arg5;
|
|
8718
8714
|
const latex = typeof arg4 === "boolean" ? arg4 : true;
|
|
@@ -8873,6 +8869,9 @@ class Graphie$1 {
|
|
|
8873
8869
|
var _options$isMobile;
|
|
8874
8870
|
let scale = options.scale || [40, 40];
|
|
8875
8871
|
scale = typeof scale === "number" ? [scale, scale] : scale;
|
|
8872
|
+
|
|
8873
|
+
// TODO(jeremy): This can be removed once we're confident that callers
|
|
8874
|
+
// obey the Typescript types.
|
|
8876
8875
|
if (options.range == null) {
|
|
8877
8876
|
throw new PerseusError("range should be specified in graph init", Errors.Internal);
|
|
8878
8877
|
}
|
|
@@ -9531,6 +9530,11 @@ class Graphie$1 {
|
|
|
9531
9530
|
});
|
|
9532
9531
|
return processed;
|
|
9533
9532
|
}
|
|
9533
|
+
|
|
9534
|
+
// This is a stub that's overridden in interactive.ts
|
|
9535
|
+
getMouseCoord(event) {
|
|
9536
|
+
throw new Error("getMouseCoord is a stub, and is not implemented");
|
|
9537
|
+
}
|
|
9534
9538
|
}
|
|
9535
9539
|
const labelDirections = {
|
|
9536
9540
|
center: [-0.5, -0.5],
|
|
@@ -13724,26 +13728,10 @@ var GraphieClasses = {
|
|
|
13724
13728
|
createSimpleClass: createSimpleClass
|
|
13725
13729
|
};
|
|
13726
13730
|
|
|
13727
|
-
/**
|
|
13728
|
-
* Movable
|
|
13729
|
-
*
|
|
13730
|
-
* A Movable Something, that sends onMove events based on the
|
|
13731
|
-
* mouse coordinate (graphie unscaled, non-pixel-value) of the
|
|
13732
|
-
* move.
|
|
13733
|
-
*
|
|
13734
|
-
* Other MovableThings should generally have a Movable field, and
|
|
13735
|
-
* let this class handle all of the virtual mouse events, and then
|
|
13736
|
-
* take appropriate action in onMoveStart, onMove, onMoveEnd
|
|
13737
|
-
*/
|
|
13738
13731
|
const normalizeOptions$3 = InteractiveUtil.normalizeOptions;
|
|
13739
13732
|
const assert$8 = InteractiveUtil.assert;
|
|
13740
13733
|
|
|
13741
|
-
//
|
|
13742
|
-
// functions
|
|
13743
|
-
const FUNCTION_ARRAY_OPTIONS$3 = ["add", "modify", "draw", "remove", "onMoveStart", "onMove", "onMoveEnd", "onClick"];
|
|
13744
|
-
|
|
13745
|
-
// Default "props" and "state". Both are added to this.state and
|
|
13746
|
-
// receive magic getter methods (this.isHovering() etc).
|
|
13734
|
+
// Default "props" and "state". Both are added to this.state.
|
|
13747
13735
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
13748
13736
|
// while those in DEFAULT_STATE persist and are not updated.
|
|
13749
13737
|
// Things that the user might want to change should be on "props",
|
|
@@ -13758,28 +13746,24 @@ const DEFAULT_STATE$3 = {
|
|
|
13758
13746
|
isDragging: false,
|
|
13759
13747
|
mouseTarget: null
|
|
13760
13748
|
};
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
|
|
13749
|
+
class Movable {
|
|
13750
|
+
constructor(graphie, options) {
|
|
13751
|
+
this.graphie = void 0;
|
|
13752
|
+
this.state = void 0;
|
|
13753
|
+
this.prevState = void 0;
|
|
13754
|
+
// TODO(benchristel): delete _listenerMap; it's unused
|
|
13755
|
+
this._listenerMap = {};
|
|
13756
|
+
this.graphie = graphie;
|
|
13757
|
+
this.state = {
|
|
13767
13758
|
id: _.uniqueId("movable")
|
|
13768
|
-
}
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
InteractiveUtil.addMovableHelperMethodsTo(Movable);
|
|
13777
|
-
_.extend(Movable.prototype, {
|
|
13778
|
-
cloneState: function () {
|
|
13779
|
-
return _.clone(this.state);
|
|
13780
|
-
},
|
|
13781
|
-
_createDefaultState: function () {
|
|
13782
|
-
return _.extend({
|
|
13759
|
+
};
|
|
13760
|
+
this.modify(_extends({}, DEFAULT_STATE$3, options));
|
|
13761
|
+
}
|
|
13762
|
+
modify(options) {
|
|
13763
|
+
this.update(_extends({}, this._createDefaultState(), options));
|
|
13764
|
+
}
|
|
13765
|
+
_createDefaultState() {
|
|
13766
|
+
return _extends({
|
|
13783
13767
|
id: this.state.id,
|
|
13784
13768
|
add: [],
|
|
13785
13769
|
modify: [],
|
|
@@ -13789,67 +13773,12 @@ _.extend(Movable.prototype, {
|
|
|
13789
13773
|
onMove: [],
|
|
13790
13774
|
onMoveEnd: [],
|
|
13791
13775
|
onClick: []
|
|
13792
|
-
|
|
13793
|
-
// We only update props here, because we want things on state to
|
|
13794
|
-
// be persistent, and updated appropriately in modify()
|
|
13795
13776
|
}, DEFAULT_PROPS$3);
|
|
13796
|
-
}
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
* Analogous to React.js's replaceProps
|
|
13802
|
-
*/
|
|
13803
|
-
modify: function (options) {
|
|
13804
|
-
this.update(_.extend({}, this._createDefaultState(), options));
|
|
13805
|
-
},
|
|
13806
|
-
/**
|
|
13807
|
-
* Simulates a mouse grab event on the movable object.
|
|
13808
|
-
*/
|
|
13809
|
-
grab: function (coord) {
|
|
13810
|
-
assert$8(point.is(coord));
|
|
13811
|
-
const self = this;
|
|
13812
|
-
const graphie = self.graphie;
|
|
13813
|
-
const state = self.state;
|
|
13814
|
-
state.isHovering = true;
|
|
13815
|
-
state.isDragging = true;
|
|
13816
|
-
graphie.isDragging = true;
|
|
13817
|
-
const startMouseCoord = coord;
|
|
13818
|
-
let prevMouseCoord = startMouseCoord;
|
|
13819
|
-
self._fireEvent(state.onMoveStart, startMouseCoord, startMouseCoord);
|
|
13820
|
-
const moveHandler = function moveHandler(e) {
|
|
13821
|
-
e.preventDefault();
|
|
13822
|
-
const mouseCoord = graphie.getMouseCoord(e);
|
|
13823
|
-
self._fireEvent(state.onMove, mouseCoord, prevMouseCoord);
|
|
13824
|
-
self.draw();
|
|
13825
|
-
prevMouseCoord = mouseCoord;
|
|
13826
|
-
};
|
|
13827
|
-
const upHandler = function upHandler(e) {
|
|
13828
|
-
$(document).unbind("vmousemove", moveHandler);
|
|
13829
|
-
$(document).unbind("vmouseup", upHandler);
|
|
13830
|
-
if (state.isHovering) {
|
|
13831
|
-
self._fireEvent(state.onClick, prevMouseCoord, startMouseCoord);
|
|
13832
|
-
}
|
|
13833
|
-
state.isHovering = self.state.isMouseOver;
|
|
13834
|
-
state.isDragging = false;
|
|
13835
|
-
graphie.isDragging = false;
|
|
13836
|
-
self._fireEvent(state.onMoveEnd, prevMouseCoord, startMouseCoord);
|
|
13837
|
-
self.draw();
|
|
13838
|
-
};
|
|
13839
|
-
$(document).bind("vmousemove", moveHandler);
|
|
13840
|
-
$(document).bind("vmouseup", upHandler);
|
|
13841
|
-
},
|
|
13842
|
-
/**
|
|
13843
|
-
* Adjusts constructor parameters without changing previous settings
|
|
13844
|
-
* for any option not specified
|
|
13845
|
-
*
|
|
13846
|
-
* Analogous to React.js's setProps
|
|
13847
|
-
*/
|
|
13848
|
-
update: function (options) {
|
|
13849
|
-
const self = this;
|
|
13850
|
-
const graphie = self.graphie;
|
|
13851
|
-
const prevState = self.cloneState();
|
|
13852
|
-
const state = _.extend(self.state, normalizeOptions$3(FUNCTION_ARRAY_OPTIONS$3, options));
|
|
13777
|
+
}
|
|
13778
|
+
update(options) {
|
|
13779
|
+
const graphie = this.graphie;
|
|
13780
|
+
const prevState = this.cloneState();
|
|
13781
|
+
const state = Object.assign(this.state, normalizeOptions$3(options));
|
|
13853
13782
|
|
|
13854
13783
|
// the invisible shape in front of the point that gets mouse events
|
|
13855
13784
|
if (state.mouseTarget && !prevState.mouseTarget) {
|
|
@@ -13861,24 +13790,24 @@ _.extend(Movable.prototype, {
|
|
|
13861
13790
|
}
|
|
13862
13791
|
const isMouse = !("ontouchstart" in window);
|
|
13863
13792
|
if (isMouse) {
|
|
13864
|
-
$mouseTarget.on("vmouseover",
|
|
13793
|
+
$mouseTarget.on("vmouseover", () => {
|
|
13865
13794
|
state.isMouseOver = true;
|
|
13866
13795
|
if (!graphie.isDragging) {
|
|
13867
13796
|
state.isHovering = true;
|
|
13868
13797
|
}
|
|
13869
|
-
if (
|
|
13798
|
+
if (this.state.added) {
|
|
13870
13799
|
// Avoid drawing if the point has been removed
|
|
13871
|
-
|
|
13800
|
+
this.draw();
|
|
13872
13801
|
}
|
|
13873
13802
|
});
|
|
13874
|
-
$mouseTarget.on("vmouseout",
|
|
13803
|
+
$mouseTarget.on("vmouseout", () => {
|
|
13875
13804
|
state.isMouseOver = false;
|
|
13876
13805
|
if (!state.isDragging) {
|
|
13877
13806
|
state.isHovering = false;
|
|
13878
13807
|
}
|
|
13879
|
-
if (
|
|
13808
|
+
if (this.state.added) {
|
|
13880
13809
|
// Avoid drawing if the point has been removed
|
|
13881
|
-
|
|
13810
|
+
this.draw();
|
|
13882
13811
|
}
|
|
13883
13812
|
});
|
|
13884
13813
|
}
|
|
@@ -13890,13 +13819,13 @@ _.extend(Movable.prototype, {
|
|
|
13890
13819
|
}, {
|
|
13891
13820
|
passive: false
|
|
13892
13821
|
});
|
|
13893
|
-
$mouseTarget.on("vmousedown",
|
|
13822
|
+
$mouseTarget.on("vmousedown", e => {
|
|
13894
13823
|
if (e.which !== 0 && e.which !== 1) {
|
|
13895
13824
|
return;
|
|
13896
13825
|
}
|
|
13897
13826
|
e.preventDefault();
|
|
13898
13827
|
const mouseCoord = graphie.getMouseCoord(e);
|
|
13899
|
-
|
|
13828
|
+
this.grab(mouseCoord);
|
|
13900
13829
|
});
|
|
13901
13830
|
}
|
|
13902
13831
|
if (state.mouseTarget && state.cursor !== undefined) {
|
|
@@ -13913,39 +13842,212 @@ _.extend(Movable.prototype, {
|
|
|
13913
13842
|
|
|
13914
13843
|
// Trigger an add event if this hasn't been added before
|
|
13915
13844
|
if (!state.added) {
|
|
13916
|
-
|
|
13845
|
+
// TODO(benchristel): No one seems to handle the modify event. Can
|
|
13846
|
+
// we delete this?
|
|
13847
|
+
// @ts-expect-error - TS2345: Argument of type '{}' is not assignable to parameter of type 'State'.
|
|
13848
|
+
this._fireEvent(state.modify, this.cloneState(), {});
|
|
13917
13849
|
state.added = true;
|
|
13918
13850
|
|
|
13919
13851
|
// Update the state for `added` and in case the add event
|
|
13920
13852
|
// changed it
|
|
13921
|
-
|
|
13853
|
+
this.prevState = this.cloneState();
|
|
13922
13854
|
}
|
|
13923
13855
|
|
|
13924
13856
|
// Trigger a modify event
|
|
13925
|
-
|
|
13926
|
-
}
|
|
13927
|
-
|
|
13928
|
-
this.state
|
|
13929
|
-
|
|
13930
|
-
|
|
13931
|
-
|
|
13932
|
-
|
|
13933
|
-
|
|
13857
|
+
this._fireEvent(state.modify, this.cloneState(), this.prevState);
|
|
13858
|
+
}
|
|
13859
|
+
cloneState() {
|
|
13860
|
+
return _extends({}, this.state);
|
|
13861
|
+
}
|
|
13862
|
+
|
|
13863
|
+
/**
|
|
13864
|
+
* Fire an onSomething type event to all functions in listeners
|
|
13865
|
+
*/
|
|
13866
|
+
_fireEvent(listeners, ...args) {
|
|
13867
|
+
if (listeners == null) {
|
|
13868
|
+
return;
|
|
13934
13869
|
}
|
|
13935
|
-
|
|
13870
|
+
for (const listener of listeners) {
|
|
13871
|
+
listener.call(this, ...args);
|
|
13872
|
+
}
|
|
13873
|
+
}
|
|
13874
|
+
|
|
13875
|
+
/**
|
|
13876
|
+
* Call all draw functions, and update our prevState for the next
|
|
13877
|
+
* draw function
|
|
13878
|
+
*/
|
|
13879
|
+
draw() {
|
|
13880
|
+
const currState = this.cloneState();
|
|
13881
|
+
this._fireEvent(this.state.draw, currState, this.prevState);
|
|
13882
|
+
this.prevState = currState;
|
|
13883
|
+
}
|
|
13884
|
+
|
|
13885
|
+
/**
|
|
13886
|
+
* Simulates a mouse grab event on the movable object.
|
|
13887
|
+
*/
|
|
13888
|
+
grab(coord) {
|
|
13889
|
+
assert$8(point.is(coord));
|
|
13890
|
+
const graphie = this.graphie;
|
|
13891
|
+
const state = this.state;
|
|
13892
|
+
state.isHovering = true;
|
|
13893
|
+
state.isDragging = true;
|
|
13894
|
+
graphie.isDragging = true;
|
|
13895
|
+
const startMouseCoord = coord;
|
|
13896
|
+
let prevMouseCoord = startMouseCoord;
|
|
13897
|
+
this._fireEvent(state.onMoveStart, startMouseCoord, startMouseCoord);
|
|
13898
|
+
const moveHandler = e => {
|
|
13899
|
+
e.preventDefault();
|
|
13900
|
+
const mouseCoord = graphie.getMouseCoord(e);
|
|
13901
|
+
this._fireEvent(state.onMove, mouseCoord, prevMouseCoord);
|
|
13902
|
+
this.draw();
|
|
13903
|
+
prevMouseCoord = mouseCoord;
|
|
13904
|
+
};
|
|
13905
|
+
const upHandler = () => {
|
|
13906
|
+
$(document).unbind("vmousemove", moveHandler);
|
|
13907
|
+
$(document).unbind("vmouseup", upHandler);
|
|
13908
|
+
if (state.isHovering) {
|
|
13909
|
+
this._fireEvent(state.onClick, prevMouseCoord, startMouseCoord);
|
|
13910
|
+
}
|
|
13911
|
+
state.isHovering = this.state.isMouseOver;
|
|
13912
|
+
state.isDragging = false;
|
|
13913
|
+
graphie.isDragging = false;
|
|
13914
|
+
this._fireEvent(state.onMoveEnd, prevMouseCoord, startMouseCoord);
|
|
13915
|
+
this.draw();
|
|
13916
|
+
};
|
|
13917
|
+
$(document).bind("vmousemove", moveHandler);
|
|
13918
|
+
$(document).bind("vmouseup", upHandler);
|
|
13919
|
+
}
|
|
13920
|
+
_applyConstraints(current, previous, extraOptions) {
|
|
13921
|
+
var _this$state$constrain;
|
|
13922
|
+
let skipRemaining = false;
|
|
13923
|
+
return ((_this$state$constrain = this.state.constraints) != null ? _this$state$constrain : []).reduce((memo, constraint) => {
|
|
13924
|
+
// A move that has been cancelled won't be propagated to later
|
|
13925
|
+
// constraints calls
|
|
13926
|
+
if (memo === false) {
|
|
13927
|
+
return false;
|
|
13928
|
+
}
|
|
13929
|
+
if (skipRemaining) {
|
|
13930
|
+
return memo;
|
|
13931
|
+
}
|
|
13932
|
+
const result = constraint.call(this, memo, previous, _extends({
|
|
13933
|
+
onSkipRemaining: () => {
|
|
13934
|
+
skipRemaining = true;
|
|
13935
|
+
}
|
|
13936
|
+
}, extraOptions));
|
|
13937
|
+
if (result === false) {
|
|
13938
|
+
// Returning false cancels the move
|
|
13939
|
+
return false;
|
|
13940
|
+
}
|
|
13941
|
+
if (point.is(result, 2)) {
|
|
13942
|
+
// Returning a coord from constraints overrides the move
|
|
13943
|
+
return result;
|
|
13944
|
+
}
|
|
13945
|
+
if (result === true || result == null) {
|
|
13946
|
+
// Returning true or undefined allow the move to occur
|
|
13947
|
+
return memo;
|
|
13948
|
+
}
|
|
13949
|
+
// Anything else is an error
|
|
13950
|
+
throw new PerseusError("Constraint returned invalid result: " + result, Errors.Internal);
|
|
13951
|
+
}, current);
|
|
13952
|
+
}
|
|
13953
|
+
|
|
13936
13954
|
// Change z-order to back
|
|
13937
|
-
toBack
|
|
13955
|
+
toBack() {
|
|
13938
13956
|
if (this.state.mouseTarget) {
|
|
13939
13957
|
this.state.mouseTarget.toBack();
|
|
13940
13958
|
}
|
|
13941
|
-
}
|
|
13959
|
+
}
|
|
13960
|
+
|
|
13942
13961
|
// Change z-order to front
|
|
13943
|
-
toFront
|
|
13962
|
+
toFront() {
|
|
13944
13963
|
if (this.state.mouseTarget) {
|
|
13945
13964
|
this.state.mouseTarget.toFront();
|
|
13946
13965
|
}
|
|
13947
13966
|
}
|
|
13948
|
-
|
|
13967
|
+
|
|
13968
|
+
/**
|
|
13969
|
+
* Add a listener to any event: startMove, constraints, onMove, onMoveEnd,
|
|
13970
|
+
* etc. If a listener is already bound to the given eventName and id, then
|
|
13971
|
+
* it is overwritten by func.
|
|
13972
|
+
*
|
|
13973
|
+
* eventName: the string name of the event to listen to. one of:
|
|
13974
|
+
* "onMoveStart", "onMove", "onMoveEnd", "draw", "remove"
|
|
13975
|
+
*
|
|
13976
|
+
* id: a string id that can be used to remove this event at a later time
|
|
13977
|
+
* note: adding multiple listeners with the same id is undefined behavior
|
|
13978
|
+
*
|
|
13979
|
+
* func: the function to call when the event happens, which is called
|
|
13980
|
+
* with the event's standard parameters [usually (coord, prevCoord) or
|
|
13981
|
+
* (state, prevState)]
|
|
13982
|
+
*/
|
|
13983
|
+
listen(eventName, id, func) {
|
|
13984
|
+
this._listenerMap = this._listenerMap || {};
|
|
13985
|
+
|
|
13986
|
+
// If there's an existing handler, replace it by using its index in
|
|
13987
|
+
// `this.state[eventName]`; otherwise, add this handler to the end
|
|
13988
|
+
const key = getKey(eventName, id);
|
|
13989
|
+
const index = this._listenerMap[key] = this._listenerMap[key] || this.state[eventName].length;
|
|
13990
|
+
this.state[eventName][index] = func;
|
|
13991
|
+
}
|
|
13992
|
+
|
|
13993
|
+
/**
|
|
13994
|
+
* Remove a previously added listener, by the id specified in the
|
|
13995
|
+
* corresponding listen() call
|
|
13996
|
+
*
|
|
13997
|
+
* If the given id has not been registered already, this is a no-op
|
|
13998
|
+
*/
|
|
13999
|
+
unlisten(eventName, id) {
|
|
14000
|
+
this._listenerMap = this._listenerMap || {};
|
|
14001
|
+
const key = getKey(eventName, id);
|
|
14002
|
+
const index = this._listenerMap[key];
|
|
14003
|
+
if (index !== undefined) {
|
|
14004
|
+
// Remove handler from list of event handlers and listenerMap
|
|
14005
|
+
this.state[eventName].splice(index, 1);
|
|
14006
|
+
delete this._listenerMap[key];
|
|
14007
|
+
|
|
14008
|
+
// Re-index existing events: if they occur after `index`, decrement
|
|
14009
|
+
const keys = _.keys(this._listenerMap);
|
|
14010
|
+
keys.forEach(key => {
|
|
14011
|
+
if (getEventName(key) === eventName && this._listenerMap[key] > index) {
|
|
14012
|
+
this._listenerMap[key]--;
|
|
14013
|
+
}
|
|
14014
|
+
});
|
|
14015
|
+
}
|
|
14016
|
+
}
|
|
14017
|
+
remove() {
|
|
14018
|
+
this.state.added = false;
|
|
14019
|
+
this._fireEvent(this.state.remove);
|
|
14020
|
+
if (this.state.mouseTarget) {
|
|
14021
|
+
$(this.state.mouseTarget).off();
|
|
14022
|
+
this.state.mouseTarget.remove();
|
|
14023
|
+
this.state.mouseTarget = null;
|
|
14024
|
+
}
|
|
14025
|
+
}
|
|
14026
|
+
cursor() {
|
|
14027
|
+
return this.state.cursor;
|
|
14028
|
+
}
|
|
14029
|
+
added() {
|
|
14030
|
+
return this.state.added;
|
|
14031
|
+
}
|
|
14032
|
+
isHovering() {
|
|
14033
|
+
return this.state.isHovering;
|
|
14034
|
+
}
|
|
14035
|
+
isMouseOver() {
|
|
14036
|
+
return this.state.isMouseOver;
|
|
14037
|
+
}
|
|
14038
|
+
isDragging() {
|
|
14039
|
+
return this.state.isDragging;
|
|
14040
|
+
}
|
|
14041
|
+
mouseTarget() {
|
|
14042
|
+
return this.state.mouseTarget;
|
|
14043
|
+
}
|
|
14044
|
+
}
|
|
14045
|
+
function getKey(eventName, id) {
|
|
14046
|
+
return eventName + ":" + id;
|
|
14047
|
+
}
|
|
14048
|
+
function getEventName(key) {
|
|
14049
|
+
return key.split(":")[0];
|
|
14050
|
+
}
|
|
13949
14051
|
|
|
13950
14052
|
/* eslint-disable @babel/no-invalid-this */
|
|
13951
14053
|
/**
|
|
@@ -14275,7 +14377,6 @@ var MovableLineOptions = {
|
|
|
14275
14377
|
*/
|
|
14276
14378
|
const assert$7 = InteractiveUtil.assert;
|
|
14277
14379
|
const normalizeOptions$2 = InteractiveUtil.normalizeOptions;
|
|
14278
|
-
const FUNCTION_ARRAY_OPTIONS$2 = ["add", "draw", "remove", "onMoveStart", "constraints", "onMove", "onMoveEnd"];
|
|
14279
14380
|
|
|
14280
14381
|
// Default "props" and "state". Both are added to this.state and
|
|
14281
14382
|
// receive magic getter methods (this.cursor() etc).
|
|
@@ -14328,7 +14429,7 @@ _.extend(MovableLine$4.prototype, {
|
|
|
14328
14429
|
_createDefaultState: function () {
|
|
14329
14430
|
return _.extend({
|
|
14330
14431
|
id: this.state.id
|
|
14331
|
-
}, normalizeOptions$2(
|
|
14432
|
+
}, normalizeOptions$2(
|
|
14332
14433
|
// Defaults are copied from MovableLineOptions.*.standard
|
|
14333
14434
|
// These defaults are set here instead of DEFAULT_PROPS/STATE
|
|
14334
14435
|
// because they:
|
|
@@ -14355,7 +14456,7 @@ _.extend(MovableLine$4.prototype, {
|
|
|
14355
14456
|
update: function (options) {
|
|
14356
14457
|
const self = this;
|
|
14357
14458
|
const graphie = this.graphie;
|
|
14358
|
-
const state = self.state = _.extend(self.state, normalizeOptions$2(
|
|
14459
|
+
const state = self.state = _.extend(self.state, normalizeOptions$2(options));
|
|
14359
14460
|
|
|
14360
14461
|
// Default things inside the state.normalStyle object, because
|
|
14361
14462
|
// _.extend is not deep.
|
|
@@ -14788,31 +14889,39 @@ const constraints$1 = {
|
|
|
14788
14889
|
snap: function (snap) {
|
|
14789
14890
|
return function (coord) {
|
|
14790
14891
|
if (snap === null) {
|
|
14791
|
-
// NOTE(kevinb): this should probably return
|
|
14892
|
+
// TODO(benchristel), NOTE(kevinb): this should probably return
|
|
14893
|
+
// the original point
|
|
14792
14894
|
return true;
|
|
14793
14895
|
}
|
|
14794
|
-
// @ts-expect-error -
|
|
14795
|
-
|
|
14796
|
-
return point.roundTo(coord, snap);
|
|
14896
|
+
// @ts-expect-error - TS2339: Property 'snap' does not exist on type 'Graphie'.
|
|
14897
|
+
return point.roundTo(coord, snap || this.graphie.snap);
|
|
14797
14898
|
};
|
|
14798
14899
|
},
|
|
14799
|
-
bound: function (range, snap,
|
|
14800
|
-
|
|
14801
|
-
if (
|
|
14802
|
-
|
|
14900
|
+
bound: function (range, snap, optionalPaddingPx) {
|
|
14901
|
+
const paddingPx = (() => {
|
|
14902
|
+
if (optionalPaddingPx === undefined) {
|
|
14903
|
+
if (range === undefined) {
|
|
14904
|
+
return 10;
|
|
14905
|
+
} else {
|
|
14906
|
+
return 0;
|
|
14907
|
+
}
|
|
14803
14908
|
} else {
|
|
14804
|
-
|
|
14909
|
+
return optionalPaddingPx;
|
|
14805
14910
|
}
|
|
14806
|
-
}
|
|
14911
|
+
})();
|
|
14807
14912
|
return function (coord, prev, options) {
|
|
14808
|
-
// @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
|
|
14809
14913
|
const graphie = this.graphie;
|
|
14810
14914
|
range = range || graphie.range;
|
|
14811
14915
|
if (snap === undefined) {
|
|
14916
|
+
// @ts-expect-error - Property 'snap' does not exist on type 'Graphie'.
|
|
14812
14917
|
snap = graphie.snap;
|
|
14813
14918
|
}
|
|
14814
|
-
let lower = graphie.unscalePoint([paddingPx,
|
|
14815
|
-
|
|
14919
|
+
let lower = graphie.unscalePoint([paddingPx,
|
|
14920
|
+
// @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
|
|
14921
|
+
graphie.ypixels - paddingPx]);
|
|
14922
|
+
let upper = graphie.unscalePoint([
|
|
14923
|
+
// @ts-expect-error - 'graphie.ypixels' is possibly 'undefined'.
|
|
14924
|
+
graphie.xpixels - paddingPx, paddingPx]);
|
|
14816
14925
|
if (snap) {
|
|
14817
14926
|
lower = point.ceilTo(lower, snap);
|
|
14818
14927
|
upper = point.floorTo(upper, snap);
|
|
@@ -14859,10 +14968,6 @@ const {
|
|
|
14859
14968
|
processMath
|
|
14860
14969
|
} = Tex$1;
|
|
14861
14970
|
|
|
14862
|
-
// State parameters that should be converted into an array of
|
|
14863
|
-
// functions
|
|
14864
|
-
const FUNCTION_ARRAY_OPTIONS$1 = _.keys(MovablePointOptions);
|
|
14865
|
-
|
|
14866
14971
|
// Default "props" and "state". Both are added to this.state and
|
|
14867
14972
|
// receive magic getter methods (this.coord() etc).
|
|
14868
14973
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
@@ -14915,7 +15020,7 @@ _.extend(MovablePoint$5.prototype, {
|
|
|
14915
15020
|
_createDefaultState: function () {
|
|
14916
15021
|
return _.extend({
|
|
14917
15022
|
id: this.state.id
|
|
14918
|
-
}, normalizeOptions$1(
|
|
15023
|
+
}, normalizeOptions$1(
|
|
14919
15024
|
// Defaults are copied from MovablePointOptions.*.standard
|
|
14920
15025
|
// These defaults are set here instead of DEFAULT_PROPS/STATE
|
|
14921
15026
|
// because they:
|
|
@@ -14988,7 +15093,7 @@ _.extend(MovablePoint$5.prototype, {
|
|
|
14988
15093
|
update: function (options) {
|
|
14989
15094
|
const self = this;
|
|
14990
15095
|
const graphie = self.graphie;
|
|
14991
|
-
const state = _.extend(self.state, normalizeOptions$1(
|
|
15096
|
+
const state = _.extend(self.state, normalizeOptions$1(options));
|
|
14992
15097
|
assert$6(point.is(state.coord));
|
|
14993
15098
|
|
|
14994
15099
|
// Default things inside the state.normalStyle object, because
|
|
@@ -15595,10 +15700,6 @@ var MovablePolygonOptions = {
|
|
|
15595
15700
|
const assert$5 = InteractiveUtil.assert;
|
|
15596
15701
|
const normalizeOptions = InteractiveUtil.normalizeOptions;
|
|
15597
15702
|
|
|
15598
|
-
// State parameters that should be converted into an array of
|
|
15599
|
-
// functions
|
|
15600
|
-
const FUNCTION_ARRAY_OPTIONS = _.keys(MovablePolygonOptions);
|
|
15601
|
-
|
|
15602
15703
|
// Default "props" and "state". Both are added to this.state and
|
|
15603
15704
|
// receive magic getter methods (this.points() etc).
|
|
15604
15705
|
// However, properties in DEFAULT_PROPS are updated on `modify()`,
|
|
@@ -15658,7 +15759,7 @@ _.extend(MovablePolygon.prototype, {
|
|
|
15658
15759
|
_createDefaultState: function () {
|
|
15659
15760
|
return _.extend({
|
|
15660
15761
|
id: this.state.id
|
|
15661
|
-
}, normalizeOptions(
|
|
15762
|
+
}, normalizeOptions(
|
|
15662
15763
|
// Defaults are copied from MovablePolygonOptions.*.standard
|
|
15663
15764
|
// These defaults are set here instead of DEFAULT_PROPS/STATE
|
|
15664
15765
|
// because they:
|
|
@@ -15689,7 +15790,7 @@ _.extend(MovablePolygon.prototype, {
|
|
|
15689
15790
|
update: function (options) {
|
|
15690
15791
|
const self = this;
|
|
15691
15792
|
const graphie = self.graphie;
|
|
15692
|
-
const state = _.extend(self.state, normalizeOptions(
|
|
15793
|
+
const state = _.extend(self.state, normalizeOptions(options));
|
|
15693
15794
|
|
|
15694
15795
|
// Default things inside the state.normalStyle object, because
|
|
15695
15796
|
// _.extend is not deep.
|
|
@@ -41499,7 +41600,7 @@ const init = function init(options) {
|
|
|
41499
41600
|
|
|
41500
41601
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
41501
41602
|
const libName = "@khanacademy/perseus";
|
|
41502
|
-
const libVersion = "19.1.
|
|
41603
|
+
const libVersion = "19.1.5";
|
|
41503
41604
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
41504
41605
|
|
|
41505
41606
|
const apiVersion = {
|