rails-darsain-tooltips 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3058ded792cbf99e09898b788a96ca5917280c90
4
+ data.tar.gz: 1704f57e6d30d24e0e2c9722ccc078085127d152
5
+ SHA512:
6
+ metadata.gz: 354bfe97750199943ac7e28843abbf508965d5ec6f67d300c4508ce89a85c57583ea0b0863932f58e94efd3bad1fafddc19124525b895809443ab8d605231105
7
+ data.tar.gz: 8bad4627f1ec26b78d214969d7d0b096993e384ef735094138c539531f70529085bd7530e7d9461fd9a63ea9e03ab83e7da33614892151063d8e5ae40d67d357
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2015 Alexander Bobrov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ # rails-darsain-tooltips
2
+
3
+ rails-darsain-tooltips wraps the [Darsain Tooltips](http://darsa.in/tooltips/) for use in Rails 3.1 and above.
4
+
5
+ ## Usage
6
+
7
+ Add the following to your Gemfile:
8
+
9
+ gem 'rails-darsain-tooltips'
10
+
11
+ Add the following to your Rails JavaScript manifest file:
12
+
13
+ //= require darsain-tooltips
14
+
15
+ If you desire minified files, add the following:
16
+
17
+ //= require darsain-tooltips.min
18
+
19
+ And add the following to your Rails Stylesheets manifest file:
20
+
21
+ *= require darsain-tooltips
22
+
23
+ ## Versioning
24
+
25
+ Current version of Darsain Tooltips - 0.1.0
@@ -0,0 +1,9 @@
1
+ require "rails-darsain-tooltips/version"
2
+
3
+ module DarsainTooltipsRails
4
+ if defined? ::Rails::Engine
5
+ require "rails-darsain-tooltips/engine"
6
+ else
7
+ puts "You should use Rails 3.1+ and higher with rails-darsain-tooltips!"
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module DarsainTooltipsRails
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module DarsainTooltipsRails
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,1559 @@
1
+ /*!
2
+ * tooltips 0.1.0 - 13th Feb 2015
3
+ * https://github.com/darsain/tooltip
4
+ *
5
+ * Licensed under the MIT license.
6
+ * http://opensource.org/licenses/MIT
7
+ */
8
+
9
+ ;(function(){
10
+
11
+ /**
12
+ * Require the module at `name`.
13
+ *
14
+ * @param {String} name
15
+ * @return {Object} exports
16
+ * @api public
17
+ */
18
+
19
+ function require(name) {
20
+ var module = require.modules[name];
21
+ if (!module) throw new Error('failed to require "' + name + '"');
22
+
23
+ if (!('exports' in module) && typeof module.definition === 'function') {
24
+ module.client = module.component = true;
25
+ module.definition.call(this, module.exports = {}, module);
26
+ delete module.definition;
27
+ }
28
+
29
+ return module.exports;
30
+ }
31
+
32
+ /**
33
+ * Meta info, accessible in the global scope unless you use AMD option.
34
+ */
35
+
36
+ require.loader = 'component';
37
+
38
+ /**
39
+ * Internal helper object, contains a sorting function for semantiv versioning
40
+ */
41
+ require.helper = {};
42
+ require.helper.semVerSort = function(a, b) {
43
+ var aArray = a.version.split('.');
44
+ var bArray = b.version.split('.');
45
+ for (var i=0; i<aArray.length; ++i) {
46
+ var aInt = parseInt(aArray[i], 10);
47
+ var bInt = parseInt(bArray[i], 10);
48
+ if (aInt === bInt) {
49
+ var aLex = aArray[i].substr((""+aInt).length);
50
+ var bLex = bArray[i].substr((""+bInt).length);
51
+ if (aLex === '' && bLex !== '') return 1;
52
+ if (aLex !== '' && bLex === '') return -1;
53
+ if (aLex !== '' && bLex !== '') return aLex > bLex ? 1 : -1;
54
+ continue;
55
+ } else if (aInt > bInt) {
56
+ return 1;
57
+ } else {
58
+ return -1;
59
+ }
60
+ }
61
+ return 0;
62
+ }
63
+
64
+ /**
65
+ * Find and require a module which name starts with the provided name.
66
+ * If multiple modules exists, the highest semver is used.
67
+ * This function can only be used for remote dependencies.
68
+
69
+ * @param {String} name - module name: `user~repo`
70
+ * @param {Boolean} returnPath - returns the canonical require path if true,
71
+ * otherwise it returns the epxorted module
72
+ */
73
+ require.latest = function (name, returnPath) {
74
+ function showError(name) {
75
+ throw new Error('failed to find latest module of "' + name + '"');
76
+ }
77
+ // only remotes with semvers, ignore local files conataining a '/'
78
+ var versionRegexp = /(.*)~(.*)@v?(\d+\.\d+\.\d+[^\/]*)$/;
79
+ var remoteRegexp = /(.*)~(.*)/;
80
+ if (!remoteRegexp.test(name)) showError(name);
81
+ var moduleNames = Object.keys(require.modules);
82
+ var semVerCandidates = [];
83
+ var otherCandidates = []; // for instance: name of the git branch
84
+ for (var i=0; i<moduleNames.length; i++) {
85
+ var moduleName = moduleNames[i];
86
+ if (new RegExp(name + '@').test(moduleName)) {
87
+ var version = moduleName.substr(name.length+1);
88
+ var semVerMatch = versionRegexp.exec(moduleName);
89
+ if (semVerMatch != null) {
90
+ semVerCandidates.push({version: version, name: moduleName});
91
+ } else {
92
+ otherCandidates.push({version: version, name: moduleName});
93
+ }
94
+ }
95
+ }
96
+ if (semVerCandidates.concat(otherCandidates).length === 0) {
97
+ showError(name);
98
+ }
99
+ if (semVerCandidates.length > 0) {
100
+ var module = semVerCandidates.sort(require.helper.semVerSort).pop().name;
101
+ if (returnPath === true) {
102
+ return module;
103
+ }
104
+ return require(module);
105
+ }
106
+ // if the build contains more than one branch of the same module
107
+ // you should not use this funciton
108
+ var module = otherCandidates.sort(function(a, b) {return a.name > b.name})[0].name;
109
+ if (returnPath === true) {
110
+ return module;
111
+ }
112
+ return require(module);
113
+ }
114
+
115
+ /**
116
+ * Registered modules.
117
+ */
118
+
119
+ require.modules = {};
120
+
121
+ /**
122
+ * Register module at `name` with callback `definition`.
123
+ *
124
+ * @param {String} name
125
+ * @param {Function} definition
126
+ * @api private
127
+ */
128
+
129
+ require.register = function (name, definition) {
130
+ require.modules[name] = {
131
+ definition: definition
132
+ };
133
+ };
134
+
135
+ /**
136
+ * Define a module's exports immediately with `exports`.
137
+ *
138
+ * @param {String} name
139
+ * @param {Generic} exports
140
+ * @api private
141
+ */
142
+
143
+ require.define = function (name, exports) {
144
+ require.modules[name] = {
145
+ exports: exports
146
+ };
147
+ };
148
+ require.register("darsain~event@0.1.0", function (exports, module) {
149
+ 'use strict';
150
+
151
+ /**
152
+ * Bind `el` event `type` to `fn`.
153
+ *
154
+ * @param {Element} el
155
+ * @param {String} type
156
+ * @param {Function} fn
157
+ * @param {Boolean} capture
158
+ *
159
+ * @return {Function}
160
+ */
161
+ exports.bind = window.addEventListener ? function (el, type, fn, capture) {
162
+ el.addEventListener(type, fn, capture || false);
163
+ return fn;
164
+ } : function (el, type, fn) {
165
+ var fnid = type + fn;
166
+ el[fnid] = el[fnid] || function () {
167
+ var event = window.event;
168
+ event.target = event.srcElement;
169
+ event.preventDefault = function () {
170
+ event.returnValue = false;
171
+ };
172
+ event.stopPropagation = function () {
173
+ event.cancelBubble = true;
174
+ };
175
+ fn.call(el, event);
176
+ };
177
+ el.attachEvent('on' + type, el[fnid]);
178
+ return fn;
179
+ };
180
+
181
+ /**
182
+ * Unbind `el` event `type`'s callback `fn`.
183
+ *
184
+ * @param {Element} el
185
+ * @param {String} type
186
+ * @param {Function} fn
187
+ * @param {Boolean} capture
188
+ *
189
+ * @return {Function}
190
+ */
191
+ exports.unbind = window.removeEventListener ? function (el, type, fn, capture) {
192
+ el.removeEventListener(type, fn, capture || false);
193
+ return fn;
194
+ } : function (el, type, fn) {
195
+ var fnid = type + fn;
196
+ el.detachEvent('on' + type, el[fnid]);
197
+ try {
198
+ delete el[fnid];
199
+ } catch (err) {
200
+ // can't delete window object properties
201
+ el[fnid] = undefined;
202
+ }
203
+ return fn;
204
+ };
205
+ });
206
+
207
+ require.register("darsain~position@0.1.0", function (exports, module) {
208
+ 'use strict';
209
+
210
+ /**
211
+ * Transport.
212
+ */
213
+ module.exports = position;
214
+
215
+ /**
216
+ * Globals.
217
+ */
218
+ var win = window;
219
+ var doc = win.document;
220
+ var docEl = doc.documentElement;
221
+
222
+ /**
223
+ * Poor man's shallow object extend.
224
+ *
225
+ * @param {Object} a
226
+ * @param {Object} b
227
+ *
228
+ * @return {Object}
229
+ */
230
+ function extend(a, b) {
231
+ for (var key in b) {
232
+ a[key] = b[key];
233
+ }
234
+ return a;
235
+ }
236
+
237
+ /**
238
+ * Checks whether object is window.
239
+ *
240
+ * @param {Object} obj
241
+ *
242
+ * @return {Boolean}
243
+ */
244
+ function isWin(obj) {
245
+ return obj && obj.setInterval != null;
246
+ }
247
+
248
+ /**
249
+ * Returns element's object with `left`, `top`, `bottom`, `right`, `width`, and `height`
250
+ * properties indicating the position and dimensions of element on a page.
251
+ *
252
+ * @param {Element} element
253
+ *
254
+ * @return {Object}
255
+ */
256
+ function position(element) {
257
+ var winTop = win.pageYOffset || docEl.scrollTop;
258
+ var winLeft = win.pageXOffset || docEl.scrollLeft;
259
+ var box = { left: 0, right: 0, top: 0, bottom: 0, width: 0, height: 0 };
260
+
261
+ if (isWin(element)) {
262
+ box.width = win.innerWidth || docEl.clientWidth;
263
+ box.height = win.innerHeight || docEl.clientHeight;
264
+ } else if (docEl.contains(element) && element.getBoundingClientRect != null) {
265
+ extend(box, element.getBoundingClientRect());
266
+ // width & height don't exist in <IE9
267
+ box.width = box.right - box.left;
268
+ box.height = box.bottom - box.top;
269
+ } else {
270
+ return box;
271
+ }
272
+
273
+ box.top = box.top + winTop - docEl.clientTop;
274
+ box.left = box.left + winLeft - docEl.clientLeft;
275
+ box.right = box.left + box.width;
276
+ box.bottom = box.top + box.height;
277
+
278
+ return box;
279
+ }
280
+ });
281
+
282
+ require.register("component~indexof@0.0.3", function (exports, module) {
283
+ module.exports = function(arr, obj){
284
+ if (arr.indexOf) return arr.indexOf(obj);
285
+ for (var i = 0; i < arr.length; ++i) {
286
+ if (arr[i] === obj) return i;
287
+ }
288
+ return -1;
289
+ };
290
+ });
291
+
292
+ require.register("component~classes@1.2.3", function (exports, module) {
293
+ /**
294
+ * Module dependencies.
295
+ */
296
+
297
+ var index = require('component~indexof@0.0.3');
298
+
299
+ /**
300
+ * Whitespace regexp.
301
+ */
302
+
303
+ var re = /\s+/;
304
+
305
+ /**
306
+ * toString reference.
307
+ */
308
+
309
+ var toString = Object.prototype.toString;
310
+
311
+ /**
312
+ * Wrap `el` in a `ClassList`.
313
+ *
314
+ * @param {Element} el
315
+ * @return {ClassList}
316
+ * @api public
317
+ */
318
+
319
+ module.exports = function(el){
320
+ return new ClassList(el);
321
+ };
322
+
323
+ /**
324
+ * Initialize a new ClassList for `el`.
325
+ *
326
+ * @param {Element} el
327
+ * @api private
328
+ */
329
+
330
+ function ClassList(el) {
331
+ if (!el || !el.nodeType) {
332
+ throw new Error('A DOM element reference is required');
333
+ }
334
+ this.el = el;
335
+ this.list = el.classList;
336
+ }
337
+
338
+ /**
339
+ * Add class `name` if not already present.
340
+ *
341
+ * @param {String} name
342
+ * @return {ClassList}
343
+ * @api public
344
+ */
345
+
346
+ ClassList.prototype.add = function(name){
347
+ // classList
348
+ if (this.list) {
349
+ this.list.add(name);
350
+ return this;
351
+ }
352
+
353
+ // fallback
354
+ var arr = this.array();
355
+ var i = index(arr, name);
356
+ if (!~i) arr.push(name);
357
+ this.el.className = arr.join(' ');
358
+ return this;
359
+ };
360
+
361
+ /**
362
+ * Remove class `name` when present, or
363
+ * pass a regular expression to remove
364
+ * any which match.
365
+ *
366
+ * @param {String|RegExp} name
367
+ * @return {ClassList}
368
+ * @api public
369
+ */
370
+
371
+ ClassList.prototype.remove = function(name){
372
+ if ('[object RegExp]' == toString.call(name)) {
373
+ return this.removeMatching(name);
374
+ }
375
+
376
+ // classList
377
+ if (this.list) {
378
+ this.list.remove(name);
379
+ return this;
380
+ }
381
+
382
+ // fallback
383
+ var arr = this.array();
384
+ var i = index(arr, name);
385
+ if (~i) arr.splice(i, 1);
386
+ this.el.className = arr.join(' ');
387
+ return this;
388
+ };
389
+
390
+ /**
391
+ * Remove all classes matching `re`.
392
+ *
393
+ * @param {RegExp} re
394
+ * @return {ClassList}
395
+ * @api private
396
+ */
397
+
398
+ ClassList.prototype.removeMatching = function(re){
399
+ var arr = this.array();
400
+ for (var i = 0; i < arr.length; i++) {
401
+ if (re.test(arr[i])) {
402
+ this.remove(arr[i]);
403
+ }
404
+ }
405
+ return this;
406
+ };
407
+
408
+ /**
409
+ * Toggle class `name`, can force state via `force`.
410
+ *
411
+ * For browsers that support classList, but do not support `force` yet,
412
+ * the mistake will be detected and corrected.
413
+ *
414
+ * @param {String} name
415
+ * @param {Boolean} force
416
+ * @return {ClassList}
417
+ * @api public
418
+ */
419
+
420
+ ClassList.prototype.toggle = function(name, force){
421
+ // classList
422
+ if (this.list) {
423
+ if ("undefined" !== typeof force) {
424
+ if (force !== this.list.toggle(name, force)) {
425
+ this.list.toggle(name); // toggle again to correct
426
+ }
427
+ } else {
428
+ this.list.toggle(name);
429
+ }
430
+ return this;
431
+ }
432
+
433
+ // fallback
434
+ if ("undefined" !== typeof force) {
435
+ if (!force) {
436
+ this.remove(name);
437
+ } else {
438
+ this.add(name);
439
+ }
440
+ } else {
441
+ if (this.has(name)) {
442
+ this.remove(name);
443
+ } else {
444
+ this.add(name);
445
+ }
446
+ }
447
+
448
+ return this;
449
+ };
450
+
451
+ /**
452
+ * Return an array of classes.
453
+ *
454
+ * @return {Array}
455
+ * @api public
456
+ */
457
+
458
+ ClassList.prototype.array = function(){
459
+ var str = this.el.className.replace(/^\s+|\s+$/g, '');
460
+ var arr = str.split(re);
461
+ if ('' === arr[0]) arr.shift();
462
+ return arr;
463
+ };
464
+
465
+ /**
466
+ * Check if class `name` is present.
467
+ *
468
+ * @param {String} name
469
+ * @return {ClassList}
470
+ * @api public
471
+ */
472
+
473
+ ClassList.prototype.has =
474
+ ClassList.prototype.contains = function(name){
475
+ return this.list
476
+ ? this.list.contains(name)
477
+ : !! ~index(this.array(), name);
478
+ };
479
+
480
+ });
481
+
482
+ require.register("darsain~tooltip@0.1.0", function (exports, module) {
483
+ 'use strict';
484
+
485
+ /**
486
+ * Dependencies.
487
+ */
488
+ var evt = require('darsain~event@0.1.0');
489
+ var classes = require('component~classes@1.2.3');
490
+ var indexOf = require('component~indexof@0.0.3');
491
+ var position = require('darsain~position@0.1.0');
492
+
493
+ /**
494
+ * Globals.
495
+ */
496
+ var win = window;
497
+ var doc = win.document;
498
+ var body = doc.body;
499
+ var verticalPlaces = ['top', 'bottom'];
500
+
501
+ /**
502
+ * Transport.
503
+ */
504
+ module.exports = Tooltip;
505
+
506
+ /**
507
+ * Prototypal inheritance.
508
+ *
509
+ * @param {Object} o
510
+ *
511
+ * @return {Object}
512
+ */
513
+ var objectCreate = Object.create || (function () {
514
+ function F() {}
515
+ return function (o) {
516
+ F.prototype = o;
517
+ return new F();
518
+ };
519
+ })();
520
+
521
+ /**
522
+ * Poor man's shallow object extend.
523
+ *
524
+ * @param {Object} a
525
+ * @param {Object} b
526
+ *
527
+ * @return {Object}
528
+ */
529
+ function extend(a, b) {
530
+ for (var key in b) {
531
+ a[key] = b[key];
532
+ }
533
+ return a;
534
+ }
535
+
536
+ /**
537
+ * Parse integer from strings like '-50px'.
538
+ *
539
+ * @param {Mixed} value
540
+ *
541
+ * @return {Integer}
542
+ */
543
+ function parsePx(value) {
544
+ return 0 | Math.round(String(value).replace(/[^\-0-9.]/g, ''));
545
+ }
546
+
547
+ /**
548
+ * Get computed style of element.
549
+ *
550
+ * @param {Element} element
551
+ *
552
+ * @type {String}
553
+ */
554
+ var style = win.getComputedStyle ? function style(element, name) {
555
+ return win.getComputedStyle(element, null)[name];
556
+ } : function style(element, name) {
557
+ return element.currentStyle[name];
558
+ };
559
+
560
+ /**
561
+ * Returns transition duration of element in ms.
562
+ *
563
+ * @param {Element} element
564
+ *
565
+ * @return {Int}
566
+ */
567
+ function transitionDuration(element) {
568
+ var duration = String(style(element, transitionDuration.propName));
569
+ var match = duration.match(/([0-9.]+)([ms]{1,2})/);
570
+ if (match) {
571
+ duration = Number(match[1]);
572
+ if (match[2] === 's') {
573
+ duration *= 1000;
574
+ }
575
+ }
576
+ return 0|duration;
577
+ }
578
+ transitionDuration.propName = (function () {
579
+ var element = doc.createElement('div');
580
+ var names = ['transitionDuration', 'webkitTransitionDuration'];
581
+ var value = '1s';
582
+ for (var i = 0; i < names.length; i++) {
583
+ element.style[names[i]] = value;
584
+ if (element.style[names[i]] === value) {
585
+ return names[i];
586
+ }
587
+ }
588
+ }());
589
+
590
+ /**
591
+ * Tooltip construnctor.
592
+ *
593
+ * @param {String|Element} content
594
+ * @param {Object} options
595
+ *
596
+ * @return {Tooltip}
597
+ */
598
+ function Tooltip(content, options) {
599
+ if (!(this instanceof Tooltip)) {
600
+ return new Tooltip(content, options);
601
+ }
602
+ this.hidden = 1;
603
+ this.options = extend(objectCreate(Tooltip.defaults), options);
604
+ this._createElement();
605
+ this.content(content);
606
+ }
607
+
608
+ /**
609
+ * Creates a tooltip element.
610
+ *
611
+ * @return {Void}
612
+ */
613
+ Tooltip.prototype._createElement = function () {
614
+ this.element = doc.createElement('div');
615
+ this.classes = classes(this.element);
616
+ this.classes.add(this.options.baseClass);
617
+ var propName;
618
+ for (var i = 0; i < Tooltip.classTypes.length; i++) {
619
+ propName = Tooltip.classTypes[i] + 'Class';
620
+ if (this.options[propName]) {
621
+ this.classes.add(this.options[propName]);
622
+ }
623
+ }
624
+ };
625
+
626
+ /**
627
+ * Changes tooltip's type class type.
628
+ *
629
+ * @param {String} name
630
+ *
631
+ * @return {Tooltip}
632
+ */
633
+ Tooltip.prototype.type = function (name) {
634
+ return this.changeClassType('type', name);
635
+ };
636
+
637
+ /**
638
+ * Changes tooltip's effect class type.
639
+ *
640
+ * @param {String} name
641
+ *
642
+ * @return {Tooltip}
643
+ */
644
+ Tooltip.prototype.effect = function (name) {
645
+ return this.changeClassType('effect', name);
646
+ };
647
+
648
+ /**
649
+ * Changes class type.
650
+ *
651
+ * @param {String} propName
652
+ * @param {String} newClass
653
+ *
654
+ * @return {Tooltip}
655
+ */
656
+ Tooltip.prototype.changeClassType = function (propName, newClass) {
657
+ propName += 'Class';
658
+ if (this.options[propName]) {
659
+ this.classes.remove(this.options[propName]);
660
+ }
661
+ this.options[propName] = newClass;
662
+ if (newClass) {
663
+ this.classes.add(newClass);
664
+ }
665
+ return this;
666
+ };
667
+
668
+ /**
669
+ * Updates tooltip's dimensions.
670
+ *
671
+ * @return {Tooltip}
672
+ */
673
+ Tooltip.prototype.updateSize = function () {
674
+ if (this.hidden) {
675
+ this.element.style.visibility = 'hidden';
676
+ body.appendChild(this.element);
677
+ }
678
+ this.width = this.element.offsetWidth;
679
+ this.height = this.element.offsetHeight;
680
+ if (this.spacing == null) {
681
+ this.spacing = this.options.spacing != null ? this.options.spacing : parsePx(style(this.element, 'top'));
682
+ }
683
+ if (this.hidden) {
684
+ body.removeChild(this.element);
685
+ this.element.style.visibility = '';
686
+ } else {
687
+ this.position();
688
+ }
689
+ return this;
690
+ };
691
+
692
+ /**
693
+ * Change tooltip content.
694
+ *
695
+ * When tooltip is visible, its size is automatically
696
+ * synced and tooltip correctly repositioned.
697
+ *
698
+ * @param {String|Element} content
699
+ *
700
+ * @return {Tooltip}
701
+ */
702
+ Tooltip.prototype.content = function (content) {
703
+ if (typeof content === 'object') {
704
+ this.element.innerHTML = '';
705
+ this.element.appendChild(content);
706
+ } else {
707
+ this.element.innerHTML = content;
708
+ }
709
+ this.updateSize();
710
+ return this;
711
+ };
712
+
713
+ /**
714
+ * Pick new place tooltip should be displayed at.
715
+ *
716
+ * When the tooltip is visible, it is automatically positioned there.
717
+ *
718
+ * @param {String} place
719
+ *
720
+ * @return {Tooltip}
721
+ */
722
+ Tooltip.prototype.place = function (place) {
723
+ this.options.place = place;
724
+ if (!this.hidden) {
725
+ this.position();
726
+ }
727
+ return this;
728
+ };
729
+
730
+ /**
731
+ * Attach tooltip to an element.
732
+ *
733
+ * @param {Element} element
734
+ *
735
+ * @return {Tooltip}
736
+ */
737
+ Tooltip.prototype.attach = function (element) {
738
+ this.attachedTo = element;
739
+ if (!this.hidden) {
740
+ this.position();
741
+ }
742
+ return this;
743
+ };
744
+
745
+ /**
746
+ * Detach tooltip from element.
747
+ *
748
+ * @return {Tooltip}
749
+ */
750
+ Tooltip.prototype.detach = function () {
751
+ this.hide();
752
+ this.attachedTo = null;
753
+ return this;
754
+ };
755
+
756
+ /**
757
+ * Pick the most reasonable place for target position.
758
+ *
759
+ * @param {Object} target
760
+ *
761
+ * @return {Tooltip}
762
+ */
763
+ Tooltip.prototype._pickPlace = function (target) {
764
+ if (!this.options.auto) {
765
+ return this.options.place;
766
+ }
767
+ var winPos = position(win);
768
+ var place = this.options.place.split('-');
769
+ var spacing = this.spacing;
770
+
771
+ if (~indexOf(verticalPlaces, place[0])) {
772
+ if (target.top - this.height - spacing <= winPos.top) {
773
+ place[0] = 'bottom';
774
+ } else if (target.bottom + this.height + spacing >= winPos.bottom) {
775
+ place[0] = 'top';
776
+ }
777
+ switch (place[1]) {
778
+ case 'left':
779
+ if (target.right - this.width <= winPos.left) {
780
+ place[1] = 'right';
781
+ }
782
+ break;
783
+ case 'right':
784
+ if (target.left + this.width >= winPos.right) {
785
+ place[1] = 'left';
786
+ }
787
+ break;
788
+ default:
789
+ if (target.left + target.width / 2 + this.width / 2 >= winPos.right) {
790
+ place[1] = 'left';
791
+ } else if (target.right - target.width / 2 - this.width / 2 <= winPos.left) {
792
+ place[1] = 'right';
793
+ }
794
+ }
795
+ } else {
796
+ if (target.left - this.width - spacing <= winPos.left) {
797
+ place[0] = 'right';
798
+ } else if (target.right + this.width + spacing >= winPos.right) {
799
+ place[0] = 'left';
800
+ }
801
+ switch (place[1]) {
802
+ case 'top':
803
+ if (target.bottom - this.height <= winPos.top) {
804
+ place[1] = 'bottom';
805
+ }
806
+ break;
807
+ case 'bottom':
808
+ if (target.top + this.height >= winPos.bottom) {
809
+ place[1] = 'top';
810
+ }
811
+ break;
812
+ default:
813
+ if (target.top + target.height / 2 + this.height / 2 >= winPos.bottom) {
814
+ place[1] = 'top';
815
+ } else if (target.bottom - target.height / 2 - this.height / 2 <= winPos.top) {
816
+ place[1] = 'bottom';
817
+ }
818
+ }
819
+ }
820
+
821
+ return place.join('-');
822
+ };
823
+
824
+ /**
825
+ * Position the element to an element or a specific coordinates.
826
+ *
827
+ * @param {Integer|Element} x
828
+ * @param {Integer} y
829
+ *
830
+ * @return {Tooltip}
831
+ */
832
+ Tooltip.prototype.position = function (x, y) {
833
+ if (this.attachedTo) {
834
+ x = this.attachedTo;
835
+ }
836
+ if (x == null && this._p) {
837
+ x = this._p[0];
838
+ y = this._p[1];
839
+ } else {
840
+ this._p = arguments;
841
+ }
842
+ var target = typeof x === 'number' ? {
843
+ left: 0|x,
844
+ right: 0|x,
845
+ top: 0|y,
846
+ bottom: 0|y,
847
+ width: 0,
848
+ height: 0
849
+ } : position(x);
850
+ var spacing = this.spacing;
851
+ var newPlace = this._pickPlace(target);
852
+
853
+ // Add/Change place class when necessary
854
+ if (newPlace !== this.curPlace) {
855
+ if (this.curPlace) {
856
+ this.classes.remove(this.curPlace);
857
+ }
858
+ this.classes.add(newPlace);
859
+ this.curPlace = newPlace;
860
+ }
861
+
862
+ // Position the tip
863
+ var top, left;
864
+ switch (this.curPlace) {
865
+ case 'top':
866
+ top = target.top - this.height - spacing;
867
+ left = target.left + target.width / 2 - this.width / 2;
868
+ break;
869
+ case 'top-left':
870
+ top = target.top - this.height - spacing;
871
+ left = target.right - this.width;
872
+ break;
873
+ case 'top-right':
874
+ top = target.top - this.height - spacing;
875
+ left = target.left;
876
+ break;
877
+
878
+ case 'bottom':
879
+ top = target.bottom + spacing;
880
+ left = target.left + target.width / 2 - this.width / 2;
881
+ break;
882
+ case 'bottom-left':
883
+ top = target.bottom + spacing;
884
+ left = target.right - this.width;
885
+ break;
886
+ case 'bottom-right':
887
+ top = target.bottom + spacing;
888
+ left = target.left;
889
+ break;
890
+
891
+ case 'left':
892
+ top = target.top + target.height / 2 - this.height / 2;
893
+ left = target.left - this.width - spacing;
894
+ break;
895
+ case 'left-top':
896
+ top = target.bottom - this.height;
897
+ left = target.left - this.width - spacing;
898
+ break;
899
+ case 'left-bottom':
900
+ top = target.top;
901
+ left = target.left - this.width - spacing;
902
+ break;
903
+
904
+ case 'right':
905
+ top = target.top + target.height / 2 - this.height / 2;
906
+ left = target.right + spacing;
907
+ break;
908
+ case 'right-top':
909
+ top = target.bottom - this.height;
910
+ left = target.right + spacing;
911
+ break;
912
+ case 'right-bottom':
913
+ top = target.top;
914
+ left = target.right + spacing;
915
+ break;
916
+ }
917
+
918
+ // Set tip position & class
919
+ this.element.style.top = Math.round(top) + 'px';
920
+ this.element.style.left = Math.round(left) + 'px';
921
+
922
+ return this;
923
+ };
924
+
925
+ /**
926
+ * Show the tooltip.
927
+ *
928
+ * @param {Integer|Element} x
929
+ * @param {Integer} y
930
+ *
931
+ * @return {Tooltip}
932
+ */
933
+ Tooltip.prototype.show = function (x, y) {
934
+ x = this.attachedTo ? this.attachedTo : x;
935
+
936
+ // Clear potential ongoing animation
937
+ clearTimeout(this.aIndex);
938
+
939
+ // Position the element when requested
940
+ if (x != null) {
941
+ this.position(x, y);
942
+ }
943
+
944
+ // Stop here if tip is already visible
945
+ if (this.hidden) {
946
+ this.hidden = 0;
947
+ body.appendChild(this.element);
948
+ }
949
+
950
+ // Make tooltip aware of window resize
951
+ if (this.attachedTo) {
952
+ this._aware();
953
+ }
954
+
955
+ // Trigger layout and kick in the transition
956
+ if (this.options.inClass) {
957
+ if (this.options.effectClass) {
958
+ void this.element.clientHeight;
959
+ }
960
+ this.classes.add(this.options.inClass);
961
+ }
962
+
963
+ return this;
964
+ };
965
+
966
+ /**
967
+ * Hide the tooltip.
968
+ *
969
+ * @return {Tooltip}
970
+ */
971
+ Tooltip.prototype.hide = function () {
972
+ if (this.hidden) {
973
+ return;
974
+ }
975
+
976
+ var self = this;
977
+ var duration = 0;
978
+
979
+ // Remove .in class and calculate transition duration if any
980
+ if (this.options.inClass) {
981
+ this.classes.remove(this.options.inClass);
982
+ if (this.options.effectClass) {
983
+ duration = transitionDuration(this.element);
984
+ }
985
+ }
986
+
987
+ // Remove tip from window resize awareness
988
+ if (this.attachedTo) {
989
+ this._unaware();
990
+ }
991
+
992
+ // Remove the tip from the DOM when transition is done
993
+ clearTimeout(this.aIndex);
994
+ this.aIndex = setTimeout(function () {
995
+ self.aIndex = 0;
996
+ body.removeChild(self.element);
997
+ self.hidden = 1;
998
+ }, duration);
999
+
1000
+ return this;
1001
+ };
1002
+
1003
+ Tooltip.prototype.toggle = function (x, y) {
1004
+ return this[this.hidden ? 'show' : 'hide'](x, y);
1005
+ };
1006
+
1007
+ Tooltip.prototype.destroy = function () {
1008
+ clearTimeout(this.aIndex);
1009
+ this._unaware();
1010
+ if (!this.hidden) {
1011
+ body.removeChild(this.element);
1012
+ }
1013
+ this.element = this.options = null;
1014
+ };
1015
+
1016
+ /**
1017
+ * Make the tip window resize aware.
1018
+ *
1019
+ * @return {Void}
1020
+ */
1021
+ Tooltip.prototype._aware = function () {
1022
+ var index = indexOf(Tooltip.winAware, this);
1023
+ if (!~index) {
1024
+ Tooltip.winAware.push(this);
1025
+ }
1026
+ };
1027
+
1028
+ /**
1029
+ * Remove the window resize awareness.
1030
+ *
1031
+ * @return {Void}
1032
+ */
1033
+ Tooltip.prototype._unaware = function () {
1034
+ var index = indexOf(Tooltip.winAware, this);
1035
+ if (~index) {
1036
+ Tooltip.winAware.splice(index, 1);
1037
+ }
1038
+ };
1039
+
1040
+ /**
1041
+ * Handles repositioning of tooltips on window resize.
1042
+ *
1043
+ * @return {Void}
1044
+ */
1045
+ Tooltip.reposition = (function () {
1046
+ var rAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function (fn) {
1047
+ return setTimeout(fn, 17);
1048
+ };
1049
+ var rIndex;
1050
+
1051
+ function requestReposition() {
1052
+ if (rIndex || !Tooltip.winAware.length) {
1053
+ return;
1054
+ }
1055
+ rIndex = rAF(reposition, 17);
1056
+ }
1057
+
1058
+ function reposition() {
1059
+ rIndex = 0;
1060
+ var tip;
1061
+ for (var i = 0, l = Tooltip.winAware.length; i < l; i++) {
1062
+ tip = Tooltip.winAware[i];
1063
+ tip.position();
1064
+ }
1065
+ }
1066
+
1067
+ return requestReposition;
1068
+ }());
1069
+ Tooltip.winAware = [];
1070
+
1071
+ // Bind winAware repositioning to window resize event
1072
+ evt.bind(window, 'resize', Tooltip.reposition);
1073
+ evt.bind(window, 'scroll', Tooltip.reposition);
1074
+
1075
+ /**
1076
+ * Array with dynamic class types.
1077
+ *
1078
+ * @type {Array}
1079
+ */
1080
+ Tooltip.classTypes = ['type', 'effect'];
1081
+
1082
+ /**
1083
+ * Default options for Tooltip constructor.
1084
+ *
1085
+ * @type {Object}
1086
+ */
1087
+ Tooltip.defaults = {
1088
+ baseClass: 'tooltip', // Base tooltip class name.
1089
+ typeClass: null, // Type tooltip class name.
1090
+ effectClass: null, // Effect tooltip class name.
1091
+ inClass: 'in', // Class used to transition stuff in.
1092
+ place: 'top', // Default place.
1093
+ spacing: null, // Gap between target and tooltip.
1094
+ auto: 0 // Whether to automatically adjust place to fit into window.
1095
+ };
1096
+ });
1097
+
1098
+ require.register("code42day~dataset@0.3.0", function (exports, module) {
1099
+ module.exports=dataset;
1100
+
1101
+ /*global document*/
1102
+
1103
+
1104
+ // replace namesLikeThis with names-like-this
1105
+ function toDashed(name) {
1106
+ return name.replace(/([A-Z])/g, function(u) {
1107
+ return "-" + u.toLowerCase();
1108
+ });
1109
+ }
1110
+
1111
+ var fn;
1112
+
1113
+ if (document.head && document.head.dataset) {
1114
+ fn = {
1115
+ set: function(node, attr, value) {
1116
+ node.dataset[attr] = value;
1117
+ },
1118
+ get: function(node, attr) {
1119
+ return node.dataset[attr];
1120
+ },
1121
+ del: function (node, attr) {
1122
+ delete node.dataset[attr];
1123
+ }
1124
+ };
1125
+ } else {
1126
+ fn = {
1127
+ set: function(node, attr, value) {
1128
+ node.setAttribute('data-' + toDashed(attr), value);
1129
+ },
1130
+ get: function(node, attr) {
1131
+ return node.getAttribute('data-' + toDashed(attr));
1132
+ },
1133
+ del: function (node, attr) {
1134
+ node.removeAttribute('data-' + toDashed(attr));
1135
+ }
1136
+ };
1137
+ }
1138
+
1139
+ function dataset(node, attr, value) {
1140
+ var self = {
1141
+ set: set,
1142
+ get: get,
1143
+ del: del
1144
+ };
1145
+
1146
+ function set(attr, value) {
1147
+ fn.set(node, attr, value);
1148
+ return self;
1149
+ }
1150
+
1151
+ function del(attr) {
1152
+ fn.del(node, attr);
1153
+ return self;
1154
+ }
1155
+
1156
+ function get(attr) {
1157
+ return fn.get(node, attr);
1158
+ }
1159
+
1160
+ if (arguments.length === 3) {
1161
+ return set(attr, value);
1162
+ }
1163
+ if (arguments.length == 2) {
1164
+ return get(attr);
1165
+ }
1166
+
1167
+ return self;
1168
+ }
1169
+
1170
+ });
1171
+
1172
+ require.register("tooltips", function (exports, module) {
1173
+ 'use strict';
1174
+
1175
+ /**
1176
+ * Dependencies.
1177
+ */
1178
+ var evt = require('darsain~event@0.1.0');
1179
+ var indexOf = require('component~indexof@0.0.3');
1180
+ var Tooltip = require('darsain~tooltip@0.1.0');
1181
+ var dataset = require('code42day~dataset@0.3.0');
1182
+
1183
+ /**
1184
+ * Transport.
1185
+ */
1186
+ module.exports = Tooltips;
1187
+
1188
+ /**
1189
+ * Globals.
1190
+ */
1191
+ var MObserver = window.MutationObserver || window.WebkitMutationObserver;
1192
+
1193
+ /**
1194
+ * Prototypal inheritance.
1195
+ *
1196
+ * @param {Object} o
1197
+ *
1198
+ * @return {Object}
1199
+ */
1200
+ var objectCreate = Object.create || (function () {
1201
+ function F() {}
1202
+ return function (o) {
1203
+ F.prototype = o;
1204
+ return new F();
1205
+ };
1206
+ })();
1207
+
1208
+ /**
1209
+ * Poor man's shallow object extend.
1210
+ *
1211
+ * @param {Object} a
1212
+ * @param {Object} b
1213
+ *
1214
+ * @return {Object}
1215
+ */
1216
+ function extend(a, b) {
1217
+ for (var key in b) {
1218
+ a[key] = b[key];
1219
+ }
1220
+ return a;
1221
+ }
1222
+
1223
+ /**
1224
+ * Capitalize the first letter of a string.
1225
+ *
1226
+ * @param {String} string
1227
+ *
1228
+ * @return {String}
1229
+ */
1230
+ function ucFirst(string) {
1231
+ return string.charAt(0).toUpperCase() + string.slice(1);
1232
+ }
1233
+
1234
+ /**
1235
+ * Tooltips constructor.
1236
+ *
1237
+ * @param {Element} container
1238
+ * @param {Object} options
1239
+ *
1240
+ * @return {Tooltips}
1241
+ */
1242
+ function Tooltips(container, options) {
1243
+ if (!(this instanceof Tooltips)) {
1244
+ return new Tooltips(container, options);
1245
+ }
1246
+
1247
+ var self = this;
1248
+ var observer, TID;
1249
+
1250
+ /**
1251
+ * Show tooltip attached to an element.
1252
+ *
1253
+ * @param {Element} element
1254
+ *
1255
+ * @return {Tooltips}
1256
+ */
1257
+ self.show = function (element) {
1258
+ return callTooltipMethod(element, 'show');
1259
+ };
1260
+
1261
+ /**
1262
+ * Hide tooltip attached to an element.
1263
+ *
1264
+ * @param {Element} element
1265
+ *
1266
+ * @return {Tooltips}
1267
+ */
1268
+ self.hide = function (element) {
1269
+ return callTooltipMethod(element, 'hide');
1270
+ };
1271
+
1272
+ /**
1273
+ * Toggle tooltip attached to an element.
1274
+ *
1275
+ * @param {Element} element
1276
+ *
1277
+ * @return {Tooltips}
1278
+ */
1279
+ self.toggle = function (element) {
1280
+ return callTooltipMethod(element, 'toggle');
1281
+ };
1282
+
1283
+ /**
1284
+ * Retrieve tooltip attached to an element and call it's method.
1285
+ *
1286
+ * @param {Element} element
1287
+ * @param {String} method
1288
+ *
1289
+ * @return {Tooltips}
1290
+ */
1291
+ function callTooltipMethod(element, method) {
1292
+ var tip = self.get(element);
1293
+ if (tip) {
1294
+ tip[method]();
1295
+ }
1296
+ return self;
1297
+ }
1298
+
1299
+ /**
1300
+ * Return a tooltip attached to an element. Tooltip is created if it doesn't exist yet.
1301
+ *
1302
+ * @param {Element} element
1303
+ *
1304
+ * @return {Tooltip}
1305
+ */
1306
+ self.get = function (element) {
1307
+ var tip = !!element && (element[TID] || createTip(element));
1308
+ if (tip && !element[TID]) {
1309
+ element[TID] = tip;
1310
+ }
1311
+ return tip;
1312
+ };
1313
+
1314
+ /**
1315
+ * Add element(s) to Tooltips instance.
1316
+ *
1317
+ * @param {[type]} element Can be element, or container containing elements to be added.
1318
+ *
1319
+ * @return {Tooltips}
1320
+ */
1321
+ self.add = function (element) {
1322
+ if (!element || element.nodeType !== 1) {
1323
+ return self;
1324
+ }
1325
+ if (dataset(element).get(options.key)) {
1326
+ bindElement(element);
1327
+ } else if (element.children) {
1328
+ bindElements(element.querySelectorAll(self.selector));
1329
+ }
1330
+ return self;
1331
+ };
1332
+
1333
+ /**
1334
+ * Remove element(s) from Tooltips instance.
1335
+ *
1336
+ * @param {Element} element Can be element, or container containing elements to be removed.
1337
+ *
1338
+ * @return {Tooltips}
1339
+ */
1340
+ self.remove = function (element) {
1341
+ if (!element || element.nodeType !== 1) {
1342
+ return self;
1343
+ }
1344
+ if (dataset(element).get(options.key)) {
1345
+ unbindElement(element);
1346
+ } else if (element.children) {
1347
+ unbindElements(element.querySelectorAll(self.selector));
1348
+ }
1349
+ return self;
1350
+ };
1351
+
1352
+ /**
1353
+ * Reload Tooltips instance.
1354
+ *
1355
+ * Unbinds current tooltipped elements, than selects the
1356
+ * data-key elements from container and binds them again.
1357
+ *
1358
+ * @return {Tooltips}
1359
+ */
1360
+ self.reload = function () {
1361
+ // Unbind old elements
1362
+ unbindElements(self.elements);
1363
+ // Bind new elements
1364
+ bindElements(self.container.querySelectorAll(self.selector));
1365
+ return self;
1366
+ };
1367
+
1368
+ /**
1369
+ * Destroy Tooltips instance.
1370
+ *
1371
+ * @return {Void}
1372
+ */
1373
+ self.destroy = function () {
1374
+ unbindElements(this.elements);
1375
+ if (observer) {
1376
+ observer.disconnect();
1377
+ }
1378
+ this.container = this.elements = this.options = observer = null;
1379
+ };
1380
+
1381
+ /**
1382
+ * Create a tip from element data attributes.
1383
+ *
1384
+ * @param {Element} element
1385
+ *
1386
+ * @return {Tooltip}
1387
+ */
1388
+ function createTip(element) {
1389
+ var data = dataset(element);
1390
+ var content = data.get(options.key);
1391
+ if (!content) {
1392
+ return false;
1393
+ }
1394
+ var tipOptions = objectCreate(options.tooltip);
1395
+ var keyData;
1396
+ for (var key in Tooltip.defaults) {
1397
+ keyData = data.get(options.key + ucFirst(key.replace(/Class$/, '')));
1398
+ if (!keyData) {
1399
+ continue;
1400
+ }
1401
+ tipOptions[key] = keyData;
1402
+ }
1403
+ return new Tooltip(content, tipOptions).attach(element);
1404
+ }
1405
+
1406
+ /**
1407
+ * Bind Tooltips events to Array/NodeList of elements.
1408
+ *
1409
+ * @param {Array} elements
1410
+ *
1411
+ * @return {Void}
1412
+ */
1413
+ function bindElements(elements) {
1414
+ for (var i = 0, l = elements.length; i < l; i++) {
1415
+ bindElement(elements[i]);
1416
+ }
1417
+ }
1418
+
1419
+ /**
1420
+ * Bind Tooltips events to element.
1421
+ *
1422
+ * @param {Element} element
1423
+ *
1424
+ * @return {Void}
1425
+ */
1426
+ function bindElement(element) {
1427
+ if (element[TID] || ~indexOf(self.elements, element)) {
1428
+ return;
1429
+ }
1430
+ evt.bind(element, options.showOn, eventHandler);
1431
+ evt.bind(element, options.hideOn, eventHandler);
1432
+ self.elements.push(element);
1433
+ }
1434
+
1435
+ /**
1436
+ * Unbind Tooltips events from Array/NodeList of elements.
1437
+ *
1438
+ * @param {Array} elements
1439
+ *
1440
+ * @return {Void}
1441
+ */
1442
+ function unbindElements(elements) {
1443
+ if (self.elements === elements) {
1444
+ elements = elements.slice();
1445
+ }
1446
+ for (var i = 0, l = elements.length; i < l; i++) {
1447
+ unbindElement(elements[i]);
1448
+ }
1449
+ }
1450
+
1451
+ /**
1452
+ * Unbind Tooltips events from element.
1453
+ *
1454
+ * @param {Element} element
1455
+ *
1456
+ * @return {Void}
1457
+ */
1458
+ function unbindElement(element) {
1459
+ var index = indexOf(self.elements, element);
1460
+ if (!~index) {
1461
+ return;
1462
+ }
1463
+ if (element[TID]) {
1464
+ element[TID].destroy();
1465
+ delete element[TID];
1466
+ }
1467
+ evt.unbind(element, options.showOn, eventHandler);
1468
+ evt.unbind(element, options.hideOn, eventHandler);
1469
+ self.elements.splice(index, 1);
1470
+ }
1471
+
1472
+ /**
1473
+ * Tooltips events handler.
1474
+ *
1475
+ * @param {Event} event
1476
+ *
1477
+ * @return {Void}
1478
+ */
1479
+ function eventHandler(event) {
1480
+ /*jshint validthis:true */
1481
+ if (options.showOn === options.hideOn) {
1482
+ self.toggle(this);
1483
+ } else {
1484
+ self[event.type === options.showOn ? 'show' : 'hide'](this);
1485
+ }
1486
+ }
1487
+
1488
+ /**
1489
+ * Mutations handler.
1490
+ *
1491
+ * @param {Array} mutations
1492
+ *
1493
+ * @return {Void}
1494
+ */
1495
+ function mutationsHandler(mutations) {
1496
+ var added, removed, i, l;
1497
+ for (var m = 0, ml = mutations.length; m < ml; m++) {
1498
+ added = mutations[m].addedNodes;
1499
+ removed = mutations[m].removedNodes;
1500
+ for (i = 0, l = added.length; i < l; i++) {
1501
+ self.add(added[i]);
1502
+ }
1503
+ for (i = 0, l = removed.length; i < l; i++) {
1504
+ self.remove(removed[i]);
1505
+ }
1506
+ }
1507
+ }
1508
+
1509
+ // Construct
1510
+ (function () {
1511
+ self.container = container;
1512
+ self.options = options = extend(objectCreate(Tooltips.defaults), options);
1513
+ self.ID = TID = options.key + Math.random().toString(36).slice(2);
1514
+ self.elements = [];
1515
+
1516
+ // Create tips selector
1517
+ self.selector = '[data-' + options.key + ']';
1518
+
1519
+ // Load tips
1520
+ self.reload();
1521
+
1522
+ // Create mutations observer
1523
+ if (options.observe && MObserver) {
1524
+ observer = new MObserver(mutationsHandler);
1525
+ observer.observe(self.container, {
1526
+ childList: true,
1527
+ subtree: true
1528
+ });
1529
+ }
1530
+ }());
1531
+ }
1532
+
1533
+ /**
1534
+ * Expose Tooltip.
1535
+ */
1536
+ Tooltips.Tooltip = Tooltip;
1537
+
1538
+ /**
1539
+ * Default Tooltips options.
1540
+ *
1541
+ * @type {Object}
1542
+ */
1543
+ Tooltips.defaults = {
1544
+ tooltip: {}, // Options for individual Tooltip instances.
1545
+ key: 'tooltip', // Tooltips data attribute key.
1546
+ showOn: 'mouseenter', // Show tooltip event.
1547
+ hideOn: 'mouseleave', // Hide tooltip event.
1548
+ observe: 0 // Enable mutation observer (used only when supported).
1549
+ };
1550
+ });
1551
+
1552
+ if (typeof exports == "object") {
1553
+ module.exports = require("tooltips");
1554
+ } else if (typeof define == "function" && define.amd) {
1555
+ define("Tooltips", [], function(){ return require("tooltips"); });
1556
+ } else {
1557
+ (this || window)["Tooltips"] = require("tooltips");
1558
+ }
1559
+ })()