tui_image_editor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ ;