Browse code

Initial commit

Benjamin Roth authored on22/05/2020 12:22:50
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,680 @@
1
+/*!
2
+ * ScrollMagic v2.0.7 (2019-05-07)
3
+ * The javascript library for magical scroll interactions.
4
+ * (c) 2019 Jan Paepke (@janpaepke)
5
+ * Project Website: http://scrollmagic.io
6
+ * 
7
+ * @version 2.0.7
8
+ * @license Dual licensed under MIT license and GPL.
9
+ * @author Jan Paepke - e-mail@janpaepke.de
10
+ *
11
+ * @file Debug Extension for ScrollMagic.
12
+ */
13
+/**
14
+ * This plugin was formerly known as the ScrollMagic debug extension.
15
+ *
16
+ * It enables you to add visual indicators to your page, to be able to see exactly when a scene is triggered.
17
+ *
18
+ * To have access to this extension, please include `plugins/debug.addIndicators.js`.
19
+ * @mixin debug.addIndicators
20
+ */
21
+(function (root, factory) {
22
+	if (typeof define === 'function' && define.amd) {
23
+		// AMD. Register as an anonymous module.
24
+		define(['ScrollMagic'], factory);
25
+	} else if (typeof exports === 'object') {
26
+		// CommonJS
27
+		factory(require('scrollmagic'));
28
+	} else {
29
+		// no browser global export needed, just execute
30
+		factory(root.ScrollMagic || (root.jQuery && root.jQuery.ScrollMagic));
31
+	}
32
+}(this, function (ScrollMagic) {
33
+	"use strict";
34
+	var NAMESPACE = "debug.addIndicators";
35
+
36
+	var
37
+		console = window.console || {},
38
+		err = Function.prototype.bind.call(console.error || console.log || function () {}, console);
39
+	if (!ScrollMagic) {
40
+		err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs.");
41
+	}
42
+
43
+	// plugin settings
44
+	var
45
+		FONT_SIZE = "0.85em",
46
+		ZINDEX = "9999",
47
+		EDGE_OFFSET = 15; // minimum edge distance, added to indentation
48
+
49
+	// overall vars
50
+	var
51
+		_util = ScrollMagic._util,
52
+		_autoindex = 0;
53
+
54
+
55
+
56
+	ScrollMagic.Scene.extend(function () {
57
+		var
58
+			Scene = this,
59
+			_indicator;
60
+
61
+		var log = function () {
62
+			if (Scene._log) { // not available, when main source minified
63
+				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
64
+				Scene._log.apply(this, arguments);
65
+			}
66
+		};
67
+
68
+		/**
69
+		 * Add visual indicators for a ScrollMagic.Scene.  
70
+		 * @memberof! debug.addIndicators#
71
+		 *
72
+		 * @example
73
+		 * // add basic indicators
74
+		 * scene.addIndicators()
75
+		 *
76
+		 * // passing options
77
+		 * scene.addIndicators({name: "pin scene", colorEnd: "#FFFFFF"});
78
+		 *
79
+		 * @param {object} [options] - An object containing one or more options for the indicators.
80
+		 * @param {(string|object)} [options.parent] - A selector, DOM Object or a jQuery object that the indicators should be added to.  
81
+		 														 														 If undefined, the controller's container will be used.
82
+		 * @param {number} [options.name=""] - This string will be displayed at the start and end indicators of the scene for identification purposes. If no name is supplied an automatic index will be used.
83
+		 * @param {number} [options.indent=0] - Additional position offset for the indicators (useful, when having multiple scenes starting at the same position).
84
+		 * @param {string} [options.colorStart=green] - CSS color definition for the start indicator.
85
+		 * @param {string} [options.colorEnd=red] - CSS color definition for the end indicator.
86
+		 * @param {string} [options.colorTrigger=blue] - CSS color definition for the trigger indicator.
87
+		 */
88
+		Scene.addIndicators = function (options) {
89
+			if (!_indicator) {
90
+				var
91
+					DEFAULT_OPTIONS = {
92
+						name: "",
93
+						indent: 0,
94
+						parent: undefined,
95
+						colorStart: "green",
96
+						colorEnd: "red",
97
+						colorTrigger: "blue",
98
+					};
99
+
100
+				options = _util.extend({}, DEFAULT_OPTIONS, options);
101
+
102
+				_autoindex++;
103
+				_indicator = new Indicator(Scene, options);
104
+
105
+				Scene.on("add.plugin_addIndicators", _indicator.add);
106
+				Scene.on("remove.plugin_addIndicators", _indicator.remove);
107
+				Scene.on("destroy.plugin_addIndicators", Scene.removeIndicators);
108
+
109
+				// it the scene already has a controller we can start right away.
110
+				if (Scene.controller()) {
111
+					_indicator.add();
112
+				}
113
+			}
114
+			return Scene;
115
+		};
116
+
117
+		/**
118
+		 * Removes visual indicators from a ScrollMagic.Scene.
119
+		 * @memberof! debug.addIndicators#
120
+		 *
121
+		 * @example
122
+		 * // remove previously added indicators
123
+		 * scene.removeIndicators()
124
+		 *
125
+		 */
126
+		Scene.removeIndicators = function () {
127
+			if (_indicator) {
128
+				_indicator.remove();
129
+				this.off("*.plugin_addIndicators");
130
+				_indicator = undefined;
131
+			}
132
+			return Scene;
133
+		};
134
+
135
+	});
136
+
137
+
138
+	/*
139
+	 * ----------------------------------------------------------------
140
+	 * Extension for controller to store and update related indicators
141
+	 * ----------------------------------------------------------------
142
+	 */
143
+	// add option to globally auto-add indicators to scenes
144
+	/**
145
+	 * Every ScrollMagic.Controller instance now accepts an additional option.  
146
+	 * See {@link ScrollMagic.Controller} for a complete list of the standard options.
147
+	 * @memberof! debug.addIndicators#
148
+	 * @method new ScrollMagic.Controller(options)
149
+	 * @example
150
+	 * // make a controller and add indicators to all scenes attached
151
+	 * var controller = new ScrollMagic.Controller({addIndicators: true});
152
+	 * // this scene will automatically have indicators added to it
153
+	 * new ScrollMagic.Scene()
154
+	 *                .addTo(controller);
155
+	 *
156
+	 * @param {object} [options] - Options for the Controller.
157
+	 * @param {boolean} [options.addIndicators=false] - If set to `true` every scene that is added to the controller will automatically get indicators added to it.
158
+	 */
159
+	ScrollMagic.Controller.addOption("addIndicators", false);
160
+	// extend Controller
161
+	ScrollMagic.Controller.extend(function () {
162
+		var
163
+			Controller = this,
164
+			_info = Controller.info(),
165
+			_container = _info.container,
166
+			_isDocument = _info.isDocument,
167
+			_vertical = _info.vertical,
168
+			_indicators = { // container for all indicators and methods
169
+				groups: []
170
+			};
171
+
172
+		var log = function () {
173
+			if (Controller._log) { // not available, when main source minified
174
+				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
175
+				Controller._log.apply(this, arguments);
176
+			}
177
+		};
178
+		if (Controller._indicators) {
179
+			log(2, "WARNING: Scene already has a property '_indicators', which will be overwritten by plugin.");
180
+		}
181
+
182
+		// add indicators container
183
+		this._indicators = _indicators;
184
+		/*
185
+			needed updates:
186
+			+++++++++++++++
187
+			start/end position on scene shift (handled in Indicator class)
188
+			trigger parameters on triggerHook value change (handled in Indicator class)
189
+			bounds position on container scroll or resize (to keep alignment to bottom/right)
190
+			trigger position on container resize, window resize (if container isn't document) and window scroll (if container isn't document)
191
+		*/
192
+
193
+		// event handler for when associated bounds markers need to be repositioned
194
+		var handleBoundsPositionChange = function () {
195
+			_indicators.updateBoundsPositions();
196
+		};
197
+
198
+		// event handler for when associated trigger groups need to be repositioned
199
+		var handleTriggerPositionChange = function () {
200
+			_indicators.updateTriggerGroupPositions();
201
+		};
202
+
203
+		_container.addEventListener("resize", handleTriggerPositionChange);
204
+		if (!_isDocument) {
205
+			window.addEventListener("resize", handleTriggerPositionChange);
206
+			window.addEventListener("scroll", handleTriggerPositionChange);
207
+		}
208
+		// update all related bounds containers
209
+		_container.addEventListener("resize", handleBoundsPositionChange);
210
+		_container.addEventListener("scroll", handleBoundsPositionChange);
211
+
212
+
213
+		// updates the position of the bounds container to aligned to the right for vertical containers and to the bottom for horizontal
214
+		this._indicators.updateBoundsPositions = function (specificIndicator) {
215
+			var // constant for all bounds
216
+				groups = specificIndicator ? [_util.extend({}, specificIndicator.triggerGroup, {
217
+					members: [specificIndicator]
218
+				})] : // create a group with only one element
219
+				_indicators.groups, // use all
220
+				g = groups.length,
221
+				css = {},
222
+				paramPos = _vertical ? "left" : "top",
223
+				paramDimension = _vertical ? "width" : "height",
224
+				edge = _vertical ?
225
+				_util.get.scrollLeft(_container) + _util.get.width(_container) - EDGE_OFFSET :
226
+				_util.get.scrollTop(_container) + _util.get.height(_container) - EDGE_OFFSET,
227
+				b, triggerSize, group;
228
+			while (g--) { // group loop
229
+				group = groups[g];
230
+				b = group.members.length;
231
+				triggerSize = _util.get[paramDimension](group.element.firstChild);
232
+				while (b--) { // indicators loop
233
+					css[paramPos] = edge - triggerSize;
234
+					_util.css(group.members[b].bounds, css);
235
+				}
236
+			}
237
+		};
238
+
239
+		// updates the positions of all trigger groups attached to a controller or a specific one, if provided
240
+		this._indicators.updateTriggerGroupPositions = function (specificGroup) {
241
+			var // constant vars
242
+				groups = specificGroup ? [specificGroup] : _indicators.groups,
243
+				i = groups.length,
244
+				container = _isDocument ? document.body : _container,
245
+				containerOffset = _isDocument ? {
246
+					top: 0,
247
+					left: 0
248
+				} : _util.get.offset(container, true),
249
+				edge = _vertical ?
250
+				_util.get.width(_container) - EDGE_OFFSET :
251
+				_util.get.height(_container) - EDGE_OFFSET,
252
+				paramDimension = _vertical ? "width" : "height",
253
+				paramTransform = _vertical ? "Y" : "X";
254
+			var // changing vars
255
+				group,
256
+				elem,
257
+				pos,
258
+				elemSize,
259
+				transform;
260
+			while (i--) {
261
+				group = groups[i];
262
+				elem = group.element;
263
+				pos = group.triggerHook * Controller.info("size");
264
+				elemSize = _util.get[paramDimension](elem.firstChild.firstChild);
265
+				transform = pos > elemSize ? "translate" + paramTransform + "(-100%)" : "";
266
+
267
+				_util.css(elem, {
268
+					top: containerOffset.top + (_vertical ? pos : edge - group.members[0].options.indent),
269
+					left: containerOffset.left + (_vertical ? edge - group.members[0].options.indent : pos)
270
+				});
271
+				_util.css(elem.firstChild.firstChild, {
272
+					"-ms-transform": transform,
273
+					"-webkit-transform": transform,
274
+					"transform": transform
275
+				});
276
+			}
277
+		};
278
+
279
+		// updates the label for the group to contain the name, if it only has one member
280
+		this._indicators.updateTriggerGroupLabel = function (group) {
281
+			var
282
+				text = "trigger" + (group.members.length > 1 ? "" : " " + group.members[0].options.name),
283
+				elem = group.element.firstChild.firstChild,
284
+				doUpdate = elem.textContent !== text;
285
+			if (doUpdate) {
286
+				elem.textContent = text;
287
+				if (_vertical) { // bounds position is dependent on text length, so update
288
+					_indicators.updateBoundsPositions();
289
+				}
290
+			}
291
+		};
292
+
293
+		// add indicators if global option is set
294
+		this.addScene = function (newScene) {
295
+
296
+			if (this._options.addIndicators && newScene instanceof ScrollMagic.Scene && newScene.controller() === Controller) {
297
+				newScene.addIndicators();
298
+			}
299
+			// call original destroy method
300
+			this.$super.addScene.apply(this, arguments);
301
+		};
302
+
303
+		// remove all previously set listeners on destroy
304
+		this.destroy = function () {
305
+			_container.removeEventListener("resize", handleTriggerPositionChange);
306
+			if (!_isDocument) {
307
+				window.removeEventListener("resize", handleTriggerPositionChange);
308
+				window.removeEventListener("scroll", handleTriggerPositionChange);
309
+			}
310
+			_container.removeEventListener("resize", handleBoundsPositionChange);
311
+			_container.removeEventListener("scroll", handleBoundsPositionChange);
312
+			// call original destroy method
313
+			this.$super.destroy.apply(this, arguments);
314
+		};
315
+		return Controller;
316
+
317
+	});
318
+
319
+	/*
320
+	 * ----------------------------------------------------------------
321
+	 * Internal class for the construction of Indicators
322
+	 * ----------------------------------------------------------------
323
+	 */
324
+	var Indicator = function (Scene, options) {
325
+		var
326
+			Indicator = this,
327
+			_elemBounds = TPL.bounds(),
328
+			_elemStart = TPL.start(options.colorStart),
329
+			_elemEnd = TPL.end(options.colorEnd),
330
+			_boundsContainer = options.parent && _util.get.elements(options.parent)[0],
331
+			_vertical,
332
+			_ctrl;
333
+
334
+		var log = function () {
335
+			if (Scene._log) { // not available, when main source minified
336
+				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
337
+				Scene._log.apply(this, arguments);
338
+			}
339
+		};
340
+
341
+		options.name = options.name || _autoindex;
342
+
343
+		// prepare bounds elements
344
+		_elemStart.firstChild.textContent += " " + options.name;
345
+		_elemEnd.textContent += " " + options.name;
346
+		_elemBounds.appendChild(_elemStart);
347
+		_elemBounds.appendChild(_elemEnd);
348
+
349
+		// set public variables
350
+		Indicator.options = options;
351
+		Indicator.bounds = _elemBounds;
352
+		// will be set later
353
+		Indicator.triggerGroup = undefined;
354
+
355
+		// add indicators to DOM
356
+		this.add = function () {
357
+			_ctrl = Scene.controller();
358
+			_vertical = _ctrl.info("vertical");
359
+
360
+			var isDocument = _ctrl.info("isDocument");
361
+
362
+			if (!_boundsContainer) {
363
+				// no parent supplied or doesnt exist
364
+				_boundsContainer = isDocument ? document.body : _ctrl.info("container"); // check if window/document (then use body)
365
+			}
366
+			if (!isDocument && _util.css(_boundsContainer, "position") === 'static') {
367
+				// position mode needed for correct positioning of indicators
368
+				_util.css(_boundsContainer, {
369
+					position: "relative"
370
+				});
371
+			}
372
+
373
+			// add listeners for updates
374
+			Scene.on("change.plugin_addIndicators", handleTriggerParamsChange);
375
+			Scene.on("shift.plugin_addIndicators", handleBoundsParamsChange);
376
+
377
+			// updates trigger & bounds (will add elements if needed)
378
+			updateTriggerGroup();
379
+			updateBounds();
380
+
381
+			setTimeout(function () { // do after all execution is finished otherwise sometimes size calculations are off
382
+				_ctrl._indicators.updateBoundsPositions(Indicator);
383
+			}, 0);
384
+
385
+			log(3, "added indicators");
386
+		};
387
+
388
+		// remove indicators from DOM
389
+		this.remove = function () {
390
+			if (Indicator.triggerGroup) { // if not set there's nothing to remove
391
+				Scene.off("change.plugin_addIndicators", handleTriggerParamsChange);
392
+				Scene.off("shift.plugin_addIndicators", handleBoundsParamsChange);
393
+
394
+				if (Indicator.triggerGroup.members.length > 1) {
395
+					// just remove from memberlist of old group
396
+					var group = Indicator.triggerGroup;
397
+					group.members.splice(group.members.indexOf(Indicator), 1);
398
+					_ctrl._indicators.updateTriggerGroupLabel(group);
399
+					_ctrl._indicators.updateTriggerGroupPositions(group);
400
+					Indicator.triggerGroup = undefined;
401
+				} else {
402
+					// remove complete group
403
+					removeTriggerGroup();
404
+				}
405
+				removeBounds();
406
+
407
+				log(3, "removed indicators");
408
+			}
409
+		};
410
+
411
+		/*
412
+		 * ----------------------------------------------------------------
413
+		 * internal Event Handlers
414
+		 * ----------------------------------------------------------------
415
+		 */
416
+
417
+		// event handler for when bounds params change
418
+		var handleBoundsParamsChange = function () {
419
+			updateBounds();
420
+		};
421
+
422
+		// event handler for when trigger params change
423
+		var handleTriggerParamsChange = function (e) {
424
+			if (e.what === "triggerHook") {
425
+				updateTriggerGroup();
426
+			}
427
+		};
428
+
429
+		/*
430
+		 * ----------------------------------------------------------------
431
+		 * Bounds (start / stop) management
432
+		 * ----------------------------------------------------------------
433
+		 */
434
+
435
+		// adds an new bounds elements to the array and to the DOM
436
+		var addBounds = function () {
437
+			var v = _ctrl.info("vertical");
438
+			// apply stuff we didn't know before...
439
+			_util.css(_elemStart.firstChild, {
440
+				"border-bottom-width": v ? 1 : 0,
441
+				"border-right-width": v ? 0 : 1,
442
+				"bottom": v ? -1 : options.indent,
443
+				"right": v ? options.indent : -1,
444
+				"padding": v ? "0 8px" : "2px 4px",
445
+			});
446
+			_util.css(_elemEnd, {
447
+				"border-top-width": v ? 1 : 0,
448
+				"border-left-width": v ? 0 : 1,
449
+				"top": v ? "100%" : "",
450
+				"right": v ? options.indent : "",
451
+				"bottom": v ? "" : options.indent,
452
+				"left": v ? "" : "100%",
453
+				"padding": v ? "0 8px" : "2px 4px"
454
+			});
455
+			// append
456
+			_boundsContainer.appendChild(_elemBounds);
457
+		};
458
+
459
+		// remove bounds from list and DOM
460
+		var removeBounds = function () {
461
+			_elemBounds.parentNode.removeChild(_elemBounds);
462
+		};
463
+
464
+		// update the start and end positions of the scene
465
+		var updateBounds = function () {
466
+			if (_elemBounds.parentNode !== _boundsContainer) {
467
+				addBounds(); // Add Bounds elements (start/end)
468
+			}
469
+			var css = {};
470
+			css[_vertical ? "top" : "left"] = Scene.triggerPosition();
471
+			css[_vertical ? "height" : "width"] = Scene.duration();
472
+			_util.css(_elemBounds, css);
473
+			_util.css(_elemEnd, {
474
+				display: Scene.duration() > 0 ? "" : "none"
475
+			});
476
+		};
477
+
478
+		/*
479
+		 * ----------------------------------------------------------------
480
+		 * trigger and trigger group management
481
+		 * ----------------------------------------------------------------
482
+		 */
483
+
484
+		// adds an new trigger group to the array and to the DOM
485
+		var addTriggerGroup = function () {
486
+			var triggerElem = TPL.trigger(options.colorTrigger); // new trigger element
487
+			var css = {};
488
+			css[_vertical ? "right" : "bottom"] = 0;
489
+			css[_vertical ? "border-top-width" : "border-left-width"] = 1;
490
+			_util.css(triggerElem.firstChild, css);
491
+			_util.css(triggerElem.firstChild.firstChild, {
492
+				padding: _vertical ? "0 8px 3px 8px" : "3px 4px"
493
+			});
494
+			document.body.appendChild(triggerElem); // directly add to body
495
+			var newGroup = {
496
+				triggerHook: Scene.triggerHook(),
497
+				element: triggerElem,
498
+				members: [Indicator]
499
+			};
500
+			_ctrl._indicators.groups.push(newGroup);
501
+			Indicator.triggerGroup = newGroup;
502
+			// update right away
503
+			_ctrl._indicators.updateTriggerGroupLabel(newGroup);
504
+			_ctrl._indicators.updateTriggerGroupPositions(newGroup);
505
+		};
506
+
507
+		var removeTriggerGroup = function () {
508
+			_ctrl._indicators.groups.splice(_ctrl._indicators.groups.indexOf(Indicator.triggerGroup), 1);
509
+			Indicator.triggerGroup.element.parentNode.removeChild(Indicator.triggerGroup.element);
510
+			Indicator.triggerGroup = undefined;
511
+		};
512
+
513
+		// updates the trigger group -> either join existing or add new one
514
+		/*	
515
+		 * Logic:
516
+		 * 1 if a trigger group exist, check if it's in sync with Scene settings – if so, nothing else needs to happen
517
+		 * 2 try to find an existing one that matches Scene parameters
518
+		 * 	 2.1 If a match is found check if already assigned to an existing group
519
+		 *			 If so:
520
+		 *       A: it was the last member of existing group -> kill whole group
521
+		 *       B: the existing group has other members -> just remove from member list
522
+		 *	 2.2 Assign to matching group
523
+		 * 3 if no new match could be found, check if assigned to existing group
524
+		 *   A: yes, and it's the only member -> just update parameters and positions and keep using this group
525
+		 *   B: yes but there are other members -> remove from member list and create a new one
526
+		 *   C: no, so create a new one
527
+		 */
528
+		var updateTriggerGroup = function () {
529
+			var
530
+				triggerHook = Scene.triggerHook(),
531
+				closeEnough = 0.0001;
532
+
533
+			// Have a group, check if it still matches
534
+			if (Indicator.triggerGroup) {
535
+				if (Math.abs(Indicator.triggerGroup.triggerHook - triggerHook) < closeEnough) {
536
+					// _util.log(0, "trigger", options.name, "->", "no need to change, still in sync");
537
+					return; // all good
538
+				}
539
+			}
540
+			// Don't have a group, check if a matching one exists
541
+			// _util.log(0, "trigger", options.name, "->", "out of sync!");
542
+			var
543
+				groups = _ctrl._indicators.groups,
544
+				group,
545
+				i = groups.length;
546
+			while (i--) {
547
+				group = groups[i];
548
+				if (Math.abs(group.triggerHook - triggerHook) < closeEnough) {
549
+					// found a match!
550
+					// _util.log(0, "trigger", options.name, "->", "found match");
551
+					if (Indicator.triggerGroup) { // do I have an old group that is out of sync?
552
+						if (Indicator.triggerGroup.members.length === 1) { // is it the only remaining group?
553
+							// _util.log(0, "trigger", options.name, "->", "kill");
554
+							// was the last member, remove the whole group
555
+							removeTriggerGroup();
556
+						} else {
557
+							Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group
558
+							_ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup);
559
+							_ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
560
+							// _util.log(0, "trigger", options.name, "->", "removing from previous member list");
561
+						}
562
+					}
563
+					// join new group
564
+					group.members.push(Indicator);
565
+					Indicator.triggerGroup = group;
566
+					_ctrl._indicators.updateTriggerGroupLabel(group);
567
+					return;
568
+				}
569
+			}
570
+
571
+			// at this point I am obviously out of sync and don't match any other group
572
+			if (Indicator.triggerGroup) {
573
+				if (Indicator.triggerGroup.members.length === 1) {
574
+					// _util.log(0, "trigger", options.name, "->", "updating existing");
575
+					// out of sync but i'm the only member => just change and update
576
+					Indicator.triggerGroup.triggerHook = triggerHook;
577
+					_ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
578
+					return;
579
+				} else {
580
+					// _util.log(0, "trigger", options.name, "->", "removing from previous member list");
581
+					Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group
582
+					_ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup);
583
+					_ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
584
+					Indicator.triggerGroup = undefined; // need a brand new group...
585
+				}
586
+			}
587
+			// _util.log(0, "trigger", options.name, "->", "add a new one");
588
+			// did not find any match, make new trigger group
589
+			addTriggerGroup();
590
+		};
591
+	};
592
+
593
+	/*
594
+	 * ----------------------------------------------------------------
595
+	 * Templates for the indicators
596
+	 * ----------------------------------------------------------------
597
+	 */
598
+	var TPL = {
599
+		start: function (color) {
600
+			// inner element (for bottom offset -1, while keeping top position 0)
601
+			var inner = document.createElement("div");
602
+			inner.textContent = "start";
603
+			_util.css(inner, {
604
+				position: "absolute",
605
+				overflow: "visible",
606
+				"border-width": 0,
607
+				"border-style": "solid",
608
+				color: color,
609
+				"border-color": color
610
+			});
611
+			var e = document.createElement('div');
612
+			// wrapper
613
+			_util.css(e, {
614
+				position: "absolute",
615
+				overflow: "visible",
616
+				width: 0,
617
+				height: 0
618
+			});
619
+			e.appendChild(inner);
620
+			return e;
621
+		},
622
+		end: function (color) {
623
+			var e = document.createElement('div');
624
+			e.textContent = "end";
625
+			_util.css(e, {
626
+				position: "absolute",
627
+				overflow: "visible",
628
+				"border-width": 0,
629
+				"border-style": "solid",
630
+				color: color,
631
+				"border-color": color
632
+			});
633
+			return e;
634
+		},
635
+		bounds: function () {
636
+			var e = document.createElement('div');
637
+			_util.css(e, {
638
+				position: "absolute",
639
+				overflow: "visible",
640
+				"white-space": "nowrap",
641
+				"pointer-events": "none",
642
+				"font-size": FONT_SIZE
643
+			});
644
+			e.style.zIndex = ZINDEX;
645
+			return e;
646
+		},
647
+		trigger: function (color) {
648
+			// inner to be above or below line but keep position
649
+			var inner = document.createElement('div');
650
+			inner.textContent = "trigger";
651
+			_util.css(inner, {
652
+				position: "relative",
653
+			});
654
+			// inner wrapper for right: 0 and main element has no size
655
+			var w = document.createElement('div');
656
+			_util.css(w, {
657
+				position: "absolute",
658
+				overflow: "visible",
659
+				"border-width": 0,
660
+				"border-style": "solid",
661
+				color: color,
662
+				"border-color": color
663
+			});
664
+			w.appendChild(inner);
665
+			// wrapper
666
+			var e = document.createElement('div');
667
+			_util.css(e, {
668
+				position: "fixed",
669
+				overflow: "visible",
670
+				"white-space": "nowrap",
671
+				"pointer-events": "none",
672
+				"font-size": FONT_SIZE
673
+			});
674
+			e.style.zIndex = ZINDEX;
675
+			e.appendChild(w);
676
+			return e;
677
+		},
678
+	};
679
+
680
+}));
0 681
\ No newline at end of file