Socket
Socket
Sign inDemoInstall

tui-code-snippet

Package Overview
Dependencies
0
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.6 to 1.2.2

6

bower.json
{
"name": "tui-code-snippet",
"version": "1.0.6",
"authors": [

@@ -24,3 +23,6 @@ "NHN Ent. FE dev team(dl_javascript@nhnent.com)"

"tutorial"
]
],
"devDependencies": {
"jquery": "~1.8.3"
}
}

@@ -1,2 +0,2 @@

/*!code-snippet v1.0.6 | NHN Entertainment*/
!function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var b=Array.prototype.slice,c=function(b,c,d){var e,f=[];for(a.util.isUndefined(c)&&(c=b||0,b=0),d=d||1,e=0>d?-1:1,c*=e;c>b*e;b+=d)f.push(b);return f},d=function(){var c=b.call(arguments),d=[];return a.util.forEach(c,function(b){a.util.forEach(b,function(a,b){d[b]||(d[b]=[]),d[b].push(a)})}),d};a.util.range=c,a.util.zip=d}(window.tui),function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var b,c,d={chrome:!1,firefox:!1,safari:!1,msie:!1,others:!1,version:0},e=window.navigator,f=e.appName.replace(/\s/g,"_"),g=e.userAgent,h=/MSIE\s([0-9]+[.0-9]*)/,i=/Trident.*rv:11\./,j={firefox:/Firefox\/(\d+)\./,chrome:/Chrome\/(\d+)\./,safari:/Version\/([\d\.]+)\sSafari\/(\d+)/},k={Microsoft_Internet_Explorer:function(){d.msie=!0,d.version=parseFloat(g.match(h)[1])},Netscape:function(){var a=!1;if(i.exec(g))d.msie=!0,d.version=11;else for(b in j)if(j.hasOwnProperty(b)&&(c=g.match(j[b]),c&&c.length>1)){d[b]=a=!0,d.version=parseFloat(c[1]||0);break}a||(d.others=!0)}};k[f](),a.util.browser=d}(window.tui),function(a){"use strict";function b(a,b,c){var d=0,e=a.length;for(c=c||null;e>d&&b.call(c,a[d],d,a)!==!1;d++);}function c(a,b,c){var d;c=c||null;for(d in a)if(a.hasOwnProperty(d)&&b.call(c,a[d],d,a)===!1)break}function d(b,c,d){a.util.isArray(b)?a.util.forEachArray(b,c,d):a.util.forEachOwnProperties(b,c,d)}function e(b,c,d){var e=[];return d=d||null,a.util.forEach(b,function(){e.push(c.apply(d,arguments))}),e}function f(b,c,d){var e,f,g,h=0;for(d=d||null,a.util.isArray(b)||(e=a.util.keys(b)),f=e?e.length:b.length,g=b[e?e[h++]:h++];f>h;h++)g=c.call(d,g,b[e?e[h]:h]);return g}function g(a){var c;try{c=Array.prototype.slice.call(a)}catch(d){c=[],b(a,function(a){c.push(a)})}return c}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var h=!!Array.prototype.indexOf,i=function(b,c,d){var e,f;if(d=d||null,!a.util.isObject(b)||!a.util.isFunction(c))throw new Error("wrong parameter");return a.util.isArray(b)?(e=[],f=function(a,b){a.push(b[0])}):(e={},f=function(a,b){a[b[1]]=b[0]}),a.util.forEach(b,function(){c.apply(d,arguments)&&f(e,arguments)},d),e},j=function(b,c,d){if(!a.util.isArray(c))return-1;if(h)return Array.prototype.indexOf.call(c,b,d);var e,f=c.length;if(a.util.isUndefined(d))d=0;else if(d>=f||0>d)return-1;for(e=d;f>e;e++)if(c[e]===b)return e;return-1},k=function(b,c){var d=a.util.map(b,function(a){return a[c]});return d};a.util.forEachOwnProperties=c,a.util.forEachArray=b,a.util.forEach=d,a.util.toArray=g,a.util.map=e,a.util.reduce=f,a.util.filter=i,a.util.inArray=j,a.util.pluck=k}(window.tui),function(a){"use strict";function b(){this._events=null,this._ctxEvents=null}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),b.mixin=function(c){a.util.extend(c.prototype,b.prototype)},b.prototype._forEachArraySplice=function(b,c){var d,e,f,g=function(){b.splice(d,1),e-=1,d-=1};if(a.util.isExisty(b)&&a.util.isArray(b))for(d=0,e=b.length;e>d;d++)if(f=b[d],c(f,d,b,g)===!1)return},b.prototype._eachCtxEvents=function(b){var c=this._ctxEvents;a.util.forEachOwnProperties(c,b)},b.prototype._eachCtxHandlerItemByContainId=function(b,c,d){a.util.forEachOwnProperties(b,function(a,b){b.indexOf(c)>-1&&d(a,b)})},b.prototype._eachCtxEventByHandler=function(b,c){var d=a.util.stamp(b),e=this._eachCtxHandlerItemByContainId;this._eachCtxEvents(function(a,b){e(a,d,function(d,e){c(d,e,a,b)})})},b.prototype._eachCtxEventByContext=function(b,c){var d=a.util.stamp(b),e=this._eachCtxHandlerItemByContainId;this._eachCtxEvents(function(a,b){e(a,d,function(d,e){c(d,e,a,b)})})},b.prototype._eachCtxEventByEventName=function(b,c){if(this._ctxEvents){var d,e=this._getCtxKey(b),f=this._ctxEvents[e];a.util.forEachOwnProperties(f,function(){d=Array.prototype.slice.call(arguments),d.push(e),c.apply(null,d)})}},b.prototype._eachEventByHandler=function(b,c){var d=this._events,e=this._forEachArraySplice,f=0;a.util.forEachOwnProperties(d,function(a,d){e(a,function(a,e,g,h){a.fn===b&&(c(a,f,g,d,h),f+=1)})})},b.prototype._eachEventByEventName=function(b,c){var d;this._events&&(d=this._events[b],a.util.isExisty(d)&&this._forEachArraySplice(d,c))},b.prototype._getCtxKey=function(a){return a+"_idx"},b.prototype._getCtxLenKey=function(a){return a+"_len"},b.prototype._getHandlerKey=function(b,c){return a.util.stamp(b)+"_"+a.util.stamp(c)},b.prototype._setCtxLen=function(b,c){var d=this._ctxEvents;a.util.isExisty(d[b])||(d[b]=0),d[b]+=c},b.prototype._addCtxEvent=function(b,c,d){var e,f=this._ctxEvents,g=this._getCtxKey(b);a.util.isExisty(f)||(f=this._ctxEvents={}),e=f[g],a.util.isExisty(e)||(e=f[g]={});var h=this._getCtxLenKey(b),i=this._getHandlerKey(d,c);e[i]={fn:d,ctx:c},this._setCtxLen(h,1)},b.prototype._addNormalEvent=function(b,c){var d,e=this._events;a.util.isExisty(e)||(e=this._events={}),d=e[b],a.util.isExisty(d)||(d=e[b]=[]),d.push({fn:c})},b.prototype._offByHandler=function(a){var b,c=this._ctxEvents;this._eachCtxEventByHandler(a,function(a,d,e,f){b=f.replace("_idx","_len"),delete e[d],c[b]-=1}),this._eachEventByHandler(a,function(a,b,c,d,e){c.splice(b,1),e()})},b.prototype._offByContext=function(b,c){var d,e,f,g=this._ctxEvents,h=a.util.isExisty(c);this._eachCtxEventByContext(b,function(b,i,j,k){f=k.replace("_idx","_len"),d=h&&a.util.isString(c)&&k.indexOf(c)>-1,e=h&&a.util.isFunction(c)&&b.fn===c,(!h||d||e)&&(delete j[i],g[f]-=1)})},b.prototype._offByEventName=function(b,c){var d,e=this._ctxEvents,f=a.util.isExisty(c);this._eachCtxEventByEventName(b,function(a,b,g,h){d=h.replace("_idx","_len"),(!f||f&&a.fn===c)&&(delete g[b],e[d]-=1)}),this._eachEventByEventName(b,function(a,b,d,e){(!f||f&&a.fn===c)&&(d.splice(b,1),e())})},b.prototype.on=function(b,c,d){var e;if(a.util.isObject(b))return d=c,void a.util.forEachOwnProperties(b,function(a,b){this.on(b,a,d)},this);if(a.util.isString(b)&&b.indexOf(" ")>-1)return e=b.split(" "),void a.util.forEachArray(e,function(a){this.on(a,c,d)},this);var f;a.util.isExisty(d)&&(f=a.util.stamp(d)),a.util.isExisty(f)?this._addCtxEvent(b,d,c):this._addNormalEvent(b,c)},b.prototype.off=function(b,c){return arguments.length?void(a.util.isFunction(b)?this._offByHandler(b):a.util.isObject(b)?a.util.hasStamp(b)?this._offByContext(b,c):a.util.forEachOwnProperties(b,function(a,b){this.off(b,a)},this):this._offByEventName(b,c)):(this._events=null,void(this._ctxEvents=null))},b.prototype.getListenerLength=function(b){var c=this._ctxEvents,d=this._events,e=a.util.isExisty,f=this._getCtxLenKey(b),g=e(d)&&a.util.isArray(d[b])?d[b].length:0,h=e(c)&&e(c[f])?c[f]:0;return g+h},b.prototype.hasListener=function(a){return this.getListenerLength(a)>0},b.prototype.invoke=function(b,c){if(!this.hasListener(b))return!0;var d=Array.prototype.slice.call(arguments,1),e=this,f=!0,g=a.util.isExisty;return this._eachEventByEventName(b,function(a){g(a)&&a.fn.apply(e,d)===!1&&(f=!1)}),this._eachCtxEventByEventName(b,function(a){g(a)&&a.fn.apply(a.ctx,d)===!1&&(f=!1)}),f},b.prototype.fire=function(a,b){return this.invoke.apply(this,arguments),this},b.prototype.once=function(b,c,d){function e(){c.apply(d,arguments),f.off(b,e,d)}var f=this;return a.util.isObject(b)?void a.util.forEachOwnProperties(b,function(a,b){this.once(b,a,c)},this):void this.on(b,e,d)},a.util.CustomEvents=b}(window.tui),function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.defineClass=function(b,c){var d;return c||(c=b,b=null),d=c.init||function(){},b&&a.util.inherit(d,b),c.hasOwnProperty("static")&&(a.util.extend(d,c["static"]),delete c["static"]),a.util.extend(d.prototype,c),d}}(window.tui),function(a){"use strict";function b(a,b){var e=b||{};return c.isFunction(e[d])&&(e[d](),delete e[d]),c.defineNamespace(a,e,!0)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=a.util,d="initialize";a.util.defineModule=b}(window.tui),function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var b=function(b,e,f){var g,h,i,j=c(b);return!f&&d(j)?j:(g=b.split("."),h=g.pop(),g.unshift(window),i=a.util.reduce(g,function(a,b){return a[b]=a[b]||{},a[b]}),i[h]=d(e)?e:{},i[h])},c=function(b){var c,d;return c=b.split("."),c.unshift(window),d=a.util.reduce(c,function(a,b){return a&&a[b]})},d=function(b){return a.util.isObject(b)||a.util.isFunction(b)};a.util.defineNamespace=b}(window.tui),function(a){"use strict";function b(a){a&&this.set.apply(this,arguments)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=function(){try{return Object.defineProperty({},"x",{}),!0}catch(a){return!1}}(),d=0;b.prototype.set=function(b){var c=this;a.util.isArray(b)||(b=a.util.toArray(arguments)),a.util.forEach(b,function(a){c._addItem(a)})},b.prototype.getName=function(b){var c,d=this;return a.util.forEach(this,function(a,e){return d._isEnumItem(e)&&b===a?(c=e,!1):void 0}),c},b.prototype._addItem=function(a){var b;this.hasOwnProperty(a)||(b=this._makeEnumValue(),c?Object.defineProperty(this,a,{enumerable:!0,configurable:!1,writable:!1,value:b}):this[a]=b)},b.prototype._makeEnumValue=function(){var a;return a=d,d+=1,a},b.prototype._isEnumItem=function(b){return a.util.isNumber(this[b])},a.util.Enum=b}(window.tui),function(a){"use strict";function b(a){this._map=new c.Map(a),this.size=this._map.size}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=a.util,d=["get","has","forEach","keys","values","entries"],e=["delete","clear"];c.forEachArray(d,function(a){b.prototype[a]=function(){return this._map[a].apply(this._map,arguments)}}),c.forEachArray(e,function(a){b.prototype[a]=function(){var b=this._map[a].apply(this._map,arguments);return this.size=this._map.size,b}}),b.prototype.set=function(){return this._map.set.apply(this._map,arguments),this.size=this._map.size,this},b.prototype.setObject=function(a){c.forEachOwnProperties(a,function(a,b){this.set(b,a)},this)},b.prototype.deleteByKeys=function(a){c.forEachArray(a,function(a){this["delete"](a)},this)},b.prototype.merge=function(a){a.forEach(function(a,b){this.set(b,a)},this)},b.prototype.filter=function(a){var c=new b;return this.forEach(function(b,d){a(b,d)&&c.set(d,b)}),c},c.ExMap=b}(window.tui),function(a){"use strict";function b(a,b,c){var d,e,g,h;return a=Number(a),b=Number(b),c=Number(c),d=a>-1&&100>a||a>1969&&2070>a,e=b>0&&13>b,d&&e?(h=f[b],2===b&&a%4===0&&(a%100!==0||a%400===0)&&(h=29),g=c>0&&h>=c):!1}function c(c,e){var f,h,i;return h=a.util.isDate(e)?{year:e.getFullYear(),month:e.getMonth()+1,date:e.getDate(),hour:e.getHours(),minute:e.getMinutes()}:{year:e.year,month:e.month,date:e.date,hour:e.hour,minute:e.minute},b(h.year,h.month,h.date)?(h.meridian="",/[^\\][aA]\b/g.test(c)&&(f=h.hour>12?"PM":"AM",h.hour%=12,h.meridian=f),i=c.replace(d,function(a){return a.indexOf("\\")>-1?a.replace(/\\/g,""):g[a](h)||""})):!1}var d=/[\\]*YYYY|[\\]*YY|[\\]*MMMM|[\\]*MMM|[\\]*MM|[\\]*M|[\\]*DD|[\\]*D|[\\]*HH|[\\]*H|[\\]*A/gi,e=["Invalid month","January","February","March","April","May","June","July","August","September","October","November","December"],f=[0,31,28,31,30,31,30,31,31,30,31,30,31],g={M:function(a){return Number(a.month)},MM:function(a){var b=a.month;return Number(b)<10?"0"+b:b},MMM:function(a){return e[Number(a.month)].substr(0,3)},MMMM:function(a){return e[Number(a.month)]},D:function(a){return Number(a.date)},d:function(a){return g.D(a)},DD:function(a){var b=a.date;return Number(b)<10?"0"+b:b},dd:function(a){return g.DD(a)},YY:function(a){return Number(a.year)%100},yy:function(a){return g.YY(a)},YYYY:function(a){var b="20",c=a.year;return c>69&&100>c&&(b="19"),Number(c)<100?b+String(c):c},yyyy:function(a){return g.YYYY(a)},A:function(a){return a.meridian},a:function(a){return a.meridian.toLowerCase()},hh:function(a){var b=a.hour;return Number(b)<10?"0"+b:b},HH:function(a){return g.hh(a)},h:function(a){return String(Number(a.hour))},H:function(a){return g.h(a)},m:function(a){return String(Number(a.minute))},mm:function(a){var b=a.minute;return Number(b)<10?"0"+b:b}};a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.formatDate=c}(window.tui),function(a){"use strict";function b(a,b){var c=Array.prototype.slice;if(a.bind)return a.bind.apply(a,c.call(arguments,1));var d=c.call(arguments,2);return function(){return a.apply(b,d.length?d.concat(c.call(arguments)):arguments)}}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.bind=b}(window.tui),function(a){"use strict";function b(a){this.length=0,a&&this.setObject(a)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c="å";b.prototype.set=function(a,b){2===arguments.length?this.setKeyValue(a,b):this.setObject(a)},b.prototype.setKeyValue=function(a,b){this.has(a)||(this.length+=1),this[this.encodeKey(a)]=b},b.prototype.setObject=function(b){var c=this;a.util.forEachOwnProperties(b,function(a,b){c.setKeyValue(b,a)})},b.prototype.merge=function(a){var b=this;a.each(function(a,c){b.setKeyValue(c,a)})},b.prototype.encodeKey=function(a){return c+a},b.prototype.decodeKey=function(a){var b=a.split(c);return b[b.length-1]},b.prototype.get=function(a){return this[this.encodeKey(a)]},b.prototype.has=function(a){return this.hasOwnProperty(this.encodeKey(a))},b.prototype.remove=function(b){return arguments.length>1&&(b=a.util.toArray(arguments)),a.util.isArray(b)?this.removeByKeyArray(b):this.removeByKey(b)},b.prototype.removeByKey=function(a){var b=this.has(a)?this.get(a):null;return null!==b&&(delete this[this.encodeKey(a)],this.length-=1),b},b.prototype.removeByKeyArray=function(b){var c=[],d=this;return a.util.forEach(b,function(a){c.push(d.removeByKey(a))}),c},b.prototype.removeAll=function(){var a=this;this.each(function(b,c){a.remove(c)})},b.prototype.each=function(b){var d,e=this;a.util.forEachOwnProperties(this,function(a,f){return f.charAt(0)===c&&(d=b(a,e.decodeKey(f))),d===!1?d:void 0})},b.prototype.keys=function(){var a=[],b=this;return this.each(function(c,d){a.push(b.decodeKey(d))}),a},b.prototype.find=function(a){var b=[];return this.each(function(c,d){a(c,d)&&b.push(c)}),b},b.prototype.toArray=function(){var a=[];return this.each(function(b){a.push(b)}),a},a.util.HashMap=b}(window.tui),function(a){"use strict";function b(){function a(){}return function(b){return a.prototype=b,new a}}function c(b,c){var d=a.util.createObject(c.prototype);d.constructor=b,b.prototype=d}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.createObject=b(),a.util.inherit=c}(window.tui),function(a){"use strict";function b(a,b){this._keys=a,this._valueGetter=b,this._length=this._keys.length,this._index=-1,this._done=!1}function c(a){this._valuesForString={},this._valuesForIndex={},this._keys=[],a&&this._setInitData(a),this.size=0}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var d=a.util,e={},f={};b.prototype.next=function(){var a={};do this._index+=1;while(d.isUndefined(this._keys[this._index])&&this._index<this._length);return this._index>=this._length?a.done=!0:(a.done=!1,a.value=this._valueGetter(this._keys[this._index],this._index)),a},c.prototype._setInitData=function(a){if(!d.isArray(a))throw new Error("Only Array is supported.");d.forEachArray(a,function(a){this.set(a[0],a[1])},this)},c.prototype._isNaN=function(a){return"number"==typeof a&&a!==a},c.prototype._getKeyIndex=function(a){var b,c=-1;return d.isString(a)?(b=this._valuesForString[a],b&&(c=b.keyIndex)):c=d.inArray(a,this._keys),c},c.prototype._getOriginKey=function(a){var b=a;return a===e?b=void 0:a===f&&(b=NaN),b},c.prototype._getUniqueKey=function(a){var b=a;return d.isUndefined(a)?b=e:this._isNaN(a)&&(b=f),b},c.prototype._getValueObject=function(a,b){return d.isString(a)?this._valuesForString[a]:(d.isUndefined(b)&&(b=this._getKeyIndex(a)),b>=0?this._valuesForIndex[b]:void 0)},c.prototype._getOriginValue=function(a,b){return this._getValueObject(a,b).origin},c.prototype._getKeyValuePair=function(a,b){return[this._getOriginKey(a),this._getOriginValue(a,b)]},c.prototype._createValueObject=function(a,b){return{keyIndex:b,origin:a}},c.prototype.set=function(a,b){var c,e=this._getUniqueKey(a),f=this._getKeyIndex(e);return 0>f&&(f=this._keys.push(e)-1,this.size+=1),c=this._createValueObject(b,f),d.isString(a)?this._valuesForString[a]=c:this._valuesForIndex[f]=c,this},c.prototype.get=function(a){var b=this._getUniqueKey(a),c=this._getValueObject(b);return c&&c.origin},c.prototype.keys=function(){return new b(this._keys,d.bind(this._getOriginKey,this))},c.prototype.values=function(){return new b(this._keys,d.bind(this._getOriginValue,this))},c.prototype.entries=function(){return new b(this._keys,d.bind(this._getKeyValuePair,this))},c.prototype.has=function(a){return!!this._getValueObject(a)},c.prototype["delete"]=function(a){var b;d.isString(a)?this._valuesForString[a]&&(b=this._valuesForString[a].keyIndex,delete this._valuesForString[a]):(b=this._getKeyIndex(a),b>=0&&delete this._valuesForIndex[b]),b>=0&&(delete this._keys[b],this.size-=1)},c.prototype.forEach=function(a,b){b=b||this,d.forEachArray(this._keys,function(c){d.isUndefined(c)||a.call(b,this._getValueObject(c).origin,c,this)},this)},c.prototype.clear=function(){c.call(this)},function(){var a=d.browser;window.Map&&(a.firefox&&a.version>=37||a.chrome&&a.version>=42)&&(c=window.Map)}(),d.Map=c}(window.tui),function(a){"use strict";function b(a,b){var c,d,e,f,g=Object.prototype.hasOwnProperty;for(e=1,f=arguments.length;f>e;e++){c=arguments[e];for(d in c)g.call(c,d)&&(a[d]=c[d])}return a}function c(a){return a.__fe_id=a.__fe_id||++i,a.__fe_id}function d(b){return a.util.isExisty(a.util.pick(b,"__fe_id"))}function e(){i=0}function f(a){var b,c=[];for(b in a)a.hasOwnProperty(b)&&c.push(b);return c}function g(b){function c(b,f){var g;if(isNaN(b)&&isNaN(f)&&a.util.isNumber(b)&&a.util.isNumber(f))return!0;if(b===f)return!0;if(a.util.isFunction(b)&&a.util.isFunction(f)||b instanceof Date&&f instanceof Date||b instanceof RegExp&&f instanceof RegExp||b instanceof String&&f instanceof String||b instanceof Number&&f instanceof Number)return b.toString()===f.toString();if(!(b instanceof Object&&f instanceof Object))return!1;if(b.isPrototypeOf(f)||f.isPrototypeOf(b)||b.constructor!==f.constructor||b.prototype!==f.prototype)return!1;if(a.util.inArray(b,d)>-1||a.util.inArray(f,e)>-1)return!1;for(g in f){if(f.hasOwnProperty(g)!==b.hasOwnProperty(g))return!1;if(typeof f[g]!=typeof b[g])return!1}for(g in b){if(f.hasOwnProperty(g)!==b.hasOwnProperty(g))return!1;if(typeof f[g]!=typeof b[g])return!1;if("object"==typeof b[g]||"function"==typeof b[g]){if(d.push(b),e.push(f),!c(b[g],f[g]))return!1;d.pop(),e.pop()}else if(b[g]!==f[g])return!1}return!0}var d,e,f,g=arguments.length;if(1>g)return!0;for(f=1;g>f;f++)if(d=[],e=[],!c(arguments[0],arguments[f]))return!1;return!0}function h(a,b){var c,d=arguments,e=d[0],f=d.length;try{for(c=1;f>c;c++)e=e[d[c]];return e}catch(g){return}}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var i=0;a.util.extend=b,a.util.stamp=c,a.util.hasStamp=d,a.util._resetLastId=e,a.util.keys=Object.keys||f,a.util.compareJSON=g,a.util.pick=h}(window.tui),function(a){"use strict";function b(a){var b={"&quot;":'"',"&amp;":"&","&lt;":"<","&gt;":">","&#39;":"'","&nbsp;":" "};return a.replace(/&amp;|&lt;|&gt;|&quot;|&#39;|&nbsp;/g,function(a){return b[a]?b[a]:a})}function c(a){var b={'"':"quot","&":"amp","<":"lt",">":"gt","'":"#39"};return a.replace(/[<>&"']/g,function(a){return b[a]?"&"+b[a]+";":a})}function d(a){return/[<>&"']/.test(a)}function e(b,c){for(var d,e,f=0,g=b.length,h={};g>f;f+=1)e=b.charAt(f),h[e]=1;for(f=0,g=c.length;g>f;f+=1)e=c.charAt(f),h[e]&&(h[e]+=1);return h=a.util.filter(h,function(a){return a>1}),h=a.util.keys(h).sort(),d=h.join("")}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.decodeHTMLEntity=b,a.util.encodeHTMLEntity=c,a.util.hasEncodableString=d,a.util.getDuplicatedChar=e}(window.tui),function(a){"use strict";function b(a,b){function c(){f=e.call(arguments),window.clearTimeout(d),d=window.setTimeout(function(){a.apply(null,f)},b)}var d,f;return b=b||0,c}function c(){return+new Date}function d(b,c){function d(){return j=e.call(arguments),l?(m(j),void(l=!1)):(i=k(),g=g||i,h(j),void(i-g>=c&&m(j)))}function f(){l=!0,g=null}var g,h,i,j,k=a.util.timestamp,l=!0,m=function(a){b.apply(null,a),g=null};return c=c||0,h=a.util.debounce(m,c),d.reset=f,d}var e=Array.prototype.slice;a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.timestamp=c,a.util.debounce=b,a.util.throttle=d}(window.tui),function(a){"use strict";function b(a){return null!=a}function c(a){return void 0===a}function d(a){return null===a}function e(a){return b(a)&&a!==!1}function f(a){return!e(a)}function g(a){var c=b(a)&&("[object Arguments]"===y.call(a)||!!a.callee);return c}function h(a){return a instanceof Array}function i(a){return a===Object(a)}function j(a){return a instanceof Function}function k(a){return"number"==typeof a||a instanceof Number}function l(a){return"string"==typeof a||a instanceof String}function m(a){return"boolean"==typeof a||a instanceof Boolean}function n(a){return"[object Array]"===y.call(a)}function o(a){return"[object Function]"===y.call(a)}function p(a){return"[object Number]"===y.call(a)}function q(a){return"[object String]"===y.call(a)}function r(a){return"[object Boolean]"===y.call(a)}function s(a){return"object"==typeof HTMLElement?a&&(a instanceof HTMLElement||!!a.nodeType):!(!a||!a.nodeType)}function t(a){return"object"==typeof HTMLElement?a&&a instanceof HTMLElement:!(!a||!a.nodeType||1!==a.nodeType)}function u(c){var d=!1;return b(c)?l(c)&&""===c?!0:h(c)||g(c)?0===c.length:i(c)&&!j(c)?(a.util.forEachOwnProperties(c,function(){return d=!0,!1}),!d):!0:!0}function v(a){return!u(a)}function w(a){return a instanceof Date}function x(a){return"[object Date]"===y.call(a)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var y=Object.prototype.toString;a.util.isExisty=b,a.util.isUndefined=c,a.util.isNull=d,a.util.isTruthy=e,a.util.isFalsy=f,a.util.isArguments=g,a.util.isArray=Array.isArray||h,a.util.isArraySafe=Array.isArray||n,a.util.isObject=i,a.util.isFunction=j,a.util.isFunctionSafe=o,a.util.isNumber=k,a.util.isNumberSafe=p,a.util.isDate=w,a.util.isDateSafe=x,a.util.isString=l,a.util.isStringSafe=q,a.util.isBoolean=m,a.util.isBooleanSafe=r,a.util.isHTMLNode=s,a.util.isHTMLTag=t,a.util.isEmpty=u,a.util.isNotEmpty=v}(window.tui),function(a){"use strict";function b(){this.openedPopup={},this.closeWithParentPopup={},this.postBridgeUrl=""}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=0;b.prototype.getPopupList=function(b){var c;return c=a.util.isExisty(b)?this.openedPopup[b]:this.openedPopup},b.prototype.openPopup=function(b,d){d=a.util.extend({popupName:"popup_"+c+"_"+ +new Date,popupOptionStr:"",useReload:!0,closeWithParent:!0,method:"get",param:{}},d||{}),d.method=d.method.toUpperCase(),this.postBridgeUrl=d.postBridgeUrl||this.postBridgeUrl;var e,f,g="POST"===d.method&&d.param&&a.util.browser.msie&&11===a.util.browser.version;if(!a.util.isExisty(b))throw new Error("Popup#open() need popup url.");c+=1,d.param&&("GET"===d.method?b=b+(/\?/.test(b)?"&":"?")+this._parameterize(d.param):"POST"===d.method&&(g||(f=this.createForm(b,d.param,d.method,d.popupName),b="about:blank"))),e=this.openedPopup[d.popupName],a.util.isExisty(e)?e.closed?this.openedPopup[d.popupName]=e=this._open(g,d.param,b,d.popupName,d.popupOptionStr):(d.useReload&&e.location.replace(b),e.focus()):this.openedPopup[d.popupName]=e=this._open(g,d.param,b,d.popupName,d.popupOptionStr),this.closeWithParentPopup[d.popupName]=d.closeWithParent,(!e||e.closed||a.util.isUndefined(e.closed))&&alert("please enable popup windows for this website"),d.param&&"POST"===d.method&&!g&&(e&&f.submit(),f.parentNode&&f.parentNode.removeChild(f)),window.onunload=a.util.bind(this.closeAllPopup,this)},b.prototype.close=function(b,c){b=a.util.isExisty(b)?b:!1;var d=c||window;b&&(window.onunload=null),d.closed||(d.opener=window.location.href,d.close())},b.prototype.closeAllPopup=function(b){var c=a.util.isExisty(b);a.util.forEachOwnProperties(this.openedPopup,function(a,b){(c&&this.closeWithParentPopup[b]||!c)&&this.close(!1,a)},this)},b.prototype.focus=function(a){this.getPopupList(a).focus()},b.prototype.parseQuery=function(){var b,c,d={};return b=window.location.search.substr(1),a.util.forEachArray(b.split("&"),function(a){c=a.split("="),d[decodeURIComponent(c[0])]=decodeURIComponent(c[1])}),d},b.prototype.createForm=function(b,c,d,e,f){var g,h=document.createElement("form");return f=f||document.body,h.method=d||"POST",h.action=b||"",h.target=e||"",h.style.display="none",a.util.forEachOwnProperties(c,function(a,b){g=document.createElement("input"),g.name=b,g.type="hidden",g.value=a,h.appendChild(g)}),f.appendChild(h),h},b.prototype._parameterize=function(b){var c=[];return a.util.forEachOwnProperties(b,function(a,b){c.push(encodeURIComponent(b)+"="+encodeURIComponent(a))}),c.join("&")},b.prototype._open=function(a,b,c,d,e){var f;return a?(f=window.open(this.postBridgeUrl,d,e),setTimeout(function(){f.redirect(c,b)},100)):f=window.open(c,d,e),f},a.util.popup=new b}(window.tui);
/*!code-snippet v1.2.2 | NHN Entertainment*/
!function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var b=Array.prototype.slice,c=!!Array.prototype.indexOf,d=function(b,c,d){var e,f=[];for(a.util.isUndefined(c)&&(c=b||0,b=0),d=d||1,e=0>d?-1:1,c*=e;c>b*e;b+=d)f.push(b);return f},e=function(){var c=b.call(arguments),d=[];return a.util.forEach(c,function(b){a.util.forEach(b,function(a,b){d[b]||(d[b]=[]),d[b].push(a)})}),d},f=function(b,d,e){var f,g;if(!a.util.isArray(d))return-1;if(c)return Array.prototype.indexOf.call(d,b,e);if(g=d.length,a.util.isUndefined(e))e=0;else if(e>=g||0>e)return-1;for(f=e;g>f;f++)if(d[f]===b)return f;return-1};a.util.inArray=f,a.util.range=d,a.util.zip=e}(window.tui),function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var b,c,d={chrome:!1,firefox:!1,safari:!1,msie:!1,edge:!1,others:!1,version:0},e=window.navigator,f=e.appName.replace(/\s/g,"_"),g=e.userAgent,h=/MSIE\s([0-9]+[.0-9]*)/,i=/Trident.*rv:11\./,j=/Edge\/(\d+)\./,k={firefox:/Firefox\/(\d+)\./,chrome:/Chrome\/(\d+)\./,safari:/Version\/([\d\.]+)\sSafari\/(\d+)/},l={Microsoft_Internet_Explorer:function(){d.msie=!0,d.version=parseFloat(g.match(h)[1])},Netscape:function(){var a=!1;if(i.exec(g))d.msie=!0,d.version=11,a=!0;else if(j.exec(g))d.edge=!0,d.version=g.match(j)[1],a=!0;else for(b in k)if(k.hasOwnProperty(b)&&(c=g.match(k[b]),c&&c.length>1)){d[b]=a=!0,d.version=parseFloat(c[1]||0);break}a||(d.others=!0)}},m=l[f];m&&l[f](),a.util.browser=d}(window.tui),function(a){"use strict";function b(a,b,c){var d=0,e=a.length;for(c=c||null;e>d&&b.call(c,a[d],d,a)!==!1;d++);}function c(a,b,c){var d;c=c||null;for(d in a)if(a.hasOwnProperty(d)&&b.call(c,a[d],d,a)===!1)break}function d(b,c,d){a.util.isArray(b)?a.util.forEachArray(b,c,d):a.util.forEachOwnProperties(b,c,d)}function e(b,c,d){var e=[];return d=d||null,a.util.forEach(b,function(){e.push(c.apply(d,arguments))}),e}function f(b,c,d){var e,f,g,h=0;for(d=d||null,a.util.isArray(b)||(e=a.util.keys(b)),f=e?e.length:b.length,g=b[e?e[h++]:h++];f>h;h++)g=c.call(d,g,b[e?e[h]:h]);return g}function g(a){var c;try{c=Array.prototype.slice.call(a)}catch(d){c=[],b(a,function(a){c.push(a)})}return c}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var h=function(b,c,d){var e,f;if(d=d||null,!a.util.isObject(b)||!a.util.isFunction(c))throw new Error("wrong parameter");return a.util.isArray(b)?(e=[],f=function(a,b){a.push(b[0])}):(e={},f=function(a,b){a[b[1]]=b[0]}),a.util.forEach(b,function(){c.apply(d,arguments)&&f(e,arguments)},d),e},i=function(b,c){var d=a.util.map(b,function(a){return a[c]});return d};a.util.forEachOwnProperties=c,a.util.forEachArray=b,a.util.forEach=d,a.util.toArray=g,a.util.map=e,a.util.reduce=f,a.util.filter=h,a.util.pluck=i}(window.tui),function(a){"use strict";function b(){this.events=null,this.contexts=null}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=/\s+/g;b.mixin=function(c){a.util.extend(c.prototype,b.prototype)},b.prototype._getHandlerItem=function(a,b){var c={handler:a};return b&&(c.context=b),c},b.prototype._safeEvent=function(a){var b,c=this.events;return c||(c=this.events={}),a&&(b=c[a],b||(b=[],c[a]=b),c=b),c},b.prototype._safeContext=function(){var a=this.contexts;return a||(a=this.contexts=[]),a},b.prototype._indexOfContext=function(a){for(var b=this._safeContext(),c=0;b[c];){if(a===b[c][0])return c;c+=1}return-1},b.prototype._memorizeContext=function(b){var c,d;a.util.isExisty(b)&&(c=this._safeContext(),d=this._indexOfContext(b),d>-1?c[d][1]+=1:c.push([b,1]))},b.prototype._forgetContext=function(b){var c,d;a.util.isExisty(b)&&(c=this._safeContext(),d=this._indexOfContext(b),d>-1&&(c[d][1]-=1,c[d][1]<=0&&c.splice(d,1)))},b.prototype._bindEvent=function(a,b,c){var d=this._safeEvent(a);this._memorizeContext(c),d.push(this._getHandlerItem(b,c))},b.prototype.on=function(b,d,e){var f=this;a.util.isString(b)?(b=b.split(c),a.util.forEach(b,function(a){f._bindEvent(a,d,e)})):a.util.isObject(b)&&(e=d,a.util.forEach(b,function(a,b){f.on(b,a,e)}))},b.prototype.once=function(b,c,d){function e(){c.apply(d,arguments),f.off(b,e,d)}var f=this;return a.util.isObject(b)?(d=c,void a.util.forEach(b,function(a,b){f.once(b,a,d)})):void this.on(b,e,d)},b.prototype._spliceMatches=function(b,c){var d,e;if(a.util.isArray(b))for(d=0,e=b.length;e>d;d+=1)c(b[d])===!0&&(b.splice(d,1),e-=1,d-=1)},b.prototype._matchHandler=function(a){var b=this;return function(c){var d=a===c.handler;return d&&b._forgetContext(c.context),d}},b.prototype._matchContext=function(a){var b=this;return function(c){var d=a===c.context;return d&&b._forgetContext(c.context),d}},b.prototype._matchHandlerAndContext=function(a,b){var c=this;return function(d){var e=a===d.handler,f=b===d.context,g=e&&f;return g&&c._forgetContext(d.context),g}},b.prototype._offByEventName=function(b,d){var e=this,f=a.util.forEachArray,g=a.util.isFunction(d),h=e._matchHandler(d);b=b.split(c),f(b,function(a){var b=e._safeEvent(a);g?e._spliceMatches(b,h):(f(b,function(a){e._forgetContext(a.context)}),e.events[a]=[])})},b.prototype._offByHandler=function(b){var c=this,d=this._matchHandler(b);a.util.forEach(this._safeEvent(),function(a){c._spliceMatches(a,d)})},b.prototype._offByObject=function(b,c){var d,e=this;this._indexOfContext(b)<0?a.util.forEach(b,function(a,b){e.off(b,a)}):a.util.isString(c)?(d=this._matchContext(b),e._spliceMatches(this._safeEvent(c),d)):a.util.isFunction(c)?(d=this._matchHandlerAndContext(c,b),a.util.forEach(this._safeEvent(),function(a){e._spliceMatches(a,d)})):(d=this._matchContext(b),a.util.forEach(this._safeEvent(),function(a){e._spliceMatches(a,d)}))},b.prototype.off=function(b,c){a.util.isString(b)?this._offByEventName(b,c):arguments.length?a.util.isFunction(b)?this._offByHandler(b):a.util.isObject(b)&&this._offByObject(b,c):(this.events={},this.contexts=[])},b.prototype.fire=function(a){this.invoke.apply(this,arguments)},b.prototype.invoke=function(a){var b,c,d,e;if(!this.hasListener(a))return!0;for(b=this._safeEvent(a),c=Array.prototype.slice.call(arguments,1),d=0;b[d];){if(e=b[d],e.handler.apply(e.context,c)===!1)return!1;d+=1}return!0},b.prototype.hasListener=function(a){return this.getListenerLength(a)>0},b.prototype.getListenerLength=function(a){var b=this._safeEvent(a);return b.length},a.util.CustomEvents=b}(window.tui),function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.defineClass=function(b,c){var d;return c||(c=b,b=null),d=c.init||function(){},b&&a.util.inherit(d,b),c.hasOwnProperty("static")&&(a.util.extend(d,c["static"]),delete c["static"]),a.util.extend(d.prototype,c),d}}(window.tui),function(a){"use strict";function b(a,b){var e=b||{};return c.isFunction(e[d])&&e[d](),c.defineNamespace(a,e)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=a.util,d="initialize";a.util.defineModule=b}(window.tui),function(a){"use strict";a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var b=a.util;a.util.defineNamespace=function(a,c,d){var e,f,g,h;return e=a.split("."),e.unshift(window),f=b.reduce(e,function(a,b){return a[b]=a[b]||{},a[b]}),d?(h=e.pop(),g=b.pick.apply(null,e),f=g[h]=c):b.extend(f,c),f}}(window.tui),function(a){"use strict";function b(a){a&&this.set.apply(this,arguments)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=function(){try{return Object.defineProperty({},"x",{}),!0}catch(a){return!1}}(),d=0;b.prototype.set=function(b){var c=this;a.util.isArray(b)||(b=a.util.toArray(arguments)),a.util.forEach(b,function(a){c._addItem(a)})},b.prototype.getName=function(b){var c,d=this;return a.util.forEach(this,function(a,e){return d._isEnumItem(e)&&b===a?(c=e,!1):void 0}),c},b.prototype._addItem=function(a){var b;this.hasOwnProperty(a)||(b=this._makeEnumValue(),c?Object.defineProperty(this,a,{enumerable:!0,configurable:!1,writable:!1,value:b}):this[a]=b)},b.prototype._makeEnumValue=function(){var a;return a=d,d+=1,a},b.prototype._isEnumItem=function(b){return a.util.isNumber(this[b])},a.util.Enum=b}(window.tui),function(a){"use strict";function b(a){this._map=new c.Map(a),this.size=this._map.size}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=a.util,d=["get","has","forEach","keys","values","entries"],e=["delete","clear"];c.forEachArray(d,function(a){b.prototype[a]=function(){return this._map[a].apply(this._map,arguments)}}),c.forEachArray(e,function(a){b.prototype[a]=function(){var b=this._map[a].apply(this._map,arguments);return this.size=this._map.size,b}}),b.prototype.set=function(){return this._map.set.apply(this._map,arguments),this.size=this._map.size,this},b.prototype.setObject=function(a){c.forEachOwnProperties(a,function(a,b){this.set(b,a)},this)},b.prototype.deleteByKeys=function(a){c.forEachArray(a,function(a){this["delete"](a)},this)},b.prototype.merge=function(a){a.forEach(function(a,b){this.set(b,a)},this)},b.prototype.filter=function(a){var c=new b;return this.forEach(function(b,d){a(b,d)&&c.set(d,b)}),c},c.ExMap=b}(window.tui),function(a){"use strict";function b(a,b,c){var d,e,g,h;return a=Number(a),b=Number(b),c=Number(c),d=a>-1&&100>a||a>1969&&2070>a,e=b>0&&13>b,d&&e?(h=f[b],2===b&&a%4===0&&(a%100===0&&a%400!==0||(h=29)),g=c>0&&h>=c):!1}function c(c,e,f){var h,i,j;return i=a.util.isDate(e)?{year:e.getFullYear(),month:e.getMonth()+1,date:e.getDate(),hour:e.getHours(),minute:e.getMinutes()}:{year:e.year,month:e.month,date:e.date,hour:e.hour,minute:e.minute},b(i.year,i.month,i.date)?(i.meridiem="",/([^\\]|^)[aA]\b/.test(c)&&(h=i.hour>11?a.util.pick(f,"meridiemSet","PM")||"PM":a.util.pick(f,"meridiemSet","AM")||"AM",i.hour>12&&(i.hour%=12),0===i.hour&&(i.hour=12),i.meridiem=h),j=c.replace(d,function(a){return a.indexOf("\\")>-1?a.replace(/\\/,""):g[a](i)||""})):!1}var d=/[\\]*YYYY|[\\]*YY|[\\]*MMMM|[\\]*MMM|[\\]*MM|[\\]*M|[\\]*DD|[\\]*D|[\\]*HH|[\\]*H|[\\]*A/gi,e=["Invalid month","January","February","March","April","May","June","July","August","September","October","November","December"],f=[0,31,28,31,30,31,30,31,31,30,31,30,31],g={M:function(a){return Number(a.month)},MM:function(a){var b=a.month;return Number(b)<10?"0"+b:b},MMM:function(a){return e[Number(a.month)].substr(0,3)},MMMM:function(a){return e[Number(a.month)]},D:function(a){return Number(a.date)},d:function(a){return g.D(a)},DD:function(a){var b=a.date;return Number(b)<10?"0"+b:b},dd:function(a){return g.DD(a)},YY:function(a){return Number(a.year)%100},yy:function(a){return g.YY(a)},YYYY:function(a){var b="20",c=a.year;return c>69&&100>c&&(b="19"),Number(c)<100?b+String(c):c},yyyy:function(a){return g.YYYY(a)},A:function(a){return a.meridiem},a:function(a){return a.meridiem},hh:function(a){var b=a.hour;return Number(b)<10?"0"+b:b},HH:function(a){return g.hh(a)},h:function(a){return String(Number(a.hour))},H:function(a){return g.h(a)},m:function(a){return String(Number(a.minute))},mm:function(a){var b=a.minute;return Number(b)<10?"0"+b:b}};a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.formatDate=c}(window.tui),function(a){"use strict";function b(a,b){var c=Array.prototype.slice;if(a.bind)return a.bind.apply(a,c.call(arguments,1));var d=c.call(arguments,2);return function(){return a.apply(b,d.length?d.concat(c.call(arguments)):arguments)}}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.bind=b}(window.tui),function(a){"use strict";function b(a){this.length=0,a&&this.setObject(a)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c="å";b.prototype.set=function(a,b){2===arguments.length?this.setKeyValue(a,b):this.setObject(a)},b.prototype.setKeyValue=function(a,b){this.has(a)||(this.length+=1),this[this.encodeKey(a)]=b},b.prototype.setObject=function(b){var c=this;a.util.forEachOwnProperties(b,function(a,b){c.setKeyValue(b,a)})},b.prototype.merge=function(a){var b=this;a.each(function(a,c){b.setKeyValue(c,a)})},b.prototype.encodeKey=function(a){return c+a},b.prototype.decodeKey=function(a){var b=a.split(c);return b[b.length-1]},b.prototype.get=function(a){return this[this.encodeKey(a)]},b.prototype.has=function(a){return this.hasOwnProperty(this.encodeKey(a))},b.prototype.remove=function(b){return arguments.length>1&&(b=a.util.toArray(arguments)),a.util.isArray(b)?this.removeByKeyArray(b):this.removeByKey(b)},b.prototype.removeByKey=function(a){var b=this.has(a)?this.get(a):null;return null!==b&&(delete this[this.encodeKey(a)],this.length-=1),b},b.prototype.removeByKeyArray=function(b){var c=[],d=this;return a.util.forEach(b,function(a){c.push(d.removeByKey(a))}),c},b.prototype.removeAll=function(){var a=this;this.each(function(b,c){a.remove(c)})},b.prototype.each=function(b){var d,e=this;a.util.forEachOwnProperties(this,function(a,f){return f.charAt(0)===c&&(d=b(a,e.decodeKey(f))),d===!1?d:void 0})},b.prototype.keys=function(){var a=[],b=this;return this.each(function(c,d){a.push(b.decodeKey(d))}),a},b.prototype.find=function(a){var b=[];return this.each(function(c,d){a(c,d)&&b.push(c)}),b},b.prototype.toArray=function(){var a=[];return this.each(function(b){a.push(b)}),a},a.util.HashMap=b}(window.tui),function(a){"use strict";function b(){function a(){}return function(b){return a.prototype=b,new a}}function c(b,c){var d=a.util.createObject(c.prototype);d.constructor=b,b.prototype=d}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.createObject=b(),a.util.inherit=c}(window.tui),function(a){"use strict";function b(a,b){this._keys=a,this._valueGetter=b,this._length=this._keys.length,this._index=-1,this._done=!1}function c(a){this._valuesForString={},this._valuesForIndex={},this._keys=[],a&&this._setInitData(a),this.size=0}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var d=a.util,e={},f={};b.prototype.next=function(){var a={};do this._index+=1;while(d.isUndefined(this._keys[this._index])&&this._index<this._length);return this._index>=this._length?a.done=!0:(a.done=!1,a.value=this._valueGetter(this._keys[this._index],this._index)),a},c.prototype._setInitData=function(a){if(!d.isArray(a))throw new Error("Only Array is supported.");d.forEachArray(a,function(a){this.set(a[0],a[1])},this)},c.prototype._isNaN=function(a){return"number"==typeof a&&a!==a},c.prototype._getKeyIndex=function(a){var b,c=-1;return d.isString(a)?(b=this._valuesForString[a],b&&(c=b.keyIndex)):c=d.inArray(a,this._keys),c},c.prototype._getOriginKey=function(a){var b=a;return a===e?b=void 0:a===f&&(b=NaN),b},c.prototype._getUniqueKey=function(a){var b=a;return d.isUndefined(a)?b=e:this._isNaN(a)&&(b=f),b},c.prototype._getValueObject=function(a,b){return d.isString(a)?this._valuesForString[a]:(d.isUndefined(b)&&(b=this._getKeyIndex(a)),b>=0?this._valuesForIndex[b]:void 0)},c.prototype._getOriginValue=function(a,b){return this._getValueObject(a,b).origin},c.prototype._getKeyValuePair=function(a,b){return[this._getOriginKey(a),this._getOriginValue(a,b)]},c.prototype._createValueObject=function(a,b){return{keyIndex:b,origin:a}},c.prototype.set=function(a,b){var c,e=this._getUniqueKey(a),f=this._getKeyIndex(e);return 0>f&&(f=this._keys.push(e)-1,this.size+=1),c=this._createValueObject(b,f),d.isString(a)?this._valuesForString[a]=c:this._valuesForIndex[f]=c,this},c.prototype.get=function(a){var b=this._getUniqueKey(a),c=this._getValueObject(b);return c&&c.origin},c.prototype.keys=function(){return new b(this._keys,d.bind(this._getOriginKey,this))},c.prototype.values=function(){return new b(this._keys,d.bind(this._getOriginValue,this))},c.prototype.entries=function(){return new b(this._keys,d.bind(this._getKeyValuePair,this))},c.prototype.has=function(a){return!!this._getValueObject(a)},c.prototype["delete"]=function(a){var b;d.isString(a)?this._valuesForString[a]&&(b=this._valuesForString[a].keyIndex,delete this._valuesForString[a]):(b=this._getKeyIndex(a),b>=0&&delete this._valuesForIndex[b]),b>=0&&(delete this._keys[b],this.size-=1)},c.prototype.forEach=function(a,b){b=b||this,d.forEachArray(this._keys,function(c){d.isUndefined(c)||a.call(b,this._getValueObject(c).origin,c,this)},this)},c.prototype.clear=function(){c.call(this)},function(){var a=d.browser;window.Map&&(a.firefox&&a.version>=37||a.chrome&&a.version>=42)&&(c=window.Map)}(),d.Map=c}(window.tui),function(a){"use strict";function b(a,b){var c,d,e,f,g=Object.prototype.hasOwnProperty;for(e=1,f=arguments.length;f>e;e++){c=arguments[e];for(d in c)g.call(c,d)&&(a[d]=c[d])}return a}function c(a){return a.__fe_id=a.__fe_id||++i,a.__fe_id}function d(b){return a.util.isExisty(a.util.pick(b,"__fe_id"))}function e(){i=0}function f(a){var b,c=[];for(b in a)a.hasOwnProperty(b)&&c.push(b);return c}function g(b){function c(b,f){var g;if(isNaN(b)&&isNaN(f)&&a.util.isNumber(b)&&a.util.isNumber(f))return!0;if(b===f)return!0;if(a.util.isFunction(b)&&a.util.isFunction(f)||b instanceof Date&&f instanceof Date||b instanceof RegExp&&f instanceof RegExp||b instanceof String&&f instanceof String||b instanceof Number&&f instanceof Number)return b.toString()===f.toString();if(!(b instanceof Object&&f instanceof Object))return!1;if(b.isPrototypeOf(f)||f.isPrototypeOf(b)||b.constructor!==f.constructor||b.prototype!==f.prototype)return!1;if(a.util.inArray(b,d)>-1||a.util.inArray(f,e)>-1)return!1;for(g in f){if(f.hasOwnProperty(g)!==b.hasOwnProperty(g))return!1;if(typeof f[g]!=typeof b[g])return!1}for(g in b){if(f.hasOwnProperty(g)!==b.hasOwnProperty(g))return!1;if(typeof f[g]!=typeof b[g])return!1;if("object"==typeof b[g]||"function"==typeof b[g]){if(d.push(b),e.push(f),!c(b[g],f[g]))return!1;d.pop(),e.pop()}else if(b[g]!==f[g])return!1}return!0}var d,e,f,g=arguments.length;if(1>g)return!0;for(f=1;g>f;f++)if(d=[],e=[],!c(arguments[0],arguments[f]))return!1;return!0}function h(a,b){var c,d=arguments,e=d[0],f=d.length;try{for(c=1;f>c;c++)e=e[d[c]];return e}catch(g){return}}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var i=0;a.util.extend=b,a.util.stamp=c,a.util.hasStamp=d,a.util._resetLastId=e,a.util.keys=Object.keys||f,a.util.compareJSON=g,a.util.pick=h}(window.tui),function(a){"use strict";function b(a){var b={"&quot;":'"',"&amp;":"&","&lt;":"<","&gt;":">","&#39;":"'","&nbsp;":" "};return a.replace(/&amp;|&lt;|&gt;|&quot;|&#39;|&nbsp;/g,function(a){return b[a]?b[a]:a})}function c(a){var b={'"':"quot","&":"amp","<":"lt",">":"gt","'":"#39"};return a.replace(/[<>&"']/g,function(a){return b[a]?"&"+b[a]+";":a})}function d(a){return/[<>&"']/.test(a)}function e(b,c){for(var d,e,f=0,g=b.length,h={};g>f;f+=1)e=b.charAt(f),h[e]=1;for(f=0,g=c.length;g>f;f+=1)e=c.charAt(f),h[e]&&(h[e]+=1);return h=a.util.filter(h,function(a){return a>1}),h=a.util.keys(h).sort(),d=h.join("")}a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.decodeHTMLEntity=b,a.util.encodeHTMLEntity=c,a.util.hasEncodableString=d,a.util.getDuplicatedChar=e}(window.tui),function(a){"use strict";function b(a,b){function c(){f=e.call(arguments),window.clearTimeout(d),d=window.setTimeout(function(){a.apply(null,f)},b)}var d,f;return b=b||0,c}function c(){return+new Date}function d(b,c){function d(){return j=e.call(arguments),l?(m(j),void(l=!1)):(i=k(),g=g||i,h(j),void(i-g>=c&&m(j)))}function f(){l=!0,g=null}var g,h,i,j,k=a.util.timestamp,l=!0,m=function(a){b.apply(null,a),g=null};return c=c||0,h=a.util.debounce(m,c),d.reset=f,d}var e=Array.prototype.slice;a||(a=window.tui={}),a.util||(a.util=window.tui.util={}),a.util.timestamp=c,a.util.debounce=b,a.util.throttle=d}(window.tui),function(a){"use strict";function b(a){return null!=a}function c(a){return void 0===a}function d(a){return null===a}function e(a){return b(a)&&a!==!1}function f(a){return!e(a)}function g(a){var c=b(a)&&("[object Arguments]"===y.call(a)||!!a.callee);return c}function h(a){return a instanceof Array}function i(a){return a===Object(a)}function j(a){return a instanceof Function}function k(a){return"number"==typeof a||a instanceof Number}function l(a){return"string"==typeof a||a instanceof String}function m(a){return"boolean"==typeof a||a instanceof Boolean}function n(a){return"[object Array]"===y.call(a)}function o(a){return"[object Function]"===y.call(a)}function p(a){return"[object Number]"===y.call(a)}function q(a){return"[object String]"===y.call(a)}function r(a){return"[object Boolean]"===y.call(a)}function s(a){return"object"==typeof HTMLElement?a&&(a instanceof HTMLElement||!!a.nodeType):!(!a||!a.nodeType)}function t(a){return"object"==typeof HTMLElement?a&&a instanceof HTMLElement:!(!a||!a.nodeType||1!==a.nodeType)}function u(c){var d=!1;return b(c)?l(c)&&""===c?!0:h(c)||g(c)?0===c.length:i(c)&&!j(c)?(a.util.forEachOwnProperties(c,function(){return d=!0,!1}),!d):!0:!0}function v(a){return!u(a)}function w(a){return a instanceof Date}function x(a){return"[object Date]"===y.call(a)}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var y=Object.prototype.toString;a.util.isExisty=b,a.util.isUndefined=c,a.util.isNull=d,a.util.isTruthy=e,a.util.isFalsy=f,a.util.isArguments=g,a.util.isArray=Array.isArray||h,a.util.isArraySafe=Array.isArray||n,a.util.isObject=i,a.util.isFunction=j,a.util.isFunctionSafe=o,a.util.isNumber=k,a.util.isNumberSafe=p,a.util.isDate=w,a.util.isDateSafe=x,a.util.isString=l,a.util.isStringSafe=q,a.util.isBoolean=m,a.util.isBooleanSafe=r,a.util.isHTMLNode=s,a.util.isHTMLTag=t,a.util.isEmpty=u,a.util.isNotEmpty=v}(window.tui),function(a){"use strict";function b(){this.openedPopup={},this.closeWithParentPopup={},this.postBridgeUrl=""}a||(a=window.tui={}),a.util||(a.util=window.tui.util={});var c=0;b.prototype.getPopupList=function(b){var c;return c=a.util.isExisty(b)?this.openedPopup[b]:this.openedPopup},b.prototype.openPopup=function(b,d){d=a.util.extend({popupName:"popup_"+c+"_"+ +new Date,popupOptionStr:"",useReload:!0,closeWithParent:!0,method:"get",param:{}},d||{}),d.method=d.method.toUpperCase(),this.postBridgeUrl=d.postBridgeUrl||this.postBridgeUrl;var e,f,g="POST"===d.method&&d.param&&a.util.browser.msie&&11===a.util.browser.version;if(!a.util.isExisty(b))throw new Error("Popup#open() need popup url.");c+=1,d.param&&("GET"===d.method?b=b+(/\?/.test(b)?"&":"?")+this._parameterize(d.param):"POST"===d.method&&(g||(f=this.createForm(b,d.param,d.method,d.popupName),b="about:blank"))),e=this.openedPopup[d.popupName],a.util.isExisty(e)?e.closed?this.openedPopup[d.popupName]=e=this._open(g,d.param,b,d.popupName,d.popupOptionStr):(d.useReload&&e.location.replace(b),e.focus()):this.openedPopup[d.popupName]=e=this._open(g,d.param,b,d.popupName,d.popupOptionStr),this.closeWithParentPopup[d.popupName]=d.closeWithParent,(!e||e.closed||a.util.isUndefined(e.closed))&&alert("please enable popup windows for this website"),d.param&&"POST"===d.method&&!g&&(e&&f.submit(),f.parentNode&&f.parentNode.removeChild(f)),window.onunload=a.util.bind(this.closeAllPopup,this)},b.prototype.close=function(b,c){b=a.util.isExisty(b)?b:!1;var d=c||window;b&&(window.onunload=null),d.closed||(d.opener=window.location.href,d.close())},b.prototype.closeAllPopup=function(b){var c=a.util.isExisty(b);a.util.forEachOwnProperties(this.openedPopup,function(a,b){(c&&this.closeWithParentPopup[b]||!c)&&this.close(!1,a)},this)},b.prototype.focus=function(a){this.getPopupList(a).focus()},b.prototype.parseQuery=function(){var b,c,d={};return b=window.location.search.substr(1),a.util.forEachArray(b.split("&"),function(a){c=a.split("="),d[decodeURIComponent(c[0])]=decodeURIComponent(c[1])}),d},b.prototype.createForm=function(b,c,d,e,f){var g,h=document.createElement("form");return f=f||document.body,h.method=d||"POST",h.action=b||"",h.target=e||"",h.style.display="none",a.util.forEachOwnProperties(c,function(a,b){g=document.createElement("input"),g.name=b,g.type="hidden",g.value=a,h.appendChild(g)}),f.appendChild(h),h},b.prototype._parameterize=function(b){var c=[];return a.util.forEachOwnProperties(b,function(a,b){c.push(encodeURIComponent(b)+"="+encodeURIComponent(a))}),c.join("&")},b.prototype._open=function(a,b,c,d,e){var f;return a?(f=window.open(this.postBridgeUrl,d,e),setTimeout(function(){f.redirect(c,b)},100)):f=window.open(c,d,e),f},a.util.popup=new b}(window.tui);
module.exports = function(grunt) {
grunt.initConfig({
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),

@@ -4,0 +4,0 @@ concat: {

@@ -29,6 +29,23 @@ // Karma configuration

'src/**/*.js',
'test/**/*.test.js'
'test/**/*.test.js',
// 'test/array.test.js',
// 'test/browser.test.js',
// 'test/collection.test.js',
// 'test/customEvent.test.js',
// 'test/defineClass.test.js',
// 'test/defineModule.test.js',
// 'test/defineNamespace.test.js',
// 'test/enum.test.js',
// 'test/exMap.test.js',
// 'test/formatDate.test.js'
// 'test/func.test.js',
// 'test/hashMap.test.js',
// 'test/inheritance.test.js',
// 'test/map.test.js',
// 'test/object.test.js',
// 'test/string.test.js',
// 'test/tricks.test.js',
// 'test/type.test.js'
],
// list of files to exclude

@@ -57,2 +74,3 @@ exclude: [

outputFile: 'report/junit-result.xml',
outputDir: 'report',
suite: ''

@@ -99,4 +117,4 @@ },

// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'IE7',
browsers: [
// 'IE7', // Karma bug - 무한대기 (Karma 0.13.22, Karma-jasmine 0.3.8)
'IE8',

@@ -107,3 +125,5 @@ 'IE9',

'Chrome-WebDriver',
'Firefox-WebDriver'
'Firefox-WebDriver',
'Edge'
// , 'PhantomJS'
],

@@ -142,2 +162,7 @@

},
'Edge': {
base: 'WebDriver',
config: webdriverConfig,
browserName: 'MicrosoftEdge'
},
'Chrome-WebDriver': {

@@ -157,4 +182,4 @@ base: 'WebDriver',

// if true, Karma captures browsers, runs the tests and exits
singleRun: false
singleRun: true
});
};
{
"name": "tui-code-snippet",
"version": "1.0.6",
"version": "1.2.2",
"description": "useful code snippets from frontend development team",

@@ -16,24 +16,20 @@ "main": "code-snippet.js",

"devDependencies": {
"fedoc-template": "git+http://14bfd38a036366f7ca90355d202038126127bd01:x-oauth-basic@github.nhnent.com/fe/share-fedoc-template.git#snippet",
"fedoc-template": "git+https://14bfd38a036366f7ca90355d202038126127bd01:x-oauth-basic@github.nhnent.com/fe/share-fedoc-template.git#snippet",
"grunt": "^0.4.5",
"grunt-contrib-concat": "^0.5.0",
"grunt-contrib-uglify": "^0.6.0",
"jasmine-ajax": "^2.0.1",
"jasmine-core": "^2.2.0",
"jasmine-jquery": "^2.0.5",
"jquery": "1.8.3",
"jasmine-ajax": "latest",
"jasmine-core": "latest",
"jasmine-jquery": "latest",
"jsdoc": "git+https://github.com/jsdoc3/jsdoc.git",
"karma": "^0.12.31",
"karma-chrome-launcher": "^0.1.5",
"karma-coverage": "^0.2.6",
"karma-jasmine": "^0.3.5",
"karma-junit-reporter": "^0.2.2",
"karma-mocha-reporter": "^1.0.2",
"karma-phantomjs-launcher": "^0.2.0",
"karma": "0.13.22",
"karma-chrome-launcher": "latest",
"karma-coverage": "latest",
"karma-jasmine": "0.3.8",
"karma-junit-reporter": "latest",
"karma-mocha-reporter": "latest",
"karma-phantomjs-launcher": "latest",
"karma-webdriver-launcher": "git+https://github.com/everedifice/karma-webdriver-launcher.git",
"phantomjs": "^1.9.17",
"body-parser": "^1.14.1",
"express": "^4.13.3",
"serve-static": "^1.10.0"
"phantomjs-prebuilt": "latest"
}
}

@@ -18,3 +18,3 @@ Toast UI CodeSnippet

* Custom event modules
* Add/Remove/fire custom events
* Add/Remove/fire custom events
* defineClass.js

@@ -24,3 +24,3 @@ * Defined classes module

* Const value modules
* Making immutability values but IE8 low
* Making immutability values but IE8 low
* func.js

@@ -30,8 +30,8 @@ * Function modules

* Hash map modules
* Managing data by key/value
* Managing data by key/value
* inheritance.js
* Simple inheritance modules (Nicholas C. Zakas, YUI Library)
* Call supur constructor of superclass
* Have to get inheritance before define child
* Using mixin and inner object
* Have to get inheritance before define child
* Using mixin and inner object
* object.js

@@ -56,6 +56,6 @@ * Object modules

## How to use CodeSnippet
## How to use CodeSnippet
* Using CodeSnippet build file
* Download code-snippet.js or code-snippet.min.js from [[master branch]](https://github.com/nhnent/tui.code-snippet)
* It's better that you do not change the file name.
* It's better that you do not change the file name.
* Using the copy only the necesary parts

@@ -70,3 +70,3 @@ * Check dependency before copy the codes

## Tested browsers
* browser :
* browser :
* IE7+

@@ -77,15 +77,5 @@ * Chrome

## Download/Install
* Bower:
* Bower:
* latest : `bower install tui-code-snippet`
* each version : `bower install tui-code-snippet[#tag]`
* Download : https://github.com/nhnent/tui.code-snippet
## History
| Version | Description | Date | Developer |
| ---- | ---- | ---- | ---- |
| <a href="https://nhnent.github.io/tui.code-snippet/1.0.6/">1.0.6</a> | Please see github release page after this versions. | 2015.11 | NHN Entertainment FE Dev team<dl_javascript@nhnent.com> |
| <a href="https://nhnent.github.io/tui.code-snippet/1.0.4/">1.0.4</a> | getDuplicatedChar added | 2015.07 | NHN Entertainment FE Dev team<dl_javascript@nhnent.com> |
| <a href="https://nhnent.github.io/tui.code-snippet/1.0.3/">1.0.3</a> | defineModule,<br>formatDate added | 2015.06 | NHN Entertainment FE Dev team<dl_javascript@nhnent.com> |
| <a href="https://nhnent.github.io/tui.code-snippet/1.0.2/">1.0.2</a> | defineNamespace,<br>map, exMap added | 2015.04 | NHN Entertainment FE Dev team<dl_javascript@nhnent.com> |
| 1.0.1 | isExisty modified,<br>pick added<br>type modifyied | 2015.04 | NHN Entertainment FE Dev team<dl_javascript@nhnent.com> |
| <a href="https://nhnent.github.io/tui.code-snippet/1.0.0/">1.0.0</a> | jquery dependency removed | 2015.03 | NHN Entertainment FE Dev team<dl_javascript@nhnent.com> |

@@ -5,3 +5,3 @@ /**

* FE Development Team <jiung.kang@nhnent.com>
* @dependency type.js
* @dependency type.js, collection.js
*/

@@ -17,11 +17,17 @@

}
var aps = Array.prototype.slice;
/**
* This variable saves whether the 'indexOf' method is in Array.prototype or not.<br>
* And it will be checked only once when the page is loaded.
* @type {boolean}
*/
var hasIndexOf = !!Array.prototype.indexOf;
/**
* Generate an integer Array containing an arithmetic progression.
* @memberof tui.util
* @param {number} start
* @param {number} stop
* @param {number} step
* @memberof tui.util
* @returns {Array}

@@ -64,4 +70,4 @@ * @example

* Zip together multiple lists into a single array
* @memberof tui.util
* @param {...Array}
* @memberof tui.util
* @returns {Array}

@@ -92,4 +98,52 @@ * @example

/**
* 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.<br>
* It compares searchElement to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator).
* @memberof tui.util
* @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)
* @return {number} the First index at which a given element, or -1 if it is not present
* @example
*
* var arr = ['one', 'two', 'three', 'four'],
* idx1,
* idx2;
*
* idx1 = tui.util.inArray('one', arr, 3);
* alert(idx1); // -1
*
* idx2 = tui.util.inArray('one', arr);
* alert(idx2); // 0
*/
var inArray = function(searchElement, array, startIndex) {
var i, length;
if (!tui.util.isArray(array)) {
return -1;
}
if (hasIndexOf) {
return Array.prototype.indexOf.call(array, searchElement, startIndex);
}
length = array.length;
if (tui.util.isUndefined(startIndex)) {
startIndex = 0;
} else if (startIndex >= length || startIndex < 0) {
return -1;
}
for (i = startIndex; i < length; i++) {
if (array[i] === searchElement) {
return i;
}
}
return -1;
};
tui.util.inArray = inArray;
tui.util.range = range;
tui.util.zip = zip;
})(window.tui);

@@ -26,2 +26,3 @@ /**

* - safari
* - edge
* @memberof tui.util

@@ -33,2 +34,3 @@ * @example

* tui.util.browser.msie === true; // IE
* tui.util.browser.edge === true; // edge
* tui.util.browser.other === true; // other browser

@@ -42,2 +44,3 @@ * tui.util.browser.version; // browser version

msie: false,
edge: false,
others: false,

@@ -53,2 +56,3 @@ version: 0

rIE11 = /Trident.*rv:11\./,
rEdge = /Edge\/(\d+)\./,
versionRegex = {

@@ -74,2 +78,7 @@ 'firefox': /Firefox\/(\d+)\./,

browser.version = 11;
detected = true;
} else if (rEdge.exec(userAgent)) {
browser.edge = true;
browser.version = userAgent.match(rEdge)[1];
detected = true;
} else {

@@ -93,4 +102,9 @@ for (key in versionRegex) {

detector[appName]();
var fn = detector[appName];
if (fn) {
detector[appName]();
}
tui.util.browser = browser;
})(window.tui);

@@ -18,9 +18,2 @@ /**

/**
* This variable saves whether the 'indexOf' method is in Array.prototype or not.<br>
* And it will be checked only once when the page is loaded.
* @type {boolean}
*/
var hasIndexOf = !!Array.prototype.indexOf;
/**
* Execute the provided callback once for each element present in the array(or Array-like object) in ascending order.<br>

@@ -289,51 +282,2 @@ * If the callback function returns false, the loop will be stopped.<br>

/**
* 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.<br>
* 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)
* @memberof tui.util
* @return {number} the First index at which a given element, or -1 if it is not present
* @example
*
* var arr = ['one', 'two', 'three', 'four'],
* idx1,
* idx2;
*
* idx1 = tui.util.inArray('one', arr, 3);
* alert(idx1); // -1
*
* idx2 = tui.util.inArray('one', arr);
* alert(idx2); // 0
*/
var inArray = function(searchElement, array, startIndex) {
if (!tui.util.isArray(array)) {
return -1;
}
if (hasIndexOf) {
return Array.prototype.indexOf.call(array, searchElement, startIndex);
}
var i,
length = array.length;
// set startIndex
if (tui.util.isUndefined(startIndex)) {
startIndex = 0;
} else if (startIndex >= length || startIndex < 0) {
return -1;
}
// search
for (i = startIndex; i < length; i++) {
if (array[i] === searchElement) {
return i;
}
}
return -1;
};
/**
* fetching a property

@@ -377,5 +321,3 @@ * @param {Array} arr target collection

tui.util.filter = filter;
tui.util.inArray = inArray;
tui.util.pluck = pluck;
})(window.tui);

@@ -22,62 +22,13 @@ /**

var R_EVENTNAME_SPLIT = /\s+/g; // eslint-disable-line
/**
* A unit of event handler item.
* @ignore
* @typedef {Object} handlerItem
* @typedef {object} HandlerItem
* @property {function} fn - event handler
* @property {*} ctx - context of event handler
* @property {object} ctx - context of event handler
*/
/**
* A data structure for storing handlerItems bound with a specific context
* and is a unit item of ctxEvents.<br>
* Handlers in this item, will be executed with same event.
* @ignore
* @typedef {Object.<string, handlerItem>} ctxEventsItem
* @example
* ctxEventsItem = {
* 1_1: {
* fn: function(){...},
* ctx: context1
* },
* 2_1: {
* fn: function(){...},
* ctx: context1
* }
* }
*/
/**
* A data structure for storing ctxEventsItem and length for each event(or event name).
* @ignore
* @typedef {Object.<string, (ctxEventsItem|number)>} ctxEvents
* @example
* ctxEvents = {
* eventName1_idx: {
* 1_1: {
* fn: function(){...},
* ctx: context1
* },
* 2_1: {
* fn: function(){...},
* ctx: context1
* }
* },
* eventName1_len: 2,
* eventName2_idx: {
* 3_2: {
* fn: function(){...},
* ctx: context2
* },
* 4_2: {
* fn: function(){...},
* ctx: context2
* }
* },
* eventName2_len: 2
* };
*/
/**
* @constructor

@@ -88,24 +39,16 @@ * @memberof tui.util

/**
* Caching a data structure that has normal event handlers which are not bound with a specific context.
* @type {object.<string, handlerItem[]>}
* @private
* @type {HandlerItem[]}
*/
this._events = null;
this.events = null;
/**
* Caching a {ctxEvents}
* @type {ctxEvents}
* @private
* only for checking specific context event was binded
* @type {object[]}
*/
this._ctxEvents = null;
this.contexts = null;
}
/**********
* static
**********/
/**
* Use for making a constructor to be able to do CustomEvent's functions.
* @param {function} func - Constructor
* Mixin custom events feature to specific constructor
* @param {function} func - constructor
* @example

@@ -119,2 +62,3 @@ * function Model() {

* model.on('change', function() { this.name = 'model'; }, this);
*
* model.fire('change');

@@ -127,355 +71,319 @@ * alert(model.name); // 'model';

/**********
* private
**********/
/**
* Work similarly to Array.prototype.forEach(),
* however does Array.prototype.splice() additionally.<br>
* Callback(iteratee) function is invoked with four arguments:
* - The value of the element
* - The index of the element
* - The array being traversed
* - A special callback function that decreases the length of array
* @param {Array} arr - Array that will be traversed
* @param {function} iteratee - Callback function
* Get HandlerItem object
* @param {function} handler - handler function
* @param {object} [context] - context for handler
* @returns {HandlerItem} HandlerItem object
* @private
*/
CustomEvents.prototype._forEachArraySplice = function(arr, iteratee) {
var i,
len,
item,
decrease = function() {
arr.splice(i, 1);
len -= 1;
i -= 1;
};
CustomEvents.prototype._getHandlerItem = function(handler, context) {
var item = {handler: handler};
if (!tui.util.isExisty(arr) || !tui.util.isArray(arr)) {
return;
if (context) {
item.context = context;
}
for (i = 0, len = arr.length; i < len; i++) {
item = arr[i];
if (iteratee(item, i, arr, decrease) === false) {
return;
}
}
return item;
};
/**********
* context event handler
**********/
/**
* Execute the callback once for each ctxEventsItem.<br>
* Callback function(iteratee) is invoked with three arguments:
* - {ctxEventsItem} A unit item of ctxEvents
* - {string} A key (ex - 'eventName_idx' or 'eventName_len')
* - {ctxEvents} A ctxEvents being traversed
* @param {function} iteratee - Callback function
* 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._eachCtxEvents = function(iteratee) {
var events = this._ctxEvents;
tui.util.forEachOwnProperties(events, iteratee);
};
CustomEvents.prototype._safeEvent = function(eventName) {
var events = this.events,
byName;
/**
* Execute the callback once
* for each handler item that is value of the key including a specific string(=id, arguments[1]).<br>
* Callback function(iteratee) is invoked with two arguments:
* - handlerItem
* - handlerItemId
* @param {ctxEventsItem} ctxEventsItem - A data structure storing handlerItems.
* @param {string} id - An id of handler for searching
* @param {function} iteratee - Callback function
* @private
*/
CustomEvents.prototype._eachCtxHandlerItemByContainId = function(ctxEventsItem, id, iteratee) {
tui.util.forEachOwnProperties(ctxEventsItem, function(handlerItem, handlerItemId) {
if (handlerItemId.indexOf(id) > -1) {
iteratee(handlerItem, handlerItemId);
if (!events) {
events = this.events = {};
}
if (eventName) {
byName = events[eventName];
if (!byName) {
byName = [];
events[eventName] = byName;
}
});
events = byName;
}
return events;
};
/**
* Execute the callback once
* for each case of when the provided handler(arguments[0]) is equal to a handler in ctxEventsItem.<br>
* Callback function(iteratee) is invoked with four arguments:
* - handlerItem
* - handlerItemId
* - ctxEventsItem
* - eventKey, A Name of custom event (ex - 'eventName_idx')
* @param {function} handler - Event handler
* @param {function} iteratee - Callback function
* @private
* Get context array safely
* @returns {array} context array
*/
CustomEvents.prototype._eachCtxEventByHandler = function(handler, iteratee) {
var handlerId = tui.util.stamp(handler),
eachById = this._eachCtxHandlerItemByContainId;
CustomEvents.prototype._safeContext = function() {
var context = this.contexts;
this._eachCtxEvents(function(ctxEventsItem, eventKey) {
eachById(ctxEventsItem, handlerId, function(handlerItem, handlerItemId) {
iteratee(handlerItem, handlerItemId, ctxEventsItem, eventKey);
});
});
if (!context) {
context = this.contexts = [];
}
return context;
};
/**
* Execute the callback once
* for each case of when the provided context(arguments[0]) is equal to a context in ctxEventsItem.<br>
* Callback function(iteratee) is invoked with four arguments:
* - handlerItem
* - handlerItemId
* - ctxEventsItem
* - eventKey, A Name of custom event with postfix (ex - 'eventName_idx')
* @param {*} context - Context for searching
* @param {function} iteratee - Callback function
* @private
* Get index of context
* @param {object} ctx - context that used for bind custom event
* @returns {number} index of context
*/
CustomEvents.prototype._eachCtxEventByContext = function(context, iteratee) {
var contextId = tui.util.stamp(context),
eachById = this._eachCtxHandlerItemByContainId;
CustomEvents.prototype._indexOfContext = function(ctx) {
var context = this._safeContext(),
index = 0;
this._eachCtxEvents(function(ctxEventsItem, eventKey) {
eachById(ctxEventsItem, contextId, function(handlerItem, handlerItemId) {
iteratee(handlerItem, handlerItemId, ctxEventsItem, eventKey);
});
});
while (context[index]) {
if (ctx === context[index][0]) {
return index;
}
index += 1;
}
return -1;
};
/**
* Execute the callback once for each handler of ctxEventsItem of the provided eventName(arguments[0]).<br>
* Callback function(iteratee) is invoked with four arguments:
* - handlerItem
* - handlerItemId
* - ctxEventsItem
* - eventKey, A Name of custom event with postfix (ex - 'eventName_idx')
* @param {string} eventName - Custom event name
* @param {function} iteratee - Callback function
* @private
* Memorize supplied context for recognize supplied object is context or
* name: handler pair object when off()
* @param {object} ctx - context object to memorize
*/
CustomEvents.prototype._eachCtxEventByEventName = function(eventName, iteratee) {
if (!this._ctxEvents) {
CustomEvents.prototype._memorizeContext = function(ctx) {
var context, index;
if (!tui.util.isExisty(ctx)) {
return;
}
var key = this._getCtxKey(eventName),
ctxEventsItem = this._ctxEvents[key],
args;
context = this._safeContext();
index = this._indexOfContext(ctx);
tui.util.forEachOwnProperties(ctxEventsItem, function() {
args = Array.prototype.slice.call(arguments);
args.push(key);
iteratee.apply(null, args);
});
if (index > -1) {
context[index][1] += 1;
} else {
context.push([ctx, 1]);
}
};
/**********
* normal event handler
**********/
/**
* Execute the callback once
* for each handler in instance equal to the provided handler(arguments[0]).<br>
* Callback function(iteratee) is invoked with five arguments:
* - handlerItem
* - index of handlerItem array
* - eventList by handler
* - eventKey, A Name of custom event with postfix (ex - 'eventName_idx')
* - decrease, A special callback function that decreases the length of array.
* @param {function} handler - A handler for searching
* @param {function} iteratee - Callback function
* @private
* Forget supplied context object
* @param {object} ctx - context object to forget
*/
CustomEvents.prototype._eachEventByHandler = function(handler, iteratee) {
var events = this._events,
forEachArrayDecrease = this._forEachArraySplice,
idx = 0;
CustomEvents.prototype._forgetContext = function(ctx) {
var context, contextIndex;
tui.util.forEachOwnProperties(events, function(eventList, eventKey) {
forEachArrayDecrease(eventList, function(handlerItem, index, eventList, decrease) {
if (handlerItem.fn === handler) {
iteratee(handlerItem, idx, eventList, eventKey, decrease);
idx += 1;
}
});
});
};
/**
* Execute the callback once for each handler of normal events of the provided eventName.<br>
* Callback function(iteratee) is invoked with four arguments:
* - handler
* - index of handler-list
* - handler-list
* - decrease, A special callback function that decreases the length of array
* @param {string} eventName - Custom event name
* @param {function} iteratee - Callback function
* @private
*/
CustomEvents.prototype._eachEventByEventName = function(eventName, iteratee) {
var events;
if (!this._events) {
if (!tui.util.isExisty(ctx)) {
return;
}
events = this._events[eventName];
if (!tui.util.isExisty(events)) {
return;
context = this._safeContext();
contextIndex = this._indexOfContext(ctx);
if (contextIndex > -1) {
context[contextIndex][1] -= 1;
if (context[contextIndex][1] <= 0) {
context.splice(contextIndex, 1);
}
}
this._forEachArraySplice(events, iteratee);
};
/**
* Return a new key for saving a handler with a context in event name.
* @param {string} eventName A event name
* @returns {string} Key
* 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._getCtxKey = function(eventName) {
return eventName + '_idx';
CustomEvents.prototype._bindEvent = function(eventName, handler, context) {
var events = this._safeEvent(eventName);
this._memorizeContext(context);
events.push(this._getHandlerItem(handler, context));
};
/**
* Return a new key for saving length of handlers in event name.
* @param {string} eventName A event name
* @returns {string} Key
* @private
* 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
* @example
* // 1. Basic
* customEvent.on('onload', handler);
*
* // 2. With context
* customEvent.on('onload', handler, myObj);
*
* // 3. Bind by object that name, handler pairs
* customEvent.on({
* 'play': handler,
* 'pause': handler2
* });
*
* // 4. Bind by object that name, handler pairs with context object
* customEvent.on({
* 'play': handler
* }, myObj);
*/
CustomEvents.prototype._getCtxLenKey = function(eventName) {
return eventName + '_len';
CustomEvents.prototype.on = function(eventName, handler, context) {
var self = this;
if (tui.util.isString(eventName)) {
// [syntax 1, 2]
eventName = eventName.split(R_EVENTNAME_SPLIT);
tui.util.forEach(eventName, function(name) {
self._bindEvent(name, handler, context);
});
} else if (tui.util.isObject(eventName)) {
// [syntax 3, 4]
context = handler;
tui.util.forEach(eventName, function(func, name) {
self.on(name, func, context);
});
}
};
/**
* Return a new key for storing to ctxEventsItem.
* @param {function} func A event handler
* @param {*} ctx A context in handler
* @returns {string} Key
* @private
* 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._getHandlerKey = function(func, ctx) {
return tui.util.stamp(func) + '_' + tui.util.stamp(ctx);
CustomEvents.prototype.once = function(eventName, handler, context) {
var self = this;
if (tui.util.isObject(eventName)) {
context = handler;
tui.util.forEach(eventName, function(func, name) {
self.once(name, func, context);
});
return;
}
function onceHandler() {
handler.apply(context, arguments);
self.off(eventName, onceHandler, context);
}
this.on(eventName, onceHandler, context);
};
/**
* Set the length of handlers in ctxEventsItem.
* @param {string} lenKey - A key for saving the length of handlers in `this._ctxEvents`
* @param {number} change - A variation value of length
* Splice supplied array by callback result
* @param {array} arr - array to splice
* @param {function} predicate - function return boolean
* @private
*/
CustomEvents.prototype._setCtxLen = function(lenKey, change) {
var events = this._ctxEvents;
CustomEvents.prototype._spliceMatches = function(arr, predicate) {
var i, len;
if (!tui.util.isExisty(events[lenKey])) {
events[lenKey] = 0;
if (!tui.util.isArray(arr)) {
return;
}
events[lenKey] += change;
for (i = 0, len = arr.length; i < len; i += 1) {
if (predicate(arr[i]) === true) {
arr.splice(i, 1);
len -= 1;
i -= 1;
}
}
};
/**
* Store a {handlerItem} to instance.
* @param {string} eventName - Custom event name
* @param {*} context - Context for binding
* @param {function} handler - Handler function
* Get matcher for unbind specific handler events
* @param {function} handler - handler function
* @returns {function} handler matcher
* @private
*/
CustomEvents.prototype._addCtxEvent = function(eventName, context, handler) {
var events = this._ctxEvents,
key = this._getCtxKey(eventName),
event;
CustomEvents.prototype._matchHandler = function(handler) {
var self = this;
if (!tui.util.isExisty(events)) {
events = this._ctxEvents = {};
}
return function(item) {
var needRemove = handler === item.handler;
event = events[key];
if (!tui.util.isExisty(event)) {
event = events[key] = {};
}
if (needRemove) {
self._forgetContext(item.context);
}
var lenKey = this._getCtxLenKey(eventName),
handlerItemId = this._getHandlerKey(handler, context);
event[handlerItemId] = {
fn: handler,
ctx: context
return needRemove;
};
this._setCtxLen(lenKey, +1);
};
/**
* Store a event handler without context to instance.
* @param {string} eventName - Custom event name
* @param {function} handler - Handler function
* Get matcher for unbind specific context events
* @param {object} context - context
* @returns {function} object matcher
* @private
*/
CustomEvents.prototype._addNormalEvent = function(eventName, handler) {
var events = this._events,
event;
CustomEvents.prototype._matchContext = function(context) {
var self = this;
if (!tui.util.isExisty(events)) {
events = this._events = {};
}
return function(item) {
var needRemove = context === item.context;
event = events[eventName];
if (!tui.util.isExisty(event)) {
event = events[eventName] = [];
}
if (needRemove) {
self._forgetContext(item.context);
}
event.push({ fn: handler });
return needRemove;
};
};
/**
* Take the event handler off by handler(arguments[0])
* @param {function} handler - Handler for offing
* 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._offByHandler = function(handler) {
var ctxEvents = this._ctxEvents,
lenKey;
CustomEvents.prototype._matchHandlerAndContext = function(handler, context) {
var self = this;
this._eachCtxEventByHandler(handler, function(handlerItem, hanId, ctxItems, eventKey) {
lenKey = eventKey.replace('_idx', '_len');
delete ctxItems[hanId];
ctxEvents[lenKey] -= 1;
});
return function(item) {
var matchHandler = (handler === item.handler),
matchContext = (context === item.context),
needRemove = (matchHandler && matchContext);
this._eachEventByHandler(handler, function(handlerItem, index, items, eventKey, decrease) {
items.splice(index, 1);
decrease();
});
if (needRemove) {
self._forgetContext(item.context);
}
return needRemove;
};
};
/**
* Take the event handler off by context with event name
* @param {*} context - Context
* @param {(string|function)} [eventName] - Custom event name
* Unbind event by event name
* @param {string} eventName - custom event name to unbind
* @param {function} [handler] - handler function
* @private
*/
CustomEvents.prototype._offByContext = function(context, eventName) {
var ctxEvents = this._ctxEvents,
hasArgs = tui.util.isExisty(eventName),
matchEventName,
matchHandler,
lenKey;
CustomEvents.prototype._offByEventName = function(eventName, handler) {
var self = this,
forEach = tui.util.forEachArray,
andByHandler = tui.util.isFunction(handler),
matchHandler = self._matchHandler(handler);
this._eachCtxEventByContext(context, function(handlerItem, hanId, ctxItems, eventKey) {
lenKey = eventKey.replace('_idx', '_len');
eventName = eventName.split(R_EVENTNAME_SPLIT);
matchEventName = hasArgs && tui.util.isString(eventName) && eventKey.indexOf(eventName) > -1;
matchHandler = hasArgs && tui.util.isFunction(eventName) && handlerItem.fn === eventName;
forEach(eventName, function(name) {
var handlerItems = self._safeEvent(name);
if (!hasArgs || (matchEventName || matchHandler)) {
delete ctxItems[hanId];
ctxEvents[lenKey] -= 1;
if (andByHandler) {
self._spliceMatches(handlerItems, matchHandler);
} else {
forEach(handlerItems, function(item) {
self._forgetContext(item.context);
});
self.events[name] = [];
}

@@ -486,85 +394,45 @@ });

/**
* Take the event handler off by event name with handler
* @param {string} eventName - Custom event name
* @param {function} [handler] - Event handler
* Unbind event by handler function
* @param {function} handler - handler function
* @private
*/
CustomEvents.prototype._offByEventName = function(eventName, handler) {
var ctxEvents = this._ctxEvents,
hasHandler = tui.util.isExisty(handler),
lenKey;
CustomEvents.prototype._offByHandler = function(handler) {
var self = this,
matchHandler = this._matchHandler(handler);
this._eachCtxEventByEventName(eventName, function(handlerItem, hanId, ctxItems, eventKey) {
lenKey = eventKey.replace('_idx', '_len');
if (!hasHandler || (hasHandler && handlerItem.fn === handler)) {
delete ctxItems[hanId];
ctxEvents[lenKey] -= 1;
}
tui.util.forEach(this._safeEvent(), function(handlerItems) {
self._spliceMatches(handlerItems, matchHandler);
});
this._eachEventByEventName(eventName, function(handlerItem, index, items, decrease) {
if (!hasHandler || (hasHandler && handlerItem.fn === handler)) {
items.splice(index, 1);
decrease();
}
});
};
/**********
* public
**********/
/**
* Attach the event handler with event name and context.
* @param {(string|{name:string, handler:function})} eventName - Custom event name or an object {eventName: handler}
* @param {(function|*)} [handler] - Handler function or context
* @param {*} [context] - Context for binding
* @example
* // 1. Basic
* customEvent.on('onload', handler);
*
* // 2. With context
* customEvent.on('onload', handler, myObj);
*
* // 3. Attach with an object
* customEvent.on({
* 'play': handler,
* 'pause': handler2
* });
*
* // 4. Attach with an object with context
* customEvent.on({
* 'play': handler
* }, myObj);
* 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.on = function(eventName, handler, context) {
var eventNameList;
CustomEvents.prototype._offByObject = function(obj, handler) {
var self = this,
matchFunc;
if (tui.util.isObject(eventName)) {
// {eventName: handler}
context = handler;
tui.util.forEachOwnProperties(eventName, function(handler, name) {
this.on(name, handler, context);
}, this);
return;
} else if (tui.util.isString(eventName) && eventName.indexOf(' ') > -1) {
// processing of multiple events by split event name
eventNameList = eventName.split(' ');
tui.util.forEachArray(eventNameList, function(name) {
this.on(name, handler, context);
}, this);
return;
}
if (this._indexOfContext(obj) < 0) {
tui.util.forEach(obj, function(func, name) {
self.off(name, func);
});
} else if (tui.util.isString(handler)) {
matchFunc = this._matchContext(obj);
var ctxId;
self._spliceMatches(this._safeEvent(handler), matchFunc);
} else if (tui.util.isFunction(handler)) {
matchFunc = this._matchHandlerAndContext(handler, obj);
if (tui.util.isExisty(context)) {
ctxId = tui.util.stamp(context);
}
tui.util.forEach(this._safeEvent(), function(handlerItems) {
self._spliceMatches(handlerItems, matchFunc);
});
} else {
matchFunc = this._matchContext(obj);
if (tui.util.isExisty(ctxId)) {
this._addCtxEvent(eventName, context, handler);
} else {
this._addNormalEvent(eventName, handler);
tui.util.forEach(this._safeEvent(), function(handlerItems) {
self._spliceMatches(handlerItems, matchFunc);
});
}

@@ -574,17 +442,18 @@ };

/**
* Detach the event handler.
* @param {(string|{name:string, handler:function})} eventName - Custom event name or an object {eventName: handler}
* @param {function} [handler] Handler function
* 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. off by context
* customEvent.off(myObj);
*
* // 2. off by event name
* // 1. off by event name
* customEvent.off('onload');
*
* // 2. off by event name and handler
* customEvent.off('play', handler);
*
* // 3. off by handler
* customEvent.off(handler);
*
* // 4. off by event name and handler
* customEvent.off('play', handler);
* // 4. off by context
* customEvent.off(myObj);
*

@@ -607,28 +476,15 @@ * // 5. off by context and handler

CustomEvents.prototype.off = function(eventName, handler) {
if (!arguments.length) {
// 8. off the all events
this._events = null;
this._ctxEvents = null;
return;
}
if (tui.util.isFunction(eventName)) {
// 3. off by handler
if (tui.util.isString(eventName)) {
// [syntax 1, 2]
this._offByEventName(eventName, handler);
} else if (!arguments.length) {
// [syntax 8]
this.events = {};
this.contexts = [];
} else if (tui.util.isFunction(eventName)) {
// [syntax 3]
this._offByHandler(eventName);
} else if (tui.util.isObject(eventName)) {
if (tui.util.hasStamp(eventName)) {
// 1, 5, 6 off by context
this._offByContext(eventName, handler);
} else {
// 4. off by an Object.<string, function>
tui.util.forEachOwnProperties(eventName, function(handler, name) {
this.off(name, handler);
}, this);
}
} else {
// 2, 4 off by event name
this._offByEventName(eventName, handler);
// [syntax 4, 5, 6]
this._offByObject(eventName, handler);
}

@@ -638,35 +494,18 @@ };

/**
* Return a count of events registered.
* @param {string} eventName - Custom event name
* @returns {*}
* Fire custom event
* @param {string} eventName - name of custom event
*/
CustomEvents.prototype.getListenerLength = function(eventName) {
var ctxEvents = this._ctxEvents,
events = this._events,
existy = tui.util.isExisty,
lenKey = this._getCtxLenKey(eventName);
var normal = (existy(events) && tui.util.isArray(events[eventName])) ? events[eventName].length : 0,
ctx = (existy(ctxEvents) && existy(ctxEvents[lenKey])) ? ctxEvents[lenKey] : 0;
return normal + ctx;
CustomEvents.prototype.fire = function(eventName) { // eslint-disable-line
this.invoke.apply(this, arguments);
};
/**
* Return whether at least one of the handlers is registered in the given event name.
* 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
* @returns {boolean} Is there at least one handler in event name?
*/
CustomEvents.prototype.hasListener = function(eventName) {
return this.getListenerLength(eventName) > 0;
};
/**
* Fire a event and returns the result of operation 'boolean AND' with all listener's results.<br>
* So, It is different from {@link CustomEvents#fire}.<br>
* 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

@@ -683,3 +522,4 @@ * @returns {boolean} The result of operation 'boolean AND'

* 'beforeZoom': function() {
* if (that.disabled && this.getState()) { // It should cancel the 'zoom' event by some conditions.
* // It should cancel the 'zoom' event by some conditions.
* if (that.disabled && this.getState()) {
* return false;

@@ -691,3 +531,5 @@ * }

*/
CustomEvents.prototype.invoke = function(eventName, data) {
CustomEvents.prototype.invoke = function(eventName) {
var events, args, index, item;
if (!this.hasListener(eventName)) {

@@ -697,65 +539,40 @@ return true;

var args = Array.prototype.slice.call(arguments, 1),
self = this,
result = true,
existy = tui.util.isExisty;
events = this._safeEvent(eventName);
args = Array.prototype.slice.call(arguments, 1);
index = 0;
this._eachEventByEventName(eventName, function(item) {
if (existy(item) && item.fn.apply(self, args) === false) {
result = false;
}
});
while (events[index]) {
item = events[index];
this._eachCtxEventByEventName(eventName, function(item) {
if (existy(item) && item.fn.apply(item.ctx, args) === false) {
result = false;
if (item.handler.apply(item.context, args) === false) {
return false;
}
});
return result;
index += 1;
}
return true;
};
/**
* Fire a event by event name with data.
* Return whether at least one of the handlers is registered in the given
* event name.
* @param {string} eventName - Custom event name
* @param {...*} data - Data for event
* @return {Object} this
* @example
* instance.on('move', function(direction) {
* var direction = direction;
* });
* instance.fire('move', 'left');
* @returns {boolean} Is there at least one handler in event name?
*/
CustomEvents.prototype.fire = function(eventName, data) {
this.invoke.apply(this, arguments);
return this;
CustomEvents.prototype.hasListener = function(eventName) {
return this.getListenerLength(eventName) > 0;
};
/**
* Attach a one-shot event.
* @param {(object|string)} eventName - Custom event name or an object {eventName: handler}
* @param {function} fn - Handler function
* @param {*} [context] - Context for binding
* Return a count of events registered.
* @param {string} eventName - Custom event name
* @returns {number} number of event
*/
CustomEvents.prototype.once = function(eventName, fn, context) {
var that = this;
if (tui.util.isObject(eventName)) {
tui.util.forEachOwnProperties(eventName, function(handler, eventName) {
this.once(eventName, handler, fn);
}, this);
return;
}
function onceHandler() {
fn.apply(context, arguments);
that.off(eventName, onceHandler, context);
}
this.on(eventName, onceHandler, context);
CustomEvents.prototype.getListenerLength = function(eventName) {
var events = this._safeEvent(eventName);
return events.length;
};
tui.util.CustomEvents = CustomEvents;
})(window.tui);

@@ -65,5 +65,5 @@ /**

obj = props.init || function(){};
obj = props.init || function() {};
if(parent) {
if (parent) {
tui.util.inherit(obj, parent);

@@ -73,4 +73,4 @@ }

if (props.hasOwnProperty('static')) {
tui.util.extend(obj, props.static);
delete props.static;
tui.util.extend(obj, props['static']);
delete props['static'];
}

@@ -82,3 +82,2 @@

};
})(window.tui);
/**
* @fileoverview Define module
* @author NHN Ent.
* FE Development Team <e0242@nhnent.com>
* FE Development Team <dl_javscript@nhnent.com>
* @dependency type.js, defineNamespace.js

@@ -47,8 +47,7 @@ */

base[INITIALIZATION_METHOD_NAME]();
delete base[INITIALIZATION_METHOD_NAME];
}
return util.defineNamespace(namespace, base, true);
return util.defineNamespace(namespace, base);
}
tui.util.defineModule = defineModule;
})(window.tui);

@@ -19,11 +19,14 @@ /**

var util = tui.util;
/**
* Define namespace
* @param {string} name - Module name
* @param {string} namespace - Namespace (ex- 'foo.bar.baz')
* @param {(object|function)} props - A set of modules or one module
* @param {boolean} isOverride flag - What if module already define, override or not
* @param {boolean} [isOverride] - Override the props to the namespace.<br>
* (It removes previous properties of this namespace)
* @returns {(object|function)} Defined namespace
* @memberof tui.util
* @example
* var neComp = defineNamespace('ne.component');
* var neComp = tui.util.defineNamespace('ne.component');
* neComp.listMenu = tui.util.defineClass({

@@ -35,17 +38,9 @@ * init: function() {

*/
var defineNamespace = function(name, props, isOverride) {
var namespace,
lastspace,
result,
module = getNamespace(name);
tui.util.defineNamespace = function(namespace, props, isOverride) {
var names, result, prevLast, last;
if (!isOverride && isValidType(module)) {
return module;
}
names = namespace.split('.');
names.unshift(window);
namespace = name.split('.');
lastspace = namespace.pop();
namespace.unshift(window);
result = tui.util.reduce(namespace, function(obj, name) {
result = util.reduce(names, function(obj, name) {
obj[name] = obj[name] || {};

@@ -55,37 +50,12 @@ return obj[name];

result[lastspace] = isValidType(props) ? props : {};
if (isOverride) {
last = names.pop();
prevLast = util.pick.apply(null, names);
result = prevLast[last] = props;
} else {
util.extend(result, props);
}
return result[lastspace];
};
/**
* Get namespace
* @param {string} name - namespace
* @returns {*}
*/
var getNamespace = function(name) {
var namespace,
result;
namespace = name.split('.');
namespace.unshift(window);
result = tui.util.reduce(namespace, function(obj, name) {
return obj && obj[name];
});
return result;
};
/**
* Check valid type
* @param {*} module
* @returns {boolean}
*/
var isValidType = function(module) {
return (tui.util.isObject(module) || tui.util.isFunction(module));
};
tui.util.defineNamespace = defineNamespace;
})(window.tui);

@@ -5,3 +5,3 @@ /**

* FE Development Team <e0242@nhnent.com>
* @dependency type.js
* @dependency type.js, object.js
*/

@@ -12,76 +12,76 @@

var tokens = /[\\]*YYYY|[\\]*YY|[\\]*MMMM|[\\]*MMM|[\\]*MM|[\\]*M|[\\]*DD|[\\]*D|[\\]*HH|[\\]*H|[\\]*A/gi,
MONTH_STR = ["Invalid month", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
MONTH_DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
replaceMap = {
M: function(date) {
return Number(date.month);
},
MM: function(date) {
var month = date.month;
return (Number(month) < 10) ? '0' + month : month;
},
MMM: function(date) {
return MONTH_STR[Number(date.month)].substr(0, 3);
},
MMMM: function(date) {
return MONTH_STR[Number(date.month)];
},
D: function(date) {
return Number(date.date);
},
d: function(date) {
return replaceMap.D(date);
},
DD: function(date) {
var dayInMonth = date.date;
return (Number(dayInMonth) < 10) ? '0' + dayInMonth : dayInMonth;
},
dd: function(date) {
return replaceMap.DD(date);
},
YY: function(date) {
return Number(date.year) % 100;
},
yy: function(date) {
return replaceMap.YY(date);
},
YYYY: function(date) {
var prefix = '20',
year = date.year;
if (year > 69 && year < 100) {
prefix = '19';
}
return (Number(year) < 100) ? prefix + String(year) : year;
},
yyyy: function(date) {
return replaceMap.YYYY(date);
},
A: function(date) {
return date.meridian;
},
a: function(date) {
return date.meridian.toLowerCase();
},
hh: function(date) {
var hour = date.hour;
return (Number(hour) < 10) ? '0' + hour : hour;
},
HH: function(date) {
return replaceMap.hh(date);
},
h: function(date) {
return String(Number(date.hour));
},
H: function(date) {
return replaceMap.h(date);
},
m: function(date) {
return String(Number(date.minute));
},
mm: function(date) {
var minute = date.minute;
return (Number(minute) < 10) ? '0' + minute : minute;
var tokens = /[\\]*YYYY|[\\]*YY|[\\]*MMMM|[\\]*MMM|[\\]*MM|[\\]*M|[\\]*DD|[\\]*D|[\\]*HH|[\\]*H|[\\]*A/gi;
var MONTH_STR = ["Invalid month", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var MONTH_DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var replaceMap = {
M: function(date) {
return Number(date.month);
},
MM: function(date) {
var month = date.month;
return (Number(month) < 10) ? '0' + month : month;
},
MMM: function(date) {
return MONTH_STR[Number(date.month)].substr(0, 3);
},
MMMM: function(date) {
return MONTH_STR[Number(date.month)];
},
D: function(date) {
return Number(date.date);
},
d: function(date) {
return replaceMap.D(date);
},
DD: function(date) {
var dayInMonth = date.date;
return (Number(dayInMonth) < 10) ? '0' + dayInMonth : dayInMonth;
},
dd: function(date) {
return replaceMap.DD(date);
},
YY: function(date) {
return Number(date.year) % 100;
},
yy: function(date) {
return replaceMap.YY(date);
},
YYYY: function(date) {
var prefix = '20',
year = date.year;
if (year > 69 && year < 100) {
prefix = '19';
}
};
return (Number(year) < 100) ? prefix + String(year) : year;
},
yyyy: function(date) {
return replaceMap.YYYY(date);
},
A: function(date) {
return date.meridiem;
},
a: function(date) {
return date.meridiem;
},
hh: function(date) {
var hour = date.hour;
return (Number(hour) < 10) ? '0' + hour : hour;
},
HH: function(date) {
return replaceMap.hh(date);
},
h: function(date) {
return String(Number(date.hour));
},
H: function(date) {
return replaceMap.h(date);
},
m: function(date) {
return String(Number(date.minute));
},
mm: function(date) {
var minute = date.minute;
return (Number(minute) < 10) ? '0' + minute : minute;
}
};

@@ -136,14 +136,15 @@ /* istanbul ignore if */

* @param {Date|Object} date - Date object
* @param {{meridiemSet: {AM: string, PM: string}}} option - Option
* @returns {boolean|string} A transformed string or false.
* @memberOf tui.util
* @example
* // key | Shorthand
* // ------------|-----------------------
* // years | YY / YYYY / yy / yyyy
* // months(n) | M / MM
* // months(str) | MMM / MMMM
* // days | D / DD / d / dd
* // hours | H / HH / h / hh
* // minutes | m / mm
* // AM/PM | A / a
* // key | Shorthand
* // --------------- |-----------------------
* // years | YY / YYYY / yy / yyyy
* // months(n) | M / MM
* // months(str) | MMM / MMMM
* // days | D / DD / d / dd
* // hours | H / HH / h / hh
* // minutes | m / mm
* // meridiem(AM,PM) | A / a
*

@@ -170,7 +171,16 @@ * var dateStr1 = formatDate('yyyy-MM-dd', {

* alert(dateStr3); // '2010년 3월 13일'
*
* var option4 = {
* meridiemSet: {
* AM: '오전',
* PM: '오후'
* }
* };
* var date4 = {year: 1999, month: 9, date: 9, hour: 13, minute: 2};
* var dateStr4 = formatDate('yyyy-MM-dd A hh:mm', date4, option4));
*
* alert(dateStr4); // '1999-09-09 오후 01:02'
*/
function formatDate(form, date) {
var meridian,
nDate,
resultStr;
function formatDate(form, date, option) {
var meridiem, nDate, resultStr;

@@ -199,15 +209,21 @@ if (tui.util.isDate(date)) {

nDate.meridian = '';
if (/[^\\][aA]\b/g.test(form)) {
meridian = (nDate.hour > 12) ? 'PM' : 'AM';
nDate.hour %= 12;
nDate.meridian = meridian;
nDate.meridiem = '';
if (/([^\\]|^)[aA]\b/.test(form)) {
meridiem = (nDate.hour > 11) ?
tui.util.pick(option, 'meridiemSet', 'PM') || 'PM'
: tui.util.pick(option, 'meridiemSet', 'AM') || 'AM';
if (nDate.hour > 12) { //See the clock system: https://en.wikipedia.org/wiki/12-hour_clock
nDate.hour %= 12;
}
if (nDate.hour === 0) {
nDate.hour = 12;
}
nDate.meridiem = meridiem;
}
resultStr = form.replace(tokens, function(key) {
if (key.indexOf('\\') > -1) {
return key.replace(/\\/g, '');
} else {
return replaceMap[key](nDate) || '';
if (key.indexOf('\\') > -1) { // escape character
return key.replace(/\\/, '');
}
return replaceMap[key](nDate) || '';
});

@@ -219,2 +235,1 @@ return resultStr;

})(window.tui);

@@ -56,3 +56,3 @@ /**

function hasEncodableString(string) {
return /[<>&"']/.test(string);
return (/[<>&"']/).test(string);
}

@@ -59,0 +59,0 @@

@@ -1,2 +0,2 @@

describe('CustomEvents2', function() {
describe('CustomEvents', function() {
var CustomEvents = tui.util.CustomEvents,

@@ -9,384 +9,303 @@ ce;

describe('_forEachArraySplice()', function() {
var arr,
result,
count;
describe('should listen other object\'s event', function() {
var handler;
beforeEach(function() {
arr = [1, 2, 3, 4, 5];
result = [];
count = 0;
handler = jasmine.createSpy('handler');
});
it('forEach와 같지만 전체 순회 수를 감소시키는 메서드를 제공한다', function() {
ce._forEachArraySplice(arr, function(num, index, arr, decrease) {
if (num % 2 === 0) {
decrease();
}
count += 1;
it('by name, handler function.', function() {
ce.on('test', handler);
expect(ce.events).toEqual({
test: [{handler: handler}]
});
expect(arr).toEqual([1, 3, 5]);
expect(count).toBe(5);
});
function handler2() {}
ce.on('test', handler2);
it('decrease를 사용하면 전체 순회 수를 감소시킨다', function() {
var arr = ['mike', 'jane', 'mike', 'foo', 'bar'];
ce._forEachArraySplice(arr, function(name, i, arr, decrease) {
if (name === 'mike') {
decrease();
}
expect(ce.events).toEqual({
test: [
{handler: handler},
{handler: handler2}
]
});
expect(arr).toEqual(['jane', 'foo', 'bar']);
});
});
// double whitespace
ce.on('multiple multiple2', handler);
describe('_eachCtxEventByHandler()', function() {
var myObj,
myObj2,
handler,
handler2,
spy;
expect(ce.events).toEqual({
test: [
{handler: handler},
{handler: handler2}
],
multiple: [{handler: handler}],
multiple2: [{handler: handler}]
});
expect(ce.contexts).toBe(null);
beforeEach(function() {
myObj = { name: 'good' };
myObj2 = { name: 'cony' };
handler = function() { return this.name; };
handler2 = function() {};
ce.on('a b c', handler);
ce.on('play', handler, myObj);
ce.on('play', handler2, myObj);
ce.on('play', handler2);
// 일반 이벤트도 등록해본다
ce.on('play', function() {});
ce.on('play', handler2, myObj2);
spy = jasmine.createSpy('playHandler');
expect(ce.events).toEqual(jasmine.objectContaining({
a: [{handler: handler}],
b: [{handler: handler}],
c: [{handler: handler}]
}));
});
it('컨텍스트 핸들러를 순회한다', function() {
ce._eachCtxEventByHandler(handler2, spy);
it('by name, handler, context object.', function() {
var obj = {};
ce.on('test', handler, obj);
expect(spy.calls.count()).toBe(2);
expect(spy.calls.argsFor(0)).toEqual([
{ fn: handler2, ctx: myObj },
ce._getHandlerKey(handler2, myObj),
ce._ctxEvents['play_idx'],
'play_idx'
]);
expect(spy.calls.argsFor(1)).toEqual([
{ fn: handler2, ctx: myObj2 },
ce._getHandlerKey(handler2, myObj2),
ce._ctxEvents['play_idx'],
'play_idx'
]);
});
});
expect(ce.events).toEqual({
test: [{handler: handler, context: obj}]
});
describe('_eachCtxEventByContext()', function() {
var handler,
handler2,
myObj,
myObj2,
spy;
ce.on('multi multi2', handler, obj);
beforeEach(function() {
handler = function() { return this.name; };
handler2 = function() {};
myObj = { name: 'cony' };
myObj2 = { name: 'good' };
ce.on('play', handler, myObj);
ce.on('play', handler2, myObj);
ce.on('play', handler, myObj2);
spy = jasmine.createSpy('play');
expect(ce.events).toEqual({
test: [{handler: handler, context: obj}],
multi: [{handler: handler, context: obj}],
multi2: [{handler: handler, context: obj}]
});
expect(ce.contexts).toEqual([[obj, 3]]);
});
it('컨텍스트를 기준으로 핸들러를 순회', function() {
ce._eachCtxEventByContext(myObj, spy);
it('by {name: handler} pair objects.', function() {
function handler2() {}
expect(spy.calls.count()).toBe(2);
expect(spy.calls.argsFor(0)).toEqual([
{ fn: handler, ctx: myObj },
ce._getHandlerKey(handler, myObj),
ce._ctxEvents['play_idx'],
'play_idx'
]);
expect(spy.calls.argsFor(1)).toEqual([
{ fn: handler2, ctx: myObj },
ce._getHandlerKey(handler2, myObj),
ce._ctxEvents['play_idx'],
'play_idx'
]);
});
});
ce.on({
'test': handler,
'test2': handler2
});
describe('_eachCtxEventByEventName()', function() {
var handler,
handler2,
myObj,
myObj2,
spy;
expect(ce.events).toEqual({
test: [{handler: handler}],
test2: [{handler: handler2}]
});
beforeEach(function() {
handler = function() { return this.name; };
handler2 = function() {};
myObj = { name: 'cony' };
myObj2 = { name: 'good' };
ce.on({'test3': handler});
ce.on({'test3': handler2});
ce.on('play', handler, myObj);
ce.on('play', handler2, myObj);
ce.on('play', handler, myObj2);
ce.on('pause', handler);
expect(ce.events).toEqual({
test: [{handler: handler}],
test2: [{handler: handler2}],
test3: [{handler: handler}, {handler: handler2}]
});
spy = jasmine.createSpy('play');
});
// double whitespace
ce.on({'multi multi2': handler});
it('이벤트명 기준으로 핸들러를 순회', function() {
ce._eachCtxEventByEventName('play', spy);
expect(spy.calls.count()).toBe(3);
expect(spy.calls.argsFor(0)).toEqual([
{ fn: handler, ctx: myObj },
ce._getHandlerKey(handler, myObj),
ce._ctxEvents['play_idx'],
'play_idx'
]);
expect(spy.calls.argsFor(1)).toEqual([
{ fn: handler2, ctx: myObj },
ce._getHandlerKey(handler2, myObj),
ce._ctxEvents['play_idx'],
'play_idx'
]);
expect(spy.calls.argsFor(2)).toEqual([
{ fn: handler, ctx: myObj2 },
ce._getHandlerKey(handler, myObj2),
ce._ctxEvents['play_idx'],
'play_idx'
]);
expect(ce.events).toEqual({
test: [{handler: handler}],
test2: [{handler: handler2}],
test3: [{handler: handler}, {handler: handler2}],
multi: [{handler: handler}],
multi2: [{handler: handler}]
});
});
});
describe('_eachEventByHandler()', function() {
var myObj,
myObj2,
handler,
handler2,
spy;
it('by {name: handler} pair object, context object.', function() {
var obj = {};
var obj2 = {};
function handler2() {}
beforeEach(function() {
myObj = { name: 'good' };
myObj2 = { name: 'cony' };
handler = function() { return this.name; };
handler2 = function() {};
ce.on({
'test': handler,
'test2': handler2
}, obj);
ce.on('play', handler, myObj);
ce.on('play', handler2, myObj);
ce.on('play', handler2);
expect(ce.events).toEqual({
'test': [{handler: handler, context: obj}],
'test2': [{handler: handler2, context: obj}]
});
expect(ce.contexts).toEqual([[obj, 2]]);
// 일반 이벤트도 등록해본다
ce.on('play', handler);
ce.on({'test': handler}, obj);
spy = jasmine.createSpy('playHandler');
});
expect(ce.events).toEqual({
'test': [
{handler: handler, context: obj},
{handler: handler, context: obj}
],
'test2': [{handler: handler2, context: obj}]
});
expect(ce.contexts).toEqual([[obj, 3]]);
it('일반 이벤트 핸들러를 순회한다', function() {
ce._eachEventByHandler(handler, spy);
ce.on({'multi multi2': handler}, obj2);
expect(spy.calls.count()).toBe(1);
expect(spy.calls.argsFor(0)).toEqual([
{ fn: handler },
0,
ce._events['play'],
'play',
spy.calls.argsFor(0)[4]
]);
expect(ce.events).toEqual({
test: [
{handler: handler, context: obj},
{handler: handler, context: obj}
],
test2: [{handler: handler2, context: obj}],
multi: [{handler: handler, context: obj2}],
multi2: [{handler: handler, context: obj2}]
});
expect(ce.contexts).toEqual([[obj, 3], [obj2, 2]]);
});
});
describe('_eachEventByEventName()', function() {
var handler,
handler2,
myObj,
spy;
describe('should stop listen other object\'s event', function() {
var spy,
spy2,
obj,
obj2,
ce;
beforeEach(function() {
handler = function() {};
handler2 = function() {};
myObj = {};
spy = jasmine.createSpy('off');
spy2 = jasmine.createSpy('last');
ce = new CustomEvents();
obj = {};
obj2 = {};
});
ce.on('play', handler);
ce.on('play', handler2);
ce.on('play', function() {}, myObj);
spy = jasmine.createSpy('play');
it('exceptional situtaions.', function() {
expect(function() {
ce.off('good');
}).not.toThrow();
});
it('이벤트명으로 일반 이벤트를 순회하며 반복자를 수행한다', function() {
ce._eachEventByEventName('play', spy);
it('by name.', function() {
ce.on('play', spy, obj);
ce.off('play');
expect(spy.calls.count()).toBe(2);
expect(spy.calls.argsFor(0)).toEqual([
{ fn: handler },
0,
ce._events['play'],
spy.calls.argsFor(0)[3]
]);
expect(spy.calls.argsFor(1)).toEqual([
{ fn: handler2 },
1,
ce._events['play'],
spy.calls.argsFor(1)[3]
]);
expect(ce.events).toEqual({'play': []});
expect(ce.contexts.length).toBe(0);
});
it('by handler function.', function() {
ce.on('play', spy);
ce.off(spy);
});
expect(ce.events).toEqual({'play': []});
});
describe('_offByHandler()', function() {
var handler,
handler2,
myObj;
it('by event name and handler function.', function() {
ce.on('play', spy, obj);
ce.on('pause', spy);
beforeEach(function() {
handler = function() { return this.name; };
handler2 = function() {};
myObj = { name: 'cony' };
ce.off('play', spy);
ce.on('play', handler, myObj);
ce.on('pause', handler2);
ce.on('play', handler2, myObj);
ce.on('play', handler);
});
expect(ce.events).toEqual({
'play': [],
'pause': [{handler: spy}]
});
it('핸들러 함수를 넘겨 이벤트를 해제할 수 있음', function() {
ce._offByHandler(handler2);
expect(ce._events['pause'].length).toBe(0);
expect(ce._events['play'].length).toBe(1);
expect(ce._ctxEvents['play_len']).toBe(1);
expect(ce.contexts).toEqual([]);
});
it('전부 제거', function() {
ce._offByHandler(handler2);
ce._offByHandler(handler);
it('by context.', function() {
ce.on('play', spy, obj);
ce.on('pause', spy);
ce.off(obj);
expect(ce._events['pause'].length).toBe(0);
expect(ce._events['play'].length).toBe(0);
expect(ce._ctxEvents['play_len']).toBe(0);
expect(ce.events).toEqual({
play: [],
pause: [{handler: spy}]
});
expect(ce.contexts.length).toBe(0);
});
});
describe('_offByContext()', function() {
var handler,
handler2,
myObj,
myObj2;
it('by context and handler.', function() {
ce.on('play', spy, obj);
ce.on('pause', spy, obj);
ce.off(obj, spy);
beforeEach(function() {
handler = function() {};
handler2 = function() {};
myObj = {};
myObj2 = {};
ce.on('play', handler, myObj);
ce.on('play', handler2, myObj);
ce.on('play', handler);
ce.on('pause', handler2, myObj2);
ce.on('play', handler, myObj2);
ce.on('pause', handler, myObj);
expect(ce.events).toEqual({
play: [],
pause: []
});
expect(ce.contexts.length).toBe(0);
});
it('컨텍스트로 이벤트를 해제할 수 있다', function() {
ce._offByContext(myObj);
it('by context and event name.', function() {
ce.on('play', spy, obj);
ce.on('play', spy, obj2);
ce.on('pause', spy, obj);
// 남은 이벤트
expect(ce._events['play'].length).toBe(1);
expect(ce._ctxEvents['play_len']).toBe(1);
expect(ce._ctxEvents['pause_len']).toBe(1);
ce.off(obj, 'pause');
// 제거된 이벤트
expect(ce._ctxEvents['play_idx'][ce._getHandlerKey(handler2, myObj)]).toBeUndefined();
expect(ce._ctxEvents['play_idx'][ce._getHandlerKey(handler, myObj)]).toBeUndefined();
expect(ce._ctxEvents['pause_idx'][ce._getHandlerKey(handler, myObj)]).toBeUndefined();
expect(ce.events).toEqual({
play: [
{handler: spy, context: obj},
{handler: spy, context: obj2}
],
pause: []
});
expect(ce.contexts.length).toBe(2);
});
it('이벤트 명을 추가로 전달해 해당하는 이벤트만 해제 가능', function() {
ce._offByContext(myObj, 'play');
it('by object with event name and handler pairs.', function() {
ce.on('play', spy, obj);
ce.on('pause', spy, obj);
ce.on('play', spy2);
ce.on('delay', spy2);
// 남은 이벤트
expect(ce._events['play'].length).toBe(1);
expect(ce._ctxEvents['play_len']).toBe(1);
expect(ce._ctxEvents['pause_len']).toBe(2);
ce.off({
'play': spy,
'pause': spy,
'delay': spy2
});
// 제거된 이벤트
expect(ce._ctxEvents['play_idx'][ce._getHandlerKey(handler, myObj)]).toBeUndefined();
expect(ce._ctxEvents['play_idx'][ce._getHandlerKey(handler2, myObj)]).toBeUndefined();
expect(ce.events).toEqual({
play: [{handler: spy2}],
pause: [],
delay: []
});
expect(ce.contexts.length).toBe(0);
});
it('핸들러 함수를 추가로 전달해 해당하는 이벤트만 제거 가능', function() {
ce._offByContext(myObj2, handler2);
it('with no arguments. then unbind all event.', function() {
ce.on('play', spy, obj);
ce.on('pause', spy, obj);
ce.on('play', spy2);
ce.on('delay', spy2);
// 남은 이벤트
expect(ce._events['play'].length).toBe(1);
expect(ce._ctxEvents['play_len']).toBe(3);
expect(ce._ctxEvents['pause_len']).toBe(1);
ce.off();
// 제거된 이벤트
expect(ce._ctxEvents['pause_idx'][ce._getHandlerKey(handler2, myObj2)]).toBeUndefined();
expect(ce.events).toEqual({});
expect(ce.contexts).toEqual([]);
});
});
describe('_offByEventName()', function() {
var handler,
handler2,
myObj,
myObj2;
describe('should fire custom event', function() {
var inst, spy;
beforeEach(function() {
handler = function() {};
handler2 = function() {};
myObj = {};
myObj2 = {};
ce.on('play', handler, myObj);
ce.on('play', handler2, myObj);
ce.on('play', handler);
ce.on('pause', handler2, myObj2);
ce.on('play', handler, myObj2);
ce.on('pause', handler, myObj);
inst = new CustomEvents();
spy = jasmine.createSpy();
});
it('이벤트명으로 이벤트를 제거한다', function() {
ce.off('play');
it('and invoke handler multiple times even if duplicated.', function() {
var obj = {};
// 남은 이벤트
expect(ce._ctxEvents['pause_len']).toBe(2);
inst.on('foo', spy);
inst.on('foo', spy);
// 제거된 이벤트
expect(ce._events['play'].length).toBe(0);
expect(ce._ctxEvents['play_len']).toBe(0);
});
inst.fire('foo');
it('핸들러를 전달해 해당하는 이벤트만 제거 가능', function() {
ce.off('play', handler);
ce.off('pause', handler2);
expect(spy.calls.count()).toBe(2);
// 남은 이벤트
expect(ce._ctxEvents['pause_len']).toBe(1);
expect(ce._ctxEvents['play_len']).toBe(1);
inst.on('bar', spy, obj);
inst.on('bar', spy, obj);
// 제거된 이벤트
expect(ce._ctxEvents['play_idx'][ce._getHandlerKey(handler, myObj)]).toBeUndefined();
expect(ce._events['play'].length).toBe(0);
inst.fire('bar');
expect(spy.calls.count()).toBe(4);
});
it('and pass arguments to each handlers.', function() {
inst.on('foo', spy);
inst.fire('foo', 'hello', 10);
expect(spy).toHaveBeenCalledWith('hello', 10);
});
});
describe('invoke()', function() {
var component,
describe('should return AND conditions for all of handler\' result', function() {
var inst,
spy;

@@ -404,698 +323,157 @@

describe('리스너의 실행결과를 AND연산하여 반환', function() {
beforeEach(function() {
component = new MockComponent();
spy = jasmine.createSpy('handler');
});
beforeEach(function() {
spy = jasmine.createSpy('handler');
inst = new MockComponent();
inst.on('zoom', spy);
});
describe('명시적으로 false를 반환하지 않으면 모두 true로 간주한다', function() {
beforeEach(function() {
component.on('zoom', spy);
});
it('빈 문자열 반환은 true로 간주', function() {
component.on('beforeZoom', function() { return ''; });
component.work();
expect(spy).toHaveBeenCalled();
});
it('undefined도 true로 간주', function() {
component.on('beforeZoom', function() { return void 0; });
component.work();
expect(spy).toHaveBeenCalled();
});
it('null도 true로 간주', function() {
component.on('beforeZoom', function() { return null; });
component.work();
expect(spy).toHaveBeenCalled();
});
describe('need return "false" explicitly for stop other event calls.', function() {
it('empty string can\'t stop event calls.', function() {
inst.on('beforeZoom', function() { return ''; });
inst.work();
expect(spy).toHaveBeenCalled();
});
describe('리스너의 실행결과를 AND연산하여 반환한다', function() {
var cnt;
beforeEach(function() {
component.on('zoom', spy);
cnt = 0;
});
it('리스너 중 하나라도 명시적 false이면 false를 반환', function() {
component.on('beforeZoom', function() { cnt += 1; return true; });
component.on('beforeZoom', function() { cnt += 1; return false; });
component.on('beforeZoom', function() { cnt += 1; return null; });
component.work();
expect(spy).not.toHaveBeenCalled();
expect(cnt).toBe(3);
});
it('그렇지 않으면 true반환', function() {
component.on('beforeZoom', function() { cnt += 1; return true; });
component.on('beforeZoom', function() { cnt += 1; return void 0; });
component.on('beforeZoom', function() { cnt += 1; });
component.work();
expect(spy).toHaveBeenCalled();
expect(cnt).toBe(3);
});
it('undefined can\'t stop event calls.', function() {
inst.on('beforeZoom', function() { return void 0; });
inst.work();
expect(spy).toHaveBeenCalled();
});
describe('리스너를 등록하지 않으면 true', function() {
beforeEach(function() {
component.on('zoom', spy);
});
it('하나도 등록하지 않았으므로 true', function() {
component.work();
expect(spy).toHaveBeenCalled();
});
it('등록했다가 제거해도 true', function() {
var falseFn = function() { return false };
component.on('beforeZoom', falseFn);
component.off('beforeZoom', falseFn);
component.work();
expect(spy).toHaveBeenCalled();
});
it('null can\' stop event calls.', function() {
inst.on('beforeZoom', function() { return null; });
inst.work();
expect(spy).toHaveBeenCalled();
});
});
});
describe('return AND condition value for result of all handlers.', function() {
it('at least one handler must return \'false\' to make invoke() return false.', function() {
inst.on('beforeZoom', function() { return true; });
inst.on('beforeZoom', function() { return false; });
inst.on('beforeZoom', function() { return null; });
describe('fire()', function() {
var component,
spyObj;
inst.work();
beforeEach(function() {
component = new tui.util.CustomEvents();
spyObj = jasmine.createSpyObj('handler', ['foo', 'bar']);
component.on({
'foo': spyObj.foo,
'bar': spyObj.bar
expect(spy).not.toHaveBeenCalled();
});
});
it('체이닝을 지원한다', function() {
component.fire('foo').fire('bar');
it('if not, invoke() will return true.', function() {
inst.on('beforeZoom', function() { return true; });
inst.on('beforeZoom', function() { return void 0; });
inst.on('beforeZoom', function() {});
expect(spyObj.foo).toHaveBeenCalled();
expect(spyObj.bar).toHaveBeenCalled();
});
inst.work();
it('호출 시 타입을 제외한 파라미터를 리스너에 전부 전달한다', function() {
component.fire('foo', { say: 'hello' }, false, 12 / 6);
expect(spyObj.foo).toHaveBeenCalledWith({ say: 'hello' }, false, 2);
});
it('호출 시 타입을 제외한 파라미터를 리스너에 전부 전달한다2', function() {
component.fire('foo', [1, 2, 3]);
expect(spyObj.foo).not.toHaveBeenCalledWith({ say: 'hello' }, false, 2);
});
describe('등록 해제 반복후 동작 확인', function() {
describe('컨텍스트를 넘기지 않을 때', function() {
beforeEach(function() {
component.off('foo', spyObj.foo);
component.on('foo', spyObj.foo);
component.fire('foo');
});
it('한번만 호출되어야 한다', function() {
expect(spyObj.foo.calls.count()).toBe(1);
});
expect(spy).toHaveBeenCalled();
});
describe('컨텍스트를 넘길 때', function() {
var myObj = {};
beforeEach(function() {
component.off('foo');
component.on('foo', spyObj.foo, myObj);
component.off('foo');
component.on('foo', spyObj.foo, myObj);
component.fire('foo');
});
it('한 번만 호출되어야 한다', function() {
expect(spyObj.foo.calls.count()).toBe(1);
});
});
});
});
var Animal = function() {};
tui.util.CustomEvents.mixin(Animal);
it('return true when no handler binded.', function() {
inst.work();
expect(spy).toHaveBeenCalled();
describe('once()', function() {
var lion,
spy;
function falseFn() { return false };
inst.on('beforeZoom', falseFn);
inst.off('beforeZoom', falseFn);
beforeEach(function() {
lion = new Animal();
spy = jasmine.createSpyObj('on', ['move', 'growl']);
});
inst.work();
describe('단발성 이벤트 등록이 가능하다', function() {
beforeEach(function() {
lion.once('move', spy.move);
lion.fire('move');
lion.fire('move');
});
it('한 번만 실행되어야 한다', function() {
expect(spy.move.calls.count()).toBe(1);
});
expect(spy).toHaveBeenCalled();
});
describe('여러 단발성 이벤트를 한번에 등록할 수 있다', function() {
beforeEach(function() {
lion.once({
'move': spy.move,
'growl': spy.growl
});
lion.fire('move');
lion.fire('move');
lion.fire('growl');
lion.fire('growl');
});
it('한 번씩만 실행되어야 한다', function() {
expect(spy.move.calls.count()).toBe(1);
expect(spy.growl.calls.count()).toBe(1);
});
});
describe('중첩하여 적용해도 문제없이 동작한다', function() {
beforeEach(function() {
lion.once('move', spy.move);
lion.fire('move');
lion.once('move', spy.move);
lion.fire('move');
});
it('두번 등록해서 사용해도 문제없다', function() {
expect(spy.move.calls.count()).toBe(2);
});
});
describe('컨텍스트가 제공되도 문제없이 동작한다', function() {
beforeEach(function() {
lion.once({
'move': spy.move
}, this);
lion.fire('move');
lion.once({
'move': spy.move
}, this);
lion.fire('move');
});
it('두 번 호출되어도 문제가 없다', function() {
expect(spy.move.calls.count()).toBe(2);
});
});
});
describe('on(), off()', function() {
describe('should memorize', function() {
it('specific context object.', function() {
var inst = new CustomEvents();
var obj = {};
var obj2 = {};
describe('on()', function() {
var handler;
beforeEach(function() {
handler = jasmine.createSpy('handler');
});
it('이름, 핸들러 전달', function() {
ce.on('myE', handler);
expect(ce._events['myE'][0]).toEqual({ fn: handler });
expect(ce._events['myE'][0].fn).toBe(handler);
});
it('이름, 핸들러 두번전달', function() {
function handler2() {}
ce.on('myE', handler);
ce.on('myE', handler2);
expect(ce._events['myE'][0].fn).toBe(handler);
expect(ce._events['myE'][1].fn).toBe(handler2);
});
it('공백으로 여러 이름 전달', function() {
ce.on('myE myE2', handler);
expect(ce._events['myE'].length).toBe(1);
expect(ce._events['myE2'].length).toBe(1);
});
it('컨텍스트 전달', function() {
var myObj = {
name: 'good'
};
ce.on('myE', handler, myObj);
var ctxId = myObj.__fe_id,
handlerId = handler.__fe_id,
id = handlerId + '_' + ctxId;
var expectObj = {};
expectObj[id] = { fn: handler, ctx: myObj };
expect(ce._ctxEvents['myE_idx']).toEqual(expectObj);
});
it('이벤트명: 핸들러 객체 전달', function() {
function handler2() {}
ce.on({
'myE': handler,
'myE2': handler2
});
expect(ce._events['myE'][0]).toEqual({ fn: handler });
expect(ce._events['myE2'][0]).toEqual({ fn: handler2 });
});
it('이벤트명: 핸들러 객체 두번 전달', function() {
function handler2() {}
ce.on({ 'myE': handler });
ce.on({ 'myE': handler2 });
expect(ce._events['myE'].length).toBe(2);
});
it('이벤트명(공백포함 2개): 핸들러 객체 전달', function() {
ce.on({ 'myE myE2': handler });
expect(ce._events['myE'].length).toBe(1);
expect(ce._events['myE2'].length).toBe(1);
});
it('이벤트명: 핸들러, 컨텍스트 전달', function() {
var myObj = {
name: 'good'
};
function handler2() {}
ce.on({
'myE': handler,
'myE2': handler2
}, myObj);
var ctxId = myObj.__fe_id,
handlerId = handler.__fe_id;
var expectedMyE = {};
expectedMyE[handlerId + '_' + ctxId] = { fn: handler, ctx: myObj };
expect(ce._ctxEvents['myE_idx']).toEqual(expectedMyE);
});
it('이벤트명: 핸들러, 컨텍스트 두개이상 등록', function() {
var myObj = {
name: 'good'
};
function handler2() {}
ce.on({ 'myE': handler }, myObj);
ce.on({ 'myE': handler2 }, myObj);
expect(ce._ctxEvents['myE_len']).toBe(2);
});
it('이벤트명(공백포함 2개): 핸들러, 컨텍스트 등록', function() {
var myObj = {
name: 'good'
};
ce.on({ 'myE myE2': handler }, myObj);
expect(tui.util.keys(ce._ctxEvents['myE_idx']).length).toBe(1);
expect(ce._ctxEvents['myE_len']).toBe(1);
expect(tui.util.keys(ce._ctxEvents['myE2_idx']).length).toBe(1);
expect(ce._ctxEvents['myE2_len']).toBe(1);
});
inst._memorizeContext(obj);
inst._memorizeContext(obj2);
expect(inst.contexts).toEqual([
[obj, 1],
[obj2, 1]
]);
});
describe('off()', function() {
var spy,
spy2,
obj,
obj2,
ce;
it('and forget specific context object.', function() {
var inst = new CustomEvents();
var obj = {};
var obj2 = {};
beforeEach(function() {
spy = jasmine.createSpy('off');
spy2 = jasmine.createSpy('last');
ce = new CustomEvents();
obj = {};
obj2 = {};
});
inst._memorizeContext(obj);
inst._memorizeContext(obj2);
it('컨텍스트 전달하여 해제 가능', function() {
ce.on('play', spy, obj);
ce.off(obj);
ce.fire('play');
inst._forgetContext(obj2);
expect(spy).not.toHaveBeenCalled();
});
it('이벤트명을 넘겨 해제 가능', function() {
ce.on('play', spy);
ce.off('play');
ce.fire('play');
expect(spy).not.toHaveBeenCalled();
});
it('핸들러만 전달하여 해제 가능', function() {
ce.on('play', spy);
ce.off(spy);
ce.fire('play');
expect(spy).not.toHaveBeenCalled();
});
it('이벤트명, 핸들러를 전달하여 해제 가능', function() {
ce.on('play', spy);
ce.on('pause', spy);
ce.off('play', spy);
ce.fire('play');
ce.fire('pause');
expect(spy.calls.count()).toBe(1);
});
it('컨텍스트, 핸들러 전달하여 해제 가능', function() {
ce.on('play', spy, obj);
ce.on('pause', spy, obj);
ce.off(obj, spy);
ce.fire('play');
ce.fire('pause');
expect(spy).not.toHaveBeenCalled();
});
it('컨텍스트, 이벤트명 전달하여 해제 가능', function() {
ce.on('play', spy, obj);
ce.on('play', spy, obj2);
ce.on('pause', spy, obj);
ce.off(obj, 'pause');
ce.fire('play');
ce.fire('pause');
expect(spy.calls.count()).toBe(2);
});
it('이벤트명: 핸들러 객체를 전달하여 해제 가능', function() {
ce.on('play', spy, obj);
ce.on('pause', spy, obj);
ce.on('play', spy2);
ce.on('delay', spy2);
ce.off({
'play': spy,
'pause': spy,
'delay': spy2
});
ce.fire('play');
ce.fire('pause');
expect(spy).not.toHaveBeenCalled();
expect(spy2).toHaveBeenCalled();
expect(spy2.calls.count()).toBe(1);
});
it('인자 없이 몽땅 해제가능', function() {
ce.on('play', spy, obj);
ce.on('pause', spy, obj);
ce.on('play', spy2);
ce.on('delay', spy2);
ce.off();
ce.fire('play');
ce.fire('pause');
expect(spy).not.toHaveBeenCalled();
expect(spy2).not.toHaveBeenCalled();
});
expect(inst.contexts).toEqual([
[obj, 1]
]);
});
describe('통합 테스트', function() {
var spy,
obj;
it('context object and compute each context index.', function() {
var inst = new CustomEvents();
var obj = {};
var obj2 = {};
var obj3 = {};
beforeEach(function() {
spy = jasmine.createSpy('integration');
obj = {};
});
inst._memorizeContext(obj);
inst._memorizeContext(obj2);
it('이벤트 걸었다 지웠다 걸었다 실행', function() {
ce.on('play', spy);
ce.off('play');
ce.on('play', spy);
ce.fire('play');
expect(spy.calls.count()).toBe(1);
});
it('일반 이벤트', function() {
ce.on('play', spy);
ce.off('play', spy);
ce.on('play', spy);
ce.fire('play');
expect(spy.calls.count()).toBe(1);
});
it('일반 이벤트2', function() {
ce.on('play', spy);
ce.off(spy);
ce.on('play', spy);
ce.fire('play');
expect(spy.calls.count()).toBe(1);
});
it('컨텍스트 이벤트', function() {
ce.on('play', spy, obj);
ce.off('play');
ce.on('play', spy, obj);
ce.fire('play');
expect(spy.calls.count()).toBe(1);
});
it('컨텍스트 이벤트2', function() {
ce.on('play', spy, obj);
ce.off(obj);
ce.on('play', spy, obj);
ce.fire('play');
expect(spy.calls.count()).toBe(1);
});
it('컨텍스트 이벤트3', function() {
ce.on('play', spy, obj);
ce.off(obj, 'play');
ce.on('play', spy, obj);
ce.fire('play');
expect(spy.calls.count()).toBe(1);
});
})
});
describe('hasListener()', function() {
var lion,
spy;
beforeEach(function() {
lion = new Animal();
spy = jasmine.createSpyObj('on', ['move', 'growl']);
lion.on('move', spy.move);
expect(inst._indexOfContext(obj2)).toBe(1);
expect(inst._indexOfContext(obj3)).toBe(-1);
});
it('특정 type에 해당하는 이벤트가 등록되어있는지 여부를 확인할 수 있다', function() {
expect(lion.hasListener('move')).toBe(true);
});
});
describe('getListenerLength()', function() {
var customEvent,
thisObj,
spy,
spyObj;
it('Can bind one-shot event.', function() {
var spy = jasmine.createSpy();
var inst = new CustomEvents();
describe('예외 테스트', function() {
beforeEach(function() {
customEvent = new tui.util.CustomEvents();
});
inst.once('foo', spy);
it('이벤트를 등록하지 않았을 경우 0', function() {
expect(customEvent.getListenerLength('pan')).toBe(0);
});
inst.fire('foo');
inst.fire('foo');
describe('컨텍스트 등록 후 해제시', function() {
var myObj = {};
beforeEach(function() {
spy = jasmine.createSpy('zoom');
customEvent.on('zoom', spy, myObj);
customEvent.off('zoom');
});
expect(spy.calls.count()).toBe(1);
});
it('0이어야 한다', function() {
expect(customEvent.getListenerLength('pan')).toBe(0);
});
});
it('Can bind mutiple one-shot events.', function() {
var spy = jasmine.createSpy();
var inst = new CustomEvents();
describe('등록했다 해제할 경우', function() {
var customEvent2;
beforeEach(function() {
spy = jasmine.createSpy('zoom');
spyObj = jasmine.createSpyObj('test', ['zoom']);
customEvent.on('zoom', spyObj.zoom, thisObj);
customEvent.off('zoom', spyObj.zoom, thisObj);
customEvent2 = new tui.util.CustomEvents();
customEvent2.on('zoom', spy);
customEvent2.off('zoom', spy);
});
it('context 제공 시', function() {
expect(customEvent.getListenerLength('zoom')).toBe(0);
});
it('context 비 제공 시', function() {
expect(customEvent2.getListenerLength('zoom')).toBe(0);
});
});
inst.once({
'foo': spy,
'bar': spy
});
describe('갯수 테스트', function() {
beforeEach(function() {
customEvent = new tui.util.CustomEvents();
spy = jasmine.createSpy('zoom');
spyObj = jasmine.createSpyObj('spy', ['pan', 'zoom']);
inst.fire('foo');
inst.fire('foo');
inst.fire('bar');
inst.fire('bar');
thisObj = {};
expect(spy.calls.count()).toBe(2);
});
customEvent.on({
'pan': spyObj.pan,
'zoom': spyObj.zoom
}, thisObj);
it('Can check specific event was binded.', function() {
var inst = new CustomEvents();
inst.on('test', function() {});
customEvent.on('zoom', spy);
});
it('할당된 이벤트의 갯수를 알 수 있다', function() {
expect(customEvent.getListenerLength('zoom')).toBe(2);
expect(customEvent.getListenerLength('pan')).toBe(1);
});
it('이벤트가 해제되어도 갯수가 반영된다', function() {
customEvent.off('zoom', spyObj.zoom, thisObj);
expect(customEvent.getListenerLength('zoom')).toBe(1);
});
it('이벤트가 해제되면 갯수가 반영된다', function() {
customEvent.off('zoom', spy);
expect(customEvent.getListenerLength('zoom')).toBe(1);
});
it('이벤트를 모두 삭제하면 0', function() {
customEvent.off();
expect(customEvent.getListenerLength('zoom')).toBe(0);
});
});
expect(inst.hasListener('test')).toBe(true);
expect(inst.hasListener('good')).not.toBe(true);
});
describe('인스턴스 자체로 사용', function() {
var Animal;
it('Can count event listeners.', function() {
var inst = new CustomEvents();
beforeEach(function() {
Animal = function() {
this.events = new tui.util.CustomEvents();
};
expect(inst.getListenerLength('foo')).toBe(0);
Animal.prototype.fire = function(type, data) {
this.events.fire(type, data);
};
});
inst.on('test', function() {});
describe('명시적으로 context를 넘기지 않으면 이벤트 객체가 context가 된다', function() {
var lion,
spy;
expect(inst.getListenerLength('test')).toBe(1);
beforeEach(function() {
// 컨텍스트를 넘기지 않는 이벤트 사용 코드
Animal.prototype.on = function(type, handler) {
this.events.on(type, handler);
};
inst.off('test');
spy = jasmine.createSpy('test');
lion = new Animal();
lion.on('growl', spy);
lion.fire('growl');
});
it('this는 CustomEvents객체', function() {
expect(spy.calls.all()[0].object).not.toBe(lion);
expect(spy.calls.all()[0].object).toBe(lion.events);
});
});
describe('명시적으로 context를 넘기도록 개발해야 한다', function() {
var lion,
spy;
beforeEach(function() {
// 컨텍스트를 넘기지 않는 이벤트 사용 코드
Animal.prototype.on = function(type, handler) {
this.events.on(type, handler, this);
};
spy = jasmine.createSpy('test');
lion = new Animal();
lion.on('growl', spy);
lion.fire('growl');
});
it('this는 lion', function() {
expect(spy.calls.all()[0].object).not.toBe(lion.events);
expect(spy.calls.all()[0].object).toBe(lion);
});
});
expect(inst.getListenerLength('test')).toBe(0);
});
});

@@ -1,78 +0,9 @@

describe('`defineModule` function', function() {
var definedModule;
it('should set namespace and override', function() {
definedModule = tui.util.defineModule('foo.bar', {a: 'a'});
expect(window.foo.bar).toBe(definedModule);
definedModule = tui.util.defineModule('foo.bar', {b: 'b'});
expect(window.foo.bar).toBe(definedModule);
expect(window.foo.bar.a).not.toBeDefined();
expect(window.foo.bar.b).toBeDefined();
});
describe('return a object', function() {
var messagesForVerifying = {
privateData: "I'm private data",
publicData: "I'm public data",
privateMethod: "I'm private method",
publicMethod: "I'm public method",
initializeMethod: "initialized!!"
},
base = {
_privateData: messagesForVerifying.privateData,
publicData: messagesForVerifying.publicData,
initializationMessage: '',
_privateMethod: function() {
return messagesForVerifying.privateMethod;
},
initialize: function() {
this.initializationMessage = messagesForVerifying.initializeMethod;
},
publicMethod: function() {
return messagesForVerifying.publicMethod;
},
getPrivateData: function() {
return this._privateData;
},
callPrivateMethod: function() {
return this._privateMethod();
},
changePublicData: function(data) {
this.publicData = data;
}
};
beforeAll(function() {
definedModule = tui.util.defineModule('foo.bar', base);
describe('"defineModule" function', function() {
it('should call initialize', function() {
tui.util.defineModule('foo.bar', {
initialize: jasmine.createSpy()
});
it('that should be initialized', function() {
expect(definedModule.initializationMessage).toEqual(messagesForVerifying.initializeMethod);
});
it('that should not have `initialize` method', function() {
expect(definedModule.initialize).not.toBeDefined();
});
it('that should have public data', function() {
expect(definedModule.publicData).toEqual(messagesForVerifying.publicData);
});
it('that should work normally', function() {
expect(definedModule.publicMethod()).toEqual(messagesForVerifying.publicMethod);
expect(definedModule.getPrivateData()).toEqual(messagesForVerifying.privateData);
expect(definedModule.callPrivateMethod()).toEqual(messagesForVerifying.privateMethod)
definedModule.changePublicData('foo');
expect(definedModule.publicData).toEqual('foo');
});
expect(window.foo.bar.initialize).toHaveBeenCalled();
});
});

@@ -33,3 +33,3 @@ describe('defineNamespace', function() {

num += 100;
});
}, true);

@@ -42,11 +42,13 @@ fdsa();

it('for class', function() {
var name = 'nhnent';
defineNamespace('asdf.nhnent', function() {
var name = 'Nhnent';
var mInstance;
defineNamespace('asdf.Nhnent', function() {
this.name = name;
this.getName = function() {
return this.name;
}
});
};
}, true);
mInstance = new asdf.Nhnent();
var mInstance = new asdf.nhnent();
expect(mInstance.getName()).toBe(name);

@@ -63,8 +65,5 @@

defineNamespace('asdf.over', {
exec: function() {
}
exec: function() {}
}, true);
expect(asdf.over.exec).toBeDefined();
});

@@ -93,2 +92,13 @@

it('should extend if exist', function() {
var tester = {
method: function() {}
};
defineNamespace('foo.bar.baz');
expect(window.foo.bar.baz).toEqual(jasmine.any(Object));
defineNamespace('foo.bar', tester);
expect(window.foo.bar.method).toEqual(tester.method);
});
});

@@ -58,3 +58,3 @@ 'use strict';

it('-> MMMM DD YYYY H:m A', function() {
expect(formatDate(forms[9], inputs[0])).toEqual('September 09 1999 0:2 AM');
expect(formatDate(forms[9], inputs[0])).toEqual('September 09 1999 12:2 AM');
});

@@ -220,3 +220,3 @@ });

expect(formatDate(forms[9], dt)).toEqual('September 09 1999 0:2 AM');
expect(formatDate(forms[9], dt)).toEqual('September 09 1999 12:2 AM');
});

@@ -411,3 +411,47 @@ });

});
describe('meridiemSet', function() {
it('AM -> 오전', function() {
var option = {
meridiemSet: {
AM: '오전',
PM: '오후'
}
};
var date = {year: 1999, month: 9, date: 9, hour: 0, minute: 2};
expect(formatDate('yyyy-MM-dd a hh:mm', date, option)).toEqual('1999-09-09 오전 12:02');
});
it('PM -> 오후', function() {
var option = {
meridiemSet: {
AM: '오전',
PM: '오후'
}
};
var date = {year: 1999, month: 9, date: 9, hour: 13, minute: 2};
expect(formatDate('yyyy-MM-dd A hh:mm', date, option)).toEqual('1999-09-09 오후 01:02');
});
});
it('not full-date but time format', function() {
var date = {year: 1999, month: 9, date: 9, hour: 2, minute: 3};
expect(formatDate('a hh:mm', date)).toEqual('AM 02:03');
});
it('not full-date but time format with meridiemSet', function() {
var option = {
meridiemSet: {
AM: '오전',
PM: '오후'
}
};
var date = {year: 1999, month: 9, date: 9, hour: 12, minute: 3};
//See the clock system: https://en.wikipedia.org/wiki/12-hour_clock
expect(formatDate('a hh:mm', date, option)).toEqual('오후 12:03');
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc