├── xa └── data.json ├── .gitignore ├── LICENSE.txt ├── sprint.min.js └── sprint.js /xa/data.json: -------------------------------------------------------------------------------- 1 | {"date":"2024-05-04T17:20:32+00:00"} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp JpjOI3olEI 2 | .DS_Store PI9KV66ssf 3 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015 Benjamin De Cock 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: lrBPyxYwf2 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. CYCw825AUn 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sprint.min.js: -------------------------------------------------------------------------------- 1 | // Sprint v0.9.2 - sprintjs.com/license 2 | var Sprint; 3 | (function(){var D=function(a,b){for(var c=Sprint(b),d=Object.keys(a),e=d.length,f=0;fa?d:a):d==window?window["inner"+a]:d.getBoundingClientRect()[b]}var e="function"==typeof c,f=e?"":w(b,c);return a.each(function(a){this==document||this== 6 | window||1 9 | Object.keys(a.sprintEventListeners).filter(function(a){return q(b)[0]===q(a)[0]}).map(function(b){return a.sprintEventListeners[b]}).reduce(function(a,b){return a.concat(b)}).filter(function(a){return a===c}).length?!1:!0},b=function(b,c,f){return function(g){f&&f!==g||(b.removeEventListener(c,g),/\./.test(c)&&!a(b,c,g)&&b.removeEventListener(q(c)[0],g))}},c=function(a,b){return a.filter(function(a){return b&&b!==a})};return function(a,e){return function(f){a.sprintEventListeners[f].forEach(b(a,f, 10 | e));a.sprintEventListeners[f]=c(a.sprintEventListeners[f],e)}}}(),M=function(a,b){return function(c){F(a,c).forEach(H(a,b))}},m=document.documentElement,A=function(a,b,c){for(var d=a.length,e=d;e--;)if(!a[e]&&0!==a[e]||b&&a[e]instanceof n||c&&("string"==typeof a[e]||"number"==typeof a[e])){for(var e=[],f=0;fe?m:document.body}if(null==d){b=b.get(0);if(!b)return;if(b==window||b==document)b=a;return b[c]}return b.each(function(){var b=this;if(b==window||b==document)b=a;b[c]=d})}}(),y=function(a,b,c,d){var e=[],f=b+"ElementSibling";a.each(function(){for(var b=this;(b=b[f])&&(!d||!a.is(d,b));)c&&!a.is(c,b)||e.push(b)});return Sprint(x(e))},J=function(a,b,c){var d=b+"ElementSibling";return a.map(function(){var b= 12 | this[d];if(b&&(!c||a.is(c,b)))return b},!1)},r=function(a,b){b=b||document;if(/^[\#.]?[\w-]+$/.test(a)){var c=a[0];return"."==c?t(b.getElementsByClassName(a.slice(1))):"#"==c?(c=b.getElementById(a.slice(1)))?[c]:[]:"body"==a?[document.body]:t(b.getElementsByTagName(a))}return t(b.querySelectorAll(a))},q=function(a){return A(a.split("."))},t=function(a){for(var b=[],c=a.length;c--;)b[c]=a[c];return b},C=function(){var a=function(a,c){var d=Sprint(a).clone(!0).get(0),e=d;if(d&&!(1",outro:""}, 14 | area:{intro:"",outro:""},param:{intro:"",outro:""},thead:{intro:"",outro:"
"},tr:{intro:"",outro:"
"},col:{intro:"",outro:"
"},td:{intro:"",outro:"
"}};["tbody","tfoot","colgroup","caption"].forEach(function(a){u[a]=u.thead});u.th=u.td;var n=function(a,b){if("string"==typeof a)if("<"==a[0]){var c=document.createElement("div"),d=/[\w:-]+/.exec(a)[0], 15 | d=u[d],e=a.trim();d&&(e=d.intro+e+d.outro);c.insertAdjacentHTML("afterbegin",e);e=c.lastChild;if(d)for(d=d.outro.match(/a&&(a+=this.length);return this.dom[a]}, 22 | has:function(a){if("string"==typeof a)return this.map(function(){if(!(1b?f+=b:0<=b&&(f=b>this.length?this.length:b);e 1) return 96 | 97 | // Duplicate event listeners for the parent element... 98 | var listeners = getEvents(el) 99 | listeners && addEventListeners(listeners, clone) 100 | 101 | // ... and its descendants. 102 | var descendants = selectElements("*", el) 103 | var descendantsLen = descendants.length 104 | 105 | // cloneDescendants is defined later to avoid calling selectElements() if not needed 106 | var cloneDescendants 107 | 108 | for (var i = 0; i < descendantsLen; i++) { 109 | var listeners = getEvents(descendants[i]) 110 | if (!listeners) continue 111 | if (!cloneDescendants) { 112 | cloneDescendants = selectElements("*", clone) 113 | } 114 | addEventListeners(listeners, cloneDescendants[i]) 115 | } 116 | } 117 | 118 | var findAncestors = function(startAtParent, limitToParent, limitToFirstMatch, selector, context) { 119 | var dom = [] 120 | var self = this 121 | this.each(function() { 122 | var prt = startAtParent ? this.parentElement : this 123 | while (prt) { 124 | if (context && context == prt) break 125 | if (!selector || self.is(selector, prt)) { 126 | dom.push(prt) 127 | if (limitToFirstMatch) break 128 | } 129 | if (limitToParent) break 130 | prt = prt.parentElement 131 | } 132 | }) 133 | return Sprint(removeDuplicates(dom)) 134 | } 135 | 136 | var getEventFromNamespace = function(event) { 137 | return splitNamespaces(event)[0] 138 | } 139 | 140 | var getEvents = function(domElement) { 141 | return domElement.sprintEventListeners 142 | } 143 | 144 | var getEventsToRemove = function(domElement, event) { 145 | /* 146 | * Returns an array with the sprintEventListeners events matching potentially 147 | * incomplete event names passed to .off(). 148 | * Example: .off("click.myPlugin") and .off("click.simple") would both remove a 149 | * "click.myPlugin.simple" event. 150 | */ 151 | return Object.keys(getEvents(domElement)).filter(function(prop) { 152 | return splitNamespaces(event).every(function(name) { 153 | return inArray(name, splitNamespaces(prop)) 154 | }) 155 | }) 156 | } 157 | 158 | var getSetDimension = function(obj, prop, value) { 159 | // get 160 | if (value == null) { 161 | var el = obj.get(0) 162 | if (!el || el.nodeType > 1) return 163 | var capitalizedProp = prop[0].toUpperCase() + prop.substring(1) 164 | // dimension of HTML document 165 | if (el == document) { 166 | var offset = root["offset" + capitalizedProp] 167 | var inner = window["inner" + capitalizedProp] 168 | return offset > inner ? offset : inner 169 | } 170 | // dimension of viewport 171 | if (el == window) { 172 | return window["inner" + capitalizedProp] 173 | } 174 | // dimension of element 175 | return el.getBoundingClientRect()[prop] 176 | } 177 | 178 | // set 179 | var isFunction = typeof value == "function" 180 | var stringValue = isFunction ? "" : addPx(prop, value) 181 | return obj.each(function(index) { 182 | if (this == document || this == window || this.nodeType > 1) return 183 | if (isFunction) { 184 | stringValue = addPx(prop, value.call(this, index, Sprint(this)[prop]())) 185 | } 186 | this.style[prop] = stringValue 187 | }) 188 | } 189 | 190 | var insertHTML = function(position, args) { 191 | var argsLen = args.length 192 | var contents = args 193 | 194 | // reverse argument list for afterbegin and afterend 195 | if (argsLen > 1 && position.indexOf("after") > -1) { 196 | contents = [] 197 | var i = argsLen 198 | while (i--) { 199 | contents.push(args[i]) 200 | } 201 | } 202 | 203 | for (var i = 0; i < argsLen; i++) { 204 | var content = contents[i] 205 | if (typeof content == "string" || typeof content == "number") { 206 | this.each(function() { 207 | this.insertAdjacentHTML(position, content) 208 | }) 209 | } 210 | else if (typeof content == "function") { 211 | this.each(function(index) { 212 | var callbackValue = content.call(this, index, this.innerHTML) 213 | insertHTML.call(Sprint(this), position, [callbackValue]) 214 | }) 215 | } 216 | else { 217 | var isSprintObj = content instanceof Init 218 | var clonedElements = [] 219 | var elementsToInsert = (function() { 220 | if (isSprintObj) { 221 | return content.get() 222 | } 223 | if (Array.isArray(content)) { 224 | return sanitize(content, true, true) 225 | } 226 | // DOM node 227 | if (content.nodeType) { 228 | return [content] 229 | } 230 | // getElementsByTagName, getElementsByClassName, querySelectorAll 231 | return toArray(content) 232 | }()) 233 | var elementsToInsertLen = elementsToInsert.length 234 | 235 | this.each(function(index) { 236 | /* 237 | * The fragment serves multiple purposes: 238 | * 1) It significantly boosts perf when multiple elements are added. 239 | * 2) It avoids the need for elementsToInsert.reverse() for afterbegin and afterend 240 | * 3) It removes an element from its original position before adding it back, which is 241 | * especially useful for elements not part of the DOM tree. That means it's important even 242 | * when elementsToInsertLen == 1. 243 | */ 244 | var fragment = document.createDocumentFragment() 245 | for (var i = 0; i < elementsToInsertLen; i++) { 246 | var element = elementsToInsert[i] 247 | var elementToInsert 248 | if (index) { 249 | elementToInsert = element.cloneNode(true) 250 | duplicateEventListeners(element, elementToInsert) 251 | } 252 | else { 253 | elementToInsert = element 254 | } 255 | fragment.appendChild(elementToInsert) 256 | clonedElements.push(elementToInsert) 257 | } 258 | domMethods[position].call(this, fragment) 259 | }) 260 | 261 | if (isSprintObj) { 262 | content.dom = clonedElements 263 | content.length = clonedElements.length 264 | } 265 | if (i < argsLen-1) continue 266 | return clonedElements 267 | } 268 | } 269 | } 270 | 271 | var inArray = function(el, arr) { 272 | var i = arr.length 273 | while (i--) { 274 | if (arr[i] === el) return true 275 | } 276 | return false 277 | } 278 | 279 | var isNamespaced = function(event) { 280 | return /\./.test(event) 281 | } 282 | 283 | var manipulateClass = function(method, className, bool) { 284 | if (className == null) { 285 | if (method == "add") { 286 | return this 287 | } 288 | return this.removeAttr("class") 289 | } 290 | 291 | var isString 292 | var classNames 293 | var classNamesLen 294 | 295 | if (typeof className == "string") { 296 | isString = true 297 | classNames = className.trim().split(" ") 298 | classNamesLen = classNames.length 299 | } 300 | 301 | return this.each(function(i, el) { 302 | if (this.nodeType > 1) return 303 | if (!isString) { 304 | // className is a function 305 | var callbackValue = className.call(el, i, el.className) 306 | if (!callbackValue) return 307 | classNames = callbackValue.trim().split(" ") 308 | classNamesLen = classNames.length 309 | } 310 | for (var j = 0; j < classNamesLen; j++) { 311 | var name = classNames[j] 312 | if (!name) continue 313 | bool == null 314 | ? el.classList[method](name) 315 | : el.classList.toggle(name, bool) 316 | } 317 | }) 318 | } 319 | 320 | var matches = (function() { 321 | var names = [ 322 | "mozMatchesSelector", 323 | "webkitMatchesSelector", 324 | "msMatchesSelector", 325 | "matches" 326 | ] 327 | var i = names.length 328 | while (i--) { 329 | var name = names[i] 330 | if (!Element.prototype[name]) continue 331 | return name 332 | } 333 | }()) 334 | 335 | var removeDuplicates = function(arr) { 336 | var clean = [] 337 | var cleanLen = 0 338 | var arrLen = arr.length 339 | 340 | for (var i = 0; i < arrLen; i++) { 341 | var el = arr[i] 342 | var duplicate = false 343 | 344 | for (var j = 0; j < cleanLen; j++) { 345 | if (el !== clean[j]) continue 346 | duplicate = true 347 | break 348 | } 349 | 350 | if (duplicate) continue 351 | clean[cleanLen++] = el 352 | } 353 | 354 | return clean 355 | } 356 | 357 | var removeEvent = (function() { 358 | var isHandlerShared = function(el, event, registeredHandler) { 359 | var similarEventsHandlers = Object.keys(getEvents(el)).filter(function(prop) { 360 | return getEventFromNamespace(event) === getEventFromNamespace(prop) 361 | }).map(function(ev) { 362 | return getEvents(el)[ev] 363 | }).reduce(function(a, b) { 364 | return a.concat(b) 365 | }).filter(function(handler) { 366 | return handler === registeredHandler 367 | }) 368 | if (similarEventsHandlers.length < 2) return false 369 | return true 370 | } 371 | var removeListener = function(el, event, namedHandler) { 372 | return function(registeredHandler) { 373 | if (namedHandler && namedHandler !== registeredHandler) return 374 | el.removeEventListener(event, registeredHandler) 375 | if (!isNamespaced(event) || isHandlerShared(el, event, registeredHandler)) return 376 | el.removeEventListener(getEventFromNamespace(event), registeredHandler) 377 | } 378 | } 379 | var clearRegisteredHandlers = function(registeredHandlers, namedHandler) { 380 | return registeredHandlers.filter(function(handler) { 381 | return namedHandler && namedHandler !== handler 382 | }) 383 | } 384 | return function(el, namedHandler) { 385 | return function(event) { 386 | getEvents(el)[event].forEach(removeListener(el, event, namedHandler)) 387 | getEvents(el)[event] = clearRegisteredHandlers(getEvents(el)[event], namedHandler) 388 | } 389 | } 390 | }()) 391 | 392 | var removeMatchedEvents = function(el, namedHandler) { 393 | return function(event) { 394 | getEventsToRemove(el, event).forEach(removeEvent(el, namedHandler)) 395 | } 396 | } 397 | 398 | var root = document.documentElement 399 | 400 | var sanitize = function(arr, flattenObjects, requireDomNodes) { 401 | /* 402 | * Remove null's from array. Optionally, flatten Sprint objects and convert strings and numbers 403 | * to DOM text nodes. 404 | */ 405 | var arrLen = arr.length 406 | var i = arrLen 407 | 408 | // Check if arr needs to be sanitized first (significant perf boost for the most common case) 409 | while (i--) { 410 | // arr needs to be sanitized 411 | if ( (!arr[i] && arr[i] !== 0) 412 | || (flattenObjects && arr[i] instanceof Init) 413 | || (requireDomNodes && (typeof arr[i] == "string" || typeof arr[i] == "number")) 414 | ) { 415 | var sanitized = [] 416 | for (var j = 0; j < arrLen; j++) { 417 | var el = arr[j] 418 | if (!el && el !== 0) continue 419 | if (flattenObjects && el instanceof Init) { 420 | for (var k = 0; k < el.length; k++) { 421 | sanitized.push(el.get(k)) 422 | } 423 | continue 424 | } 425 | if (requireDomNodes && (typeof el == "string" || typeof el == "number")) { 426 | sanitized.push(document.createTextNode(el)) 427 | continue 428 | } 429 | sanitized.push(el) 430 | } 431 | return sanitized 432 | } 433 | } 434 | 435 | // arr didn't need to be sanitized, return it 436 | return arr 437 | } 438 | 439 | var scroll = (function() { 440 | var scrollRoot 441 | return function(sprintObj, method, value) { 442 | // define scroll root element on first run 443 | if (!scrollRoot) { 444 | var initialScrollPos = root.scrollTop 445 | root.scrollTop = initialScrollPos + 1 446 | var updatedScrollPos = root.scrollTop 447 | root.scrollTop = initialScrollPos 448 | scrollRoot = updatedScrollPos > initialScrollPos 449 | ? root // spec-compliant browsers (like FF34 and IE11) 450 | : document.body // naughty boys (like Chrome 39 and Safari 8) 451 | } 452 | 453 | // get scroll position 454 | if (value == null) { 455 | var el = sprintObj.get(0) 456 | if (!el) return 457 | if (el == window || el == document) { 458 | el = scrollRoot 459 | } 460 | return el[method] 461 | } 462 | 463 | // set scroll position 464 | return sprintObj.each(function() { 465 | var el = this 466 | if (el == window || el == document) { 467 | el = scrollRoot 468 | } 469 | el[method] = value 470 | }) 471 | } 472 | }()) 473 | 474 | var selectAdjacentSiblings = function(sprintObj, direction, selector, until) { 475 | var dom = [] 476 | var prop = direction + "ElementSibling" 477 | sprintObj.each(function() { 478 | var el = this 479 | while (el = el[prop]) { 480 | if (until && sprintObj.is(until, el)) break 481 | if (selector && !sprintObj.is(selector, el)) continue 482 | dom.push(el) 483 | } 484 | }) 485 | return Sprint(removeDuplicates(dom)) 486 | } 487 | 488 | var selectImmediateAdjacentSibling = function(sprintObj, direction, selector) { 489 | var prop = direction + "ElementSibling" 490 | return sprintObj.map(function() { 491 | var el = this[prop] 492 | if (!el || (selector && !sprintObj.is(selector, el))) return 493 | return el 494 | }, false) 495 | } 496 | 497 | var selectElements = function(selector, context) { 498 | context = context || document 499 | // class, id, tag name or universal selector 500 | if (/^[\#.]?[\w-]+$/.test(selector)) { 501 | var firstChar = selector[0] 502 | if (firstChar == ".") { 503 | return toArray(context.getElementsByClassName(selector.slice(1))) 504 | } 505 | if (firstChar == "#") { 506 | var el = context.getElementById(selector.slice(1)) 507 | return el ? [el] : [] 508 | } 509 | if (selector == "body") { 510 | return [document.body] 511 | } 512 | return toArray(context.getElementsByTagName(selector)) 513 | } 514 | return toArray(context.querySelectorAll(selector)) 515 | } 516 | 517 | var splitNamespaces = function(event) { 518 | return sanitize(event.split(".")) 519 | } 520 | 521 | var toArray = function(obj) { 522 | var arr = [] 523 | var i = obj.length 524 | while (i--) { 525 | arr[i] = obj[i] 526 | } 527 | return arr 528 | } 529 | 530 | var wrap = (function() { 531 | var callback = function(wrappingElement, variant) { 532 | var wrap = Sprint(wrappingElement).clone(true).get(0) 533 | var innerWrap = wrap 534 | if (!wrap || this.nodeType > 1) return 535 | while (innerWrap.firstChild) { 536 | innerWrap = innerWrap.firstChild 537 | } 538 | if (variant == "inner") { 539 | while (this.firstChild) { 540 | innerWrap.appendChild(this.firstChild) 541 | } 542 | this.appendChild(wrap) 543 | } 544 | else { 545 | var el = variant == "all" ? this.get(0) : this 546 | var prt = el.parentNode 547 | var next = el.nextSibling 548 | variant == "all" 549 | ? this.each(function() { innerWrap.appendChild(this) }) 550 | : innerWrap.appendChild(el) 551 | prt.insertBefore(wrap, next) 552 | } 553 | } 554 | return function(wrappingElement, variant) { 555 | if (typeof wrappingElement == "function") { 556 | this.each(function(i) { 557 | Sprint(this)[variant == "inner" ? "wrapInner" : "wrap"](wrappingElement.call(this, i)) 558 | }) 559 | } 560 | else { 561 | variant == "all" 562 | ? callback.call(this, wrappingElement, variant) 563 | : this.each(function() { callback.call(this, wrappingElement, variant) }) 564 | } 565 | return this 566 | } 567 | }()) 568 | 569 | var wrapMap = { 570 | legend: { 571 | intro: "
", 572 | outro: "
" 573 | }, 574 | area: { 575 | intro: "", 576 | outro: "" 577 | }, 578 | param: { 579 | intro: "", 580 | outro: "" 581 | }, 582 | thead: { 583 | intro: "", 584 | outro: "
" 585 | }, 586 | tr: { 587 | intro: "", 588 | outro: "
" 589 | }, 590 | col: { 591 | intro: "", 592 | outro: "
" 593 | }, 594 | td: { 595 | intro: "", 596 | outro: "
" 597 | } 598 | }; 599 | // elements needing a construct already defined by other elements 600 | ["tbody", "tfoot", "colgroup", "caption"].forEach(function(tag) { 601 | wrapMap[tag] = wrapMap.thead 602 | }) 603 | wrapMap.th = wrapMap.td 604 | 605 | // constructor 606 | 607 | var Init = function(selector, context) { 608 | if (typeof selector == "string") { 609 | // create DOM element 610 | if (selector[0] == "<") { 611 | this.dom = [createDOM(selector)] 612 | } 613 | // select DOM elements 614 | else { 615 | this.dom = context && context instanceof Init 616 | ? context.find(selector).get() 617 | : selectElements(selector, context) 618 | } 619 | } 620 | else if (Array.isArray(selector)) { 621 | this.dom = sanitize(selector) 622 | } 623 | else if ( 624 | selector instanceof NodeList || 625 | selector instanceof HTMLCollection 626 | ) { 627 | this.dom = toArray(selector) 628 | } 629 | else if (selector instanceof Init) { 630 | return selector 631 | } 632 | else if (typeof selector == "function") { 633 | return this.ready(selector) 634 | } 635 | else { 636 | // assume DOM node 637 | this.dom = selector ? [selector] : [] 638 | } 639 | this.length = this.dom.length 640 | } 641 | 642 | Init.prototype = { 643 | add: function(selector) { 644 | var dom = this.get() 645 | var objToAdd = Sprint(selector) 646 | var domToAdd = objToAdd.get() 647 | for (var i = 0; i < objToAdd.length; i++) { 648 | dom.push(domToAdd[i]) 649 | } 650 | return Sprint(removeDuplicates(dom)) 651 | }, 652 | addClass: function(className) { 653 | return manipulateClass.call(this, "add", className) 654 | }, 655 | after: function() { 656 | insertHTML.call(this, "afterend", arguments) 657 | return this 658 | }, 659 | append: function() { 660 | insertHTML.call(this, "beforeend", arguments) 661 | return this 662 | }, 663 | appendTo: function(target) { 664 | return Sprint(insertHTML.call(Sprint(target), "beforeend", [this])) 665 | }, 666 | attr: function(name, value) { 667 | var isFunc = typeof value == "function" 668 | if (typeof value == "string" || typeof value == "number" || isFunc) { 669 | return this.each(function(i) { 670 | if (this.nodeType > 1) return 671 | this.setAttribute( 672 | name, isFunc ? value.call(this, i, this.getAttribute(name)) : value 673 | ) 674 | }) 675 | } 676 | if (typeof name == "object") { 677 | var attrNames = Object.keys(name) 678 | var attrNamesLen = attrNames.length 679 | return this.each(function() { 680 | if (this.nodeType > 1) return 681 | for (var i = 0; i < attrNamesLen; i++) { 682 | var attribute = attrNames[i] 683 | this.setAttribute(attribute, name[attribute]) 684 | } 685 | }) 686 | } 687 | var el = this.get(0) 688 | if (!el || el.nodeType > 1) return 689 | var attrValue = el.getAttribute(name) 690 | if (attrValue == null) { 691 | return undefined 692 | } 693 | if (!attrValue) { 694 | return name 695 | } 696 | return attrValue 697 | }, 698 | before: function() { 699 | insertHTML.call(this, "beforebegin", arguments) 700 | return this 701 | }, 702 | children: function(selector) { 703 | var dom = [] 704 | var self = this 705 | this.each(function() { 706 | if (this.nodeType > 1) return 707 | var nodes = this.children 708 | var nodesLen = nodes.length 709 | for (var i = 0; i < nodesLen; i++) { 710 | var node = nodes[i] 711 | if (!selector || self.is(selector, node)) { 712 | dom.push(node) 713 | } 714 | } 715 | }) 716 | return Sprint(dom) 717 | }, 718 | clone: function(withEvents) { 719 | return this.map(function() { 720 | if (!this) return 721 | var clone = this.cloneNode(true) 722 | withEvents && duplicateEventListeners(this, clone) 723 | return clone 724 | }, false) 725 | }, 726 | closest: function(selector, context) { 727 | return findAncestors.call(this, false, false, true, selector, context) 728 | }, 729 | css: function(property, value) { 730 | var valueType = typeof value 731 | var isString = valueType == "string" 732 | 733 | // set 734 | if (isString || valueType == "number") { 735 | var isRelativeValue = isString && /=/.test(value) 736 | if (isRelativeValue) { 737 | var relativeValue = parseInt(value[0] + value.slice(2)) 738 | } 739 | return this.each(function() { 740 | if (this.nodeType > 1) return 741 | if (isRelativeValue) { 742 | var current = parseInt(getComputedStyle(this).getPropertyValue(property)) 743 | var result = current + relativeValue 744 | } 745 | this.style[property] = addPx(property, isRelativeValue ? result : value) 746 | }) 747 | } 748 | // set 749 | if (valueType == "function") { 750 | return this.each(function(index) { 751 | if (this.nodeType > 1) return 752 | var oldValue = getComputedStyle(this).getPropertyValue(property) 753 | this.style[property] = value.call(this, index, oldValue) 754 | }) 755 | } 756 | // read 757 | if (typeof property == "string") { 758 | var el = this.get(0) 759 | if (!el || el.nodeType > 1) return 760 | return getComputedStyle(el).getPropertyValue(property) 761 | } 762 | // read 763 | if (Array.isArray(property)) { 764 | var el = this.get(0) 765 | if (!el || el.nodeType > 1) return 766 | var o = {} 767 | var styles = getComputedStyle(el) 768 | var propertyLen = property.length 769 | for (var i = 0; i < propertyLen; i++) { 770 | var prop = property[i] 771 | o[prop] = styles.getPropertyValue(prop) 772 | } 773 | return o 774 | } 775 | // set 776 | var properties = Object.keys(property) 777 | var propertiesLen = properties.length 778 | return this.each(function() { 779 | if (this.nodeType > 1) return 780 | for (var i = 0; i < propertiesLen; i++) { 781 | var prop = properties[i] 782 | this.style[prop] = addPx(prop, property[prop]) 783 | } 784 | }) 785 | }, 786 | detach: function() { 787 | return this.map(function() { 788 | var parent = this.parentElement 789 | if (!parent) return 790 | parent.removeChild(this) 791 | return this 792 | }, false) 793 | }, 794 | each: function(callback) { 795 | // callback(index, element) where element == this 796 | var dom = this.dom 797 | var len = this.length 798 | for (var i = 0; i < len; i++) { 799 | var node = dom[i] 800 | callback.call(node, i, node) 801 | } 802 | return this 803 | }, 804 | empty: function() { 805 | return this.each(function() { 806 | this.innerHTML = "" 807 | }) 808 | }, 809 | eq: function(index) { 810 | return Sprint(this.get(index)) 811 | }, 812 | filter: function(selector) { 813 | var isFunc = typeof selector == "function" 814 | var self = this 815 | return this.map(function(i) { 816 | if ( this.nodeType > 1 817 | || (!isFunc && !self.is(selector, this)) 818 | || (isFunc && !selector.call(this, i, this)) 819 | ) return 820 | return this 821 | }, false) 822 | }, 823 | find: function(selector) { 824 | // .find(selector) 825 | if (typeof selector == "string") { 826 | var dom = [] 827 | this.each(function() { 828 | if (this.nodeType > 1) return 829 | var elements = selectElements(selector, this) 830 | var elementsLen = elements.length 831 | for (var i = 0; i < elementsLen; i++) { 832 | dom.push(elements[i]) 833 | } 834 | }) 835 | return Sprint(removeDuplicates(dom)) 836 | } 837 | 838 | // .find(element) 839 | var elementsToFind = selector.nodeType ? [selector] : selector.get() 840 | var elementsToFindLen = elementsToFind.length 841 | var elementsFound = [] 842 | var elementsFoundLen = 0 843 | 844 | for (var i = 0; i < this.length; i++) { 845 | var el = this.get(i) 846 | if (el.nodeType > 1) continue 847 | // check if each element in `this` contains the elements to find 848 | for (var j = 0; j < elementsToFindLen; j++) { 849 | var elementToFind = elementsToFind[j] 850 | if (!el.contains(elementToFind)) continue 851 | elementsFound[elementsFoundLen++] = elementToFind 852 | if (elementsFoundLen < elementsToFindLen) continue 853 | // everything has been found, return results 854 | return Sprint(elementsFound) 855 | } 856 | } 857 | 858 | // some elements in elementsToFind weren't descendants of `this` 859 | return Sprint(elementsFound) 860 | }, 861 | first: function() { 862 | return this.eq(0) 863 | }, 864 | get: function(index) { 865 | if (index == null) { 866 | return this.dom 867 | } 868 | if (index < 0) { 869 | index += this.length 870 | } 871 | return this.dom[index] 872 | }, 873 | has: function(selector) { 874 | // .has(selector) 875 | if (typeof selector == "string") { 876 | return this.map(function() { 877 | if (this.nodeType > 1 || !selectElements(selector, this)[0]) return 878 | return this 879 | }, false) 880 | } 881 | 882 | // .has(contained) 883 | var result = [] 884 | var i = this.length 885 | while (i--) { 886 | var el = this.get(i) 887 | if (!el.contains(selector)) continue 888 | result.push(el) 889 | break 890 | } 891 | return Sprint(result) 892 | }, 893 | hasClass: function(name) { 894 | var i = this.length 895 | while (i--) { 896 | var el = this.get(i) 897 | if (el.nodeType > 1) return 898 | if (el.classList.contains(name)) { 899 | return true 900 | } 901 | } 902 | return false 903 | }, 904 | height: function(value) { 905 | return getSetDimension(this, "height", value) 906 | }, 907 | html: function(htmlString) { 908 | if (htmlString == null) { 909 | var el = this.get(0) 910 | if (!el) return 911 | return el.innerHTML 912 | } 913 | if (typeof htmlString == "function") { 914 | return this.each(function(i) { 915 | var content = htmlString.call(this, i, this.innerHTML) 916 | Sprint(this).html(content) 917 | }) 918 | } 919 | return this.each(function() { 920 | this.innerHTML = htmlString 921 | }) 922 | }, 923 | index: function(el) { 924 | if (!this.length) return 925 | var toFind 926 | var sprintElements 927 | if (!el) { 928 | toFind = this.get(0) 929 | sprintElements = this.first().parent().children() 930 | } 931 | else if (typeof el == "string") { 932 | toFind = this.get(0) 933 | sprintElements = Sprint(el) 934 | } 935 | else { 936 | toFind = el instanceof Init ? el.get(0) : el 937 | sprintElements = this 938 | } 939 | var elements = sprintElements.get() 940 | var i = elements.length 941 | while (i--) { 942 | if (elements[i] == toFind) { 943 | return i 944 | } 945 | } 946 | return -1 947 | }, 948 | insertAfter: function(target) { 949 | Sprint(target).after(this) 950 | return this 951 | }, 952 | insertBefore: function(target) { 953 | Sprint(target).before(this) 954 | return this 955 | }, 956 | is: function(selector, element) { 957 | // element is undocumented, internal-use only. 958 | // It gives better perfs as it prevents the creation of many objects in internal methods. 959 | var set = element ? [element] : this.get() 960 | var setLen = set.length 961 | 962 | if (typeof selector == "string") { 963 | for (var i = 0; i < setLen; i++) { 964 | var el = set[i] 965 | if (el.nodeType > 1) continue 966 | if (el[matches](selector)) { 967 | return true 968 | } 969 | } 970 | return false 971 | } 972 | if (typeof selector == "object") { 973 | // Sprint object or DOM element(s) 974 | var obj 975 | if (selector instanceof Init) { 976 | obj = selector.get() 977 | } 978 | else { 979 | obj = selector.length ? selector : [selector] 980 | } 981 | var objLen = obj.length 982 | for (var i = 0; i < setLen; i++) { 983 | for (var j = 0; j < objLen; j++) { 984 | if (set[i] === obj[j]) { 985 | return true 986 | } 987 | } 988 | } 989 | return false 990 | } 991 | if (typeof selector == "function") { 992 | for (var i = 0; i < setLen; i++) { 993 | if (selector.call(this, i, this)) { 994 | return true 995 | } 996 | } 997 | return false 998 | } 999 | }, 1000 | last: function() { 1001 | return this.eq(-1) 1002 | }, 1003 | map: function(callback, flattenArrays) { 1004 | /* 1005 | * flattenArrays (bool, true by default) is for internal usage only (although it might be 1006 | * interesting to document it publicly). 1007 | * Many methods rely on map(), thus being able to avoid the unnecessary Array.isArray() check 1008 | * on each element is a significant perf boost. 1009 | */ 1010 | if (flattenArrays == null) { 1011 | flattenArrays = true 1012 | } 1013 | 1014 | var dom = this.get() 1015 | var len = this.length 1016 | var values = [] 1017 | 1018 | for (var i = 0; i < len; i++) { 1019 | var el = dom[i] 1020 | var val = callback.call(el, i, el) 1021 | 1022 | if (flattenArrays && Array.isArray(val)) { 1023 | var valLen = val.length 1024 | for (var j = 0; j < valLen; j++) { 1025 | values.push(val[j]) 1026 | } 1027 | continue 1028 | } 1029 | 1030 | values.push(val) 1031 | } 1032 | 1033 | return Sprint(values) 1034 | }, 1035 | next: function(selector) { 1036 | return selectImmediateAdjacentSibling(this, "next", selector) 1037 | }, 1038 | nextAll: function(selector) { 1039 | return selectAdjacentSiblings(this, "next", selector) 1040 | }, 1041 | nextUntil: function(selector, filter) { 1042 | return selectAdjacentSiblings(this, "next", filter, selector) 1043 | }, 1044 | not: function(selector) { 1045 | var isFunc = typeof selector == "function" 1046 | var self = this 1047 | return this.map(function(i) { 1048 | if (isFunc) { 1049 | if (selector.call(this, i, this)) return 1050 | } 1051 | else { 1052 | if (self.is(selector, this)) return 1053 | } 1054 | return this 1055 | }, false) 1056 | }, 1057 | off: function(events, handler) { 1058 | if (typeof events == "object") { 1059 | Object.keys(events).forEach(function(event) { 1060 | this.off(event, events[event]) 1061 | }, this) 1062 | return this 1063 | } 1064 | if (events) { 1065 | events = events.trim().split(" ") 1066 | } 1067 | return this.each(function() { 1068 | if (!getEvents(this)) return 1069 | if (events) { 1070 | events.forEach(removeMatchedEvents(this, handler)) 1071 | return 1072 | } 1073 | Object.keys(getEvents(this)).forEach(removeEvent(this)) 1074 | }) 1075 | }, 1076 | offset: function(coordinates) { 1077 | if (!coordinates) { 1078 | var el = this.get(0) 1079 | if (!el || el.nodeType > 1) return 1080 | var pos = el.getBoundingClientRect() 1081 | return { 1082 | top: pos.top, 1083 | left: pos.left 1084 | } 1085 | } 1086 | if (typeof coordinates == "object") { 1087 | return this.each(function() { 1088 | if (this.nodeType > 1) return 1089 | var $this = Sprint(this) 1090 | $this.css("position") == "static" 1091 | ? $this.css("position", "relative") 1092 | : $this.css({ 1093 | top: 0, 1094 | left: 0 1095 | }) 1096 | var pos = $this.offset() 1097 | $this.css({ 1098 | top: coordinates.top - pos.top + "px", 1099 | left: coordinates.left - pos.left + "px" 1100 | }) 1101 | }) 1102 | } 1103 | if (typeof coordinates == "function") { 1104 | return this.each(function(i) { 1105 | var $this = Sprint(this) 1106 | var posObj = coordinates.call(this, i, $this.offset()) 1107 | $this.offset(posObj) 1108 | }) 1109 | } 1110 | }, 1111 | offsetParent: function() { 1112 | var dom = [] 1113 | this.each(function() { 1114 | if (this.nodeType > 1) return 1115 | var prt = this 1116 | while (prt != root) { 1117 | prt = prt.parentNode 1118 | var pos = getComputedStyle(prt).getPropertyValue("position") 1119 | if (!pos) break 1120 | if (pos != "static") { 1121 | dom.push(prt) 1122 | return 1123 | } 1124 | } 1125 | dom.push(root) 1126 | }) 1127 | return Sprint(dom) 1128 | }, 1129 | on: function(events, handler) { 1130 | // .on(events, handler) 1131 | if (handler) { 1132 | var eventsArr = events.trim().split(" ") 1133 | 1134 | return this.each(function() { 1135 | if (!getEvents(this)) { 1136 | this.sprintEventListeners = {} 1137 | } 1138 | eventsArr.forEach(function(event) { 1139 | if (!getEvents(this)[event]) { 1140 | getEvents(this)[event] = [] 1141 | } 1142 | getEvents(this)[event].push(handler) 1143 | 1144 | // Ensure we add both the standard event (eg: "click") and the full event 1145 | // (eg: "click.foo") in order to be able to trigger them manually and programmatically. 1146 | this.addEventListener(event, handler) 1147 | if (!isNamespaced(event)) return 1148 | this.addEventListener(getEventFromNamespace(event), handler) 1149 | }, this) 1150 | }) 1151 | } 1152 | 1153 | // .on({ event: handler }) 1154 | Object.keys(events).forEach(function(event) { 1155 | this.on(event, events[event]) 1156 | }, this) 1157 | return this 1158 | }, 1159 | parent: function(selector) { 1160 | return findAncestors.call(this, true, true, false, selector) 1161 | }, 1162 | parents: function(selector) { 1163 | /* Differences with jQuery: 1164 | * 1. $("html").parent() and $("html").parents() return an empty set. 1165 | * 2. The returned set won't be in reverse order. 1166 | */ 1167 | return findAncestors.call(this, true, false, false, selector) 1168 | }, 1169 | position: function() { 1170 | var pos = { 1171 | first: this.offset(), 1172 | prt: this.parent().offset() 1173 | } 1174 | if (!pos.first) return 1175 | return { 1176 | top: pos.first.top - pos.prt.top, 1177 | left: pos.first.left - pos.prt.left 1178 | } 1179 | }, 1180 | prop: function(propertyName, value) { 1181 | if (typeof propertyName == "object") { 1182 | var props = Object.keys(propertyName) 1183 | var propsLen = props.length 1184 | return this.each(function() { 1185 | for (var i = 0; i < propsLen; i++) { 1186 | var prop = props[i] 1187 | this[prop] = propertyName[prop] 1188 | } 1189 | }) 1190 | } 1191 | if (value == null) { 1192 | var el = this.get(0) 1193 | if (!el) return 1194 | return el[propertyName] 1195 | } 1196 | var isFunc = typeof value == "function" 1197 | return this.each(function(i) { 1198 | this[propertyName] = isFunc ? value.call(this, i, this[propertyName]) : value 1199 | }) 1200 | }, 1201 | prepend: function() { 1202 | insertHTML.call(this, "afterbegin", arguments) 1203 | return this 1204 | }, 1205 | prependTo: function(target) { 1206 | return Sprint(insertHTML.call(Sprint(target), "afterbegin", [this])) 1207 | }, 1208 | prev: function(selector) { 1209 | return selectImmediateAdjacentSibling(this, "previous", selector) 1210 | }, 1211 | prevAll: function(selector) { 1212 | return selectAdjacentSiblings(this, "previous", selector) 1213 | }, 1214 | prevUntil: function(selector, filter) { 1215 | return selectAdjacentSiblings(this, "previous", filter, selector) 1216 | }, 1217 | ready: function(handler) { 1218 | this.dom = [document] 1219 | this.length = 1 1220 | return this.on("DOMContentLoaded", handler) 1221 | }, 1222 | remove: function(selector) { 1223 | var self = this 1224 | return this.each(function() { 1225 | var parent = this.parentElement 1226 | if (!parent) return 1227 | if (!selector || self.is(selector, this)) { 1228 | parent.removeChild(this) 1229 | } 1230 | }) 1231 | }, 1232 | removeAttr: function(attributeName) { 1233 | if (attributeName) { 1234 | var attributes = attributeName.trim().split(" ") 1235 | var attributesLen = attributes.length LBhojQ4fKR 1236 | this.each(function() { 1237 | if (this.nodeType > 1) return 1238 | for (var i = 0; i < attributesLen; i++) { 1239 | this.removeAttribute(attributes[i]) 1240 | } 1241 | }) 1242 | } 1243 | return this 1244 | }, 1245 | removeClass: function(className) { 1246 | return manipulateClass.call(this, "remove", className) 1247 | }, 1248 | removeProp: function(propertyName) { 1249 | return this.each(function() { 1250 | this[propertyName] = undefined 1251 | }) 1252 | }, 1253 | replaceAll: function(target) { 1254 | Sprint(target).replaceWith(this) 1255 | return this 1256 | }, 1257 | replaceWith: function(newContent) { 1258 | if (typeof newContent == "function") { 1259 | return this.each(function(i) { 1260 | Sprint(this).replaceWith(newContent.call(this, i, this)) 1261 | }) 1262 | } 1263 | return this.before(newContent).remove() 1264 | }, 1265 | scrollLeft: function(value) { 1266 | return scroll(this, "scrollLeft", value) 1267 | }, 1268 | scrollTop: function(value) { 1269 | return scroll(this, "scrollTop", value) 1270 | }, 1271 | siblings: function(selector) { 1272 | var siblings = [] 1273 | var self = this 1274 | this.each(function(i, el) { 1275 | Sprint(this).parent().children().each(function() { 1276 | if (this == el || (selector && !self.is(selector, this))) return 1277 | siblings.push(this) 1278 | }) 1279 | }) 1280 | return Sprint(siblings) 1281 | }, 1282 | size: function() { 1283 | return this.length 1284 | }, 1285 | slice: function(start, end) { 1286 | var dom = this.get() 1287 | var range = [] 1288 | var i = start >= 0 ? start : start + this.length 1289 | var l = this.length 1290 | if (end < 0) { 1291 | l += end 1292 | } 1293 | else if (end >= 0) { 1294 | l = end > this.length ? this.length : end 1295 | } 1296 | for (; i < l; i++) { 1297 | range.push(dom[i]) 1298 | } 1299 | return Sprint(range) 1300 | }, 1301 | text: function(content) { 1302 | if (content == null) { 1303 | var textContents = [] 1304 | this.each(function() { 1305 | textContents.push(this.textContent) 1306 | }) 1307 | return textContents.join("") 1308 | } 1309 | var isFunc = typeof content == "function" 1310 | return this.each(function(i) { 1311 | this.textContent = isFunc ? content.call(this, i, this.textContent) : content 1312 | }) 1313 | }, 1314 | toggleClass: function(className, bool) { 1315 | return manipulateClass.call(this, "toggle", className, bool) 1316 | }, 1317 | trigger: function(event) { 1318 | // IE polyfill 1319 | if (!window.CustomEvent || typeof window.CustomEvent !== "function") { 1320 | var CustomEvent = function(event, params) { 1321 | var evt 1322 | params = params || { 1323 | bubbles: false, 1324 | cancelable: false, 1325 | detail: undefined 1326 | } 1327 | evt = document.createEvent("CustomEvent") 1328 | evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail) 1329 | return evt 1330 | } 1331 | CustomEvent.prototype = window.Event.prototype 1332 | window.CustomEvent = CustomEvent 1333 | } 1334 | return this.each(function() { 1335 | getEventsToRemove(this, event).forEach(function(matchedEvent) { 1336 | this.dispatchEvent(new CustomEvent(matchedEvent, { 1337 | bubbles: true, 1338 | cancelable: true 1339 | })) 1340 | }, this) 1341 | }) 1342 | }, 1343 | unwrap: function() { 1344 | this.parent().each(function() { 1345 | if (this == document.body || this == root) return 1346 | Sprint(this).replaceWith(this.childNodes) 1347 | }) 1348 | return this 1349 | }, 1350 | val: function(value) { 1351 | if (value == null) { 1352 | var el = this.get(0) 1353 | if (!el) return 1354 | if (el.multiple) { 1355 | var values = [] 1356 | this.first().children(":checked").each(function() { 1357 | values.push(this.value) 1358 | }) 1359 | return values 1360 | } 1361 | return el.value 1362 | } 1363 | if (Array.isArray(value)) { 1364 | var self = this 1365 | return this.each(function() { 1366 | if (this.multiple) { 1367 | self.children().each(function() { 1368 | this.selected = inArray(this.value, value) 1369 | }) 1370 | return 1371 | } 1372 | this.checked = inArray(this.value, value) 1373 | }) 1374 | } 1375 | if (typeof value == "function") { 1376 | return this.each(function(i) { 1377 | Sprint(this).val(value.call(this, i, this.value)) 1378 | }) 1379 | } 1380 | return this.each(function() { 1381 | this.value = value 1382 | }) 1383 | }, 1384 | width: function(value) { 1385 | return getSetDimension(this, "width", value) 1386 | }, 1387 | wrap: function(wrappingElement) { 1388 | return wrap.call(this, wrappingElement) 1389 | }, 1390 | wrapAll: function(wrappingElement) { 1391 | return wrap.call(this, wrappingElement, "all") 1392 | }, 1393 | wrapInner: function(wrappingElement) { 1394 | return wrap.call(this, wrappingElement, "inner") 1395 | } 1396 | } 1397 | 1398 | // public 1399 | 1400 | Sprint = function(selector, context) { 1401 | return new Init(selector, context) 1402 | } 1403 | 1404 | if (window.$ == null) { 1405 | window.$ = Sprint 1406 | } 1407 | }()); 1408 | --------------------------------------------------------------------------------