debut des details de la page. Vu que c'est le troisieme (euh quatrieme?) composant, c'etait un peu plus rapide, mais heureusement que claude est la pour repasser derriere mes erreurs prcq en solo je n'y arriverais pas du tout!

This commit is contained in:
camille
2026-03-27 17:49:26 +01:00
parent 24e85c4471
commit 43589e583e
92 changed files with 12959 additions and 0 deletions
+90
View File
@@ -3,11 +3,101 @@
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"node_modules/@riotjs/route": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/route/-/route-10.0.0.tgz",
"integrity": "sha512-NQ9JfIzq/itFthEbCS7GqaVEJ+yjgMqIEZcP2QbiHALcMjyeaR1CacGMMd44e9Gi+Y+N+kOebpTVw2QczTAiqg==",
"license": "MIT",
"dependencies": {
"@riotjs/util": "^10.0.0",
"bianco.attr": "^1.1.1",
"bianco.events": "^1.1.1",
"bianco.query": "^1.1.4",
"cumpa": "^2.0.1",
"rawth": "^3.0.0"
}
},
"node_modules/@riotjs/util": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/@riotjs/util/-/util-10.1.2.tgz",
"integrity": "sha512-K85suj+5YItWHB5N6LO1uMJNH6ZMBl8FxGH2xDb6dl8V3EBlLuQaPQGVzp3SOKKqeqcxJH3o5UHHIgjc2I8YrA==",
"license": "MIT"
},
"node_modules/bianco.attr": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bianco.attr/-/bianco.attr-1.1.1.tgz",
"integrity": "sha512-fTjfPnnGYiCVbe5UltC/LsDRtJE+MjmadtL749CMIfCwjl18sdbCkaQ7cgtSao6iC9ZJC8Pzw0rjMdIuA6mK1g==",
"license": "MIT",
"dependencies": {
"bianco.dom-to-array": "^1.1.0"
}
},
"node_modules/bianco.dom-to-array": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/bianco.dom-to-array/-/bianco.dom-to-array-1.1.0.tgz",
"integrity": "sha512-IWUgplQRhJSZh+7PgD/my5+X27PXNUFdcHPosOYz39a/iFF8Wl9d0N/mOArdR7Zgr3J0Q9pKVk7nO6W+7XZwBg==",
"license": "MIT"
},
"node_modules/bianco.events": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bianco.events/-/bianco.events-1.1.1.tgz",
"integrity": "sha512-Ja7oY4xThYgsmfS+JltOnzdAvqP90DVXjbXab0lwrygJdCVRoL0Q4SkEKVMnN1VqNfDtxIUKNlubEUVNp00H7A==",
"license": "MIT",
"dependencies": {
"bianco.dom-to-array": "^1.1.0"
}
},
"node_modules/bianco.query": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/bianco.query/-/bianco.query-1.1.4.tgz",
"integrity": "sha512-jUu8l484ckacCBmxN0gYLZ4Ge5aMfReL+aYNiC81s37s8+l0+rn9pnQayEgQtMHGlnL8ejd+x5U2PKpo0rvQzw==",
"license": "MIT",
"dependencies": {
"bianco.dom-to-array": "^1.1.0"
}
},
"node_modules/cumpa": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/cumpa/-/cumpa-2.0.1.tgz",
"integrity": "sha512-8oBF1cSWkgYq0ZsLP9iiLLZDicIh1eYM8WLicRhaSLMrdtjEf9A3DgMYMxB/i/xgVUZGxPVD/hrwVzx/pjdmmw==",
"license": "MIT"
},
"node_modules/erre": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/erre/-/erre-3.0.1.tgz",
"integrity": "sha512-NoexRasUiWU1CcBMh997iybzdKRw4RPhjjiVjPwh1h+aK0PglsR6+7A3osXP5829hXNnarn9Yr1Zi9ThwwV4aA==",
"license": "MIT",
"dependencies": {
"ruit": "^1.0.4"
}
},
"node_modules/leaflet": { "node_modules/leaflet": {
"version": "1.9.4", "version": "1.9.4",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
},
"node_modules/path-to-regexp": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
"integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
"license": "MIT"
},
"node_modules/rawth": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/rawth/-/rawth-3.0.0.tgz",
"integrity": "sha512-712WxtKAVEhtFm/4keDUefyjxAZR/jKrFR8ownCdjnFUxJstyigv3LBo3Shtd5VPC/p6r5gd6jY0bnAfPSol9Q==",
"license": "MIT",
"dependencies": {
"erre": "^3.0.1",
"path-to-regexp": "^6.2.1"
}
},
"node_modules/ruit": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/ruit/-/ruit-1.0.4.tgz",
"integrity": "sha512-eiHVb18DQ24Of/fdJmZCysw6X21IIyed5c87eAW95KQY5TvTfh6SR9pCkAowciyvhW1Bhm3RXuRX6eILKl+49w==",
"license": "MIT"
} }
} }
} }
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Gianluca Guarini
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.
+264
View File
@@ -0,0 +1,264 @@
# Riot Router
[![Route logo](https://raw.githubusercontent.com/riot/branding/main/route/route-horizontal.svg)](https://github.com/riot/route/)
[![Build Status][ci-image]][ci-url] [![Code Quality][qlty-image]][qlty-url] [![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Coverage Status][coverage-image]][coverage-url]
> Simple isomorphic router
The Riot.js Router is the minimal router implementation with such technologies:
- compatible with the DOM pushState and history API
- isomorphic functional API
- [erre.js streams](https://github.com/GianlucaGuarini/erre) and javascript async generators
- [rawth.js](https://github.com/GianlucaGuarini/rawth) urls parsing
It doesn't need Riot.js to work and can be used as standalone module.
**For Riot.js 3 and the older route version please check the [v3 branch](https://github.com/riot/route/tree/v3)**
## Table of Contents
- [Install](#install)
- [Documentation](#documentation)
- [Demos](https://github.com/riot/examples)
## Install
We have 2 editions:
| edition | file |
| :------------------------ | :------------------------ |
| **ESM Module** | `index.js` |
| **UMD Version** | `index.umd.js` |
| **Standalone ESM Module** | `index.standalone.js` |
| **Standalone UMD Module** | `index.standalone.umd.js` |
### Script injection
```html
<script src="https://unpkg.com/@riotjs/route@x.x.x/index.umd.js"></script>
```
_Note_: change the part `x.x.x` to the version numbers what you want to use: ex. `4.5.0` or `4.7.0`.
### ESM module
```js
import { route } from 'https://unpkg.com/@riotjs/route/index.js'
```
### npm
```bash
npm i -S @riotjs/route
```
### Download by yourself
- [Standalone](https://unpkg.com/@riotjs/route/route.js)
- [ESM](https://unpkg.com/@riotjs/route/route.esm.js)
## Documentation
### With Riot.js
You can import the `<router>` and `<route>` components in your application and use them as it follows:
```html
<app>
<router>
<!-- These links will trigger automatically HTML5 history events -->
<nav>
<a href="/home">Home</a>
<a href="/about">About</a>
<a href="/team/gianluca">Gianluca</a>
</nav>
<!-- Your application routes will be rendered here -->
<route path="/home"> Home page </route>
<route path="/about"> About </route>
<route path="/team/:person"> Hello dear { route.params.person } </route>
</router>
<script>
import { Router, Route } from '@riotjs/route'
export default {
components { Router, Route }
}
</script>
</app>
```
You can also use the `riot.register` method to register them globally
```js
import { Route, Router } from '@riotjs/route'
import { register } from 'riot'
// now the Router and Route components are globally available
register('router', Router)
register('route', Route)
```
#### Router
The `<router>` component should wrap your application markup and will detect automatically all the clicks on links that should trigger a route event.
```html
<router>
<!-- this link will trigger a riot router event -->
<a href="/path/somewhere">Link</a>
</router>
<!-- this link will work as normal link without triggering router events -->
<a href="/path/to/a/page">Link</a>
```
You can also specify the base of your application via component attributes:
```html
<router base="/internal/path">
<!-- this link is outside the base so it will work as a normal link -->
<a href="/somewhere">Link<a>
</router>
```
The router component has also an `onStarted` callback that will be called asynchronously after the first route event will be called
```html
<router onStarted="{onRouterStarted}"></router>
```
#### Route
The `<route>` component provides the `route` property to its children (it's simply a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) object) allowing you to detect the url params and queries.
```html
<route path="/:some/:route/:param"> {JSON.stringify(route.params)} </route>
<route path="/search(.*)">
<!-- Assuming the URL is "/search?q=awesome" -->
{route.searchParams.get('q')}
</route>
```
Each `<route>` component has its own lifecycle attributes in order to let you know when it gets mounted or unmounted.
```riot
<app>
<router>
<route path="/home"
on-before-mount={onBeforeHomeMount}
on-mounted={onHomeMounted}
on-before-update={onBeforeHomeUpdate}
on-updated={onHomeUpdated}
on-before-unmount={onBeforeHomeUnmount}
on-unmounted={onHomeUnmounted}
/>
</router>
</app>
```
### Standalone
This module was not only designed to be used with Riot.js but also as standalone module.
Without importing the Riot.js components in your application you can use the core methods exported to build and customize your own router compatible with any kind of frontend setup.
Depending on your project setup you might import it as follows:
```js
// in a Riot.js application
import { route } from '@riotjs/route'
// in a standalone context
import { route } from '@riotjs/route/standalone'
```
#### Fundamentals
This module works on node and on any modern browser, it exports the `router` and `router` property exposed by [rawth](https://github.com/GianlucaGuarini/rawth)
```js
import { route, router, setBase } from '@riotjs/route'
// required to set base first
setBase('/')
// create a route stream
const aboutStream = route('/about')
aboutStream.on.value((url) => {
console.log(url) // URL object
})
aboutStream.on.value(() => {
console.log('just log that the about route was triggered')
})
// triggered on each route event
router.on.value((path) => {
// path is always a string in this function
console.log(path)
})
// trigger a route change manually
router.push('/about')
// end the stream
aboutStream.end()
```
#### Base path
Before using the router in your browser you will need to set your application base path.
This setting can be configured simply via `setBase` method:
```js
import { setBase } from '@riotjs/route'
// in case you want to use the HTML5 history navigation
setBase(`/`)
// in case you use the hash navigation
setBase(`#`)
```
Setting the base path of your application route is mandatory and is the first you probably are going to do before creating your route listeners.
#### DOM binding
The example above is not really practical in case you are working in a browser environment. In that case you might want to bind your router to the DOM listening all the click events that might trigger a route change event.
Window history `popstate` events should be also connected to the router.
With the `initDomListeners` method you can automatically achieve all the features above:
```js
import { initDomListeners } from '@riotjs/route'
const unsubscribe = initDomListeners()
// the router is connected to the page DOM
// ...tear down and disconnect the router from the DOM
unsubscribe()
```
The `initDomListeners` will intercept any link click on your application. However it can also receive a HTMLElement or a list of HTMLElements as argument to scope the click listener only to a specific DOM region of your application
```js
import { initDomListeners } from '@riotjs/route'
initDomListeners(document.querySelector('.main-navigation'))
```
[ci-image]: https://img.shields.io/github/actions/workflow/status/riot/route/test.yml?style=flat-square
[ci-url]: https://github.com/riot/route/actions
[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE.txt
[npm-version-image]: http://img.shields.io/npm/v/@riotjs/route.svg?style=flat-square
[npm-downloads-image]: http://img.shields.io/npm/dm/@riotjs/route.svg?style=flat-square
[npm-url]: https://npmjs.org/package/@riotjs/route
[coverage-image]: https://qlty.sh/gh/riot/projects/route/coverage.svg
[coverage-url]: https://qlty.sh/gh/riot/projects/route
[qlty-image]: https://qlty.sh/gh/riot/projects/route/maintainability.svg
[qlty-url]: https://qlty.sh/gh/riot/projects/route
+26
View File
@@ -0,0 +1,26 @@
import { RiotComponentWrapper, RiotComponent } from 'riot'
import { URLWithParams } from 'rawth'
export * from 'rawth'
export declare const Route: RiotComponentWrapper<
RiotComponent<{
path: string
'on-before-mount'?: (path: URLWithParams) => void
'on-mounted'?: (path: URLWithParams) => void
'on-before-unmount'?: (path: URLWithParams) => void
'on-unmounted'?: (path: URLWithParams) => void
}>
>
export declare const Router: RiotComponentWrapper<
RiotComponent<{
base?: string
'initial-route'?: string
'on-started'?: (route: string) => void
}>
>
export declare function getCurrentRoute(): string
export declare function initDomListeners(): void
export declare function setBase(base: string): void
+1416
View File
File diff suppressed because it is too large Load Diff
+1039
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1435
View File
File diff suppressed because it is too large Load Diff
+92
View File
@@ -0,0 +1,92 @@
{
"name": "@riotjs/route",
"version": "10.0.0",
"description": "Riot.js isomorphic router",
"type": "module",
"main": "index.umd.js",
"jsnext:main": "index.js",
"module": "index.js",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js",
"require": "./index.umd.js",
"browser": "./index.umd.js"
},
"./standalone": {
"types": "./index.d.ts",
"import": "./index.standalone.js",
"require": "./index.standalone.umd.js",
"browser": "./index.standalone.umd.js"
}
},
"scripts": {
"prepublishOnly": "npm run build && npm test",
"lint": "eslint src test rollup.config.js && prettier -c .",
"build": "rollup -c && npm run build-demo",
"build-demo": "riot demos/components -o demos/components",
"demo": "npm run build && serve",
"cov": "c8 report --reporter=lcov",
"cov-html": "c8 report --reporter=html",
"test": "npm run lint && c8 mocha -r test/setup.js test/*.spec.js"
},
"files": [
"index.d.ts",
"index.js",
"index.umd.js",
"index.standalone.js",
"index.standalone.umd.js"
],
"repository": {
"type": "git",
"url": "git+https://github.com/riot/route.git"
},
"keywords": [
"riot",
"Riot.js",
"router",
"riot-route",
"route"
],
"author": "Gianluca Guarini <gianluca.guarini@gmail.com> (https://gianlucaguarini.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/riot/route/issues"
},
"homepage": "https://github.com/riot/route#readme",
"devDependencies": {
"@riotjs/cli": "10.0.0",
"@riotjs/compiler": "10.0.0",
"@riotjs/prettier-config": "^1.1.0",
"@riotjs/register": "10.0.0",
"@rollup/plugin-commonjs": "^28.0.6",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-virtual": "^3.0.2",
"c8": "^10.1.3",
"chai": "^6.0.1",
"eslint": "^9.33.0",
"eslint-config-riot": "^5.0.2",
"globals": "^16.3.0",
"jsdom": "26.1.0",
"jsdom-global": "3.0.2",
"mocha": "^11.7.1",
"prettier": "^3.6.2",
"riot": "^10.0.0",
"rollup": "^4.47.1",
"rollup-plugin-riot": "10.0.0",
"serve": "^14.2.4",
"sinon": "^21.0.0",
"sinon-chai": "^4.0.1"
},
"peerDependency": {
"riot": "^6.0.0 || ^7.0.0 || ^9.0.0 || ^10.0.0"
},
"dependencies": {
"@riotjs/util": "^10.0.0",
"bianco.attr": "^1.1.1",
"bianco.events": "^1.1.1",
"bianco.query": "^1.1.4",
"cumpa": "^2.0.1",
"rawth": "^3.0.0"
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Gianluca Guarini
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.
+19
View File
@@ -0,0 +1,19 @@
# @riotjs/util
Riot.js shared util scripts
[![Build Status][ci-image]][ci-url]
[![Issue Count][qlty-image]][qlty-url]
[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-url]
[![MIT License][license-image]][license-url]
[ci-image]: https://img.shields.io/github/actions/workflow/status/riot/util/test.yml?style=flat-square
[ci-url]: https://github.com/riot/util/actions
[license-image]: https://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE
[npm-version-image]: https://img.shields.io/npm/v/@riotjs/util.svg?style=flat-square
[npm-downloads-image]: https://img.shields.io/npm/dm/@riotjs/util.svg?style=flat-square
[npm-url]: https://npmjs.org/package/@riotjs/util
[qlty-image]: https://qlty.sh/gh/riot/projects/util/maintainability.svg
[qlty-url]: https://qlty.sh/gh/riot/projects/util
+24
View File
@@ -0,0 +1,24 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const EACH = 0;
const IF = 1;
const SIMPLE = 2;
const TAG = 3;
const SLOT = 4;
var bindingTypes = {
EACH,
IF,
SIMPLE,
TAG,
SLOT,
};
exports.EACH = EACH;
exports.IF = IF;
exports.SIMPLE = SIMPLE;
exports.SLOT = SLOT;
exports.TAG = TAG;
exports.default = bindingTypes;
+13
View File
@@ -0,0 +1,13 @@
export const EACH = 0
export const IF = 1
export const SIMPLE = 2
export const TAG = 3
export const SLOT = 4
export default {
EACH,
IF,
SIMPLE,
TAG,
SLOT,
}
+96
View File
@@ -0,0 +1,96 @@
'use strict';
var constants = require('./constants.cjs');
/**
* Quick type checking
* @param {*} element - anything
* @param {string} type - type definition
* @returns {boolean} true if the type corresponds
*/
function checkType(element, type) {
return typeof element === type
}
/**
* Check if an element is part of an svg
* @param {HTMLElement} el - element to check
* @returns {boolean} true if we are in an svg context
*/
function isSvg(el) {
const owner = el.ownerSVGElement;
return !!owner || owner === null
}
/**
* Check if an element is a template tag
* @param {HTMLElement} el - element to check
* @returns {boolean} true if it's a <template>
*/
function isTemplate(el) {
return el.tagName.toLowerCase() === 'template'
}
/**
* Check that will be passed if its argument is a function
* @param {*} value - value to check
* @returns {boolean} - true if the value is a function
*/
function isFunction(value) {
return checkType(value, 'function')
}
/**
* Check if a value is a Boolean
* @param {*} value - anything
* @returns {boolean} true only for the value is a boolean
*/
function isBoolean(value) {
return checkType(value, 'boolean')
}
/**
* Check if a value is an Object
* @param {*} value - anything
* @returns {boolean} true only for the value is an object
*/
function isObject(value) {
return !isNil(value) && value.constructor === Object
}
/**
* Check if a value is null or undefined
* @param {*} value - anything
* @returns {boolean} true only for the 'undefined' and 'null' types
*/
function isNil(value) {
return value === null || value === undefined
}
/**
* Detect node js environment
* @returns {boolean} true if the runtime is node
*/
function isNode() {
return typeof globalThis.process !== 'undefined'
}
/**
* Check if an attribute is a DOM handler
* @param {string} attribute - attribute string
* @returns {boolean} true only for dom listener attribute nodes
*/
function isEventAttribute(attribute) {
return constants.EVENT_ATTRIBUTE_RE.test(attribute)
}
exports.checkType = checkType;
exports.isBoolean = isBoolean;
exports.isEventAttribute = isEventAttribute;
exports.isFunction = isFunction;
exports.isNil = isNil;
exports.isNode = isNode;
exports.isObject = isObject;
exports.isSvg = isSvg;
exports.isTemplate = isTemplate;
+84
View File
@@ -0,0 +1,84 @@
import { EVENT_ATTRIBUTE_RE } from './constants.js'
/**
* Quick type checking
* @param {*} element - anything
* @param {string} type - type definition
* @returns {boolean} true if the type corresponds
*/
export function checkType(element, type) {
return typeof element === type
}
/**
* Check if an element is part of an svg
* @param {HTMLElement} el - element to check
* @returns {boolean} true if we are in an svg context
*/
export function isSvg(el) {
const owner = el.ownerSVGElement
return !!owner || owner === null
}
/**
* Check if an element is a template tag
* @param {HTMLElement} el - element to check
* @returns {boolean} true if it's a <template>
*/
export function isTemplate(el) {
return el.tagName.toLowerCase() === 'template'
}
/**
* Check that will be passed if its argument is a function
* @param {*} value - value to check
* @returns {boolean} - true if the value is a function
*/
export function isFunction(value) {
return checkType(value, 'function')
}
/**
* Check if a value is a Boolean
* @param {*} value - anything
* @returns {boolean} true only for the value is a boolean
*/
export function isBoolean(value) {
return checkType(value, 'boolean')
}
/**
* Check if a value is an Object
* @param {*} value - anything
* @returns {boolean} true only for the value is an object
*/
export function isObject(value) {
return !isNil(value) && value.constructor === Object
}
/**
* Check if a value is null or undefined
* @param {*} value - anything
* @returns {boolean} true only for the 'undefined' and 'null' types
*/
export function isNil(value) {
return value === null || value === undefined
}
/**
* Detect node js environment
* @returns {boolean} true if the runtime is node
*/
export function isNode() {
return typeof globalThis.process !== 'undefined'
}
/**
* Check if an attribute is a DOM handler
* @param {string} attribute - attribute string
* @returns {boolean} true only for dom listener attribute nodes
*/
export function isEventAttribute(attribute) {
return EVENT_ATTRIBUTE_RE.test(attribute)
}
+57
View File
@@ -0,0 +1,57 @@
'use strict';
// Riot.js constants that can be used across more modules
const COMPONENTS_IMPLEMENTATION_MAP = new Map(),
DOM_COMPONENT_INSTANCE_PROPERTY = Symbol('riot-component'),
PLUGINS_SET = new Set(),
IS_DIRECTIVE = 'is',
VALUE_ATTRIBUTE = 'value',
REF_ATTRIBUTE = 'ref',
EVENT_ATTRIBUTE_RE = /^on/,
MOUNT_METHOD_KEY = 'mount',
UPDATE_METHOD_KEY = 'update',
UNMOUNT_METHOD_KEY = 'unmount',
SHOULD_UPDATE_KEY = 'shouldUpdate',
ON_BEFORE_MOUNT_KEY = 'onBeforeMount',
ON_MOUNTED_KEY = 'onMounted',
ON_BEFORE_UPDATE_KEY = 'onBeforeUpdate',
ON_UPDATED_KEY = 'onUpdated',
ON_BEFORE_UNMOUNT_KEY = 'onBeforeUnmount',
ON_UNMOUNTED_KEY = 'onUnmounted',
PROPS_KEY = 'props',
STATE_KEY = 'state',
SLOTS_KEY = 'slots',
ROOT_KEY = 'root',
IS_PURE_SYMBOL = Symbol('pure'),
IS_COMPONENT_UPDATING = Symbol('is_updating'),
PARENT_KEY_SYMBOL = Symbol('parent'),
TEMPLATE_KEY_SYMBOL = Symbol('template'),
ROOT_ATTRIBUTES_KEY_SYMBOL = Symbol('root-attributes');
exports.COMPONENTS_IMPLEMENTATION_MAP = COMPONENTS_IMPLEMENTATION_MAP;
exports.DOM_COMPONENT_INSTANCE_PROPERTY = DOM_COMPONENT_INSTANCE_PROPERTY;
exports.EVENT_ATTRIBUTE_RE = EVENT_ATTRIBUTE_RE;
exports.IS_COMPONENT_UPDATING = IS_COMPONENT_UPDATING;
exports.IS_DIRECTIVE = IS_DIRECTIVE;
exports.IS_PURE_SYMBOL = IS_PURE_SYMBOL;
exports.MOUNT_METHOD_KEY = MOUNT_METHOD_KEY;
exports.ON_BEFORE_MOUNT_KEY = ON_BEFORE_MOUNT_KEY;
exports.ON_BEFORE_UNMOUNT_KEY = ON_BEFORE_UNMOUNT_KEY;
exports.ON_BEFORE_UPDATE_KEY = ON_BEFORE_UPDATE_KEY;
exports.ON_MOUNTED_KEY = ON_MOUNTED_KEY;
exports.ON_UNMOUNTED_KEY = ON_UNMOUNTED_KEY;
exports.ON_UPDATED_KEY = ON_UPDATED_KEY;
exports.PARENT_KEY_SYMBOL = PARENT_KEY_SYMBOL;
exports.PLUGINS_SET = PLUGINS_SET;
exports.PROPS_KEY = PROPS_KEY;
exports.REF_ATTRIBUTE = REF_ATTRIBUTE;
exports.ROOT_ATTRIBUTES_KEY_SYMBOL = ROOT_ATTRIBUTES_KEY_SYMBOL;
exports.ROOT_KEY = ROOT_KEY;
exports.SHOULD_UPDATE_KEY = SHOULD_UPDATE_KEY;
exports.SLOTS_KEY = SLOTS_KEY;
exports.STATE_KEY = STATE_KEY;
exports.TEMPLATE_KEY_SYMBOL = TEMPLATE_KEY_SYMBOL;
exports.UNMOUNT_METHOD_KEY = UNMOUNT_METHOD_KEY;
exports.UPDATE_METHOD_KEY = UPDATE_METHOD_KEY;
exports.VALUE_ATTRIBUTE = VALUE_ATTRIBUTE;
+28
View File
@@ -0,0 +1,28 @@
// Riot.js constants that can be used across more modules
export const COMPONENTS_IMPLEMENTATION_MAP = new Map(),
DOM_COMPONENT_INSTANCE_PROPERTY = Symbol('riot-component'),
PLUGINS_SET = new Set(),
IS_DIRECTIVE = 'is',
VALUE_ATTRIBUTE = 'value',
REF_ATTRIBUTE = 'ref',
EVENT_ATTRIBUTE_RE = /^on/,
MOUNT_METHOD_KEY = 'mount',
UPDATE_METHOD_KEY = 'update',
UNMOUNT_METHOD_KEY = 'unmount',
SHOULD_UPDATE_KEY = 'shouldUpdate',
ON_BEFORE_MOUNT_KEY = 'onBeforeMount',
ON_MOUNTED_KEY = 'onMounted',
ON_BEFORE_UPDATE_KEY = 'onBeforeUpdate',
ON_UPDATED_KEY = 'onUpdated',
ON_BEFORE_UNMOUNT_KEY = 'onBeforeUnmount',
ON_UNMOUNTED_KEY = 'onUnmounted',
PROPS_KEY = 'props',
STATE_KEY = 'state',
SLOTS_KEY = 'slots',
ROOT_KEY = 'root',
IS_PURE_SYMBOL = Symbol('pure'),
IS_COMPONENT_UPDATING = Symbol('is_updating'),
PARENT_KEY_SYMBOL = Symbol('parent'),
TEMPLATE_KEY_SYMBOL = Symbol('template'),
ROOT_ATTRIBUTES_KEY_SYMBOL = Symbol('root-attributes')
+97
View File
@@ -0,0 +1,97 @@
'use strict';
var strings = require('./strings.cjs');
/**
* Get all the element attributes as object
* @param {HTMLElement} element - DOM node we want to parse
* @returns {object} all the attributes found as a key value pairs
*/
function DOMattributesToObject(element) {
return Array.from(element.attributes).reduce((acc, attribute) => {
acc[strings.dashToCamelCase(attribute.name)] = attribute.value;
return acc
}, {})
}
/**
* Move all the child nodes from a source tag to another
* @param {HTMLElement} source - source node
* @param {HTMLElement} target - target node
* @returns {undefined} it's a void method ¯\_(ツ)_/¯
*/
// Ignore this helper because it's needed only for svg tags
function moveChildren(source, target) {
// eslint-disable-next-line fp/no-loops
while (source.firstChild) target.appendChild(source.firstChild);
}
/**
* Remove the child nodes from any DOM node
* @param {HTMLElement} node - target node
* @returns {undefined}
*/
function cleanNode(node) {
// eslint-disable-next-line fp/no-loops
while (node.firstChild) node.removeChild(node.firstChild);
}
/**
* Clear multiple children in a node
* @param {HTMLElement[]} children - direct children nodes
* @returns {undefined}
*/
function clearChildren(children) {
// eslint-disable-next-line fp/no-loops,fp/no-let
for (let i = 0; i < children.length; i++) removeChild(children[i]);
}
/**
* Remove a node
* @param {HTMLElement}node - node to remove
* @returns {undefined}
*/
const removeChild = (node) => node.remove();
/**
* Insert before a node
* @param {HTMLElement} newNode - node to insert
* @param {HTMLElement} refNode - ref child
* @returns {undefined}
*/
const insertBefore = (newNode, refNode) =>
refNode?.parentNode?.insertBefore(newNode, refNode);
/**
* Move a node into its new position. Use the moveBefore method if it's available
* @param {HTMLElement} existingNode - node to move
* @param {HTMLElement} refNode - ref child
* @returns {undefined}
*/
const moveBefore = ((hasMoveBefore) => (existingNode, refNode) =>
hasMoveBefore
? refNode?.parentNode?.moveBefore(existingNode, refNode)
: insertBefore(existingNode, refNode))(
// Rely on the new moveBefore method to move nodes if it's available https://developer.mozilla.org/en-US/docs/Web/API/Element/moveBefore
// cache the value of the check into a boolean variable
typeof Element !== 'undefined' && Element.prototype.moveBefore,
);
/**
* Replace a node
* @param {HTMLElement} newNode - new node to add to the DOM
* @param {HTMLElement} replaced - node to replace
* @returns {undefined}
*/
const replaceChild = (newNode, replaced) =>
replaced?.parentNode?.replaceChild(newNode, replaced);
exports.DOMattributesToObject = DOMattributesToObject;
exports.cleanNode = cleanNode;
exports.clearChildren = clearChildren;
exports.insertBefore = insertBefore;
exports.moveBefore = moveBefore;
exports.moveChildren = moveChildren;
exports.removeChild = removeChild;
exports.replaceChild = replaceChild;
+86
View File
@@ -0,0 +1,86 @@
import { dashToCamelCase } from './strings.js'
/**
* Get all the element attributes as object
* @param {HTMLElement} element - DOM node we want to parse
* @returns {object} all the attributes found as a key value pairs
*/
export function DOMattributesToObject(element) {
return Array.from(element.attributes).reduce((acc, attribute) => {
acc[dashToCamelCase(attribute.name)] = attribute.value
return acc
}, {})
}
/**
* Move all the child nodes from a source tag to another
* @param {HTMLElement} source - source node
* @param {HTMLElement} target - target node
* @returns {undefined} it's a void method ¯\_(ツ)_/¯
*/
// Ignore this helper because it's needed only for svg tags
export function moveChildren(source, target) {
// eslint-disable-next-line fp/no-loops
while (source.firstChild) target.appendChild(source.firstChild)
}
/**
* Remove the child nodes from any DOM node
* @param {HTMLElement} node - target node
* @returns {undefined}
*/
export function cleanNode(node) {
// eslint-disable-next-line fp/no-loops
while (node.firstChild) node.removeChild(node.firstChild)
}
/**
* Clear multiple children in a node
* @param {HTMLElement[]} children - direct children nodes
* @returns {undefined}
*/
export function clearChildren(children) {
// eslint-disable-next-line fp/no-loops,fp/no-let
for (let i = 0; i < children.length; i++) removeChild(children[i])
}
/**
* Remove a node
* @param {HTMLElement}node - node to remove
* @returns {undefined}
*/
export const removeChild = (node) => node.remove()
/**
* Insert before a node
* @param {HTMLElement} newNode - node to insert
* @param {HTMLElement} refNode - ref child
* @returns {undefined}
*/
export const insertBefore = (newNode, refNode) =>
refNode?.parentNode?.insertBefore(newNode, refNode)
/**
* Move a node into its new position. Use the moveBefore method if it's available
* @param {HTMLElement} existingNode - node to move
* @param {HTMLElement} refNode - ref child
* @returns {undefined}
*/
export const moveBefore = ((hasMoveBefore) => (existingNode, refNode) =>
hasMoveBefore
? refNode?.parentNode?.moveBefore(existingNode, refNode)
: insertBefore(existingNode, refNode))(
// Rely on the new moveBefore method to move nodes if it's available https://developer.mozilla.org/en-US/docs/Web/API/Element/moveBefore
// cache the value of the check into a boolean variable
typeof Element !== 'undefined' && Element.prototype.moveBefore,
)
/**
* Replace a node
* @param {HTMLElement} newNode - new node to add to the DOM
* @param {HTMLElement} replaced - node to replace
* @returns {undefined}
*/
export const replaceChild = (newNode, replaced) =>
replaced?.parentNode?.replaceChild(newNode, replaced)
+24
View File
@@ -0,0 +1,24 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const ATTRIBUTE = 0;
const EVENT = 1;
const TEXT = 2;
const VALUE = 3;
const REF = 4;
var expressionTypes = {
ATTRIBUTE,
EVENT,
TEXT,
VALUE,
REF,
};
exports.ATTRIBUTE = ATTRIBUTE;
exports.EVENT = EVENT;
exports.REF = REF;
exports.TEXT = TEXT;
exports.VALUE = VALUE;
exports.default = expressionTypes;
+13
View File
@@ -0,0 +1,13 @@
export const ATTRIBUTE = 0
export const EVENT = 1
export const TEXT = 2
export const VALUE = 3
export const REF = 4
export default {
ATTRIBUTE,
EVENT,
TEXT,
VALUE,
REF,
}
+40
View File
@@ -0,0 +1,40 @@
'use strict';
var checks = require('./checks.cjs');
require('./constants.cjs');
// does simply nothing
function noop() {
return this
}
/**
* Autobind the methods of a source object to itself
* @param {object} source - probably a riot tag instance
* @param {Array<string>} methods - list of the methods to autobind
* @returns {object} the original object received
*/
function autobindMethods(source, methods) {
methods.forEach((method) => {
source[method] = source[method].bind(source);
});
return source
}
/**
* Call the first argument received only if it's a function otherwise return it as it is
* @param {*} source - anything
* @returns {*} anything
*/
function callOrAssign(source) {
return checks.isFunction(source)
? source.prototype && source.prototype.constructor
? new source()
: source()
: source
}
exports.autobindMethods = autobindMethods;
exports.callOrAssign = callOrAssign;
exports.noop = noop;
+33
View File
@@ -0,0 +1,33 @@
import { isFunction } from './checks.js'
// does simply nothing
export function noop() {
return this
}
/**
* Autobind the methods of a source object to itself
* @param {object} source - probably a riot tag instance
* @param {Array<string>} methods - list of the methods to autobind
* @returns {object} the original object received
*/
export function autobindMethods(source, methods) {
methods.forEach((method) => {
source[method] = source[method].bind(source)
})
return source
}
/**
* Call the first argument received only if it's a function otherwise return it as it is
* @param {*} source - anything
* @returns {*} anything
*/
export function callOrAssign(source) {
return isFunction(source)
? source.prototype && source.prototype.constructor
? new source()
: source()
: source
}
+81
View File
@@ -0,0 +1,81 @@
'use strict';
var bindingTypes = require('./binding-types.cjs');
var checks = require('./checks.cjs');
var constants = require('./constants.cjs');
var dom = require('./dom.cjs');
var expressionTypes = require('./expression-types.cjs');
var functions = require('./functions.cjs');
var misc = require('./misc.cjs');
var objects = require('./objects.cjs');
var strings = require('./strings.cjs');
exports.EACH = bindingTypes.EACH;
exports.IF = bindingTypes.IF;
exports.SIMPLE = bindingTypes.SIMPLE;
exports.SLOT = bindingTypes.SLOT;
exports.TAG = bindingTypes.TAG;
exports.checkType = checks.checkType;
exports.isBoolean = checks.isBoolean;
exports.isEventAttribute = checks.isEventAttribute;
exports.isFunction = checks.isFunction;
exports.isNil = checks.isNil;
exports.isNode = checks.isNode;
exports.isObject = checks.isObject;
exports.isSvg = checks.isSvg;
exports.isTemplate = checks.isTemplate;
exports.COMPONENTS_IMPLEMENTATION_MAP = constants.COMPONENTS_IMPLEMENTATION_MAP;
exports.DOM_COMPONENT_INSTANCE_PROPERTY = constants.DOM_COMPONENT_INSTANCE_PROPERTY;
exports.EVENT_ATTRIBUTE_RE = constants.EVENT_ATTRIBUTE_RE;
exports.IS_COMPONENT_UPDATING = constants.IS_COMPONENT_UPDATING;
exports.IS_DIRECTIVE = constants.IS_DIRECTIVE;
exports.IS_PURE_SYMBOL = constants.IS_PURE_SYMBOL;
exports.MOUNT_METHOD_KEY = constants.MOUNT_METHOD_KEY;
exports.ON_BEFORE_MOUNT_KEY = constants.ON_BEFORE_MOUNT_KEY;
exports.ON_BEFORE_UNMOUNT_KEY = constants.ON_BEFORE_UNMOUNT_KEY;
exports.ON_BEFORE_UPDATE_KEY = constants.ON_BEFORE_UPDATE_KEY;
exports.ON_MOUNTED_KEY = constants.ON_MOUNTED_KEY;
exports.ON_UNMOUNTED_KEY = constants.ON_UNMOUNTED_KEY;
exports.ON_UPDATED_KEY = constants.ON_UPDATED_KEY;
exports.PARENT_KEY_SYMBOL = constants.PARENT_KEY_SYMBOL;
exports.PLUGINS_SET = constants.PLUGINS_SET;
exports.PROPS_KEY = constants.PROPS_KEY;
exports.REF_ATTRIBUTE = constants.REF_ATTRIBUTE;
exports.ROOT_ATTRIBUTES_KEY_SYMBOL = constants.ROOT_ATTRIBUTES_KEY_SYMBOL;
exports.ROOT_KEY = constants.ROOT_KEY;
exports.SHOULD_UPDATE_KEY = constants.SHOULD_UPDATE_KEY;
exports.SLOTS_KEY = constants.SLOTS_KEY;
exports.STATE_KEY = constants.STATE_KEY;
exports.TEMPLATE_KEY_SYMBOL = constants.TEMPLATE_KEY_SYMBOL;
exports.UNMOUNT_METHOD_KEY = constants.UNMOUNT_METHOD_KEY;
exports.UPDATE_METHOD_KEY = constants.UPDATE_METHOD_KEY;
exports.VALUE_ATTRIBUTE = constants.VALUE_ATTRIBUTE;
exports.DOMattributesToObject = dom.DOMattributesToObject;
exports.cleanNode = dom.cleanNode;
exports.clearChildren = dom.clearChildren;
exports.insertBefore = dom.insertBefore;
exports.moveBefore = dom.moveBefore;
exports.moveChildren = dom.moveChildren;
exports.removeChild = dom.removeChild;
exports.replaceChild = dom.replaceChild;
exports.ATTRIBUTE = expressionTypes.ATTRIBUTE;
exports.EVENT = expressionTypes.EVENT;
exports.REF = expressionTypes.REF;
exports.TEXT = expressionTypes.TEXT;
exports.VALUE = expressionTypes.VALUE;
exports.autobindMethods = functions.autobindMethods;
exports.callOrAssign = functions.callOrAssign;
exports.noop = functions.noop;
exports.generatePropsFromAttributes = misc.generatePropsFromAttributes;
exports.memoize = misc.memoize;
exports.panic = misc.panic;
exports.cloneDeep = objects.cloneDeep;
exports.defineDefaults = objects.defineDefaults;
exports.defineProperties = objects.defineProperties;
exports.defineProperty = objects.defineProperty;
exports.filter = objects.filter;
exports.pick = objects.pick;
exports.camelToDashCase = strings.camelToDashCase;
exports.dashToCamelCase = strings.dashToCamelCase;
+9
View File
@@ -0,0 +1,9 @@
export * from './binding-types.js'
export * from './checks.js'
export * from './constants.js'
export * from './dom.js'
export * from './expression-types.js'
export * from './functions.js'
export * from './misc.js'
export * from './objects.js'
export * from './strings.js'
+68
View File
@@ -0,0 +1,68 @@
'use strict';
var expressionTypes = require('./expression-types.cjs');
var strings = require('./strings.cjs');
/**
* Throw an error with a descriptive message
* @param { string } message - error message
* @param { string } cause - optional error cause object
* @returns { undefined } hoppla... at this point the program should stop working
*/
function panic(message, cause) {
throw new Error(message, { cause })
}
/**
* Returns the memoized (cached) function.
* // borrowed from https://www.30secondsofcode.org/js/s/memoize
* @param {Function} fn - function to memoize
* @returns {Function} memoize function
*/
function memoize(fn) {
const cache = new Map();
const cached = (val) => {
return cache.has(val)
? cache.get(val)
: cache.set(val, fn.call(this, val)) && cache.get(val)
};
cached.cache = cache;
return cached
}
/**
* Generate key-value pairs from a list of attributes
* @param {Array} attributes - list of attributes generated by the riot compiler, each containing type, name, and evaluate function
* @param {object} scope - the scope in which the attribute values will be evaluated
* @returns {object} An object containing key-value pairs representing the computed attribute values
*/
function generatePropsFromAttributes(attributes, scope) {
return attributes.reduce((acc, { type, name, evaluate }) => {
const value = evaluate(scope);
switch (true) {
// spread attribute
case !name && type === expressionTypes.ATTRIBUTE:
return {
...acc,
...value,
}
// ref attribute
case type === expressionTypes.REF:
acc.ref = value;
break
// value attribute
case type === expressionTypes.VALUE:
acc.value = value;
break
// normal attributes
default:
acc[strings.dashToCamelCase(name)] = value;
}
return acc
}, {})
}
exports.generatePropsFromAttributes = generatePropsFromAttributes;
exports.memoize = memoize;
exports.panic = panic;
+62
View File
@@ -0,0 +1,62 @@
import { ATTRIBUTE, VALUE, REF } from './expression-types.js'
import { dashToCamelCase } from './strings.js'
/**
* Throw an error with a descriptive message
* @param { string } message - error message
* @param { string } cause - optional error cause object
* @returns { undefined } hoppla... at this point the program should stop working
*/
export function panic(message, cause) {
throw new Error(message, { cause })
}
/**
* Returns the memoized (cached) function.
* // borrowed from https://www.30secondsofcode.org/js/s/memoize
* @param {Function} fn - function to memoize
* @returns {Function} memoize function
*/
export function memoize(fn) {
const cache = new Map()
const cached = (val) => {
return cache.has(val)
? cache.get(val)
: cache.set(val, fn.call(this, val)) && cache.get(val)
}
cached.cache = cache
return cached
}
/**
* Generate key-value pairs from a list of attributes
* @param {Array} attributes - list of attributes generated by the riot compiler, each containing type, name, and evaluate function
* @param {object} scope - the scope in which the attribute values will be evaluated
* @returns {object} An object containing key-value pairs representing the computed attribute values
*/
export function generatePropsFromAttributes(attributes, scope) {
return attributes.reduce((acc, { type, name, evaluate }) => {
const value = evaluate(scope)
switch (true) {
// spread attribute
case !name && type === ATTRIBUTE:
return {
...acc,
...value,
}
// ref attribute
case type === REF:
acc.ref = value
break
// value attribute
case type === VALUE:
acc.value = value
break
// normal attributes
default:
acc[dashToCamelCase(name)] = value
}
return acc
}, {})
}
+95
View File
@@ -0,0 +1,95 @@
'use strict';
var checks = require('./checks.cjs');
require('./constants.cjs');
/**
* Helper function to set an immutable property
* @param {object} source - object where the new property will be set
* @param {string} key - object key where the new property will be stored
* @param {*} value - value of the new property
* @param {object} options - set the property overriding the default options
* @returns {object} - the original object modified
*/
function defineProperty(source, key, value, options = {}) {
Object.defineProperty(source, key, {
value,
enumerable: false,
writable: false,
configurable: true,
...options,
});
return source
}
/**
* Define multiple properties on a target object
* @param {object} source - object where the new properties will be set
* @param {object} properties - object containing as key pair the key + value properties
* @param {object} options - set the property overriding the default options
* @returns {object} the original object modified
*/
function defineProperties(source, properties, options) {
Object.entries(properties).forEach(([key, value]) => {
defineProperty(source, key, value, options);
});
return source
}
/**
* Define default properties if they don't exist on the source object
* @param {object} source - object that will receive the default properties
* @param {object} defaults - object containing additional optional keys
* @returns {object} the original object received enhanced
*/
function defineDefaults(source, defaults) {
Object.entries(defaults).forEach(([key, value]) => {
if (!source[key]) source[key] = value;
});
return source
}
/**
* Simple clone deep function, do not use it for classes or recursive objects!
* @param {*} source - possibly an object to clone
* @returns {*} the object we wanted to clone
*/
function cloneDeep(source) {
return structuredClone(source)
}
/**
* Like Array.prototype.filter but for objects
* @param {object} source - target object
* @param {(key: unknown, value: unknown) => boolean} filter - filter function
* @returns {object} filtered source or the original source received
*/
function filter(source, filter) {
return checks.isObject(source)
? Object.fromEntries(
Object.entries(source).filter(([key, value]) => filter(key, value)),
)
: source
}
/**
* Generate a new object picking only the properties from a given array
* @param {object} source - target object
* @param {Array} keys - list of keys that we want to copy over to the new object
* @returns {object} a new object conaining only the keys that we have picked from the keys array list
*/
function pick(source, keys) {
return checks.isObject(source)
? Object.fromEntries(keys.map((key) => [key, source[key]]))
: source
}
exports.cloneDeep = cloneDeep;
exports.defineDefaults = defineDefaults;
exports.defineProperties = defineProperties;
exports.defineProperty = defineProperty;
exports.filter = filter;
exports.pick = pick;
+85
View File
@@ -0,0 +1,85 @@
import { isObject } from './checks.js'
/**
* Helper function to set an immutable property
* @param {object} source - object where the new property will be set
* @param {string} key - object key where the new property will be stored
* @param {*} value - value of the new property
* @param {object} options - set the property overriding the default options
* @returns {object} - the original object modified
*/
export function defineProperty(source, key, value, options = {}) {
Object.defineProperty(source, key, {
value,
enumerable: false,
writable: false,
configurable: true,
...options,
})
return source
}
/**
* Define multiple properties on a target object
* @param {object} source - object where the new properties will be set
* @param {object} properties - object containing as key pair the key + value properties
* @param {object} options - set the property overriding the default options
* @returns {object} the original object modified
*/
export function defineProperties(source, properties, options) {
Object.entries(properties).forEach(([key, value]) => {
defineProperty(source, key, value, options)
})
return source
}
/**
* Define default properties if they don't exist on the source object
* @param {object} source - object that will receive the default properties
* @param {object} defaults - object containing additional optional keys
* @returns {object} the original object received enhanced
*/
export function defineDefaults(source, defaults) {
Object.entries(defaults).forEach(([key, value]) => {
if (!source[key]) source[key] = value
})
return source
}
/**
* Simple clone deep function, do not use it for classes or recursive objects!
* @param {*} source - possibly an object to clone
* @returns {*} the object we wanted to clone
*/
export function cloneDeep(source) {
return structuredClone(source)
}
/**
* Like Array.prototype.filter but for objects
* @param {object} source - target object
* @param {(key: unknown, value: unknown) => boolean} filter - filter function
* @returns {object} filtered source or the original source received
*/
export function filter(source, filter) {
return isObject(source)
? Object.fromEntries(
Object.entries(source).filter(([key, value]) => filter(key, value)),
)
: source
}
/**
* Generate a new object picking only the properties from a given array
* @param {object} source - target object
* @param {Array} keys - list of keys that we want to copy over to the new object
* @returns {object} a new object conaining only the keys that we have picked from the keys array list
*/
export function pick(source, keys) {
return isObject(source)
? Object.fromEntries(keys.map((key) => [key, source[key]]))
: source
}
+104
View File
@@ -0,0 +1,104 @@
{
"name": "@riotjs/util",
"version": "10.1.2",
"description": "Riot.js util functions",
"main": "index.cjs",
"module": "index.js",
"type": "module",
"scripts": {
"prepublishOnly": "npm test && npm run build",
"lint": "npx prettier -c . && eslint *.js",
"build": "find . -name '*.js' -not -name '*.spec.js' -not -name 'rollup.config.js' -maxdepth 1 | xargs rollup -c rollup.config.js",
"test": "npm run lint && mocha -r jsdom-global/register *.spec.js"
},
"exports": {
".": {
"import": "./index.js",
"require": "./index.cjs"
},
"./dom": {
"import": "./dom.js",
"require": "./dom.cjs"
},
"./functions": {
"import": "./functions.js",
"require": "./functions.cjs"
},
"./constants": {
"import": "./constants.js",
"require": "./constants.cjs"
},
"./strings": {
"import": "./strings.js",
"require": "./strings.cjs"
},
"./objects": {
"import": "./objects.js",
"require": "./objects.cjs"
},
"./checks": {
"import": "./checks.js",
"require": "./checks.cjs"
},
"./expression-types": {
"import": "./expression-types.js",
"require": "./expression-types.cjs"
},
"./binding-types": {
"import": "./binding-types.js",
"require": "./binding-types.cjs"
},
"./misc": {
"import": "./misc.js",
"require": "./misc.cjs"
}
},
"files": [
"index.js",
"dom.js",
"functions.js",
"constants.js",
"strings.js",
"objects.js",
"checks.js",
"expression-types.js",
"binding-types.js",
"misc.js",
"index.cjs",
"dom.cjs",
"functions.cjs",
"constants.cjs",
"strings.cjs",
"objects.cjs",
"checks.cjs",
"expression-types.cjs",
"binding-types.cjs",
"misc.cjs"
],
"repository": {
"type": "git",
"url": "git+https://github.com/GianlucaGuarini/@riotjs/util.git"
},
"keywords": [
"Riot.js",
"shared",
"Riot util"
],
"author": "Gianluca Guarini <gianluca.guarini@gmail.com> (https://gianlucaguarini.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/GianlucaGuarini/@riotjs/util/issues"
},
"homepage": "https://github.com/GianlucaGuarini/@riotjs/util#readme",
"devDependencies": {
"@riotjs/prettier-config": "^1.1.0",
"chai": "^6.2.1",
"eslint": "^9.39.1",
"eslint-config-riot": "^5.0.2",
"jsdom": "27.2.0",
"jsdom-global": "3.0.2",
"mocha": "^11.7.5",
"prettier": "^3.6.2",
"rollup": "^4.53.3"
}
}
+22
View File
@@ -0,0 +1,22 @@
'use strict';
/**
* Convert a string from camel case to dash-case
* @param {string} string - probably a component tag name
* @returns {string} component name normalized
*/
function camelToDashCase(string) {
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
}
/**
* Convert a string containing dashes to camel case
* @param {string} string - input string
* @returns {string} my-string -> myString
*/
function dashToCamelCase(string) {
return string.replace(/-(\w)/g, (_, c) => c.toUpperCase())
}
exports.camelToDashCase = camelToDashCase;
exports.dashToCamelCase = dashToCamelCase;
+17
View File
@@ -0,0 +1,17 @@
/**
* Convert a string from camel case to dash-case
* @param {string} string - probably a component tag name
* @returns {string} component name normalized
*/
export function camelToDashCase(string) {
return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
}
/**
* Convert a string containing dashes to camel case
* @param {string} string - input string
* @returns {string} my-string -> myString
*/
export function dashToCamelCase(string) {
return string.replace(/-(\w)/g, (_, c) => c.toUpperCase())
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Gianluca Guarini
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.
+160
View File
@@ -0,0 +1,160 @@
# bianco.attr
[![Build Status][ci-image]][ci-url]
[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-url]
[![MIT License][license-image]][license-url]
## Usage
```js
import { set, get, has, remove } from 'bianco.attr'
// set an attribute on a node
const img = document.createElement('img')
set(img, 'width', 100)
get(img, 'width') // => '100'
has(img, 'width') // => true
remove(img, 'width')
get(img, 'width') // => null
```
[ci-image]:https://img.shields.io/github/workflow/status/biancojs/attr/test?style=flat-square
[ci-url]:https://github.com/biancojs/attr/actions
[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE.txt
[npm-version-image]: http://img.shields.io/npm/v/bianco.attr.svg?style=flat-square
[npm-downloads-image]: http://img.shields.io/npm/dm/bianco.attr.svg?style=flat-square
[npm-url]: https://npmjs.org/package/bianco.attr
## API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
#### Table of Contents
- [set](#set)
- [Parameters](#parameters)
- [Examples](#examples)
- [get](#get)
- [Parameters](#parameters-1)
- [Examples](#examples-1)
- [remove](#remove)
- [Parameters](#parameters-2)
- [Examples](#examples-2)
- [has](#has)
- [Parameters](#parameters-3)
- [Examples](#examples-3)
### set
Set any attribute on a single or a list of DOM nodes
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s to parse
- `name` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))** either the name of the attribute to set
or a list of properties as object key - value
- `value` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the new value of the attribute (optional)
#### Examples
```javascript
import { set } from 'bianco.attr'
const img = document.createElement('img')
set(img, 'width', 100)
// or also
set(img, {
width: 300,
height: 300
})
```
Returns **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** the original array of elements passed to this function
### get
Get any attribute from a single or a list of DOM nodes
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s to parse
- `name` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** name or list of attributes to get
#### Examples
```javascript
import { get } from 'bianco.attr'
const img = document.createElement('img')
get(img, 'width') // => '200'
// or also
get(img, ['width', 'height']) // => ['200', '300']
// or also
get([img1, img2], ['width', 'height']) // => [['200', '300'], ['500', '200']]
```
Returns **([Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** list of the attributes found
### remove
Remove any attribute from a single or a list of DOM nodes
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s to parse
- `name` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** name or list of attributes to remove
#### Examples
```javascript
import { remove } from 'bianco.attr'
remove(img, 'width') // remove the width attribute
// or also
remove(img, ['width', 'height']) // remove the width and the height attribute
// or also
remove([img1, img2], ['width', 'height']) // remove the width and the height attribute from both images
```
Returns **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** the original array of elements passed to this function
### has
Set any attribute on a single or a list of DOM nodes
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s to parse
- `name` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** name or list of attributes to detect
#### Examples
```javascript
import { has } from 'bianco.attr'
has(img, 'width') // false
// or also
has(img, ['width', 'height']) // => [false, false]
// or also
has([img1, img2], ['width', 'height']) // => [[false, false], [false, false]]
```
Returns **([boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** true or false or an array of boolean values
+27
View File
@@ -0,0 +1,27 @@
export declare function get<T extends Element>(el: T, attr: string): string | null
export declare function get<T extends Element>(el: T, attrs: string[]): string[] | null
export declare function get<T extends Element>(els: T[], attr: string): string[] | null
export declare function get<T extends Element>(els: T[], attrs: string[]): string[][] | null
export declare function set<T extends Element>(el: T, attr: string, val: unknown): T
export declare function set<T extends Element>(el: T, attrs: Record<string, unknown>): T
export declare function set<T extends Element>(els: T[], attr: string, val: unknown): T[]
export declare function set<T extends Element>(els: T[], attrs: Record<string, unknown>): T[]
export declare function remove<T extends Element>(el: T, attr: string | string[]): void
export declare function remove<T extends Element>(els: T[], attr: string | string[]): void
export declare function has<T extends Element>(el: T, attr: string): boolean | null
export declare function has<T extends Element>(el: T, attrs: string[]): boolean[] | null
export declare function has<T extends Element>(els: T[], attr: string): boolean[] | null
export declare function has<T extends Element>(els: T[], attrs: string[]): boolean[][] | null
export default {
get,
set,
remove,
has
}
+145
View File
@@ -0,0 +1,145 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var domToArray = require('bianco.dom-to-array');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var domToArray__default = /*#__PURE__*/_interopDefaultLegacy(domToArray);
/**
* Normalize the return values, in case of a single value we avoid to return an array
* @param { Array } values - list of values we want to return
* @returns { Array|string|boolean } either the whole list of values or the single one found
* @private
*/
const normalize = values => values.length === 1 ? values[0] : values;
/**
* Parse all the nodes received to get/remove/check their attributes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes
* @param { string } method - method that will be used to parse the attributes
* @returns { Array|string } result of the parsing in a list or a single value
* @private
*/
function parseNodes(els, name, method) {
const names = typeof name === 'string' ? [name] : name;
return normalize(domToArray__default["default"](els).map(el => {
return normalize(names.map(n => el[method](n)))
}))
}
/**
* Set any attribute on a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Object } name - either the name of the attribute to set
* or a list of properties as object key - value
* @param { string } value - the new value of the attribute (optional)
* @returns { HTMLElement|NodeList|Array } the original array of elements passed to this function
*
* @example
*
* import { set } from 'bianco.attr'
*
* const img = document.createElement('img')
*
* set(img, 'width', 100)
*
* // or also
* set(img, {
* width: 300,
* height: 300
* })
*
*/
function set(els, name, value) {
const attrs = typeof name === 'object' ? name : { [name]: value };
const props = Object.keys(attrs);
domToArray__default["default"](els).forEach(el => {
props.forEach(prop => el.setAttribute(prop, attrs[prop]));
});
return els
}
/**
* Get any attribute from a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes to get
* @returns { Array|string } list of the attributes found
*
* @example
*
* import { get } from 'bianco.attr'
*
* const img = document.createElement('img')
*
* get(img, 'width') // => '200'
*
* // or also
* get(img, ['width', 'height']) // => ['200', '300']
*
* // or also
* get([img1, img2], ['width', 'height']) // => [['200', '300'], ['500', '200']]
*/
function get(els, name) {
return parseNodes(els, name, 'getAttribute')
}
/**
* Remove any attribute from a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes to remove
* @returns { HTMLElement|NodeList|Array } the original array of elements passed to this function
*
* @example
*
* import { remove } from 'bianco.attr'
*
* remove(img, 'width') // remove the width attribute
*
* // or also
* remove(img, ['width', 'height']) // remove the width and the height attribute
*
* // or also
* remove([img1, img2], ['width', 'height']) // remove the width and the height attribute from both images
*/
function remove(els, name) {
return parseNodes(els, name, 'removeAttribute')
}
/**
* Set any attribute on a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes to detect
* @returns { boolean|Array } true or false or an array of boolean values
* @example
*
* import { has } from 'bianco.attr'
*
* has(img, 'width') // false
*
* // or also
* has(img, ['width', 'height']) // => [false, false]
*
* // or also
* has([img1, img2], ['width', 'height']) // => [[false, false], [false, false]]
*/
function has(els, name) {
return parseNodes(els, name, 'hasAttribute')
}
var index_next = {
get,
set,
remove,
has
};
exports["default"] = index_next;
exports.get = get;
exports.has = has;
exports.remove = remove;
exports.set = set;
+131
View File
@@ -0,0 +1,131 @@
import domToArray from 'bianco.dom-to-array'
/**
* Normalize the return values, in case of a single value we avoid to return an array
* @param { Array } values - list of values we want to return
* @returns { Array|string|boolean } either the whole list of values or the single one found
* @private
*/
const normalize = values => values.length === 1 ? values[0] : values
/**
* Parse all the nodes received to get/remove/check their attributes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes
* @param { string } method - method that will be used to parse the attributes
* @returns { Array|string } result of the parsing in a list or a single value
* @private
*/
function parseNodes(els, name, method) {
const names = typeof name === 'string' ? [name] : name
return normalize(domToArray(els).map(el => {
return normalize(names.map(n => el[method](n)))
}))
}
/**
* Set any attribute on a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Object } name - either the name of the attribute to set
* or a list of properties as object key - value
* @param { string } value - the new value of the attribute (optional)
* @returns { HTMLElement|NodeList|Array } the original array of elements passed to this function
*
* @example
*
* import { set } from 'bianco.attr'
*
* const img = document.createElement('img')
*
* set(img, 'width', 100)
*
* // or also
* set(img, {
* width: 300,
* height: 300
* })
*
*/
export function set(els, name, value) {
const attrs = typeof name === 'object' ? name : { [name]: value }
const props = Object.keys(attrs)
domToArray(els).forEach(el => {
props.forEach(prop => el.setAttribute(prop, attrs[prop]))
})
return els
}
/**
* Get any attribute from a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes to get
* @returns { Array|string } list of the attributes found
*
* @example
*
* import { get } from 'bianco.attr'
*
* const img = document.createElement('img')
*
* get(img, 'width') // => '200'
*
* // or also
* get(img, ['width', 'height']) // => ['200', '300']
*
* // or also
* get([img1, img2], ['width', 'height']) // => [['200', '300'], ['500', '200']]
*/
export function get(els, name) {
return parseNodes(els, name, 'getAttribute')
}
/**
* Remove any attribute from a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes to remove
* @returns { HTMLElement|NodeList|Array } the original array of elements passed to this function
*
* @example
*
* import { remove } from 'bianco.attr'
*
* remove(img, 'width') // remove the width attribute
*
* // or also
* remove(img, ['width', 'height']) // remove the width and the height attribute
*
* // or also
* remove([img1, img2], ['width', 'height']) // remove the width and the height attribute from both images
*/
export function remove(els, name) {
return parseNodes(els, name, 'removeAttribute')
}
/**
* Set any attribute on a single or a list of DOM nodes
* @param { HTMLElement|NodeList|Array } els - DOM node/s to parse
* @param { string|Array } name - name or list of attributes to detect
* @returns { boolean|Array } true or false or an array of boolean values
* @example
*
* import { has } from 'bianco.attr'
*
* has(img, 'width') // false
*
* // or also
* has(img, ['width', 'height']) // => [false, false]
*
* // or also
* has([img1, img2], ['width', 'height']) // => [[false, false], [false, false]]
*/
export function has(els, name) {
return parseNodes(els, name, 'hasAttribute')
}
export default {
get,
set,
remove,
has
}
+47
View File
@@ -0,0 +1,47 @@
{
"name": "bianco.attr",
"version": "1.1.1",
"description": "Helper to set/get/remove DOM attributes on a list of nodes",
"main": "index.js",
"jsnext:main": "index.next.js",
"module": "index.next.js",
"types": "index.d.ts",
"scripts": {
"prepare": "npm run build && npm test",
"lint": "eslint index.next.js test.js rollup.config.js",
"build": "rollup -c",
"doc": "documentation readme index.next.js -s API",
"test": "npm run lint && mocha test.js"
},
"files": [
"index.js",
"index.next.js",
"index.d.ts"
],
"repository": {
"type": "git",
"url": "git+https://github.com/biancojs/@.git"
},
"keywords": [
"es6",
"es2015"
],
"author": "Gianluca Guarini <gianluca.guarini@gmail.com> (http://gianlucaguarini.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/biancojs/@/issues"
},
"homepage": "https://github.com/biancojs/@#readme",
"devDependencies": {
"@gianlucaguarini/eslint-config": "^2.0.0",
"eslint": "^8.10.0",
"jsdom": "19.0.0",
"jsdom-global": "3.0.2",
"mocha": "^9.2.1",
"rollup": "^2.70.0",
"rollup-plugin-node-resolve": "^3.4.0"
},
"dependencies": {
"bianco.dom-to-array": "^1.1.0"
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Gianluca Guarini
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.
+62
View File
@@ -0,0 +1,62 @@
# bianco.dom-to-array
[![Build Status][ci-image]][ci-url]
[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-url]
[![MIT License][license-image]][license-url]
## Usage
```js
import domToArray from 'bianco.dom-to-array'
var div = document.createElement('div')
div.innerHTML = `
<ul>
<li>one</li>
<li>two</li>
</ul>
`
body.appendChild(div)
// It can convert node list
const lis = document.querySelectorAll('li')
const $lis = domToArray(lis)
$lis.length // => 2
Array.isArray($lis) // => true
// It can convert a single node
const li = document.querySelector('li')
const $li = domToArray(li)
$li.length // => 1
Array.isArray($li) // => true
```
[ci-image]:https://img.shields.io/github/workflow/status/biancojs/dom-to-array/test?style=flat-square
[ci-url]:https://github.com/biancojs/dom-to-array/actions
[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE.txt
[npm-version-image]: http://img.shields.io/npm/v/bianco.dom-to-array.svg?style=flat-square
[npm-downloads-image]: http://img.shields.io/npm/dm/bianco.dom-to-array.svg?style=flat-square
[npm-url]: https://npmjs.org/package/bianco.dom-to-array
## API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
#### Table of Contents
- [domToArray](#domtoarray)
- [Parameters](#parameters)
### domToArray
Converts any DOM node/s to a loopable array
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList))** single html element or a node list
Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)** always a loopable object
+4
View File
@@ -0,0 +1,4 @@
type DOMElement = Window | Document | Element
export default function domToArray<T extends DOMElement, R extends DOMElement[]>(els: T | T[]): R[];
+27
View File
@@ -0,0 +1,27 @@
'use strict';
/**
* Converts any DOM node/s to a loopable array
* @param { HTMLElement|NodeList } els - single html element or a node list
* @returns { Array } always a loopable object
*/
function domToArray(els) {
// can this object be already looped?
if (!Array.isArray(els)) {
// is it a node list?
if (
/^\[object (HTMLCollection|NodeList|Object)\]$/
.test(Object.prototype.toString.call(els))
&& typeof els.length === 'number'
)
return Array.from(els)
else
// if it's a single node
// it will be returned as "array" with one single entry
return [els]
}
// this object could be looped out of the box
return els
}
module.exports = domToArray;
+23
View File
@@ -0,0 +1,23 @@
/**
* Converts any DOM node/s to a loopable array
* @param { HTMLElement|NodeList } els - single html element or a node list
* @returns { Array } always a loopable object
*/
export default function domToArray(els) {
// can this object be already looped?
if (!Array.isArray(els)) {
// is it a node list?
if (
/^\[object (HTMLCollection|NodeList|Object)\]$/
.test(Object.prototype.toString.call(els))
&& typeof els.length === 'number'
)
return Array.from(els)
else
// if it's a single node
// it will be returned as "array" with one single entry
return [els]
}
// this object could be looped out of the box
return els
}
+49
View File
@@ -0,0 +1,49 @@
{
"name": "bianco.dom-to-array",
"version": "1.1.0",
"description": "Converts any DOM node/s to a loopable array",
"main": "index.js",
"jsnext:main": "index.next.js",
"module": "index.next.js",
"types": "index.d.ts",
"scripts": {
"prepare": "npm run build && npm test",
"lint": "eslint index.next.js test.js rollup.config.js",
"build": "rollup -c",
"doc": "documentation readme index.next.js -s API",
"test": "npm run lint && mocha test.js"
},
"files": [
"index.js",
"index.next.js",
"index.d.ts"
],
"repository": {
"type": "git",
"url": "git+https://github.com/biancojs/dom-to-array.git"
},
"keywords": [
"es6",
"es2015",
"dom",
"array",
"iterator",
"dom loops",
"nodes"
],
"author": "Gianluca Guarini <gianluca.guarini@gmail.com> (http://gianlucaguarini.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/biancojs/dom-to-array/issues"
},
"homepage": "https://github.com/biancojs/dom-to-array#readme",
"devDependencies": {
"@gianlucaguarini/eslint-config": "^2.0.0",
"eslint": "^8.10.0",
"jsdom": "19.0.0",
"jsdom-global": "3.0.2",
"mocha": "^9.2.1",
"rollup": "^2.70.0",
"rollup-plugin-node-resolve": "^3.4.0"
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Gianluca Guarini
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.
+83
View File
@@ -0,0 +1,83 @@
# bianco.events
[![Build Status][ci-image]][ci-url]
[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-downloads-image]][npm-url]
[![MIT License][license-image]][license-url]
Modern DOM events helpers written in es2015
This script will not be transpiled and it is only thought to be part of your build chain.
## Usage
```js
import { add, remove, once } from 'bianco.events'
add(node/s, 'click mouseenter', function(e) {
console.log('tadaaa!')
})
```
[ci-image]:https://img.shields.io/github/workflow/status/biancojs/events/test?style=flat-square
[ci-url]:https://github.com/biancojs/events/actions
[license-image]: http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE.txt
[npm-version-image]: http://img.shields.io/npm/v/bianco.events.svg?style=flat-square
[npm-downloads-image]: http://img.shields.io/npm/dm/bianco.events.svg?style=flat-square
[npm-url]: https://npmjs.org/package/bianco.events
## API
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
#### Table of Contents
- [add](#add)
- [Parameters](#parameters)
- [once](#once)
- [Parameters](#parameters-1)
- [remove](#remove)
- [Parameters](#parameters-2)
### add
Set a listener for all the events received separated by spaces
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s where the listeners will be bound
- `evList` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** list of events we want to bind space separated
- `cb` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** listeners callback
- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** event options (capture, once and passive)
Returns **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s and first argument of the function
### once
Set a listener using from a list of events triggering the callback only once
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node where the listeners will be bound
- `evList` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** list of events we want to bind space separated
- `cb` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** listeners callback
- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** event options (capture, once and passive)
Returns **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s and first argument of the function
### remove
Remove all the listeners for the events received separated by spaces
#### Parameters
- `els` **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s where the events will be unbind
- `evList` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** list of events we want unbind space separated
- `cb` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** listeners callback
- `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** event options (capture, once and passive)
Returns **([HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element) \| [NodeList](https://developer.mozilla.org/docs/Web/API/NodeList) \| [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array))** DOM node/s and first argument of the function
+29
View File
@@ -0,0 +1,29 @@
export function add<
Target extends EventTarget,
Callback extends EventListenerOrEventListenerObject,
>(
el: Target | Target[],
eventName: string,
callback: Callback,
options?: AddEventListenerOptions | boolean,
): Target
export function once<
Target extends EventTarget,
Callback extends EventListenerOrEventListenerObject,
>(
el: Target | Target[],
eventName: string,
callback: Callback,
options?: AddEventListenerOptions | boolean,
): Target
export function remove<
Target extends EventTarget,
Callback extends EventListenerOrEventListenerObject,
>(
el: Target | Target[],
eventName: string,
callback: Callback,
options?: EventListenerOptions | boolean,
): Target
+85
View File
@@ -0,0 +1,85 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var domToArray = require('bianco.dom-to-array');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var domToArray__default = /*#__PURE__*/_interopDefaultLegacy(domToArray);
/**
* Split a string into several items separed by spaces
* @param { string } l - events list
* @returns { Array } all the events detected
* @private
*/
const split = l => l.split(/\s/);
/**
* Set a listener for all the events received separated by spaces
* @param { HTMLElement|NodeList|Array } els - DOM node/s where the listeners will be bound
* @param { string } evList - list of events we want to bind or unbind space separated
* @param { Function } cb - listeners callback
* @param { string } method - either 'addEventListener' or 'removeEventListener'
* @param { Object } options - event options (capture, once and passive)
* @returns { undefined }
* @private
*/
function manageEvents(els, evList, cb, method, options) {
els = domToArray__default["default"](els);
split(evList).forEach((e) => {
els.forEach(el => el[method](e, cb, options || false));
});
}
/**
* Set a listener for all the events received separated by spaces
* @param { HTMLElement|Array } els - DOM node/s where the listeners will be bound
* @param { string } evList - list of events we want to bind space separated
* @param { Function } cb - listeners callback
* @param { Object } options - event options (capture, once and passive)
* @returns { HTMLElement|NodeList|Array } DOM node/s and first argument of the function
*/
function add(els, evList, cb, options) {
manageEvents(els, evList, cb, 'addEventListener', options);
return els
}
/**
* Set a listener using from a list of events triggering the callback only once
* @param { HTMLElement|Array } els - DOM node where the listeners will be bound
* @param { string } evList - list of events we want to bind space separated
* @param { Function } cb - listeners callback
* @param { Object } options - event options (capture, once and passive)
* @returns { HTMLElement|NodeList|Array } DOM node/s and first argument of the function
*/
function once(els, evList, cb, options) {
manageEvents(els, evList, cb, 'addEventListener', Object.assign(options || {}, { once: true }));
return els
}
/**
* Remove all the listeners for the events received separated by spaces
* @param { HTMLElement|Array } els - DOM node/s where the events will be unbind
* @param { string } evList - list of events we want unbind space separated
* @param { Function } cb - listeners callback
* @param { Object } options - event options (capture, once and passive)
* @returns { HTMLElement|NodeList|Array } DOM node/s and first argument of the function
*/
function remove(els, evList, cb, options) {
manageEvents(els, evList, cb, 'removeEventListener', options);
return els
}
var index_next = {
add,
once,
remove
};
exports.add = add;
exports["default"] = index_next;
exports.once = once;
exports.remove = remove;
+73
View File
@@ -0,0 +1,73 @@
import domToArray from 'bianco.dom-to-array'
/**
* Split a string into several items separed by spaces
* @param { string } l - events list
* @returns { Array } all the events detected
* @private
*/
const split = l => l.split(/\s/)
/**
* Set a listener for all the events received separated by spaces
* @param { HTMLElement|NodeList|Array } els - DOM node/s where the listeners will be bound
* @param { string } evList - list of events we want to bind or unbind space separated
* @param { Function } cb - listeners callback
* @param { string } method - either 'addEventListener' or 'removeEventListener'
* @param { Object } options - event options (capture, once and passive)
* @returns { undefined }
* @private
*/
function manageEvents(els, evList, cb, method, options) {
els = domToArray(els)
split(evList).forEach((e) => {
els.forEach(el => el[method](e, cb, options || false))
})
}
/**
* Set a listener for all the events received separated by spaces
* @param { HTMLElement|Array } els - DOM node/s where the listeners will be bound
* @param { string } evList - list of events we want to bind space separated
* @param { Function } cb - listeners callback
* @param { Object } options - event options (capture, once and passive)
* @returns { HTMLElement|NodeList|Array } DOM node/s and first argument of the function
*/
export function add(els, evList, cb, options) {
manageEvents(els, evList, cb, 'addEventListener', options)
return els
}
/**
* Set a listener using from a list of events triggering the callback only once
* @param { HTMLElement|Array } els - DOM node where the listeners will be bound
* @param { string } evList - list of events we want to bind space separated
* @param { Function } cb - listeners callback
* @param { Object } options - event options (capture, once and passive)
* @returns { HTMLElement|NodeList|Array } DOM node/s and first argument of the function
*/
export function once(els, evList, cb, options) {
manageEvents(els, evList, cb, 'addEventListener', Object.assign(options || {}, { once: true }))
return els
}
/**
* Remove all the listeners for the events received separated by spaces
* @param { HTMLElement|Array } els - DOM node/s where the events will be unbind
* @param { string } evList - list of events we want unbind space separated
* @param { Function } cb - listeners callback
* @param { Object } options - event options (capture, once and passive)
* @returns { HTMLElement|NodeList|Array } DOM node/s and first argument of the function
*/
export function remove(els, evList, cb, options) {
manageEvents(els, evList, cb, 'removeEventListener', options)
return els
}
export default {
add,
once,
remove
}
+50
View File
@@ -0,0 +1,50 @@
{
"name": "bianco.events",
"version": "1.1.1",
"description": "Modern DOM events helpers written in es2015",
"main": "index.js",
"jsnext:main": "index.next.js",
"module": "index.next.js",
"types": "index.d.ts",
"scripts": {
"prepare": "npm run build && npm test",
"lint": "eslint index.next.js test.js rollup.config.js",
"build": "rollup -c",
"doc": "documentation readme index.next.js -s API",
"test": "npm run lint && mocha test.js"
},
"files": [
"index.js",
"index.next.js",
"index.d.ts"
],
"repository": {
"type": "git",
"url": "git+https://github.com/biancojs/events.git"
},
"keywords": [
"es6",
"es2015",
"addEventListener",
"removeEventListener",
"DOM"
],
"author": "Gianluca Guarini <gianluca.guarini@gmail.com> (http://gianlucaguarini.com)",
"license": "MIT",
"bugs": {
"url": "https://github.com/biancojs/events/issues"
},
"homepage": "https://github.com/biancojs/events#readme",
"devDependencies": {
"@gianlucaguarini/eslint-config": "^2.0.0",
"eslint": "^8.10.0",
"jsdom": "19.0.0",
"jsdom-global": "3.0.2",
"mocha": "^9.2.1",
"rollup": "^2.70.0",
"rollup-plugin-node-resolve": "^3.4.0"
},
"dependencies": {
"bianco.dom-to-array": "^1.1.0"
}
}

Some files were not shown because too many files have changed in this diff Show More