1 2 /** 3 * @fileOverview Librería para la producción de contenidos de la web 4 * @version 1.0 5 * @author taejin (drumtj@gmail.com) 6 */ 7 8 /** 9 * @see <a href="http://jquery.com/">http://jquery.com/</a> 10 * @name jQuery 11 * @class 12 * Refiere jQuery Library (http://jquery.com/) para ver los detalles completos. Esto solo documenta las funciones y clases que son añadidos por este plug-in de jQuery. 13 */ 14 15 16 /** 17 * @see <a href="http://jquery.com/">http://jquery.com/</a> 18 * @name fn 19 * @class 20 * Refiere jQuery Library (http://jquery.com/) para ver los detalles completos. Esto solo documenta la función y clases que son añadidos a jQuery por este plug-in. 21 * @memberOf jQuery 22 */ 23 24 (function(){ 25 26 if( !("jQuery" in window) ){ 27 throw new Error("sg library is require jQuery"); 28 } 29 30 var toString = {}.toString 31 , slice = [].slice; 32 33 var //readyCallbackList = [] 34 initCallbackList = [] 35 , customTagList = {} 36 , customAttrList = {} 37 , setStageFunc 38 , setScaleModeFunc 39 , progressImg; 40 41 //private 42 var version = "1.0" 43 , scaleMode = "none" 44 , scaleX = 0 45 , scaleY = 0 46 , stageWidth = 0 47 , stageHeight = 0 48 , $stage = null 49 , $content = null 50 , $body = null 51 , $window = $( window ); 52 53 //support 54 if( !("forEach" in Array.prototype) ){ 55 Array.prototype.forEach = function ( callback ){ 56 for( var i=0; i<this.length; i++ ){ 57 callback.call( window, this[ i ] ); 58 } 59 } 60 } 61 62 /** 63 * Configura el cursor del mouse como puntero. 64 * @function 65 * @name pointer 66 * @memberOf jQuery.fn 67 * @example 68 * $( element ).pointer(); 69 * @example 70 * $( element ).pointer( false ); 71 * @param {boolean} bool 72 * @returns Objeto de jQuery 73 * @type jQuery Object 74 */ 75 jQuery.fn.pointer = function(){ 76 return $( this ).css( "cursor", arguments[0] == false ? "auto" : "pointer" ); 77 }; 78 79 /** 80 * Devuelve el valor numérico del CSS. 81 * @function 82 * @name cssVal 83 * @memberOf jQuery.fn 84 * @example 85 * $( element ).cssVal( "margin-top" ); 86 * @param {string} cssName 87 * @returns value 88 * @type number 89 */ 90 jQuery.fn.cssVal = function( cssName ){ 91 var num = parseFloat( $( this ).css( cssName ) ); 92 return isNaN( num ) ? 0 : num; 93 }; 94 95 /** 96 * Es una función que extrae las etiquetas personalizadas específicas. Extrae las etiquetas personalizadas entre los elementos hijos. 97 * @function 98 * @name getCustomTag 99 * @memberOf jQuery.fn 100 * @example 101 * $( 'p' ).getCustomTag( "sg-btn-hide" ); 102 * @param {string} tagName 103 * @returns Objeto de jQuery 104 * @type jQuery Object 105 * @link sg.addCustomTag referir las funciones definidas de etiquetas personalizadas. 106 */ 107 jQuery.fn.getCustomTag = function( tagName ){ 108 var isRoot = (this == $); 109 for( var o in customTagList ){ 110 if( tagName == o ){ 111 if( isRoot ) return $( "[" + customTagList[ o ].identifier + "]" ); 112 else return $( this ).children( "[" + customTagList[ o ].identifier + "]" ); 113 } 114 } 115 return $; 116 }; 117 118 /** 119 * Función que extrae las etiquetas personalizadas específicas. 120 * @function 121 * @name getCustomTag 122 * @memberOf jQuery 123 * @example 124 * $.getCustomTag( "sg-btn-hide" ); 125 * @param {string} tagName 126 * @returns objeto de jQuery 127 * @type jQuery Object 128 * @link sg.addCustomTag referir funciones definidas de etiquetas personalizadas. 129 */ 130 jQuery.getCustomTag = jQuery.fn.getCustomTag; 131 132 133 134 function swapTag( obj, findTagName, swapTagName, identifier ) { 135 if ( document.querySelector( findTagName ) ) { 136 identifier = identifier ? ' ' + identifier + ' ' : ''; 137 obj.html = obj.html 138 .replace( new RegExp( '<' + findTagName, 'g' ), '<' + swapTagName + identifier ) 139 .replace( new RegExp( '</' + findTagName + '>', 'g' ), '</' + swapTagName + '>' ); 140 }else{ 141 customTagList[ findTagName ].nothing = true; 142 } 143 } 144 145 function replaceTagList(){ 146 var obj = { html: document.body.innerHTML } 147 , customTagName 148 , customAttrName 149 , ctInfo, caInfo, i, j, k; 150 151 for( customTagName in customTagList ){ 152 ctInfo = customTagList[ customTagName ]; 153 swapTag(obj, customTagName, ctInfo.originTag, ctInfo.identifier); 154 }; 155 156 //add custom attribute prefix : data- 157 var sgAttrNameReg = /\ssg([\-][\w]*){1,5}(\s)?=/gi, 158 s1 = obj.html.split('<'), 159 s2, matchArr, r2 = []; 160 161 for ( i = 0; i < s1.length; i++ ) { 162 s2 = s1[ i ].split( '>' ); 163 for ( j = 0; j < s2.length; j++ ) { 164 if ( j % 2 == 0 ) { 165 matchArr = s2[ j ].match( sgAttrNameReg ); 166 if ( matchArr ) { 167 for ( k = 0; k < matchArr.length; k++ ) { 168 s2[ j ] = s2[ j ].replace( matchArr[ k ], " data-" + matchArr[ k ].substr( 1 ) ); 169 } 170 } 171 } 172 } 173 r2.push( s2.join( '>' ) ); 174 } 175 176 obj.html = r2.join( '<' ); 177 document.body.innerHTML = obj.html; 178 179 delete s1; 180 delete s2; 181 delete r2; 182 delete obj; 183 delete matchArr; 184 185 //support placeholder bug 186 $( "[placeholder]" ).each(function(i,e){ 187 $( this ).text("").attr( "placeholder", $( this ).attr("placeholder") ); 188 }); 189 190 //function apply for custom tags 191 var $customTag; 192 for( customTagName in customTagList ){ 193 ctInfo = customTagList[ customTagName ]; 194 if( ctInfo.nothing ) continue; 195 196 $customTag = $.getCustomTag( customTagName ); 197 198 if( sg.isFunction( ctInfo[ "initFunc" ] ) ){ 199 ctInfo[ "initFunc" ].call( sg ); 200 } 201 202 //execute to init function of custom attribute for each custom tag 203 $customTag.each(function(index, element) { 204 $( element ).data( "_customTagName", customTagName ); 205 sg.setOption( element ); 206 if( /^sg-btn-/.test( customTagName ) ) $( element ).pointer(); 207 if( sg.isFunction( ctInfo[ "eachInitFunc" ] ) ){ 208 ctInfo[ "eachInitFunc" ].call( element, element ); 209 } 210 sg.initAttr( element ); 211 }); 212 213 //execute to action function of custom attribute when called event handle 214 if( ctInfo[ "eventName" ] ){ 215 $customTag.bind( ctInfo[ "eventName" ], function( e ){ 216 var ctname = $( this ).data( "_customTagName" ); 217 if ( !$( this ).data( "options" ).enabled ) return; 218 if( sg.isFunction( customTagList[ ctname ][ "eventFunc" ] ) ) customTagList[ ctname ][ "eventFunc" ].call( this, this, e ); 219 sg.actionAttr( this ); 220 }); 221 }; 222 $customTag = null; 223 }; 224 225 //apply custom attribute for all tag 226 for( customAttrName in customAttrList ){ 227 caInfo = customAttrList[ customAttrName ]; 228 if( caInfo.isForEveryTags ){ 229 if( caInfo && sg.isFunction( caInfo[ "init" ] ) ){ 230 $( "[data-" + customAttrName + "]" ).each(function( i, element ){ 231 sg.setOption( element ); 232 caInfo[ "init" ].call( element, element, element.getAttribute( "data-" + customAttrName ) ); 233 }); 234 } 235 } 236 } 237 } 238 239 //call by 'resize' event 240 var _ww, _hh, _ch, _msc; 241 function applyScaleMode(){ 242 _ww = $window.width(); 243 _hh = $window.height(); 244 _ch = $content.height(); 245 _ch += $content.cssVal( "border-top-width" ) + $content.cssVal( "border-bottom-width" ); 246 _ch += $content.cssVal( "margin-top" ) + $content.cssVal( "margin-bottom" ); 247 _ch += $content.cssVal( "padding-top" ) + $content.cssVal( "padding-bottom" ); 248 249 switch( scaleMode ){ 250 case "showall": 251 _msc = Math.min(_ww / stageWidth, _hh / stageHeight); 252 if(_ch - stageHeight <= 1){ 253 //컨텐츠가 스테이지보다 클 때 254 if(_ch * _msc > _hh){ 255 //console.log("top 0, overflow:visible"); 256 $stage.css({ 257 "transform" : "scale(" + _msc + ")", 258 "transform-origin" : "0 0", 259 "left" : ((_ww - stageWidth * _msc) * 0.5) + "px", 260 "top" : 0 261 }); 262 263 $stage.parent().css({ 264 "overflow-y" : "visible" 265 }); 266 } 267 //컨텐츠가 스테이지 안에 있을 때 268 else{ 269 //console.log("top center, overflow:hidden"); 270 $stage.css({ 271 "transform" : "scale(" + _msc + ")", 272 "transform-origin" : "0 0", 273 "left" : ((_ww - stageWidth * _msc) * 0.5) + "px", 274 "top" : ((_hh - _ch * _msc) * 0.5) + "px" 275 }); 276 277 $stage.parent().css({ 278 "overflow-y" : "hidden" 279 }); 280 } 281 } 282 else{ 283 //console.log("top center, overflow:auto"); 284 $stage.css({ 285 "transform" : "scale(" + _msc + ")", 286 "transform-origin" : "0 0", 287 "left" : ((_ww - stageWidth * _msc) * 0.5) + "px", 288 "top" : ((_hh - stageHeight * _msc) * 0.5) + "px" 289 }); 290 291 $stage.parent().css({ 292 "overflow-y" : "auto" 293 }); 294 } 295 scaleX = scaleY = _msc; 296 break; 297 298 case "noscale": 299 scaleX = scaleY = 1; 300 $stage.css({ 301 "transform" : "scale(" + scaleX + ")", 302 "transform-origin" : "0 0" 303 }); 304 break; 305 306 case "exactfit": 307 scaleX = _ww / stageWidth; 308 scaleY = _hh / stageHeight; 309 $stage.css({ 310 "transform" : "scale(" + scaleX + ", " + scaleY + ")", 311 "transform-origin" : "0 0" 312 }); 313 break; 314 } 315 } 316 317 318 /** 319 * @namespace Librería para la producción de contenidos de la web 320 * @author taejin (drumtj@gmail.com) 321 * @name sg 322 * @version 1.0 323 * @since 2014.09.22 324 * @description 325 * sg library es una librería que requiere jQuery. <br> 326 * Ofrece configuración de scaleMode, atributos personalizados y API para la producción de etiquetas personalizadas.<br> 327 */ 328 var sg = { 329 /** 330 * [Read Only] es información sobre versions de la librería sg. 331 * @name version 332 * @memberOf sg 333 * @type string 334 */ 335 get version() { return version }, 336 337 /** 338 * [Read Only] Método de escala de stage. Se lo configura con Sg.setScaleMode y se puede colocar "showall", "exactfit" o "none" como su valor. 339 * @name scaleMode 340 * @memberOf sg 341 * @type string 342 */ 343 get scaleMode() { return scaleMode }, 344 345 /** 346 *[Read Only] Es el valor del eje X de stage. Se calcula el valor cuando se ajusta scaleMode como la función de sg.set. 347 * Su proporción se calcula en base del width de stage. 348 * @name scaleX 349 * @memberOf sg 350 * @type number 0.0 ~ 1.0 351 */ 352 get scaleX() { return scaleX }, 353 354 /** 355 * [Read Only] stage의 Es el valor del eje Y de stage. Se calcula el valor cuando se ajusta scaleMode como la función de sg.set. 356 * Su proporción se calcula en base del width de stage. 357 * @name scaleY 358 * @memberOf sg 359 * @type number 0.0 ~ 1.0 360 */ 361 get scaleY() { return scaleY }, 362 363 /** 364 * [Read Only] El valor de width de stage. Se importa el valor de width de stage al configurar stage con la función de set Stage. 365 * @name stageWidth 366 * @memberOf sg 367 * @type number 368 */ 369 get stageWidth() { return stageWidth }, 370 371 /** 372 * [Read Only] El valor de height de stage. Se importa el valor de height de stage al configurar stage con la función de set Stage. 373 * @name stageHeight 374 * @memberOf sg 375 * @type number 376 */ 377 get stageHeight() { return stageHeight }, 378 379 /** 380 * [Read Only] Es un elemento configurado como stage. Se lo configura con sg.setStage. 381 * @name $stage 382 * @memberOf sg 383 * @type jQuery Object 384 */ 385 get $stage() { return $stage }, 386 387 /** 388 * [Read Only] Es un contenedor que contiene los elementos hijos de stage. Se crea cuando se configura $stage. 389 * @name $content 390 * @memberOf sg 391 * @type jQuery Object 392 */ 393 get $content() { return $content }, 394 395 /** 396 * [Read Only] $("body") 397 * @name $body 398 * @memberOf sg 399 * @type jQuery Object 400 */ 401 get $body() { return $body }, 402 403 /** 404 * [Read Only] $(window) 405 * @name $window 406 * @memberOf sg 407 * @type jQuery Object 408 */ 409 get $window() { return $window }, 410 411 /** 412 * Se puede añadir o extender funciones en sg. 413 * @function 414 * @name extend 415 * @memberOf sg 416 * @example 417 * sg.extend({ 418 * myfunc: function( ){ 419 * //TO DO 420 * } 421 * }); 422 * 423 * sg.myfunc(); 424 * @param {object} property 425 * @link sg.super Referencia 426 */ 427 extend: function( prop ){ 428 if(typeof prop !== "object"){ throw new Error("sg.extend arguments is not Object!"); } 429 430 for( var name in prop ){ 431 //sg.hasOwnProperty( name ) 432 if( name in sg ) prop[ name ]._super = sg[ name ]; 433 sg[ name ] = prop[ name ]; 434 } 435 }, 436 437 /** 438 * importa la etiqueta original desde la función extendida a través de sg.extend. 439 * @function 440 * @name super 441 * @memberOf sg 442 * @example 443 * sg.extend({ 444 * myfunc: function( str ){ 445 * return '<<' + str + '>>'; 446 * } 447 * }); 448 * 449 * sg.myfunc( 'abc' ); //return "<<abc>>" 450 * 451 * sg.extend({ 452 * myfunc: function( str ){ 453 * return this.super( str.toUpperCase() ); 454 * } 455 * }); 456 * 457 * sg.myfunc( 'abc' ); //return "<<ABC>>" 458 * @param {object} [arguments=undefined] Parámetros de la función original. 459 * @return {*} el valor devuelto de la función original. 460 * @type * 461 * @link sg.extend Refencia 462 */ 463 super: function(){ 464 var _super = arguments.callee.caller._super; 465 return sg.isFunction( _super ) ? _super.apply( this, arguments ) : null; 466 } 467 }; 468 469 470 sg.extend({ 471 /** 472 * Verificar si el objeto es función. Usar isFunction de jQuery. 473 * @function 474 * @name isFunction 475 * @memberOf sg 476 * @param {object} object 477 * @returns true o false 478 * @type boolean 479 */ 480 isFunction: $.isFunction, 481 482 /** 483 * Verificar si el objeto es array. Usar la función isArray de jQuery. 484 * @function 485 * @name isArray 486 * @memberOf sg 487 * @param {object} object 488 * @returns true o false 489 * @type boolean 490 */ 491 isArray: $.isArray, 492 493 /** 494 * Verificar si el objeto es objeto de window. Usar la función isWindow de jQuery. 495 * @function 496 * @name isWindow 497 * @memberOf sg 498 * @param {object} object 499 * @returns true o false 500 * @type boolean 501 */ 502 isWindow: $.isWindow, 503 504 /** 505 * Verificar si el objeto es número. Usar la función isNumeric de jQuery. 506 * @function 507 * @name isNumeric 508 * @memberOf sg 509 * @param {object} object 510 * @returns true o false 511 * @type boolean 512 */ 513 isNumeric: $.isNumeric, 514 515 /** 516 * Verificar si el objeto es un objeto vacío. Usar la función isEmptyObject de jQuery. 517 * @function 518 * @name isEmptyObject 519 * @memberOf sg 520 * @param {object} object 521 * @returns true o false 522 * @type boolean 523 */ 524 isEmptyObject: $.isEmptyObject, 525 526 /** 527 * Verificar si el objeto está incluido en el array. Usar la función inArray de jQuery. 528 * @function 529 * @name inArray 530 * @memberOf sg 531 * @param {object} element 532 * @param {array} array 533 * @param {number} index 534 * @returns true o false 535 * @type string 536 */ 537 inArray: $.inArray, 538 539 /** 540 * Devuelve data type del objeto. Usar la función type de jQuery. 541 * @function 542 * @name type 543 * @memberOf sg 544 * @param {object} 545 * @returns true o false 546 * @type string 547 */ 548 type: $.type 549 }); 550 551 552 553 sg.extend({ 554 555 /** 556 * Añadir la función de inicialización (callback). Las funciones (callback) añadidas se ejecutan después de la inicialización. 557 * @function 558 * @name addInit 559 * @memberOf sg 560 * @example 561 * sg.addInit( function(){} ); 562 * @param {function} callback 563 */ 564 addInit: function( callback ){ 565 initCallbackList.push( callback ); 566 }, 567 568 /** 569 * Configurar la ruta de la imagen de cargando. La imagen configurada se visualiza en la pantalla durante la ejecución de página. 570 * @function 571 * @name setLoadingImage 572 * @memberOf sg 573 * @example 574 * sg.setLoadingImage( '../common/img/progress.gif' ); 575 * @param {string} path 576 */ 577 setLoadingImage: function( path ){ 578 progressImg = new Image(); 579 progressImg.setAttribute("data-sg-id", "progressImg"); 580 progressImg["onload"] = function( e ){ 581 this.style.left = (((window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) - this.width) * 0.5) + "px"; 582 this.style.top = (((window.innerHeight || document.documentElement.clientWidth || document.body.clientWidth) - this.height) * 0.5) + "px"; 583 if( !sg.isReady ) document.body.appendChild( progressImg ); 584 else delete progressImg; 585 }; 586 progressImg.src = path; 587 progressImg.style.position = "fixed"; 588 progressImg.style.visibility = "visible"; 589 }, 590 591 /** 592 * Configura stage. El stage configurado tiene acceso al sg.$stage. El stage es el criterio de controlar la escala. 593 * @function 594 * @name setStage 595 * @memberOf sg 596 * @example 597 * sg.setStage( "#stage" ); 598 * @param {object} elementOrSelector 599 */ 600 setStage: function( elementOrSelector ){ 601 setStageFunc = function(){ 602 var $temp = $( elementOrSelector ); 603 if( $temp.length == 0 ) throw new Error( "setStage : $stage is not select. (selector : " + elementOrSelector + ")" ); 604 605 $temp.attr( "data-sg-id", "stage" ); 606 $content = $( "<div data-sg-id='content'></div>" ); 607 $content.append( $temp.contents() ); 608 609 $temp.append( $content ).css( "position", "absolute" ); 610 $temp.parent().css( "overflow-x", "hidden" ); 611 612 //border가 없으면, 때로는 크기가 잘 못 계산되기 때문에 613 if( $temp.cssVal( "border-top-width" ) == 0 ){ 614 $temp.css( "border", "solid 1px rgba(255,255,255,0)" ); 615 } 616 617 stageWidth = $temp.width(); 618 stageHeight = $temp.height(); 619 620 $content.css({ 621 "min-height": stageHeight, 622 "visibility": "hidden" 623 }); 624 625 $stage = $temp; 626 627 //apply scaleMode 628 if( setScaleModeFunc ){ 629 setScaleModeFunc.apply( sg ); 630 setScaleModeFunc = null; 631 } 632 } 633 634 if( sg.isReady ){ 635 setStageFunc.apply( sg ); 636 setStageFunc = null; 637 } 638 }, 639 640 /** 641 * Configura scaleMode. Se habilita siempre y cuando tenga configurado el stage, y hay modos de "showall", "exactfit" y "none". 642 * @function 643 * @name setScaleMode 644 * @memberOf sg 645 * @example 646 * sg.setStage( "#stage" ); 647 * sg.setScaleMode( "showall" ); 648 * @example 649 * sg.setStage( "#stage" ); 650 * sg.setScaleMode( "exactfit" ); 651 * @param {string} scaleMode 652 */ 653 setScaleMode: function( _scaleMode ){ 654 scaleMode = _scaleMode; 655 setScaleModeFunc = function(){ 656 $window.bind( "resize" , function(){ 657 applyScaleMode(); 658 }); 659 applyScaleMode(); 660 } 661 662 if( $stage ){ 663 setScaleModeFunc.apply( this ); 664 setScaleModeFunc = null; 665 } 666 }, 667 668 //options setting for custom tags 669 /** 670 * Se guarda el valor a ser aplicado al ejecutar la etiqueta personalizada en $(target).data("options"). 671 * @function 672 * @name setOption 673 * @memberOf sg 674 * @example 675 * sg.setOption( element ); 676 * @example 677 * sg.setOption( element , {myClicked: false} ); 678 * @param {object} elementOrSelector - elemento o selector de jQuery 679 * @param {object} [options=undefined] - Objeto con el conjunto de valores 680 */ 681 setOption: function ( target, options ){ 682 var op = { enabled: true }; 683 for( var o in options ) op[ o ] = options[ o ]; 684 $( target ).data( "options", op ); 685 }, 686 687 /** 688 * Añadir atributos personalizados.<br> 689 * Al definir los atributos, se puede colocar true en el valor de applyAll con el fin de utlizarlos en todas las etiquetas.<br> 690 * Cuando el valor es false, se habilita la función del atributo al usarlo en la etiqueta personalizada. En general, 691 * los atributos personalizados definidos poseen una función especial, y esta función es habilitada con los eventos de las etiquetas personalizadas, 692 * y por ende, se deja el valor básico de applyAll como false. 693 * @function 694 * @name addCustomAttr 695 * @memberOf sg 696 * @param {object} option - inicializar el objeto de atributo personalizado 697 * @param {string} option.name - nombre de atributo personalizado. 698 * @param {function} [option.init=undefined] - función de inicialización. 699 * @param {function} [option.action=undefined] - función a ejecutar: se ejecuta cuando se procede los eventos de la etiquetas 700 * personalizadas que utilitza estos atributos personalizados. 701 * @param {boolean} [option.applyAll=true] - determina si se habilita la función de este atributo en todas las etiquetas básicas. 702 * @example 703 * //script 704 * sg.addCustomAttr({ 705 * name: "sg-fadeIn", 706 * init: function( element, attrValue ){ 707 * $( element ).fadeIn(); 708 * }, 709 * applyAll: true 710 * }); 711 * //html 712 * <div sg-fadeIn> ABCD </div> 713 * @example 714 * //script 715 * sg.addCustomAttr({ 716 * name: "sg-color", 717 * init: function( element, attrValue ){ 718 * $( element ).css( "color", attrValue ); 719 * }, 720 * applyAll: true 721 * }); 722 * //html 723 * <div sg-color="red"> ABCD </div> 724 * @example 725 * sg.addCustomAttr({ 726 * name: "sg-alert", 727 * action: function( element, attrValue ){ 728 * if( attrValue ) alert( attrValue ); 729 * } 730 * }); 731 * @link sg.addCustomTag referir la función definida para etiquetas personalizdas. 732 */ 733 addCustomAttr: function( obj ){ 734 customAttrList[ obj.name ] = { 735 init: obj.init, 736 action: obj.action, 737 isForEveryTags: obj.applyAll 738 } 739 }, 740 741 /** 742 * Añadir etiquetas personalizadas.<br> 743 * El mecanismo básico de la etiqueta personalizada es reemplazar las líneas de código html. <br> 744 * Después de la carga de la página, se busca las etiquetas personalizadas en el body de html, y las reemplaza a las etiquetas básicas definidas. <br> 745 * Al definir las etiquetas personalizadas, se escribe el nombre de la etiqueta original en originTag. Puede ser que las etiquetas personalizadas tengan evento o no. 746 * Se puede crear una etiqueta personalizada que sirve para cambiar la estructura interna de la etiqueta definiendo una función en tagInit. 747 * Por otra parte, se puede crear las etiquetas personalizadas que se habilitan con eventos específicos con una definión de función eventHandle. 748 * @function 749 * @name addCustomTag 750 * @memberOf sg 751 * @param {object} option - inicializar el objeto de etiqueta personalizado 752 * @param {string} option.name - Nombre de etiqueta personalizada. 753 * @param {string} [option.originTag="div"] - El nombre de la etiqueta a ser reemplazada. 754 * @param {string} [option.id="data-sg-id={name of custom tag}"] 755 * - Identificador de etiqueta personalizada. Si no es un caso específico, se usa el valor básico. 756 * @param {array} [option.attr=undefined] - un array donde se listan los nombres de los atributos personalizados a ser usados en la etiqueta personalizada. 757 * @param {function} [option.init=undefined] - se define las funciones si hay algo que se tiene que ejecutar al inicializar. 758 * @param {function} [option.tagInit=undefined] - se define las funciones si hay algo que se tiene que ejecutar en cada etiqueta al inicializar. 759 * @param {string} [option.event=undefined] - si se habilita con un evento específico, se escribe el nombre. 760 * @param {function} [option.eventHandle=undefined] - se define la función que ejecute evento. 761 * @example 762 * //script 763 * sg.addCustomTag({ 764 * name: "sg-depth", 765 * tagInit: function( element ){ 766 * $("<p></p>").append( $( element ).contents() ).appendTo( $( element ) ); 767 * } 768 * }); 769 * //html 770 * <sg-depth> ABCD <sg-depth> 771 * //result 772 * <sg-depth> <p>ABCD</p> <sg-depth> 773 * @example 774 * //script 775 * sg.addCustomTag({ 776 * name: "sg-h1", 777 * attr: [ "sg-color", "sg-alert" ], 778 * tagInit: function( element ){ 779 * $( element ).css( "font-size", "40pt" ); 780 * }, 781 * event: "click", 782 * eventHandle: function( element ){ 783 * $( element ).animate( {"font-size": "80pt"} ); 784 * } 785 * }); 786 * //html 787 * <sg-h1 sc-color="blue" sg-alert="hello!"> ABCD </sg-h1> 788 * @link jQuery.getCustomTag Hacer referencia la función extraída de la etiqueta personalizada. 789 * @link sg.addCustomAttr Hacer referencia la función definida del atributo personalizado. 790 */ 791 addCustomTag: function( obj ){ 792 customTagList[ obj.name ] = { 793 originTag: obj.originTag ? obj.originTag : "div", 794 identifier: obj.id ? obj.id : "data-sg-id='" + obj.name + "'", 795 eventName: obj.event, 796 attrList: (function( list ){ 797 if( !list ) return null; 798 else list = slice.call( list );//copy array 799 var i=0, attrName; 800 list.forEach( function(attrName){ 801 if( !(attrName in customAttrList) ) list.splice( i, 1 ); 802 else i++; 803 }); 804 return list; 805 })( obj.attr ), 806 initFunc: obj.init, 807 eachInitFunc: obj.tagInit, 808 eventFunc: obj.eventHandle 809 } 810 }, 811 812 //initialize about custom attribute in custom tag 813 /** 814 * La función de inicialización sobre los atributos configurados al definir la etiqueta personalizada. 815 * @function 816 * @name initAttr 817 * @memberOf sg 818 * @example sg.initAttr( element ); 819 * @param {object} element 820 */ 821 initAttr: function( element ){ 822 //console.log( element, arguments.callee ); 823 var customTagName = $( element ).data( "_customTagName" ) 824 , attrList, attr, attrValue; 825 826 if( customTagName ){ 827 attrList = customTagList[ customTagName ].attrList; 828 if( attrList ){ 829 attrList.forEach(function( attrName ){ 830 attr = customAttrList[ attrName ]; 831 attrValue = element.getAttribute( "data-" + attrName ); 832 if( attr && attr[ "init" ] && !attr.isForEveryTags ){ 833 attr[ "init" ].call( element, element, attrValue ); 834 } 835 }); 836 } 837 } 838 }, 839 840 //execute function about custom attribute in custom tag 841 /** 842 * Ejecuta la función action del atributo personalizado definedo en la etiqueta personalizada. 843 * @function 844 * @name actionAttr 845 * @memberOf sg 846 * @example sg.actionAttr( element ); 847 * @param {object} element 848 */ 849 actionAttr: function( element ){ 850 var customTagName = $( element ).data( "_customTagName" ) 851 , attrList, attr, attrValue; 852 853 if( customTagName ){ 854 attrList = customTagList[ customTagName ].attrList; 855 if( attrList ){ 856 attrList.forEach(function( attrName ){ 857 attr = customAttrList[ attrName ]; 858 attrValue = element.getAttribute( "data-" + attrName ); 859 if( attr && attr[ "action" ] ){ 860 attr[ "action" ].call( element, element, attrValue ); 861 } 862 }); 863 } 864 } 865 }, 866 867 868 869 /** 870 * jQuery.hide 871 * @function 872 * @name hide 873 * @memberOf sg 874 * @example 875 * sg.hide( 'p' ); //$( 'p' ).hide(); 876 * sg.hide( this ); //$( this ).hide(); 877 * @param {object} elementOrSelector 878 */ 879 hide: function( elementOrSelector ){ 880 $( elementOrSelector ).hide(); 881 }, 882 883 /** 884 * jQuery.show 885 * @function 886 * @name show 887 * @memberOf sg 888 * @example 889 * sg.show( 'p' ); //$( 'p' ).show(); 890 * sg.show( this ); //$( this ).show(); 891 * @param {object} elementOrSelector 892 */ 893 show: function( elementOrSelector ){ 894 $( elementOrSelector ).show(); 895 }, 896 897 /** 898 * jQuery.fadeIn("slow") 899 * @function 900 * @name fadeIn 901 * @memberOf sg 902 * @example 903 * sg.fadeIn( 'p' ); //$( 'p' ).fadeIn( 'slow' ); 904 * sg.fadeIn( this ); //$( this ).fadeIn( 'slow' ); 905 * @param {object} elementOrSelector 906 */ 907 fadeIn: function( elementOrSelector ){ 908 $( elementOrSelector ).fadeIn("slow"); 909 }, 910 911 /** 912 * jQuery.fadeOut("slow") 913 * @function 914 * @name fadeOut 915 * @memberOf sg 916 * @example 917 * sg.fadeOut( 'p' ); //$( 'p' ).fadeOut( 'slow' ); 918 * sg.fadeOut( this ); //$( this ).fadeOut( 'slow' ); 919 * @param {object} elementOrSelector 920 */ 921 fadeOut: function( elementOrSelector ){ 922 $( elementOrSelector ).fadeOut("slow"); 923 }, 924 925 /** 926 * Deshabilitar los eventos en el componente, y configura el cursor como puntero. 927 * @function 928 * @name enabled 929 * @memberOf sg 930 * @example 931 * sg.enabled( this ); 932 * sg.enabled( '#myButton' ); 933 * sg.enabled( $.getCustomTag( 'sg-btn-hide' ) ); 934 * @param {object} elementOrSelector 935 * @returns objeto de jQuery 936 * @type jQuery Object 937 */ 938 enabled: function ( elementOrSelector ){ 939 return $(elementOrSelector).each(function(i,e){ 940 var $this = $(this); 941 $this.css("cursor","pointer"); 942 var options = $this.data("options") || {}; 943 options.enabled = true; 944 $this.data("options", options); 945 }); 946 }, 947 948 /** 949 * Deshabilitar los eventos en el componente, y configura el cursor por defecto. 950 * @function 951 * @name disabled 952 * @memberOf sg 953 * @example 954 * sg.disabled( this ); 955 * sg.disabled( '#myButton' ); 956 * sg.disabled( $.getCustomTag( 'sg-btn-hide' ) ); 957 * @param {object} elementOrSelector 958 * @returns objeto de jQuery 959 * @type jQuery Object 960 */ 961 disabled: function ( elementOrSelector ){ 962 return $(elementOrSelector).each(function(i,e){ 963 var $this = $(this); 964 $this.css("cursor","default"); 965 var options = $this.data("options") || {}; 966 options.enabled = false; 967 $this.data("options", options); 968 }); 969 } 970 }); 971 972 sg.extend({ 973 /** 974 * En el caso de que se pase la función (callback) como función de inicialización o parámetro, se ejecuta primero la inicialización y luego la función.<br> 975 * En el caso de sg.init(), se ejecuta primero html content(contenido de html) internamente y la inicialización.<br> 976 * Si hay algo que se debe ejecutar después de la inicialización, se pasa la función (callback) al parámetro de init(). 977 * @function 978 * @name init 979 * @memberOf sg 980 * @example 981 * sg.setStage( "#stage" ); 982 * sg.setScaleMode( "showall" ); 983 * sg.init(); 984 * @example 985 * sg.setStage( "#stage" ); 986 * sg.setScaleMode( "showall" ); 987 * sg.init( function(){} ); 988 * @param {function} [callback=undefined] 989 */ 990 init: function ( callback ) { 991 function _init(){ 992 //////setting 993 //console.log("setting"); 994 $body = $( document.body ); 995 996 replaceTagList(); 997 998 if( setStageFunc ){ 999 setStageFunc.apply( sg ); 1000 setStageFunc = null; 1001 } 1002 1003 ///compatibility for old versions 1004 if( "init" in window && sg.isFunction( window[ "init" ] ) ){ 1005 window[ "init" ].apply( window ); 1006 } 1007 1008 if( "initList" in window ){ 1009 initCallbackList = initCallbackList.concat( window[ "initList" ] ); 1010 } 1011 /// 1012 1013 initCallbackList.forEach( function( initFunc ){ 1014 if( sg.isFunction( initFunc ) ) initFunc.apply( window ); 1015 }); 1016 1017 1018 $("[data-sg-id='progressImg']").remove(); 1019 $content = $("[data-sg-id='content']").css( "visibility", "visible" ); 1020 $stage = $("[data-sg-id='stage']"); 1021 sg.isReady = true; 1022 1023 setTimeout(function(){ 1024 $window.trigger("resize"); 1025 }, 0); 1026 } 1027 1028 if( $.isReady ){ 1029 _init.apply( window ); 1030 if( sg.isFunction( callback ) ) callback.apply( window ); 1031 }else{ 1032 $( document ).ready(function(e) { 1033 _init.apply( window ); 1034 if( sg.isFunction( callback ) ) callback.apply( window ); 1035 }); 1036 } 1037 } 1038 }); 1039 1040 window.sg = sg; 1041 1042 return sg; 1043 })();