tui_image_editor 0.1.0

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.
@@ -0,0 +1,3228 @@
1
+ /*!
2
+ * Toast UI Colorpicker
3
+ * @version 2.2.0
4
+ * @author NHNEnt FE Development Team <dl_javascript@nhnent.com>
5
+ * @license MIT
6
+ */
7
+ (function webpackUniversalModuleDefinition(root, factory) {
8
+ if (typeof exports === 'object' && typeof module === 'object')
9
+ module.exports = factory(require("tui-code-snippet"));
10
+ else if (typeof define === 'function' && define.amd)
11
+ define(["tui-code-snippet"], factory);
12
+ else if (typeof exports === 'object')
13
+ exports["colorPicker"] = factory(require("tui-code-snippet"));
14
+ else
15
+ root["tui"] = root["tui"] || {}, root["tui"]["colorPicker"] = factory((root["tui"] && root["tui"]["util"]));
16
+ })(this, function (__WEBPACK_EXTERNAL_MODULE_8__) {
17
+ return /******/ (function (modules) { // webpackBootstrap
18
+ /******/ // The module cache
19
+ /******/ var installedModules = {};
20
+
21
+ /******/ // The require function
22
+ /******/ function __webpack_require__(moduleId) {
23
+
24
+ /******/ // Check if module is in cache
25
+ /******/ if (installedModules[moduleId])
26
+ /******/ return installedModules[moduleId].exports;
27
+
28
+ /******/ // Create a new module (and put it into the cache)
29
+ /******/ var module = installedModules[moduleId] = {
30
+ /******/ exports: {},
31
+ /******/ id: moduleId,
32
+ /******/ loaded: false
33
+ /******/
34
+ };
35
+
36
+ /******/ // Execute the module function
37
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
38
+
39
+ /******/ // Flag the module as loaded
40
+ /******/ module.loaded = true;
41
+
42
+ /******/ // Return the exports of the module
43
+ /******/ return module.exports;
44
+ /******/
45
+ }
46
+
47
+
48
+ /******/ // expose the modules object (__webpack_modules__)
49
+ /******/ __webpack_require__.m = modules;
50
+
51
+ /******/ // expose the module cache
52
+ /******/ __webpack_require__.c = installedModules;
53
+
54
+ /******/ // __webpack_public_path__
55
+ /******/ __webpack_require__.p = "dist";
56
+
57
+ /******/ // Load entry module and return exports
58
+ /******/ return __webpack_require__(0);
59
+ /******/
60
+ })
61
+ /************************************************************************/
62
+ /******/([
63
+ /* 0 */
64
+ /***/ (function (module, exports, __webpack_require__) {
65
+
66
+ __webpack_require__(1);
67
+ module.exports = __webpack_require__(6);
68
+
69
+
70
+ /***/
71
+ }),
72
+ /* 1 */
73
+ /***/ (function (module, exports) {
74
+
75
+ // removed by extract-text-webpack-plugin
76
+
77
+ /***/
78
+ }),
79
+ /* 2 */,
80
+ /* 3 */,
81
+ /* 4 */,
82
+ /* 5 */,
83
+ /* 6 */
84
+ /***/ (function (module, exports, __webpack_require__) {
85
+
86
+ 'use strict';
87
+
88
+ var domutil = __webpack_require__(7);
89
+ var domevent = __webpack_require__(9);
90
+ var Collection = __webpack_require__(10);
91
+ var View = __webpack_require__(11);
92
+ var Drag = __webpack_require__(12);
93
+ var create = __webpack_require__(13);
94
+ var Palette = __webpack_require__(16);
95
+ var Slider = __webpack_require__(18);
96
+ var colorutil = __webpack_require__(14);
97
+ var svgvml = __webpack_require__(19);
98
+
99
+ var colorPicker = {
100
+ domutil: domutil,
101
+ domevent: domevent,
102
+ Collection: Collection,
103
+ View: View,
104
+ Drag: Drag,
105
+
106
+ create: create,
107
+ Palette: Palette,
108
+ Slider: Slider,
109
+ colorutil: colorutil,
110
+ svgvml: svgvml
111
+ };
112
+
113
+ module.exports = colorPicker;
114
+
115
+ /***/
116
+ }),
117
+ /* 7 */
118
+ /***/ (function (module, exports, __webpack_require__) {
119
+
120
+ /**
121
+ * @fileoverview Utility modules for manipulate DOM elements.
122
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
123
+ */
124
+
125
+ 'use strict';
126
+
127
+ var snippet = __webpack_require__(8);
128
+ var domevent = __webpack_require__(9);
129
+ var Collection = __webpack_require__(10);
130
+
131
+ var util = snippet,
132
+ posKey = '_pos',
133
+ supportSelectStart = 'onselectstart' in document,
134
+ prevSelectStyle = '',
135
+ domutil,
136
+ userSelectProperty;
137
+
138
+ var CSS_AUTO_REGEX = /^auto$|^$|%/;
139
+
140
+ function trim(str) {
141
+ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
142
+ }
143
+
144
+ domutil = {
145
+ /**
146
+ * Create DOM element and return it.
147
+ * @param {string} tagName Tag name to append.
148
+ * @param {HTMLElement} [container] HTML element will be parent to created element.
149
+ * if not supplied, will use **document.body**
150
+ * @param {string} [className] Design class names to appling created element.
151
+ * @returns {HTMLElement} HTML element created.
152
+ */
153
+ appendHTMLElement: function (tagName, container, className) {
154
+ var el;
155
+
156
+ className = className || '';
157
+
158
+ el = document.createElement(tagName);
159
+ el.className = className;
160
+
161
+ if (container) {
162
+ container.appendChild(el);
163
+ } else {
164
+ document.body.appendChild(el);
165
+ }
166
+
167
+ return el;
168
+ },
169
+
170
+ /**
171
+ * Remove element from parent node.
172
+ * @param {HTMLElement} el - element to remove.
173
+ */
174
+ remove: function (el) {
175
+ if (el && el.parentNode) {
176
+ el.parentNode.removeChild(el);
177
+ }
178
+ },
179
+
180
+ /**
181
+ * Get element by id
182
+ * @param {string} id element id attribute
183
+ * @returns {HTMLElement} element
184
+ */
185
+ get: function (id) {
186
+ return document.getElementById(id);
187
+ },
188
+
189
+ /**
190
+ * Check supplied element is matched selector.
191
+ * @param {HTMLElement} el - element to check
192
+ * @param {string} selector - selector string to check
193
+ * @returns {boolean} match?
194
+ */
195
+ _matcher: function (el, selector) {
196
+ var cssClassSelector = /^\./,
197
+ idSelector = /^#/;
198
+
199
+ if (cssClassSelector.test(selector)) {
200
+ return domutil.hasClass(el, selector.replace('.', ''));
201
+ } else if (idSelector.test(selector)) {
202
+ return el.id === selector.replace('#', '');
203
+ }
204
+
205
+ return el.nodeName.toLowerCase() === selector.toLowerCase();
206
+ },
207
+
208
+ /**
209
+ * Find DOM element by specific selectors.
210
+ * below three selector only supported.
211
+ *
212
+ * 1. css selector
213
+ * 2. id selector
214
+ * 3. nodeName selector
215
+ * @param {string} selector selector
216
+ * @param {(HTMLElement|string)} [root] You can assign root element to find. if not supplied, document.body will use.
217
+ * @param {boolean|function} [multiple=false] - set true then return all elements that meet condition, if set function then use it filter function.
218
+ * @returns {HTMLElement} HTML element finded.
219
+ */
220
+ find: function (selector, root, multiple) {
221
+ var result = [],
222
+ found = false,
223
+ isFirst = util.isUndefined(multiple) || multiple === false,
224
+ isFilter = util.isFunction(multiple);
225
+
226
+ if (util.isString(root)) {
227
+ root = domutil.get(root);
228
+ }
229
+
230
+ root = root || window.document.body;
231
+
232
+ function recurse(el, selector) {
233
+ var childNodes = el.childNodes,
234
+ i = 0,
235
+ len = childNodes.length,
236
+ cursor;
237
+
238
+ for (; i < len; i += 1) {
239
+ cursor = childNodes[i];
240
+
241
+ if (cursor.nodeName === '#text') {
242
+ continue;
243
+ }
244
+
245
+ if (domutil._matcher(cursor, selector)) {
246
+ if (isFilter && multiple(cursor) || !isFilter) {
247
+ result.push(cursor);
248
+ }
249
+
250
+ if (isFirst) {
251
+ found = true;
252
+ break;
253
+ }
254
+ } else if (cursor.childNodes.length > 0) {
255
+ recurse(cursor, selector);
256
+ if (found) {
257
+ break;
258
+ }
259
+ }
260
+ }
261
+ }
262
+
263
+ recurse(root, selector);
264
+
265
+ return isFirst ? result[0] || null : result;
266
+ },
267
+
268
+ /**
269
+ * Find parent element recursively.
270
+ * @param {HTMLElement} el - base element to start find.
271
+ * @param {string} selector - selector string for find
272
+ * @returns {HTMLElement} - element finded or undefined.
273
+ */
274
+ closest: function (el, selector) {
275
+ var parent = el.parentNode;
276
+
277
+ if (domutil._matcher(el, selector)) {
278
+ return el;
279
+ }
280
+
281
+ while (parent && parent !== window.document.body) {
282
+ if (domutil._matcher(parent, selector)) {
283
+ return parent;
284
+ }
285
+
286
+ parent = parent.parentNode;
287
+ }
288
+ },
289
+
290
+ /**
291
+ * Return texts inside element.
292
+ * @param {HTMLElement} el target element
293
+ * @returns {string} text inside node
294
+ */
295
+ text: function (el) {
296
+ var ret = '',
297
+ i = 0,
298
+ nodeType = el.nodeType;
299
+
300
+ if (nodeType) {
301
+ if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
302
+ // nodes that available contain other nodes
303
+ if (typeof el.textContent === 'string') {
304
+ return el.textContent;
305
+ }
306
+
307
+ for (el = el.firstChild; el; el = el.nextSibling) {
308
+ ret += domutil.text(el);
309
+ }
310
+ } else if (nodeType === 3 || nodeType === 4) {
311
+ // TEXT, CDATA SECTION
312
+ return el.nodeValue;
313
+ }
314
+ } else {
315
+ for (; el[i]; i += 1) {
316
+ ret += domutil.text(el[i]);
317
+ }
318
+ }
319
+
320
+ return ret;
321
+ },
322
+
323
+ /**
324
+ * Set data attribute to target element
325
+ * @param {HTMLElement} el - element to set data attribute
326
+ * @param {string} key - key
327
+ * @param {string|number} data - data value
328
+ */
329
+ setData: function (el, key, data) {
330
+ if ('dataset' in el) {
331
+ el.dataset[key] = data;
332
+
333
+ return;
334
+ }
335
+
336
+ el.setAttribute('data-' + key, data);
337
+ },
338
+
339
+ /**
340
+ * Get data value from data-attribute
341
+ * @param {HTMLElement} el - target element
342
+ * @param {string} key - key
343
+ * @returns {string} value
344
+ */
345
+ getData: function (el, key) {
346
+ if ('dataset' in el) {
347
+ return el.dataset[key];
348
+ }
349
+
350
+ return el.getAttribute('data-' + key);
351
+ },
352
+
353
+ /**
354
+ * Check element has specific design class name.
355
+ * @param {HTMLElement} el target element
356
+ * @param {string} name css class
357
+ * @returns {boolean} return true when element has that css class name
358
+ */
359
+ hasClass: function (el, name) {
360
+ var className;
361
+
362
+ if (!util.isUndefined(el.classList)) {
363
+ return el.classList.contains(name);
364
+ }
365
+
366
+ className = domutil.getClass(el);
367
+
368
+ return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
369
+ },
370
+
371
+ /**
372
+ * Add design class to HTML element.
373
+ * @param {HTMLElement} el target element
374
+ * @param {string} name css class name
375
+ */
376
+ addClass: function (el, name) {
377
+ var className;
378
+
379
+ if (!util.isUndefined(el.classList)) {
380
+ util.forEachArray(name.split(' '), function (value) {
381
+ el.classList.add(value);
382
+ });
383
+ } else if (!domutil.hasClass(el, name)) {
384
+ className = domutil.getClass(el);
385
+ domutil.setClass(el, (className ? className + ' ' : '') + name);
386
+ }
387
+ },
388
+
389
+ /**
390
+ *
391
+ * Overwrite design class to HTML element.
392
+ * @param {HTMLElement} el target element
393
+ * @param {string} name css class name
394
+ */
395
+ setClass: function (el, name) {
396
+ if (util.isUndefined(el.className.baseVal)) {
397
+ el.className = name;
398
+ } else {
399
+ el.className.baseVal = name;
400
+ }
401
+ },
402
+
403
+ /**
404
+ * Element에 cssClass속성을 ì œê±°í•˜ëŠ” 메서드
405
+ * Remove specific design class from HTML element.
406
+ * @param {HTMLElement} el target element
407
+ * @param {string} name class name to remove
408
+ */
409
+ removeClass: function (el, name) {
410
+ var removed = '';
411
+
412
+ if (!util.isUndefined(el.classList)) {
413
+ el.classList.remove(name);
414
+ } else {
415
+ removed = (' ' + domutil.getClass(el) + ' ').replace(' ' + name + ' ', ' ');
416
+ domutil.setClass(el, trim(removed));
417
+ }
418
+ },
419
+
420
+ /**
421
+ * Get HTML element's design classes.
422
+ * @param {HTMLElement} el target element
423
+ * @returns {string} element css class name
424
+ */
425
+ getClass: function (el) {
426
+ if (!el || !el.className) {
427
+ return '';
428
+ }
429
+
430
+ return util.isUndefined(el.className.baseVal) ? el.className : el.className.baseVal;
431
+ },
432
+
433
+ /**
434
+ * Get specific CSS style value from HTML element.
435
+ * @param {HTMLElement} el target element
436
+ * @param {string} style css attribute name
437
+ * @returns {(string|null)} css style value
438
+ */
439
+ getStyle: function (el, style) {
440
+ var value = el.style[style] || el.currentStyle && el.currentStyle[style],
441
+ css;
442
+
443
+ if ((!value || value === 'auto') && document.defaultView) {
444
+ css = document.defaultView.getComputedStyle(el, null);
445
+ value = css ? css[style] : null;
446
+ }
447
+
448
+ return value === 'auto' ? null : value;
449
+ },
450
+
451
+ /**
452
+ * get element's computed style values.
453
+ *
454
+ * in lower IE8. use polyfill function that return object. it has only one function 'getPropertyValue'
455
+ * @param {HTMLElement} el - element want to get style.
456
+ * @returns {object} virtual CSSStyleDeclaration object.
457
+ */
458
+ getComputedStyle: function (el) {
459
+ var defaultView = document.defaultView;
460
+
461
+ if (!defaultView || !defaultView.getComputedStyle) {
462
+ return {
463
+ getPropertyValue: function (prop) {
464
+ var re = /(\-([a-z]){1})/g;
465
+ if (prop === 'float') {
466
+ prop = 'styleFloat';
467
+ }
468
+
469
+ if (re.test(prop)) {
470
+ prop = prop.replace(re, function () {
471
+ return arguments[2].toUpperCase();
472
+ });
473
+ }
474
+
475
+ return el.currentStyle[prop] ? el.currentStyle[prop] : null;
476
+ }
477
+ };
478
+ }
479
+
480
+ return document.defaultView.getComputedStyle(el);
481
+ },
482
+
483
+ /**
484
+ * Set position CSS style.
485
+ * @param {HTMLElement} el target element
486
+ * @param {number} [x=0] left pixel value.
487
+ * @param {number} [y=0] top pixel value.
488
+ */
489
+ setPosition: function (el, x, y) {
490
+ x = util.isUndefined(x) ? 0 : x;
491
+ y = util.isUndefined(y) ? 0 : y;
492
+
493
+ el[posKey] = [x, y];
494
+
495
+ el.style.left = x + 'px';
496
+ el.style.top = y + 'px';
497
+ },
498
+
499
+ /**
500
+ * Get position from HTML element.
501
+ * @param {HTMLElement} el target element
502
+ * @param {boolean} [clear=false] clear cache before calculating position.
503
+ * @returns {number[]} point
504
+ */
505
+ getPosition: function (el, clear) {
506
+ var left, top, bound;
507
+
508
+ if (clear) {
509
+ el[posKey] = null;
510
+ }
511
+
512
+ if (el[posKey]) {
513
+ return el[posKey];
514
+ }
515
+
516
+ left = 0;
517
+ top = 0;
518
+
519
+ if ((CSS_AUTO_REGEX.test(el.style.left) || CSS_AUTO_REGEX.test(el.style.top)) && 'getBoundingClientRect' in el) {
520
+ // 엘리먼트의 left또는 top이 'auto'일 때 수단
521
+ bound = el.getBoundingClientRect();
522
+
523
+ left = bound.left;
524
+ top = bound.top;
525
+ } else {
526
+ left = parseFloat(el.style.left || 0);
527
+ top = parseFloat(el.style.top || 0);
528
+ }
529
+
530
+ return [left, top];
531
+ },
532
+
533
+ /**
534
+ * Return element's size
535
+ * @param {HTMLElement} el target element
536
+ * @returns {number[]} width, height
537
+ */
538
+ getSize: function (el) {
539
+ var bound,
540
+ width = domutil.getStyle(el, 'width'),
541
+ height = domutil.getStyle(el, 'height');
542
+
543
+ if ((CSS_AUTO_REGEX.test(width) || CSS_AUTO_REGEX.test(height)) && 'getBoundingClientRect' in el) {
544
+ bound = el.getBoundingClientRect();
545
+ width = bound.width;
546
+ height = bound.height;
547
+ } else {
548
+ width = parseFloat(width || 0);
549
+ height = parseFloat(height || 0);
550
+ }
551
+
552
+ return [width, height];
553
+ },
554
+
555
+ /**
556
+ * Check specific CSS style is available.
557
+ * @param {array} props property name to testing
558
+ * @returns {(string|boolean)} return true when property is available
559
+ * @example
560
+ * var props = ['transform', '-webkit-transform'];
561
+ * domutil.testProp(props); // 'transform'
562
+ */
563
+ testProp: function (props) {
564
+ var style = document.documentElement.style,
565
+ i = 0,
566
+ len = props.length;
567
+
568
+ for (; i < len; i += 1) {
569
+ if (props[i] in style) {
570
+ return props[i];
571
+ }
572
+ }
573
+
574
+ return false;
575
+ },
576
+
577
+ /**
578
+ * Get form data
579
+ * @param {HTMLFormElement} formElement - form element to extract data
580
+ * @returns {object} form data
581
+ */
582
+ getFormData: function (formElement) {
583
+ var groupedByName = new Collection(function () {
584
+ return this.length;
585
+ }),
586
+ noDisabledFilter = function (el) {
587
+ return !el.disabled;
588
+ },
589
+ output = {};
590
+
591
+ groupedByName.add.apply(groupedByName, domutil.find('input', formElement, noDisabledFilter).concat(domutil.find('select', formElement, noDisabledFilter)).concat(domutil.find('textarea', formElement, noDisabledFilter)));
592
+
593
+ groupedByName = groupedByName.groupBy(function (el) {
594
+ return el && el.getAttribute('name') || '_other';
595
+ });
596
+
597
+ util.forEach(groupedByName, function (elements, name) {
598
+ if (name === '_other') {
599
+ return;
600
+ }
601
+
602
+ elements.each(function (el) {
603
+ var nodeName = el.nodeName.toLowerCase(),
604
+ type = el.type,
605
+ result = [];
606
+
607
+ if (type === 'radio') {
608
+ result = [elements.find(function (el) {
609
+ return el.checked;
610
+ }).toArray().pop()];
611
+ } else if (type === 'checkbox') {
612
+ result = elements.find(function (el) {
613
+ return el.checked;
614
+ }).toArray();
615
+ } else if (nodeName === 'select') {
616
+ elements.find(function (el) {
617
+ return !!el.childNodes.length;
618
+ }).each(function (el) {
619
+ result = result.concat(domutil.find('option', el, function (opt) {
620
+ return opt.selected;
621
+ }));
622
+ });
623
+ } else {
624
+ result = elements.find(function (el) {
625
+ return el.value !== '';
626
+ }).toArray();
627
+ }
628
+
629
+ result = util.map(result, function (el) {
630
+ return el.value;
631
+ });
632
+
633
+ if (!result.length) {
634
+ result = '';
635
+ } else if (result.length === 1) {
636
+ result = result[0];
637
+ }
638
+
639
+ output[name] = result;
640
+ });
641
+ });
642
+
643
+ return output;
644
+ }
645
+ };
646
+
647
+ userSelectProperty = domutil.testProp(['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
648
+
649
+ /**
650
+ * Disable browser's text selection behaviors.
651
+ * @method
652
+ */
653
+ domutil.disableTextSelection = function () {
654
+ if (supportSelectStart) {
655
+ return function () {
656
+ domevent.on(window, 'selectstart', domevent.preventDefault);
657
+ };
658
+ }
659
+
660
+ return function () {
661
+ var style = document.documentElement.style;
662
+ prevSelectStyle = style[userSelectProperty];
663
+ style[userSelectProperty] = 'none';
664
+ };
665
+ }();
666
+
667
+ /**
668
+ * Enable browser's text selection behaviors.
669
+ * @method
670
+ */
671
+ domutil.enableTextSelection = function () {
672
+ if (supportSelectStart) {
673
+ return function () {
674
+ domevent.off(window, 'selectstart', domevent.preventDefault);
675
+ };
676
+ }
677
+
678
+ return function () {
679
+ document.documentElement.style[userSelectProperty] = prevSelectStyle;
680
+ };
681
+ }();
682
+
683
+ /**
684
+ * Disable browser's image drag behaviors.
685
+ */
686
+ domutil.disableImageDrag = function () {
687
+ domevent.on(window, 'dragstart', domevent.preventDefault);
688
+ };
689
+
690
+ /**
691
+ * Enable browser's image drag behaviors.
692
+ */
693
+ domutil.enableImageDrag = function () {
694
+ domevent.off(window, 'dragstart', domevent.preventDefault);
695
+ };
696
+
697
+ /**
698
+ * Replace matched property with template
699
+ * @param {string} template - String of template
700
+ * @param {Object} propObj - Properties
701
+ * @returns {string} Replaced template string
702
+ */
703
+ domutil.applyTemplate = function (template, propObj) {
704
+ var newTemplate = template.replace(/\{\{(\w*)\}\}/g, function (value, prop) {
705
+ return propObj.hasOwnProperty(prop) ? propObj[prop] : '';
706
+ });
707
+
708
+ return newTemplate;
709
+ };
710
+
711
+ module.exports = domutil;
712
+
713
+ /***/
714
+ }),
715
+ /* 8 */
716
+ /***/ (function (module, exports) {
717
+
718
+ module.exports = __WEBPACK_EXTERNAL_MODULE_8__;
719
+
720
+ /***/
721
+ }),
722
+ /* 9 */
723
+ /***/ (function (module, exports, __webpack_require__) {
724
+
725
+ /**
726
+ * @fileoverview Utility module for handling DOM events.
727
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
728
+ */
729
+
730
+ 'use strict';
731
+
732
+ var snippet = __webpack_require__(8);
733
+
734
+ var util = snippet,
735
+ browser = util.browser,
736
+ eventKey = '_evt',
737
+ DRAG = {
738
+ START: ['touchstart', 'mousedown'],
739
+ END: {
740
+ mousedown: 'mouseup',
741
+ touchstart: 'touchend',
742
+ pointerdown: 'touchend',
743
+ MSPointerDown: 'touchend'
744
+ },
745
+ MOVE: {
746
+ mousedown: 'mousemove',
747
+ touchstart: 'touchmove',
748
+ pointerdown: 'touchmove',
749
+ MSPointerDown: 'touchmove'
750
+ }
751
+ };
752
+
753
+ var domevent = {
754
+ /**
755
+ * Bind dom events.
756
+ * @param {HTMLElement} obj HTMLElement to bind events.
757
+ * @param {(string|object)} types Space splitted events names or eventName:handler object.
758
+ * @param {*} fn handler function or context for handler method.
759
+ * @param {*} [context] context object for handler method.
760
+ */
761
+ on: function (obj, types, fn, context) {
762
+ if (util.isString(types)) {
763
+ util.forEach(types.split(' '), function (type) {
764
+ domevent._on(obj, type, fn, context);
765
+ });
766
+
767
+ return;
768
+ }
769
+
770
+ util.forEachOwnProperties(types, function (handler, type) {
771
+ domevent._on(obj, type, handler, fn);
772
+ });
773
+ },
774
+
775
+ /**
776
+ * DOM event binding.
777
+ * @param {HTMLElement} obj HTMLElement to bind events.
778
+ * @param {String} type The name of events.
779
+ * @param {*} fn handler function
780
+ * @param {*} [context] context object for handler method.
781
+ * @private
782
+ */
783
+ _on: function (obj, type, fn, context) {
784
+ var id, handler, originHandler;
785
+
786
+ id = type + util.stamp(fn) + (context ? '_' + util.stamp(context) : '');
787
+
788
+ if (obj[eventKey] && obj[eventKey][id]) {
789
+ return;
790
+ }
791
+
792
+ handler = function (e) {
793
+ fn.call(context || obj, e || window.event);
794
+ };
795
+
796
+ originHandler = handler;
797
+
798
+ if ('addEventListener' in obj) {
799
+ if (type === 'mouseenter' || type === 'mouseleave') {
800
+ handler = function (e) {
801
+ e = e || window.event;
802
+ if (!domevent._checkMouse(obj, e)) {
803
+ return;
804
+ }
805
+ originHandler(e);
806
+ };
807
+ obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
808
+ } else {
809
+ if (type === 'mousewheel') {
810
+ obj.addEventListener('DOMMouseScroll', handler, false);
811
+ }
812
+
813
+ obj.addEventListener(type, handler, false);
814
+ }
815
+ } else if ('attachEvent' in obj) {
816
+ obj.attachEvent('on' + type, handler);
817
+ }
818
+
819
+ obj[eventKey] = obj[eventKey] || {};
820
+ obj[eventKey][id] = handler;
821
+ },
822
+
823
+ /**
824
+ * Unbind DOM Event handler.
825
+ * @param {HTMLElement} obj HTMLElement to unbind.
826
+ * @param {(string|object)} types Space splitted events names or eventName:handler object.
827
+ * @param {*} fn handler function or context for handler method.
828
+ * @param {*} [context] context object for handler method.
829
+ */
830
+ off: function (obj, types, fn, context) {
831
+ if (util.isString(types)) {
832
+ util.forEach(types.split(' '), function (type) {
833
+ domevent._off(obj, type, fn, context);
834
+ });
835
+
836
+ return;
837
+ }
838
+
839
+ util.forEachOwnProperties(types, function (handler, type) {
840
+ domevent._off(obj, type, handler, fn);
841
+ });
842
+ },
843
+
844
+ /**
845
+ * Unbind DOM event handler.
846
+ * @param {HTMLElement} obj HTMLElement to unbind.
847
+ * @param {String} type The name of event to unbind.
848
+ * @param {function()} fn Event handler that supplied when binding.
849
+ * @param {*} context context object that supplied when binding.
850
+ * @private
851
+ */
852
+ _off: function (obj, type, fn, context) {
853
+ var id = type + util.stamp(fn) + (context ? '_' + util.stamp(context) : ''),
854
+ handler = obj[eventKey] && obj[eventKey][id];
855
+
856
+ if (!handler) {
857
+ return;
858
+ }
859
+
860
+ if ('removeEventListener' in obj) {
861
+ if (type === 'mouseenter' || type === 'mouseleave') {
862
+ obj.removeEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
863
+ } else {
864
+ if (type === 'mousewheel') {
865
+ obj.removeEventListener('DOMMouseScroll', handler, false);
866
+ }
867
+
868
+ obj.removeEventListener(type, handler, false);
869
+ }
870
+ } else if ('detachEvent' in obj) {
871
+ try {
872
+ obj.detachEvent('on' + type, handler);
873
+ } catch (e) { } //eslint-disable-line
874
+ }
875
+
876
+ delete obj[eventKey][id];
877
+
878
+ if (util.keys(obj[eventKey]).length) {
879
+ return;
880
+ }
881
+
882
+ // throw exception when deleting host object's property in below IE8
883
+ if (util.browser.msie && util.browser.version < 9) {
884
+ obj[eventKey] = null;
885
+
886
+ return;
887
+ }
888
+
889
+ delete obj[eventKey];
890
+ },
891
+
892
+ /**
893
+ * Bind DOM event. this event will unbind after invokes.
894
+ * @param {HTMLElement} obj HTMLElement to bind events.
895
+ * @param {(string|object)} types Space splitted events names or eventName:handler object.
896
+ * @param {*} fn handler function or context for handler method.
897
+ * @param {*} [context] context object for handler method.
898
+ */
899
+ once: function (obj, types, fn, context) {
900
+ var that = this;
901
+
902
+ if (util.isObject(types)) {
903
+ util.forEachOwnProperties(types, function (handler, type) {
904
+ domevent.once(obj, type, handler, fn);
905
+ });
906
+
907
+ return;
908
+ }
909
+
910
+ function onceHandler() {
911
+ fn.apply(context || obj, arguments);
912
+ that._off(obj, types, onceHandler, context);
913
+ }
914
+
915
+ domevent.on(obj, types, onceHandler, context);
916
+ },
917
+
918
+ /**
919
+ * Cancel event bubbling.
920
+ * @param {Event} e Event object.
921
+ */
922
+ stopPropagation: function (e) {
923
+ if (e.stopPropagation) {
924
+ e.stopPropagation();
925
+ } else {
926
+ e.cancelBubble = true;
927
+ }
928
+ },
929
+
930
+ /**
931
+ * Cancel browser default actions.
932
+ * @param {Event} e Event object.
933
+ */
934
+ preventDefault: function (e) {
935
+ if (e.preventDefault) {
936
+ e.preventDefault();
937
+ } else {
938
+ e.returnValue = false;
939
+ }
940
+ },
941
+
942
+ /**
943
+ * Syntatic sugar of stopPropagation and preventDefault
944
+ * @param {Event} e Event object.
945
+ */
946
+ stop: function (e) {
947
+ domevent.preventDefault(e);
948
+ domevent.stopPropagation(e);
949
+ },
950
+
951
+ /**
952
+ * Stop scroll events.
953
+ * @param {HTMLElement} el HTML element to prevent scroll.
954
+ */
955
+ disableScrollPropagation: function (el) {
956
+ domevent.on(el, 'mousewheel MozMousePixelScroll', domevent.stopPropagation);
957
+ },
958
+
959
+ /**
960
+ * Stop all events related with click.
961
+ * @param {HTMLElement} el HTML element to prevent all event related with click.
962
+ */
963
+ disableClickPropagation: function (el) {
964
+ domevent.on(el, DRAG.START.join(' ') + ' click dblclick', domevent.stopPropagation);
965
+ },
966
+
967
+ /**
968
+ * Get mouse position from mouse event.
969
+ *
970
+ * If supplied relatveElement parameter then return relative position based on element.
971
+ * @param {Event} mouseEvent Mouse event object
972
+ * @param {HTMLElement} relativeElement HTML element that calculate relative position.
973
+ * @returns {number[]} mouse position.
974
+ */
975
+ getMousePosition: function (mouseEvent, relativeElement) {
976
+ var rect;
977
+
978
+ if (!relativeElement) {
979
+ return [mouseEvent.clientX, mouseEvent.clientY];
980
+ }
981
+
982
+ rect = relativeElement.getBoundingClientRect();
983
+
984
+ return [mouseEvent.clientX - rect.left - relativeElement.clientLeft, mouseEvent.clientY - rect.top - relativeElement.clientTop];
985
+ },
986
+
987
+ /**
988
+ * Normalize mouse wheel event that different each browsers.
989
+ * @param {MouseEvent} e Mouse wheel event.
990
+ * @returns {Number} delta
991
+ */
992
+ getWheelDelta: function (e) {
993
+ var delta = 0;
994
+
995
+ if (e.wheelDelta) {
996
+ delta = e.wheelDelta / 120;
997
+ }
998
+
999
+ if (e.detail) {
1000
+ delta = -e.detail / 3;
1001
+ }
1002
+
1003
+ return delta;
1004
+ },
1005
+
1006
+ /**
1007
+ * prevent firing mouseleave event when mouse entered child elements.
1008
+ * @param {HTMLElement} el HTML element
1009
+ * @param {MouseEvent} e Mouse event
1010
+ * @returns {Boolean} leave?
1011
+ * @private
1012
+ */
1013
+ _checkMouse: function (el, e) {
1014
+ var related = e.relatedTarget;
1015
+
1016
+ if (!related) {
1017
+ return true;
1018
+ }
1019
+
1020
+ try {
1021
+ while (related && related !== el) {
1022
+ related = related.parentNode;
1023
+ }
1024
+ } catch (err) {
1025
+ return false;
1026
+ }
1027
+
1028
+ return related !== el;
1029
+ },
1030
+
1031
+ /**
1032
+ * Trigger specific events to html element.
1033
+ * @param {HTMLElement} obj HTMLElement
1034
+ * @param {string} type Event type name
1035
+ * @param {object} [eventData] Event data
1036
+ */
1037
+ trigger: function (obj, type, eventData) {
1038
+ var rMouseEvent = /(mouse|click)/;
1039
+ if (util.isUndefined(eventData) && rMouseEvent.exec(type)) {
1040
+ eventData = domevent.mouseEvent(type);
1041
+ }
1042
+
1043
+ if (obj.dispatchEvent) {
1044
+ obj.dispatchEvent(eventData);
1045
+ } else if (obj.fireEvent) {
1046
+ obj.fireEvent('on' + type, eventData);
1047
+ }
1048
+ },
1049
+
1050
+ /**
1051
+ * Create virtual mouse event.
1052
+ *
1053
+ * Tested at
1054
+ *
1055
+ * - IE7 ~ IE11
1056
+ * - Chrome
1057
+ * - Firefox
1058
+ * - Safari
1059
+ * @param {string} type Event type
1060
+ * @param {object} [eventObj] Event data
1061
+ * @returns {MouseEvent} Virtual mouse event.
1062
+ */
1063
+ mouseEvent: function (type, eventObj) {
1064
+ var evt, e;
1065
+
1066
+ e = util.extend({
1067
+ bubbles: true,
1068
+ cancelable: type !== 'mousemove',
1069
+ view: window,
1070
+ wheelDelta: 0,
1071
+ detail: 0,
1072
+ screenX: 0,
1073
+ screenY: 0,
1074
+ clientX: 0,
1075
+ clientY: 0,
1076
+ ctrlKey: false,
1077
+ altKey: false,
1078
+ shiftKey: false,
1079
+ metaKey: false,
1080
+ button: 0,
1081
+ relatedTarget: undefined // eslint-disable-line
1082
+ }, eventObj);
1083
+
1084
+ // prevent throw error when inserting wheelDelta property to mouse event on below IE8
1085
+ if (browser.msie && browser.version < 9) {
1086
+ delete e.wheelDelta;
1087
+ }
1088
+
1089
+ if (typeof document.createEvent === 'function') {
1090
+ evt = document.createEvent('MouseEvents');
1091
+ evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, document.body.parentNode);
1092
+ } else if (document.createEventObject) {
1093
+ evt = document.createEventObject();
1094
+
1095
+ util.forEach(e, function (value, propName) {
1096
+ evt[propName] = value;
1097
+ }, this);
1098
+ evt.button = {
1099
+ 0: 1,
1100
+ 1: 4,
1101
+ 2: 2
1102
+ }[evt.button] || evt.button;
1103
+ }
1104
+
1105
+ return evt;
1106
+ },
1107
+
1108
+ /**
1109
+ * Normalize mouse event's button attributes.
1110
+ *
1111
+ * Can detect which button is clicked by this method.
1112
+ *
1113
+ * Meaning of return numbers
1114
+ *
1115
+ * - 0: primary mouse button
1116
+ * - 1: wheel button or center button
1117
+ * - 2: secondary mouse button
1118
+ * @param {MouseEvent} mouseEvent - The mouse event object want to know.
1119
+ * @returns {number} - The value of meaning which button is clicked?
1120
+ */
1121
+ getMouseButton: function (mouseEvent) {
1122
+ var button,
1123
+ primary = '0,1,3,5,7',
1124
+ secondary = '2,6',
1125
+ wheel = '4';
1126
+
1127
+ /* istanbul ignore else */
1128
+ if (document.implementation.hasFeature('MouseEvents', '2.0')) {
1129
+ return mouseEvent.button;
1130
+ }
1131
+
1132
+ button = mouseEvent.button + '';
1133
+ if (~primary.indexOf(button)) {
1134
+ return 0;
1135
+ } else if (~secondary.indexOf(button)) {
1136
+ return 2;
1137
+ } else if (~wheel.indexOf(button)) {
1138
+ return 1;
1139
+ }
1140
+ }
1141
+ };
1142
+
1143
+ module.exports = domevent;
1144
+
1145
+ /***/
1146
+ }),
1147
+ /* 10 */
1148
+ /***/ (function (module, exports, __webpack_require__) {
1149
+
1150
+ /**
1151
+ * @fileoverview Common collections.
1152
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
1153
+ */
1154
+
1155
+ 'use strict';
1156
+
1157
+ var snippet = __webpack_require__(8);
1158
+
1159
+ var util = snippet,
1160
+ forEachProp = util.forEachOwnProperties,
1161
+ forEachArr = util.forEachArray,
1162
+ isFunc = util.isFunction,
1163
+ isObj = util.isObject;
1164
+
1165
+ var aps = Array.prototype.slice;
1166
+
1167
+ /**
1168
+ * Common collection.
1169
+ *
1170
+ * It need function for get model's unique id.
1171
+ *
1172
+ * if the function is not supplied then it use default function {@link Collection#getItemID}
1173
+ * @constructor
1174
+ * @param {function} [getItemIDFn] function for get model's id.
1175
+ * @ignore
1176
+ */
1177
+ function Collection(getItemIDFn) {
1178
+ /**
1179
+ * @type {object.<string, *>}
1180
+ */
1181
+ this.items = {};
1182
+
1183
+ /**
1184
+ * @type {number}
1185
+ */
1186
+ this.length = 0;
1187
+
1188
+ if (isFunc(getItemIDFn)) {
1189
+ /**
1190
+ * @type {function}
1191
+ */
1192
+ this.getItemID = getItemIDFn;
1193
+ }
1194
+ }
1195
+
1196
+ /**********
1197
+ * static props
1198
+ **********/
1199
+
1200
+ /**
1201
+ * Combind supplied function filters and condition.
1202
+ * @param {...function} filters - function filters
1203
+ * @returns {function} combined filter
1204
+ */
1205
+ Collection.and = function (filters) {
1206
+ var cnt;
1207
+
1208
+ filters = aps.call(arguments);
1209
+ cnt = filters.length;
1210
+
1211
+ return function (item) {
1212
+ var i = 0;
1213
+
1214
+ for (; i < cnt; i += 1) {
1215
+ if (!filters[i].call(null, item)) {
1216
+ return false;
1217
+ }
1218
+ }
1219
+
1220
+ return true;
1221
+ };
1222
+ };
1223
+
1224
+ /**
1225
+ * Combine multiple function filters with OR clause.
1226
+ * @param {...function} filters - function filters
1227
+ * @returns {function} combined filter
1228
+ */
1229
+ Collection.or = function (filters) {
1230
+ var cnt;
1231
+
1232
+ filters = aps.call(arguments);
1233
+ cnt = filters.length;
1234
+
1235
+ return function (item) {
1236
+ var i = 1,
1237
+ result = filters[0].call(null, item);
1238
+
1239
+ for (; i < cnt; i += 1) {
1240
+ result = result || filters[i].call(null, item);
1241
+ }
1242
+
1243
+ return result;
1244
+ };
1245
+ };
1246
+
1247
+ /**
1248
+ * Merge several collections.
1249
+ *
1250
+ * You can\'t merge collections different _getEventID functions. Take case of use.
1251
+ * @param {...Collection} collections collection arguments to merge
1252
+ * @returns {Collection} merged collection.
1253
+ */
1254
+ Collection.merge = function (collections) {
1255
+ // eslint-disable-line
1256
+ var cols = aps.call(arguments),
1257
+ newItems = {},
1258
+ merged = new Collection(cols[0].getItemID),
1259
+ extend = util.extend;
1260
+
1261
+ forEachArr(cols, function (col) {
1262
+ extend(newItems, col.items);
1263
+ });
1264
+
1265
+ merged.items = newItems;
1266
+ merged.length = util.keys(merged.items).length;
1267
+
1268
+ return merged;
1269
+ };
1270
+
1271
+ /**********
1272
+ * prototype props
1273
+ **********/
1274
+
1275
+ /**
1276
+ * get model's unique id.
1277
+ * @param {object} item model instance.
1278
+ * @returns {number} model unique id.
1279
+ */
1280
+ Collection.prototype.getItemID = function (item) {
1281
+ return item._id + '';
1282
+ };
1283
+
1284
+ /**
1285
+ * add models.
1286
+ * @param {...*} item models to add this collection.
1287
+ */
1288
+ Collection.prototype.add = function (item) {
1289
+ var id, ownItems;
1290
+
1291
+ if (arguments.length > 1) {
1292
+ forEachArr(aps.call(arguments), function (o) {
1293
+ this.add(o);
1294
+ }, this);
1295
+
1296
+ return;
1297
+ }
1298
+
1299
+ id = this.getItemID(item);
1300
+ ownItems = this.items;
1301
+
1302
+ if (!ownItems[id]) {
1303
+ this.length += 1;
1304
+ }
1305
+ ownItems[id] = item;
1306
+ };
1307
+
1308
+ /**
1309
+ * remove models.
1310
+ * @param {...(object|string|number)} id model instance or unique id to delete.
1311
+ * @returns {array} deleted model list.
1312
+ */
1313
+ Collection.prototype.remove = function (id) {
1314
+ var removed = [],
1315
+ ownItems,
1316
+ itemToRemove;
1317
+
1318
+ if (!this.length) {
1319
+ return removed;
1320
+ }
1321
+
1322
+ if (arguments.length > 1) {
1323
+ removed = util.map(aps.call(arguments), function (id) {
1324
+ return this.remove(id);
1325
+ }, this);
1326
+
1327
+ return removed;
1328
+ }
1329
+
1330
+ ownItems = this.items;
1331
+
1332
+ if (isObj(id)) {
1333
+ id = this.getItemID(id);
1334
+ }
1335
+
1336
+ if (!ownItems[id]) {
1337
+ return removed;
1338
+ }
1339
+
1340
+ this.length -= 1;
1341
+ itemToRemove = ownItems[id];
1342
+ delete ownItems[id];
1343
+
1344
+ return itemToRemove;
1345
+ };
1346
+
1347
+ /**
1348
+ * remove all models in collection.
1349
+ */
1350
+ Collection.prototype.clear = function () {
1351
+ this.items = {};
1352
+ this.length = 0;
1353
+ };
1354
+
1355
+ /**
1356
+ * check collection has specific model.
1357
+ * @param {(object|string|number|function)} id model instance or id or filter function to check
1358
+ * @returns {boolean} is has model?
1359
+ */
1360
+ Collection.prototype.has = function (id) {
1361
+ var isFilter, has;
1362
+
1363
+ if (!this.length) {
1364
+ return false;
1365
+ }
1366
+
1367
+ isFilter = isFunc(id);
1368
+ has = false;
1369
+
1370
+ if (isFilter) {
1371
+ this.each(function (item) {
1372
+ if (id(item) === true) {
1373
+ has = true;
1374
+
1375
+ return false;
1376
+ }
1377
+
1378
+ return true;
1379
+ });
1380
+ } else {
1381
+ id = isObj(id) ? this.getItemID(id) : id;
1382
+ has = util.isExisty(this.items[id]);
1383
+ }
1384
+
1385
+ return has;
1386
+ };
1387
+
1388
+ /**
1389
+ * invoke callback when model exist in collection.
1390
+ * @param {(string|number)} id model unique id.
1391
+ * @param {function} fn the callback.
1392
+ * @param {*} [context] callback context.
1393
+ */
1394
+ Collection.prototype.doWhenHas = function (id, fn, context) {
1395
+ var item = this.items[id];
1396
+
1397
+ if (!util.isExisty(item)) {
1398
+ return;
1399
+ }
1400
+
1401
+ fn.call(context || this, item);
1402
+ };
1403
+
1404
+ /**
1405
+ * Search model. and return new collection.
1406
+ * @param {function} filter filter function.
1407
+ * @returns {Collection} new collection with filtered models.
1408
+ * @example
1409
+ * collection.find(function(item) {
1410
+ * return item.edited === true;
1411
+ * });
1412
+ *
1413
+ * function filter1(item) {
1414
+ * return item.edited === false;
1415
+ * }
1416
+ *
1417
+ * function filter2(item) {
1418
+ * return item.disabled === false;
1419
+ * }
1420
+ *
1421
+ * collection.find(Collection.and(filter1, filter2));
1422
+ *
1423
+ * collection.find(Collection.or(filter1, filter2));
1424
+ */
1425
+ Collection.prototype.find = function (filter) {
1426
+ var result = new Collection();
1427
+
1428
+ if (this.hasOwnProperty('getItemID')) {
1429
+ result.getItemID = this.getItemID;
1430
+ }
1431
+
1432
+ this.each(function (item) {
1433
+ if (filter(item) === true) {
1434
+ result.add(item);
1435
+ }
1436
+ });
1437
+
1438
+ return result;
1439
+ };
1440
+
1441
+ /**
1442
+ * Group element by specific key values.
1443
+ *
1444
+ * if key parameter is function then invoke it and use returned value.
1445
+ * @param {(string|number|function|array)} key key property or getter function. if string[] supplied, create each collection before grouping.
1446
+ * @param {function} [groupFunc] - function that return each group's key
1447
+ * @returns {object.<string, Collection>} grouped object
1448
+ * @example
1449
+ *
1450
+ * // pass `string`, `number`, `boolean` type value then group by property value.
1451
+ * collection.groupBy('gender'); // group by 'gender' property value.
1452
+ * collection.groupBy(50); // group by '50' property value.
1453
+ *
1454
+ * // pass `function` then group by return value. each invocation `function` is called with `(item)`.
1455
+ * collection.groupBy(function(item) {
1456
+ * if (item.score > 60) {
1457
+ * return 'pass';
1458
+ * }
1459
+ * return 'fail';
1460
+ * });
1461
+ *
1462
+ * // pass `array` with first arguments then create each collection before grouping.
1463
+ * collection.groupBy(['go', 'ruby', 'javascript']);
1464
+ * // result: { 'go': empty Collection, 'ruby': empty Collection, 'javascript': empty Collection }
1465
+ *
1466
+ * // can pass `function` with `array` then group each elements.
1467
+ * collection.groupBy(['go', 'ruby', 'javascript'], function(item) {
1468
+ * if (item.isFast) {
1469
+ * return 'go';
1470
+ * }
1471
+ *
1472
+ * return item.name;
1473
+ * });
1474
+ */
1475
+ Collection.prototype.groupBy = function (key, groupFunc) {
1476
+ var result = {},
1477
+ collection,
1478
+ baseValue,
1479
+ keyIsFunc = isFunc(key),
1480
+ getItemIDFn = this.getItemID;
1481
+
1482
+ if (util.isArray(key)) {
1483
+ util.forEachArray(key, function (k) {
1484
+ result[k + ''] = new Collection(getItemIDFn);
1485
+ });
1486
+
1487
+ if (!groupFunc) {
1488
+ return result;
1489
+ }
1490
+
1491
+ key = groupFunc;
1492
+ keyIsFunc = true;
1493
+ }
1494
+
1495
+ this.each(function (item) {
1496
+ if (keyIsFunc) {
1497
+ baseValue = key(item);
1498
+ } else {
1499
+ baseValue = item[key];
1500
+
1501
+ if (isFunc(baseValue)) {
1502
+ baseValue = baseValue.apply(item);
1503
+ }
1504
+ }
1505
+
1506
+ collection = result[baseValue];
1507
+
1508
+ if (!collection) {
1509
+ collection = result[baseValue] = new Collection(getItemIDFn);
1510
+ }
1511
+
1512
+ collection.add(item);
1513
+ });
1514
+
1515
+ return result;
1516
+ };
1517
+
1518
+ /**
1519
+ * Return single item in collection.
1520
+ *
1521
+ * Returned item is inserted in this collection firstly.
1522
+ * @returns {object} item.
1523
+ */
1524
+ Collection.prototype.single = function () {
1525
+ var result;
1526
+
1527
+ this.each(function (item) {
1528
+ result = item;
1529
+
1530
+ return false;
1531
+ }, this);
1532
+
1533
+ return result;
1534
+ };
1535
+
1536
+ /**
1537
+ * sort a basis of supplied compare function.
1538
+ * @param {function} compareFunction compareFunction
1539
+ * @returns {array} sorted array.
1540
+ */
1541
+ Collection.prototype.sort = function (compareFunction) {
1542
+ var arr = [];
1543
+
1544
+ this.each(function (item) {
1545
+ arr.push(item);
1546
+ });
1547
+
1548
+ if (isFunc(compareFunction)) {
1549
+ arr = arr.sort(compareFunction);
1550
+ }
1551
+
1552
+ return arr;
1553
+ };
1554
+
1555
+ /**
1556
+ * iterate each model element.
1557
+ *
1558
+ * when iteratee return false then break the loop.
1559
+ * @param {function} iteratee iteratee(item, index, items)
1560
+ * @param {*} [context] context
1561
+ */
1562
+ Collection.prototype.each = function (iteratee, context) {
1563
+ forEachProp(this.items, iteratee, context || this);
1564
+ };
1565
+
1566
+ /**
1567
+ * return new array with collection items.
1568
+ * @returns {array} new array.
1569
+ */
1570
+ Collection.prototype.toArray = function () {
1571
+ if (!this.length) {
1572
+ return [];
1573
+ }
1574
+
1575
+ return util.map(this.items, function (item) {
1576
+ return item;
1577
+ });
1578
+ };
1579
+
1580
+ module.exports = Collection;
1581
+
1582
+ /***/
1583
+ }),
1584
+ /* 11 */
1585
+ /***/ (function (module, exports, __webpack_require__) {
1586
+
1587
+ /**
1588
+ * @fileoverview The base class of views.
1589
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
1590
+ */
1591
+
1592
+ 'use strict';
1593
+
1594
+ var util = __webpack_require__(8);
1595
+ var domutil = __webpack_require__(7);
1596
+ var Collection = __webpack_require__(10);
1597
+
1598
+ /**
1599
+ * Base class of views.
1600
+ *
1601
+ * All views create own container element inside supplied container element.
1602
+ * @constructor
1603
+ * @param {options} options The object for describe view's specs.
1604
+ * @param {HTMLElement} container Default container element for view. you can use this element for this.container syntax.
1605
+ * @ignore
1606
+ */
1607
+ function View(options, container) {
1608
+ var id = util.stamp(this);
1609
+
1610
+ options = options || {};
1611
+
1612
+ if (util.isUndefined(container)) {
1613
+ container = domutil.appendHTMLElement('div');
1614
+ }
1615
+
1616
+ domutil.addClass(container, 'tui-view-' + id);
1617
+
1618
+ /**
1619
+ * unique id
1620
+ * @type {number}
1621
+ */
1622
+ this.id = id;
1623
+
1624
+ /**
1625
+ * base element of view.
1626
+ * @type {HTMLDIVElement}
1627
+ */
1628
+ this.container = container;
1629
+
1630
+ /**
1631
+ * child views.
1632
+ * @type {Collection}
1633
+ */
1634
+ this.childs = new Collection(function (view) {
1635
+ return util.stamp(view);
1636
+ });
1637
+
1638
+ /**
1639
+ * parent view instance.
1640
+ * @type {View}
1641
+ */
1642
+ this.parent = null;
1643
+ }
1644
+
1645
+ /**
1646
+ * Add child views.
1647
+ * @param {View} view The view instance to add.
1648
+ * @param {function} [fn] Function for invoke before add. parent view class is supplied first arguments.
1649
+ */
1650
+ View.prototype.addChild = function (view, fn) {
1651
+ if (fn) {
1652
+ fn.call(view, this);
1653
+ }
1654
+ // add parent view
1655
+ view.parent = this;
1656
+
1657
+ this.childs.add(view);
1658
+ };
1659
+
1660
+ /**
1661
+ * Remove added child view.
1662
+ * @param {(number|View)} id View id or instance itself to remove.
1663
+ * @param {function} [fn] Function for invoke before remove. parent view class is supplied first arguments.
1664
+ */
1665
+ View.prototype.removeChild = function (id, fn) {
1666
+ var view = util.isNumber(id) ? this.childs.items[id] : id;
1667
+
1668
+ id = util.stamp(view);
1669
+
1670
+ if (fn) {
1671
+ fn.call(view, this);
1672
+ }
1673
+
1674
+ this.childs.remove(id);
1675
+ };
1676
+
1677
+ /**
1678
+ * Render view recursively.
1679
+ */
1680
+ View.prototype.render = function () {
1681
+ this.childs.each(function (childView) {
1682
+ childView.render();
1683
+ });
1684
+ };
1685
+
1686
+ /**
1687
+ * Invoke function recursively.
1688
+ * @param {function} fn - function to invoke child view recursively
1689
+ * @param {boolean} [skipThis=false] - set true then skip invoke with this(root) view.
1690
+ */
1691
+ View.prototype.recursive = function (fn, skipThis) {
1692
+ if (!util.isFunction(fn)) {
1693
+ return;
1694
+ }
1695
+
1696
+ if (!skipThis) {
1697
+ fn(this);
1698
+ }
1699
+
1700
+ this.childs.each(function (childView) {
1701
+ childView.recursive(fn);
1702
+ });
1703
+ };
1704
+
1705
+ /**
1706
+ * Resize view recursively to parent.
1707
+ */
1708
+ View.prototype.resize = function () {
1709
+ var args = Array.prototype.slice.call(arguments),
1710
+ parent = this.parent;
1711
+
1712
+ while (parent) {
1713
+ if (util.isFunction(parent._onResize)) {
1714
+ parent._onResize.apply(parent, args);
1715
+ }
1716
+
1717
+ parent = parent.parent;
1718
+ }
1719
+ };
1720
+
1721
+ /**
1722
+ * Invoking method before destroying.
1723
+ */
1724
+ View.prototype._beforeDestroy = function () { };
1725
+
1726
+ /**
1727
+ * Clear properties
1728
+ */
1729
+ View.prototype._destroy = function () {
1730
+ this._beforeDestroy();
1731
+ this.childs.clear();
1732
+ this.container.innerHTML = '';
1733
+
1734
+ this.id = this.parent = this.childs = this.container = null;
1735
+ };
1736
+
1737
+ /**
1738
+ * Destroy child view recursively.
1739
+ * @param {boolean} isChildView - Whether it is the child view or not
1740
+ */
1741
+ View.prototype.destroy = function (isChildView) {
1742
+ this.childs.each(function (childView) {
1743
+ childView.destroy(true);
1744
+ childView._destroy();
1745
+ });
1746
+
1747
+ if (isChildView) {
1748
+ return;
1749
+ }
1750
+
1751
+ this._destroy();
1752
+ };
1753
+
1754
+ /**
1755
+ * Calculate view's container element bound.
1756
+ * @returns {object} The bound of container element.
1757
+ */
1758
+ View.prototype.getViewBound = function () {
1759
+ var container = this.container,
1760
+ position = domutil.getPosition(container),
1761
+ size = domutil.getSize(container);
1762
+
1763
+ return {
1764
+ x: position[0],
1765
+ y: position[1],
1766
+ width: size[0],
1767
+ height: size[1]
1768
+ };
1769
+ };
1770
+
1771
+ module.exports = View;
1772
+
1773
+ /***/
1774
+ }),
1775
+ /* 12 */
1776
+ /***/ (function (module, exports, __webpack_require__) {
1777
+
1778
+ /* WEBPACK VAR INJECTION */(function (global) {/**
1779
+ * @fileoverview General drag handler
1780
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
1781
+ */
1782
+
1783
+ 'use strict';
1784
+
1785
+ var util = __webpack_require__(8);
1786
+ var domutil = __webpack_require__(7);
1787
+ var domevent = __webpack_require__(9);
1788
+
1789
+ /**
1790
+ * @constructor
1791
+ * @mixes CustomEvents
1792
+ * @param {object} options - options for drag handler
1793
+ * @param {number} [options.distance=10] - distance in pixels after mouse must move before dragging should start
1794
+ * @param {HTMLElement} container - container element to bind drag events
1795
+ * @ignore
1796
+ */
1797
+ function Drag(options, container) {
1798
+ domevent.on(container, 'mousedown', this._onMouseDown, this);
1799
+
1800
+ this.options = util.extend({
1801
+ distance: 10
1802
+ }, options);
1803
+
1804
+ /**
1805
+ * @type {HTMLElement}
1806
+ */
1807
+ this.container = container;
1808
+
1809
+ /**
1810
+ * @type {boolean}
1811
+ */
1812
+ this._isMoved = false;
1813
+
1814
+ /**
1815
+ * dragging distance in pixel between mousedown and firing dragStart events
1816
+ * @type {number}
1817
+ */
1818
+ this._distance = 0;
1819
+
1820
+ /**
1821
+ * @type {boolean}
1822
+ */
1823
+ this._dragStartFired = false;
1824
+
1825
+ /**
1826
+ * @type {object}
1827
+ */
1828
+ this._dragStartEventData = null;
1829
+ }
1830
+
1831
+ /**
1832
+ * Destroy method.
1833
+ */
1834
+ Drag.prototype.destroy = function () {
1835
+ domevent.off(this.container, 'mousedown', this._onMouseDown, this);
1836
+
1837
+ this.options = this.container = this._isMoved = this._distance = this._dragStartFired = this._dragStartEventData = null;
1838
+ };
1839
+
1840
+ /**
1841
+ * Toggle events for mouse dragging.
1842
+ * @param {boolean} toBind - bind events related with dragging when supplied "true"
1843
+ */
1844
+ Drag.prototype._toggleDragEvent = function (toBind) {
1845
+ var container = this.container,
1846
+ domMethod,
1847
+ method;
1848
+
1849
+ if (toBind) {
1850
+ domMethod = 'on';
1851
+ method = 'disable';
1852
+ } else {
1853
+ domMethod = 'off';
1854
+ method = 'enable';
1855
+ }
1856
+
1857
+ domutil[method + 'TextSelection'](container);
1858
+ domutil[method + 'ImageDrag'](container);
1859
+ domevent[domMethod](global.document, {
1860
+ mousemove: this._onMouseMove,
1861
+ mouseup: this._onMouseUp
1862
+ }, this);
1863
+ };
1864
+
1865
+ /**
1866
+ * Normalize mouse event object.
1867
+ * @param {MouseEvent} mouseEvent - mouse event object.
1868
+ * @returns {object} normalized mouse event data.
1869
+ */
1870
+ Drag.prototype._getEventData = function (mouseEvent) {
1871
+ return {
1872
+ target: mouseEvent.target || mouseEvent.srcElement,
1873
+ originEvent: mouseEvent
1874
+ };
1875
+ };
1876
+
1877
+ /**
1878
+ * MouseDown DOM event handler.
1879
+ * @param {MouseEvent} mouseDownEvent MouseDown event object.
1880
+ */
1881
+ Drag.prototype._onMouseDown = function (mouseDownEvent) {
1882
+ // only primary button can start drag.
1883
+ if (domevent.getMouseButton(mouseDownEvent) !== 0) {
1884
+ return;
1885
+ }
1886
+
1887
+ this._distance = 0;
1888
+ this._dragStartFired = false;
1889
+ this._dragStartEventData = this._getEventData(mouseDownEvent);
1890
+
1891
+ this._toggleDragEvent(true);
1892
+ };
1893
+
1894
+ /**
1895
+ * MouseMove DOM event handler.
1896
+ * @emits Drag#drag
1897
+ * @emits Drag#dragStart
1898
+ * @param {MouseEvent} mouseMoveEvent MouseMove event object.
1899
+ */
1900
+ Drag.prototype._onMouseMove = function (mouseMoveEvent) {
1901
+ var distance = this.options.distance;
1902
+ // prevent automatic scrolling.
1903
+ domevent.preventDefault(mouseMoveEvent);
1904
+
1905
+ this._isMoved = true;
1906
+
1907
+ if (this._distance < distance) {
1908
+ this._distance += 1;
1909
+
1910
+ return;
1911
+ }
1912
+
1913
+ if (!this._dragStartFired) {
1914
+ this._dragStartFired = true;
1915
+
1916
+ /**
1917
+ * Drag starts events. cancelable.
1918
+ * @event Drag#dragStart
1919
+ * @type {object}
1920
+ * @property {HTMLElement} target - target element in this event.
1921
+ * @property {MouseEvent} originEvent - original mouse event object.
1922
+ */
1923
+ if (!this.invoke('dragStart', this._dragStartEventData)) {
1924
+ this._toggleDragEvent(false);
1925
+
1926
+ return;
1927
+ }
1928
+ }
1929
+
1930
+ /**
1931
+ * Events while dragging.
1932
+ * @event Drag#drag
1933
+ * @type {object}
1934
+ * @property {HTMLElement} target - target element in this event.
1935
+ * @property {MouseEvent} originEvent - original mouse event object.
1936
+ */
1937
+ this.fire('drag', this._getEventData(mouseMoveEvent));
1938
+ };
1939
+
1940
+ /**
1941
+ * MouseUp DOM event handler.
1942
+ * @param {MouseEvent} mouseUpEvent MouseUp event object.
1943
+ * @emits Drag#dragEnd
1944
+ * @emits Drag#click
1945
+ */
1946
+ Drag.prototype._onMouseUp = function (mouseUpEvent) {
1947
+ this._toggleDragEvent(false);
1948
+
1949
+ // emit "click" event when not emitted drag event between mousedown and mouseup.
1950
+ if (this._isMoved) {
1951
+ this._isMoved = false;
1952
+
1953
+ /**
1954
+ * Drag end events.
1955
+ * @event Drag#dragEnd
1956
+ * @type {MouseEvent}
1957
+ * @property {HTMLElement} target - target element in this event.
1958
+ * @property {MouseEvent} originEvent - original mouse event object.
1959
+ */
1960
+ this.fire('dragEnd', this._getEventData(mouseUpEvent));
1961
+
1962
+ return;
1963
+ }
1964
+
1965
+ /**
1966
+ * Click events.
1967
+ * @event Drag#click
1968
+ * @type {MouseEvent}
1969
+ * @property {HTMLElement} target - target element in this event.
1970
+ * @property {MouseEvent} originEvent - original mouse event object.
1971
+ */
1972
+ this.fire('click', this._getEventData(mouseUpEvent));
1973
+ };
1974
+
1975
+ util.CustomEvents.mixin(Drag);
1976
+
1977
+ module.exports = Drag;
1978
+ /* WEBPACK VAR INJECTION */
1979
+ }.call(exports, (function () { return this; }())))
1980
+
1981
+ /***/
1982
+ }),
1983
+ /* 13 */
1984
+ /***/ (function (module, exports, __webpack_require__) {
1985
+
1986
+ /**
1987
+ * @fileoverview ColorPicker factory module
1988
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
1989
+ */
1990
+
1991
+ 'use strict';
1992
+
1993
+ var util = __webpack_require__(8);
1994
+ var colorutil = __webpack_require__(14);
1995
+ var Layout = __webpack_require__(15);
1996
+ var Palette = __webpack_require__(16);
1997
+ var Slider = __webpack_require__(18);
1998
+
1999
+ var hostnameSent = false;
2000
+
2001
+ /**
2002
+ * send hostname
2003
+ * @ignore
2004
+ */
2005
+ function sendHostname() {
2006
+ var hostname = location.hostname;
2007
+
2008
+ if (hostnameSent) {
2009
+ return;
2010
+ }
2011
+ hostnameSent = true;
2012
+
2013
+
2014
+ }
2015
+
2016
+ /**
2017
+ * @constructor
2018
+ * @mixes CustomEvents
2019
+ * @param {object} options - options for colorpicker component
2020
+ * @param {HTMLDivElement} options.container - container element
2021
+ * @param {string} [options.color='#ffffff'] - default selected color
2022
+ * @param {string[]} [options.preset] - color preset for palette (use base16 palette if not supplied)
2023
+ * @param {string} [options.cssPrefix='tui-colorpicker-'] - css prefix text for each child elements
2024
+ * @param {string} [options.detailTxt='Detail'] - text for detail button.
2025
+ * @param {boolean} [options.usageStatistics=true] - Let us know the hostname. If you don't want to send the hostname, please set to false.
2026
+ * @example
2027
+ * var colorPicker = tui.colorPicker; // or require('tui-color-picker')
2028
+ *
2029
+ * colorPicker.create({
2030
+ * container: document.getElementById('color-picker')
2031
+ * });
2032
+ */
2033
+ function ColorPicker(options) {
2034
+ var layout;
2035
+
2036
+ if (!(this instanceof ColorPicker)) {
2037
+ return new ColorPicker(options);
2038
+ }
2039
+ /**
2040
+ * Option object
2041
+ * @type {object}
2042
+ * @private
2043
+ */
2044
+ options = this.options = util.extend({
2045
+ container: null,
2046
+ color: '#f8f8f8',
2047
+ preset: ['#181818', '#282828', '#383838', '#585858', '#b8b8b8', '#d8d8d8', '#e8e8e8', '#f8f8f8', '#ab4642', '#dc9656', '#f7ca88', '#a1b56c', '#86c1b9', '#7cafc2', '#ba8baf', '#a16946'],
2048
+ cssPrefix: 'tui-colorpicker-',
2049
+ detailTxt: 'Detail',
2050
+ usageStatistics: true
2051
+ }, options);
2052
+
2053
+ if (!options.container) {
2054
+ throw new Error('ColorPicker(): need container option.');
2055
+ }
2056
+
2057
+ /**********
2058
+ * Create layout view
2059
+ **********/
2060
+
2061
+ /**
2062
+ * @type {Layout}
2063
+ * @private
2064
+ */
2065
+ layout = this.layout = new Layout(options, options.container);
2066
+
2067
+ /**********
2068
+ * Create palette view
2069
+ **********/
2070
+ this.palette = new Palette(options, layout.container);
2071
+ this.palette.on({
2072
+ '_selectColor': this._onSelectColorInPalette,
2073
+ '_toggleSlider': this._onToggleSlider
2074
+ }, this);
2075
+
2076
+ /**********
2077
+ * Create slider view
2078
+ **********/
2079
+ this.slider = new Slider(options, layout.container);
2080
+ this.slider.on('_selectColor', this._onSelectColorInSlider, this);
2081
+
2082
+ /**********
2083
+ * Add child views
2084
+ **********/
2085
+ layout.addChild(this.palette);
2086
+ layout.addChild(this.slider);
2087
+
2088
+ this.render(options.color);
2089
+
2090
+ if (options.usageStatistics) {
2091
+ sendHostname();
2092
+ }
2093
+ }
2094
+
2095
+ /**
2096
+ * Handler method for Palette#_selectColor event
2097
+ * @private
2098
+ * @fires ColorPicker#selectColor
2099
+ * @param {object} selectColorEventData - event data
2100
+ */
2101
+ ColorPicker.prototype._onSelectColorInPalette = function (selectColorEventData) {
2102
+ var color = selectColorEventData.color,
2103
+ opt = this.options;
2104
+
2105
+ if (!colorutil.isValidRGB(color) && color !== '') {
2106
+ this.render();
2107
+
2108
+ return;
2109
+ }
2110
+
2111
+ /**
2112
+ * @event ColorPicker#selectColor
2113
+ * @type {object}
2114
+ * @property {string} color - selected color (hex string)
2115
+ * @property {string} origin - flags for represent the source of event fires.
2116
+ */
2117
+ this.fire('selectColor', {
2118
+ color: color,
2119
+ origin: 'palette'
2120
+ });
2121
+
2122
+ if (opt.color === color) {
2123
+ return;
2124
+ }
2125
+
2126
+ opt.color = color;
2127
+ this.render(color);
2128
+ };
2129
+
2130
+ /**
2131
+ * Handler method for Palette#_toggleSlider event
2132
+ * @private
2133
+ */
2134
+ ColorPicker.prototype._onToggleSlider = function () {
2135
+ this.slider.toggle(!this.slider.isVisible());
2136
+ };
2137
+
2138
+ /**
2139
+ * Handler method for Slider#_selectColor event
2140
+ * @private
2141
+ * @fires ColorPicker#selectColor
2142
+ * @param {object} selectColorEventData - event data
2143
+ */
2144
+ ColorPicker.prototype._onSelectColorInSlider = function (selectColorEventData) {
2145
+ var color = selectColorEventData.color,
2146
+ opt = this.options;
2147
+
2148
+ /**
2149
+ * @event ColorPicker#selectColor
2150
+ * @type {object}
2151
+ * @property {string} color - selected color (hex string)
2152
+ * @property {string} origin - flags for represent the source of event fires.
2153
+ * @ignore
2154
+ */
2155
+ this.fire('selectColor', {
2156
+ color: color,
2157
+ origin: 'slider'
2158
+ });
2159
+
2160
+ if (opt.color === color) {
2161
+ return;
2162
+ }
2163
+
2164
+ opt.color = color;
2165
+ this.palette.render(color);
2166
+ };
2167
+
2168
+ /**********
2169
+ * PUBLIC API
2170
+ **********/
2171
+
2172
+ /**
2173
+ * Set color to colorpicker instance.<br>
2174
+ * The string parameter must be hex color value
2175
+ * @param {string} hexStr - hex formatted color string
2176
+ * @example
2177
+ * colorPicker.setColor('#ffff00');
2178
+ */
2179
+ ColorPicker.prototype.setColor = function (hexStr) {
2180
+ if (!colorutil.isValidRGB(hexStr)) {
2181
+ throw new Error('ColorPicker#setColor(): need valid hex string color value');
2182
+ }
2183
+
2184
+ this.options.color = hexStr;
2185
+ this.render(hexStr);
2186
+ };
2187
+
2188
+ /**
2189
+ * Get hex color string of current selected color in colorpicker instance.
2190
+ * @returns {string} hex string formatted color
2191
+ * @example
2192
+ * colorPicker.setColor('#ffff00');
2193
+ * colorPicker.getColor(); // '#ffff00';
2194
+ */
2195
+ ColorPicker.prototype.getColor = function () {
2196
+ return this.options.color;
2197
+ };
2198
+
2199
+ /**
2200
+ * Toggle colorpicker element. set true then reveal colorpicker view.
2201
+ * @param {boolean} [isShow=false] - A flag to show
2202
+ * @example
2203
+ * colorPicker.toggle(false); // hide
2204
+ * colorPicker.toggle(); // hide
2205
+ * colorPicker.toggle(true); // show
2206
+ */
2207
+ ColorPicker.prototype.toggle = function (isShow) {
2208
+ this.layout.container.style.display = !!isShow ? 'block' : 'none';
2209
+ };
2210
+
2211
+ /**
2212
+ * Render colorpicker
2213
+ * @param {string} [color] - selected color
2214
+ * @ignore
2215
+ */
2216
+ ColorPicker.prototype.render = function (color) {
2217
+ this.layout.render(color || this.options.color);
2218
+ };
2219
+
2220
+ /**
2221
+ * Destroy colorpicker instance.
2222
+ * @example
2223
+ * colorPicker.destroy(); // DOM-element is removed
2224
+ */
2225
+ ColorPicker.prototype.destroy = function () {
2226
+ this.layout.destroy();
2227
+ this.options.container.innerHTML = '';
2228
+
2229
+ this.layout = this.slider = this.palette = this.options = null;
2230
+ };
2231
+
2232
+ util.CustomEvents.mixin(ColorPicker);
2233
+
2234
+ module.exports = ColorPicker;
2235
+
2236
+ /***/
2237
+ }),
2238
+ /* 14 */
2239
+ /***/ (function (module, exports) {
2240
+
2241
+ /**
2242
+ * @fileoverview Utility methods to manipulate colors
2243
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
2244
+ */
2245
+
2246
+ 'use strict';
2247
+
2248
+ var hexRX = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i;
2249
+
2250
+ var colorutil = {
2251
+ /**
2252
+ * pad left zero characters.
2253
+ * @param {number} number number value to pad zero.
2254
+ * @param {number} length pad length to want.
2255
+ * @returns {string} padded string.
2256
+ */
2257
+ leadingZero: function (number, length) {
2258
+ var zero = '',
2259
+ i = 0;
2260
+
2261
+ if ((number + '').length > length) {
2262
+ return number + '';
2263
+ }
2264
+
2265
+ for (; i < length - 1; i += 1) {
2266
+ zero += '0';
2267
+ }
2268
+
2269
+ return (zero + number).slice(length * -1);
2270
+ },
2271
+
2272
+ /**
2273
+ * Check validate of hex string value is RGB
2274
+ * @param {string} str - rgb hex string
2275
+ * @returns {boolean} return true when supplied str is valid RGB hex string
2276
+ */
2277
+ isValidRGB: function (str) {
2278
+ return hexRX.test(str);
2279
+ },
2280
+
2281
+ // @license RGB <-> HSV conversion utilities based off of http://www.cs.rit.edu/~ncs/color/t_convert.html
2282
+
2283
+ /**
2284
+ * Convert color hex string to rgb number array
2285
+ * @param {string} hexStr - hex string
2286
+ * @returns {number[]} rgb numbers
2287
+ */
2288
+ hexToRGB: function (hexStr) {
2289
+ var r, g, b;
2290
+
2291
+ if (!colorutil.isValidRGB(hexStr)) {
2292
+ return false;
2293
+ }
2294
+
2295
+ hexStr = hexStr.substring(1);
2296
+
2297
+ r = parseInt(hexStr.substr(0, 2), 16);
2298
+ g = parseInt(hexStr.substr(2, 2), 16);
2299
+ b = parseInt(hexStr.substr(4, 2), 16);
2300
+
2301
+ return [r, g, b];
2302
+ },
2303
+
2304
+ /**
2305
+ * Convert rgb number to hex string
2306
+ * @param {number} r - red
2307
+ * @param {number} g - green
2308
+ * @param {number} b - blue
2309
+ * @returns {string|boolean} return false when supplied rgb number is not valid. otherwise, converted hex string
2310
+ */
2311
+ rgbToHEX: function (r, g, b) {
2312
+ var hexStr = '#' + colorutil.leadingZero(r.toString(16), 2) + colorutil.leadingZero(g.toString(16), 2) + colorutil.leadingZero(b.toString(16), 2);
2313
+
2314
+ if (colorutil.isValidRGB(hexStr)) {
2315
+ return hexStr;
2316
+ }
2317
+
2318
+ return false;
2319
+ },
2320
+
2321
+ /**
2322
+ * Convert rgb number to HSV value
2323
+ * @param {number} r - red
2324
+ * @param {number} g - green
2325
+ * @param {number} b - blue
2326
+ * @returns {number[]} hsv value
2327
+ */
2328
+ rgbToHSV: function (r, g, b) {
2329
+ var max, min, h, s, v, d;
2330
+
2331
+ r /= 255;
2332
+ g /= 255;
2333
+ b /= 255;
2334
+ max = Math.max(r, g, b);
2335
+ min = Math.min(r, g, b);
2336
+ v = max;
2337
+ d = max - min;
2338
+ s = max === 0 ? 0 : d / max;
2339
+
2340
+ if (max === min) {
2341
+ h = 0;
2342
+ } else {
2343
+ switch (max) {
2344
+ case r:
2345
+ h = (g - b) / d + (g < b ? 6 : 0); break;
2346
+ case g:
2347
+ h = (b - r) / d + 2; break;
2348
+ case b:
2349
+ h = (r - g) / d + 4; break;
2350
+ // no default
2351
+ }
2352
+ h /= 6;
2353
+ }
2354
+
2355
+ return [Math.round(h * 360), Math.round(s * 100), Math.round(v * 100)];
2356
+ },
2357
+
2358
+ /**
2359
+ * Convert HSV number to RGB
2360
+ * @param {number} h - hue
2361
+ * @param {number} s - saturation
2362
+ * @param {number} v - value
2363
+ * @returns {number[]} rgb value
2364
+ */
2365
+ hsvToRGB: function (h, s, v) {
2366
+ var r, g, b;
2367
+ var i;
2368
+ var f, p, q, t;
2369
+
2370
+ h = Math.max(0, Math.min(360, h));
2371
+ s = Math.max(0, Math.min(100, s));
2372
+ v = Math.max(0, Math.min(100, v));
2373
+
2374
+ s /= 100;
2375
+ v /= 100;
2376
+
2377
+ if (s === 0) {
2378
+ // Achromatic (grey)
2379
+ r = g = b = v;
2380
+
2381
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
2382
+ }
2383
+
2384
+ h /= 60; // sector 0 to 5
2385
+ i = Math.floor(h);
2386
+ f = h - i; // factorial part of h
2387
+ p = v * (1 - s);
2388
+ q = v * (1 - s * f);
2389
+ t = v * (1 - s * (1 - f));
2390
+
2391
+ switch (i) {
2392
+ case 0:
2393
+ r = v; g = t; b = p; break;
2394
+ case 1:
2395
+ r = q; g = v; b = p; break;
2396
+ case 2:
2397
+ r = p; g = v; b = t; break;
2398
+ case 3:
2399
+ r = p; g = q; b = v; break;
2400
+ case 4:
2401
+ r = t; g = p; b = v; break;
2402
+ default:
2403
+ r = v; g = p; b = q; break;
2404
+ }
2405
+
2406
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
2407
+ }
2408
+ };
2409
+
2410
+ module.exports = colorutil;
2411
+
2412
+ /***/
2413
+ }),
2414
+ /* 15 */
2415
+ /***/ (function (module, exports, __webpack_require__) {
2416
+
2417
+ /**
2418
+ * @fileoverview ColorPicker layout module
2419
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
2420
+ */
2421
+
2422
+ 'use strict';
2423
+
2424
+ var util = __webpack_require__(8);
2425
+ var domutil = __webpack_require__(7);
2426
+ var View = __webpack_require__(11);
2427
+
2428
+ /**
2429
+ * @constructor
2430
+ * @extends {View}
2431
+ * @param {object} options - option object
2432
+ * @param {string} options.cssPrefix - css prefix for each child elements
2433
+ * @param {HTMLDivElement} container - container
2434
+ * @ignore
2435
+ */
2436
+ function Layout(options, container) {
2437
+ /**
2438
+ * option object
2439
+ * @type {object}
2440
+ */
2441
+ this.options = util.extend({
2442
+ cssPrefix: 'tui-colorpicker-'
2443
+ }, options);
2444
+
2445
+ container = domutil.appendHTMLElement('div', container, this.options.cssPrefix + 'container');
2446
+
2447
+ View.call(this, options, container);
2448
+
2449
+ this.render();
2450
+ }
2451
+
2452
+ util.inherit(Layout, View);
2453
+
2454
+ /**
2455
+ * @override
2456
+ * @param {string} [color] - selected color
2457
+ */
2458
+ Layout.prototype.render = function (color) {
2459
+ this.recursive(function (view) {
2460
+ view.render(color);
2461
+ }, true);
2462
+ };
2463
+
2464
+ module.exports = Layout;
2465
+
2466
+ /***/
2467
+ }),
2468
+ /* 16 */
2469
+ /***/ (function (module, exports, __webpack_require__) {
2470
+
2471
+ /**
2472
+ * @fileoverview Color palette view
2473
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
2474
+ */
2475
+
2476
+ 'use strict';
2477
+
2478
+ var util = __webpack_require__(8);
2479
+ var domutil = __webpack_require__(7);
2480
+ var colorutil = __webpack_require__(14);
2481
+ var domevent = __webpack_require__(9);
2482
+ var View = __webpack_require__(11);
2483
+ var tmpl = __webpack_require__(17);
2484
+
2485
+ /**
2486
+ * @constructor
2487
+ * @extends {View}
2488
+ * @mixes CustomEvents
2489
+ * @param {object} options - options for color palette view
2490
+ * @param {string[]} options.preset - color list
2491
+ * @param {HTMLDivElement} container - container element
2492
+ * @ignore
2493
+ */
2494
+ function Palette(options, container) {
2495
+ /**
2496
+ * option object
2497
+ * @type {object}
2498
+ */
2499
+ this.options = util.extend({
2500
+ cssPrefix: 'tui-colorpicker-',
2501
+ preset: ['#181818', '#282828', '#383838', '#585858', '#B8B8B8', '#D8D8D8', '#E8E8E8', '#F8F8F8', '#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946'],
2502
+ detailTxt: 'Detail'
2503
+ }, options);
2504
+
2505
+ container = domutil.appendHTMLElement('div', container, this.options.cssPrefix + 'palette-container');
2506
+
2507
+ View.call(this, options, container);
2508
+ }
2509
+
2510
+ util.inherit(Palette, View);
2511
+
2512
+ /**
2513
+ * Mouse click event handler
2514
+ * @fires Palette#_selectColor
2515
+ * @fires Palette#_toggleSlider
2516
+ * @param {MouseEvent} clickEvent - mouse event object
2517
+ */
2518
+ Palette.prototype._onClick = function (clickEvent) {
2519
+ var options = this.options,
2520
+ target = clickEvent.srcElement || clickEvent.target,
2521
+ eventData = {};
2522
+
2523
+ if (domutil.hasClass(target, options.cssPrefix + 'palette-button')) {
2524
+ eventData.color = target.value;
2525
+
2526
+ /**
2527
+ * @event Palette#_selectColor
2528
+ * @type {object}
2529
+ * @property {string} color - selected color value
2530
+ */
2531
+ this.fire('_selectColor', eventData);
2532
+
2533
+ return;
2534
+ }
2535
+
2536
+ if (domutil.hasClass(target, options.cssPrefix + 'palette-toggle-slider')) {
2537
+ /**
2538
+ * @event Palette#_toggleSlider
2539
+ */
2540
+ this.fire('_toggleSlider');
2541
+ }
2542
+ };
2543
+
2544
+ /**
2545
+ * Textbox change event handler
2546
+ * @fires Palette#_selectColor
2547
+ * @param {Event} changeEvent - change event object
2548
+ */
2549
+ Palette.prototype._onChange = function (changeEvent) {
2550
+ var options = this.options,
2551
+ target = changeEvent.srcElement || changeEvent.target,
2552
+ eventData = {};
2553
+
2554
+ if (domutil.hasClass(target, options.cssPrefix + 'palette-hex')) {
2555
+ eventData.color = target.value;
2556
+
2557
+ /**
2558
+ * @event Palette#_selectColor
2559
+ * @type {object}
2560
+ * @property {string} color - selected color value
2561
+ */
2562
+ this.fire('_selectColor', eventData);
2563
+ }
2564
+ };
2565
+
2566
+ /**
2567
+ * Invoke before destory
2568
+ * @override
2569
+ */
2570
+ Palette.prototype._beforeDestroy = function () {
2571
+ this._toggleEvent(false);
2572
+ };
2573
+
2574
+ /**
2575
+ * Toggle view DOM events
2576
+ * @param {boolean} [onOff=false] - true to bind event.
2577
+ */
2578
+ Palette.prototype._toggleEvent = function (onOff) {
2579
+ var options = this.options,
2580
+ container = this.container,
2581
+ method = domevent[!!onOff ? 'on' : 'off'],
2582
+ hexTextBox;
2583
+
2584
+ method(container, 'click', this._onClick, this);
2585
+
2586
+ hexTextBox = domutil.find('.' + options.cssPrefix + 'palette-hex', container);
2587
+
2588
+ if (hexTextBox) {
2589
+ method(hexTextBox, 'change', this._onChange, this);
2590
+ }
2591
+ };
2592
+
2593
+ /**
2594
+ * Render palette
2595
+ * @override
2596
+ */
2597
+ Palette.prototype.render = function (color) {
2598
+ var options = this.options,
2599
+ html = '';
2600
+
2601
+ this._toggleEvent(false);
2602
+
2603
+ html = tmpl.layout.replace('{{colorList}}', util.map(options.preset, function (itemColor) {
2604
+ var itemHtml = '';
2605
+ var style = '';
2606
+
2607
+ if (colorutil.isValidRGB(itemColor)) {
2608
+ style = domutil.applyTemplate(tmpl.itemStyle, { color: itemColor });
2609
+ }
2610
+
2611
+ itemHtml = domutil.applyTemplate(tmpl.item, {
2612
+ itemStyle: style,
2613
+ itemClass: !itemColor ? ' ' + options.cssPrefix + 'color-transparent' : '',
2614
+ color: itemColor,
2615
+ cssPrefix: options.cssPrefix,
2616
+ selected: itemColor === color ? ' ' + options.cssPrefix + 'selected' : ''
2617
+ });
2618
+
2619
+ return itemHtml;
2620
+ }).join(''));
2621
+
2622
+ html = domutil.applyTemplate(html, {
2623
+ cssPrefix: options.cssPrefix,
2624
+ detailTxt: options.detailTxt,
2625
+ color: color
2626
+ });
2627
+
2628
+ this.container.innerHTML = html;
2629
+
2630
+ this._toggleEvent(true);
2631
+ };
2632
+
2633
+ util.CustomEvents.mixin(Palette);
2634
+
2635
+ module.exports = Palette;
2636
+
2637
+ /***/
2638
+ }),
2639
+ /* 17 */
2640
+ /***/ (function (module, exports) {
2641
+
2642
+ /**
2643
+ * @fileoverview Palette view template
2644
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
2645
+ */
2646
+
2647
+ 'use strict';
2648
+
2649
+ var layout = ['<ul class="{{cssPrefix}}clearfix">{{colorList}}</ul>', '<div class="{{cssPrefix}}clearfix" style="overflow:hidden">', '<input type="button" class="{{cssPrefix}}palette-toggle-slider" value="{{detailTxt}}" />', '<input type="text" class="{{cssPrefix}}palette-hex" value="{{color}}" maxlength="7" />', '<span class="{{cssPrefix}}palette-preview" style="background-color:{{color}};color:{{color}}">{{color}}</span>', '</div>'].join('\n');
2650
+
2651
+ var item = '<li><input class="{{cssPrefix}}palette-button{{selected}}{{itemClass}}" type="button" style="{{itemStyle}}" title="{{color}}" value="{{color}}" /></li>';
2652
+ var itemStyle = 'background-color:{{color}};color:{{color}}';
2653
+
2654
+ module.exports = {
2655
+ layout: layout,
2656
+ item: item,
2657
+ itemStyle: itemStyle
2658
+ };
2659
+
2660
+ /***/
2661
+ }),
2662
+ /* 18 */
2663
+ /***/ (function (module, exports, __webpack_require__) {
2664
+
2665
+ /**
2666
+ * @fileoverview Slider view
2667
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
2668
+ */
2669
+
2670
+ 'use strict';
2671
+
2672
+ var util = __webpack_require__(8);
2673
+ var domutil = __webpack_require__(7);
2674
+ var domevent = __webpack_require__(9);
2675
+ var svgvml = __webpack_require__(19);
2676
+ var colorutil = __webpack_require__(14);
2677
+ var View = __webpack_require__(11);
2678
+ var Drag = __webpack_require__(12);
2679
+ var tmpl = __webpack_require__(20);
2680
+
2681
+ // Limitation position of point element inside of colorslider and hue bar
2682
+ // Minimum value can to be negative because that using color point of handle element is center point. not left, top point.
2683
+ var COLORSLIDER_POS_LIMIT_RANGE = [-7, 112];
2684
+ var HUEBAR_POS_LIMIT_RANGE = [-3, 115];
2685
+ var HUE_WHEEL_MAX = 359.99;
2686
+
2687
+ /**
2688
+ * @constructor
2689
+ * @extends {View}
2690
+ * @mixes CustomEvents
2691
+ * @param {object} options - options for view
2692
+ * @param {string} options.cssPrefix - design css prefix
2693
+ * @param {HTMLElement} container - container element
2694
+ * @ignore
2695
+ */
2696
+ function Slider(options, container) {
2697
+ container = domutil.appendHTMLElement('div', container, options.cssPrefix + 'slider-container');
2698
+ container.style.display = 'none';
2699
+
2700
+ View.call(this, options, container);
2701
+
2702
+ /**
2703
+ * @type {object}
2704
+ */
2705
+ this.options = util.extend({
2706
+ color: '#f8f8f8',
2707
+ cssPrefix: 'tui-colorpicker-'
2708
+ }, options);
2709
+
2710
+ /**
2711
+ * Cache immutable data in click, drag events.
2712
+ *
2713
+ * (i.e. is event related with colorslider? or huebar?)
2714
+ * @type {object}
2715
+ * @property {boolean} isColorSlider
2716
+ * @property {number[]} containerSize
2717
+ */
2718
+ this._dragDataCache = {};
2719
+
2720
+ /**
2721
+ * Color slider handle element
2722
+ * @type {SVG|VML}
2723
+ */
2724
+ this.sliderHandleElement = null;
2725
+
2726
+ /**
2727
+ * hue bar handle element
2728
+ * @type {SVG|VML}
2729
+ */
2730
+ this.huebarHandleElement = null;
2731
+
2732
+ /**
2733
+ * Element that render base color in colorslider part
2734
+ * @type {SVG|VML}
2735
+ */
2736
+ this.baseColorElement = null;
2737
+
2738
+ /**
2739
+ * @type {Drag}
2740
+ */
2741
+ this.drag = new Drag({
2742
+ distance: 0
2743
+ }, container);
2744
+
2745
+ // bind drag events
2746
+ this.drag.on({
2747
+ 'dragStart': this._onDragStart,
2748
+ 'drag': this._onDrag,
2749
+ 'dragEnd': this._onDragEnd,
2750
+ 'click': this._onClick
2751
+ }, this);
2752
+ }
2753
+
2754
+ util.inherit(Slider, View);
2755
+
2756
+ /**
2757
+ * @override
2758
+ */
2759
+ Slider.prototype._beforeDestroy = function () {
2760
+ this.drag.off();
2761
+
2762
+ this.drag = this.options = this._dragDataCache = this.sliderHandleElement = this.huebarHandleElement = this.baseColorElement = null;
2763
+ };
2764
+
2765
+ /**
2766
+ * Toggle slider view
2767
+ * @param {boolean} onOff - set true then reveal slider view
2768
+ */
2769
+ Slider.prototype.toggle = function (onOff) {
2770
+ this.container.style.display = !!onOff ? 'block' : 'none';
2771
+ };
2772
+
2773
+ /**
2774
+ * Get slider display status
2775
+ * @returns {boolean} return true when slider is visible
2776
+ */
2777
+ Slider.prototype.isVisible = function () {
2778
+ return this.container.style.display === 'block';
2779
+ };
2780
+
2781
+ /**
2782
+ * Render slider view
2783
+ * @override
2784
+ * @param {string} colorStr - hex string color from parent view (Layout)
2785
+ */
2786
+ Slider.prototype.render = function (colorStr) {
2787
+ var that = this,
2788
+ container = that.container,
2789
+ options = that.options,
2790
+ html = tmpl.layout,
2791
+ rgb,
2792
+ hsv;
2793
+
2794
+ if (!colorutil.isValidRGB(colorStr)) {
2795
+ return;
2796
+ }
2797
+
2798
+ html = html.replace(/{{slider}}/, tmpl.slider);
2799
+ html = html.replace(/{{huebar}}/, tmpl.huebar);
2800
+ html = html.replace(/{{cssPrefix}}/g, options.cssPrefix);
2801
+
2802
+ that.container.innerHTML = html;
2803
+
2804
+ that.sliderHandleElement = domutil.find('.' + options.cssPrefix + 'slider-handle', container);
2805
+ that.huebarHandleElement = domutil.find('.' + options.cssPrefix + 'huebar-handle', container);
2806
+ that.baseColorElement = domutil.find('.' + options.cssPrefix + 'slider-basecolor', container);
2807
+
2808
+ rgb = colorutil.hexToRGB(colorStr);
2809
+ hsv = colorutil.rgbToHSV.apply(null, rgb);
2810
+
2811
+ this.moveHue(hsv[0], true);
2812
+ this.moveSaturationAndValue(hsv[1], hsv[2], true);
2813
+ };
2814
+
2815
+ /**
2816
+ * Move colorslider by newLeft(X), newTop(Y) value
2817
+ * @private
2818
+ * @param {number} newLeft - left pixel value to move handle
2819
+ * @param {number} newTop - top pixel value to move handle
2820
+ * @param {boolean} [silent=false] - set true then not fire custom event
2821
+ */
2822
+ Slider.prototype._moveColorSliderHandle = function (newLeft, newTop, silent) {
2823
+ var handle = this.sliderHandleElement,
2824
+ handleColor;
2825
+
2826
+ // Check position limitation.
2827
+ newTop = Math.max(COLORSLIDER_POS_LIMIT_RANGE[0], newTop);
2828
+ newTop = Math.min(COLORSLIDER_POS_LIMIT_RANGE[1], newTop);
2829
+ newLeft = Math.max(COLORSLIDER_POS_LIMIT_RANGE[0], newLeft);
2830
+ newLeft = Math.min(COLORSLIDER_POS_LIMIT_RANGE[1], newLeft);
2831
+
2832
+ svgvml.setTranslateXY(handle, newLeft, newTop);
2833
+
2834
+ handleColor = newTop > 50 ? 'white' : 'black';
2835
+ svgvml.setStrokeColor(handle, handleColor);
2836
+
2837
+ if (!silent) {
2838
+ this.fire('_selectColor', {
2839
+ color: colorutil.rgbToHEX.apply(null, this.getRGB())
2840
+ });
2841
+ }
2842
+ };
2843
+
2844
+ /**
2845
+ * Move colorslider by supplied saturation and values.
2846
+ *
2847
+ * The movement of color slider handle follow HSV cylinder model. {@link https://en.wikipedia.org/wiki/HSL_and_HSV}
2848
+ * @param {number} saturation - the percent of saturation (0% ~ 100%)
2849
+ * @param {number} value - the percent of saturation (0% ~ 100%)
2850
+ * @param {boolean} [silent=false] - set true then not fire custom event
2851
+ */
2852
+ Slider.prototype.moveSaturationAndValue = function (saturation, value, silent) {
2853
+ var absMin, maxValue, newLeft, newTop;
2854
+
2855
+ saturation = saturation || 0;
2856
+ value = value || 0;
2857
+
2858
+ absMin = Math.abs(COLORSLIDER_POS_LIMIT_RANGE[0]);
2859
+ maxValue = COLORSLIDER_POS_LIMIT_RANGE[1];
2860
+
2861
+ // subtract absMin value because current color position is not left, top of handle element.
2862
+ // The saturation. from left 0 to right 100
2863
+ newLeft = saturation * maxValue / 100 - absMin;
2864
+ // The Value. from top 100 to bottom 0. that why newTop subtract by maxValue.
2865
+ newTop = maxValue - value * maxValue / 100 - absMin;
2866
+
2867
+ this._moveColorSliderHandle(newLeft, newTop, silent);
2868
+ };
2869
+
2870
+ /**
2871
+ * Move color slider handle to supplied position
2872
+ *
2873
+ * The number of X, Y must be related value from color slider container
2874
+ * @private
2875
+ * @param {number} x - the pixel value to move handle
2876
+ * @param {number} y - the pixel value to move handle
2877
+ */
2878
+ Slider.prototype._moveColorSliderByPosition = function (x, y) {
2879
+ var offset = COLORSLIDER_POS_LIMIT_RANGE[0];
2880
+ this._moveColorSliderHandle(x + offset, y + offset);
2881
+ };
2882
+
2883
+ /**
2884
+ * Get saturation and value value.
2885
+ * @returns {number[]} saturation and value
2886
+ */
2887
+ Slider.prototype.getSaturationAndValue = function () {
2888
+ var absMin = Math.abs(COLORSLIDER_POS_LIMIT_RANGE[0]),
2889
+ maxValue = absMin + COLORSLIDER_POS_LIMIT_RANGE[1],
2890
+ position = svgvml.getTranslateXY(this.sliderHandleElement),
2891
+ saturation,
2892
+ value;
2893
+
2894
+ saturation = (position[1] + absMin) / maxValue * 100;
2895
+ // The value of HSV color model is inverted. top 100 ~ bottom 0. so subtract by 100
2896
+ value = 100 - (position[0] + absMin) / maxValue * 100;
2897
+
2898
+ return [saturation, value];
2899
+ };
2900
+
2901
+ /**
2902
+ * Move hue handle supplied pixel value
2903
+ * @private
2904
+ * @param {number} newTop - pixel to move hue handle
2905
+ * @param {boolean} [silent=false] - set true then not fire custom event
2906
+ */
2907
+ Slider.prototype._moveHueHandle = function (newTop, silent) {
2908
+ var hueHandleElement = this.huebarHandleElement,
2909
+ baseColorElement = this.baseColorElement,
2910
+ newGradientColor,
2911
+ hexStr;
2912
+
2913
+ newTop = Math.max(HUEBAR_POS_LIMIT_RANGE[0], newTop);
2914
+ newTop = Math.min(HUEBAR_POS_LIMIT_RANGE[1], newTop);
2915
+
2916
+ svgvml.setTranslateY(hueHandleElement, newTop);
2917
+
2918
+ newGradientColor = colorutil.hsvToRGB(this.getHue(), 100, 100);
2919
+ hexStr = colorutil.rgbToHEX.apply(null, newGradientColor);
2920
+
2921
+ svgvml.setGradientColorStop(baseColorElement, hexStr);
2922
+
2923
+ if (!silent) {
2924
+ this.fire('_selectColor', {
2925
+ color: colorutil.rgbToHEX.apply(null, this.getRGB())
2926
+ });
2927
+ }
2928
+ };
2929
+
2930
+ /**
2931
+ * Move hue bar handle by supplied degree
2932
+ * @param {number} degree - (0 ~ 359.9 degree)
2933
+ * @param {boolean} [silent=false] - set true then not fire custom event
2934
+ */
2935
+ Slider.prototype.moveHue = function (degree, silent) {
2936
+ var newTop = 0,
2937
+ absMin,
2938
+ maxValue;
2939
+
2940
+ absMin = Math.abs(HUEBAR_POS_LIMIT_RANGE[0]);
2941
+ maxValue = absMin + HUEBAR_POS_LIMIT_RANGE[1];
2942
+
2943
+ degree = degree || 0;
2944
+ newTop = maxValue * degree / HUE_WHEEL_MAX - absMin;
2945
+
2946
+ this._moveHueHandle(newTop, silent);
2947
+ };
2948
+
2949
+ /**
2950
+ * Move hue bar handle by supplied percent
2951
+ * @private
2952
+ * @param {number} y - pixel value to move hue handle
2953
+ */
2954
+ Slider.prototype._moveHueByPosition = function (y) {
2955
+ var offset = HUEBAR_POS_LIMIT_RANGE[0];
2956
+
2957
+ this._moveHueHandle(y + offset);
2958
+ };
2959
+
2960
+ /**
2961
+ * Get huebar handle position by color degree
2962
+ * @returns {number} degree (0 ~ 359.9 degree)
2963
+ */
2964
+ Slider.prototype.getHue = function () {
2965
+ var handle = this.huebarHandleElement,
2966
+ position = svgvml.getTranslateXY(handle),
2967
+ absMin,
2968
+ maxValue;
2969
+
2970
+ absMin = Math.abs(HUEBAR_POS_LIMIT_RANGE[0]);
2971
+ maxValue = absMin + HUEBAR_POS_LIMIT_RANGE[1];
2972
+
2973
+ // maxValue : 359.99 = pos.y : x
2974
+ return (position[0] + absMin) * HUE_WHEEL_MAX / maxValue;
2975
+ };
2976
+
2977
+ /**
2978
+ * Get HSV value from slider
2979
+ * @returns {number[]} hsv values
2980
+ */
2981
+ Slider.prototype.getHSV = function () {
2982
+ var sv = this.getSaturationAndValue(),
2983
+ h = this.getHue();
2984
+
2985
+ return [h].concat(sv);
2986
+ };
2987
+
2988
+ /**
2989
+ * Get RGB value from slider
2990
+ * @returns {number[]} RGB value
2991
+ */
2992
+ Slider.prototype.getRGB = function () {
2993
+ return colorutil.hsvToRGB.apply(null, this.getHSV());
2994
+ };
2995
+
2996
+ /**********
2997
+ * Drag event handler
2998
+ **********/
2999
+
3000
+ /**
3001
+ * Cache immutable data when dragging or click view
3002
+ * @param {object} event - Click, DragStart event.
3003
+ * @returns {object} cached data.
3004
+ */
3005
+ Slider.prototype._prepareColorSliderForMouseEvent = function (event) {
3006
+ var options = this.options,
3007
+ sliderPart = domutil.closest(event.target, '.' + options.cssPrefix + 'slider-part'),
3008
+ cache;
3009
+
3010
+ cache = this._dragDataCache = {
3011
+ isColorSlider: domutil.hasClass(sliderPart, options.cssPrefix + 'slider-left'),
3012
+ parentElement: sliderPart
3013
+ };
3014
+
3015
+ return cache;
3016
+ };
3017
+
3018
+ /**
3019
+ * Click event handler
3020
+ * @param {object} clickEvent - Click event from Drag module
3021
+ */
3022
+ Slider.prototype._onClick = function (clickEvent) {
3023
+ var cache = this._prepareColorSliderForMouseEvent(clickEvent),
3024
+ mousePos = domevent.getMousePosition(clickEvent.originEvent, cache.parentElement);
3025
+
3026
+ if (cache.isColorSlider) {
3027
+ this._moveColorSliderByPosition(mousePos[0], mousePos[1]);
3028
+ } else {
3029
+ this._moveHueByPosition(mousePos[1]);
3030
+ }
3031
+
3032
+ this._dragDataCache = null;
3033
+ };
3034
+
3035
+ /**
3036
+ * DragStart event handler
3037
+ * @param {object} dragStartEvent - dragStart event data from Drag#dragStart
3038
+ */
3039
+ Slider.prototype._onDragStart = function (dragStartEvent) {
3040
+ this._prepareColorSliderForMouseEvent(dragStartEvent);
3041
+ };
3042
+
3043
+ /**
3044
+ * Drag event handler
3045
+ * @param {Drag#drag} dragEvent - drag event data
3046
+ */
3047
+ Slider.prototype._onDrag = function (dragEvent) {
3048
+ var cache = this._dragDataCache,
3049
+ mousePos = domevent.getMousePosition(dragEvent.originEvent, cache.parentElement);
3050
+
3051
+ if (cache.isColorSlider) {
3052
+ this._moveColorSliderByPosition(mousePos[0], mousePos[1]);
3053
+ } else {
3054
+ this._moveHueByPosition(mousePos[1]);
3055
+ }
3056
+ };
3057
+
3058
+ /**
3059
+ * Drag#dragEnd event handler
3060
+ */
3061
+ Slider.prototype._onDragEnd = function () {
3062
+ this._dragDataCache = null;
3063
+ };
3064
+
3065
+ util.CustomEvents.mixin(Slider);
3066
+
3067
+ module.exports = Slider;
3068
+
3069
+ /***/
3070
+ }),
3071
+ /* 19 */
3072
+ /***/ (function (module, exports, __webpack_require__) {
3073
+
3074
+ /**
3075
+ * @fileoverview module for manipulate SVG or VML object
3076
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
3077
+ */
3078
+
3079
+ 'use strict';
3080
+
3081
+ var util = __webpack_require__(8);
3082
+ var PARSE_TRANSLATE_NUM_REGEX = /[\.\-0-9]+/g;
3083
+ var SVG_HUE_HANDLE_RIGHT_POS = -6;
3084
+
3085
+ /* istanbul ignore next */
3086
+ var svgvml = {
3087
+ /**
3088
+ * Return true when browser is below IE8.
3089
+ * @returns {boolean} is old browser?
3090
+ */
3091
+ isOldBrowser: function () {
3092
+ var _isOldBrowser = svgvml._isOldBrowser;
3093
+
3094
+ if (!util.isExisty(_isOldBrowser)) {
3095
+ svgvml._isOldBrowser = _isOldBrowser = util.browser.msie && util.browser.version < 9;
3096
+ }
3097
+
3098
+ return _isOldBrowser;
3099
+ },
3100
+
3101
+ /**
3102
+ * Get translate transform value
3103
+ * @param {SVG|VML} obj - svg or vml object that want to know translate x, y
3104
+ * @returns {number[]} translated coordinates [x, y]
3105
+ */
3106
+ getTranslateXY: function (obj) {
3107
+ var temp;
3108
+
3109
+ if (svgvml.isOldBrowser()) {
3110
+ temp = obj.style;
3111
+
3112
+ return [parseFloat(temp.top), parseFloat(temp.left)];
3113
+ }
3114
+
3115
+ temp = obj.getAttribute('transform');
3116
+
3117
+ if (!temp) {
3118
+ return [0, 0];
3119
+ }
3120
+
3121
+ temp = temp.match(PARSE_TRANSLATE_NUM_REGEX);
3122
+
3123
+ // need caution for difference of VML, SVG coordinates system.
3124
+ // translate command need X coords in first parameter. but VML is use CSS coordinate system(top, left)
3125
+ return [parseFloat(temp[1]), parseFloat(temp[0])];
3126
+ },
3127
+
3128
+ /**
3129
+ * Set translate transform value
3130
+ * @param {SVG|VML} obj - SVG or VML object to setting translate transform.
3131
+ * @param {number} x - translate X value
3132
+ * @param {number} y - translate Y value
3133
+ */
3134
+ setTranslateXY: function (obj, x, y) {
3135
+ if (svgvml.isOldBrowser()) {
3136
+ obj.style.left = x + 'px';
3137
+ obj.style.top = y + 'px';
3138
+ } else {
3139
+ obj.setAttribute('transform', 'translate(' + x + ',' + y + ')');
3140
+ }
3141
+ },
3142
+
3143
+ /**
3144
+ * Set translate only Y value
3145
+ * @param {SVG|VML} obj - SVG or VML object to setting translate transform.
3146
+ * @param {number} y - translate Y value
3147
+ */
3148
+ setTranslateY: function (obj, y) {
3149
+ if (svgvml.isOldBrowser()) {
3150
+ obj.style.top = y + 'px';
3151
+ } else {
3152
+ obj.setAttribute('transform', 'translate(' + SVG_HUE_HANDLE_RIGHT_POS + ',' + y + ')');
3153
+ }
3154
+ },
3155
+
3156
+ /**
3157
+ * Set stroke color to SVG or VML object
3158
+ * @param {SVG|VML} obj - SVG or VML object to setting stroke color
3159
+ * @param {string} colorStr - color string
3160
+ */
3161
+ setStrokeColor: function (obj, colorStr) {
3162
+ if (svgvml.isOldBrowser()) {
3163
+ obj.strokecolor = colorStr;
3164
+ } else {
3165
+ obj.setAttribute('stroke', colorStr);
3166
+ }
3167
+ },
3168
+
3169
+ /**
3170
+ * Set gradient stop color to SVG, VML object.
3171
+ * @param {SVG|VML} obj - SVG, VML object to applying gradient stop color
3172
+ * @param {string} colorStr - color string
3173
+ */
3174
+ setGradientColorStop: function (obj, colorStr) {
3175
+ if (svgvml.isOldBrowser()) {
3176
+ obj.color = colorStr;
3177
+ } else {
3178
+ obj.setAttribute('stop-color', colorStr);
3179
+ }
3180
+ }
3181
+
3182
+ };
3183
+
3184
+ module.exports = svgvml;
3185
+
3186
+ /***/
3187
+ }),
3188
+ /* 20 */
3189
+ /***/ (function (module, exports, __webpack_require__) {
3190
+
3191
+ /* WEBPACK VAR INJECTION */(function (global) {/**
3192
+ * @fileoverview Slider template
3193
+ * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
3194
+ */
3195
+
3196
+ 'use strict';
3197
+
3198
+ var util = __webpack_require__(8);
3199
+
3200
+ var layout = ['<div class="{{cssPrefix}}slider-left {{cssPrefix}}slider-part">{{slider}}</div>', '<div class="{{cssPrefix}}slider-right {{cssPrefix}}slider-part">{{huebar}}</div>'].join('\n');
3201
+
3202
+ var SVGSlider = ['<svg class="{{cssPrefix}}svg {{cssPrefix}}svg-slider">', '<defs>', '<linearGradient id="{{cssPrefix}}svg-fill-color" x1="0%" y1="0%" x2="100%" y2="0%">', '<stop offset="0%" stop-color="rgb(255,255,255)" />', '<stop class="{{cssPrefix}}slider-basecolor" offset="100%" stop-color="rgb(255,0,0)" />', '</linearGradient>', '<linearGradient id="{{cssPrefix}}svn-fill-black" x1="0%" y1="0%" x2="0%" y2="100%">', '<stop offset="0%" style="stop-color:rgb(0,0,0);stop-opacity:0" />', '<stop offset="100%" style="stop-color:rgb(0,0,0);stop-opacity:1" />', '</linearGradient>', '</defs>', '<rect width="100%" height="100%" fill="url(#{{cssPrefix}}svg-fill-color)"></rect>', '<rect width="100%" height="100%" fill="url(#{{cssPrefix}}svn-fill-black)"></rect>', '<path transform="translate(0,0)" class="{{cssPrefix}}slider-handle" d="M0 7.5 L15 7.5 M7.5 15 L7.5 0 M2 7 a5.5 5.5 0 1 1 0 1 Z" stroke="black" stroke-width="0.75" fill="none" />', '</svg>'].join('\n');
3203
+
3204
+ var VMLSlider = ['<div class="{{cssPrefix}}vml-slider">', '<v:rect strokecolor="none" class="{{cssPrefix}}vml {{cssPrefix}}vml-slider-bg">', '<v:fill class="{{cssPrefix}}vml {{cssPrefix}}slider-basecolor" type="gradient" method="none" color="#ff0000" color2="#fff" angle="90" />', '</v:rect>', '<v:rect strokecolor="#ccc" class="{{cssPrefix}}vml {{cssPrefix}}vml-slider-bg">', '<v:fill type="gradient" method="none" color="black" color2="white" o:opacity2="0%" class="{{cssPrefix}}vml" />', '</v:rect>', '<v:shape class="{{cssPrefix}}vml {{cssPrefix}}slider-handle" coordsize="1 1" style="width:1px;height:1px;"' + 'path="m 0,7 l 14,7 m 7,14 l 7,0 ar 12,12 2,2 z" filled="false" stroked="true" />', '</div>'].join('\n');
3205
+
3206
+ var SVGHuebar = ['<svg class="{{cssPrefix}}svg {{cssPrefix}}svg-huebar">', '<defs>', '<linearGradient id="g" x1="0%" y1="0%" x2="0%" y2="100%">', '<stop offset="0%" stop-color="rgb(255,0,0)" />', '<stop offset="16.666%" stop-color="rgb(255,255,0)" />', '<stop offset="33.333%" stop-color="rgb(0,255,0)" />', '<stop offset="50%" stop-color="rgb(0,255,255)" />', '<stop offset="66.666%" stop-color="rgb(0,0,255)" />', '<stop offset="83.333%" stop-color="rgb(255,0,255)" />', '<stop offset="100%" stop-color="rgb(255,0,0)" />', '</linearGradient>', '</defs>', '<rect width="18px" height="100%" fill="url(#g)"></rect>', '<path transform="translate(-6,-3)" class="{{cssPrefix}}huebar-handle" d="M0 0 L4 4 L0 8 L0 0 Z" fill="black" stroke="none" />', '</svg>'].join('\n');
3207
+
3208
+ var VMLHuebar = ['<div class="{{cssPrefix}}vml-huebar">', '<v:rect strokecolor="#ccc" class="{{cssPrefix}}vml {{cssPrefix}}vml-huebar-bg">', '<v:fill type="gradient" method="none" colors="' + '0% rgb(255,0,0), 16.666% rgb(255,255,0), 33.333% rgb(0,255,0), 50% rgb(0,255,255), 66.666% rgb(0,0,255), 83.333% rgb(255,0,255), 100% rgb(255,0,0)' + '" angle="180" class="{{cssPrefix}}vml" />', '</v:rect>', '<v:shape class="{{cssPrefix}}vml {{cssPrefix}}huebar-handle" coordsize="1 1" style="width:1px;height:1px;position:absolute;z-index:1;right:22px;top:-3px;"' + 'path="m 0,0 l 4,4 l 0,8 l 0,0 z" filled="true" fillcolor="black" stroked="false" />', '</div>'].join('\n');
3209
+
3210
+ var isOldBrowser = util.browser.msie && util.browser.version < 9;
3211
+
3212
+ if (isOldBrowser) {
3213
+ global.document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
3214
+ }
3215
+
3216
+ module.exports = {
3217
+ layout: layout,
3218
+ slider: isOldBrowser ? VMLSlider : SVGSlider,
3219
+ huebar: isOldBrowser ? VMLHuebar : SVGHuebar
3220
+ };
3221
+ /* WEBPACK VAR INJECTION */
3222
+ }.call(exports, (function () { return this; }())))
3223
+
3224
+ /***/
3225
+ })
3226
+ /******/])
3227
+ });
3228
+ ;