1/** 2 * Yellow 3 * enrich html with javascript in a clean, non-complicated way 4 * Yellow uses jquery, so include that before Yellow. Config is done through data- attributes 5 * 6 * Example usage 7 * ------------- 8 * <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script> 9 * <script 10 * type="text/javascript" 11 * src="vendor/yellow/Yellow.js" 12 * data-main="js/build/build.js" <!-- Location to load built script from --> 13 * data-src="js/" <!-- Location to load scripts from when they are not included --> 14 * data-console="1" <!-- Whether output should be sent to the console with y.log --> 15 * ></script> 16 * 17 * 18 * 19 * The following steps are taken on startup 20 * 1. The url provided in data-main is loaded 21 * 2. The document is scanned for html elements that have attribute y-use 22 * 3. Scripts are loaded for all space separated paths that are provided in these html-elements under y-use="path path path" 23 * 4. For all elements a definition-instance is created for each provided path 24 * 5. the 'start' function is called on all instances 25 * 26 * 27 * HTML example snippet 28 * -------------------- 29 * <div y-use="people.List"> 30 * <span y-name="header">This is a list</span> 31 * </div> 32 * 33 * Script example snippet 34 * ---------------------- 35 * define('people.List') // Create e definition under the same name 36 * .use('people.Helper') // Use some other script. 37 * .use('http://libary', 'globalname') // Use some vendor script. When it registers as a global, pass along the name of the global 38 * .as(function(y, helper, external){ // The class that is used for the elemens 39 * this.start = function(scope){ // init function receives jQuery(element) (scope) 40 * 41 * } 42 * }); 43 * 44 * Templates can be defined in two places: In the html or in the definition. 45 * 46 * HTMl template definition: 47 * ------------------------ 48 * <div y-use="people.List"> 49 * <script type="text/html" y-name="person.html"> 50 * <div> 51 * <span>{{firstname}}</span><br /> 52 * <span>{{lastname}}</span> 53 * </div> 54 * </script> 55 * </div> 56 * 57 * 58 * Script template definition 59 * When a tempalte is defined in the componenet, the second argument will be a template function 60 * to access the defined tempaltes 61 * -------------------------- 62 * define('people.List') 63 * .template('person.script' , '\ 64 * <div>\ 65 * <span>{{firstname}}</span><br />\ 66 * <span>{{lastname}}</span> 67 * </div>') 68 * .as(function(y, template){ 69 * this.init = function(scope){ 70 * y.log(scope.template('person.html')); 71 * y.log(template('person.script')); 72 * } 73 * }); 74 * 75 */ 76(function(document, window, jQuery) 77{ 78 /** 79 * Get executing (this) script node 80 * use currentScript for everythis but IE11: fall back on last script for IE 81 */ 82 var script = document.currentScript ? jQuery(document.currentScript) : script = jQuery('script').last(); 83 84 /** 85 * Config object that gets it's vars from the script html attributes 86 * @type Object 87 */ 88 var __config = { 89 define: script.data('define') || 'define', 90 main: script.data('main') || false, 91 src: script.data('src') || '', 92 console: script.data('console') || false 93 }; 94 95 96 /** 97 * The public yellow object that will be available in the global namespace 98 * under the configured name 99 * Call it with a html element as argument and a jQuery wrapped element will be returned 100 * Loaded script will use the global object to call define() to register themselves 101 * Also helper functions like is[Type](), outer() and log() 102 * 103 * @type Object 104 */ 105 var __public = function(element) { 106 return jQuery(element); 107 }; 108 109 110 /** 111 * Add Yellow helpers to jQuery 112 * start: start up an element 113 * element: get an element with y-name="name" 114 */ 115 jQuery.fn.extend({ 116 117 /** 118 * attach a definition-instance to an alement, so it can be used to call invoke 119 */ 120 attach: function(instance){ 121 // get domnode 122 var node = this[0]; 123 // add array with attached instances to the htmlnode 124 if(!__public.isSet(node.instances)){ 125 node.instances = []; 126 } 127 // add the instance to the used instances array on the node 128 node.instances.push(instance); 129 //chainable 130 return this; 131 }, 132 133 /** 134 * Start up a portion of a document 135 * @returns void 136 */ 137 start: function(handlers){ 138 // alias for this 139 var scope = this; 140 141 // add events on elements in scope and scope itself 142 var emitters = scope.find('[y-on]'); 143 if(scope.attr('y-on')) { 144 emitters = emitters.add(scope); 145 } 146 emitters.each(function(){ 147 // attribute has the form: click touchstart|stop:dosomething(1) ~ mouseover|stop:dosomethingelse(1 + 4) 148 var emitter = jQuery(this); 149 var attr = emitter.attr('y-on'); 150 emitter.removeAttr('y-on'); 151 var statements = attr.split('~'); 152 for(var i = 0; i < statements.length; i++) { 153 // add handler 154 emitter.handler(statements[i], handlers); 155 } 156 }); 157 158 // get named elements from scope and scope itself 159 // so we can save the original html and make a fresh copy later 160 var named = scope.find('[y-name]'); 161 if(scope.attr('y-name')) { 162 named = named.add(scope); 163 } 164 165 named.each(function(){ 166 // save the original html, so we can make a fresh copy later 167 this.__html = this.outerHTML; 168 }); 169 170 // get elements from scope and scope itself 171 var use = scope.find('[y-use]'); 172 if(scope.attr('y-use')) { 173 use = use.add(scope); 174 } 175 176 // the elements by definition path 177 var elements = {}; 178 use.each(function(){ 179 // save the original html, so we can make a fresh copy later 180 this.__html = this.outerHTML; 181 // the element 182 var element = jQuery(this); 183 // get used paths: spaceseparated names 184 var paths = element.attr('y-use').split(' '); 185 for(var i = 0; i < paths.length; i++){ 186 var path = paths[i].trim(); 187 if(path.length > 0){ 188 // if it doesnt exist, create an array for it 189 if(!__public.isSet(elements[path])){ 190 elements[path] = []; 191 } 192 // add to the instances dictionary 193 elements[path].push(element); 194 // add it to the used definitions list 195 __loader.add(path); 196 } 197 } 198 }); 199 200 // Tell loader to process the queue 201 // and pass a callback function 202 __loader.process(function(){ 203 // loader queue has resolved: 204 // create an instance for each used definition 205 // call start on all instances after instantiatiion 206 var instances = []; 207 208 for(var path in elements){ 209 // get the definition 210 var definition = __public.get(path); 211 // check if it exists 212 if(!definition){ 213 throw new Error('Unknown definition: ' + path + '. ') 214 } 215 // make an instance for all the elements with this name 216 for(var i = 0; i < elements[path].length; i++){ 217 // get element 218 var element = elements[path][i]; 219 // create instance 220 var instance = definition.__instance(); 221 // attach the definition to the instance so it is invovakable 222 element.attach(instance); 223 224 // keep track of all the instance / element pairs, so they can be started later 225 instances.push({ 226 instance: instance, 227 element: element 228 }); 229 } 230 } 231 // start all the instances at once 232 // if one instance calls invoke on another, this way they will at least all be created at that moment 233 // if invoke was called before __init (and therefore before start()), the invoke method will take care of that 234 for(var j = 0; j < instances.length; j++){ 235 instances[j].instance.__init( instances[j].element ); 236 } 237 }); 238 239 // chainable 240 return scope; 241 }, 242 243 244 /** 245 * Add an eventhandler 246 * Will use methods in handler, but will also look at all exposed methods in attached instances up to body 247 * And call the all. 248 * Unless the stop filter is given 249 * 250 * @param string statement of the form click touchstart|stop:dosomething(1) or click touchstart|stop:dosomething 251 * @param object handlers named callbacks that can be referenced in the expression 252 */ 253 handler: function(statement, handlers) { 254 // the element that receives the event 255 var scope = this; 256 257 // retreive the correct parts from the statement 258 var parts = statement.split(':'); 259 var event = parts[0]; 260 var filters = event.split('|'); 261 event = filters.shift(); 262 var expression = __public.isSet(parts[1]) ? parts[1].trim().replace(/\$e/g, 'e').replace(/\$this/g, '__public(scope)') : ''; 263 var handler = expression.split('(')[0].trim(); 264 265 // make sure handlers is an object 266 if(! __public.isObject(handlers)) { 267 handlers = {}; 268 } 269 270 // normalize filters 271 var stop = false;
272 var prevent = false; 273 for(var i = 0; i < filters.length; i++){ 274 if(filters[i] === 'stop'){ 275 stop = true; 276 } 277 if(filters[i] === 'prevent'){ 278 prevent = true; 279 } 280 } 281 282 // finally, register the event 283 scope.on(event, function(e){ 284 // use filters 285 if(stop){ 286 e.stopPropagation(); 287 } 288 if(prevent){ 289 e.preventDefault(); 290 } 291 292 // try to find a function to use as callback 293 var fn = null; 294 if(__public.isFunction(handlers[handler])) { 295 // function is given in the provided handlers 296 fn = handlers[handler]; 297 } else { 298 // function not given, traverse up to find a usable function in y-use instances 299 var receiver = scope.parents('[y-use]'); 300 while(receiver.length > 0 && fn === null) { 301 if(__public.isArray(receiver[0].instances)) { 302 var instances = receiver[0].instances; 303 for(var i = 0; i < instances.length; i++){ 304 if(__public.isFunction(instances[i][handler])){ 305 fn = instances[i][handler]; 306 break; 307 } 308 } 309 } 310 receiver = receiver.parents('[y-use]'); 311 } 312 } 313 if(__public.isFunction(fn)) { 314 if(handler !== expression) { 315 (function(___fn___) { 316 eval ('var ' + handler + ' = ___fn___; ' + expression + ';'); 317 })(fn); 318 } else { 319 fn.call(scope, e); 320 } 321 } 322 }); 323 }, 324 325 326 /** 327 * Get a html element with y-name attribute 328 * @param string name 329 * @param string method jquery method to use instead of 'find' 330 * @returns element 331 */ 332 fetch: function(name, method) { 333 if(! __public.isSet(name)){ 334 var found = this.find('[y-name]:not(script)'); 335 336 var elements = {}; 337 found.each(function(index, element){ 338 element = jQuery(element); 339 var names = element.attr('y-name').split(' '); 340 for(var i = 0; i < names.length; i++) { 341 if(__public.isSet(elements[names[i]])) { 342 // add to jquery resultset 343 elements[names[i]] = elements[names[i]].add(element); 344 } else { 345 // add jquery element 346 elements[names[i]] = element; 347 } 348 } 349 }); 350 351 return elements; 352 } else { 353 if(! __public.isSet(method)){ 354 method = 'find'; 355 } 356 return this[method]('[y-name~="' + name + '"]:not(script)'); 357 } 358 359 }, 360 361 362 /** 363 * Call a method on an element that has a Yellow component instance tied to it 364 * In case of multiple components, the first available method with the name will be called and that's it. 365 * @param string method 366 * @returns mixed 367 */ 368 invoke : function(method){ 369 // get the real dom element, as the used array is attached there 370 var node = this[0]; 371 // check if it exists and if there is a 'used' array 372 if(__public.isSet(this[0]) && __public.isArray(this[0].instances)){ 373 // check on all the used instances if there are 374 for(var i = 0; i < node.instances.length; i++){ 375 // check is there is a method with the supplied name 376 if(__public.isFunction(node.instances[i][method])){ 377 var instance = node.instances[i]; 378 // call __init first, just to be sure. If it was called before, that's ok, as init will only run once 379 // the argument is the element 380 instance.__init(this); 381 // shift the first argument (the method name) 382 var args = Array.prototype.slice.call(arguments); 383 args.shift(); 384 // call the method with the remaining arguments 385 return instance[method].apply(instance, args); 386 } 387 } 388 } 389 }, 390 391 392 /** 393 * Get a html contents of a script with the name y-[name] 394 * @param String name 395 * @returns string 396 */ 397 template: function(name){ 398 return this.find('script[y-name~="'+name+'"]').html(); 399 }, 400 401 402 /** 403 * Create a copy of an element 404 * @param Booelan start If true is passed, the element will be started automatically 405 */ 406 make: function(start) 407 { 408 if(this[0].__html) { 409 var element = __public(this[0].__html); 410 } else { 411 var element = __public(this[0].outerHTML); 412 } 413 if(start) { 414 element.start(); 415 } 416 return element; 417 } 418 }); 419 420 421 422 /** 423 * Properties that will be copied over to the __public object 424 * we could have writen this as __public.prop = ..., but this is shorter 425 * Will be removed after copying 426 * @type Object 427 */ 428 var properties = { 429 /** 430 * Globals 431 */ 432 document: jQuery(document), 433 window: jQuery(window), 434 script: script, 435 jQuery: jQuery, 436 437 /** 438 * Definitions 439 */ 440 definitions: {}, 441 442 /** 443 * Create a definition and set it 444 * returns a creator object that can be used to further fill in the definition 445 * @param string path 446 * @returns Object 447 */ 448 define: function(path){ 449 // create a new definition 450 var definition = new __Definition(); 451 // store it 452 __public.set(path, definition); 453 // let the loader know this path was loaded and resolve it. 454 // this is used when we load a prcompiled buncle of scripts 455 __loader.resolve(path); 456 // return definition creator to chain additional commands 457 return definition.creator; 458 }, 459 460 /** 461 * Set a definition 462 * @param string path 463 * @param Object definition 464 * @returns void 465 */ 466 set: function(path, definition) { 467 // check if name is ok 468 if(!__public.isString(path) || ! /^[a-zA-Z0-9\-_\.\:]+$/.test(path)){ 469 throw new Error('Trying to define without a valid name: ' + path); 470 } 471 if(__public.isSet(__public.definitions[path])){ 472 __public.log('Redefining previously defined ' + path); 473 } 474 __public.definitions[path] = definition; 475 }, 476 477 /** 478 * Get a definition 479 * @param string path 480 * @returns Object 481 */ 482 get: function(path) { 483 if(__public.isSet(__public.definitions[path])) { 484 return __public.definitions[path]; 485 } 486 }, 487 488 489 /** 490 * Run a definition 491 * @param string path 492 * @returns {undefined} 493 */ 494 run: function(path) { 495 // add the path to the loader 496 __loader.add(path); 497 // process the queue 498 __loader.process(function(){ 499 // get the definition 500 var definition = __public.get(path); 501 // check if it exists 502 if(!definition){ 503 throw new Error('Unknown definition: ' + path + '. ') 504 } 505 // create instance 506 var instance = definition.__instance(); 507 // get extra arguments passed to run 508 var args = Array.prototype.slice.call(arguments); 509 args.shift(); 510 // call the __init method with the remaining arguments and return the result 511 instance.__init.apply(instance, args); 512 }); 513 }, 514 515 516 /** 517 * Get outer yellow instance 518 * @returns {window} 519 */ 520 outer: function() { 521 var traverse = window; 522 var outer = window; 523 // walk through parents to find outermost window with yellow defined 524 // if one is found, use that as yellow 525 while(traverse.parent.location !== traverse.location){ 526 traverse = traverse.parent; 527 if(traverse.globalYellowInstance !== null){ 528 outer = traverse; 529 } 530 } 531 return outer.globalYellowInstance; 532 }, 533 534 /** 535 * Testers for value type 536 */ 537 isString: function(mixed) { 538 return this.isType(mixed,'[object String]'); 539 }, 540 isArray: function(mixed){ 541 return this.isType(mixed,'[object Array]'); 542 }, 543 isPlainObject: function(mixed){ 544 if (typeof mixed == 'object' && mixed !== null) { 545 if (typeof Object.getPrototypeOf == 'function') { 546 var proto = Object.getPrototypeOf(mixed); 547 return proto === Object.prototype || proto === null; 548 } 549 return Object.prototype.toString.call(mixed) == '[object Object]'; 550 } 551 return false;
552 }, 553 isObject: function(mixed){ 554 if(this.isSet(mixed) === false){ 555 return false; 556 } else { 557 return this.isType(mixed,'[object Object]'); 558 } 559 }, 560 isFunction: function(mixed){ 561 return this.isType(mixed,'[object Function]'); 562 }, 563 isNumeric: function(mixed){ 564 return !isNaN(mixed); 565 }, 566 isNumber: function(mixed){ 567 return this.isType(mixed,'[object Number]'); 568 }, 569 isInt: function(mixed){ 570 return !isNaN(parseInt(mixed,10)) && (parseFloat(mixed,10) === parseInt(mixed,10)); 571 }, 572 isFloat: function(mixed){ 573 return this.isNumber(mixed) === true && this.isInt(mixed) === false; 574 }, 575 isSet: function(mixed){ 576 return !(typeof mixed === 'undefined' || mixed === null); 577 }, 578 isNull: function(mixed){ 579 return mixed === null; 580 }, 581 isType: function(mixed, type) { 582 return Object.prototype.toString.call( mixed ) === type; 583 }, 584 585 /** 586 * Helper: log a variable to console 587 * @param {mixed} variable 588 * @returns {void} 589 */ 590 log: function(variable, showLineNr) { 591 if(__config.console && window.console && window.console.log){ 592 window.console.log(variable); 593 if(showLineNr !== false){ 594 var error = new Error(); 595 if(error.stack){ 596 window.console.log(error.stack.split("\n")[2]); 597 } 598 } 599 } 600 }, 601 ajax: jQuery.ajax 602 }; 603 604 // copy over the properties to yellow and remove var 605 for(var name in properties){ 606 __public[name] = properties[name]; 607 } 608 properties = null; 609 610 611 /** 612 * Loader object that loads scripts 613 */ 614 var __loader = { 615 616 // the queue that holds paths that should be loaded 617 queue: [], 618 619 // object that holds paths that are still loading 620 pending: {}, 621 622 // object that holds loaded paths 623 loaded: {}, 624 625 /** 626 * load a single script from an url, call done when done 627 * @param string url 628 * @param function done 629 * @returns void 630 */ 631 load: function(url, done){ 632 // create script tag to load the script 633 var parent = document.getElementsByTagName('body')[0]; 634 var script = document.createElement('script'); 635 script.src = url; 636 script.setAttribute('async', false); 637 // callback for the script load 638 var callback = function(result){ 639 //help garbage collection 640 script.onload = null; 641 script.onerror = null; 642 script.onreadystatechange = null; 643 script.ontimeout = null; 644 parent.removeChild(script); 645 // call callbacks 646 if(__public.isFunction(done)){ 647 done(result); 648 } 649 }; 650 // add callback 651 if(script.addEventListener){ 652 // Modern browsers 653 script.onload = function(){ 654 callback('done'); 655 }; 656 script.onerror = function(){ 657 callback('fail'); 658 }; 659 } else if(script.readyState) { 660 // IE 8- 661 script.onreadystatechange = function(){ 662 if(script.readyState == 'loaded' || script.readyState == 'complete'){ 663 callback('done'); 664 } 665 }; 666 script.ontimeout = function(){ 667 callback('fail'); 668 }; 669 } 670 // add script to the page to start loading 671 parent.appendChild(script); 672 }, 673 674 /** 675 * Add a path to the queue 676 * 677 * @param string path 678 * @param string globalName when using an extrernal library, there will probably be a global var available to use 679 * @returns void 680 */ 681 add: function(path){ 682 __loader.queue.push(path); 683 }, 684 685 /** 686 * Process the queue 687 * @param function done 688 * @returns void 689 */ 690 process: function(done){ 691 // load elements still in the queue 692 while(__loader.queue.length > 0) { 693 var path = __loader.queue.shift(); 694 if(! __loader.loaded[path] && ! __loader.pending[path]){ 695 696 // start loading: add this element to the pending scripts 697 __loader.pending[path] = true; 698 if(path.indexOf('http://') === 0 || path.indexOf('https://') === 0 || path.indexOf('//') === 0){ 699 // absolute url given 700 var src = path; 701 } else { 702 // dotted path given: create a url 703 var src = __config.src + path.split('.').join('/') + '.js' 704 } 705 706 // go get it 707 __loader.load(src, (function(p){ 708 return function(result) { 709 if(result === 'fail') { 710 throw new Error('Failed to load script: ' + p); 711 } 712 // resolve path 713 __loader.resolve(p); 714 715 // try processing the loader again 716 __loader.process(done); 717 }; 718 })(path)); 719 } else if(__loader.loaded[path]) { 720 // path was already loaded before: resolve it. 721 __loader.resolve(path); 722 } 723 } 724 725 // check if there are pending files 726 var pending = false;
727 for(var i in __loader.pending){ 728 if(__loader.pending[i] === true){ 729 pending = true; 730 break; 731 } 732 } 733 734 // no pending files: callback! 735 if(! pending) { 736 done(); 737 } 738 }, 739 740 /** 741 * Remove a path from pending and add it to loaded 742 * @param {type} path 743 * @returns {undefined} 744 */ 745 resolve: function(path){ 746 // remove this path from pending 747 delete __loader.pending[path]; 748 // set it to loaded instead, so we dont load it twice. 749 __loader.loaded[path] = true; 750 } 751 }; 752 753 754 /** 755 * A definition instance contains an object called 'creator' 756 * When __public.define is called, a new definition is created and the creator object is returned. 757 * A creator object is used to add dependencies, templates, and static properties to the definition 758 * Lastly the .as function should be called to finalize the definition. 759 * 760 * When a the argument for 'as' is a function, a call to .make will reutn a new instance of the function 761 * after that, the 'init' function will be called on the new instance, if available with the supplied argumens 762 * 763 * @returns Object 764 */ 765 var __Definition = function() 766 { 767 // array with dependencies to load 768 var _use = []; 769 770 // templates 771 var _templates = {}; 772 773 // the public definition 774 // only contains a make function 775 // but will receive additional properties while defining 776 var _definition = { 777 778 // this yellow object for use in static definitions as this.yellow or this.y 779 y: __public, 780 yellow: __public, 781 782 // make templates available in defintitions as this.template() 783 template: function(name){ 784 if(__public.isSet(_templates[name])){ 785 return _templates[name]; 786 } 787 }, 788 789 /** 790 * Set of creator functions that allow modules to define themselves 791 */ 792 creator: { 793 794 /** 795 * set dependencies 796 */ 797 use: function(path, globalName) { 798 // add it to the use array 799 _use.push([path, globalName]); 800 // chainable 801 return this; 802 }, 803 804 /** 805 * Set static vars & methods 806 */ 807 set: function(object) { 808 if(! __public.isObject(object)){ 809 // check if static data is valid 810 throw new Error('Trying to set invalid data: ' + object); 811 return; 812 } 813 // copy over properties 814 for(var i in object){ 815 _definition[i] = object[i]; 816 } 817 // chainable 818 return this; 819 }, 820 821 822 /** 823 * Set template 824 */ 825 template: function(name, template) { 826 // store template under name 827 _templates[name] = template; 828 // chainable 829 return this; 830 }, 831 832 /** 833 * This is the closing call for a definition 834 * Either pass an object with additional properties or a constructor function 835 * no extra calls, so not chainable 836 * Cleanup & load dependencies afterwards 837 */ 838 as: function(definition) { 839 840 if(__public.isFunction(definition)){ 841 // create an __instance method to create an instance 842 _definition.__instance = function() { 843 // variable arguments for constructor. 844 // always start with yellow 845 var args = [null, __public]; 846 847 // add dependencies 848 for(var i = 0; i < _use.length; i++){ 849 if(__public.isString(_use[i][1])){ 850 // a global name was given: 851 // this is a vendor file that registers under a global name 852 args.push(window[_use[i][1]]); 853 } else { 854 args.push(__public.get(_use[i][0])); 855 } 856 } 857 858 // add template function if there are templates 859 if(Object.keys(_templates).length > 0){ 860 args.push(_definition.template) 861 } 862 863 // add the defintion itself as last argument, so we have access to static vars 864 args.push(_definition); 865 866 867 // create instance with variable arguments 868 // check StackOverflow for how this works 869 var instance = new (Function.prototype.bind.apply(definition, args)); 870 871 // add init function that calls start and cleans up start itself 872 instance.__init = function() { 873 if(__public.isFunction(instance.start)){ 874 // get the function 875 var fn = instance.start; 876 // start can only run once. so remove it 877 instance.start = null; 878 // pass along arguments that were given to __init() 879 fn.apply(instance, arguments); 880 } 881 }; 882 883 return instance; 884 }; 885 886 // convenient shortcut to call __instantiate() and __init() in order 887 _definition.make = function() { 888 // create instance 889 var instance = _definition.__instance(); 890 // pass along arguments that were given to make() 891 instance.__init.apply(null, arguments); 892 // return it 893 return instance; 894 }; 895 896 } else if(__public.isObject(definition)){ 897 // copy over extra stuff from definition to _definition 898 for(var i in definition){ 899 _definition[i] = definition[i]; 900 } 901 } else { 902 // error 903 throw new Error('Trying to define without a valid constructor or object'); 904 } 905 906 // remove creator object 907 delete _definition.creator; 908
909 // load dependencies defined in 'use' 910 // by adding the to the loader queue 911 for(var i = 0; i < _use.length; i++){ 912 __loader.add(_use[i][0], _use[i][1]); 913 } 914 915 // make define.as. chainable 916 return __public; 917 } 918 } 919 }; 920 return _definition; 921 }; 922 923 924 // make a public define function that calls __public.define 925 window.globalYellowInstance = __public; 926 window[__config.define] = function(name){ 927 return __public.define(name) 928 }; 929 930 // error handler 931 window.addEventListener('error', function (e) { 932 e.preventDefault(); 933 var message = ''+e.filename+':' + e.lineno + ': ' + e.message; 934 __public.log(message, false); 935 }); 936 937 938 if(__config.main){ 939 // load main if one was given 940 __loader.load(__config.main, function(){ 941 // when done, process the dependencies set by main 942 __loader.process(function(){ 943 // when that is done, start app with document as the scope 944 __public(document).start(); 945 }); 946 }); 947 } else { 948 // just start it, when no main was given 949 __public(document).start(); 950 } 951 952 // make chainable 953 return __public; 954})(document, window, jQuery)
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.