jsxgraph 1.4.1 → 1.4.4

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/src/base/board.js CHANGED
@@ -816,8 +816,12 @@ define([
816
816
  */
817
817
  getCoordsTopLeftCorner: function () {
818
818
  var cPos, doc, crect,
819
- docElement = this.document.documentElement || this.document.body.parentNode,
820
- docBody = this.document.body,
819
+ // In ownerDoc we need the "real" document object.
820
+ // The first version is used in the case of shadowDom,
821
+ // the second case in the "normal" case.
822
+ ownerDoc = this.document.ownerDocument || this.document,
823
+ docElement = ownerDoc.documentElement || this.document.body.parentNode,
824
+ docBody = ownerDoc.body,
821
825
  container = this.containerObj,
822
826
  // viewport, content,
823
827
  zoom, o;
@@ -1664,7 +1668,7 @@ define([
1664
1668
  },
1665
1669
 
1666
1670
  addKeyboardEventHandlers: function() {
1667
- if (!this.hasKeyboardHandlers && Env.isBrowser) {
1671
+ if (this.attr.keyboard.enabled && !this.hasKeyboardHandlers && Env.isBrowser) {
1668
1672
  Env.addEvent(this.containerObj, 'keydown', this.keyDownListener, this);
1669
1673
  Env.addEvent(this.containerObj, 'focusin', this.keyFocusInListener, this);
1670
1674
  Env.addEvent(this.containerObj, 'focusout', this.keyFocusOutListener, this);
@@ -2417,10 +2421,14 @@ define([
2417
2421
  }
2418
2422
  }
2419
2423
 
2424
+ this.originMoveEnd();
2425
+ this.update();
2426
+
2420
2427
  // selection
2421
2428
  if (this.selectingMode) {
2422
2429
  this._stopSelecting(evt);
2423
2430
  this.triggerEventHandlers(['touchstopselecting', 'pointerstopselecting', 'stopselecting'], [evt]);
2431
+ this.stopSelectionMode();
2424
2432
  } else {
2425
2433
  for (i = this.downObjects.length - 1; i > -1; i--) {
2426
2434
  found = false;
@@ -2431,32 +2439,30 @@ define([
2431
2439
  }
2432
2440
  if (!found) {
2433
2441
  this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
2434
- this.downObjects[i].snapToGrid();
2435
- this.downObjects[i].snapToPoints();
2442
+ // this.downObjects[i].snapToGrid();
2443
+ // this.downObjects[i].snapToPoints();
2436
2444
  this.downObjects.splice(i, 1);
2437
2445
  }
2438
2446
  }
2439
2447
  }
2440
2448
 
2441
- // this._pointerRemoveTouches(evt);
2442
- // if (this._board_touches.length === 0) {
2443
- if (this.hasPointerUp) {
2444
- if (window.navigator.msPointerEnabled) { // IE10-
2445
- Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);
2446
- } else {
2447
- Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
2448
- Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
2449
- }
2450
- this.hasPointerUp = false;
2449
+ if (this.hasPointerUp) {
2450
+ if (window.navigator.msPointerEnabled) { // IE10-
2451
+ Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);
2452
+ } else {
2453
+ Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
2454
+ Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
2451
2455
  }
2456
+ this.hasPointerUp = false;
2457
+ }
2452
2458
 
2453
- // this.dehighlightAll();
2454
- // this.updateQuality = this.BOARD_QUALITY_HIGH;
2455
- // this.mode = this.BOARD_MODE_NONE;
2459
+ // this.dehighlightAll();
2460
+ // this.updateQuality = this.BOARD_QUALITY_HIGH;
2461
+ // this.mode = this.BOARD_MODE_NONE;
2462
+
2463
+ // this.originMoveEnd();
2464
+ // this.update();
2456
2465
 
2457
- this.originMoveEnd();
2458
- this.update();
2459
- // }
2460
2466
  // After one finger leaves the screen the gesture is stopped.
2461
2467
  this._pointerClearTouches();
2462
2468
  return true;
@@ -2591,7 +2597,7 @@ define([
2591
2597
  obj.type === Const.OBJECT_TYPE_TICKS ||
2592
2598
  obj.type === Const.OBJECT_TYPE_IMAGE) {
2593
2599
  // It's a point, so it's single touch, so we just push it to our touches
2594
- targets = [obj];
2600
+ targets = [target];
2595
2601
 
2596
2602
  // For the UNDO/REDO of object moves
2597
2603
  this.saveStartPos(obj, targets[0]);
@@ -2799,6 +2805,7 @@ define([
2799
2805
  if (this.selectingMode) {
2800
2806
  this._stopSelecting(evt);
2801
2807
  this.triggerEventHandlers(['touchstopselecting', 'stopselecting'], [evt]);
2808
+ this.stopSelectionMode();
2802
2809
  } else if (evtTouches && evtTouches.length > 0) {
2803
2810
  for (i = 0; i < this.touches.length; i++) {
2804
2811
  tmpTouches[i] = this.touches[i];
@@ -2890,8 +2897,8 @@ define([
2890
2897
  }
2891
2898
  if (!found) {
2892
2899
  this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
2893
- this.downObjects[i].snapToGrid();
2894
- this.downObjects[i].snapToPoints();
2900
+ // this.downObjects[i].snapToGrid();
2901
+ // this.downObjects[i].snapToPoints();
2895
2902
  this.downObjects.splice(i, 1);
2896
2903
  }
2897
2904
  }
@@ -3054,11 +3061,11 @@ define([
3054
3061
  // redraw with high precision
3055
3062
  this.updateQuality = this.BOARD_QUALITY_HIGH;
3056
3063
 
3057
- if (this.mouse && this.mouse.obj) {
3058
- // The parameter is needed for lines with snapToGrid enabled
3059
- this.mouse.obj.snapToGrid(this.mouse.targets[0]);
3060
- this.mouse.obj.snapToPoints();
3061
- }
3064
+ // if (this.mouse && this.mouse.obj) {
3065
+ // // The parameter is needed for lines with snapToGrid enabled
3066
+ // this.mouse.obj.snapToGrid(this.mouse.targets[0]);
3067
+ // this.mouse.obj.snapToPoints();
3068
+ // }
3062
3069
 
3063
3070
  this.originMoveEnd();
3064
3071
  this.dehighlightAll();
@@ -3068,6 +3075,7 @@ define([
3068
3075
  if (this.selectingMode) {
3069
3076
  this._stopSelecting(evt);
3070
3077
  this.triggerEventHandlers(['mousestopselecting', 'stopselecting'], [evt]);
3078
+ this.stopSelectionMode();
3071
3079
  } else {
3072
3080
  for (i = 0; i < this.downObjects.length; i++) {
3073
3081
  this.downObjects[i].triggerEventHandlers(['mouseup', 'up'], [evt]);
@@ -3136,6 +3144,7 @@ define([
3136
3144
  dx = Type.evaluate(this.attr.keyboard.dx) / this.unitX,
3137
3145
  dy = Type.evaluate(this.attr.keyboard.dy) / this.unitY,
3138
3146
  doZoom = false,
3147
+ done = true,
3139
3148
  dir, actPos;
3140
3149
 
3141
3150
  if (!this.attr.keyboard.enabled || id_node === '') {
@@ -3164,6 +3173,8 @@ define([
3164
3173
  this.clickLeftArrow();
3165
3174
  } else if (evt.keyCode === 39) { // right
3166
3175
  this.clickRightArrow();
3176
+ } else {
3177
+ done = false;
3167
3178
  }
3168
3179
  } else {
3169
3180
  // Adapt dx, dy to snapToGrid and attractToGrid
@@ -3216,7 +3227,10 @@ define([
3216
3227
  this.zoomOut();
3217
3228
  } else if (doZoom && evt.key === 'o') { // o
3218
3229
  this.zoom100();
3230
+ } else {
3231
+ done = false;
3219
3232
  }
3233
+
3220
3234
  if (dir && el.isDraggable &&
3221
3235
  el.visPropCalc.visible &&
3222
3236
  ((this.geonextCompatibilityMode &&
@@ -3242,6 +3256,9 @@ define([
3242
3256
 
3243
3257
  this.update();
3244
3258
 
3259
+ if (done && Type.exists(evt.preventDefault)) {
3260
+ evt.preventDefault();
3261
+ }
3245
3262
  return true;
3246
3263
  },
3247
3264
 
@@ -3327,7 +3344,7 @@ define([
3327
3344
  }
3328
3345
 
3329
3346
  // If div is invisible - do nothing
3330
- if (w <= 0 || h <= 0) {
3347
+ if (w <= 0 || h <= 0 || Type.isNaN(w) || Type.isNaN(h)) {
3331
3348
  return;
3332
3349
  }
3333
3350
 
@@ -4733,12 +4750,12 @@ define([
4733
4750
  this.inUpdate = true;
4734
4751
 
4735
4752
  if (this.attr.minimizereflow === 'all' && this.containerObj && this.renderer.type !== 'vml') {
4736
- storeActiveEl = document.activeElement; // Store focus element
4753
+ storeActiveEl = this.document.activeElement; // Store focus element
4737
4754
  insert = this.renderer.removeToInsertLater(this.containerObj);
4738
4755
  }
4739
4756
 
4740
4757
  if (this.attr.minimizereflow === 'svg' && this.renderer.type === 'svg') {
4741
- storeActiveEl = document.activeElement;
4758
+ storeActiveEl = this.document.activeElement;
4742
4759
  insert = this.renderer.removeToInsertLater(this.renderer.svgRoot);
4743
4760
  }
4744
4761
 
@@ -4840,6 +4857,7 @@ define([
4840
4857
  for (i = 0; i < parents.length; i++) {
4841
4858
  if (Type.isString(parents[i]) &&
4842
4859
  !(elementType === 'text' && i === 2) &&
4860
+ !(elementType === 'solidofrevolution3d' && i === 2) &&
4843
4861
  !((elementType === 'input' || elementType === 'checkbox' || elementType === 'button') &&
4844
4862
  (i === 2 || i === 3)) &&
4845
4863
  !(elementType === 'curve' && i > 0) // Allow curve plots with jessiecode
@@ -5360,7 +5378,7 @@ define([
5360
5378
  o2 = o2.parentNode;
5361
5379
  while (o2 !== o) {
5362
5380
  this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
5363
- o2 = o2.parentNode;
5381
+ o2 = o2.parentNode || o2.host;
5364
5382
  }
5365
5383
 
5366
5384
  o = o.offsetParent;
@@ -5930,7 +5948,7 @@ define([
5930
5948
 
5931
5949
  id = id || this.container;
5932
5950
  this._fullscreen_inner_id = id;
5933
- inner_node = document.getElementById(id);
5951
+ inner_node = this.document.getElementById(id);
5934
5952
  wrap_id = 'fullscreenwrap_' + id;
5935
5953
 
5936
5954
  // Wrap a div around the JSXGraph div.
@@ -5976,16 +5994,16 @@ define([
5976
5994
  return;
5977
5995
  }
5978
5996
 
5979
- document.fullscreenElement = document.fullscreenElement ||
5980
- document.webkitFullscreenElement ||
5981
- document.mozFullscreenElement ||
5982
- document.msFullscreenElement;
5997
+ this.document.fullscreenElement = this.document.fullscreenElement ||
5998
+ this.document.webkitFullscreenElement ||
5999
+ this.document.mozFullscreenElement ||
6000
+ this.document.msFullscreenElement;
5983
6001
 
5984
- inner_node = document.getElementById(inner_id);
6002
+ inner_node = this.document.getElementById(inner_id);
5985
6003
  // If full screen mode is started we have to remove CSS margin around the JSXGraph div.
5986
6004
  // Otherwise, the positioning of the fullscreen div will be false.
5987
6005
  // When leaving the fullscreen mode, the margin is put back in.
5988
- if (document.fullscreenElement) {
6006
+ if (this.document.fullscreenElement) {
5989
6007
  // Just entered fullscreen mode
5990
6008
 
5991
6009
  // Get the data computed in board.toFullscreen()
@@ -5997,7 +6015,7 @@ define([
5997
6015
  // Further, the CSS margin has to be removed when in fullscreen mode,
5998
6016
  // and must be restored later.
5999
6017
  inner_node._cssFullscreenStore = {
6000
- id: document.fullscreenElement.id,
6018
+ id: this.document.fullscreenElement.id,
6001
6019
  isFullscreen: true,
6002
6020
  margin: inner_node.style.margin,
6003
6021
  width: inner_node.style.width,
@@ -6013,16 +6031,16 @@ define([
6013
6031
  // of the JSXGraph div.
6014
6032
  Env.scaleJSXGraphDiv(document.fullscreenElement.id, inner_id, res.scale, res.vshift);
6015
6033
 
6016
- // Clear document.fullscreenElement, because Safari doesn't to it and
6034
+ // Clear this.document.fullscreenElement, because Safari doesn't to it and
6017
6035
  // when leaving full screen mode it is still set.
6018
- document.fullscreenElement = null;
6036
+ this.document.fullscreenElement = null;
6019
6037
 
6020
6038
  } else if (Type.exists(inner_node._cssFullscreenStore)) {
6021
6039
  // Just left the fullscreen mode
6022
6040
 
6023
6041
  // Remove the CSS rules added in Env.scaleJSXGraphDiv
6024
6042
  try {
6025
- document.styleSheets[document.styleSheets.length - 1].deleteRule(0);
6043
+ this.document.styleSheets[this.document.styleSheets.length - 1].deleteRule(0);
6026
6044
  } catch (err) {
6027
6045
  console.log('JSXGraph: Could not remove CSS rules for full screen mode');
6028
6046
  }
@@ -6030,7 +6048,6 @@ define([
6030
6048
  inner_node._cssFullscreenStore.isFullscreen = false;
6031
6049
  inner_node.style.margin = inner_node._cssFullscreenStore.margin;
6032
6050
  inner_node.style.width = inner_node._cssFullscreenStore.width;
6033
-
6034
6051
  }
6035
6052
 
6036
6053
  this.updateCSSTransforms();
@@ -42,7 +42,7 @@ define(['jxg'], function (JXG) {
42
42
 
43
43
  var major = 1,
44
44
  minor = 4,
45
- patch = 1,
45
+ patch = 4,
46
46
  add = '', //'dev'
47
47
  version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),
48
48
  constants;
@@ -111,6 +111,7 @@ define(['jxg'], function (JXG) {
111
111
  OBJECT_TYPE_BUTTON: 29,
112
112
  OBJECT_TYPE_TRANSFORMATION: 30,
113
113
  OBJECT_TYPE_FOREIGNOBJECT: 31,
114
+ OBJECT_TYPE_VIEW3D: 32,
114
115
 
115
116
  // IMPORTANT:
116
117
  // ----------
@@ -198,8 +198,6 @@ define([
198
198
  * @private
199
199
  */
200
200
  updateCoords: function (fromParent) {
201
- var i;
202
-
203
201
  if (!this.needsUpdate) {
204
202
  return this;
205
203
  }
@@ -326,7 +324,6 @@ define([
326
324
  doRound = true;
327
325
  newPos = 0.0;
328
326
  } else {
329
- //this.coords.setCoordinates(Const.COORDS_BY_USER, Geometry.projectPointToLine(this, slide, this.board).usrCoords, false);
330
327
  newCoords = Geometry.projectPointToLine(this, slide, this.board);
331
328
  p1c = p1c.usrCoords.slice(0);
332
329
  p2c = p2c.usrCoords.slice(0);
@@ -1833,7 +1830,7 @@ define([
1833
1830
  if (direction < 0) {
1834
1831
  alpha *= this.intervalCount / stepCount;
1835
1832
  } else {
1836
- alpha *= (stepCount - this.intervalCount);
1833
+ alpha *= (stepCount - this.intervalCount) / stepCount;
1837
1834
  }
1838
1835
  radius = this.slideObject.Radius();
1839
1836
 
@@ -224,7 +224,7 @@ define([
224
224
 
225
225
  /**
226
226
  * Inherits contains the subelements, which may have an attribute
227
- * (in partuclar the attribute "visible") having value 'inherit'.
227
+ * (in particular the attribute "visible") having value 'inherit'.
228
228
  * @type Object
229
229
  */
230
230
  this.inherits = [];
@@ -1052,26 +1052,35 @@ define([
1052
1052
  },
1053
1053
 
1054
1054
  /**
1055
- * Resolves property shortcuts like <tt>color</tt> and expands them, e.g. <tt>strokeColor</tt> and <tt>fillColor</tt>.
1056
- * Writes the expanded properties back to the given <tt>properties</tt>.
1057
- * @param {Object} properties
1058
- * @returns {Object} The given parameter with shortcuts expanded.
1055
+ * Resolves attribute shortcuts like <tt>color</tt> and expands them, e.g. <tt>strokeColor</tt> and <tt>fillColor</tt>.
1056
+ * Writes the expanded attributes back to the given <tt>attributes</tt>.
1057
+ * @param {Object} attributes object
1058
+ * @returns {Object} The given attributes object with shortcuts expanded.
1059
+ * @private
1059
1060
  */
1060
- resolveShortcuts: function (properties) {
1061
- var key, i;
1061
+ resolveShortcuts: function (attributes) {
1062
+ var key, i,
1063
+ j,
1064
+ subattr = ['traceattributes', 'traceAttributes'];
1062
1065
 
1063
1066
  for (key in Options.shortcuts) {
1064
1067
  if (Options.shortcuts.hasOwnProperty(key)) {
1065
- if (Type.exists(properties[key])) {
1066
- for (i = 0; i < Options.shortcuts[key].length; i++) {
1067
- if (!Type.exists(properties[Options.shortcuts[key][i]])) {
1068
- properties[Options.shortcuts[key][i]] = properties[key];
1068
+
1069
+ if (Type.exists(attributes[key])) {
1070
+ for (i = 0; i < Options.shortcuts[key].length; i++) {
1071
+ if (!Type.exists(attributes[Options.shortcuts[key][i]])) {
1072
+ attributes[Options.shortcuts[key][i]] = attributes[key];
1073
+ }
1074
+ }
1075
+ }
1076
+ for (j = 0; j < subattr.length; j++) {
1077
+ if (Type.isObject(attributes[subattr[j]])) {
1078
+ attributes[subattr[j]] = this.resolveShortcuts(attributes[subattr[j]]);
1079
+ }
1069
1080
  }
1070
1081
  }
1071
- }
1072
- }
1073
1082
  }
1074
- return properties;
1083
+ return attributes;
1075
1084
  },
1076
1085
 
1077
1086
  /**
@@ -324,7 +324,13 @@
324
324
  * an SVG foreignObject container.
325
325
  * <p>
326
326
  * Instead of board.create('foreignobject') the shortcut board.create('fo') may be used.
327
- *
327
+ *
328
+ * <p style="background-color:#dddddd; padding:10px"><b>NOTE:</b> In Safari up to version 15, a foreignObject does not obey the layer structure
329
+ * if it contains &lt;video&gt; or &lt;iframe&gt; tags, as well as elements which are
330
+ * positioned with <tt>position:absolute|relative|fixed</tt>. In this case, the foreignobject will be
331
+ * "above" the JSXGraph construction.
332
+ * </p>
333
+ *
328
334
  * @pseudo
329
335
  * @description
330
336
  * @name ForeignObject
package/src/base/line.js CHANGED
@@ -695,7 +695,7 @@ define([
695
695
  if (this.parents.length < 3) { // Line through two points
696
696
  this.point1.handleSnapToGrid(true, true);
697
697
  this.point2.handleSnapToGrid(true, true);
698
- } else if (Type.exists(pos)) { // Free line
698
+ } else if (Type.exists(pos)) { // Free line
699
699
  sX = Type.evaluate(this.visProp.snapsizex);
700
700
  sY = Type.evaluate(this.visProp.snapsizey);
701
701
 
package/src/base/point.js CHANGED
@@ -87,6 +87,7 @@ define([
87
87
  this.board.renderer.drawPoint(this);
88
88
  this.board.finalizeAdding(this);
89
89
 
90
+ this.createGradient();
90
91
  this.createLabel();
91
92
 
92
93
  };
@@ -559,8 +559,35 @@ define([
559
559
 
560
560
  /**
561
561
  * Add more points to the polygon. The new points will be inserted at the end.
562
- * @param {JXG.Point} p Arbitrary number of points
562
+ * The attributes of new border segments are set to the same values
563
+ * as those used when the polygon was created.
564
+ * If new vertices are supplied by coordinates, the default attributes of polygon
565
+ * vertices are taken as their attributes. Therefore, the visual attributes of
566
+ * new vertices and borders may have to be adapted afterwards.
567
+ * @param {JXG.Point} p Arbitrary number of points or coordinate arrays
563
568
  * @returns {JXG.Polygon} Reference to the polygon
569
+ * @example
570
+ * const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
571
+ * var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
572
+ * var newPoint = board.create('point', [-1, -1]);
573
+ * var newPoint2 = board.create('point', [-1, -2]);
574
+ * pg.addPoints(newPoint, newPoint2, [1, -2]);
575
+ *
576
+ * </pre><div id="JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5" class="jxgbox" style="width: 300px; height: 300px;"></div>
577
+ * <script type="text/javascript">
578
+ * (function() {
579
+ * var board = JXG.JSXGraph.initBoard('JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5',
580
+ * {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
581
+ * const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
582
+ * var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
583
+ * var newPoint = board.create('point', [-1, -1]);
584
+ * var newPoint2 = board.create('point', [-1, -2]);
585
+ * pg.addPoints(newPoint, newPoint2, [1, -2]);
586
+ *
587
+ * })();
588
+ *
589
+ * </script><pre>
590
+ *
564
591
  */
565
592
  addPoints: function (p) {
566
593
  var args = Array.prototype.slice.call(arguments);
@@ -569,44 +596,72 @@ define([
569
596
  },
570
597
 
571
598
  /**
572
- * Adds more points to the vertex list of the polygon, starting with index <tt><i</tt>
573
- * @param {Number} idx The position where the new vertices are inserted, starting with 0.
574
- * @param {JXG.Point} p Arbitrary number of points to insert.
599
+ * Insert points to the vertex list of the polygon after index <tt><idx</tt>.
600
+ * The attributes of new border segments are set to the same values
601
+ * as those used when the polygon was created.
602
+ * If new vertices are supplied by coordinates, the default attributes of polygon
603
+ * vertices are taken as their attributes. Therefore, the visual attributes of
604
+ * new vertices and borders may have to be adapted afterwards.
605
+ *
606
+ * @param {Number} idx The position after which the new vertices are inserted.
607
+ * Setting idx to -1 inserts the new points at the front, i.e. at position 0.
608
+ * @param {JXG.Point} p Arbitrary number of points or coordinate arrays to insert.
575
609
  * @returns {JXG.Polygon} Reference to the polygon object
610
+ *
611
+ * @example
612
+ * const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
613
+ * var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
614
+ * var newPoint = board.create('point', [-1, -1]);
615
+ * pg.insertPoints(0, newPoint, newPoint, [1, -2]);
616
+ *
617
+ * </pre><div id="JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca" class="jxgbox" style="width: 300px; height: 300px;"></div>
618
+ * <script type="text/javascript">
619
+ * (function() {
620
+ * var board = JXG.JSXGraph.initBoard('JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca',
621
+ * {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
622
+ * const board = JXG.JSXGraph.initBoard('jxgbox', {axis:true});
623
+ * var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});
624
+ * var newPoint = board.create('point', [-1, -1]);
625
+ * pg.insertPoints(0, newPoint, newPoint, [1, -2]);
626
+ *
627
+ * })();
628
+ *
629
+ * </script><pre>
630
+ *
576
631
  */
577
632
  insertPoints: function (idx, p) {
578
- var i, npoints = [], tmp;
633
+ var i, le;
579
634
 
580
635
  if (arguments.length === 0) {
581
636
  return this;
582
637
  }
583
638
 
584
639
 
585
- if (idx < 0 || idx > this.vertices.length - 2) {
640
+ if (idx < -1 || idx > this.vertices.length - 2) {
586
641
  return this;
587
642
  }
588
643
 
589
- for (i = 1; i < arguments.length; i++) {
590
- if (Type.isPoint(arguments[i])) {
591
- npoints.push(arguments[i]);
592
- }
644
+ le = arguments.length - 1;
645
+ for (i = 1; i < le + 1; i++) {
646
+ this.vertices.splice(idx + i, 0,
647
+ Type.providePoints(this.board, [arguments[i]], {}, 'polygon', ['vertices'])[0]
648
+ );
649
+ }
650
+ if (idx === -1) {
651
+ this.vertices[this.vertices.length - 1] = this.vertices[0];
593
652
  }
594
-
595
- tmp = this.vertices.slice(0, idx + 1).concat(npoints);
596
- this.vertices = tmp.concat(this.vertices.slice(idx + 1));
597
-
598
653
  if (this.withLines) {
599
- tmp = this.borders.slice(0, idx);
600
- this.board.removeObject(this.borders[idx]);
601
-
602
- for (i = 0; i < npoints.length; i++) {
603
- tmp.push(this.board.create('segment', [this.vertices[idx + i], this.vertices[idx + i + 1]], this.attr_line));
654
+ if (idx < 0) {
655
+ this.borders[this.borders.length - 1].point2 = this.vertices[this.vertices.length - 1];
656
+ } else {
657
+ this.borders[idx].point2 = this.vertices[idx + 1];
658
+ }
659
+ for (i = idx + 1; i < idx + 1 + le; i++) {
660
+ this.borders.splice(i, 0,
661
+ this.board.create('segment', [this.vertices[i], this.vertices[i + 1]], this.attr_line)
662
+ );
604
663
  }
605
-
606
- tmp.push(this.board.create('segment', [this.vertices[idx + npoints.length], this.vertices[idx + npoints.length + 1]], this.attr_line));
607
- this.borders = tmp.concat(this.borders.slice(idx + 1));
608
664
  }
609
-
610
665
  this.board.update();
611
666
 
612
667
  return this;
@@ -621,7 +676,7 @@ define([
621
676
  var i, j, idx, nvertices = [], nborders = [],
622
677
  nidx = [], partition = [];
623
678
 
624
- // partition:
679
+ // Partition:
625
680
  // in order to keep the borders which could be recycled, we have to partition
626
681
  // the set of removed points. I.e. if the points 1, 2, 5, 6, 7, 10 are removed,
627
682
  // the partitions are
@@ -629,10 +684,10 @@ define([
629
684
  // this gives us the borders, that can be removed and the borders we have to create.
630
685
 
631
686
 
632
- // remove the last vertex which is identical to the first
687
+ // Remove the last vertex which is identical to the first
633
688
  this.vertices = this.vertices.slice(0, this.vertices.length - 1);
634
689
 
635
- // collect all valid parameters as indices in nidx
690
+ // Collect all valid parameters as indices in nidx
636
691
  for (i = 0; i < arguments.length; i++) {
637
692
  idx = arguments[i];
638
693
  if (Type.isPoint(idx)) {
@@ -644,22 +699,22 @@ define([
644
699
  }
645
700
  }
646
701
 
647
- // remove the polygon from each removed point's children
702
+ // Remove the polygon from each removed point's children
648
703
  for (i = 0; i < nidx.length; i++) {
649
704
  this.vertices[nidx[i]].removeChild(this);
650
705
  }
651
706
 
652
- // sort the elements to be eliminated
707
+ // Sort the elements to be eliminated
653
708
  nidx = nidx.sort();
654
709
  nvertices = this.vertices.slice();
655
710
  nborders = this.borders.slice();
656
711
 
657
- // initialize the partition
712
+ // Initialize the partition
658
713
  if (this.withLines) {
659
714
  partition.push([nidx[nidx.length - 1]]);
660
715
  }
661
716
 
662
- // run through all existing vertices and copy all remaining ones to nvertices
717
+ // Run through all existing vertices and copy all remaining ones to nvertices,
663
718
  // compute the partition
664
719
  for (i = nidx.length - 1; i > -1; i--) {
665
720
  nvertices[nidx[i]] = -1;
@@ -670,12 +725,12 @@ define([
670
725
  }
671
726
  }
672
727
 
673
- // finalize the partition computation
728
+ // Finalize the partition computation
674
729
  if (this.withLines) {
675
730
  partition[partition.length - 1][1] = nidx[0];
676
731
  }
677
732
 
678
- // update vertices
733
+ // Update vertices
679
734
  this.vertices = [];
680
735
  for (i = 0; i < nvertices.length; i++) {
681
736
  if (Type.isPoint(nvertices[i])) {
@@ -686,7 +741,7 @@ define([
686
741
  this.vertices.push(this.vertices[0]);
687
742
  }
688
743
 
689
- // delete obsolete and create missing borders
744
+ // Delete obsolete and create missing borders
690
745
  if (this.withLines) {
691
746
  for (i = 0; i < partition.length; i++) {
692
747
  for (j = partition[i][1] - 1; j < partition[i][0] + 1; j++) {