Repository: fabiospampinato/cash Branch: master Commit: fe1904d367eb Files: 155 Total size: 246.5 KB Directory structure: gitextract_03ob_z96/ ├── .editorconfig ├── .github/ │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── .gitignore ├── bump.json ├── changelog.md ├── docs/ │ ├── extending_cash.md │ ├── migration_guide.md │ └── partial_builds.md ├── license ├── package.json ├── readme.md ├── resources/ │ ├── banner/ │ │ └── banner.afphoto │ └── logo/ │ └── logo.psd ├── src/ │ ├── attributes/ │ │ ├── add_class.ts │ │ ├── attr.ts │ │ ├── has_class.ts │ │ ├── helpers/ │ │ │ └── variables.ts │ │ ├── prop.ts │ │ ├── remove_attr.ts │ │ ├── remove_class.ts │ │ ├── remove_prop.ts │ │ └── toggle_class.ts │ ├── collection/ │ │ ├── add.ts │ │ ├── each.ts │ │ ├── eq.ts │ │ ├── filter.ts │ │ ├── first.ts │ │ ├── get.ts │ │ ├── index.ts │ │ ├── last.ts │ │ ├── map.ts │ │ └── slice.ts │ ├── core/ │ │ ├── attempt.ts │ │ ├── camel_case.ts │ │ ├── cash.ts │ │ ├── each.ts │ │ ├── extend.ts │ │ ├── filtered.ts │ │ ├── find.ts │ │ ├── get_compare_function.ts │ │ ├── get_split_values.ts │ │ ├── guid.ts │ │ ├── matches.ts │ │ ├── parse_html.ts │ │ ├── pluck.ts │ │ ├── type_checking.ts │ │ ├── types.ts │ │ ├── unique.ts │ │ └── variables.ts │ ├── css/ │ │ ├── css.ts │ │ └── helpers/ │ │ ├── compute_style.ts │ │ ├── compute_style_int.ts │ │ ├── get_prefixed_prop.ts │ │ ├── get_suffixed_value.ts │ │ ├── is_css_variable.ts │ │ └── variables.ts │ ├── data/ │ │ ├── data.ts │ │ └── helpers/ │ │ ├── get_data.ts │ │ └── set_data.ts │ ├── dimensions/ │ │ ├── helpers/ │ │ │ ├── get_document_dimension.ts │ │ │ └── get_extra_space.ts │ │ ├── inner_outer.ts │ │ └── normal.ts │ ├── effects/ │ │ ├── helpers/ │ │ │ ├── get_default_display.ts │ │ │ ├── is_hidden.ts │ │ │ └── variables.ts │ │ ├── hide.ts │ │ ├── show.ts │ │ └── toggle.ts │ ├── events/ │ │ ├── helpers/ │ │ │ ├── add_event.ts │ │ │ ├── get_event_name_bubbling.ts │ │ │ ├── get_events_cache.ts │ │ │ ├── has_namespaces.ts │ │ │ ├── parse_event_name.ts │ │ │ ├── remove_event.ts │ │ │ └── variables.ts │ │ ├── off.ts │ │ ├── on.ts │ │ ├── one.ts │ │ ├── ready.ts │ │ └── trigger.ts │ ├── export_cjs.ts │ ├── export_esm.ts │ ├── extra/ │ │ ├── get_script.ts │ │ └── shorthands.ts │ ├── forms/ │ │ ├── helpers/ │ │ │ ├── get_value.ts │ │ │ └── query_encode.ts │ │ ├── serialize.ts │ │ └── val.ts │ ├── manipulation/ │ │ ├── after.ts │ │ ├── append.ts │ │ ├── append_to.ts │ │ ├── before.ts │ │ ├── clone.ts │ │ ├── detach.ts │ │ ├── empty.ts │ │ ├── helpers/ │ │ │ ├── eval_scripts.ts │ │ │ ├── insert_element.ts │ │ │ └── insert_selectors.ts │ │ ├── html.ts │ │ ├── insert_after.ts │ │ ├── insert_before.ts │ │ ├── prepend.ts │ │ ├── prepend_to.ts │ │ ├── remove.ts │ │ ├── replace_all.ts │ │ ├── replace_with.ts │ │ ├── text.ts │ │ ├── unwrap.ts │ │ ├── wrap.ts │ │ ├── wrap_all.ts │ │ └── wrap_inner.ts │ ├── methods.ts │ ├── offset/ │ │ ├── offset.ts │ │ ├── offset_parent.ts │ │ └── position.ts │ └── traversal/ │ ├── children.ts │ ├── closest.ts │ ├── contents.ts │ ├── find.ts │ ├── has.ts │ ├── is.ts │ ├── next.ts │ ├── next_all.ts │ ├── next_until.ts │ ├── not.ts │ ├── parent.ts │ ├── parents.ts │ ├── parents_until.ts │ ├── prev.ts │ ├── prev_all.ts │ ├── prev_until.ts │ └── siblings.ts ├── tasks/ │ └── build.sh ├── test/ │ ├── helpers.js │ ├── index.html │ ├── jquery_patch.js │ ├── jquery_reverse_patch.js │ ├── modules/ │ │ ├── attributes.js │ │ ├── collection.js │ │ ├── core.js │ │ ├── css.js │ │ ├── data.js │ │ ├── dimensions.js │ │ ├── effects.js │ │ ├── events.js │ │ ├── forms.js │ │ ├── manipulation.js │ │ ├── offset.js │ │ ├── traversal.js │ │ └── utilities.js │ └── playwright.mjs └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] charset = utf-8 end_of_line = lf indent_size = 2 indent_style = space insert_final_newline = true trim_trailing_whitespace = true ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve --- ### Current behavior ### Expected behavior ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project --- ### Feature description ### Feature motivation Is this feature present in jQuery? Yes/No ================================================ FILE: .github/ISSUE_TEMPLATE/question.md ================================================ --- name: Question about: Ask a question --- ================================================ FILE: .gitignore ================================================ *~ *.err *.log ._* .cache .fseventsd .DocumentRevisions* .DS_Store .TemporaryItems .Trashes Thumbs.db dist node_modules package-lock.json ================================================ FILE: bump.json ================================================ { "changelog": { "path": "changelog.md", "version": "### [v[version]](https://github.com/fabiospampinato/cash/releases/tag/[version]) ([version_date])" }, "tag": { "enabled": false, "name": "[version]" }, "release": { "github": { "enabled": true, "files": [ "**/dist/**" ] } }, "scripts": { "prebump": "npm run prepublishOnly", "prerelease": "npm run prepublishOnly", "postrelease": "npm publish" } } ================================================ FILE: changelog.md ================================================ ### [v8.1.5](https://github.com/fabiospampinato/cash/releases/tag/8.1.5) (2023-04-13) - Fixed support for using a selector as context - $.hide: ensuring calling it multiple times sequentially works too ### [v8.1.4](https://github.com/fabiospampinato/cash/releases/tag/8.1.4) (2023-03-08) - Updatd contribution guide - Replaced Karma with Playwright, removing most dev dependencies, removing coverage reports, and adding support for Safari - Updated dependencies - Lowercased readme file - Lowercased changelog file - $.serialize: avoiding encoding "%20" as "+", for better alignment with jQuery ### [v8.1.3](https://github.com/fabiospampinato/cash/releases/tag/8.1.3) (2023-01-31) - $.fn.text: ensuring it reads text from every node in the collection, not just the first one, for better alignment with jQuery ### [v8.1.2](https://github.com/fabiospampinato/cash/releases/tag/8.1.2) (2022-11-18) - Migration guide: mentioning $.fn.css as a potential workaround for ignoring the effects of CSS transforms - $.fn.html: ensuring script elements are executed, to better align with jQuery - Switched to a new bundler, minipacco - Deleted most development dependencies - Simplified significantly partial compilation - Ensuring selectors contains escaped dots are handled correctly ### [v8.1.1](https://github.com/fabiospampinato/cash/releases/tag/8.1.1) (2022-02-16) - Ensuring the proper types for iteration are provided - Ensuring $.fn.find works with document fragments too - Ensuring the "delegateProperty" is attached to events - More reliably using "getElementById", only if the context node actually supports it - Ensuring that before inserting a node before/after the html node the html node is removed from the DOM ### [v8.1.0](https://github.com/fabiospampinato/cash/releases/tag/8.1.0) (2020-09-12) - Added `$.isPlainObject` - $.each: added support for iterating over objects - $.extend: added support for extending deeply - Readme: updated dimensions - Updated changelog template ### [v8.0.0](https://github.com/fabiospampinato/cash/releases/tag/8.0.0) (2020-06-20) - Improved alignment with jQuery regarding handling of non-bubbling events significantly ### [v7.0.4](https://github.com/fabiospampinato/cash/releases/tag/7.0.4) (2020-06-19) - Ensuring unusual but valid simple selectors are handled properly ### [v7.0.3](https://github.com/fabiospampinato/cash/releases/tag/7.0.3) (2020-05-31) - Updated "EleLoose" type ### v7.0.2 (2020-05-30) - Readme: updated npm installation command - Updated the "EleLoose" TypeScript type ensuring it isn't evaluated as "never" ### [v7.0.1](https://github.com/fabiospampinato/cash/releases/tag/7.0.1) (2020-04-15) - $.fn.css: added support for retrieving properties of disconnected nodes ### [v7.0.0](https://github.com/fabiospampinato/cash/releases/tag/7.0.0) (2020-03-31) - focus|blur|mouseenter|mouseleave: ensuring namespaces are handled properly - focus|blur|mouseenter|mouseleave: aligned behavior more with jQuery - focus|blur|mouseenter|mouseleave: ensuring natively triggered events are handled properly - Migration guide: mentioning native non-bubbling events ### [v6.0.2](https://github.com/fabiospampinato/cash/releases/tag/6.0.2) (2020-02-15) - Readme: improved comparison with jQuery, fixing some wrong/unfair comparisons/statements - Migration guide: mentioning sort order - $.fn.ready: ensuring the callback is called asynchronously and errors are not silenced ### [v6.0.1](https://github.com/fabiospampinato/cash/releases/tag/6.0.1) (2020-01-05) - Ensuring events work with Document and Window objects - Ensuring "event.data" is setted reliably ### [v6.0.0](https://github.com/fabiospampinato/cash/releases/tag/6.0.0) (2020-01-05) ##### Removed Features - $.camelCase|matches|isString|prefixedProp: no longer exposing these methods, aligning with jQuery ##### New Features - $.fn.nextUntil|prevUntil|parentsUntil: implemented these methods - $.fn.detach|remove: added support for an optional "selector" argument - $.fn.on|one: added support for an optional "data" argument - Set-up test coverage (currently at ~99%) reporting to coveralls.io - Migration guide: major update ##### Bug Fixes - $.extend: aligned more with jQuery when called with zero or one argument - $.fn.before|after|append|prepend|insertBefore|insertAfter|appendTo|prependTo: ensuring cloned scripts don't get executed - $.fn.contents: ensuring template elements are supported - $.fn.css: ensuring "grid-*" properties don't get the "px" suffix appended to their values when they are not supposed to - $.fn.data: doing nothing when trying to set values to undefined - $.fn.data: ensuring strings containing leading/trailing whitespace aren't parsed as JSON - $.fn.get|eq: ensuring string indexes are supported - $.fn.map: ensuring callbacks that return an array of elements are supported too - $.fn.offset|offsetParent|position: rewritten to much more closely match jQuery's implementation - $.fn.on|one|off: ensuring namespaces-only events are ignored - $.fn.on|one|off: ensuring they don't throw when receiving a falsy callback - $.fn.on|one: ensuring these methods are chainable even when receiving falsy callbacks - $.fn.prop|removeProp: mapping special HTML attributes into their equivalent DOM properties (e.g. "for" -> "htmlFor") - $.fn.ready: ensuring exceptions are always caught, so they can't crash the app - $.fn.serialize: normalizing newlines - $.fn.trigger: testing that non-nil falsy values are passed correctly - $.fn.unwrap: ensuring immediate children of the body don't get unwrapped - $.fn.val: ensuring checkboxes and radios can be set properly - $.fn.val: ensuring non-string values are supported - $.fn.val|html: more reliably detecting when being called with no arguments - $.fn.width|height|innerWidth|innerHeight|outerWidth|outerHeight: ensuring document objects are supported too - $.fn.width|height|innerWidth|innerHeight|outerWidth|outerHeight: ensuring they return the right value for the Window object - $.fn.wrapAll: ensuring elements aren't cloned unnecessarely - $.parseHTML: ensuring whitespace around a single HTML tag is preserved - Ensuring empty selectors don't throw an error - Collections containing non-element objects: - $.fn.addClass|removeClass|toggleClass: ensuring it doesn't throw with collections containing non-elements - $.fn.attr: ensuring a collection containing non-element objects doesn't cause an error to be thrown - $.fn.before|after|append|prepend|insertBefore|insertAfter|appendTo|prependTo: ensuring non-element nodes are accounted for properly - $.fn.hasClass: ensuring a collection containing non-element objects doesn't cause an error to be thrown - $.fn.hide|show|toggle: ensuring a collection containing non-element objects doesn't cause an error to be thrown - $.fn.html: ensuring collections containing non-element objects are supported - $.fn.not: ensuring non-element nodes are excluded - $.fn.on|off: ensuring non-element objects in the collection are ignored - $.fn.removeAttr: ensuring a collection containing non-element objects doesn't cause an error to be thrown - $.fn.text: improved support of collections containing non-elements objects ### [v5.0.0](https://github.com/fabiospampinato/cash/releases/tag/5.0.0) (2019-12-17) - Dropped support for IE10 - $.fn.hasClass: ensuring it always returns a boolean - $.fn.off: accepting also an events map as its only argument - $.fn.show|toggle: restoring custom display values - $.fn.before|after|append|prepend|insertBefore|insertAfter|appendTo|prependTo: ensuring multiple nodes are inserted in the correct order - Ensuring attached events never get forgotten - Ensuring script tags are executed even if they have a "src" attribute, and without using `eval` - Ensuring the order of event namespaces doesn't matter - Squeezed some more bytes out of the bundle (~4%) and improved code style consistency - Squeezed some more bytes out of the bundle (~1.5%), bringing back the minified and gzipped size below 5kb ### [v4.1.5](https://github.com/fabiospampinato/cash/releases/tag/4.1.5) (2019-09-06) - $.fn.val: ensuring it works with "input[type=file][multiple]" elements - Migration guide: mentioning how $.fn.data stores values ### [v4.1.4](https://github.com/fabiospampinato/cash/releases/tag/4.1.4) (2019-08-05) - $.fn.get: improved types - TypeScript: made types a little more forgiving - TypeScript: improved collections index signature - TypeScript: improved support for props/methods available only in specific HTML nodes - Added a guide for extending Cash ### [v4.1.3](https://github.com/fabiospampinato/cash/releases/tag/4.1.3) (2019-07-13) - Ensuring Cash can be bundled correctly via webpack - $.fn.toggle: ensuring each element is toggled independently - TypeScript: ensuring some useful internal types are exported - TypeScript: made types a little more forgiving ### [v4.1.2](https://github.com/fabiospampinato/cash/releases/tag/4.1.2) (2019-05-16) - Avoiding publishing unnecessary files to NPM ### [v4.1.1](https://github.com/fabiospampinato/cash/releases/tag/4.1.1) (2019-05-13) - Raising bundle size limit to 5.5kB - Test: replaced iOS 9.3 with iOS 11.0 - Test: using setAttribute instead of the dataset API - Migration guide: mentioning the `:scope` CSS pseudo-class - Migration guide: mentioning inserting plain text - TypeScript: typing events more loosely - TypeScript: typing collection elements more loosely ### [v4.1.0](https://github.com/fabiospampinato/cash/releases/tag/4.1.0) (2019-05-12) - Added $.isWindow - Made the TypeScript type system stricter - $.guid: ensuring it's properly exported - $.fn.siblings: ensuring it supports multi-element collections - $.fn.empty: ensuring it supports multi-element collections - $.fn.attr: doing nothing when the value equals undefined ### [v4.0.0](https://github.com/fabiospampinato/cash/releases/tag/4.0.0) (2019-05-08) - Removed `$.fn.removeData` - Removed `$.hasData` - `$.fn.data`: removed caching mechanism - `$.fn.data`: added a missing TypeScript method overload ### [v3.2.0](https://github.com/fabiospampinato/cash/releases/tag/3.2.0) (2019-04-30) - Readme: updated sizes - $.fn.off: added support for removing delegated handlers ### [v3.1.0](https://github.com/fabiospampinato/cash/releases/tag/3.1.0) (2019-03-22) - Improved support for running selectors inside documents - Ensuring Cash collections are iterable - Added an extra reference implementation for shorthand event methods - Added an extra reference implementation for `$.getScript` - Readme: mentioning the extra methods ### [v3.0.0](https://github.com/fabiospampinato/cash/releases/tag/3.0.0) (2019-03-17) - Library rewritten in TypeScript - Bundle TypeScript typings (no need for @types/cash, which is now obsolete) - Added a changelog - Migration guide: mention the `zoom` property - Readme: improved description of the optional context argument - Ensure valid TypeScript types are generated - Ensure build files are updated when bumping the version ### v3.0.0-beta.3 (2018-12-06) - Fixed export on the ESM build ### v3.0.0-beta.2 (2018-11-21) - Renamed some "private" variables - Travis: avoiding caching `node_modules` - Test: improved tests regarding event delegating - Migration guide: added a section about events - Moved "@types/*" to "dependencies" - Replaced tabs with spaces - $.fn.trigger: triggering focus/blur natively - Event delegation: ensuring events that do not bubble (focus/blur/mouseenter/mouseleave) are still usable - Test: renamed some tests - Event delegation: ensuring `event.currentTarget` points to the right element - Migration guide: added a section about computing the dimensions of hidden elements - Fixed support for `event.currentTarget` - Migration guide: added a section about parsing script tags - Generalized `insertElement` to support a custom prepend target - Evaluating the content of `script` tags when attaching them to the DOM - Migration guide: added a `loadScript` function - find: improved resilience against text/comment/etc. nodes - $.fn.trigger: using `MouseEvents` when appropriate - evalScripts: improved browsers support - Improved support for `event.currentTarget` ### v3.0.0-beta.1 (2018-10-27) - Merge branch 'master' of github.com:kenwheeler/cash - Updated Karma configuration - $.fn.hasClass: ensuring it supports falsy values - $.matches: added back support for vendor-prefixed methods - Updated test suite - $.fn.val: improved support for old-ish browsers - Karma: picking versions relative to `latest`, when possible - Readme: ensuring `Cash` is always title-cased - Added a `filtered` utility - $.fn.children: cleaner implementation - $.fn.closest: faster implementation - $.fn.next|parent|prev|siblings: added support for an optional selector - pluck: added an optional `deep` parameter - $.fn.parents: much cleaner implementation - Added `$.fn.prevAll` - Added `$.fn.nextAll` - Updated readme - Added a "Migration Guide" - Added `$.fn.hide|show|toggle` - Added `$.fn.unwrap|wrap|wrapAll|wrapInner` ### v3.0.0-beta.0 (2018-10-26) - Test: added Firefox to Karma - Rewritten test suite - TypeScript: updated compiler options - $.fn.hasClass: aligned more with jQuery - $.camelCase: aligned more with jQuery - $.fn.extend: fixed support for defining plugins with it - computeStyle: check if a property is actually passed - computeStyle: returning `undefined` for unset CSS variables - Added `@types/node` as a dev dependency - camelCase: removed description - $.fn.each: improved performance - $.matches: removed support for older browsers - Travis: addded bundlesize - $.fn.prev|next: retrieving all previous/next elements - Test: ensuring `$.fn.replaceWith` and `$.fn.replaceAll` support multiple elements - Test: ensuring that `$.fn.data` supports more data types - $.fn.replaceWith: much cleaner implementation - $.fn.hasClass: much cleaner implementation - Added a `pluck` utility - $.fn.prev|next|parent: much cleaner implementation - $.fn.val: cleaner implementation - Simplified some events-related helpers - Creating one fewer div element - unique: improved performance - Updated logo - Readme: updated comparison tables - Added configuration for `bump` ### [v2.3.9](https://github.com/fabiospampinato/cash/releases/tag/2.3.9) (2018-10-21) - Changed files extensions to `ts` - $.parseHTML: fixed a regression regarding non-browser environments ### [v2.3.8](https://github.com/fabiospampinato/cash/releases/tag/2.3.8) (2018-10-20) - Updated some dependencies - Test: added `travis_retry` to tests with SauceLabs - Ignored package-lock.json - $.fn.val: ensuring when `null` is passed the value is cleared - Test: updated Travis CI configuration - Updated some dependencies - Test: updated `height` test to better support browsers returning floating values - Test: updated Karma configuration - $.fn.val: properly handling `null` - $.fn.append|prepend: ensuring it doesn't throw when passed `undefined` - $.parseHTML: added support for malformed single-tags - $.parseHTML: added support for parsing thead/tbody/tfoot/tr/td/th elements - Test: removed the " Passed!" suffix from messages - Test: fixed some malformed HTML ### [v2.3.7](https://github.com/fabiospampinato/cash/releases/tag/2.3.7) (2018-10-14) - Added cross-platform tests with SauceLabs - Test only against node LTS - Test: use IE11 on Windows 8.1 - Added a `test:karma:sauce` script - Added a `prepublish` script - Added some issue templates - Readme: added a "Contributing" section - Renamed `prepublish` script to `prepublishOnly` - Ensuring `$.parseHTML` always preserves the content of nodes ### [v2.3.6](https://github.com/fabiospampinato/cash/releases/tag/2.3.6) (2018-10-03) - Merge pull request #201 from limonte/patch-1 - chore(tests): bump qunit to latest - Merge pull request #202 from limonte/upgrade-qunit - CI: set up Karma test runner + Travis - Readme: removed travis-ci badge - Coding-style normalization - Added a `test:karma` script - Test: avoiding passing malformed html to `$.parseHTML` - Test: ensuring there are no syntax errors on IE11 - Readme: added a "License" section - Readme: added a "Thanks" section - Optimize .empty(), use removeChild() instead of .innerHTML = '' - `$.fn.empty`: updated code style ### [v2.3.5](https://github.com/fabiospampinato/cash/releases/tag/2.3.5) (2018-09-08) - Improved support for Node.js ### v2.3.4 (2018-09-07) - Moved `pacco` to `devDependencies` ### [v2.3.3](https://github.com/fabiospampinato/cash/releases/tag/2.3.3) (2018-07-09) - using the provided context when selecting by id - added support for using a cash object as the context - Improved readme ### [v2.3.2](https://github.com/fabiospampinato/cash/releases/tag/2.3.2) (2018-07-09) - Added a logo - Ensuring `$.fn.replaceWith` and `$.fn.replaceAll` work with multiple targets - $.fn.val: ensuring setting multiple values on a `select[multiple]` works - Added some tests ### [v2.3.1](https://github.com/fabiospampinato/cash/releases/tag/2.3.1) (2018-07-05) - Added support for `window` to dimensions-related methods ### [v2.3.0](https://github.com/fabiospampinato/cash/releases/tag/2.3.0) (2018-07-05) - Added a `$.fn.contents` method ### [v2.2.1](https://github.com/fabiospampinato/cash/releases/tag/2.2.1) (2018-06-16) - Ensuring a cash collection gets printed as array-like in Chrome ### [v2.2.0](https://github.com/fabiospampinato/cash/releases/tag/2.2.0) (2018-06-10) - Improved `test:jquery` script - Added `$.hasData` - $.fn.serialize: ensuring elements have a name - $.fn.serialize: ensuring empty string values are included - getValueSelectMultiple: checking for disabled options and disabled parent optgroups - $.fn.width|height: ensuring only element nodes are considered - computeStyle: ensuring only element nodes are considered - $.fn.css: skipping setting unsupported properties - $.fn.css: ensuring only element nodes are considered - $.parseHTML: ensuring it doesn't throw when non-string values are passed to it - $.parseHTML: returning an array instead of a `NodeList` - $.fn.attr: returning `undefined` instead of `null` for missing attributes - $.fn.attr: removing the attribute when setting a value of `null` - $.fn.removeAttr: added support for passing a space-separated string of attributes - $.fn.css: added support for CSS variables - $.fn.detach: avoding throwing an error when the parent node is missing - getData: some minor changes - $.fn.data: added support for getting the entire data object - Test: added some tests for `$.fn.before` and `$.fn.after` - $.fn.before|prepend|append|after: added support for inserting multiple contents - $.fn.after|prependTo: fixed ordering - $.fn.serialize: skipping inputs of type `image` - $.fn.serialize: ensuring multiple forms can be serialized at once - $.fn.ready: passing `cash` as the first argument to the callback - getSuffixedValue: added back support for `animationIterationCount` - $.fn.after|prependTo: avoiding mutating passed objects ### [v2.1.8](https://github.com/fabiospampinato/cash/releases/tag/2.1.8) (2018-06-10) - Updated some dependencies - $.fn.on: calling `preventDefault` and `stopPropagation` on the event if the handler returns `false` - Added a `test:jquery` script for running the jQuery test suite with cash ### [v2.1.7](https://github.com/fabiospampinato/cash/releases/tag/2.1.7) (2018-05-28) - Added some more explicit `@require` statements - Added a script for rendering the dependencies graph - Added an ESM build ### [v2.1.6](https://github.com/fabiospampinato/cash/releases/tag/2.1.6) (2018-05-19) - Events: passing the actual target element as `this` for delegated events ### [v2.1.5](https://github.com/fabiospampinato/cash/releases/tag/2.1.5) (2018-05-16) - $.fn.removeClass: fixed attribute resetting ### v2.1.4 (2018-05-14) - Updated jsDelivr URL - $.fn.trigger: events are now cancelable ### [v2.1.3](https://github.com/fabiospampinato/cash/releases/tag/2.1.3) (2018-05-12) - Merge pull request #184 from fabiospampinato/master - $.fn.width|height: fixed a bug with Firefox - Dropped IE9 support - Assuming getAttribute/setAttribute/remoteAttribute APIs are available - Added a `test:watch` script - Explicitly compile for IE10+ - Switching from UglifyJS to Google Closure Compiler - Events: removed jQuery-like methods: isDefaultPrevented/isPropagationStopped/isImmediatePropagationStopped - Events: avoiding using `get_data` for the cache - $.fn.filter: without a selector returns an empty collection - $.fn.index: optimized - getPrefixedProp: fixed caching logic - Major cleanup and bytes squeezing - Readme: updated `fn.has` documentation - Readme: fixed a typo - Readme: improved wording - Updated cash sizes - Updated partial builds ### v2.1.2 (2018-05-11) - Added some alternative configurations for pacco - Aligned `$.fn.prop` with jQuery's - Aligned `$.fn.removeClass` with jQuery's - Event delegation: handling the removal of the target from the DOM ### v2.1.1 (2018-05-03) - $.parseHTML: added a todo - $.fn.filter: optimized - $.fn.map: optimized - $.fn.find: optimized - Minor style changes - Aligned `$.fn.removeData` with jQuery's ### v2.1.0 (2018-04-12) - Aligned `$.fn.each` with jQuery's - Aligned `$.fn.map` with jQuery's - Aligned `$.fn.filter` with jQuery's - $.fn.height|width: setting to each element in the collection - $.fn.on: renamed `delegate` to `selector` - Aligned `$.val` with jQuery's - Aligned `$.fn.data` with jQuery's - $.fn.css: automatically adding the `px` suffix when necessary - Readme: updated minified + gzip size - $.fn.height: fixed - Aligned `$.fn.width|height` with jQuery's - Added support for namespaced events - $.fn.trigger: ensuring all namespaces match - Adding some methods to events: isDefaultPrevented, isPropagationStopped, isImmediatePropagationStopped ### v2.0.0 (2018-04-08) - Added a `guid` - $.fn.trigger: added support for triggering already-made events - $.fn.on|one|off: added support for multiple events - Readme: documented `$.guid` - Readme: updated `$.fn.trigger` documentation - Readme: updated `$.fn.on|one|off` documentation - Events: removing jQuery-like namespaces automatically - Added a `$.fn.slice` method - $.fn.height|width: added support for setting - Renamed `Init` to `Cash` - Readme: updated `$.fn.addClass|removeClass` - Readme: updated `$.fn.filter` - Readme: updated `$.fn.not` - Improved support for empty objects, without throwing errors - Ensuring eventCache is properly cleared - $.fn.off: added support for removing all handlers - $.fn.remove: removing also all events - Added a `$.fn.detach` method - Added a `$.contains` utility - Added a `$.fn.replaceWith` method - Added a `$.fn.replaceAll` method - Removed event un-namespacing - Added support for removing wrapped event handlers - Added support for removing handlers attached with `.one` - $.fn.one: ensuring `callback.guid` is set - Passing data as an argument - Readme: updated links - Renamed `Global Methods` to `Cash Methods` - hasClass: properly escaping regex special characters - $.fn.offsetParent: ensuring it doesn't throw with an empty collection - $.fn.removeData: fixed - removeData: fixed a variable name - initFragment: passing a string to `doc.implementation.createHTMLDocument`, as per spec - Added some tests - Requiring pacco@^1.1.0 - Explicitly compiling for IE >= 9 - Updated a todo ### [v1.3.7](https://github.com/fabiospampinato/cash/releases/tag/1.3.7) (2018-01-17) ### [v1.3.6](https://github.com/fabiospampinato/cash/releases/tag/1.3.6) (2018-01-11) - Test fixes - Argument required for `createHTMLDocument` - fix: attributes/addClass, the wrong checking on class-name inclusion - fix: remove `spacedName` from `addClass` interface - Added Travis CI support for modern node versions - Merge pull request #160 from amilajack/patch-1 - Update jsDelivr links - Merge pull request #168 from LukasDrgon/patch-1 - Merge pull request #173 from DanielRuf/patch-travis - Merge pull request #171 from DanielRuf/patch-readme - Merge pull request #157 from AugustMiller/am-createdocument-argument - Merge branch 'pr/153' (Async DOM Ready) - Merge branch 'pr/158' - Compiled className fix - Merge pull request #141 from vivekimsit/add-gitattribute ### [v1.3.5](https://github.com/fabiospampinato/cash/releases/tag/1.3.5) (2016-10-12) - Normalize all text files in the repo - Serialize elements outside form as well - Fix for #143 - fn in should always be called asynchronously - Merge PR #105 'parseHTML-fix' of https://github.com/softwarespot/cash into 1.3.5 - Merge PR #116 "Form Cleanup" - Merge PR #140 "Form Cleanup" - Merge PR #123 "Filter Fix" - Merge PR #124 `isFunction` fix - Merge PR #133 "Traversal Fixes" - Merge PR #136 'semicolon-iife' of https://github.com/vivekimsit/cash into 1.3.5 - Merge PR #138 'constructor-fix' into 1.3.5 - Merge PR #145 "event-off-fix" ### [v1.3.4](https://github.com/fabiospampinato/cash/releases/tag/1.3.4) (2016-06-28) ### [v1.3.3](https://github.com/fabiospampinato/cash/releases/tag/1.3.3) (2016-05-20) - Filter fix ### [v1.3.2](https://github.com/fabiospampinato/cash/releases/tag/1.3.2) (2016-05-18) ### [v1.3.1](https://github.com/fabiospampinato/cash/releases/tag/1.3.1) (2016-05-16) - CDN version links ### [v1.3.0](https://github.com/fabiospampinato/cash/releases/tag/1.3.0) (2016-05-04) - jQuery 3 comparison - Unified compare function for `$.fn.is` and `$.fn.not` to support looking for elements - Fixed `$.fn.siblings` to return a Collection instead of Array. - Fix for `$.fn.has` to return collection instead of Array and support for checking for an element instead of a string selector. - Use `$.fn.find` with an element instead of selector. - Merge branch 'master' of https://github.com/kenwheeler/cash - Fix for `$.fn.closest` to return correct results, `$.fn.filter` can now filter by Elements - Fix for #135: `$.fn.closest()` callstack exceeded - Use `Object.defineProperty` to attach the `constructor` property to the `cash.fn` prototype. #134 - merge PR #110 - merge PR #111 ### v1.2.3 (2016-??-??) - Saving bytes - [ remove class ] - add test for removing all classes - [ remove all classes ] - add an option for removing all classes - supply no arguments to .removeClass() - update readme ### v1.2.2 (2016-??-??) - `$.fn.filter` fix - merge PR #96 - [ add / remove / toggle / has class ] - add checks for integers and falsey values - closer to jQuery - was having script-killing errors when `.addClass("")` ### [v1.2.1](https://github.com/fabiospampinato/cash/releases/tag/1.2.1) (2016-04-25) - [ attr() ] - fix to return collection for multi-add - [ update ] - improve based on @shshaw comment https://github.com/kenwheeler/cash/pull/111#issuecomment-216283171 - Cleanup and @rwwagner90 fix - CloudFlare CDN - Clarified intro paragraph - Updated parseHTML which fixes the base URL issue - Fix conflict - Merge branch 'kenwheeler-master' - Added NPM reference - Bower.json fix - Usage updates - Merge pull request #102 from kenwheeler/npm-bower-fixes - Update README.md - Fix example for $.isArray - Merge pull request #81 from shvelo/patch-1 - Add data to trigger event - Increment test values - Update README to state approximate size - Merge pull request #84 from joezimjs/master - Browser Support Clarification - Size comparison - Latest CDN version - Heading comment - Set multiple attributes & properties - Merge pull request #87 from kenwheeler/attr-obj - added index to docs - updated utilities & type checking links - Merge pull request #89 from devinargenta/docs/index-added - Size alignment - Documentation for `$.fn.offet`, `$.fn.offetParent` and `$.fn.position` - Documentation for `$.fn.removeProp` - Documentation for setting properties - Utility alphabetical order - Clarifying $.fn prototype - Method index tables ( #88 ) ### [v1.2.0](https://github.com/fabiospampinato/cash/releases/tag/1.2.0) (2016-04-01) - Merge pull request #1 from shshaw/selector - Merge pull request #70 from shshaw/master - Size updates - Keep CDN files at last version until the CDNs have had a chance to update. - Simplified `on` - Updated README - Merge pull request #115 from kenwheeler/1.3.0 ### [v1.1.0](https://github.com/fabiospampinato/cash/releases/tag/1.1.0) (2016-04-12) - Fixed css() return value for object type input - Merge pull request #58 from kornalius/master - Update README.md - Fixing length to 0 when element doesn't exist - Merge pull request #64 from defrag/fix/empty-item-length - Merge pull request #65 from defrag/fix/suite-fix - Improve `fn.find` - `return false` breaks `.each` - `fn.children` and `fn.is` improvements - Smaller file size & consistency - Improve `append`, `prepend` - Clone entire collections - Added `.map` - README fixes - Simplification of manipulations - Fixed chainability of `remove` - Traversal cleanup - Unified collection functions - Simplified class manipulation - Form fixes - Tiny utils added to `cash` - Trim down by using local `each` - `add`, `push` and `splice` - `toggleClass` - Trimming - Multi-parameter extend - Merge pull request #66 from shshaw/master - Merge remote-tracking branch 'kenwheeler/master' - Trimmed `index` - Direct `map` - Trimmed `outerWidth` & `outerHeight` - Cleaned up events - Form serialize fix - Merge pull request #67 from shshaw/master - Merge remote-tracking branch 'kenwheeler/master' - `after`, `before` & `insert...` - Updated hints - Simplified `outerWidth` & `outerHeight` - Prefixed CSS Properties - Selector performance - Form test update - Merge pull request #69 from shshaw/better-selector - Merge remote-tracking branch 'kenwheeler/master' into selector - Even smaller `dimensions` - `event` fixes - `window` fixes - Clear `_eventCache` when all removed - Private `data` store - Replace `_eventCache` - `.one` support - `offset` ### [v1.0.0](https://github.com/fabiospampinato/cash/releases/tag/1.0.0) (2015-02-06) - Available in npm as cash-dom now - Adding `is` documentation - Add UMD wrapper - Store references for better minifying - Fill out package.json - Clean up README - Merge pull request #40 from hackbone/umd - Conform to Airbnb JavaScript style guide - Arbitrary stylistic changes for readability - Minify dimensions better - Minify events better and cleanup - Alias slice and filter for minifying - fn reference for minifying - Clean up gulpfile and remove beautify - Build lib - Stop using arguments object when unnecessary for better minifying - Switch to ES6 with 6to5 and update linting - Return target in extend, improve minifying - Build lib - Remove "use strict" due to Safari HTMLCollection bug - Merge branch 'master' of https://github.com/thejameskyle/cash into thejameskyle-master - Removing strict from list - Merge branch 'thejameskyle-master' ### [v0.0.3](https://github.com/fabiospampinato/cash/releases/tag/0.0.3) (2014-11-09) - Update README.md - Merge pull request #9 from richguan/patch-1 - Merge pull request #7 from Fender123/master - Committing the `add` feature in response to #16 - create tests for .add - allowing selector string input - fixing tests for selector string - Refactoring the $.fn.add method based on Ken's feedback, also update documentation and tests - Merge pull request #20 from simeydotme/master - add tests for parents, closest - updating documentation for closest and parents - change parents to closest and create new parents - Merge branch 'master' of https://github.com/simeydotme/cash - improve performance - test that HTML is last item in collection - Merge pull request #23 from simeydotme/master - Merge pull request #22 from vivekimsit/feature-closest-method - Remove deprecated JSHint options - `package.json` will always be 2 spaces - Merge pull request #26 from arthurvr/patch-2 - Merge pull request #25 from arthurvr/patch-1 - matches was throwing errors in IE9 - fix up closest tests, and make the removeClass test more robust - fix merge error with .closest() - make .removeClass() more robust for IE9 - dist files committed - improve the removeClass() function and performance slightly for IE9. removeClass will now accept space delimited class names for removal - Merge pull request #29 from simeydotme/fix-closest-and-removeclass - Making .each more performant via length caching. Fixing html() numeric input - Update README.md - Merge pull request #31 from simeydotme/patch-1 - Fixing #32 - Adds cash object support. - updating addClass function to allow multiple classes and to prevent duplicates in IE9 - update tests for multiple classes and to detect duplicates - update dist files - Merge pull request #38 from simeydotme/patch-addclass-2 - create a utility method to return a unique collection - update .parent(), .parents() and .add() to use $.unique() - update dist files and test cases - Merge pull request #37 from simeydotme/patch-parents-with-unique - Merge pull request #34 from vivekimsit/feature-add-is-support ### [v0.0.2](https://github.com/fabiospampinato/cash/releases/tag/0.0.2) (2014-09-27) - Performance - Fixing readme - Fixing siblings, making qSA return array - Fixing `_` leak - Add bower.json - Merge pull request #3 from digitaljhelms/bower-json - First round of unit tests + bug fixes - Fixing README typo & adding License - Fixes - Adding "auto-off" event registration and indexing - Bug Fixes - Updating delegate test and JSHint compat - delegate accuracy - updated outerWidth and innerWidth doc - Perf updates - Added a period(.) to the descriptions in README - Fixes #6 - Append and AppendTo can't chain - Merge pull request #10 from mienaikoe/master - Fixing html() & append returns - Merge branch 'master' of https://github.com/kenwheeler/cash ### [v0.0.1](https://github.com/fabiospampinato/cash/releases/tag/0.0.1) (2014-09-19) - Initial commit - README & Homepage - Update README.md ================================================ FILE: docs/extending_cash.md ================================================ # Extending Cash Cash can be extended, adding custom methods to Cash collections or custom static methods to the Cash object. If you're writing JavaScript the way to do it is exactly the same as what you'd do for extending jQuery, but if you're writing TypeScript you'll want to take advantage of the type system, so in order to extend Cash you'll have to do a bit of [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html). ## Collection Method This is how you can add an hypothetical `foo` method to Cash collections: ```ts /* IMPORTING */ import $ from 'cash-dom'; import {Cash} from 'cash-dom'; /* DECLARATION MERGING */ declare module 'cash-dom' { interface Cash { foo (): Cash } } /* FOO DEFINITION */ $.fn.foo = function ( this: Cash ): Cash { // Do something here... return this; } /* FOO USAGE */ $('*').foo (); ``` ## Static Method This is how you can add an hypothetical `foo` static method to the Cash object: ```ts /* IMPORTING */ import $ from 'cash-dom'; import {CashStatic} from 'cash-dom'; /* DECLARATION MERGING */ declare module 'cash-dom' { interface CashStatic { foo (): number } } /* FOO DEFINITION */ $.foo = function (): number { // Do something here... return 123; } /* FOO USAGE */ $.foo (); ``` ================================================ FILE: docs/migration_guide.md ================================================ # Migration Guide While Cash doesn't implement every feature that jQuery provides, everything that it implements should be compatible with jQuery, but there are some minor differences to be aware of and they are listed in this document. ## Attributes ### Booleans Boolean attributes are: `checked`, `selected`, `async`, `autofocus`, `autoplay`, `controls`, `defer`, `disabled`, `hidden`, `ismap`, `loop`, `multiple`, `open`, `readonly`, `required`, `scoped`. jQuery handles boolean attributes specially, potentially setting a different value than the one you passed it and updating the corresponding properties as well. Cash just handles them like any other attribute instead. ## CSS ### Relative values jQuery supports relative CSS values. ```javascript $('#foo').css ( 'padding-left', '+=10' ); ``` Cash doesn't support this. ## Data ### Caching jQuery's `$.fn.data` function caches retrieved values, and doesn't refresh them when they are updated outside of jQuery (e.g. via the `dataset` API), this makes jQuery's `$.fn.data` function unusable with libraries like React. Cash doesn't implement such caching functionality and doesn't have this problem, the retrieved values are always fresh. Also values set via Cash's `$.fn.data` function are stored as JSON values in `data-*` attributes set on the DOM nodes, so for instance calling `$('#foo').data ( 'test', 123 )` will add the `data-test="123"` attribute to the `#foo` node, as a concequence of this values that are not JSON-serializable are not supported. ### Plain objects jQuery supports handling data on plain objects. ```javascript $({}).data ( 'foo', 123 ); ``` Cash doesn't support this. ## Dimensions ### Hidden elements If you're trying to retrieve the width/height of an hidden element jQuery will briefly try to render it in order to compute it's dimension, this is unreliable and should be avoided. Cash doesn't implement such functionality. If you need this anyway you'll have to show/hide the element on your own: ```javascript // jQuery $('#foo').width (); // Cash $('#foo').show (); $('#foo').width (); $('#foo').hide (); ``` ### Negative dimension A negative width/height gets automatically converted to `0` by jQuery, both when setting it via `$.fn.width|height` or `$.fn.css`. Cash discourages you from setting a negative width/height, if you want this to work like jQuery you'll have to convert negative values to `0` on your own: ```javascript // jQuery $('#foo').width ( myWidth ); $('#foo').css ( width, myWidth ); $('#foo').css ({ width: myWidth }); // Cash myWidth = Math.max ( 0, parseFloat ( myWidth ) ); $('#foo').width ( myWidth ); $('#foo').css ( width, myWidth ); $('#foo').css ({ width: myWidth }); ``` ### Transformed element jQuery ignores any `transform` applied to the element when computing its dimensions. Cash doesn't. You may try reading untransformed dimensions with the `$.fn.css` method instead. ## Events Cash's event system relies heavily on the browser's underlying event system so there are some differences when comparing it with jQuery's. ### Custom methods jQuery provides some custom event methods. ```javascript event.isDefaultPrevented (); event.isPropagationStopped (); event.isImmediatePropagationStopped (); event.originalEvent; ``` Cash doesn't provide them, as it simply passes along the raw event object instead. ```javascript event.defaultPrevented; event.cancelBubble; // No way of knowing if `stopImmediatePropagation` was called event; ``` ### Stopping propagation from a delegated event handler In Cash when using event delegation calling `event.stopPropagation` or returning `false` stops the propagation from the target element, not the delegate element. There's no perfect workaround for this unfortunately, but in most practical cases you could call `event.stopImmediatePropagation` instead. ```javascript // jQuery $('#foo').on ( 'click', '.bar', event => false ); // First function called $('#foo').on ( 'click', '.bar', event => {} ); // Second function called $('#foo').on ( 'click', event => {} ); // Function never called $('.bar').trigger ( 'click' ); // Cash $('#foo').on ( 'click', '.bar', event => false ); // First function called $('#foo').on ( 'click', '.bar', event => {} ); // Second function called $('#foo').on ( 'click', event => {} ); // Third function called $('.bar').trigger ( 'click' ); // Cash + "stopImmediatePropagation" $('#foo').on ( 'click', '.bar', event => { // First function called event.stopImmediatePropagation (); }); $('#foo').on ( 'click', '.bar', event => {} ); // Function never called $('#foo').on ( 'click', event => {} ); // Function never called $('.bar').trigger ( 'click' ); ``` ### Trigger data jQuery supports passing multiple data arguments to your event handlers by providing an array of data arguments to `$.fn.trigger`. Cash doesn't support this, whatever you provide as a data argument will be passed through as is, even if it's an array. ### Plain objects jQuery supports handling events on plain objects. ```javascript $({}).on ( 'foo', () => {} ); ``` Cash doesn't support this. ## Manipulation ### Inserting plain text jQuery supports inserting plain text using different methods (`$.fn.after`, `$.fn.append` etc.). ```javascript $('.foo').append ( 'something' ); ``` Cash doesn't support that because it instead supports receiving a selector as an argument, and that can be ambigous when also supporting plain text. ```javascript $('.foo').append ( '.foo' ); // Is that a target or do we actually wanto to append ".foo"? ``` In Cash you should generally wrap your plain texts in a `` element, or create a `textNode` node manually. ```javascript $('.foo').append ( 'something' ); $('.foo').append ( document.createTextNode ( 'something' ) ); ``` ## Parsing ### Malformed HTML jQuery smooths over many details and attempts to correctly parse malformed HTML. ```javascript $('

').length // => 4 ``` Cash on the other hand for the most part just lets the browser handle your HTML directly, so it behaves more strictly and you should be more careful about the HTML strings you're passing to it. ```javascript $('

').length // => 1 ``` ## Selectors ### Custom selectors jQuery implements many custom selectors, like `:hidden`. Cash only supports selectors the browser recognizes as valid, everything else will throw an error. ### Binary operators Some CSS operators are binary, they operate on something before and after them: `>`, `~`, `+`. jQuery allows you to use them at the beginning of your selectors inside `$.fn.find`, in a unary fashion. Cash only supports selectors the browser recognizes as valid, so you can't just use `> .bar` like you sometimes can with jQuery. If you only target modern browsers you could use the [`:scope`](https://developer.mozilla.org/en-US/docs/Web/CSS/:scope) CSS pseudo-class. ```javascript // jQuery $('#foo').find ( '> .bar' ); $('#foo').find ( '~ .bar' ); $('#foo').find ( '+ .bar' ); // Cash $('#foo').children ( '.bar' ); $('#foo').nextAll ( '.bar' ); $('#foo').next ( '.bar' ); // Cash + ":scope" $('#foo').find ( ':scope > .bar' ); $('#foo').find ( ':scope ~ .bar' ); $('#foo').find ( ':scope + .bar' ); ``` ## Utilities ### Unique jQuery's `$.unique` function only works with DOM nodes. Cash's `$.unique` function works with any kind of value. ## Others Other general differences to be aware of. ### Disconnected nodes, iframes and SVGs jQuery handles specially disconnected nodes, iframes and SVGs, smoothing over many rough corners and just making their APIs "work". Cash doesn't smooth over as many rough corners (yet?), so you should test more carefully the portions of your code that deal with those kind of objects. ### Function that returns a value jQuery accepts in many methods a function that returns a value, other than just the value itself. ```javascript $('#foo').attr ( 'bar', () => Math.random () ); ``` Cash doesn't support this. ### Sort order Elements inside Cash and jQuery collections may be sorted differently. ## Contributing Did you find another difference between jQuery and Cash during your migration? Please add that to this page so that future migrations will be smoother for others. ================================================ FILE: docs/partial_builds.md ================================================ # Partial Builds Cash is bundled using [minipacco](https://github.com/fabiospampinato/minipacco), therefore it supports partial builds out of the box. ## Guide Replace the content of [`src/methods.ts`](https://github.com/fabiospampinato/cash/tree/master/src/methods.ts) with your custom configuration, basically deleting imports for methods that you don't want, then you can simply rebuild the library with: ```sh npm install npm run build ``` ================================================ FILE: license ================================================ The MIT License (MIT) Copyright (c) 2014-2020 Ken Wheeler, 2020-present Fabio Spampinato Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: package.json ================================================ { "name": "cash-dom", "repository": "github:fabiospampinato/cash", "description": "An absurdly small jQuery alternative for modern browsers.", "version": "8.1.5", "license": "MIT", "browser": "./dist/cash.js", "main": "./dist/cash.js", "module": "./dist/cash.esm.js", "jsnext:main": "./dist/cash.esm.js", "types": "dist/cash.d.ts", "files": [ "dist" ], "scripts": { "build": "bash ./tasks/build.sh", "watch": "monex --watch src --exec npm:build", "dev": "npm run build && npm run watch", "test": "open ./test/index.html", "test:jquery:init": "( git -C ./test/jquery reset --hard HEAD && git -C ./test/jquery pull ) || git clone https://github.com/jquery/jquery.git ./test/jquery", "test:jquery": "npm run test:jquery:init && npm run test:jquery:build && cd ./test/jquery && npm i && opn http://localhost:4444/test/index.html\\?module=css && php -S localhost:4444", "test:jquery:build": "cat ./node_modules/jquery/dist/jquery.js ./dist/cash.js ./test/jquery_patch.js > ./test/jquery/dist/jquery.js && cp ./test/jquery/dist/jquery.js ./test/jquery/dist/jquery.min.js", "test:jquery:build:watch": "while sleep 1; do npm run test:jquery:build; done", "test:jquery:reverse": "npm run test:jquery:init && npm run test:jquery:reverse:build && npm run test:watch", "test:jquery:reverse:build": "cat ./node_modules/jquery/dist/jquery.js ./dist/cash.min.js ./test/jquery_reverse_patch.js > ./dist/cash.js", "test:jquery:reverse:build:watch": "while sleep 1; do npm run test:jquery:reverse:build; done", "test:playwright": "node ./test/playwright.mjs", "graph": "minipacco graph src/export_esm.ts", "prepublishOnly": "npm run build && npm run test:playwright" }, "devDependencies": { "esbuild": "^0.17.10", "jquery": "^3.6.3", "minipacco": "^1.0.4", "monex": "^2.0.0", "playwright": "^1.30.0", "qunit": "^2.19.4", "qunit-ava-spec": "^2.0.0", "tiny-colors": "^2.0.2", "typescript": "^4.9.5" } } ================================================ FILE: readme.md ================================================

Cash Logo

# Cash Cash is an absurdly small jQuery alternative for modern browsers (IE11+) that provides jQuery-style syntax for manipulating the DOM. Utilizing modern browser features to minimize the codebase, developers can use the familiar chainable methods at a fraction of the file size. 100% feature parity with jQuery isn't a goal, but Cash comes helpfully close, covering most day to day use cases. ## Comparison | Size | Cash | Zepto 1.2.0 | jQuery Slim 3.4.1 | | ------------------ | ----------- | ----------- | ----------------- | | Unminified | **36.5 KB** | 58.7 KB | 227 KB | | Minified | **16 KB** | 26 KB | 71 KB | | Minified & Gzipped | **6 KB** | 9.8 KB | 24.4 KB | A **76.6%** gain in size reduction compared to jQuery Slim. If you need a smaller bundle, we support [partial builds](https://github.com/fabiospampinato/cash/blob/master/docs/partial_builds.md) too. | Features | Cash | Zepto 1.2.0 | jQuery Slim 3.4.1 | | ------------------------ | ---------------------------------- | ------------------------------ | ------------------------------ | | Supports Older Browsers | ❌ | ️❌ | ✔ | | Supports Modern Browsers | ✔ | ️✔ | ✔ | | Actively Maintained | ✔ | ❌ | ✔ | | Namespaced Events | ✔ | ️❌ | ✔ | | Typed Codebase | ✔ (TypeScript) | ️❌ | ❌ | | TypeScript Types | ✔ (generated from code) | ⚠️ (via DefinitelyTyped) | ⚠️ (via DefinitelyTyped) | | Partial Builds | ✔ (can exclude individual methods) | ⚠️ (can exclude whole modules) | ⚠️ (can exclude whole modules) | If you're migrating from jQuery be sure to read our [migration guide](https://github.com/fabiospampinato/cash/blob/master/docs/migration_guide.md). ## Usage You can get Cash from [jsDelivr](https://cdn.jsdelivr.net/npm/cash-dom/dist/cash.min.js) and use it like this: ```html ``` Cash is also available through [npm](https://npmjs.com) as the [`cash-dom`](https://www.npmjs.com/package/cash-dom) package: ```sh npm install --save cash-dom ``` That you can then use like this: ```js import $ from "cash-dom"; $(function () { $('html').addClass ( 'dom-loaded' ); $('
Appended with Cash
').appendTo ( document.body ); }); ``` ## Documentation Cash gives you a query selector, [collection methods](#collection-methods) and some [library methods](#cash-methods). If you need more details about our API just check out [jQuery's](https://api.jquery.com), while we don't implement everything that jQuery provides, pretty much everything that we do implement should be compatible with jQuery. Cash can be extended with custom methods, read how [here](https://github.com/fabiospampinato/cash/blob/master/docs/extending_cash.md). ### $() This is the main selector method for Cash. It returns an actionable collection of nodes. If a function is provided, the function will be run once the DOM is ready. ```js $( selector [, element] ) // => collection, using `element` as the context $( selector [, collection] ) // => collection, using `collection` as the context $(node) // => collection $(nodeList) // => collection $(htmlString) // => collection $(collection) // => self $(function () {}) // => document ready callback ``` ### Collection Methods These methods from the collection prototype ([$.fn](#fn)) are available once you create a collection with `$()` and are called like so: ```js $(element).addClass ( className ) // => collection ``` Some [extra methods](https://github.com/fabiospampinato/cash/tree/master/src/extra) are available but disabled by default. | Attributes | Collection | CSS | Data | Dimensions | Effects | | ------------------------------------ | -------------------------- | -------------------- | ---------------------- | ------------------------------------ | -------------------------- | | [fn.addClass ()](#fnaddclass-) | [fn.add ()](#fnadd-) | [fn.css ()](#fncss-) | [fn.data ()](#fndata-) | [fn.height ()](#fnheight-) | [fn.hide ()](#fnhide-) | | [fn.attr ()](#fnattr-) | [fn.each ()](#fneach-) | | | [fn.innerHeight ()](#fninnerheight-) | [fn.show ()](#fnshow-) | | [fn.hasClass ()](#fnhasclass-) | [fn.eq ()](#fneq-) | | | [fn.innerWidth ()](#fninnerwidth-) | [fn.toggle ()](#fntoggle-) | | [fn.prop ()](#fnprop-) | [fn.filter ()](#fnfilter-) | | | [fn.outerHeight ()](#fnouterheight-) | | | [fn.removeAttr ()](#fnremoveattr-) | [fn.first ()](#fnfirst-) | | | [fn.outerWidth ()](#fnouterwidth-) | | | [fn.removeClass ()](#fnremoveclass-) | [fn.get ()](#fnget-) | | | [fn.width ()](#fnwidth-) | | | [fn.removeProp ()](#fnremoveprop-) | [fn.index ()](#fnindex-) | | | | | | [fn.toggleClass ()](#fntoggleclass-) | [fn.last ()](#fnlast-) | | | | | | | [fn.map ()](#fnmap-) | | | | | | | [fn.slice ()](#fnslice-) | | | | | | Events | Forms | Manipulation | Offset | Traversal | | ---------------------------- | -------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- | | [fn.off ()](#fnoff-) | [fn.serialize ()](#fnserialize-) | [fn.after ()](#fnafter-) | [fn.offset ()](#fnoffset-) | [fn.children ()](#fnchildren-) | | [fn.on ()](#fnon-) | [fn.val ()](#fnval-) | [fn.append ()](#fnappend-) | [fn.offsetParent ()](#fnoffsetparent-) | [fn.closest ()](#fnclosest-) | | [fn.one ()](#fnone-) | | [fn.appendTo ()](#fnappendto-) | [fn.position ()](#fnposition-) | [fn.contents ()](#fncontents-) | | [fn.ready ()](#fnready-) | | [fn.before ()](#fnbefore-) | | [fn.find ()](#fnfind-) | | [fn.trigger ()](#fntrigger-) | | [fn.clone ()](#fnclone-) | | [fn.has ()](#fnhas-) | | | | [fn.detach ()](#fndetach-) | | [fn.is ()](#fnis-) | | | | [fn.empty ()](#fnempty-) | | [fn.next ()](#fnnext-) | | | | [fn.html ()](#fnhtml-) | | [fn.nextAll ()](#fnnextall-) | | | | [fn.insertAfter ()](#fninsertafter-) | | [fn.nextUntil ()](#fnnextuntil-) | | | | [fn.insertBefore ()](#fninsertbefore-) | | [fn.not ()](#fnnot-) | | | | [fn.prepend ()](#fnprepend-) | | [fn.parent ()](#fnparent-) | | | | [fn.prependTo ()](#fnprependto-) | | [fn.parents ()](#fnparents-) | | | | [fn.remove ()](#fnremove-) | | [fn.parentsUntil ()](#fnparentsuntil-) | | | | [fn.replaceAll ()](#fnreplaceall-) | | [fn.prev ()](#fnprev-) | | | | [fn.replaceWith ()](#fnreplacewith-) | | [fn.prevAll ()](#fnprevall-) | | | | [fn.text ()](#fntext-) | | [fn.prevUntil ()](#fnprevuntil-) | | | | [fn.unwrap ()](#fnunwrap-) | | [fn.siblings ()](#fnsiblings-) | | | | [fn.wrap ()](#fnwrap-) | | | | | | [fn.wrapAll ()](#fnwrapall-) | | | | | | [fn.wrapInner ()](#fnwrapinner-) | | | #### $.fn The main prototype for collections, allowing you to extend Cash with plugins by adding methods to all collections. ```js $.fn // => Cash.prototype $.fn.myMethod = function () {}; // Custom method added to all collections $.fn.extend ( object ); // Add multiple methods to the prototype ``` #### fn.add () Returns a new collection with the element(s) added to the end. ```js $(element).add ( element ) // => collection $(element).add ( selector ) // => collection $(element).add ( collection ) // => collection ``` #### fn.addClass () Adds the `className` class to each element in the collection. Accepts space-separated `className` for adding multiple classes. ```js $(element).addClass ( className ) // => collection ``` #### fn.after () Inserts content or elements after the collection. ```js $(element).after ( element ) // => collection $(element).after ( htmlString ) // => collection $(element).after ( content [, content] ) // => collection ``` #### fn.append () Appends content or elements to each element in the collection. ```js $(element).append ( element ) // => collection $(element).append ( htmlString ) // => collection $(element).append ( content [, content] ) // => collection ``` #### fn.appendTo () Adds the elements in the collection to the target element(s). ```js $(element).appendTo ( element ) // => collection ``` #### fn.attr () Without `attrValue`, returns the attribute value of the first element in the collection. With `attrValue`, sets the attribute value of each element of the collection. ```js $(element).attr ( attrName ) // value $(element).attr ( attrName, attrValue ) // => collection $(element).attr ( object ) // => collection ``` #### fn.before () Inserts content or elements before the collection. ```js $(element).before ( element ) // => collection $(element).before ( htmlString ) // => collection $(element).before ( content [, content] ) // => collection ``` #### fn.children () Without a selector specified, returns a collection of child elements. With a selector, returns child elements that match the selector. ```js $(element).children () // => collection $(element).children ( selector ) // => collection ``` #### fn.closest () Returns the closest matching selector up the DOM tree. ```js $(element).closest ( selector ) // => collection ``` #### fn.contents () Get the children of each element in the set of matched elements, including text and comment nodes. Useful for selecting elements in friendly iframes. ```js $('iframe').contents ().find ( '*' ) // => collection ``` #### fn.clone () Returns a collection with cloned elements. ```js $(element).clone () // => collection ``` #### fn.detach () Removes collection elements, optionally that match the selector, from the DOM. ```js $(element).detach () // => collection $(element).detach ( selector ) // => collection ``` #### fn.css () Returns a CSS property value when just property is supplied. Sets a CSS property when property and value are supplied. Sets multiple properties when an object is supplied. Properties will be autoprefixed if needed for the user's browser. ```js $(element).css ( property ) // => value $(element).css ( property, value ) // => collection $(element).css ( object ) // => collection ``` #### fn.data () Without arguments, returns an object mapping all the `data-*` attributes to their values. With a `key`, return the value of the corresponding `data-*` attribute. With both a `key` and `value`, sets the value of the corresponding `data-*` attribute to `value`. Multiple data can be set when an object is supplied. ```js $(element).data () // => object $(element).data ( key ) // => value $(element).data ( key, value ) // => collection $(element).data ( object ) // => collection ``` #### fn.each () Iterates over a collection with `callback ( index, element )`. The callback function may exit iteration early by returning `false`. ```js $(element).each ( callback ) // => collection ``` #### fn.empty () Empties the elements interior markup. ```js $(element).empty () // => collection ``` #### fn.eq () Returns a collection with the element at index. ```js $(element).eq ( index ) // => collection ``` #### fn.extend () Adds properties to the Cash collection prototype. ```js $.fn.extend ( object ) // => object ``` #### fn.filter () Returns the collection that results from applying the filter selector/method. ```js $(element).filter ( selector ) // => collection $(element).filter ( function ( index, element ) {} ) // => collection ``` #### fn.find () Returns selector match descendants from the first element in the collection. ```js $(element).find ( selector ) // => collection ``` #### fn.first () Returns a collection containing only the first element. ```js $(element).first () // => collection ``` #### fn.get () Returns the element at the index, or returns all elements. ```js $(element).get ( index ) // => domNode $(element).get () // => domNode[] ``` #### fn.has () Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element. ```js $(element).has ( selector ) // => collection $(element).has ( element ) // => collection ``` #### fn.hasClass () Returns the boolean result of checking if any element in the collection has the `className` attribute. ```js $(element).hasClass ( className ) // => boolean ``` #### fn.height () Returns or sets the height of the element. ```js $(element).height () // => Integer $(element).height ( number ) // => collection ``` #### fn.hide () Hide the elements. ```js $(element).hide () // => collection ``` #### fn.html () Returns the HTML text of the first element in the collection, sets the HTML if provided. ```js $(element).html () // => HTML Text $(element).html ( htmlString ) // => HTML Text ``` #### fn.index () Returns the index of the element in its parent if an element or selector isn't provided. Returns index within element or selector if it is. ```js $(element).index () // => Integer $(element).index ( element ) // => Integer ``` #### fn.innerHeight () Returns the height of the element + padding. ```js $(element).innerHeight () // => Integer ``` #### fn.innerWidth () Returns the width of the element + padding. ```js $(element).innerWidth () // => Integer ``` #### fn.insertAfter () Inserts collection after specified element. ```js $(element).insertAfter ( element ) // => collection ``` #### fn.insertBefore () Inserts collection before specified element. ```js $(element).insertBefore ( element ) // => collection ``` #### fn.is () Returns whether the provided selector, element or collection matches any element in the collection. ```js $(element).is ( selector ) // => boolean ``` #### fn.last () Returns a collection containing only the last element. ```js $(element).last () // => collection ``` #### fn.map () Returns a new collection, mapping each element with `callback ( index, element )`. ```js $(selector).map ( callback ) // => collection ``` #### fn.next () Returns the next adjacent elements. ```js $(element).next () // => collection $(element).next ( selector ) // => collection ``` #### fn.nextAll () Returns all the next elements. ```js $(element).nextAll () // => collection $(element).nextAll ( selector ) // => collection ``` #### fn.nextUntil () Returns all the next elements, until the provided selector matches. ```js $(element).nextUntil ( selector ) // => collection $(element).nextUntil ( selector, filterSelector ) // => collection ``` #### fn.not () Filters collection by false match on collection/selector. ```js $(element).not ( selector ) // => collection $(element).not ( collection ) // => collection ``` #### fn.off () Removes event listener from collection elements. Accepts space-separated `eventName` for removing multiple events listeners. Removes all event listeners if called without arguments. ```js $(element).off ( eventName, eventHandler ) // => collection $(element).off ( eventName ) // => collection $(element).off ( eventsMap ) // => collection $(element).off () // => collection ``` #### fn.offset () Get the coordinates of the first element in a collection relative to the document. ```js $(element).offset () // => Object ``` #### fn.offsetParent () Get the first element's ancestor that's positioned. ```js $(element).offsetParent () // => collection ``` #### fn.on () Adds event listener to collection elements. Accepts space-separated `eventName` for listening to multiple events. Event is delegated if delegate is supplied. ```js $(element).on ( eventsMap ) // => collection $(element).on ( eventName, eventHandler ) // => collection $(element).on ( eventName, delegate, eventHandler ) // => collection ``` #### fn.one () Adds event listener to collection elements that only triggers once for each element. Accepts space-separated `eventName` for listening to multiple events. Event is delegated if delegate is supplied. ```js $(element).one ( eventName, eventHandler ) // => collection $(element).one ( eventName, delegate, eventHandler ) // => collection ``` #### fn.outerHeight () Returns the outer height of the element. Includes margins if `includeMargings` is set to true. ```js $(element).outerHeight () // => Integer $(element).outerHeight ( includeMargins ) // => Integer ``` #### fn.outerWidth () Returns the outer width of the element. Includes margins if `includeMargings` is set to true. ```js $(element).outerWidth () // => Integer $(element).outerWidth ( includeMargins ) // => Integer ``` #### fn.parent () Returns collection of elements who are parent of elements. ```js $(element).parent () // => collection $(element).parent ( selector ) // => collection ``` #### fn.parents () Returns collection of elements who are parents of elements. Optionally filtering by selector. ```js $(element).parents () // => collection $(element).parents ( selector ) // => collection ``` #### fn.parentsUntil () Returns collection of elements who are parents of elements, until a provided selector matches. Optionally filtering by selector. ```js $(element).parentsUntil ( selector ) // => collection $(element).parentsUntil ( selector, filterSelector ) // => collection ``` #### fn.position () Get the coordinates of the first element in a collection relative to its `offsetParent`. ```js $(element).position () // => object ``` #### fn.prepend () Prepends content or elements to the each element in collection. ```js $(element).prepend ( element ) // => collection $(element).prepend ( htmlString ) // => collection $(element).prepend ( content [, content] ) // => collection ``` #### fn.prependTo () Prepends elements in a collection to the target element(s). ```js $(element).prependTo ( element ) // => collection ``` #### fn.prev () Returns the previous adjacent elements. ```js $(element).prev () // => collection $(element).prev ( selector ) // => collection ``` #### fn.prevAll () Returns all the previous elements. ```js $(element).prevAll () // => collection $(element).prevAll ( selector ) // => collection ``` #### fn.prevUntil () Returns all the previous elements, until the provided selector matches. ```js $(element).prevUntil ( selector ) // => collection $(element).prevUntil ( selector, filterSelector ) // => collection ``` #### fn.prop () Returns a property value when just property is supplied. Sets a property when property and value are supplied, and sets multiple properties when an object is supplied. ```js $(element).prop ( property ) // => property value $(element).prop ( property, value ) // => collection $(element).prop ( object ) // => collection ``` #### fn.ready () Calls callback method on DOMContentLoaded. ```js $(document).ready ( callback ) // => collection/span ``` #### fn.remove () Removes collection elements, optionally that match the selector, from the DOM and removes all their event listeners. ```js $(element).remove () // => collection $(element).remove ( selector ) // => collection ``` #### fn.replaceAll () This is similar to [fn.replaceWith ()](#fnreplacewith-), but with the source and target reversed. ```js $(element).replaceAll ( content ) // => collection ``` #### fn.replaceWith () Replace collection elements with the provided new content. ```js $(element).replaceWith ( content ) // => collection ``` #### fn.removeAttr () Removes attribute from collection elements. Accepts space-separated attrName for removing multiple attributes. ```js $(element).removeAttr ( attrName ) // => collection ``` #### fn.removeClass () Removes className from collection elements. Accepts space-separated className for adding multiple classes. Providing no arguments will remove all classes. ```js $(element).removeClass () // => collection $(element).removeClass ( className ) // => collection ``` #### fn.removeProp () Removes property from collection elements. ```js $(element).removeProp ( propName ) // => collection ``` #### fn.serialize () When called on a form, serializes and returns form data. ```js $(form).serialize () // => String ``` #### fn.show () Show the elements. ```js $(element).show () // => collection ``` #### fn.siblings () Returns a collection of sibling elements. ```js $(element).siblings () // => collection $(element).siblings ( selector ) // => collection ``` #### fn.slice () Returns a new collection with elements taken from start to end. ```js $(selector).slice ( start, end ) // => collection ``` #### fn.text () Returns the inner text of the first element in the collection, sets the text if textContent is provided. ```js $(element).text () // => text $(element).text ( textContent ) // => collection ``` #### fn.toggle () Hide or show the elements. ```js $(element).toggle () // => collection $(element).toggle ( force ) // => collection ``` #### fn.toggleClass () Adds or removes className from collection elements based on if the element already has the class. Accepts space-separated classNames for toggling multiple classes, and an optional `force` boolean to ensure classes are added (`true`) or removed (`false`). ```js $(element).toggleClass ( className ) // => collection $(element).toggleClass ( className, force ) // => collection ``` #### fn.trigger () Triggers supplied event on elements in collection. Data can be passed along as the second parameter. ```js $(element).trigger ( eventName ) // => collection $(element).trigger ( eventObj ) // => collection $(element).trigger ( eventName, data ) // => collection $(element).trigger ( eventObj, data ) // => collection ``` #### fn.unwrap () Removes the wrapper from all elements. ```js $(element).unwrap () // => collection ``` #### fn.val () Returns an inputs value. If value is supplied, sets all inputs in collection's value to the value argument. ```js $(input).val () // => value $(input).val ( value ) // => collection ``` #### fn.width () Returns or sets the width of the element. ```js $(element).width () // => number $(element).width ( number ) // => collection ``` #### fn.wrap () Wraps a structure around each element. ```js $(element).wrap ( structure ) // => collection ``` #### fn.wrapAll () Wraps a structure around all elements. ```js $(element).wrapAll ( structure ) // => collection ``` #### fn.wrapInner () Wraps a structure around all children. ```js $(element).wrapInner ( structure ) // => collection ``` ### Cash Methods These methods are exported from the global `$` object, and are called like so: ```js $.isArray ( arr ) // => boolean ``` Some [extra methods](https://github.com/fabiospampinato/cash/tree/master/src/extra) are available but [disabled](https://github.com/fabiospampinato/cash/blob/master/pacco.json#L3) by default. | Type Checking | Utilities | | ------------------------------------- | ----------------------------- | | [$.isArray ()](#isarray-) | [$.guid](#guid) | | [$.isFunction ()](#isfunction-) | [$.each ()](#each-) | | [$.isNumeric ()](#isnumeric-) | [$.extend ()](#extend-) | | [$.isPlainObject ()](#isplainobject-) | [$.parseHTML ()](#parsehtml-) | | [$.isWindow ()](#iswindow-) | [$.unique ()](#unique-) | #### $.guid A unique number. ```js $.guid++ // => number ``` #### $.each () Iterates through an array and calls the `callback ( index, element )` method on each element. Iterates through an object and calls the `callback ( key, value )` method on each property. The callback function may exit iteration early by returning `false`. ```js $.each ( array, callback ) // => array $.each ( object, callback ) // => object ``` #### $.extend () Extends target object with properties from the source object, potentially deeply too. ```js $.extend ( target, source ) // => object $.extend ( true, target, source ) // => object ``` #### $.isArray () Check if the argument is an array. ```js $.isArray ([ 1, 2, 3 ]) // => true ``` #### $.isFunction () Check if the argument is a function. ```js function fn () {}; $.isFunction ( fn ) // => true ``` #### $.isNumeric () Check if the argument is numeric. ```js $.isNumeric ( 57 ) // => true ``` #### $.isPlainObject () Check if the argument is a plain object. ```js $.isPlainObject ( {} ) // => true ``` #### $.isWindow () Check if the argument is a Window object. ```js $.isWindow ( window ) // => true ``` #### $.parseHTML () Returns a collection from an HTML string. ```js $.parseHTML ( htmlString ) // => collection ``` #### $.unique () Returns a new array with duplicates removed. ```js $.unique ( array ) // => array ``` ## Contributing If you found a problem, or have a feature request, please open an [issue](https://github.com/fabiospampinato/cash/issues) about it. If you want to make a pull request you should: 1. Clone the repository: `git clone https://github.com/fabiospampinato/cash.git`. 2. Enter the cloned repository: `cd cash` 3. Install the dependencies: `npm install`. 4. Automatically recompile Cash whenever a change is made: `npm run dev`. 5. Open the test suite: `npm run test`. 6. Remember to update the readme, if necessary. ## Thanks - **[@kenwheeler](https://github.com/kenwheeler), [@shshaw](https://github.com/shshaw), [@jamiebuilds](https://github.com/jamiebuilds), [@simeydotme](https://github.com/simeydotme)** and all the contributors who helped making Cash. - **[@hisk](https://github.com/hisk)** - The "design focused engineer" behind our awesome logo. ## License MIT © Fabio Spampinato ================================================ FILE: src/attributes/add_class.ts ================================================ // @require core/cash.ts // @require ./toggle_class.ts interface Cash { addClass ( classes: string ): this; } fn.addClass = function ( this: Cash, cls: string ) { return this.toggleClass ( cls, true ); }; ================================================ FILE: src/attributes/attr.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./remove_attr.ts interface Cash { attr (): undefined; attr ( attrs: string ): string | null; attr ( attrs: string, value: string ): this; attr ( attrs: Record ): this; } function attr ( this: Cash ): undefined; function attr ( this: Cash, attr: string ): string | null; function attr ( this: Cash, attr: string, value: string ): Cash; function attr ( this: Cash, attr: Record ): Cash; function attr ( this: Cash, attr?: string | Record, value?: string ) { if ( !attr ) return; if ( isString ( attr ) ) { if ( arguments.length < 2 ) { if ( !this[0] || !isElement ( this[0] ) ) return; const value = this[0].getAttribute ( attr ); return isNull ( value ) ? undefined : value; } if ( isUndefined ( value ) ) return this; if ( isNull ( value ) ) return this.removeAttr ( attr ); return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; ele.setAttribute ( attr, value ) }); } for ( const key in attr ) { this.attr ( key, attr[key] ); } return this; } fn.attr = attr; ================================================ FILE: src/attributes/has_class.ts ================================================ // @require core/cash.ts // @require core/get_split_values.ts // @require core/type_checking.ts // @require collection/each.ts interface Cash { hasClass ( cls: string ): boolean; } fn.hasClass = function ( this: Cash, cls: string ) { return !!cls && some.call ( this, ( ele: EleLoose ) => isElement ( ele ) && ele.classList.contains ( cls ) ); }; ================================================ FILE: src/attributes/helpers/variables.ts ================================================ const propMap: Record = { /* GENERAL */ class: 'className', contenteditable: 'contentEditable', /* LABEL */ for: 'htmlFor', /* INPUT */ readonly: 'readOnly', maxlength: 'maxLength', tabindex: 'tabIndex', /* TABLE */ colspan: 'colSpan', rowspan: 'rowSpan', /* IMAGE */ usemap: 'useMap' }; ================================================ FILE: src/attributes/prop.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./helpers/variables.ts interface Cash { prop ( prop: string ): any; prop ( prop: string, value: any ): this; prop ( props: Record ): this; } fn.prop = function ( this: Cash, prop: string | Record, value?: any ) { if ( !prop ) return; if ( isString ( prop ) ) { prop = propMap[prop] || prop; if ( arguments.length < 2 ) return this[0] && this[0][prop]; return this.each ( ( i, ele ) => { ele[prop] = value } ); } for ( const key in prop ) { this.prop ( key, prop[key] ); } return this; }; ================================================ FILE: src/attributes/remove_attr.ts ================================================ // @require core/cash.ts // @require core/get_split_values.ts // @require collection/each.ts interface Cash { removeAttr ( attrs: string ): this; } fn.removeAttr = function ( this: Cash, attr: string ) { const attrs = getSplitValues ( attr ); return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; each ( attrs, ( i, a ) => { ele.removeAttribute ( a ); }); }); }; ================================================ FILE: src/attributes/remove_class.ts ================================================ // @require core/cash.ts // @require ./attr.ts // @require ./toggle_class.ts interface Cash { removeClass ( classes?: string ): this; } fn.removeClass = function ( this: Cash, cls?: string ) { if ( arguments.length ) return this.toggleClass ( cls, false ); return this.attr ( 'class', '' ); }; ================================================ FILE: src/attributes/remove_prop.ts ================================================ // @require core/cash.ts // @require collection/each.ts // @require ./helpers/variables.ts interface Cash { removeProp ( prop: string ): this; } fn.removeProp = function ( this: Cash, prop: string ) { return this.each ( ( i, ele ) => { delete ele[propMap[prop] || prop] } ); }; ================================================ FILE: src/attributes/toggle_class.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require core/get_split_values.ts // @require core/type_checking.ts // @require collection/each.ts interface Cash { toggleClass ( classes: string, force?: boolean ): this; } fn.toggleClass = function ( this: Cash, cls: string, force?: boolean ) { const classes = getSplitValues ( cls ); const isForce = !isUndefined ( force ); return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; each ( classes, ( i, c ) => { if ( isForce ) { force ? ele.classList.add ( c ) : ele.classList.remove ( c ); } else { ele.classList.toggle ( c ); } }); }); }; ================================================ FILE: src/collection/add.ts ================================================ // @require core/cash.ts // @require core/unique.ts // @require ./get.ts interface Cash { add ( selector: Selector, context?: Context ): Cash; } fn.add = function ( this: Cash, selector: Selector, context?: Context ) { return cash ( unique ( this.get ().concat ( cash ( selector, context ).get () ) ) ); }; ================================================ FILE: src/collection/each.ts ================================================ // @require core/cash.ts // @require core/each.ts interface Cash { each ( callback: EachArrayCallback ): this; } fn.each = function ( this: Cash, callback: EachArrayCallback ) { return each ( this, callback ); }; ================================================ FILE: src/collection/eq.ts ================================================ // @require core/cash.ts // @require ./get.ts interface Cash { eq ( index: number ): Cash; } fn.eq = function ( this: Cash, index: number ) { return cash ( this.get ( index ) ); }; ================================================ FILE: src/collection/filter.ts ================================================ // @require core/cash.ts // @require core/get_compare_function.ts // @require core/type_checking.ts // @require core/variables.ts // @require collection/get.ts interface Cash { filter ( comparator?: Comparator ): Cash; } fn.filter = function ( this: Cash, comparator?: Comparator ) { const compare = getCompareFunction ( comparator ); return cash ( filter.call ( this, ( ele: EleLoose, i: number ) => compare.call ( ele, i, ele ) ) ); }; ================================================ FILE: src/collection/first.ts ================================================ // @require core/cash.ts // @require ./eq.ts interface Cash { first (): Cash; } fn.first = function ( this: Cash ) { return this.eq ( 0 ); }; ================================================ FILE: src/collection/get.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require core/variables.ts interface Cash { get (): EleLoose[]; get ( index: number ): EleLoose | undefined; } fn.get = function ( this: Cash, index?: number ) { if ( isUndefined ( index ) ) return slice.call ( this ); index = Number ( index ); return this[index < 0 ? index + this.length : index]; }; ================================================ FILE: src/collection/index.ts ================================================ // @require core/cash.ts // @require core/variables.ts // @require traversal/children.ts // @require traversal/parent.ts // @require ./get.ts interface Cash { index ( selector?: Selector ): number; } fn.index = function ( this: Cash, selector?: Selector ) { const child = selector ? cash ( selector )[0] : this[0]; const collection = selector ? this : cash ( child ).parent ().children (); return indexOf.call ( collection, child ); }; ================================================ FILE: src/collection/last.ts ================================================ // @require core/cash.ts // @require ./eq.ts interface Cash { last (): Cash; } fn.last = function ( this: Cash ) { return this.eq ( -1 ); }; ================================================ FILE: src/collection/map.ts ================================================ // @require core/cash.ts // @require core/variables.ts type MapCallback = ( this: T, index: number, ele: T ) => Ele; interface Cash { map ( callback: MapCallback ): Cash; } fn.map = function ( this: Cash, callback: MapCallback ) { return cash ( concat.apply ( [], map.call ( this, ( ele: EleLoose, i: number ) => callback.call ( ele, i, ele ) ) ) ); }; ================================================ FILE: src/collection/slice.ts ================================================ // @require core/cash.ts // @require core/variables.ts interface Cash { slice ( start?: number, end?: number ): Cash; } fn.slice = function ( this: Cash, start?: number, end?: number ) { return cash ( slice.call ( this, start, end ) ); }; ================================================ FILE: src/core/attempt.ts ================================================ function attempt ( fn: (( arg?: U ) => T), arg?: U ): T | U { try { return fn ( arg ); } catch { return arg; } } ================================================ FILE: src/core/camel_case.ts ================================================ // @require ./cash.ts const dashAlphaRe = /-([a-z])/g; function camelCase ( str: string ): string { return str.replace ( dashAlphaRe, ( match: string, letter: string ) => letter.toUpperCase () ); } ================================================ FILE: src/core/cash.ts ================================================ // @require ./find.ts // @require ./variables.ts class Cash { constructor ( selector?: Selector, context?: Context | Cash ) { if ( !selector ) return; if ( isCash ( selector ) ) return selector; let eles: any = selector; if ( isString ( selector ) ) { const ctx = context || doc; eles = idRe.test ( selector ) && isDocument ( ctx ) ? ctx.getElementById ( selector.slice ( 1 ).replace ( /\\/g, '' ) ) : htmlRe.test ( selector ) ? parseHTML ( selector ) : isCash ( ctx ) ? ctx.find ( selector ) : isString ( ctx ) ? cash ( ctx ).find ( selector ) : find ( selector, ctx ); if ( !eles ) return; } else if ( isFunction ( selector ) ) { return this.ready ( selector ); //FIXME: `fn.ready` is not included in `core`, but it's actually a core functionality } if ( eles.nodeType || eles === win ) eles = [eles]; this.length = eles.length; for ( let i = 0, l = this.length; i < l; i++ ) { this[i] = eles[i]; } } init ( selector?: Selector, context?: Context | Cash ) { return new Cash ( selector, context ); } } const fn = Cash.prototype; const cash = fn.init as ( typeof Cash.prototype.init & CashStatic ); cash.fn = cash.prototype = fn; // Ensuring that `cash () instanceof cash` fn.length = 0; fn.splice = splice; // Ensuring a cash collection gets printed as array-like in Chrome's devtools if ( typeof Symbol === 'function' ) { // Ensuring a cash collection is iterable fn[Symbol['iterator']] = ArrayPrototype[Symbol['iterator']]; } ================================================ FILE: src/core/each.ts ================================================ // @require ./cash.ts // @require ./type_checking.ts type EachArrayCallback = ( this: T, index: number, ele: T ) => any; type EachObjectCallback = ( this: T, key: string, value: T ) => any; interface CashStatic { each ( arr: ArrayLike, callback: EachArrayCallback ): void; each ( obj: PlainObject, callback: EachObjectCallback ): void; } function each = ArrayLike> ( arr: U, callback: EachArrayCallback, _reverse?: boolean ): U; function each = PlainObject> ( obj: U, callback: EachObjectCallback ): U; function each | PlainObject = ArrayLike> ( arr: U, callback: EachArrayCallback | EachObjectCallback, _reverse?: boolean ): U { if ( _reverse ) { let i = arr.length; while ( i-- ) { if ( callback.call ( arr[i], i, arr[i] ) === false ) return arr; } } else if ( isPlainObject ( arr ) ) { const keys = Object.keys ( arr ); for ( let i = 0, l = keys.length; i < l; i++ ) { const key = keys[i]; if ( callback.call ( arr[key], key, arr[key] ) === false ) return arr; } } else { for ( let i = 0, l = arr.length; i < l; i++ ) { if ( callback.call ( arr[i], i, arr[i] ) === false ) return arr; } } return arr; } cash.each = each; ================================================ FILE: src/core/extend.ts ================================================ // @require ./cash.ts // @require ./type_checking.ts interface CashStatic { extend (): any; extend ( deep: true, target: any, ...sources: any[] ): any; extend ( target: any ): typeof cash; extend ( target: any, ...sources: any[] ): any; } interface Cash { extend ( plugins: Record ): this; } function extend ( ...sources: any[] ) { const deep = isBoolean ( sources[0] ) ? sources.shift () : false; const target = sources.shift (); const length = sources.length; if ( !target ) return {}; if ( !length ) return extend ( deep, cash, target ); for ( let i = 0; i < length; i++ ) { const source = sources[i]; for ( const key in source ) { if ( deep && ( isArray ( source[key] ) || isPlainObject ( source[key] ) ) ) { if ( !target[key] || target[key].constructor !== source[key].constructor ) target[key] = new source[key].constructor (); extend ( deep, target[key], source[key] ); } else { target[key] = source[key]; } } } return target; } cash.extend = extend; fn.extend = function ( plugins: Record ) { return extend ( fn, plugins ); }; ================================================ FILE: src/core/filtered.ts ================================================ // @require collection/filter.ts function filtered ( collection: Cash, comparator?: Comparator ): Cash { return !comparator ? collection : collection.filter ( comparator ); } ================================================ FILE: src/core/find.ts ================================================ // @require ./variables.ts function find ( selector: string, context: Ele ): ArrayLike { const isFragment = isDocumentFragment ( context ); return !selector || ( !isFragment && !isDocument ( context ) && !isElement ( context ) ) ? [] : !isFragment && classRe.test ( selector ) ? context.getElementsByClassName ( selector.slice ( 1 ).replace ( /\\/g, '' ) ) : !isFragment && tagRe.test ( selector ) ? context.getElementsByTagName ( selector ) : context.querySelectorAll ( selector ); } ================================================ FILE: src/core/get_compare_function.ts ================================================ // @require ./matches.ts // @require ./type_checking.ts function getCompareFunction ( comparator?: Comparator ): (( i: number, ele: EleLoose ) => boolean) { return isString ( comparator ) ? ( i: number, ele: EleLoose ) => matches ( ele, comparator ) : isFunction ( comparator ) ? comparator : isCash ( comparator ) ? ( i: number, ele: EleLoose ) => comparator.is ( ele ) : !comparator ? () => false : ( i: number, ele: EleLoose ) => ele === comparator; } ================================================ FILE: src/core/get_split_values.ts ================================================ // @require ./type_checking.ts const splitValuesRe = /\S+/g; function getSplitValues ( str: string ) { return isString ( str ) ? str.match ( splitValuesRe ) || [] : []; } ================================================ FILE: src/core/guid.ts ================================================ // @require ./cash.ts interface CashStatic { guid: number; } cash.guid = 1; ================================================ FILE: src/core/matches.ts ================================================ // @require ./cash.ts function matches ( ele: any, selector: string ): boolean { const matches = ele && ( ele['matches'] || ele['webkitMatchesSelector'] || ele['msMatchesSelector'] ); return !!matches && !!selector && matches.call ( ele, selector ); } ================================================ FILE: src/core/parse_html.ts ================================================ // @require ./cash.ts // @require ./variables.ts // @require ./type_checking.ts // @require collection/get.ts // @require manipulation/detach.ts interface CashStatic { parseHTML ( html: string ): EleLoose[]; } const fragmentRe = /^\s*<(\w+)[^>]*>/; const singleTagRe = /^<(\w+)\s*\/?>(?:<\/\1>)?$/; const containers = { '*': div, tr: tbody, td: tr, th: tr, thead: table, tbody: table, tfoot: table }; //TODO: Create elements inside a document fragment, in order to prevent inline event handlers from firing //TODO: Ensure the created elements have the fragment as their parent instead of null, this also ensures we can deal with detatched nodes more reliably function parseHTML ( html: string ): EleLoose[] { if ( !isString ( html ) ) return []; if ( singleTagRe.test ( html ) ) return [createElement ( RegExp.$1 )]; const fragment = fragmentRe.test ( html ) && RegExp.$1; const container = containers[fragment] || containers['*']; container.innerHTML = html; return cash ( container.childNodes ).detach ().get (); } cash.parseHTML = parseHTML; ================================================ FILE: src/core/pluck.ts ================================================ // @require ./get_compare_function.ts // @require ./type_checking.ts // @require ./variables.ts type PluckCallback = ( ele: T ) => ArrayLike; function pluck = ArrayLike> ( arr: U, prop: string | PluckCallback, deep?: boolean, until?: Comparator ): Array { const plucked: Array = []; const isCallback = isFunction ( prop ); const compare = until && getCompareFunction ( until ); for ( let i = 0, l = arr.length; i < l; i++ ) { if ( isCallback ) { const val = prop ( arr[i] ); if ( val.length ) push.apply ( plucked, val ); } else { let val = arr[i][prop]; while ( val != null ) { if ( until && compare ( -1, val ) ) break; plucked.push ( val ); val = deep ? val[prop] : null; } } } return plucked; } ================================================ FILE: src/core/type_checking.ts ================================================ // @require ./cash.ts // @require ./variables.ts interface CashStatic { isWindow ( x: unknown ): x is Window; isFunction ( x: unknown ): x is Function; isArray ( x: unknown ): x is Array; isNumeric ( x: unknown ): boolean; isPlainObject ( x: unknown ): x is PlainObject; } function isCash ( value: unknown ): value is Cash { return value instanceof Cash; } function isWindow ( value: unknown ): value is Window { return !!value && value === value.window; } function isDocument ( value: unknown ): value is Document { return !!value && value.nodeType === 9; } function isDocumentFragment ( value: unknown ): value is DocumentFragment { return !!value && value.nodeType === 11; } function isElement ( value: unknown ): value is HTMLElement { return !!value && value.nodeType === 1; } function isText ( value: unknown ): value is Text { return !!value && value.nodeType === 3; } function isBoolean ( value: unknown ): value is boolean { return typeof value === 'boolean'; } function isFunction ( value: unknown ): value is Function { return typeof value === 'function'; } function isString ( value: unknown ): value is string { return typeof value === 'string'; } function isUndefined ( value: unknown ): value is undefined { return value === undefined; } function isNull ( value: unknown ): value is null { return value === null; } function isNumeric ( value: unknown ): boolean { return !isNaN ( parseFloat ( value ) ) && isFinite ( value ); } function isPlainObject ( value: unknown ): value is PlainObject { if ( typeof value !== 'object' || value === null ) return false; const proto = Object.getPrototypeOf ( value ); return proto === null || proto === Object.prototype; } cash.isWindow = isWindow; cash.isFunction = isFunction; cash.isArray = isArray; cash.isNumeric = isNumeric; cash.isPlainObject = isPlainObject; ================================================ FILE: src/core/types.ts ================================================ interface Event { namespace: string, data: any, relatedTarget?: Node | null, ___ifocus?: boolean, // Ignore focus ___iblur?: boolean, // Ignore blur ___ot?: string, // Original type ___td?: boolean // Trigger data } interface Cash { [Symbol.iterator](): IterableIterator, [index: number]: EleLoose | undefined, length: number, splice ( start: number, deleteCount?: number ): EleLoose[], splice ( start: number, deleteCount: number, ...items: Ele[] ): EleLoose[] } interface CashStatic { fn: Cash } type falsy = undefined | null | false | 0 | ''; type Ele = Window | Document | HTMLElement | Element | Node; type EleLoose = HTMLElement & Element & Node; //UGLY: Trick to remove some kind-of useless type errors //URL: https://github.com/fabiospampinato/cash/issues/278 type Selector = falsy | string | Function | HTMLCollection | NodeList | Ele | Ele[] | ArrayLike | Cash; type Comparator = string | Ele | Cash | (( this: EleLoose, index: number, ele: EleLoose ) => boolean); type Context = Document | HTMLElement | Element | string; type PlainObject = Record; //FIXME: Arrays can be assigned to this type, for whatever reason type EventCallback = { ( event: any, data?: any ): any, guid?: number }; ================================================ FILE: src/core/unique.ts ================================================ // @require ./cash.ts // @require ./variables.ts interface CashStatic { unique ( arr: ArrayLike ): ArrayLike; } function unique ( arr: ArrayLike ): ArrayLike { return arr.length > 1 ? filter.call ( arr, ( item: T, index: number, self: ArrayLike ) => indexOf.call ( self, item ) === index ) : arr; } cash.unique = unique; ================================================ FILE: src/core/variables.ts ================================================ const doc = document; const win = window; const docEle = doc.documentElement; const createElement = doc.createElement.bind ( doc ); const div = createElement ( 'div' ); const table = createElement ( 'table' ); const tbody = createElement ( 'tbody' ); const tr = createElement ( 'tr' ); const {isArray, prototype: ArrayPrototype} = Array; const {concat, filter, indexOf, map, push, slice, some, splice} = ArrayPrototype; const idRe = /^#(?:[\w-]|\\.|[^\x00-\xa0])*$/; const classRe = /^\.(?:[\w-]|\\.|[^\x00-\xa0])*$/; const htmlRe = /<.+>/; const tagRe = /^\w+$/; ================================================ FILE: src/css/css.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./helpers/compute_style.ts // @require ./helpers/get_prefixed_prop.ts // @require ./helpers/get_suffixed_value.ts // @require ./helpers/is_css_variable.ts interface Cash { css ( prop: string ): string | undefined; css ( prop: string, value: number | string ): this; css ( props: Record ): this; } function css ( this: Cash, prop: string ): string | undefined; function css ( this: Cash, prop: string, value: number | string ): Cash; function css ( this: Cash, prop: Record ): Cash; function css ( this: Cash, prop: string | Record, value?: number | string ) { if ( isString ( prop ) ) { const isVariable = isCSSVariable ( prop ); prop = getPrefixedProp ( prop, isVariable ); if ( arguments.length < 2 ) return this[0] && computeStyle ( this[0], prop, isVariable ); if ( !prop ) return this; value = getSuffixedValue ( prop, value, isVariable ); return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; if ( isVariable ) { ele.style.setProperty ( prop, value ); } else { ele.style[prop] = value; } }); } for ( const key in prop ) { this.css ( key, prop[key] ); } return this; }; fn.css = css; ================================================ FILE: src/css/helpers/compute_style.ts ================================================ // @require core/type_checking.ts // @require core/variables.ts function computeStyle ( ele: EleLoose, prop: string, isVariable?: boolean ): string | undefined { if ( !isElement ( ele ) ) return; const style = win.getComputedStyle ( ele, null ); return isVariable ? style.getPropertyValue ( prop ) || undefined : style[prop] || ele.style[prop]; } ================================================ FILE: src/css/helpers/compute_style_int.ts ================================================ // @require ./compute_style.ts function computeStyleInt ( ele: EleLoose, prop: string ): number { return parseInt ( computeStyle ( ele, prop ), 10 ) || 0; } ================================================ FILE: src/css/helpers/get_prefixed_prop.ts ================================================ // @require core/camel_case.ts // @require core/cash.ts // @require core/each.ts // @require core/variables.ts // @require ./is_css_variable.ts const prefixedProps: { [prop: string]: string } = {}; const {style} = div; const vendorsPrefixes = ['webkit', 'moz', 'ms']; function getPrefixedProp ( prop: string, isVariable: boolean = isCSSVariable ( prop ) ): string { if ( isVariable ) return prop; if ( !prefixedProps[prop] ) { const propCC = camelCase ( prop ); const propUC = `${propCC[0].toUpperCase ()}${propCC.slice ( 1 )}`; const props = ( `${propCC} ${vendorsPrefixes.join ( `${propUC} ` )}${propUC}` ).split ( ' ' ); each ( props, ( i, p ) => { if ( p in style ) { prefixedProps[prop] = p; return false; } }); } return prefixedProps[prop]; } ================================================ FILE: src/css/helpers/get_suffixed_value.ts ================================================ // @require core/type_checking.ts // @require ./is_css_variable.ts const numericProps: { [prop: string]: true | undefined } = { animationIterationCount: true, columnCount: true, flexGrow: true, flexShrink: true, fontWeight: true, gridArea: true, gridColumn: true, gridColumnEnd: true, gridColumnStart: true, gridRow: true, gridRowEnd: true, gridRowStart: true, lineHeight: true, opacity: true, order: true, orphans: true, widows: true, zIndex: true }; function getSuffixedValue ( prop: string, value: number | string, isVariable: boolean = isCSSVariable ( prop ) ): string { return !isVariable && !numericProps[prop] && isNumeric ( value ) ? `${value}px` : value; } ================================================ FILE: src/css/helpers/is_css_variable.ts ================================================ // @require ./variables.ts function isCSSVariable ( prop: string ): boolean { return cssVariableRe.test ( prop ); } ================================================ FILE: src/css/helpers/variables.ts ================================================ const cssVariableRe = /^--/; ================================================ FILE: src/data/data.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./helpers/get_data.ts // @require ./helpers/set_data.ts interface Cash { data (): Record | undefined; data ( name: string ): any; data ( name: string, value: any ): this; data ( datas: Record ): this; } function data ( this: Cash ): Record | undefined; function data ( this: Cash, name: string ): any; function data ( this: Cash, name: string, value: any ): Cash; function data ( this: Cash, name: Record ): Cash; function data ( this: Cash, name?: string | Record, value?: any ) { if ( !name ) { if ( !this[0] ) return; const datas: { [data: string]: any } = {}; for ( const key in this[0].dataset ) { datas[key] = getData ( this[0], key ); } return datas; } if ( isString ( name ) ) { if ( arguments.length < 2 ) return this[0] && getData ( this[0], name ); if ( isUndefined ( value ) ) return this; return this.each ( ( i, ele ) => { setData ( ele, name, value ) } ); } for ( const key in name ) { this.data ( key, name[key] ); } return this; } fn.data = data; ================================================ FILE: src/data/helpers/get_data.ts ================================================ // @require core/attempt.ts // @require core/camel_case.ts const JSONStringRe = /^\s+|\s+$/; function getData ( ele: EleLoose, key: string ): any { const value = ele.dataset[key] || ele.dataset[camelCase ( key )]; if ( JSONStringRe.test ( value ) ) return value; return attempt ( JSON.parse, value ); } ================================================ FILE: src/data/helpers/set_data.ts ================================================ // @require core/attempt.ts // @require core/camel_case.ts function setData ( ele: EleLoose, key: string, value: any ): void { value = attempt ( JSON.stringify, value ); ele.dataset[camelCase ( key )] = value; } ================================================ FILE: src/dimensions/helpers/get_document_dimension.ts ================================================ function getDocumentDimension ( doc: Document, dimension: 'Width' | 'Height' ): number { const docEle = doc.documentElement; return Math.max ( doc.body[`scroll${dimension}`], docEle[`scroll${dimension}`], doc.body[`offset${dimension}`], docEle[`offset${dimension}`], docEle[`client${dimension}`] ); } ================================================ FILE: src/dimensions/helpers/get_extra_space.ts ================================================ // @require css/helpers/compute_style_int.ts function getExtraSpace ( ele: EleLoose, xAxis?: boolean ): number { return computeStyleInt ( ele, `border${ xAxis ? 'Left' : 'Top' }Width` ) + computeStyleInt ( ele, `padding${ xAxis ? 'Left' : 'Top' }` ) + computeStyleInt ( ele, `padding${ xAxis ? 'Right' : 'Bottom' }` ) + computeStyleInt ( ele, `border${ xAxis ? 'Right' : 'Bottom' }Width` ); } ================================================ FILE: src/dimensions/inner_outer.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require core/type_checking.ts // @require core/variables.ts // @require ./helpers/get_document_dimension.ts interface Cash { innerWidth (): number | undefined; innerHeight (): number | undefined; outerWidth ( includeMargins?: boolean ): number; outerHeight ( includeMargins?: boolean ): number; } each ( [true, false], ( i, outer?: boolean ) => { each ( ['Width', 'Height'], ( i, prop: 'Width' | 'Height' ) => { const name: 'outerWidth' | 'innerHeight' = `${outer ? 'outer' : 'inner'}${prop}`; fn[name] = function ( this: Cash, includeMargins?: boolean ) { if ( !this[0] ) return; if ( isWindow ( this[0] ) ) return outer ? this[0][`inner${prop}`] : this[0].document.documentElement[`client${prop}`]; if ( isDocument ( this[0] ) ) return getDocumentDimension ( this[0], prop ); return this[0][`${outer ? 'offset' : 'client'}${prop}`] + ( includeMargins && outer ? computeStyleInt ( this[0], `margin${ i ? 'Top' : 'Left' }` ) + computeStyleInt ( this[0], `margin${ i ? 'Bottom' : 'Right' }` ) : 0 ); }; }); }); ================================================ FILE: src/dimensions/normal.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require core/type_checking.ts // @require core/variables.ts // @require css/helpers/compute_style.ts // @require css/helpers/get_suffixed_value.ts // @require ./helpers/get_extra_space.ts // @require ./helpers/get_document_dimension.ts interface Cash { width (): number; width ( value: number | string ): this; height (): number; height ( value: number | string ): this; } each ( ['Width', 'Height'], ( index: number, prop: 'Width' | 'Height' ) => { const propLC = prop.toLowerCase (); fn[propLC] = function ( this: Cash, value?: number | string ) { if ( !this[0] ) return isUndefined ( value ) ? undefined : this; if ( !arguments.length ) { if ( isWindow ( this[0] ) ) return this[0].document.documentElement[`client${prop}`]; if ( isDocument ( this[0] ) ) return getDocumentDimension ( this[0], prop ); return this[0].getBoundingClientRect ()[propLC] - getExtraSpace ( this[0], !index ); } const valueNumber = parseInt ( value, 10 ); return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; const boxSizing = computeStyle ( ele, 'boxSizing' ); ele.style[propLC] = getSuffixedValue ( propLC, valueNumber + ( boxSizing === 'border-box' ? getExtraSpace ( ele, !index ) : 0 ) ); }); }; }); ================================================ FILE: src/effects/helpers/get_default_display.ts ================================================ // @require css/helpers/compute_style.ts const defaultDisplay: { [tagName: string]: string } = {}; function getDefaultDisplay ( tagName: string ): string { if ( defaultDisplay[tagName] ) return defaultDisplay[tagName]; const ele = createElement ( tagName ); doc.body.insertBefore ( ele, null ); const display = computeStyle ( ele, 'display' ); doc.body.removeChild ( ele ); return defaultDisplay[tagName] = display !== 'none' ? display : 'block'; } ================================================ FILE: src/effects/helpers/is_hidden.ts ================================================ // @require css/helpers/compute_style.ts function isHidden ( ele: EleLoose ): boolean { return computeStyle ( ele, 'display' ) === 'none'; } ================================================ FILE: src/effects/helpers/variables.ts ================================================ const displayProperty = '___cd'; ================================================ FILE: src/effects/hide.ts ================================================ // @require core/cash.ts // @require ./toggle.ts interface Cash { hide (): this; } fn.hide = function ( this: Cash ) { return this.toggle ( false ); }; ================================================ FILE: src/effects/show.ts ================================================ // @require core/cash.ts // @require ./toggle.ts interface Cash { show (): this; } fn.show = function ( this: Cash ) { return this.toggle ( true ); }; ================================================ FILE: src/effects/toggle.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require css/helpers/compute_style.ts // @require ./helpers/get_default_display.ts // @require ./helpers/is_hidden.ts // @require ./helpers/variables.ts interface Cash { toggle ( force?: boolean ): this; } fn.toggle = function ( this: Cash, force?: boolean ) { return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; const hidden = isHidden ( ele ); const show = isUndefined ( force ) ? hidden : force; if ( show ) { ele.style.display = ele[displayProperty] || ''; if ( isHidden ( ele ) ) { ele.style.display = getDefaultDisplay ( ele.tagName ); } } else if ( !hidden ) { ele[displayProperty] = computeStyle ( ele, 'display' ); ele.style.display = 'none'; } }); }; ================================================ FILE: src/events/helpers/add_event.ts ================================================ // @require core/guid.ts // @require events/helpers/get_events_cache.ts function addEvent ( ele: EleLoose, name: string, namespaces: string[], selector: string, callback: EventCallback ): void { const eventCache = getEventsCache ( ele ); eventCache[name] = ( eventCache[name] || [] ); eventCache[name].push ([ namespaces, selector, callback ]); ele.addEventListener ( name, callback ); } ================================================ FILE: src/events/helpers/get_event_name_bubbling.ts ================================================ // @require ./variables.ts function getEventNameBubbling ( name: string ): string { return eventsHover[name] || eventsFocus[name] || name; } ================================================ FILE: src/events/helpers/get_events_cache.ts ================================================ // @require ./variables.ts function getEventsCache ( ele: EleLoose ): { [event: string]: [string[], string, EventCallback][] } { return ele[eventsNamespace] = ( ele[eventsNamespace] || {} ); } ================================================ FILE: src/events/helpers/has_namespaces.ts ================================================ function hasNamespaces ( ns1: string[], ns2?: string[] ): boolean { return !ns2 || !some.call ( ns2, ( ns: string ) => ns1.indexOf ( ns ) < 0 ); } ================================================ FILE: src/events/helpers/parse_event_name.ts ================================================ // @require ./variables.ts function parseEventName ( eventName: string ): [string, string[]] { const parts = eventName.split ( eventsNamespacesSeparator ); return [parts[0], parts.slice ( 1 ).sort ()]; // [name, namespace[]] } ================================================ FILE: src/events/helpers/remove_event.ts ================================================ // @require ./get_events_cache.ts // @require ./has_namespaces.ts // @require ./parse_event_name.ts function removeEvent ( ele: EleLoose, name?: string, namespaces?: string[], selector?: string, callback?: EventCallback ): void { const cache = getEventsCache ( ele ); if ( !name ) { for ( name in cache ) { removeEvent ( ele, name, namespaces, selector, callback ); } } else if ( cache[name] ) { cache[name] = cache[name].filter ( ([ ns, sel, cb ]) => { if ( ( callback && cb.guid !== callback.guid ) || !hasNamespaces ( ns, namespaces ) || ( selector && selector !== sel ) ) return true; ele.removeEventListener ( name, cb ); }); } } ================================================ FILE: src/events/helpers/variables.ts ================================================ const eventsNamespace = '___ce'; const eventsNamespacesSeparator = '.'; const eventsFocus: { [event: string]: string | undefined } = { focus: 'focusin', blur: 'focusout' }; const eventsHover: { [event: string]: string | undefined } = { mouseenter: 'mouseover', mouseleave: 'mouseout' }; const eventsMouseRe = /^(mouse|pointer|contextmenu|drag|drop|click|dblclick)/i; ================================================ FILE: src/events/off.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./helpers/get_event_name_bubbling.ts // @require ./helpers/parse_event_name.ts // @require ./helpers/remove_event.ts interface Cash { off (): this; off ( events: string ): this; off ( events: Record ): this; off ( events: string, callback: EventCallback ): this; off ( events: string, selector: string, callback: EventCallback ): this; } fn.off = function ( this: Cash, eventFullName?: string | Record, selector?: string | EventCallback, callback?: EventCallback ) { if ( isUndefined ( eventFullName ) ) { this.each ( ( i, ele ) => { if ( !isElement ( ele ) && !isDocument ( ele ) && !isWindow ( ele ) ) return; removeEvent ( ele ); }); } else if ( !isString ( eventFullName ) ) { for ( const key in eventFullName ) { this.off ( key, eventFullName[key] ); } } else { if ( isFunction ( selector ) ) { callback = selector; selector = ''; } each ( getSplitValues ( eventFullName ), ( i, eventFullName ) => { const [nameOriginal, namespaces] = parseEventName ( eventFullName ); const name = getEventNameBubbling ( nameOriginal ); this.each ( ( i, ele ) => { if ( !isElement ( ele ) && !isDocument ( ele ) && !isWindow ( ele ) ) return; removeEvent ( ele, name, namespaces, selector, callback ); }); }); } return this; }; ================================================ FILE: src/events/on.ts ================================================ // @require core/cash.ts // @require core/get_split_values.ts // @require core/guid.ts // @require core/matches.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./helpers/variables.ts // @require ./helpers/add_event.ts // @require ./helpers/get_event_name_bubbling.ts // @require ./helpers/has_namespaces.ts // @require ./helpers/parse_event_name.ts // @require ./helpers/remove_event.ts interface Cash { on ( events: Record ): this; on ( events: Record, selector: string ): this; on ( events: Record, data: any ): this; on ( events: Record, selector: string | null | undefined, data: any ): this; on ( events: string, callback: EventCallback ): this; on ( events: string, selector: string, callback: EventCallback ): this; on ( events: string, data: any, callback: EventCallback ): this; on ( events: string, selector: string | null | undefined, data: any, callback: EventCallback, _one?: boolean ): this; } function on ( this: Cash, eventFullName: Record ): Cash; function on ( this: Cash, eventFullName: Record, selector: string ): Cash; function on ( this: Cash, eventFullName: Record, data: any ): Cash; function on ( this: Cash, eventFullName: Record, selector: string | null | undefined, data: any ): Cash; function on ( this: Cash, eventFullName: string, callback: EventCallback ): Cash; function on ( this: Cash, eventFullName: string, selector: string, callback: EventCallback ): Cash; function on ( this: Cash, eventFullName: string, data: any, callback: EventCallback ): Cash; function on ( this: Cash, eventFullName: string, selector: string | null | undefined, data: any, callback: EventCallback, _one?: boolean ): Cash; function on ( this: Cash, eventFullName: Record | string, selector?: any, data?: any, callback?: EventCallback, _one?: boolean ) { if ( !isString ( eventFullName ) ) { for ( const key in eventFullName ) { this.on ( key, selector, data, eventFullName[key], _one ); } return this; } if ( !isString ( selector ) ) { if ( isUndefined ( selector ) || isNull ( selector ) ) { selector = ''; } else if ( isUndefined ( data ) ) { data = selector; selector = ''; } else { callback = data; data = selector; selector = ''; } } if ( !isFunction ( callback ) ) { callback = data; data = undefined; } if ( !callback ) return this; each ( getSplitValues ( eventFullName ), ( i, eventFullName ) => { const [nameOriginal, namespaces] = parseEventName ( eventFullName ); const name = getEventNameBubbling ( nameOriginal ); const isEventHover = ( nameOriginal in eventsHover ); const isEventFocus = ( nameOriginal in eventsFocus ); if ( !name ) return; this.each ( ( i, ele ) => { if ( !isElement ( ele ) && !isDocument ( ele ) && !isWindow ( ele ) ) return; const finalCallback = function ( event: Event ) { if ( event.target[`___i${event.type}`] ) return event.stopImmediatePropagation (); // Ignoring native event in favor of the upcoming custom one if ( event.namespace && !hasNamespaces ( namespaces, event.namespace.split ( eventsNamespacesSeparator ) ) ) return; if ( !selector && ( ( isEventFocus && ( event.target !== ele || event.___ot === name ) ) || ( isEventHover && event.relatedTarget && ele.contains ( event.relatedTarget ) ) ) ) return; let thisArg: EventTarget = ele; if ( selector ) { let target = event.target; while ( !matches ( target, selector ) ) { if ( target === ele ) return; target = target.parentNode; if ( !target ) return; } thisArg = target; } Object.defineProperty ( event, 'currentTarget', { configurable: true, get () { // We need to define a getter for this to work everywhere return thisArg; } }); Object.defineProperty ( event, 'delegateTarget', { configurable: true, get () { // We need to define a getter for this to work everywhere return ele; } }); Object.defineProperty ( event, 'data', { configurable: true, get () { return data; } }); const returnValue = callback.call ( thisArg, event, event.___td ); if ( _one ) { removeEvent ( ele, name, namespaces, selector, finalCallback ); } if ( returnValue === false ) { event.preventDefault (); event.stopPropagation (); } }; finalCallback.guid = callback.guid = ( callback.guid || cash.guid++ ); addEvent ( ele, name, namespaces, selector, finalCallback ); }); }); return this; } fn.on = on; ================================================ FILE: src/events/one.ts ================================================ // @require core/cash.ts // @require ./on.ts interface Cash { one ( events: Record ): this; one ( events: Record, selector: string ): this; one ( events: Record, data: any ): this; one ( events: Record, selector: string | null | undefined, data: any ): this; one ( events: string, callback: EventCallback ): this; one ( events: string, selector: string, callback: EventCallback ): this; one ( events: string, data: any, callback: EventCallback ): this; one ( events: string, selector: string | null | undefined, data: any, callback: EventCallback ): this; } function one ( this: Cash, eventFullName: Record ): Cash; function one ( this: Cash, eventFullName: Record, selector: string ): Cash; function one ( this: Cash, eventFullName: Record, data: any ): Cash; function one ( this: Cash, eventFullName: Record, selector: string | null | undefined, data: any ): Cash; function one ( this: Cash, eventFullName: string, callback: EventCallback ): Cash; function one ( this: Cash, eventFullName: string, selector: string, callback: EventCallback ): Cash; function one ( this: Cash, eventFullName: string, data: any, callback: EventCallback ): Cash; function one ( this: Cash, eventFullName: string, selector: string | null | undefined, data: any, callback: EventCallback ): Cash; function one ( this: Cash, eventFullName: Record | string, selector?: any, data?: any, callback?: EventCallback ) { return this.on ( eventFullName, selector, data, callback, true ); }; fn.one = one; ================================================ FILE: src/events/ready.ts ================================================ // @require core/cash.ts // @require core/variables.ts interface Cash { ready ( callback: Function ): this; } fn.ready = function ( this: Cash, callback: ( $: typeof cash ) => any ) { const cb = () => setTimeout ( callback, 0, cash ); if ( doc.readyState !== 'loading' ) { cb (); } else { doc.addEventListener ( 'DOMContentLoaded', cb ); } return this; }; ================================================ FILE: src/events/trigger.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require core/variables.ts // @require collection/each.ts // @require ./helpers/get_event_name_bubbling.ts // @require ./helpers/parse_event_name.ts // @require ./helpers/variables.ts interface Cash { trigger ( event: Event | string, data?: any ): this; } fn.trigger = function ( this: Cash, event: Event | string, data?: any ) { if ( isString ( event ) ) { const [nameOriginal, namespaces] = parseEventName ( event ); const name = getEventNameBubbling ( nameOriginal ); if ( !name ) return this; const type = eventsMouseRe.test ( name ) ? 'MouseEvents' : 'HTMLEvents'; event = doc.createEvent ( type ); event.initEvent ( name, true, true ); event.namespace = namespaces.join ( eventsNamespacesSeparator ); event.___ot = nameOriginal; } event.___td = data; const isEventFocus = ( event.___ot in eventsFocus ); return this.each ( ( i, ele ) => { if ( isEventFocus && isFunction ( ele[event.___ot] ) ) { ele[`___i${event.type}`] = true; // Ensuring the native event is ignored ele[event.___ot](); ele[`___i${event.type}`] = false; // Ensuring the custom event is not ignored } ele.dispatchEvent ( event ); }); }; ================================================ FILE: src/export_cjs.ts ================================================ // @require methods.ts if ( typeof exports !== 'undefined' ) { // Node.js module.exports = cash; } else { // Browser win['cash'] = win['$'] = cash; } ================================================ FILE: src/export_esm.ts ================================================ // @require methods.ts export default cash; export {Cash, CashStatic, Ele as Element, Selector, Comparator, Context}; ================================================ FILE: src/extra/get_script.ts ================================================ // @require core/cash.ts // @require core/variables.ts interface CashStatic { getScript ( url: string, success?: Function ): void; } cash.getScript = function ( url: string, success?: Function ): void { const script = createElement ( 'script' ); const $anchor = cash ( 'script' ); script.async = true; script.src = url; if ( success ) script.onload = () => { success () }; $anchor.before ( script ); }; ================================================ FILE: src/extra/shorthands.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require events/on.ts // @require events/trigger.ts type shorthandEventName = 'blur' | 'focus' | 'focusin' | 'focusout' | 'resize' | 'scroll' | 'click' | 'dblclick' | 'mousedown' | 'mouseup' | 'mousemove' | 'mouseover' | 'mouseout' | 'mouseenter' | 'mouseleave' | 'change' | 'select' | 'submit' | 'keydown' | 'keypress' | 'keyup' | 'contextmenu'; interface Cash { blur ( handler?: Function ): Cash; focus ( handler?: Function ): Cash; focusin ( handler?: Function ): Cash; focusout ( handler?: Function ): Cash; resize ( handler?: Function ): Cash; scroll ( handler?: Function ): Cash; click ( handler?: Function ): Cash; dblclick ( handler?: Function ): Cash; mousedown ( handler?: Function ): Cash; mouseup ( handler?: Function ): Cash; mousemove ( handler?: Function ): Cash; mouseover ( handler?: Function ): Cash; mouseout ( handler?: Function ): Cash; mouseenter ( handler?: Function ): Cash; mouseleave ( handler?: Function ): Cash; change ( handler?: Function ): Cash; select ( handler?: Function ): Cash; submit ( handler?: Function ): Cash; keydown ( handler?: Function ): Cash; keypress ( handler?: Function ): Cash; keyup ( handler?: Function ): Cash; contextmenu ( handler?: Function ): Cash; } cash.each ( 'blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu'.split ( ' ' ), ( i, event: shorthandEventName ) => { cash.fn[event] = function ( this: Cash, callback?: EventCallback ) { if ( callback ) return this.on ( event, callback ); return this.trigger ( event ); }; }); ================================================ FILE: src/forms/helpers/get_value.ts ================================================ // @require core/pluck.ts // @require core/variables.ts function getValue ( ele: EleLoose ): string | string[] { if ( ele.multiple && ele.options ) return pluck ( filter.call ( ele.options, option => option.selected && !option.disabled && !option.parentNode.disabled ), 'value' ); return ele.value || ''; } ================================================ FILE: src/forms/helpers/query_encode.ts ================================================ const queryEncodeCRLFRe = /\r?\n/g; function queryEncode ( prop: string, value: string ): string { return `&${encodeURIComponent ( prop )}=${encodeURIComponent ( value.replace ( queryEncodeCRLFRe, '\r\n' ) )}`; } ================================================ FILE: src/forms/serialize.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require core/type_checking.ts // @require ./helpers/get_value.ts // @require ./helpers/query_encode.ts interface Cash { serialize (): string; } const skippableRe = /file|reset|submit|button|image/i; const checkableRe = /radio|checkbox/i; fn.serialize = function ( this: Cash ) { let query = ''; this.each ( ( i, ele ) => { each ( ele.elements || [ele], ( i, ele: EleLoose ) => { if ( ele.disabled || !ele.name || ele.tagName === 'FIELDSET' || skippableRe.test ( ele.type ) || ( checkableRe.test ( ele.type ) && !ele.checked ) ) return; const value = getValue ( ele ); if ( !isUndefined ( value ) ) { const values = isArray ( value ) ? value : [value]; each ( values, ( i, value ) => { query += queryEncode ( ele.name, value ); }); } }); }); return query.slice ( 1 ); }; ================================================ FILE: src/forms/val.ts ================================================ // @require core/cash.ts // @require core/each.ts // @require core/type_checking.ts // @require collection/each.ts // @require ./helpers/get_value.ts interface Cash { val (): string | string[]; val ( value: string | string[] ): this; } function val ( this: Cash ): string | string[]; function val ( this: Cash, value: string | string[] ): Cash; function val ( this: Cash, value?: string | string[] ) { if ( !arguments.length ) return this[0] && getValue ( this[0] ); return this.each ( ( i, ele ) => { const isSelect = ele.multiple && ele.options; if ( isSelect || checkableRe.test ( ele.type ) ) { const eleValue = isArray ( value ) ? map.call ( value, String ) : ( isNull ( value ) ? [] : [String ( value )] ); if ( isSelect ) { each ( ele.options, ( i, option ) => { option.selected = eleValue.indexOf ( option.value ) >= 0; }, true ); } else { ele.checked = eleValue.indexOf ( ele.value ) >= 0; } } else { ele.value = isUndefined ( value ) || isNull ( value ) ? '' : value; } }); } fn.val = val; ================================================ FILE: src/manipulation/after.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { after ( ...selectors: Selector[] ): this; } fn.after = function ( this: Cash ) { return insertSelectors ( arguments, this, false, false, false, true, true ); }; ================================================ FILE: src/manipulation/append.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { append ( ...selectors: Selector[] ): this; } fn.append = function ( this: Cash ) { return insertSelectors ( arguments, this, false, false, true ); }; ================================================ FILE: src/manipulation/append_to.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { appendTo ( selector: Selector ): this; } fn.appendTo = function ( this: Cash, selector: Selector ) { return insertSelectors ( arguments, this, true, false, true ); }; ================================================ FILE: src/manipulation/before.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { before ( ...selectors: Selector[] ): this; } fn.before = function ( this: Cash ) { return insertSelectors ( arguments, this, false, true ); }; ================================================ FILE: src/manipulation/clone.ts ================================================ // @require core/cash.ts // @require collection/map.ts interface Cash { clone (): this; } fn.clone = function ( this: Cash ) { return this.map ( ( i, ele ) => ele.cloneNode ( true ) ); }; ================================================ FILE: src/manipulation/detach.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require collection/each.ts interface Cash { detach ( comparator?: Comparator ): this; } fn.detach = function ( this: Cash, comparator?: Comparator ) { filtered ( this, comparator ).each ( ( i, ele ) => { if ( ele.parentNode ) { ele.parentNode.removeChild ( ele ); } }); return this; }; ================================================ FILE: src/manipulation/empty.ts ================================================ // @require core/cash.ts // @require collection/each.ts interface Cash { empty (): this; } fn.empty = function ( this: Cash ) { return this.each ( ( i, ele ) => { while ( ele.firstChild ) { ele.removeChild ( ele.firstChild ); } }); }; ================================================ FILE: src/manipulation/helpers/eval_scripts.ts ================================================ // @require core/variables.ts // @require collection/filter.ts // @require traversal/find.ts const HTMLCDATARe = /^\s*\s*$/g; const scriptTypeRe = /^$|^module$|\/(java|ecma)script/i; const scriptAttributes: ('type' | 'src' | 'nonce' | 'noModule')[] = ['type', 'src', 'nonce', 'noModule']; function evalScripts ( node: Node, doc: Document ): void { const collection = cash ( node ); collection.filter ( 'script' ).add ( collection.find ( 'script' ) ).each ( ( i, ele: HTMLScriptElement ) => { if ( scriptTypeRe.test ( ele.type ) && docEle.contains ( ele ) ) { // The script type is supported // The element is attached to the DOM // Using `documentElement` for broader browser support const script = createElement ( 'script' ); script.text = ele.textContent.replace ( HTMLCDATARe, '' ); each ( scriptAttributes, ( i, attr ) => { if ( ele[attr] ) script[attr] = ele[attr]; }); doc.head.insertBefore ( script, null ); doc.head.removeChild ( script ); } }); } ================================================ FILE: src/manipulation/helpers/insert_element.ts ================================================ // @require ./eval_scripts.ts function insertElement ( anchor: EleLoose, target: EleLoose, left?: boolean, inside?: boolean, evaluate?: boolean ): void { if ( inside ) { // prepend/append anchor.insertBefore ( target, left ? anchor.firstChild : null ); } else { // before/after if ( anchor.nodeName === 'HTML' ) { anchor.parentNode.replaceChild ( target, anchor ); } else { anchor.parentNode.insertBefore ( target, left ? anchor : anchor.nextSibling ); } } if ( evaluate ) { evalScripts ( target, anchor.ownerDocument ); } } ================================================ FILE: src/manipulation/helpers/insert_selectors.ts ================================================ // @require ./insert_element.ts function insertSelectors = ArrayLike> ( selectors: ArrayLike, anchors: T, inverse?: boolean, left?: boolean, inside?: boolean, reverseLoop1?: boolean, reverseLoop2?: boolean, reverseLoop3?: boolean ): T { each ( selectors, ( si, selector: Selector ) => { each ( cash ( selector ), ( ti, target ) => { each ( cash ( anchors ), ( ai, anchor ) => { const anchorFinal = inverse ? target : anchor; const targetFinal = inverse ? anchor : target; const indexFinal = inverse ? ti : ai; insertElement ( anchorFinal, !indexFinal ? targetFinal : targetFinal.cloneNode ( true ), left, inside, !indexFinal ); }, reverseLoop3 ); }, reverseLoop2 ); }, reverseLoop1 ); return anchors; } ================================================ FILE: src/manipulation/html.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require collection/each.ts // @require manipulation/append.ts // @require manipulation/empty.ts interface Cash { html (): string; html ( html: string ): this; } function html ( this: Cash ): string; function html ( this: Cash, html: string ): Cash; function html ( this: Cash, html?: string ) { if ( !arguments.length ) return this[0] && this[0].innerHTML; if ( isUndefined ( html ) ) return this; const hasScript = /]/.test ( html ); return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; if ( hasScript ) { cash ( ele ).empty ().append ( html ); } else { ele.innerHTML = html; } }); } fn.html = html; ================================================ FILE: src/manipulation/insert_after.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { insertAfter ( selector: Selector ): this; } fn.insertAfter = function ( this: Cash, selector: Selector ) { return insertSelectors ( arguments, this, true, false, false, false, false, true ); }; ================================================ FILE: src/manipulation/insert_before.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { insertBefore ( selector: Selector ): this; } fn.insertBefore = function ( this: Cash, selector: Selector ) { return insertSelectors ( arguments, this, true, true ); }; ================================================ FILE: src/manipulation/prepend.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { prepend ( ...selectors: Selector[] ): this; } fn.prepend = function ( this: Cash ) { return insertSelectors ( arguments, this, false, true, true, true, true ); }; ================================================ FILE: src/manipulation/prepend_to.ts ================================================ // @require core/cash.ts // @require ./helpers/insert_selectors.ts interface Cash { prependTo ( selector: Selector ): this; } fn.prependTo = function ( this: Cash, selector: Selector ) { return insertSelectors ( arguments, this, true, true, true, false, false, true ); }; ================================================ FILE: src/manipulation/remove.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require events/off.ts // @require ./detach.ts interface Cash { remove ( comparator?: Comparator ): this; } fn.remove = function ( this: Cash, comparator?: Comparator ) { filtered ( this, comparator ).detach ().off (); return this; }; ================================================ FILE: src/manipulation/replace_all.ts ================================================ // @require core/cash.ts // @require ./replace_with.ts interface Cash { replaceAll ( selector: Selector ): this; } fn.replaceAll = function ( this: Cash, selector: Selector ) { cash ( selector ).replaceWith ( this ); return this; }; ================================================ FILE: src/manipulation/replace_with.ts ================================================ // @require core/cash.ts // @require ./before.ts // @require ./remove.ts interface Cash { replaceWith ( selector: Selector ): this; } fn.replaceWith = function ( this: Cash, selector: Selector ) { return this.before ( selector ).remove (); }; ================================================ FILE: src/manipulation/text.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require collection/each.ts // @require collection/get.ts interface Cash { text (): string; text ( text: string ): this; } function text ( this: Cash ): string; function text ( this: Cash, text: string ): Cash; function text ( this: Cash, text?: string ) { if ( isUndefined ( text ) ) { return this.get ().map ( ele => isElement ( ele ) || isText ( ele ) ? ele.textContent : '' ).join ( '' ); } return this.each ( ( i, ele ) => { if ( !isElement ( ele ) ) return; ele.textContent = text; }); } fn.text = text; ================================================ FILE: src/manipulation/unwrap.ts ================================================ // @require core/cash.ts interface Cash { unwrap (): this; } fn.unwrap = function ( this: Cash ) { this.parent ().each ( ( i, ele ) => { if ( ele.tagName === 'BODY' ) return; const $ele = cash ( ele ); $ele.replaceWith ( $ele.children () ); }); return this; }; ================================================ FILE: src/manipulation/wrap.ts ================================================ // @require core/cash.ts // @require collection/each.ts // @require ./wrap_all.ts interface Cash { wrap ( selector?: Selector ): this; } fn.wrap = function ( this: Cash, selector?: Selector ) { return this.each ( ( i, ele ) => { const wrapper = cash ( selector )[0]; cash ( ele ).wrapAll ( !i ? wrapper : wrapper.cloneNode ( true ) ); }); }; ================================================ FILE: src/manipulation/wrap_all.ts ================================================ // @require core/cash.ts // @require collection/first.ts // @require manipulation/append_to.ts // @require manipulation/before.ts interface Cash { wrapAll ( selector?: Selector ): this; } fn.wrapAll = function ( this: Cash, selector?: Selector ) { let structure = cash ( selector ); let wrapper: Element = structure[0]; while ( wrapper.children.length ) wrapper = wrapper.firstElementChild; this.first ().before ( structure ); return this.appendTo ( wrapper ); }; ================================================ FILE: src/manipulation/wrap_inner.ts ================================================ // @require core/cash.ts // @require collection/first.ts // @require manipulation/append_to.ts interface Cash { wrapInner ( selector?: Selector ): this; } fn.wrapInner = function ( this: Cash, selector?: Selector ) { return this.each ( ( i, ele ) => { const $ele = cash ( ele ); const contents = $ele.contents (); contents.length ? contents.wrapAll ( selector ) : $ele.append ( selector ); }); }; ================================================ FILE: src/methods.ts ================================================ // @require core/types.ts // @require core/cash.ts // @require core/type_checking.ts // @require core/variables.ts // @require core/each.ts // @require core/extend.ts // @require core/find.ts // @require core/get_compare_function.ts // @require core/get_split_values.ts // @require core/guid.ts // @require core/parse_html.ts // @require core/unique.ts // @require attributes/add_class.ts // @require attributes/attr.ts // @require attributes/has_class.ts // @require attributes/prop.ts // @require attributes/remove_attr.ts // @require attributes/remove_class.ts // @require attributes/remove_prop.ts // @require attributes/toggle_class.ts // @require collection/add.ts // @require collection/each.ts // @require collection/eq.ts // @require collection/filter.ts // @require collection/first.ts // @require collection/get.ts // @require collection/index.ts // @require collection/last.ts // @require collection/map.ts // @require collection/slice.ts // @require css/css.ts // @require data/data.ts // @require dimensions/inner_outer.ts // @require dimensions/normal.ts // @require effects/hide.ts // @require effects/show.ts // @require effects/toggle.ts // @require events/off.ts // @require events/on.ts // @require events/one.ts // @require events/ready.ts // @require events/trigger.ts // @require forms/serialize.ts // @require forms/val.ts // @require manipulation/after.ts // @require manipulation/append.ts // @require manipulation/append_to.ts // @require manipulation/before.ts // @require manipulation/clone.ts // @require manipulation/detach.ts // @require manipulation/empty.ts // @require manipulation/html.ts // @require manipulation/insert_after.ts // @require manipulation/insert_before.ts // @require manipulation/prepend.ts // @require manipulation/prepend_to.ts // @require manipulation/remove.ts // @require manipulation/replace_all.ts // @require manipulation/replace_with.ts // @require manipulation/text.ts // @require manipulation/unwrap.ts // @require manipulation/wrap.ts // @require manipulation/wrap_all.ts // @require manipulation/wrap_inner.ts // @require offset/offset.ts // @require offset/offset_parent.ts // @require offset/position.ts // @require traversal/children.ts // @require traversal/closest.ts // @require traversal/contents.ts // @require traversal/find.ts // @require traversal/has.ts // @require traversal/is.ts // @require traversal/next.ts // @require traversal/next_all.ts // @require traversal/next_until.ts // @require traversal/not.ts // @require traversal/parent.ts // @require traversal/parents.ts // @require traversal/parents_until.ts // @require traversal/prev.ts // @require traversal/prev_all.ts // @require traversal/prev_until.ts // @require traversal/siblings.ts // @no-require extras/get_script.ts // @no-require extras/shorthands.ts ================================================ FILE: src/offset/offset.ts ================================================ // @require core/cash.ts // @require core/variables.ts interface Cash { offset (): undefined | { top: number, left: number }; } fn.offset = function ( this: Cash ) { const ele = this[0]; if ( !ele ) return; const rect = ele.getBoundingClientRect (); return { top: rect.top + win.pageYOffset, left: rect.left + win.pageXOffset }; }; ================================================ FILE: src/offset/offset_parent.ts ================================================ // @require core/cash.ts // @require collection/map.ts // @require css/helpers/compute_style.ts interface Cash { offsetParent (): Cash; } fn.offsetParent = function ( this: Cash ) { return this.map ( ( i, ele ) => { let offsetParent = ele.offsetParent; while ( offsetParent && computeStyle ( offsetParent, 'position' ) === 'static' ) { offsetParent = offsetParent.offsetParent; } return offsetParent || docEle; }); }; ================================================ FILE: src/offset/position.ts ================================================ // @require core/cash.ts // @require core/type_checking.ts // @require css/helpers/compute_style.ts // @require css/helpers/compute_style_int.ts // @require ./offset.ts interface Cash { position (): undefined | { top: number, left: number }; } fn.position = function ( this: Cash ) { const ele = this[0]; if ( !ele ) return; const isFixed = ( computeStyle ( ele, 'position' ) === 'fixed' ); const offset = isFixed ? ele.getBoundingClientRect () : this.offset (); if ( !isFixed ) { const doc = ele.ownerDocument; let offsetParent = ele.offsetParent || doc.documentElement; while ( ( offsetParent === doc.body || offsetParent === doc.documentElement ) && computeStyle ( offsetParent, 'position' ) === 'static' ) { offsetParent = offsetParent.parentNode; } if ( offsetParent !== ele && isElement ( offsetParent ) ) { const parentOffset = cash ( offsetParent ).offset (); offset.top -= parentOffset.top + computeStyleInt ( offsetParent, 'borderTopWidth' ); offset.left -= parentOffset.left + computeStyleInt ( offsetParent, 'borderLeftWidth' ); } } return { top: offset.top - computeStyleInt ( ele, 'marginTop' ), left: offset.left - computeStyleInt ( ele, 'marginLeft' ) }; }; ================================================ FILE: src/traversal/children.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require core/pluck.ts // @require core/unique.ts // @require core/variables.ts // @require collection/each.ts interface Cash { children ( comparator?: Comparator ): Cash; } fn.children = function ( this: Cash, comparator?: Comparator ) { return filtered ( cash ( unique ( pluck ( this, ele => ele.children ) ) ), comparator ); }; ================================================ FILE: src/traversal/closest.ts ================================================ // @require core/cash.ts // @require collection/filter.ts // @require ./is.ts // @require ./parent.ts interface Cash { closest ( comparator?: Comparator ): Cash; } fn.closest = function ( this: Cash, comparator?: Comparator ) { const filtered = this.filter ( comparator ); if ( filtered.length ) return filtered; const $parent = this.parent (); if ( !$parent.length ) return filtered; return $parent.closest ( comparator ); }; ================================================ FILE: src/traversal/contents.ts ================================================ // @require core/cash.ts // @require core/pluck.ts // @require core/unique.ts // @require collection/each.ts interface Cash { contents (): Cash; } fn.contents = function ( this: Cash ) { return cash ( unique ( pluck ( this, ele => ele.tagName === 'IFRAME' ? [ele.contentDocument] : ( ele.tagName === 'TEMPLATE' ? ele.content.childNodes : ele.childNodes ) ) ) ); }; ================================================ FILE: src/traversal/find.ts ================================================ // @require core/cash.ts // @require core/pluck.ts // @require core/unique.ts // @require core/find.ts // @require core/variables.ts interface Cash { find ( selector: string ): Cash; } fn.find = function ( this: Cash, selector: string ) { return cash ( unique ( pluck ( this, ele => find ( selector, ele ) ) ) ); }; ================================================ FILE: src/traversal/has.ts ================================================ // @require core/cash.ts // @require core/find.ts // @require core/type_checking.ts // @require collection/filter.ts interface Cash { has ( selector: string | Node ): Cash; } fn.has = function ( this: Cash, selector: string | Node ) { const comparator = isString ( selector ) ? ( i: number, ele: EleLoose ) => find ( selector, ele ).length : ( i: number, ele: EleLoose ) => ele.contains ( selector ); return this.filter ( comparator ); }; ================================================ FILE: src/traversal/is.ts ================================================ // @require core/cash.ts // @require core/get_compare_function.ts // @require core/variables.ts // @require collection/each.ts interface Cash { is ( comparator?: Comparator ): boolean; } fn.is = function ( this: Cash, comparator?: Comparator ) { const compare = getCompareFunction ( comparator ); return some.call ( this, ( ele: EleLoose, i: number ) => compare.call ( ele, i, ele ) ); }; ================================================ FILE: src/traversal/next.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require core/pluck.ts // @require core/unique.ts interface Cash { next ( comparator?: Comparator, _all?: boolean, _until?: Comparator ): Cash; } fn.next = function ( this: Cash, comparator?: Comparator, _all?: boolean, _until?: Comparator ) { return filtered ( cash ( unique ( pluck ( this, 'nextElementSibling', _all, _until ) ) ), comparator ); }; ================================================ FILE: src/traversal/next_all.ts ================================================ // @require ./next.ts interface Cash { nextAll ( comparator?: Comparator): Cash; } fn.nextAll = function ( this: Cash, comparator?: Comparator ) { return this.next ( comparator, true ); }; ================================================ FILE: src/traversal/next_until.ts ================================================ // @require ./next.ts interface Cash { nextUntil ( until?: Comparator, comparator?: Comparator): Cash; } fn.nextUntil = function ( this: Cash, until?: Comparator, comparator?: Comparator ) { return this.next ( comparator, true, until ); }; ================================================ FILE: src/traversal/not.ts ================================================ // @require core/cash.ts // @require core/get_compare_function.ts // @require core/type_checking.ts // @require collection/filter.ts interface Cash { not ( comparator?: Comparator ): Cash; } fn.not = function ( this: Cash, comparator?: Comparator ) { const compare = getCompareFunction ( comparator ); return this.filter ( ( i: number, ele: EleLoose ) => ( !isString ( comparator ) || isElement ( ele ) ) && !compare.call ( ele, i, ele ) ); }; ================================================ FILE: src/traversal/parent.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require core/pluck.ts // @require core/unique.ts interface Cash { parent ( comparator?: Comparator ): Cash; } fn.parent = function ( this: Cash, comparator?: Comparator ) { return filtered ( cash ( unique ( pluck ( this, 'parentNode' ) ) ), comparator ); }; ================================================ FILE: src/traversal/parents.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require core/matches.ts // @require core/unique.ts // @require core/variables.ts // @require collection/each.ts interface Cash { parents ( comparator?: Comparator, _until?: Comparator ): Cash; } fn.parents = function ( this: Cash, comparator?: Comparator, _until?: Comparator ) { return filtered ( cash ( unique ( pluck ( this, 'parentElement', true, _until ) ) ), comparator ); }; ================================================ FILE: src/traversal/parents_until.ts ================================================ // @require ./parents.ts interface Cash { parentsUntil ( until?: Comparator, comparator?: Comparator): Cash; } fn.parentsUntil = function ( this: Cash, until?: Comparator, comparator?: Comparator ) { return this.parents ( comparator, until ); }; ================================================ FILE: src/traversal/prev.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require core/pluck.ts // @require core/unique.ts interface Cash { prev ( comparator?: Comparator, _all?: boolean, _until?: Comparator ): Cash; } fn.prev = function ( this: Cash, comparator?: Comparator, _all?: boolean, _until?: Comparator ) { return filtered ( cash ( unique ( pluck ( this, 'previousElementSibling', _all, _until ) ) ), comparator ); }; ================================================ FILE: src/traversal/prev_all.ts ================================================ // @require ./prev.ts interface Cash { prevAll ( comparator?: Comparator ): Cash; } fn.prevAll = function ( this: Cash, comparator?: Comparator ) { return this.prev ( comparator, true ); }; ================================================ FILE: src/traversal/prev_until.ts ================================================ // @require ./prev.ts interface Cash { prevUntil ( until?: Comparator, comparator?: Comparator ): Cash; } fn.prevUntil = function ( this: Cash, until?: Comparator, comparator?: Comparator ) { return this.prev ( comparator, true, until ); }; ================================================ FILE: src/traversal/siblings.ts ================================================ // @require core/cash.ts // @require core/filtered.ts // @require core/pluck.ts // @require core/unique.ts // @require core/variables.ts // @require collection/each.ts // @require ./children.ts // @require ./not.ts // @require ./parent.ts interface Cash { siblings ( comparator?: Comparator ): Cash; } fn.siblings = function ( this: Cash, comparator?: Comparator ) { return filtered ( cash ( unique ( pluck ( this, ele => cash ( ele ).parent ().children ().not ( ele ) ) ) ), comparator ); }; ================================================ FILE: tasks/build.sh ================================================ # CLEANUP rm -rf dist mkdir dist # ESM npx minipacco bundle src/export_esm.ts > dist/cash.esm.ts npx tsc --target es2016 --skipLibCheck --declaration dist/cash.esm.ts mv dist/cash.esm.ts dist/cash.ts mv dist/cash.esm.d.ts dist/cash.d.ts mv dist/cash.esm.js dist/cash.esm.js # CJS npx minipacco bundle src/export_cjs.ts > dist/cash.cjs.ts npx tsc --target es5 --skipLibCheck dist/cash.cjs.ts node -e 'fs.writeFileSync("dist/cash.cjs.js",`(function(){\n"use strict";\n${fs.readFileSync("dist/cash.cjs.js","utf8")}})();`);' npx esbuild --minify dist/cash.cjs.js > dist/cash.cjs.min.js mv dist/cash.cjs.js dist/cash.js mv dist/cash.cjs.min.js dist/cash.min.js rm dist/cash.cjs.ts ================================================ FILE: test/helpers.js ================================================ /* FIXTURES */ function getFixtureInit ( fixture ) { return function init () { document.getElementById ( 'qunit-fixture' ).innerHTML = fixture; }; } /* SUPPORTS */ var Supports = { CSSvariables: window.CSS && window.CSS.supports && window.CSS.supports ( '--f:0' ), template: !!$('