tui_image_editor 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +2 -0
- data/lib/tui_image_editor/version.rb +3 -0
- data/lib/tui_image_editor.rb +7 -0
- data/vendor/assets/images/icon-a.svg +235 -0
- data/vendor/assets/images/icon-b.svg +224 -0
- data/vendor/assets/images/icon-c.svg +224 -0
- data/vendor/assets/images/icon-d.svg +224 -0
- data/vendor/assets/javascripts/fabric.js +26122 -0
- data/vendor/assets/javascripts/file_server.min.js +2 -0
- data/vendor/assets/javascripts/tui-code-snippet.min.js +0 -0
- data/vendor/assets/javascripts/tui.color-picker.js +3228 -0
- data/vendor/assets/javascripts/tui.image-editor.js.erb +22667 -0
- data/vendor/assets/javascripts/tui_image_editor.js +5 -0
- data/vendor/assets/stylesheets/tui-color-picker.css +177 -0
- data/vendor/assets/stylesheets/tui.image-editor.css +1081 -0
- metadata +129 -0
@@ -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
|
+
;
|