tui-color-picker-hvx
Version:
TOAST UI Components: Color Picker
2,075 lines (1,723 loc) • 129 kB
JavaScript
/*!
* TOAST UI Color Picker
* @version 2.2.7
* @author NHN FE Development Team <dl_javascript@nhn.com>
* @license MIT
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["colorPicker"] = factory();
else
root["tui"] = root["tui"] || {}, root["tui"]["colorPicker"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "dist";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 33);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Extend the target object from other objects.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* @module object
*/
/**
* Extend the target object from other objects.
* @param {object} target - Object that will be extended
* @param {...object} objects - Objects as sources
* @returns {object} Extended object
* @memberof module:object
*/
function extend(target, objects) { // eslint-disable-line no-unused-vars
var hasOwnProp = Object.prototype.hasOwnProperty;
var source, prop, i, len;
for (i = 1, len = arguments.length; i < len; i += 1) {
source = arguments[i];
for (prop in source) {
if (hasOwnProp.call(source, prop)) {
target[prop] = source[prop];
}
}
}
return target;
}
module.exports = extend;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Check whether the given variable is an instance of Array or not.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Check whether the given variable is an instance of Array or not.
* If the given variable is an instance of Array, return true.
* @param {*} obj - Target for checking
* @returns {boolean} Is array instance?
* @memberof module:type
*/
function isArray(obj) {
return obj instanceof Array;
}
module.exports = isArray;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Execute the provided callback once for each property of object(or element of array) which actually exist.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
var isArray = __webpack_require__(1);
var forEachArray = __webpack_require__(6);
var forEachOwnProperties = __webpack_require__(7);
/**
* @module collection
*/
/**
* Execute the provided callback once for each property of object(or element of array) which actually exist.
* If the object is Array-like object(ex-arguments object), It needs to transform to Array.(see 'ex2' of example).
* If the callback function returns false, the loop will be stopped.
* Callback function(iteratee) is invoked with three arguments:
* 1) The value of the property(or The value of the element)
* 2) The name of the property(or The index of the element)
* 3) The object being traversed
* @param {Object} obj The object that will be traversed
* @param {function} iteratee Callback function
* @param {Object} [context] Context(this) of callback function
* @memberof module:collection
* @example
* var forEach = require('tui-code-snippet/collection/forEach'); // node, commonjs
*
* var sum = 0;
*
* forEach([1,2,3], function(value){
* sum += value;
* });
* alert(sum); // 6
*
* // In case of Array-like object
* var array = Array.prototype.slice.call(arrayLike); // change to array
* forEach(array, function(value){
* sum += value;
* });
*/
function forEach(obj, iteratee, context) {
if (isArray(obj)) {
forEachArray(obj, iteratee, context);
} else {
forEachOwnProperties(obj, iteratee, context);
}
}
module.exports = forEach;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Check whether the given variable is undefined or not.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Check whether the given variable is undefined or not.
* If the given variable is undefined, returns true.
* @param {*} obj - Target for checking
* @returns {boolean} Is undefined?
* @memberof module:type
*/
function isUndefined(obj) {
return obj === undefined; // eslint-disable-line no-undefined
}
module.exports = isUndefined;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Utils for ColorPicker component
* @author NHN. FE dev Lab. <dl_javascript@nhn.com>
*/
var browser = __webpack_require__(22);
var forEach = __webpack_require__(2);
var forEachArray = __webpack_require__(6);
var forEachOwnProperties = __webpack_require__(7);
var sendHostname = __webpack_require__(37);
var currentId = 0;
/**
* Utils
* @namespace util
* @ignore
*/
var utils = {
/**
* Get the number of properties in the object.
* @param {Object} obj - object
* @returns {number}
*/
getLength: function (obj) {
var length = 0;
forEachOwnProperties(obj, function () {
length += 1;
});
return length;
},
/**
* Constructs a new array by executing the provided callback function.
* @param {Object|Array} obj - object or array to be traversed
* @param {function} iteratee - callback function
* @param {Object} context - context of callback function
* @returns {Array}
*/
map: function (obj, iteratee, context) {
var result = [];
forEach(obj, function () {
result.push(iteratee.apply(context || null, arguments));
});
return result;
},
/**
* Construct a new array with elements that pass the test by the provided callback function.
* @param {Array|NodeList|Arguments} arr - array to be traversed
* @param {function} iteratee - callback function
* @param {Object} context - context of callback function
* @returns {Array}
*/
filter: function (arr, iteratee, context) {
var result = [];
forEachArray(arr, function (elem) {
if (iteratee.apply(context || null, arguments)) {
result.push(elem);
}
});
return result;
},
/**
* Create an unique id for a color-picker instance.
* @returns {number}
*/
generateId: function () {
currentId += 1;
return currentId;
},
/**
* True when browser is below IE8.
*/
isOldBrowser: function () {
return browser.msie && browser.version < 9;
}(),
/**
* send host name
* @ignore
*/
sendHostName: function () {
sendHostname('color-picker', 'UA-129987462-1');
}
};
module.exports = utils;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/* eslint-disable complexity */
/**
* @fileoverview Returns the first index at which a given element can be found in the array.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
var isArray = __webpack_require__(1);
/**
* @module array
*/
/**
* Returns the first index at which a given element can be found in the array
* from start index(default 0), or -1 if it is not present.
* It compares searchElement to elements of the Array using strict equality
* (the same method used by the ===, or triple-equals, operator).
* @param {*} searchElement Element to locate in the array
* @param {Array} array Array that will be traversed.
* @param {number} startIndex Start index in array for searching (default 0)
* @returns {number} the First index at which a given element, or -1 if it is not present
* @memberof module:array
* @example
* var inArray = require('tui-code-snippet/array/inArray'); // node, commonjs
*
* var arr = ['one', 'two', 'three', 'four'];
* var idx1 = inArray('one', arr, 3); // -1
* var idx2 = inArray('one', arr); // 0
*/
function inArray(searchElement, array, startIndex) {
var i;
var length;
startIndex = startIndex || 0;
if (!isArray(array)) {
return -1;
}
if (Array.prototype.indexOf) {
return Array.prototype.indexOf.call(array, searchElement, startIndex);
}
length = array.length;
for (i = startIndex; startIndex >= 0 && i < length; i += 1) {
if (array[i] === searchElement) {
return i;
}
}
return -1;
}
module.exports = inArray;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Execute the provided callback once for each element present in the array(or Array-like object) in ascending order.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Execute the provided callback once for each element present
* in the array(or Array-like object) in ascending order.
* If the callback function returns false, the loop will be stopped.
* Callback function(iteratee) is invoked with three arguments:
* 1) The value of the element
* 2) The index of the element
* 3) The array(or Array-like object) being traversed
* @param {Array|Arguments|NodeList} arr The array(or Array-like object) that will be traversed
* @param {function} iteratee Callback function
* @param {Object} [context] Context(this) of callback function
* @memberof module:collection
* @example
* var forEachArray = require('tui-code-snippet/collection/forEachArray'); // node, commonjs
*
* var sum = 0;
*
* forEachArray([1,2,3], function(value){
* sum += value;
* });
* alert(sum); // 6
*/
function forEachArray(arr, iteratee, context) {
var index = 0;
var len = arr.length;
context = context || null;
for (; index < len; index += 1) {
if (iteratee.call(context, arr[index], index, arr) === false) {
break;
}
}
}
module.exports = forEachArray;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Execute the provided callback once for each property of object which actually exist.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Execute the provided callback once for each property of object which actually exist.
* If the callback function returns false, the loop will be stopped.
* Callback function(iteratee) is invoked with three arguments:
* 1) The value of the property
* 2) The name of the property
* 3) The object being traversed
* @param {Object} obj The object that will be traversed
* @param {function} iteratee Callback function
* @param {Object} [context] Context(this) of callback function
* @memberof module:collection
* @example
* var forEachOwnProperties = require('tui-code-snippet/collection/forEachOwnProperties'); // node, commonjs
*
* var sum = 0;
*
* forEachOwnProperties({a:1,b:2,c:3}, function(value){
* sum += value;
* });
* alert(sum); // 6
*/
function forEachOwnProperties(obj, iteratee, context) {
var key;
context = context || null;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (iteratee.call(context, obj[key], key, obj) === false) {
break;
}
}
}
}
module.exports = forEachOwnProperties;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview The base class of views.
* @author NHN. FE Development Team <dl_javascript@nhn.com>
*/
var addClass = __webpack_require__(39);
var isFunction = __webpack_require__(13);
var isNumber = __webpack_require__(41);
var isUndefined = __webpack_require__(3);
var domUtil = __webpack_require__(9);
var Collection = __webpack_require__(19);
var util = __webpack_require__(4);
/**
* Base class of views.
*
* All views create own container element inside supplied container element.
* @constructor
* @param {options} options The object for describe view's specs.
* @param {HTMLElement} container Default container element for view. you can use this element for this.container syntax.
* @ignore
*/
function View(options, container) {
var id = util.generateId();
options = options || {};
if (isUndefined(container)) {
container = domUtil.appendHTMLElement('div');
}
addClass(container, 'tui-view-' + id);
/**
* unique id
* @type {number}
*/
this.id = id;
/**
* base element of view.
* @type {HTMLDIVElement}
*/
this.container = container;
/**
* child views.
* @type {Collection}
*/
this.childs = new Collection(function (view) {
return view.id;
});
/**
* parent view instance.
* @type {View}
*/
this.parent = null;
}
/**
* Add child views.
* @param {View} view The view instance to add.
* @param {function} [fn] Function for invoke before add. parent view class is supplied first arguments.
*/
View.prototype.addChild = function (view, fn) {
if (fn) {
fn.call(view, this);
} // add parent view
view.parent = this;
this.childs.add(view);
};
/**
* Remove added child view.
* @param {(number|View)} id View id or instance itself to remove.
* @param {function} [fn] Function for invoke before remove. parent view class is supplied first arguments.
*/
View.prototype.removeChild = function (id, fn) {
var view = isNumber(id) ? this.childs.items[id] : id;
if (fn) {
fn.call(view, this);
}
this.childs.remove(view.id);
};
/**
* Render view recursively.
*/
View.prototype.render = function () {
this.childs.each(function (childView) {
childView.render();
});
};
/**
* Invoke function recursively.
* @param {function} fn - function to invoke child view recursively
* @param {boolean} [skipThis=false] - set true then skip invoke with this(root) view.
*/
View.prototype.recursive = function (fn, skipThis) {
if (!isFunction(fn)) {
return;
}
if (!skipThis) {
fn(this);
}
this.childs.each(function (childView) {
childView.recursive(fn);
});
};
/**
* Resize view recursively to parent.
*/
View.prototype.resize = function () {
var args = Array.prototype.slice.call(arguments);
var parent = this.parent;
while (parent) {
if (isFunction(parent._onResize)) {
parent._onResize.apply(parent, args);
}
parent = parent.parent;
}
};
/**
* Invoking method before destroying.
*/
View.prototype._beforeDestroy = function () {};
/**
* Clear properties
*/
View.prototype._destroy = function () {
this._beforeDestroy();
this.container.innerHTML = '';
this.id = this.parent = this.childs = this.container = null;
};
/**
* Destroy child view recursively.
* @param {boolean} isChildView - Whether it is the child view or not
*/
View.prototype.destroy = function (isChildView) {
if (this.childs) {
this.childs.each(function (childView) {
childView.destroy(true);
childView._destroy();
});
this.childs.clear();
}
if (isChildView) {
return;
}
this._destroy();
};
/**
* Calculate view's container element bound.
* @returns {object} The bound of container element.
*/
View.prototype.getViewBound = function () {
var bound = this.container.getBoundingClientRect();
return {
x: bound.left,
y: bound.top,
width: bound.right - bound.left,
height: bound.bottom - bound.top
};
};
module.exports = View;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Utility modules for manipulate DOM elements.
* @author NHN. FE Development Team <dl_javascript@nhn.com>
*/
var domUtil = {
/**
* Create DOM element and return it.
* @param {string} tagName Tag name to append.
* @param {HTMLElement} [container] HTML element will be parent to created element.
* if not supplied, will use **document.body**
* @param {string} [className] Design class names to appling created element.
* @returns {HTMLElement} HTML element created.
*/
appendHTMLElement: function (tagName, container, className) {
var el = document.createElement(tagName);
el.className = className || '';
if (container) {
container.appendChild(el);
} else {
document.body.appendChild(el);
}
return el;
}
};
module.exports = domUtil;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview This module provides some functions for custom events. And it is implemented in the observer design pattern.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
var extend = __webpack_require__(0);
var isExisty = __webpack_require__(20);
var isString = __webpack_require__(11);
var isObject = __webpack_require__(21);
var isArray = __webpack_require__(1);
var isFunction = __webpack_require__(13);
var forEach = __webpack_require__(2);
var R_EVENTNAME_SPLIT = /\s+/g;
/**
* @class
* @example
* // node, commonjs
* var CustomEvents = require('tui-code-snippet/customEvents/customEvents');
*/
function CustomEvents() {
/**
* @type {HandlerItem[]}
*/
this.events = null;
/**
* only for checking specific context event was binded
* @type {object[]}
*/
this.contexts = null;
}
/**
* Mixin custom events feature to specific constructor
* @param {function} func - constructor
* @example
* var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); // node, commonjs
*
* var model;
* function Model() {
* this.name = '';
* }
* CustomEvents.mixin(Model);
*
* model = new Model();
* model.on('change', function() { this.name = 'model'; }, this);
* model.fire('change');
* alert(model.name); // 'model';
*/
CustomEvents.mixin = function(func) {
extend(func.prototype, CustomEvents.prototype);
};
/**
* Get HandlerItem object
* @param {function} handler - handler function
* @param {object} [context] - context for handler
* @returns {HandlerItem} HandlerItem object
* @private
*/
CustomEvents.prototype._getHandlerItem = function(handler, context) {
var item = {handler: handler};
if (context) {
item.context = context;
}
return item;
};
/**
* Get event object safely
* @param {string} [eventName] - create sub event map if not exist.
* @returns {(object|array)} event object. if you supplied `eventName`
* parameter then make new array and return it
* @private
*/
CustomEvents.prototype._safeEvent = function(eventName) {
var events = this.events;
var byName;
if (!events) {
events = this.events = {};
}
if (eventName) {
byName = events[eventName];
if (!byName) {
byName = [];
events[eventName] = byName;
}
events = byName;
}
return events;
};
/**
* Get context array safely
* @returns {array} context array
* @private
*/
CustomEvents.prototype._safeContext = function() {
var context = this.contexts;
if (!context) {
context = this.contexts = [];
}
return context;
};
/**
* Get index of context
* @param {object} ctx - context that used for bind custom event
* @returns {number} index of context
* @private
*/
CustomEvents.prototype._indexOfContext = function(ctx) {
var context = this._safeContext();
var index = 0;
while (context[index]) {
if (ctx === context[index][0]) {
return index;
}
index += 1;
}
return -1;
};
/**
* Memorize supplied context for recognize supplied object is context or
* name: handler pair object when off()
* @param {object} ctx - context object to memorize
* @private
*/
CustomEvents.prototype._memorizeContext = function(ctx) {
var context, index;
if (!isExisty(ctx)) {
return;
}
context = this._safeContext();
index = this._indexOfContext(ctx);
if (index > -1) {
context[index][1] += 1;
} else {
context.push([ctx, 1]);
}
};
/**
* Forget supplied context object
* @param {object} ctx - context object to forget
* @private
*/
CustomEvents.prototype._forgetContext = function(ctx) {
var context, contextIndex;
if (!isExisty(ctx)) {
return;
}
context = this._safeContext();
contextIndex = this._indexOfContext(ctx);
if (contextIndex > -1) {
context[contextIndex][1] -= 1;
if (context[contextIndex][1] <= 0) {
context.splice(contextIndex, 1);
}
}
};
/**
* Bind event handler
* @param {(string|{name:string, handler:function})} eventName - custom
* event name or an object {eventName: handler}
* @param {(function|object)} [handler] - handler function or context
* @param {object} [context] - context for binding
* @private
*/
CustomEvents.prototype._bindEvent = function(eventName, handler, context) {
var events = this._safeEvent(eventName);
this._memorizeContext(context);
events.push(this._getHandlerItem(handler, context));
};
/**
* Bind event handlers
* @param {(string|{name:string, handler:function})} eventName - custom
* event name or an object {eventName: handler}
* @param {(function|object)} [handler] - handler function or context
* @param {object} [context] - context for binding
* //-- #1. Get Module --//
* var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); // node, commonjs
*
* //-- #2. Use method --//
* // # 2.1 Basic Usage
* CustomEvents.on('onload', handler);
*
* // # 2.2 With context
* CustomEvents.on('onload', handler, myObj);
*
* // # 2.3 Bind by object that name, handler pairs
* CustomEvents.on({
* 'play': handler,
* 'pause': handler2
* });
*
* // # 2.4 Bind by object that name, handler pairs with context object
* CustomEvents.on({
* 'play': handler
* }, myObj);
*/
CustomEvents.prototype.on = function(eventName, handler, context) {
var self = this;
if (isString(eventName)) {
// [syntax 1, 2]
eventName = eventName.split(R_EVENTNAME_SPLIT);
forEach(eventName, function(name) {
self._bindEvent(name, handler, context);
});
} else if (isObject(eventName)) {
// [syntax 3, 4]
context = handler;
forEach(eventName, function(func, name) {
self.on(name, func, context);
});
}
};
/**
* Bind one-shot event handlers
* @param {(string|{name:string,handler:function})} eventName - custom
* event name or an object {eventName: handler}
* @param {function|object} [handler] - handler function or context
* @param {object} [context] - context for binding
*/
CustomEvents.prototype.once = function(eventName, handler, context) {
var self = this;
if (isObject(eventName)) {
context = handler;
forEach(eventName, function(func, name) {
self.once(name, func, context);
});
return;
}
function onceHandler() { // eslint-disable-line require-jsdoc
handler.apply(context, arguments);
self.off(eventName, onceHandler, context);
}
this.on(eventName, onceHandler, context);
};
/**
* Splice supplied array by callback result
* @param {array} arr - array to splice
* @param {function} predicate - function return boolean
* @private
*/
CustomEvents.prototype._spliceMatches = function(arr, predicate) {
var i = 0;
var len;
if (!isArray(arr)) {
return;
}
for (len = arr.length; i < len; i += 1) {
if (predicate(arr[i]) === true) {
arr.splice(i, 1);
len -= 1;
i -= 1;
}
}
};
/**
* Get matcher for unbind specific handler events
* @param {function} handler - handler function
* @returns {function} handler matcher
* @private
*/
CustomEvents.prototype._matchHandler = function(handler) {
var self = this;
return function(item) {
var needRemove = handler === item.handler;
if (needRemove) {
self._forgetContext(item.context);
}
return needRemove;
};
};
/**
* Get matcher for unbind specific context events
* @param {object} context - context
* @returns {function} object matcher
* @private
*/
CustomEvents.prototype._matchContext = function(context) {
var self = this;
return function(item) {
var needRemove = context === item.context;
if (needRemove) {
self._forgetContext(item.context);
}
return needRemove;
};
};
/**
* Get matcher for unbind specific hander, context pair events
* @param {function} handler - handler function
* @param {object} context - context
* @returns {function} handler, context matcher
* @private
*/
CustomEvents.prototype._matchHandlerAndContext = function(handler, context) {
var self = this;
return function(item) {
var matchHandler = (handler === item.handler);
var matchContext = (context === item.context);
var needRemove = (matchHandler && matchContext);
if (needRemove) {
self._forgetContext(item.context);
}
return needRemove;
};
};
/**
* Unbind event by event name
* @param {string} eventName - custom event name to unbind
* @param {function} [handler] - handler function
* @private
*/
CustomEvents.prototype._offByEventName = function(eventName, handler) {
var self = this;
var andByHandler = isFunction(handler);
var matchHandler = self._matchHandler(handler);
eventName = eventName.split(R_EVENTNAME_SPLIT);
forEach(eventName, function(name) {
var handlerItems = self._safeEvent(name);
if (andByHandler) {
self._spliceMatches(handlerItems, matchHandler);
} else {
forEach(handlerItems, function(item) {
self._forgetContext(item.context);
});
self.events[name] = [];
}
});
};
/**
* Unbind event by handler function
* @param {function} handler - handler function
* @private
*/
CustomEvents.prototype._offByHandler = function(handler) {
var self = this;
var matchHandler = this._matchHandler(handler);
forEach(this._safeEvent(), function(handlerItems) {
self._spliceMatches(handlerItems, matchHandler);
});
};
/**
* Unbind event by object(name: handler pair object or context object)
* @param {object} obj - context or {name: handler} pair object
* @param {function} handler - handler function
* @private
*/
CustomEvents.prototype._offByObject = function(obj, handler) {
var self = this;
var matchFunc;
if (this._indexOfContext(obj) < 0) {
forEach(obj, function(func, name) {
self.off(name, func);
});
} else if (isString(handler)) {
matchFunc = this._matchContext(obj);
self._spliceMatches(this._safeEvent(handler), matchFunc);
} else if (isFunction(handler)) {
matchFunc = this._matchHandlerAndContext(handler, obj);
forEach(this._safeEvent(), function(handlerItems) {
self._spliceMatches(handlerItems, matchFunc);
});
} else {
matchFunc = this._matchContext(obj);
forEach(this._safeEvent(), function(handlerItems) {
self._spliceMatches(handlerItems, matchFunc);
});
}
};
/**
* Unbind custom events
* @param {(string|object|function)} eventName - event name or context or
* {name: handler} pair object or handler function
* @param {(function)} handler - handler function
* @example
* //-- #1. Get Module --//
* var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); // node, commonjs
*
* //-- #2. Use method --//
* // # 2.1 off by event name
* CustomEvents.off('onload');
*
* // # 2.2 off by event name and handler
* CustomEvents.off('play', handler);
*
* // # 2.3 off by handler
* CustomEvents.off(handler);
*
* // # 2.4 off by context
* CustomEvents.off(myObj);
*
* // # 2.5 off by context and handler
* CustomEvents.off(myObj, handler);
*
* // # 2.6 off by context and event name
* CustomEvents.off(myObj, 'onload');
*
* // # 2.7 off by an Object.<string, function> that is {eventName: handler}
* CustomEvents.off({
* 'play': handler,
* 'pause': handler2
* });
*
* // # 2.8 off the all events
* CustomEvents.off();
*/
CustomEvents.prototype.off = function(eventName, handler) {
if (isString(eventName)) {
// [syntax 1, 2]
this._offByEventName(eventName, handler);
} else if (!arguments.length) {
// [syntax 8]
this.events = {};
this.contexts = [];
} else if (isFunction(eventName)) {
// [syntax 3]
this._offByHandler(eventName);
} else if (isObject(eventName)) {
// [syntax 4, 5, 6]
this._offByObject(eventName, handler);
}
};
/**
* Fire custom event
* @param {string} eventName - name of custom event
*/
CustomEvents.prototype.fire = function(eventName) { // eslint-disable-line
this.invoke.apply(this, arguments);
};
/**
* Fire a event and returns the result of operation 'boolean AND' with all
* listener's results.
*
* So, It is different from {@link CustomEvents#fire}.
*
* In service code, use this as a before event in component level usually
* for notifying that the event is cancelable.
* @param {string} eventName - Custom event name
* @param {...*} data - Data for event
* @returns {boolean} The result of operation 'boolean AND'
* @example
* var map = new Map();
* map.on({
* 'beforeZoom': function() {
* // It should cancel the 'zoom' event by some conditions.
* if (that.disabled && this.getState()) {
* return false;
* }
* return true;
* }
* });
*
* if (this.invoke('beforeZoom')) { // check the result of 'beforeZoom'
* // if true,
* // doSomething
* }
*/
CustomEvents.prototype.invoke = function(eventName) {
var events, args, index, item;
if (!this.hasListener(eventName)) {
return true;
}
events = this._safeEvent(eventName);
args = Array.prototype.slice.call(arguments, 1);
index = 0;
while (events[index]) {
item = events[index];
if (item.handler.apply(item.context, args) === false) {
return false;
}
index += 1;
}
return true;
};
/**
* Return whether at least one of the handlers is registered in the given
* event name.
* @param {string} eventName - Custom event name
* @returns {boolean} Is there at least one handler in event name?
*/
CustomEvents.prototype.hasListener = function(eventName) {
return this.getListenerLength(eventName) > 0;
};
/**
* Return a count of events registered.
* @param {string} eventName - Custom event name
* @returns {number} number of event
*/
CustomEvents.prototype.getListenerLength = function(eventName) {
var events = this._safeEvent(eventName);
return events.length;
};
module.exports = CustomEvents;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Check whether the given variable is a string or not.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Check whether the given variable is a string or not.
* If the given variable is a string, return true.
* @param {*} obj - Target for checking
* @returns {boolean} Is string?
* @memberof module:type
*/
function isString(obj) {
return typeof obj === 'string' || obj instanceof String;
}
module.exports = isString;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Utility methods to manipulate colors
* @author NHN. FE Development Team <dl_javascript@nhn.com>
*/
var hexRX = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i;
var colorUtil = {
/**
* pad left zero characters.
* @param {number} number number value to pad zero.
* @param {number} length pad length to want.
* @returns {string} padded string.
*/
leadingZero: function (number, length) {
var zero = '';
var i = 0;
if ((number + '').length > length) {
return number + '';
}
for (; i < length - 1; i += 1) {
zero += '0';
}
return (zero + number).slice(length * -1);
},
/**
* Check validate of hex string value is RGB
* @param {string} str - rgb hex string
* @returns {boolean} return true when supplied str is valid RGB hex string
*/
isValidRGB: function (str) {
return hexRX.test(str);
},
// @license RGB <-> HSV conversion utilities based off of http://www.cs.rit.edu/~ncs/color/t_convert.html
/**
* Convert color hex string to rgb number array
* @param {string} hexStr - hex string
* @returns {number[]} rgb numbers
*/
hexToRGB: function (hexStr) {
var r, g, b;
if (!colorUtil.isValidRGB(hexStr)) {
return false;
}
hexStr = hexStr.substring(1);
r = parseInt(hexStr.substr(0, 2), 16);
g = parseInt(hexStr.substr(2, 2), 16);
b = parseInt(hexStr.substr(4, 2), 16);
return [r, g, b];
},
/**
* Convert rgb number to hex string
* @param {number} r - red
* @param {number} g - green
* @param {number} b - blue
* @returns {string|boolean} return false when supplied rgb number is not valid. otherwise, converted hex string
*/
rgbToHEX: function (r, g, b) {
var hexStr = '#' + colorUtil.leadingZero(r.toString(16), 2) + colorUtil.leadingZero(g.toString(16), 2) + colorUtil.leadingZero(b.toString(16), 2);
if (colorUtil.isValidRGB(hexStr)) {
return hexStr;
}
return false;
},
/**
* Convert rgb number to HSV value
* @param {number} r - red
* @param {number} g - green
* @param {number} b - blue
* @returns {number[]} hsv value
*/
rgbToHSV: function (r, g, b) {
var max, min, h, s, v, d;
r /= 255;
g /= 255;
b /= 255;
max = Math.max(r, g, b);
min = Math.min(r, g, b);
v = max;
d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0;
} else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
// no default
}
h /= 6;
}
return [Math.round(h * 360), Math.round(s * 100), Math.round(v * 100)];
},
/**
* Convert HSV number to RGB
* @param {number} h - hue
* @param {number} s - saturation
* @param {number} v - value
* @returns {number[]} rgb value
*/
hsvToRGB: function (h, s, v) {
var r, g, b;
var i;
var f, p, q, t;
h = Math.max(0, Math.min(360, h));
s = Math.max(0, Math.min(100, s));
v = Math.max(0, Math.min(100, v));
s /= 100;
v /= 100;
if (s === 0) {
// Achromatic (grey)
r = g = b = v;
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
h /= 60; // sector 0 to 5
i = Math.floor(h);
f = h - i; // factorial part of h
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch (i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
};
module.exports = colorUtil;
/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Check whether the given variable is a function or not.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Check whether the given variable is a function or not.
* If the given variable is a function, return true.
* @param {*} obj - Target for checking
* @returns {boolean} Is function?
* @memberof module:type
*/
function isFunction(obj) {
return obj instanceof Function;
}
module.exports = isFunction;
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Bind DOM events
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
var isString = __webpack_require__(11);
var forEach = __webpack_require__(2);
var safeEvent = __webpack_require__(26);
/**
* Bind DOM events.
* @param {HTMLElement} element - element to bind events
* @param {(string|object)} types - Space splitted events names or eventName:handler object
* @param {(function|object)} handler - handler function or context for handler method
* @param {object} [context] context - context for handler method.
* @memberof module:domEvent
* @example
* var div = document.querySelector('div');
*
* // Bind one event to an element.
* on(div, 'click', toggle);
*
* // Bind multiple events with a same handler to multiple elements at once.
* // Use event names splitted by a space.
* on(div, 'mouseenter mouseleave', changeColor);
*
* // Bind multiple events with different handlers to an element at once.
* // Use an object which of key is an event name and value is a handler function.
* on(div, {
* keydown: highlight,
* keyup: dehighlight
* });
*
* // Set a context for handler method.
* var name = 'global';
* var repository = {name: 'CodeSnippet'};
* on(div, 'drag', function() {
* console.log(this.name);
* }, repository);
* // Result when you drag a div: "CodeSnippet"
*/
function on(element, types, handler, context) {
if (isString(types)) {
forEach(types.split(/\s+/g), function(type) {
bindEvent(element, type, handler, context);
});
return;
}
forEach(types, function(func, type) {
bindEvent(element, type, func, handler);
});
}
/**
* Bind DOM events
* @param {HTMLElement} element - element to bind events
* @param {string} type - events name
* @param {function} handler - handler function or context for handler method
* @param {object} [context] context - context for handler method.
* @private
*/
function bindEvent(element, type, handler, context) {
/**
* Event handler
* @param {Event} e - event object
*/
function eventHandler(e) {
handler.call(context || element, e || window.event);
}
if ('addEventListener' in element) {
element.addEventListener(type, eventHandler);
} else if ('attachEvent' in element) {
element.attachEvent('on' + type, eventHandler);
}
memorizeHandler(element, type, handler, eventHandler);
}
/**
* Memorize DOM event handler for unbinding.
* @param {HTMLElement} element - element to bind events
* @param {string} type - events name
* @param {function} handler - handler function that user passed at on() use
* @param {function} wrappedHandler - handler function that wrapped by domevent for implementing some features
* @private
*/
function memorizeHandler(element, type, handler, wrappedHandler) {
var events = safeEvent(element, type);
var existInEvents = false;
forEach(events, function(obj) {
if (obj.handler === handler) {
existInEvents = true;
return false;
}
return true;
});
if (!existInEvents) {
events.push({
handler: handler,
wrappedHandler: wrappedHandler
});
}
}
module.exports = on;
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Prevent default action
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Prevent default action
* @param {Event} e - event object
* @memberof module:domEvent
*/
function preventDefault(e) {
if (e.preventDefault) {
e.preventDefault();
return;
}
e.returnValue = false;
}
module.exports = preventDefault;
/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Convert kebab-case
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
/**
* Convert kebab-case
* @param {string} key - string to be converted to Kebab-case
* @private
*/
function convertToKebabCase(key) {
return key.replace(/([A-Z])/g, function(match) {
return '-' + match.toLowerCase();
});
}
module.exports = convertToKebabCase;
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Unbind DOM events
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
var isString = __webpack_require__(11);
var forEach = __webpack_require__(2);
var safeEvent = __webpack_require__(26);
/**
* Unbind DOM events
* If a handler function is not passed, remove all events of that type.
* @param {HTMLElement} element - element to unbind events
* @param {(string|object)} types - Space splitted events names or eventName:handler object
* @param {function} [handler] - handler function
* @memberof module:domEvent
* @example
* // Following the example of domEvent#on
*
* // Unbind one event from an element.
* off(div, 'click', toggle);
*
* // Unbind multiple events with a same handler from multiple elements at once.
* // Use event names splitted by a space.
* off(element, 'mouseenter mouseleave', changeColor);
*
* // Unbind multiple events with different handlers from an element at once.
* // Use an object which of key is an event name and value is a handler function.
* off(div, {
* keydown: highlight,
* keyup: dehighlight
* });
*
* // Unbind events without handlers.
* off(div, 'drag');
*/
function off(element, types, handler) {
if (isString(types)) {
forEach(types.split(/\s+/g), function(type) {
unbindEvent(element, type, handler);
});
return;
}
forEach(types, function(func, type) {
unbindEvent(element, type, func);
});
}
/**
* Unbind DOM events
* If a handler function is not passed, remove all events of that type.
* @param {HTMLElement} element - element to unbind events
* @param {string} type - events name
* @param {function} [handler] - handler function
* @private
*/
function unbindEvent(element, type, handler) {
var events = safeEvent(element, type);
var index;
if (!handler) {
forEach(events, function(item) {
removeHandler(element, type, item.wrappedHandler);
});
events.splice(0, events.length);
} else {
forEach(events, function(item, idx) {
if (handler === item.handler) {
removeHandler(element, type, item.wrappedHandler);
index = idx;
return false;
}
return true;
});
events.splice(index, 1);
}
}
/**
* Remove an event handler
* @param {HTMLElement} element - An element to remove an event
* @param {string} type - event type
* @param {function} handler - event handler
* @private
*/
function removeHandler(element, type, handler) {
if ('removeEventListener' in element) {
element.removeEventListener(type, handler);
} else if ('detachEvent' in element) {
element.detachEvent('on' + type, handler);
}
}
module.exports = off;
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Provide a simple inheritance in prototype-oriented.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
var createObject = __webpack_require__(50);
/**
* Provide a simple inheritance in prototype-oriented.
* Caution :
* Don't overwrite the prototype of child constructor.
*
* @param {function} subType Child constructor
* @param {function} superType Parent constructor
* @memberof module:inheritance
* @example
* var inherit = require('tui-code-snippet/inheritance/inherit'); // node, commonjs
*
* // Parent constructor
* function Animal(leg) {
* this.leg = leg;
* }
* Animal.prototype.growl = function() {
* // ...
* };
*
* // Child constructor
* function Person(name) {
* this.name = name;
* }
*
* // Inheritance
* inherit(Person, Animal);
*
* // After this inheritance, please use only the extending of property.
* // Do not overwrite prototype.
* Person.prototype.walk = function(direction) {
* // ...
* };
*/
function inherit(subType, superType) {
var prototype = createObject(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
module.exports = inherit;
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* @fileoverview Common collections.
* @author NHN. FE Development Team <dl_javascript@nhn.com>
*/
var forEachArray = __webpack_require__(6);
var forEachOwnProperties = __webpack_require__(7);
var extend = __webpack_require__(0);
var isArray = __webpack_require__(1);
var isExisty = __webpack_require__(20);
var isFunction = __webpack_require__(13);
var isObject = __webpack_require__(21);
var util = __webpack_require__(4);
var slice = Array.prototype.slice;
/**
* Common collection.
*
* It need function for get model's unique id.
*
* if the function is not supplied then it use default function {@link Collection#getItemID}
* @constructor
* @param {function} [getItemIDFn] function for get model's id.
* @ignore
*/
function Collection(getItemIDFn) {
/**
* @type {object.<string, *>}
*/
this.items = {};
/**
* @type {number}
*/
this.length = 0;
if (isFunction(getItemIDFn)) {
/**
* @type {function}
*/
this.getItemID = getItemIDFn;
}
}
/**********
* static props
**********/
/**
* Combind supplied function filters and condition.
* @param {...function} filters - function filters
* @returns {function} combined filter
*/
Collection.and = function (filters) {
var cnt;
filters = slice.call(arguments);
cnt = filters.length;
return function (item) {
var i = 0;
for (; i < cnt; i += 1) {
if (!filters[i].call(null, item)) {
return false;
}
}
return true;
};
};
/**
* Combine multiple function filters with OR clause.
* @param {...function} filters - function filters
* @returns {function} combined filter
*/
Collection.or = function (filters) {
var cnt;
filters = slice.call(arguments);
cnt = filters.length;
return function (item) {
var i = 1;
var result = filters[0].call(null, item);
for (; i < cnt; i += 1) {
result = result || filters[i].call(null, item);
}
return result;
};
};
/**
* Merge several collections.
*
* You can\'t merge collections different _getEventID functions. Take case of use.
* @param {...Collection} collections collection arguments to merge
* @returns {Collection} merged collection.
*/
Collection.merge = function (firstCollection) {
var newItems = {};
var merged = new Collection(firstCollection.getItemID);
forEachArray(arguments, function (col) {
extend(newItems, col.items);
});
merged.items = newItems;
merged.length = util.getLength(merged.items);
return merged;
};
/**********
* prototype props
**********/
/**
* get model's unique id.
* @param {object} item model instance.
* @returns {number} model unique id.
*/
Collection.prototype.getItemID = function (item) {
return item._id + '';
};
/**
* add models.
* @param {...*} item models to add this collection.
*/
Collection.prototype.add = function (item) {
var id, ownItems;
if (arguments.length > 1) {
forEachArray(slice.call(arguments), function