@checksub_team/peaks_timeline 1.15.4-alpha.1 → 1.15.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checksub_team/peaks_timeline",
3
- "version": "1.15.4-alpha.1",
3
+ "version": "1.15.6",
4
4
  "description": "JavaScript UI component for displaying audio waveforms",
5
5
  "main": "./peaks.js",
6
6
  "types": "./peaks.js.d.ts",
package/peaks.js CHANGED
@@ -14776,9 +14776,6 @@ module.exports = function (Konva, Utils, SVGs) {
14776
14776
  });
14777
14777
  this._layer.add(this._separatingLine);
14778
14778
  this._layer.draw();
14779
- if (this._peaks.options.enableLineIndicatorContextMenu) {
14780
- this._createContextMenu();
14781
- }
14782
14779
  this._peaks.on('lineIndicator.setType', this._onSetType.bind(this));
14783
14780
  this._peaks.on('lineIndicator.setText', this._onSetText.bind(this));
14784
14781
  }
@@ -14924,8 +14921,7 @@ module.exports = function (Konva, Utils, SVGs) {
14924
14921
  if (this._indicators[lineId]) {
14925
14922
  var y = this._indicators[lineId].line.getY();
14926
14923
  var isVisible = y + this._indicators[lineId].line.lineHeight() + this._yPadding > 0 && y - this._yPadding < this._height;
14927
- var isLineNotEmpty = !this._indicators[lineId].line.isEmpty();
14928
- if (isLineNotEmpty && isVisible) {
14924
+ if (isVisible) {
14929
14925
  if (!this._indicators[lineId].indicator) {
14930
14926
  this._indicators[lineId].indicator = this._createIndicator(this._indicators[lineId].line, this._indicators[lineId].type, this._indicators[lineId].text);
14931
14927
  this._layer.add(this._indicators[lineId].indicator);
@@ -14947,118 +14943,6 @@ module.exports = function (Konva, Utils, SVGs) {
14947
14943
  LineIndicator.prototype.draw = function () {
14948
14944
  this._layer.draw();
14949
14945
  };
14950
- LineIndicator.prototype._createContextMenu = function () {
14951
- var menu = document.createElement('div');
14952
- var addLine = document.createElement('button');
14953
- var addLineAbove = document.createElement('button');
14954
- var addLineBelow = document.createElement('button');
14955
- var deleteLine = document.createElement('button');
14956
- var currentIndicator = null;
14957
- var self = this;
14958
- menu.style.display = 'none';
14959
- menu.style.position = 'absolute';
14960
- menu.style.backgroundColor = 'white';
14961
- menu.style.boxShadow = '0 0 5px grey';
14962
- menu.style.borderRadius = '3px';
14963
- menu.style.zIndex = 2;
14964
- addLine.style.display = 'none';
14965
- addLine.style.border = 'none';
14966
- addLine.style.margin = '0';
14967
- addLine.style.width = '100%';
14968
- addLine.style.backgroundColor = 'white';
14969
- addLine.style.padding = '10px';
14970
- addLine.textContent = 'Add first line';
14971
- addLine.onmouseover = function () {
14972
- this.style.backgroundColor = 'lightgray';
14973
- };
14974
- addLine.onmouseout = function () {
14975
- this.style.backgroundColor = 'white';
14976
- };
14977
- addLineAbove.style.display = 'none';
14978
- addLineAbove.style.border = 'none';
14979
- addLineAbove.style.margin = '0';
14980
- addLineAbove.style.width = '100%';
14981
- addLineAbove.style.backgroundColor = 'white';
14982
- addLineAbove.style.padding = '10px';
14983
- addLineAbove.textContent = 'Add line above';
14984
- addLineAbove.onmouseover = function () {
14985
- this.style.backgroundColor = 'lightgray';
14986
- };
14987
- addLineAbove.onmouseout = function () {
14988
- this.style.backgroundColor = 'white';
14989
- };
14990
- addLineBelow.style.display = 'none';
14991
- addLineBelow.style.border = 'none';
14992
- addLineBelow.style.margin = '0';
14993
- addLineBelow.style.width = '100%';
14994
- addLineBelow.style.backgroundColor = 'white';
14995
- addLineBelow.style.padding = '10px';
14996
- addLineBelow.textContent = 'Add line below';
14997
- addLineBelow.onmouseover = function () {
14998
- this.style.backgroundColor = 'lightgray';
14999
- };
15000
- addLineBelow.onmouseout = function () {
15001
- this.style.backgroundColor = 'white';
15002
- };
15003
- deleteLine.style.display = 'none';
15004
- deleteLine.style.border = 'none';
15005
- deleteLine.style.margin = '0';
15006
- deleteLine.style.width = '100%';
15007
- deleteLine.style.backgroundColor = 'white';
15008
- deleteLine.style.padding = '10px';
15009
- deleteLine.textContent = 'Delete line';
15010
- deleteLine.onmouseover = function () {
15011
- this.style.backgroundColor = 'lightgray';
15012
- };
15013
- deleteLine.onmouseout = function () {
15014
- this.style.backgroundColor = 'white';
15015
- };
15016
- menu.appendChild(addLine);
15017
- menu.appendChild(addLineAbove);
15018
- menu.appendChild(addLineBelow);
15019
- menu.appendChild(deleteLine);
15020
- this._container.appendChild(menu);
15021
- addLine.addEventListener('click', function () {
15022
- self._peaks.emit('line.add', 0);
15023
- self.draw();
15024
- });
15025
- addLineAbove.addEventListener('click', function () {
15026
- var line = self._indicators[currentIndicator.getAttr('lineId')].line;
15027
- self._peaks.emit('line.add', Number(line.getPosition()));
15028
- self.draw();
15029
- });
15030
- addLineBelow.addEventListener('click', function () {
15031
- var line = self._indicators[currentIndicator.getAttr('lineId')].line;
15032
- self._peaks.emit('line.add', Number(line.getPosition()) + 1);
15033
- self.draw();
15034
- });
15035
- deleteLine.addEventListener('click', function () {
15036
- var line = self._indicators[currentIndicator.getAttr('lineId')].line;
15037
- self._peaks.emit('line.remove', Number(line.getPosition()));
15038
- self.draw();
15039
- });
15040
- window.addEventListener('click', function () {
15041
- menu.style.display = 'none';
15042
- });
15043
- this._stage.on('contextmenu', function (e) {
15044
- e.evt.preventDefault();
15045
- if (e.target === self._stage && Object.keys(self._indicators).length === 0) {
15046
- addLine.style.display = 'block';
15047
- addLineAbove.style.display = 'none';
15048
- addLineBelow.style.display = 'none';
15049
- deleteLine.style.display = 'none';
15050
- self._showMenu(menu);
15051
- } else if (e.target !== self._stage) {
15052
- currentIndicator = e.target;
15053
- addLine.style.display = 'none';
15054
- addLineAbove.style.display = 'block';
15055
- addLineBelow.style.display = 'block';
15056
- deleteLine.style.display = 'block';
15057
- deleteLine.disabled = !self._indicators[currentIndicator.getAttr('lineId')].line.isEmpty();
15058
- self._showMenu(menu);
15059
- }
15060
- });
15061
- };
15062
14946
  return LineIndicator;
15063
14947
  }(_dereq_('konva'), _dereq_('./utils'), _dereq_('./svgs'));
15064
14948
  },{"./svgs":108,"./utils":113,"konva":43}],92:[function(_dereq_,module,exports){
@@ -15970,7 +15854,6 @@ module.exports = function (Colors, EventEmitter, TimelineSegments, TimelineSourc
15970
15854
  sourceButtonsXOffset: 8,
15971
15855
  sourceButtonsYOffset: 0,
15972
15856
  autoScrollThreshold: 0.05,
15973
- enableLineIndicatorContextMenu: true,
15974
15857
  minSourceSize: 0.05,
15975
15858
  minSegmentSize: 0.2,
15976
15859
  canMoveSourcesBetweenLines: true
@@ -17632,6 +17515,20 @@ module.exports = function (Utils) {
17632
17515
  Segment.prototype.shouldShowWarning = function () {
17633
17516
  return this.duration > Utils.roundTime(this.endTime - this.startTime);
17634
17517
  };
17518
+ Segment.prototype.toSerializable = function () {
17519
+ var serializable = {};
17520
+ var proto = Object.getPrototypeOf(this);
17521
+ var descriptors = Object.getOwnPropertyDescriptors(proto);
17522
+ for (var prop in descriptors) {
17523
+ if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
17524
+ var descriptor = descriptors[prop];
17525
+ if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
17526
+ serializable[prop] = this[prop];
17527
+ }
17528
+ }
17529
+ }
17530
+ return serializable;
17531
+ };
17635
17532
  return Segment;
17636
17533
  }(_dereq_('./utils'));
17637
17534
  },{"./utils":113}],104:[function(_dereq_,module,exports){
@@ -18172,13 +18069,16 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Loader, Konva)
18172
18069
  this._indicators = {};
18173
18070
  var self = this;
18174
18071
  this._x = this._view.timeToPixels(source.startTime);
18072
+ this._roundedX = Math.round(this._x);
18175
18073
  this._width = this._view.timeToPixels(source.endTime - source.startTime);
18074
+ this._roundedWidth = Math.round(this._width);
18176
18075
  this._unwrappedHeight = source.binaryHeight && source.previewHeight ? source.binaryHeight + source.previewHeight : this._peaks.options.lineHeight;
18177
18076
  this._wrappedHeight = this._peaks.options.wrappedLineHeight;
18178
18077
  this._borderWidth = this._source.borderWidth || 0;
18179
18078
  this._height = this._unwrappedHeight;
18180
18079
  this._currentTimeToPixelsScaleUsed = this._view.getTimeToPixelsScale();
18181
18080
  this._selected = this._source.selected;
18081
+ this._isDragged = false;
18182
18082
  this._previewList = [];
18183
18083
  this._markersGroup = this._createMarkers();
18184
18084
  this._group = new Konva.Group({
@@ -18192,8 +18092,8 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Loader, Konva)
18192
18092
  self.drawSourceShape(ctx, null);
18193
18093
  }
18194
18094
  });
18195
- this._group.on('dragstart', this._layer.onSourcesGroupDragStart.bind(this._layer));
18196
- this._group.on('dragend', this._layer.onSourcesGroupDragEnd.bind(this._layer));
18095
+ this._group.on('dragstart', this._onDragStart.bind(this));
18096
+ this._group.on('dragend', this._onDragEnd.bind(this));
18197
18097
  this._cursor = null;
18198
18098
  this._group.on('mouseenter', function () {
18199
18099
  self._view.setHoveredElement(self);
@@ -18239,6 +18139,17 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Loader, Konva)
18239
18139
  this.createIndicators();
18240
18140
  this.setLoadingState(this._source.loading);
18241
18141
  }
18142
+ SourceGroup.prototype._onDragStart = function (element) {
18143
+ this._isDragged = true;
18144
+ this._layer.onSourcesGroupDragStart(element);
18145
+ };
18146
+ SourceGroup.prototype._onDragEnd = function (element) {
18147
+ this._isDragged = false;
18148
+ this._layer.onSourcesGroupDragEnd(element);
18149
+ };
18150
+ SourceGroup.prototype.isActive = function () {
18151
+ return this._isDragged;
18152
+ };
18242
18153
  SourceGroup.prototype.addToContent = function (newChild) {
18243
18154
  if (this._source.wrapped) {
18244
18155
  this._wrap.add(newChild);
@@ -18271,9 +18182,11 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Loader, Konva)
18271
18182
  const newTimeToPixelsScale = this._view.getTimeToPixelsScale();
18272
18183
  this._group.x(startPixel - frameOffset);
18273
18184
  this._x = startPixel;
18185
+ this._roundedX = Math.round(this._x);
18274
18186
  const newWidth = endPixel - startPixel;
18275
18187
  if (newWidth !== this._width) {
18276
18188
  this._width = newWidth;
18189
+ this._roundedWidth = Math.round(this._width);
18277
18190
  if (newTimeToPixelsScale !== this._currentTimeToPixelsScaleUsed) {
18278
18191
  this._currentTimeToPixelsScaleUsed = newTimeToPixelsScale;
18279
18192
  this._updateMarkers();
@@ -18404,9 +18317,9 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Loader, Konva)
18404
18317
  };
18405
18318
  SourceGroup.prototype.drawSourceShape = function (ctx, shape, addBorderWidth, fill) {
18406
18319
  var offset = addBorderWidth ? this._borderWidth : 0;
18407
- var radius = this._source.borderRadius !== undefined && this._source.borderRadius !== null ? this._source.borderRadius : Math.max(1, Math.min(this._width / 2, Math.min(CORNER_RADIUS, this._height / 2)));
18408
- var x = Math.max(0, this._view.getFrameOffset() - this._x - radius);
18409
- var width = Math.min(this._width - x, this._view.getWidth() + radius - Math.max(0, this._x - this._view.getFrameOffset()));
18320
+ var radius = this._source.borderRadius !== undefined && this._source.borderRadius !== null ? this._source.borderRadius : Math.max(1, Math.min(this._roundedWidth / 2, Math.min(CORNER_RADIUS, this._height / 2)));
18321
+ var x = Math.max(0, this._view.getFrameOffset() - this._roundedX - radius);
18322
+ var width = Math.min(this._roundedWidth - x, this._view.getWidth() + radius - Math.max(0, this._roundedX - this._view.getFrameOffset()));
18410
18323
  var xWidth = x + width;
18411
18324
  ctx.beginPath();
18412
18325
  ctx.moveTo(x + radius, offset);
@@ -18421,14 +18334,14 @@ module.exports = function (WaveformBuilder, WaveformShape, Utils, Loader, Konva)
18421
18334
  ctx.closePath();
18422
18335
  if (fill) {
18423
18336
  if (this._source.shouldShowWarning()) {
18424
- var gradient = ctx.createLinearGradient(0, 0, this._width, 0);
18337
+ var gradient = ctx.createLinearGradient(0, 0, this._roundedWidth, 0);
18425
18338
  if (this._source.mediaEndTime < this._source.duration) {
18426
- var rightStopPosition = Math.max(1 - this._source.warningWidth / this._width, 0.5);
18339
+ var rightStopPosition = Math.max(1 - this._source.warningWidth / this._roundedWidth, 0.5);
18427
18340
  gradient.addColorStop(rightStopPosition, this._source.backgroundColor);
18428
18341
  gradient.addColorStop(1, this._source.warningColor);
18429
18342
  }
18430
18343
  if (this._source.mediaStartTime > 0) {
18431
- var leftStopPosition = Math.min(this._source.warningWidth / this._width, 0.5);
18344
+ var leftStopPosition = Math.min(this._source.warningWidth / this._roundedWidth, 0.5);
18432
18345
  gradient.addColorStop(0, this._source.warningColor);
18433
18346
  gradient.addColorStop(leftStopPosition, this._source.backgroundColor);
18434
18347
  }
@@ -20299,6 +20212,25 @@ module.exports = function (Utils) {
20299
20212
  return visibleTitle;
20300
20213
  }.bind(this), []).join(' ');
20301
20214
  };
20215
+ Source.prototype.toSerializable = function () {
20216
+ var serializable = {};
20217
+ for (var key in this) {
20218
+ if (Object.prototype.hasOwnProperty.call(this, key) && key.startsWith('custom_')) {
20219
+ serializable[key] = this[key];
20220
+ }
20221
+ }
20222
+ var proto = Object.getPrototypeOf(this);
20223
+ var descriptors = Object.getOwnPropertyDescriptors(proto);
20224
+ for (var prop in descriptors) {
20225
+ if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
20226
+ var descriptor = descriptors[prop];
20227
+ if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
20228
+ serializable[prop] = this[prop];
20229
+ }
20230
+ }
20231
+ }
20232
+ return serializable;
20233
+ };
20302
20234
  return Source;
20303
20235
  }(_dereq_('./utils'));
20304
20236
  },{"./utils":113}],107:[function(_dereq_,module,exports){
@@ -20600,10 +20532,13 @@ module.exports = function (SourceGroup, Lines, DataRetriever, Utils, Invoker, Ko
20600
20532
  var count = 0;
20601
20533
  for (var sourceId in this._sourcesGroup) {
20602
20534
  if (Utils.objectHasProperty(this._sourcesGroup, sourceId)) {
20603
- var source = this._sourcesGroup[sourceId].getSource();
20604
- if (!this._isSourceVisible(source, startTime, endTime)) {
20605
- this._removeSource(source);
20606
- count++;
20535
+ var sourceGroup = this._sourcesGroup[sourceId];
20536
+ if (!sourceGroup.isActive()) {
20537
+ var source = this._sourcesGroup[sourceId].getSource();
20538
+ if (!this._isSourceVisible(source, startTime, endTime)) {
20539
+ this._removeSource(source);
20540
+ count++;
20541
+ }
20607
20542
  }
20608
20543
  }
20609
20544
  }
@@ -20952,6 +20887,11 @@ module.exports = function (Colors, Segment, Utils) {
20952
20887
  TimelineSegments.prototype.getSegments = function () {
20953
20888
  return this._segments;
20954
20889
  };
20890
+ TimelineSegments.prototype.getSegmentsSerialized = function () {
20891
+ return this._segments.map(function (segment) {
20892
+ return segment.toSerializable();
20893
+ });
20894
+ };
20955
20895
  TimelineSegments.prototype.addSegmentsToPosition = function (lineId, position) {
20956
20896
  this._peaks.emit('segments.show', lineId, position);
20957
20897
  };
@@ -21168,6 +21108,11 @@ module.exports = function (Source, Utils) {
21168
21108
  TimelineSources.prototype.getSources = function () {
21169
21109
  return this._sources;
21170
21110
  };
21111
+ TimelineSources.prototype.getSourcesSerialized = function () {
21112
+ return this._sources.map(function (source) {
21113
+ return source.toSerializable();
21114
+ });
21115
+ };
21171
21116
  TimelineSources.prototype.getSource = function (id) {
21172
21117
  return this._sourcesById[id] || null;
21173
21118
  };
@@ -21710,7 +21655,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
21710
21655
  this.updateTimeline(this.timeToPixels(time));
21711
21656
  };
21712
21657
  TimelineZoomView.prototype.timeToPixels = function (time) {
21713
- return Math.round(time * this._timeToPixelsScale);
21658
+ return Utils.roundTime(time) * this._timeToPixelsScale;
21714
21659
  };
21715
21660
  TimelineZoomView.prototype.pixelsToTime = function (pixels) {
21716
21661
  return Utils.roundTime(pixels / this._timeToPixelsScale);
@@ -70,10 +70,6 @@ define([
70
70
 
71
71
  this._layer.draw();
72
72
 
73
- if (this._peaks.options.enableLineIndicatorContextMenu) {
74
- this._createContextMenu();
75
- }
76
-
77
73
  this._peaks.on('lineIndicator.setType', this._onSetType.bind(this));
78
74
  this._peaks.on('lineIndicator.setText', this._onSetText.bind(this));
79
75
  }
@@ -268,9 +264,8 @@ define([
268
264
  var y = this._indicators[lineId].line.getY();
269
265
  var isVisible = y + this._indicators[lineId].line.lineHeight() + this._yPadding > 0
270
266
  && y - this._yPadding < this._height;
271
- var isLineNotEmpty = !this._indicators[lineId].line.isEmpty();
272
267
 
273
- if (isLineNotEmpty && isVisible) {
268
+ if (isVisible) {
274
269
  if (!this._indicators[lineId].indicator) {
275
270
  this._indicators[lineId].indicator = this._createIndicator(
276
271
  this._indicators[lineId].line,
@@ -304,157 +299,5 @@ define([
304
299
  this._layer.draw();
305
300
  };
306
301
 
307
- LineIndicator.prototype._createContextMenu = function() {
308
- var menu = document.createElement('div');
309
- var addLine = document.createElement('button');
310
- var addLineAbove = document.createElement('button');
311
- var addLineBelow = document.createElement('button');
312
- var deleteLine = document.createElement('button');
313
- var currentIndicator = null;
314
- var self = this;
315
-
316
- menu.style.display = 'none';
317
- menu.style.position = 'absolute';
318
- menu.style.backgroundColor = 'white';
319
- menu.style.boxShadow = '0 0 5px grey';
320
- menu.style.borderRadius = '3px';
321
- menu.style.zIndex = 2;
322
-
323
- addLine.style.display = 'none';
324
- addLine.style.border = 'none';
325
- addLine.style.margin = '0';
326
- addLine.style.width = '100%';
327
- addLine.style.backgroundColor = 'white';
328
- addLine.style.padding = '10px';
329
-
330
- addLine.textContent = 'Add first line';
331
-
332
- addLine.onmouseover = function() {
333
- this.style.backgroundColor = 'lightgray';
334
- };
335
-
336
- addLine.onmouseout = function() {
337
- this.style.backgroundColor = 'white';
338
- };
339
-
340
- addLineAbove.style.display = 'none';
341
- addLineAbove.style.border = 'none';
342
- addLineAbove.style.margin = '0';
343
- addLineAbove.style.width = '100%';
344
- addLineAbove.style.backgroundColor = 'white';
345
- addLineAbove.style.padding = '10px';
346
-
347
- addLineAbove.textContent = 'Add line above';
348
-
349
- addLineAbove.onmouseover = function() {
350
- this.style.backgroundColor = 'lightgray';
351
- };
352
-
353
- addLineAbove.onmouseout = function() {
354
- this.style.backgroundColor = 'white';
355
- };
356
-
357
- addLineBelow.style.display = 'none';
358
- addLineBelow.style.border = 'none';
359
- addLineBelow.style.margin = '0';
360
- addLineBelow.style.width = '100%';
361
- addLineBelow.style.backgroundColor = 'white';
362
- addLineBelow.style.padding = '10px';
363
-
364
- addLineBelow.textContent = 'Add line below';
365
-
366
- addLineBelow.onmouseover = function() {
367
- this.style.backgroundColor = 'lightgray';
368
- };
369
-
370
- addLineBelow.onmouseout = function() {
371
- this.style.backgroundColor = 'white';
372
- };
373
-
374
- deleteLine.style.display = 'none';
375
- deleteLine.style.border = 'none';
376
- deleteLine.style.margin = '0';
377
- deleteLine.style.width = '100%';
378
- deleteLine.style.backgroundColor = 'white';
379
- deleteLine.style.padding = '10px';
380
-
381
- deleteLine.textContent = 'Delete line';
382
-
383
- deleteLine.onmouseover = function() {
384
- this.style.backgroundColor = 'lightgray';
385
- };
386
-
387
- deleteLine.onmouseout = function() {
388
- this.style.backgroundColor = 'white';
389
- };
390
-
391
- menu.appendChild(addLine);
392
- menu.appendChild(addLineAbove);
393
- menu.appendChild(addLineBelow);
394
- menu.appendChild(deleteLine);
395
- this._container.appendChild(menu);
396
-
397
- addLine.addEventListener('click', function() {
398
- self._peaks.emit('line.add', 0);
399
- self.draw();
400
- });
401
-
402
- addLineAbove.addEventListener('click', function() {
403
- var line = self._indicators[currentIndicator.getAttr('lineId')].line;
404
-
405
- self._peaks.emit('line.add', Number(line.getPosition()));
406
- self.draw();
407
- });
408
-
409
- addLineBelow.addEventListener('click', function() {
410
- var line = self._indicators[currentIndicator.getAttr('lineId')].line;
411
-
412
- self._peaks.emit('line.add', Number(line.getPosition()) + 1);
413
- self.draw();
414
- });
415
-
416
- deleteLine.addEventListener('click', function() {
417
- var line = self._indicators[currentIndicator.getAttr('lineId')].line;
418
-
419
- self._peaks.emit('line.remove', Number(line.getPosition()));
420
- self.draw();
421
- });
422
-
423
- window.addEventListener('click', function() {
424
- // hide menu
425
- menu.style.display = 'none';
426
- });
427
-
428
- this._stage.on('contextmenu', function(e) {
429
- // prevent default behavior
430
- e.evt.preventDefault();
431
-
432
- if (e.target === self._stage && Object.keys(self._indicators).length === 0) {
433
- // if we are on empty place of the stage
434
- // we will show the possibility to add a first line
435
- addLine.style.display = 'block';
436
- addLineAbove.style.display = 'none';
437
- addLineBelow.style.display = 'none';
438
- deleteLine.style.display = 'none';
439
-
440
- // show menu
441
- self._showMenu(menu);
442
- }
443
- else if (e.target !== self._stage) {
444
- currentIndicator = e.target;
445
-
446
- addLine.style.display = 'none';
447
- addLineAbove.style.display = 'block';
448
- addLineBelow.style.display = 'block';
449
- deleteLine.style.display = 'block';
450
-
451
- deleteLine.disabled = !self._indicators[currentIndicator.getAttr('lineId')].line.isEmpty();
452
-
453
- // show menu
454
- self._showMenu(menu);
455
- }
456
- });
457
- };
458
-
459
302
  return LineIndicator;
460
303
  });
package/src/main.js CHANGED
@@ -395,12 +395,6 @@ define([
395
395
  */
396
396
  autoScrollThreshold: 0.05,
397
397
 
398
- /**
399
- * Indicates whether or not the context menu should be displayed
400
- * on right click in the line indicator.
401
- */
402
- enableLineIndicatorContextMenu: true,
403
-
404
398
  /**
405
399
  * The minimal size of a source, in seconds
406
400
  */
package/src/segment.js CHANGED
@@ -389,5 +389,31 @@ define([
389
389
  return this.duration > Utils.roundTime(this.endTime - this.startTime);
390
390
  };
391
391
 
392
+ /**
393
+ * Returns a serializable object containing only the properties defined with Object.defineProperties.
394
+ * This includes all enumerable properties that can be safely serialized.
395
+ *
396
+ * @returns {Object} A plain object containing the serializable properties of the segment.
397
+ */
398
+ Segment.prototype.toSerializable = function() {
399
+ var serializable = {};
400
+
401
+ // Add all the enumerable properties from the prototype
402
+ var proto = Object.getPrototypeOf(this);
403
+ var descriptors = Object.getOwnPropertyDescriptors(proto);
404
+
405
+ for (var prop in descriptors) {
406
+ if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
407
+ var descriptor = descriptors[prop];
408
+
409
+ if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
410
+ serializable[prop] = this[prop];
411
+ }
412
+ }
413
+ }
414
+
415
+ return serializable;
416
+ };
417
+
392
418
  return Segment;
393
419
  });
@@ -47,7 +47,9 @@ define([
47
47
  var self = this;
48
48
 
49
49
  this._x = this._view.timeToPixels(source.startTime);
50
+ this._roundedX = Math.round(this._x);
50
51
  this._width = this._view.timeToPixels(source.endTime - source.startTime);
52
+ this._roundedWidth = Math.round(this._width);
51
53
  this._unwrappedHeight = source.binaryHeight && source.previewHeight ?
52
54
  source.binaryHeight + source.previewHeight :
53
55
  this._peaks.options.lineHeight;
@@ -56,6 +58,7 @@ define([
56
58
  this._height = this._unwrappedHeight;
57
59
  this._currentTimeToPixelsScaleUsed = this._view.getTimeToPixelsScale();
58
60
  this._selected = this._source.selected;
61
+ this._isDragged = false;
59
62
 
60
63
  this._previewList = [];
61
64
 
@@ -73,8 +76,8 @@ define([
73
76
  }
74
77
  });
75
78
 
76
- this._group.on('dragstart', this._layer.onSourcesGroupDragStart.bind(this._layer));
77
- this._group.on('dragend', this._layer.onSourcesGroupDragEnd.bind(this._layer));
79
+ this._group.on('dragstart', this._onDragStart.bind(this));
80
+ this._group.on('dragend', this._onDragEnd.bind(this));
78
81
 
79
82
  this._cursor = null;
80
83
  this._group.on('mouseenter', function() {
@@ -132,6 +135,20 @@ define([
132
135
  this.setLoadingState(this._source.loading);
133
136
  }
134
137
 
138
+ SourceGroup.prototype._onDragStart = function(element) {
139
+ this._isDragged = true;
140
+ this._layer.onSourcesGroupDragStart(element);
141
+ };
142
+
143
+ SourceGroup.prototype._onDragEnd = function(element) {
144
+ this._isDragged = false;
145
+ this._layer.onSourcesGroupDragEnd(element);
146
+ };
147
+
148
+ SourceGroup.prototype.isActive = function() {
149
+ return this._isDragged;
150
+ };
151
+
135
152
  SourceGroup.prototype.addToContent = function(newChild) {
136
153
  if (this._source.wrapped) {
137
154
  this._wrap.add(newChild);
@@ -181,11 +198,13 @@ define([
181
198
  this._group.x(startPixel - frameOffset);
182
199
 
183
200
  this._x = startPixel;
201
+ this._roundedX = Math.round(this._x);
184
202
 
185
203
  const newWidth = endPixel - startPixel;
186
204
 
187
205
  if (newWidth !== this._width) {
188
206
  this._width = newWidth;
207
+ this._roundedWidth = Math.round(this._width);
189
208
 
190
209
  // the zoom was changed
191
210
  if (newTimeToPixelsScale !== this._currentTimeToPixelsScaleUsed) {
@@ -355,7 +374,7 @@ define([
355
374
  Math.max(
356
375
  1,
357
376
  Math.min(
358
- this._width / 2,
377
+ this._roundedWidth / 2,
359
378
  Math.min(
360
379
  CORNER_RADIUS,
361
380
  this._height / 2
@@ -364,13 +383,13 @@ define([
364
383
  );
365
384
  var x = Math.max(
366
385
  0,
367
- this._view.getFrameOffset() - this._x - radius
386
+ this._view.getFrameOffset() - this._roundedX - radius
368
387
  );
369
388
  var width = Math.min(
370
- this._width - x,
389
+ this._roundedWidth - x,
371
390
  this._view.getWidth() + radius - Math.max(
372
391
  0,
373
- this._x - this._view.getFrameOffset()
392
+ this._roundedX - this._view.getFrameOffset()
374
393
  )
375
394
  );
376
395
  var xWidth = x + width;
@@ -394,17 +413,17 @@ define([
394
413
 
395
414
  if (fill) {
396
415
  if (this._source.shouldShowWarning()) {
397
- var gradient = ctx.createLinearGradient(0, 0, this._width, 0);
416
+ var gradient = ctx.createLinearGradient(0, 0, this._roundedWidth, 0);
398
417
 
399
418
  if (this._source.mediaEndTime < this._source.duration) {
400
- var rightStopPosition = Math.max(1 - (this._source.warningWidth / this._width), 0.5);
419
+ var rightStopPosition = Math.max(1 - (this._source.warningWidth / this._roundedWidth), 0.5);
401
420
 
402
421
  gradient.addColorStop(rightStopPosition, this._source.backgroundColor);
403
422
  gradient.addColorStop(1, this._source.warningColor);
404
423
  }
405
424
 
406
425
  if (this._source.mediaStartTime > 0) {
407
- var leftStopPosition = Math.min(this._source.warningWidth / this._width, 0.5);
426
+ var leftStopPosition = Math.min(this._source.warningWidth / this._roundedWidth, 0.5);
408
427
 
409
428
  gradient.addColorStop(0, this._source.warningColor);
410
429
  gradient.addColorStop(leftStopPosition, this._source.backgroundColor);
package/src/source.js CHANGED
@@ -1232,5 +1232,38 @@ define([
1232
1232
  }.bind(this), []).join(' ');
1233
1233
  };
1234
1234
 
1235
+ /**
1236
+ * Returns a serializable object containing only the properties defined with Object.defineProperties.
1237
+ * This includes all enumerable properties that can be safely serialized.
1238
+ *
1239
+ * @returns {Object} A plain object containing the serializable properties of the source.
1240
+ */
1241
+ Source.prototype.toSerializable = function() {
1242
+ var serializable = {};
1243
+
1244
+ // Get all custom properties
1245
+ for (var key in this) {
1246
+ if (Object.prototype.hasOwnProperty.call(this, key) && key.startsWith('custom_')) {
1247
+ serializable[key] = this[key];
1248
+ }
1249
+ }
1250
+
1251
+ // Add all the enumerable properties from the prototype
1252
+ var proto = Object.getPrototypeOf(this);
1253
+ var descriptors = Object.getOwnPropertyDescriptors(proto);
1254
+
1255
+ for (var prop in descriptors) {
1256
+ if (Object.prototype.hasOwnProperty.call(descriptors, prop)) {
1257
+ var descriptor = descriptors[prop];
1258
+
1259
+ if (descriptor.enumerable && descriptor.get && typeof descriptor.get === 'function') {
1260
+ serializable[prop] = this[prop];
1261
+ }
1262
+ }
1263
+ }
1264
+
1265
+ return serializable;
1266
+ };
1267
+
1235
1268
  return Source;
1236
1269
  });
@@ -511,11 +511,15 @@ define([
511
511
 
512
512
  for (var sourceId in this._sourcesGroup) {
513
513
  if (Utils.objectHasProperty(this._sourcesGroup, sourceId)) {
514
- var source = this._sourcesGroup[sourceId].getSource();
514
+ var sourceGroup = this._sourcesGroup[sourceId];
515
+
516
+ if (!sourceGroup.isActive()) {
517
+ var source = this._sourcesGroup[sourceId].getSource();
515
518
 
516
- if (!this._isSourceVisible(source, startTime, endTime)) {
517
- this._removeSource(source);
518
- count++;
519
+ if (!this._isSourceVisible(source, startTime, endTime)) {
520
+ this._removeSource(source);
521
+ count++;
522
+ }
519
523
  }
520
524
  }
521
525
  }
@@ -160,6 +160,18 @@ define([
160
160
  return this._segments;
161
161
  };
162
162
 
163
+ /**
164
+ * Returns all segments, serialized to a plain object.
165
+ *
166
+ * @returns {Array<Object>}
167
+ */
168
+
169
+ TimelineSegments.prototype.getSegmentsSerialized = function() {
170
+ return this._segments.map(function(segment) {
171
+ return segment.toSerializable();
172
+ });
173
+ };
174
+
163
175
  /**
164
176
  * Add segments to the given line so they can be displayed.
165
177
  */
@@ -240,6 +240,18 @@ define([
240
240
  return this._sources;
241
241
  };
242
242
 
243
+ /**
244
+ * Returns all sources, serialized to a plain object.
245
+ *
246
+ * @returns {Array<Object>}
247
+ */
248
+
249
+ TimelineSources.prototype.getSourcesSerialized = function() {
250
+ return this._sources.map(function(source) {
251
+ return source.toSerializable();
252
+ });
253
+ };
254
+
243
255
  /**
244
256
  * Returns the Source with the given id, or <code>null</code> if not found.
245
257
  *
@@ -679,7 +679,7 @@ define([
679
679
  */
680
680
 
681
681
  TimelineZoomView.prototype.timeToPixels = function(time) {
682
- return Math.round(time * this._timeToPixelsScale);
682
+ return Utils.roundTime(time) * this._timeToPixelsScale;
683
683
  };
684
684
 
685
685
  /**