@ribajs/bs4
Advanced tools
Comparing version 1.9.0-alpha.2 to 1.9.0-alpha.10
{ | ||
"name": "@ribajs/bs4", | ||
"description": "Bootstrap 4 module for Riba.js", | ||
"version": "1.9.0-alpha.2", | ||
"version": "1.9.0-alpha.10", | ||
"author": "Pascal Garber <pascal@artandcode.studio>", | ||
@@ -45,32 +45,32 @@ "contributors": [], | ||
"devDependencies": { | ||
"@babel/cli": "^7.10.5", | ||
"@babel/core": "^7.10.5", | ||
"@babel/cli": "^7.11.6", | ||
"@babel/core": "^7.11.6", | ||
"@babel/plugin-proposal-class-properties": "^7.10.4", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.10.4", | ||
"@babel/plugin-proposal-optional-chaining": "^7.10.4", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.11.0", | ||
"@babel/plugin-proposal-optional-chaining": "^7.11.0", | ||
"@babel/plugin-syntax-export-default-from": "^7.10.4", | ||
"@babel/plugin-transform-runtime": "^7.10.5", | ||
"@babel/preset-env": "^7.10.4", | ||
"@babel/plugin-transform-runtime": "^7.11.5", | ||
"@babel/preset-env": "^7.11.5", | ||
"@babel/preset-typescript": "^7.10.4", | ||
"@babel/runtime": "^7.10.5", | ||
"@babel/runtime-corejs3": "^7.10.5", | ||
"@ribajs/eslint-config": "1.9.0-alpha.2", | ||
"@ribajs/tsconfig": "1.9.0-alpha.2", | ||
"@babel/runtime": "^7.11.2", | ||
"@babel/runtime-corejs3": "^7.11.2", | ||
"@ribajs/eslint-config": "1.9.0-alpha.10", | ||
"@ribajs/tsconfig": "1.9.0-alpha.10", | ||
"@ribajs/types": "1.8.3", | ||
"@types/jest": "^26.0.4", | ||
"@typescript-eslint/eslint-plugin": "^3.6.1", | ||
"@typescript-eslint/parser": "^3.6.1", | ||
"@yarnpkg/pnpify": "^2.1.0", | ||
"babel-jest": "^26.1.0", | ||
"@types/jest": "^26.0.13", | ||
"@typescript-eslint/eslint-plugin": "^3.10.1", | ||
"@typescript-eslint/parser": "^3.10.1", | ||
"@yarnpkg/pnpify": "^2.2.1", | ||
"babel-jest": "^26.3.0", | ||
"babel-loader": "^8.1.0", | ||
"babel-plugin-array-includes": "^2.0.3", | ||
"core-js": "^3.6.5", | ||
"eslint": "^7.4.0", | ||
"eslint": "^7.8.1", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"jest": "^26.1.0", | ||
"jest": "^26.4.2", | ||
"jest-extended": "^0.11.5", | ||
"prettier": "^2.0.5", | ||
"ts-jest": "^26.1.3", | ||
"typescript": "^3.9.7", | ||
"prettier": "^2.1.1", | ||
"ts-jest": "^26.3.0", | ||
"typescript": "^4.0.2", | ||
"webpack": "^5.0.0-beta.22", | ||
@@ -80,7 +80,7 @@ "webpack-cli": "^3.3.12" | ||
"dependencies": { | ||
"@ribajs/cache": "1.9.0-alpha.1", | ||
"@ribajs/core": "1.9.0-alpha.2", | ||
"@ribajs/extras": "1.9.0-alpha.2", | ||
"@ribajs/utils": "1.9.0-alpha.2", | ||
"bootstrap": "^4.5.0", | ||
"@ribajs/cache": "1.9.0-alpha.10", | ||
"@ribajs/core": "1.9.0-alpha.10", | ||
"@ribajs/extras": "1.9.0-alpha.10", | ||
"@ribajs/utils": "1.9.0-alpha.10", | ||
"bootstrap": "^4.5.2", | ||
"popper.js": "^1.16.1" | ||
@@ -87,0 +87,0 @@ }, |
@@ -14,10 +14,12 @@ # Bootstrap 4 Module | ||
```ts | ||
import { Riba, Utils } from '@ribajs/core'; | ||
import { Riba, coreModule } from '@ribajs/core'; | ||
import { ready } from '@ribajs/utils/src/dom'; | ||
import bs4Module from '@ribajs/bs4'; | ||
const riba = new Riba(); | ||
const model = {}; | ||
riba.module.regist(coreModule); | ||
riba.module.regist(bs4Module); | ||
Utils.domIsReady(() => { | ||
ready(() => { | ||
riba.bind(document.body, model); | ||
}); | ||
``` |
@@ -9,3 +9,3 @@ import { Binder } from "@ribajs/core"; | ||
export const dropdownBinder: Binder<string> = { | ||
name: "bs4-dropdown", | ||
name: "bs4-", | ||
routine(el: HTMLElement, option: any = {}) { | ||
@@ -12,0 +12,0 @@ let toggler: HTMLButtonElement; |
import { RibaModule } from "@ribajs/core"; | ||
import * as binders from "./binders"; | ||
@@ -7,2 +6,3 @@ import * as components from "./components"; | ||
import * as services from "./services"; | ||
export const bs4Module: RibaModule = { | ||
@@ -14,3 +14,1 @@ binders, | ||
}; | ||
export default bs4Module; |
@@ -1,2 +0,2 @@ | ||
import { handleizeFormatter } from "@ribajs/core"; | ||
import { handleizeFormatter, FormatterFn } from "@ribajs/core"; | ||
import { | ||
@@ -12,2 +12,4 @@ CollapseService, | ||
const handleize = handleizeFormatter.read as FormatterFn; | ||
interface AccordionItem { | ||
@@ -171,4 +173,3 @@ title: string; | ||
protected transformTemplateAttributes(attributes: any) { | ||
attributes.handle = | ||
attributes.handle || handleizeFormatter.read(attributes.title); | ||
attributes.handle = attributes.handle || handleize(attributes.title); | ||
attributes.show = !!attributes.show; | ||
@@ -175,0 +176,0 @@ attributes.iconDirection = |
@@ -137,11 +137,2 @@ import { Component } from "@ribajs/core"; | ||
public attributeChangedCallback( | ||
name: string, | ||
oldValue: any, | ||
newValue: any, | ||
namespace: string | null | ||
) { | ||
super.attributeChangedCallback(name, oldValue, newValue, namespace); | ||
} | ||
protected connectedCallback() { | ||
@@ -148,0 +139,0 @@ super.connectedCallback(); |
@@ -125,6 +125,2 @@ import { Component } from "@ribajs/core"; | ||
protected async beforeBind() { | ||
await super.beforeBind(); | ||
} | ||
protected async afterBind() { | ||
@@ -131,0 +127,0 @@ await super.afterBind(); |
@@ -60,3 +60,3 @@ import { Component, HttpService, HttpMethod, HttpDataType } from "@ribajs/core"; | ||
public static tagName = "bs4-form"; | ||
public _debug = true; | ||
public _debug = false; | ||
protected autobind = true; | ||
@@ -63,0 +63,0 @@ |
@@ -18,3 +18,3 @@ import { Component, EventDispatcher } from "@ribajs/core"; | ||
protected autobind = true; | ||
public _debug = true; | ||
public _debug = false; | ||
@@ -21,0 +21,0 @@ protected notificationDispatcher?: EventDispatcher; |
@@ -5,2 +5,3 @@ import { TemplatesComponent } from "../templates/templates.component"; | ||
import { clone, camelCase } from "@ribajs/utils/src/type"; | ||
import { throttle, debounce } from "@ribajs/utils/src/control"; | ||
@@ -680,12 +681,15 @@ import { | ||
protected onViewChanges() { | ||
const newBreakpoint = this.getBreakpoint(); | ||
if (newBreakpoint !== this.breakpoint) { | ||
this.breakpoint = newBreakpoint; | ||
this.onBreakpointChanges(); | ||
} | ||
this.setSlidePositions(); | ||
const index = this.setCenteredSlideActive(); | ||
if (this.scope.sticky) { | ||
this.goTo(index); | ||
} | ||
throttle(() => { | ||
console.debug("onViewChanges"); | ||
const newBreakpoint = this.getBreakpoint(); | ||
if (newBreakpoint !== this.breakpoint) { | ||
this.breakpoint = newBreakpoint; | ||
this.onBreakpointChanges(); | ||
} | ||
this.setSlidePositions(); | ||
const index = this.setCenteredSlideActive(); | ||
if (this.scope.sticky) { | ||
this.goTo(index); | ||
} | ||
})(); | ||
} | ||
@@ -701,5 +705,9 @@ | ||
protected onScroll() { | ||
// this.setSlidePositions(); | ||
// this.setCenteredSlideActive(); | ||
this.resume(1000); | ||
throttle(() => { | ||
debounce(() => { | ||
// this.setSlidePositions(); | ||
// this.setCenteredSlideActive(); | ||
this.resume(1000); | ||
})(); | ||
})(); | ||
} | ||
@@ -727,3 +735,7 @@ | ||
protected onMouseUp() { | ||
this.resume(1000); | ||
throttle(() => { | ||
debounce(() => { | ||
this.resume(1000); | ||
})(); | ||
})(); | ||
} | ||
@@ -760,5 +772,3 @@ | ||
window.addEventListener("resize", this.onViewChanges.bind(this), { | ||
passive: true, | ||
}); | ||
window.addEventListener("resize", this.onViewChanges.bind(this)); | ||
@@ -827,2 +837,3 @@ // Custom event triggered by some parent components when this component changes his visibility, e.g. triggered in the bs4-tabs component | ||
protected removeEventListeners() { | ||
// TODO is this removing other throttled resize event listeners? | ||
window.removeEventListener("resize", this.onViewChanges.bind(this)); | ||
@@ -1189,3 +1200,3 @@ | ||
* Default custom Element method | ||
* Invoked when the custom element is moved to a new document. | ||
* Invoked when an attribute on the custom element changes. | ||
* @param attributeName | ||
@@ -1192,0 +1203,0 @@ * @param oldValue |
@@ -1,2 +0,2 @@ | ||
import { handleizeFormatter } from "@ribajs/core"; | ||
import { handleizeFormatter, FormatterFn } from "@ribajs/core"; | ||
import templateHorizontal from "./bs4-tabs-horizontal.component.html"; | ||
@@ -6,3 +6,6 @@ import templateVertical from "./bs4-tabs-vertical.component.html"; | ||
import { TemplatesComponent } from "../templates/templates.component"; | ||
import { throttle } from "@ribajs/utils/src/control"; | ||
const handleize = handleizeFormatter.read as FormatterFn; | ||
export interface Tab { | ||
@@ -293,9 +296,10 @@ title: string; | ||
const onResize = () => { | ||
throttle(this.onResizeEventHandler.bind(this))(); | ||
}; | ||
if (this.scope.optionTabsAutoHeight) { | ||
window.removeEventListener( | ||
"resize", | ||
this.onResizeEventHandler.bind(this) | ||
); | ||
window.addEventListener("resize", this.onResizeEventHandler.bind(this)); | ||
this.setHeight(); | ||
window.removeEventListener("resize", onResize); | ||
window.addEventListener("resize", onResize); | ||
this.onResizeEventHandler(); | ||
} | ||
@@ -317,3 +321,3 @@ } | ||
this.scope.items[index].handle || | ||
handleizeFormatter.read(this.scope.items[index].title); | ||
handleize(this.scope.items[index].title); | ||
} | ||
@@ -336,6 +340,9 @@ if (attributeName.endsWith("Handle")) { | ||
/** | ||
* Extends TemplatesComponent.transformTemplateAttributes to set the handle by the title if no handle is set | ||
*/ | ||
protected transformTemplateAttributes(attributes: any, index: number) { | ||
attributes = super.transformTemplateAttributes(attributes, index); | ||
if (!attributes.handle && attributes.title) { | ||
attributes.handle = handleizeFormatter.read(attributes.title); | ||
attributes.handle = handleize(attributes.title); | ||
} | ||
@@ -342,0 +349,0 @@ attributes.active = attributes.active || false; |
@@ -22,3 +22,3 @@ import { Component } from "@ribajs/core"; | ||
public _debug = true; | ||
public _debug = false; | ||
protected autobind = true; | ||
@@ -25,0 +25,0 @@ |
@@ -1,132 +0,4 @@ | ||
import { Component } from "@ribajs/core"; | ||
import { camelCase } from "@ribajs/utils/src/type"; | ||
// import { hasChildNodesTrim } from "@ribajs/utils/src/dom"; | ||
export type AttributeType = string; // 'string' | 'number' | 'boolean'; | ||
export interface TemplateAttribute { | ||
name: string; | ||
type?: AttributeType; | ||
required?: boolean; | ||
} | ||
export type TemplateAttributes = Array<TemplateAttribute>; | ||
export interface Scope { | ||
items: Array<any>; | ||
} | ||
export abstract class TemplatesComponent extends Component { | ||
protected templateAttributes: TemplateAttributes = []; | ||
protected templateReady = false; | ||
protected abstract scope: Scope; | ||
protected connectedCallback() { | ||
this.addItemsByTemplate(); | ||
super.connectedCallback(); | ||
this.removeTemplates(); | ||
this.bindIfReady(); | ||
} | ||
protected ready() { | ||
return super.ready() && this.templateReady; | ||
} | ||
/** | ||
* Called before getting attribute value, use this method to tramsform the attribute value if you wish | ||
* @param name Attribute name | ||
* @param value Attribute value | ||
*/ | ||
protected transformTemplateAttribute( | ||
name: string, | ||
value: any, | ||
type?: AttributeType | ||
) { | ||
switch (type) { | ||
case "number": | ||
value = Number(value); | ||
break; | ||
case "boolean": | ||
value = value === "true"; | ||
break; | ||
case "string": | ||
default: | ||
break; | ||
} | ||
return value; | ||
} | ||
/** | ||
* Called before getting all attribute values, use this method to tramsform the attribute values if you wish | ||
* @param attributes | ||
*/ | ||
protected transformTemplateAttributes(attributes: any, index: number) { | ||
attributes.index = attributes.index || index; | ||
return attributes; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
protected getTemplateAttributes(tpl: HTMLTemplateElement, index: number) { | ||
const attributes: any = {}; | ||
for (const attribute of this.templateAttributes) { | ||
const attrValue = this.transformTemplateAttribute( | ||
attribute.name, | ||
tpl.getAttribute(attribute.name) | ||
); | ||
if (attribute.required && !attrValue) { | ||
console.error( | ||
new Error(`template "${attribute.name}" attribute is required!`) | ||
); | ||
return; | ||
} | ||
attributes[camelCase(attribute.name)] = attrValue; | ||
} | ||
return this.transformTemplateAttributes(attributes, index); | ||
} | ||
protected addItemByTemplate(tpl: HTMLTemplateElement, index: number) { | ||
const attributes = this.getTemplateAttributes(tpl, index); | ||
const content = tpl.innerHTML; | ||
this.scope.items.push({ ...attributes, content }); | ||
} | ||
protected addItemsByTemplate() { | ||
const templates = this.el.querySelectorAll<HTMLTemplateElement>("template"); | ||
for (let index = 0; index < templates.length; index++) { | ||
const tpl = templates[index]; | ||
this.addItemByTemplate(tpl, index); | ||
} | ||
this.templateReady = true; | ||
} | ||
protected removeTemplates() { | ||
const templates = this.el.querySelectorAll<HTMLTemplateElement>("template"); | ||
for (let index = 0; index < templates.length; index++) { | ||
const tpl = templates[index]; | ||
this.el.removeChild(tpl); | ||
} | ||
} | ||
protected hasOnlyTemplateChilds() { | ||
let allAreTemplates = true; | ||
for (let index = 0; index < this.el.childNodes.length; index++) { | ||
const child = this.el.childNodes[index]; | ||
allAreTemplates = | ||
allAreTemplates && | ||
(child.nodeName === "TEMPLATE" || child.nodeName === "#text"); | ||
} | ||
return allAreTemplates; | ||
} | ||
// protected template() { | ||
// // Only set the component template if there no childs or the childs are templates | ||
// if (!hasChildNodesTrim(this.el) || this.hasOnlyTemplateChilds()) { | ||
// return template; | ||
// } else { | ||
// return null; | ||
// } | ||
// } | ||
} | ||
/** | ||
* @deprecated Moved abstract TemplatesComponent to core module | ||
*/ | ||
export * from "@ribajs/core/src/components/templates/templates.component"; |
@@ -8,2 +8,2 @@ export * from "./services"; | ||
export * from "./constants"; | ||
export * from "./bs4.module"; | ||
export { bs4Module } from "./bs4.module"; |
@@ -200,3 +200,3 @@ import { CarouselOption } from "../interfaces/carousel-option"; | ||
if (this._config && this._config.interval && !this._isPaused) { | ||
this._interval = setInterval( | ||
this._interval = window.setInterval( | ||
(document.visibilityState ? this.nextWhenVisible : this.next).bind( | ||
@@ -292,4 +292,4 @@ this | ||
if (this._config.keyboard) { | ||
EventHandler.on<KeyboardEvent>(this._element, Event.KEYDOWN, (event) => | ||
this._keydown(event) | ||
EventHandler.on(this._element, Event.KEYDOWN, (event) => | ||
this._keydown(event as KeyboardEvent) | ||
); | ||
@@ -299,11 +299,7 @@ } | ||
if (this._config.pause === "hover") { | ||
EventHandler.on( | ||
this._element, | ||
Event.MOUSEENTER, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => this.pause(event) | ||
EventHandler.on(this._element, Event.MOUSEENTER, (event: Event) => | ||
this.pause(event as TouchEvent & MouseEvent & PointerEvent) | ||
); | ||
EventHandler.on( | ||
this._element, | ||
Event.MOUSELEAVE, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => this.cycle(event) | ||
EventHandler.on(this._element, Event.MOUSELEAVE, (event: Event) => | ||
this.cycle(event) | ||
); | ||
@@ -371,7 +367,4 @@ } | ||
).forEach((itemImg) => { | ||
EventHandler.on( | ||
itemImg, | ||
Event.DRAG_START, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => | ||
event.preventDefault() | ||
EventHandler.on(itemImg, Event.DRAG_START, (event: Event) => | ||
event.preventDefault() | ||
); | ||
@@ -381,11 +374,7 @@ }); | ||
if (this._pointerEvent) { | ||
EventHandler.on( | ||
this._element, | ||
Event.POINTERDOWN, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => start(event) | ||
EventHandler.on(this._element, Event.POINTERDOWN, (event: Event) => | ||
start(event as TouchEvent & MouseEvent & PointerEvent) | ||
); | ||
EventHandler.on( | ||
this._element, | ||
Event.POINTERUP, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => end(event) | ||
EventHandler.on(this._element, Event.POINTERUP, (event: Event) => | ||
end(event as TouchEvent & MouseEvent & PointerEvent) | ||
); | ||
@@ -395,16 +384,10 @@ | ||
} else { | ||
EventHandler.on( | ||
this._element, | ||
Event.TOUCHSTART, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => start(event) | ||
EventHandler.on(this._element, Event.TOUCHSTART, (event: Event) => | ||
start(event as TouchEvent & MouseEvent & PointerEvent) | ||
); | ||
EventHandler.on( | ||
this._element, | ||
Event.TOUCHMOVE, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => move(event) | ||
EventHandler.on(this._element, Event.TOUCHMOVE, (event: Event) => | ||
move(event as TouchEvent & MouseEvent & PointerEvent) | ||
); | ||
EventHandler.on( | ||
this._element, | ||
Event.TOUCHEND, | ||
(event: TouchEvent & MouseEvent & PointerEvent) => end(event) | ||
EventHandler.on(this._element, Event.TOUCHEND, (event: Event) => | ||
end(event as TouchEvent & MouseEvent & PointerEvent) | ||
); | ||
@@ -411,0 +394,0 @@ } |
@@ -66,14 +66,23 @@ /** | ||
class Data { | ||
public static setData(instance: HTMLElement, key: string, data: any) { | ||
mapData.set(instance, key, data); | ||
} | ||
public static getData(instance: HTMLElement, key: string) { | ||
return mapData.get(instance, key); | ||
} | ||
public static removeData(instance: HTMLElement, key: string) { | ||
mapData.delete(instance, key); | ||
} | ||
export const setData = (instance: HTMLElement, key: string, data: any) => { | ||
mapData.set(instance, key, data); | ||
}; | ||
export const getData = (instance: HTMLElement, key: string) => { | ||
return mapData.get(instance, key); | ||
}; | ||
export const removeData = (instance: HTMLElement, key: string) => { | ||
mapData.delete(instance, key); | ||
}; | ||
/** | ||
* @deprecated Import the methods directly instead of this class | ||
*/ | ||
export class Data { | ||
public static setData = setData; | ||
public static getData = getData; | ||
public static removeData = removeData; | ||
} | ||
export default Data; |
/** | ||
* see see https://github.com/twbs/bootstrap/blob/master/js/src/dom/event-handler.js | ||
*/ | ||
class EventHandler { | ||
public static on<T>( | ||
element: HTMLElement | Document | Window, | ||
eventName: string, | ||
handler: EventListenerOrEventListenerObject | ||
) { | ||
return element.addEventListener(eventName as any, handler, {}); | ||
} | ||
public static one<T>( | ||
element: HTMLElement | Document | Window, | ||
eventName: string, | ||
handler: EventListenerOrEventListenerObject | ||
) { | ||
return element.addEventListener(eventName as any, handler, { once: true }); | ||
} | ||
export const on = ( | ||
element: Element | HTMLElement | Document | Window, | ||
eventName: string, | ||
handler: EventListenerOrEventListenerObject | ||
) => { | ||
return element.addEventListener(eventName as any, handler, {}); | ||
}; | ||
public static off<T>( | ||
element: HTMLElement | Document | Window, | ||
originalTypeEvent: string, | ||
handler: EventListenerOrEventListenerObject | ||
) { | ||
return element.removeEventListener(originalTypeEvent as any, handler); | ||
} | ||
export const one = ( | ||
element: Element | HTMLElement | Document | Window, | ||
eventName: string, | ||
handler: EventListenerOrEventListenerObject | ||
) => { | ||
return element.addEventListener(eventName as any, handler, { once: true }); | ||
}; | ||
public static trigger<T = any>( | ||
element: HTMLElement | Document | Window, | ||
eventName: string, | ||
extraParameters: any = {} | ||
) { | ||
const event = new CustomEvent<T>(eventName, { | ||
detail: extraParameters, | ||
}); | ||
element.dispatchEvent(event); | ||
return event; | ||
} | ||
export const off = ( | ||
element: Element | HTMLElement | Document | Window, | ||
originalTypeEvent: string, | ||
handler: EventListenerOrEventListenerObject | ||
) => { | ||
return element.removeEventListener(originalTypeEvent as any, handler); | ||
}; | ||
export const trigger = <T = any>( | ||
element: Element | HTMLElement | Document | Window, | ||
eventName: string, | ||
extraParameters: any = {} | ||
) => { | ||
const event = new CustomEvent<T>(eventName, { | ||
detail: extraParameters, | ||
}); | ||
element.dispatchEvent(event); | ||
return event; | ||
}; | ||
/** | ||
* @deprecated Import the methods directly instead of this class | ||
*/ | ||
export class EventHandler { | ||
public static on = on; | ||
public static one = one; | ||
public static off = off; | ||
public static trigger = trigger; | ||
} | ||
export default EventHandler; |
export * from "./data"; | ||
export * from "./event-handler"; | ||
export * from "./manipulator"; | ||
export * from "./selector-engine"; |
@@ -17,76 +17,96 @@ /** | ||
const NODE_TEXT = 3; | ||
export const NODE_TEXT = 3; | ||
class SelectorEngine { | ||
public static matches( | ||
element: HTMLElement | (Node & ParentNode), | ||
selector: string | ||
export const matches = ( | ||
element: HTMLElement | (Node & ParentNode), | ||
selector: string | ||
) => { | ||
return Element.prototype.matches.call(element, selector); | ||
}; | ||
export const find = (selector: string, element = document.documentElement) => { | ||
return Element.prototype.querySelectorAll.call( | ||
element, | ||
selector | ||
) as NodeListOf<HTMLElement>; | ||
}; | ||
export const findOne = ( | ||
selector: string, | ||
element = document.documentElement | ||
) => { | ||
return Element.prototype.querySelector.call( | ||
element, | ||
selector | ||
) as HTMLElement | null; | ||
}; | ||
export const children = (element: HTMLElement, selector: string) => { | ||
const children = Utils.makeArray(element.children); | ||
return children.filter((child) => matches(child, selector)); | ||
}; | ||
export const parents = (element: HTMLElement, selector: string) => { | ||
const parents = []; | ||
let ancestor = element.parentNode; | ||
while ( | ||
ancestor && | ||
ancestor.nodeType === Node.ELEMENT_NODE && | ||
ancestor.nodeType !== NODE_TEXT | ||
) { | ||
return Element.prototype.matches.call(element, selector); | ||
} | ||
if (matches(ancestor, selector)) { | ||
parents.push(ancestor); | ||
} | ||
public static find(selector: string, element = document.documentElement) { | ||
return Element.prototype.querySelectorAll.call( | ||
element, | ||
selector | ||
) as NodeListOf<HTMLElement>; | ||
ancestor = ancestor.parentNode; | ||
} | ||
public static findOne(selector: string, element = document.documentElement) { | ||
return Element.prototype.querySelector.call( | ||
element, | ||
selector | ||
) as HTMLElement | null; | ||
} | ||
return parents; | ||
}; | ||
public static children(element: HTMLElement, selector: string) { | ||
const children = Utils.makeArray(element.children); | ||
return children.filter((child) => this.matches(child, selector)); | ||
} | ||
export const closest = (element: HTMLElement, selector: string) => { | ||
return Element.prototype.closest.call(element, selector); | ||
}; | ||
public static parents(element: HTMLElement, selector: string) { | ||
const parents = []; | ||
export const prev = (element: HTMLElement, selector: string) => { | ||
const siblings = []; | ||
let ancestor = element.parentNode; | ||
let previous = element.previousSibling; | ||
while ( | ||
ancestor && | ||
ancestor.nodeType === Node.ELEMENT_NODE && | ||
ancestor.nodeType !== NODE_TEXT | ||
) { | ||
if (this.matches(ancestor, selector)) { | ||
parents.push(ancestor); | ||
} | ||
ancestor = ancestor.parentNode; | ||
while ( | ||
previous && | ||
previous.nodeType === Node.ELEMENT_NODE && | ||
previous.nodeType !== NODE_TEXT | ||
) { | ||
if (matches(previous as HTMLElement, selector)) { | ||
siblings.push(previous); | ||
} | ||
return parents; | ||
previous = previous.previousSibling; | ||
} | ||
public static closest(element: HTMLElement, selector: string) { | ||
return Element.prototype.closest.call(element, selector); | ||
} | ||
return siblings; | ||
}; | ||
public static prev(element: HTMLElement, selector: string) { | ||
const siblings = []; | ||
/** | ||
* @deprecated Import the methods directly instead of this class | ||
*/ | ||
export class SelectorEngine { | ||
public static matches = matches; | ||
let previous = element.previousSibling; | ||
public static find = find; | ||
while ( | ||
previous && | ||
previous.nodeType === Node.ELEMENT_NODE && | ||
previous.nodeType !== NODE_TEXT | ||
) { | ||
if (this.matches(previous as HTMLElement, selector)) { | ||
siblings.push(previous); | ||
} | ||
public static findOne = findOne; | ||
previous = previous.previousSibling; | ||
} | ||
public static children = children; | ||
return siblings; | ||
} | ||
public static parents = parents; | ||
public static closest = closest; | ||
public static prev = prev; | ||
} | ||
export default SelectorEngine; |
import Popper from "popper.js"; // /dist/umd/popper | ||
import { Utils } from "./utils.service"; | ||
import { isElement, typeCheckConfig } from "./utils.service"; | ||
/** | ||
@@ -7,3 +7,3 @@ * -------------------------------------------------------------------------- | ||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
* @see https://raw.githubusercontent.com/twbs/bootstrap/v4-dev/js/src/dropdown.js | ||
* @see https://github.com/twbs/bootstrap/blob/main/js/src/dropdown.js | ||
* -------------------------------------------------------------------------- | ||
@@ -261,3 +261,3 @@ */ | ||
referenceElement = parent as HTMLElement; | ||
} else if (Utils.isElement(this._config.reference)) { | ||
} else if (isElement(this._config.reference)) { | ||
referenceElement = this._config.reference; | ||
@@ -303,4 +303,4 @@ | ||
this._element.removeAttribute("data-" + DATA_KEY); | ||
delete this._element; | ||
delete this._menu; | ||
// delete this._element; | ||
// delete this._menu; | ||
if (this._popper !== null) { | ||
@@ -350,3 +350,3 @@ this._popper.destroy(); | ||
Utils.typeCheckConfig(NAME, config, DropdownService.DefaultType); | ||
typeCheckConfig(NAME, config, DropdownService.DefaultType); | ||
@@ -353,0 +353,0 @@ return config; |
@@ -6,3 +6,7 @@ export * from "./dom"; | ||
export { ModalService } from "./modal.service"; | ||
export * from "./tooltip.service"; | ||
export * from "./popover.service"; | ||
export * from "./sanitizer"; | ||
export { ToastService } from "./toast.service"; | ||
export { TooltipService } from "./tooltip.service"; | ||
export * from "./utils.service"; |
import { Utils as RibaUtils } from "@ribajs/core"; | ||
export const MILLISECONDS_MULTIPLIER = 1000; | ||
@@ -7,210 +6,240 @@ export const TRANSITION_END = "transitionend"; | ||
/** | ||
* | ||
* @see https://github.com/twbs/bootstrap/blob/master/js/src/util/index.js | ||
* Shoutout AngusCroll (https://goo.gl/pxwQGp) | ||
* @param obj | ||
*/ | ||
export class Utils extends RibaUtils { | ||
/** | ||
* Shoutout AngusCroll (https://goo.gl/pxwQGp) | ||
* @param obj | ||
*/ | ||
public static toType(obj: any) { | ||
const matches = {}.toString.call(obj).match(/\s([a-z]+)/i); | ||
return matches ? matches[1].toLowerCase() : null; | ||
export const toType = (obj: any) => { | ||
const matches = {}.toString.call(obj).match(/\s([a-z]+)/i); | ||
return matches ? matches[1].toLowerCase() : null; | ||
}; | ||
export const getSelector = (element: HTMLElement) => { | ||
let selector = element.getAttribute("data-target"); | ||
if (!selector || selector === "#") { | ||
const hrefAttr = element.getAttribute("href"); | ||
selector = hrefAttr && hrefAttr !== "#" ? hrefAttr.trim() : null; | ||
} | ||
public static getSelector(element: HTMLElement) { | ||
let selector = element.getAttribute("data-target"); | ||
return selector; | ||
}; | ||
if (!selector || selector === "#") { | ||
const hrefAttr = element.getAttribute("href"); | ||
export const getSelectorFromElement = (element: HTMLElement) => { | ||
const selector = Utils.getSelector(element); | ||
selector = hrefAttr && hrefAttr !== "#" ? hrefAttr.trim() : null; | ||
} | ||
if (selector) { | ||
return document.querySelector(selector) ? selector : null; | ||
} | ||
return selector; | ||
return null; | ||
}; | ||
export const getElementFromSelector = (element: HTMLElement) => { | ||
const selector = Utils.getSelector(element); | ||
return (selector | ||
? document.querySelector(selector) | ||
: null) as HTMLElement | null; | ||
}; | ||
export const getTransitionDurationFromElement = (element: HTMLElement) => { | ||
if (!element) { | ||
return 0; | ||
} | ||
public static getSelectorFromElement(element: HTMLElement) { | ||
const selector = Utils.getSelector(element); | ||
// Get transition-duration of the element | ||
let { transitionDuration, transitionDelay } = window.getComputedStyle( | ||
element | ||
); | ||
if (selector) { | ||
return document.querySelector(selector) ? selector : null; | ||
} | ||
const floatTransitionDuration = parseFloat(transitionDuration); | ||
const floatTransitionDelay = parseFloat(transitionDelay); | ||
return null; | ||
// Return 0 if element or transition duration is not found | ||
if (!floatTransitionDuration && !floatTransitionDelay) { | ||
return 0; | ||
} | ||
public static getElementFromSelector(element: HTMLElement) { | ||
const selector = Utils.getSelector(element); | ||
// If multiple durations are defined, take the first | ||
transitionDuration = transitionDuration.split(",")[0]; | ||
transitionDelay = transitionDelay.split(",")[0]; | ||
return (selector | ||
? document.querySelector(selector) | ||
: null) as HTMLElement | null; | ||
return ( | ||
(parseFloat(transitionDuration) + parseFloat(transitionDelay)) * | ||
MILLISECONDS_MULTIPLIER | ||
); | ||
}; | ||
export const triggerTransitionEnd = (element: HTMLElement) => { | ||
const evt = document.createEvent("HTMLEvents"); | ||
evt.initEvent(TRANSITION_END, true, true); | ||
element.dispatchEvent(evt); | ||
}; | ||
export const isElement = (obj: Element | Element[]) => { | ||
return ((obj as Element[])[0] || (obj as Element)).nodeType; | ||
}; | ||
export const emulateTransitionEnd = ( | ||
element: HTMLElement, | ||
duration: number | ||
) => { | ||
let called = false; | ||
const durationPadding = 5; | ||
const emulatedDuration = duration + durationPadding; | ||
function listener() { | ||
called = true; | ||
element.removeEventListener(TRANSITION_END, listener); | ||
} | ||
public static getTransitionDurationFromElement(element: HTMLElement) { | ||
if (!element) { | ||
return 0; | ||
element.addEventListener(TRANSITION_END, listener); | ||
setTimeout(() => { | ||
if (!called) { | ||
Utils.triggerTransitionEnd(element); | ||
} | ||
}, emulatedDuration); | ||
}; | ||
// Get transition-duration of the element | ||
let { transitionDuration, transitionDelay } = window.getComputedStyle( | ||
element | ||
); | ||
/** | ||
* | ||
* @param componentName | ||
* @param config | ||
* @param configTypes | ||
*/ | ||
export const typeCheckConfig = ( | ||
componentName: string, | ||
config: any, | ||
configTypes: any | ||
) => { | ||
for (const property in configTypes) { | ||
if (Object.prototype.hasOwnProperty.call(configTypes, property)) { | ||
const expectedTypes = configTypes[property]; | ||
const value = config[property]; | ||
const valueType = | ||
value && Utils.isElement(value) ? "element" : Utils.toType(value); | ||
const floatTransitionDuration = parseFloat(transitionDuration); | ||
const floatTransitionDelay = parseFloat(transitionDelay); | ||
// Return 0 if element or transition duration is not found | ||
if (!floatTransitionDuration && !floatTransitionDelay) { | ||
return 0; | ||
if (!valueType || !new RegExp(expectedTypes).test(valueType)) { | ||
throw new Error( | ||
`${componentName.toUpperCase()}: ` + | ||
`Option "${property}" provided type "${valueType}" ` + | ||
`but expected type "${expectedTypes}".` | ||
); | ||
} | ||
} | ||
} | ||
}; | ||
// If multiple durations are defined, take the first | ||
transitionDuration = transitionDuration.split(",")[0]; | ||
transitionDelay = transitionDelay.split(",")[0]; | ||
export const makeArray = ( | ||
nodeList: NodeList | HTMLCollection | ||
): HTMLElement[] => { | ||
if (!nodeList) { | ||
return []; | ||
} | ||
return [].slice.call(nodeList); | ||
}; | ||
export const isVisible = (element: HTMLElement) => { | ||
if (!element) { | ||
return false; | ||
} | ||
if ( | ||
element.style && | ||
element.parentNode && | ||
(element.parentNode as HTMLElement).style | ||
) { | ||
const elementStyle = getComputedStyle(element); | ||
const parentNodeStyle = getComputedStyle(element.parentNode as HTMLElement); | ||
return ( | ||
(parseFloat(transitionDuration) + parseFloat(transitionDelay)) * | ||
MILLISECONDS_MULTIPLIER | ||
elementStyle.display !== "none" && | ||
parentNodeStyle.display !== "none" && | ||
elementStyle.visibility !== "hidden" | ||
); | ||
} | ||
public static triggerTransitionEnd(element: HTMLElement) { | ||
const evt = document.createEvent("HTMLEvents"); | ||
return false; | ||
}; | ||
evt.initEvent(TRANSITION_END, true, true); | ||
element.dispatchEvent(evt); | ||
export const findShadowRoot = ( | ||
element: HTMLElement | (Node & ParentNode) | ||
): HTMLElement | (Node & ParentNode) | null => { | ||
if (!document.documentElement.attachShadow) { | ||
return null; | ||
} | ||
public static isElement(obj: Element | Element[]) { | ||
return ((obj as Element[])[0] || (obj as Element)).nodeType; | ||
// Can find the shadow root otherwise it'll return the document | ||
if (typeof element.getRootNode === "function") { | ||
const root = element.getRootNode(); | ||
return root instanceof ShadowRoot ? root : null; | ||
} | ||
public static emulateTransitionEnd = ( | ||
element: HTMLElement, | ||
duration: number | ||
) => { | ||
let called = false; | ||
const durationPadding = 5; | ||
const emulatedDuration = duration + durationPadding; | ||
function listener() { | ||
called = true; | ||
element.removeEventListener(TRANSITION_END, listener); | ||
} | ||
if (element instanceof ShadowRoot) { | ||
return element; | ||
} | ||
element.addEventListener(TRANSITION_END, listener); | ||
setTimeout(() => { | ||
if (!called) { | ||
Utils.triggerTransitionEnd(element); | ||
} | ||
}, emulatedDuration); | ||
// when we don't find a shadow root | ||
if (!element.parentNode) { | ||
return null; | ||
} | ||
return Utils.findShadowRoot(element.parentNode); | ||
}; | ||
export const noop = () => { | ||
return function () { | ||
/** nothing */ | ||
}; | ||
}; | ||
/** | ||
* | ||
* @param componentName | ||
* @param config | ||
* @param configTypes | ||
*/ | ||
public static typeCheckConfig( | ||
componentName: string, | ||
config: any, | ||
configTypes: any | ||
) { | ||
for (const property in configTypes) { | ||
if (Object.prototype.hasOwnProperty.call(configTypes, property)) { | ||
const expectedTypes = configTypes[property]; | ||
const value = config[property]; | ||
const valueType = | ||
value && Utils.isElement(value) ? "element" : Utils.toType(value); | ||
export const reflow = (element: HTMLElement) => { | ||
return element.offsetHeight; | ||
}; | ||
if (!valueType || !new RegExp(expectedTypes).test(valueType)) { | ||
throw new Error( | ||
`${componentName.toUpperCase()}: ` + | ||
`Option "${property}" provided type "${valueType}" ` + | ||
`but expected type "${expectedTypes}".` | ||
); | ||
} | ||
} | ||
} | ||
export const getjQuery = () => { | ||
const { jQuery } = window as any; | ||
if (jQuery && !document.body.hasAttribute("data-no-jquery")) { | ||
return jQuery; | ||
} | ||
public static makeArray(nodeList: NodeList | HTMLCollection): HTMLElement[] { | ||
if (!nodeList) { | ||
return []; | ||
} | ||
return null; | ||
}; | ||
return [].slice.call(nodeList); | ||
} | ||
/** | ||
* @deprecated Import the methods directly instead of this Utils class | ||
* @see https://github.com/twbs/bootstrap/blob/master/js/src/util/index.js | ||
*/ | ||
export class Utils extends RibaUtils { | ||
public static toType = toType; | ||
public static isVisible(element: HTMLElement) { | ||
if (!element) { | ||
return false; | ||
} | ||
public static getSelector = getSelector; | ||
if ( | ||
element.style && | ||
element.parentNode && | ||
(element.parentNode as HTMLElement).style | ||
) { | ||
const elementStyle = getComputedStyle(element); | ||
const parentNodeStyle = getComputedStyle( | ||
element.parentNode as HTMLElement | ||
); | ||
public static getSelectorFromElement = getSelectorFromElement; | ||
return ( | ||
elementStyle.display !== "none" && | ||
parentNodeStyle.display !== "none" && | ||
elementStyle.visibility !== "hidden" | ||
); | ||
} | ||
public static getElementFromSelector = getElementFromSelector; | ||
return false; | ||
} | ||
public static getTransitionDurationFromElement = getTransitionDurationFromElement; | ||
public static findShadowRoot( | ||
element: HTMLElement | (Node & ParentNode) | ||
): HTMLElement | (Node & ParentNode) | null { | ||
if (!document.documentElement.attachShadow) { | ||
return null; | ||
} | ||
public static triggerTransitionEnd = triggerTransitionEnd; | ||
// Can find the shadow root otherwise it'll return the document | ||
if (typeof element.getRootNode === "function") { | ||
const root = element.getRootNode(); | ||
return root instanceof ShadowRoot ? root : null; | ||
} | ||
public static isElement = isElement; | ||
if (element instanceof ShadowRoot) { | ||
return element; | ||
} | ||
public static emulateTransitionEnd = emulateTransitionEnd; | ||
// when we don't find a shadow root | ||
if (!element.parentNode) { | ||
return null; | ||
} | ||
public static typeCheckConfig = typeCheckConfig; | ||
return Utils.findShadowRoot(element.parentNode); | ||
} | ||
public static makeArray = makeArray; | ||
public static noop() { | ||
return function () { | ||
/** nothing */ | ||
}; | ||
} | ||
public static isVisible = isVisible; | ||
public static reflow(element: HTMLElement) { | ||
return element.offsetHeight; | ||
} | ||
public static findShadowRoot = findShadowRoot; | ||
public static getjQuery = () => { | ||
const { jQuery } = window as any; | ||
public static noop = noop; | ||
if (jQuery && !document.body.hasAttribute("data-no-jquery")) { | ||
return jQuery; | ||
} | ||
public static reflow = reflow; | ||
return null; | ||
}; | ||
public static getjQuery = getjQuery; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
306293
106
8338
25
+ Added@ribajs/cache@1.9.0-alpha.10(transitive)
+ Added@ribajs/core@1.9.0-alpha.10(transitive)
+ Added@ribajs/extras@1.9.0-alpha.10(transitive)
+ Added@ribajs/utils@1.9.0-alpha.10(transitive)
- Removed@ribajs/cache@1.9.0-alpha.1(transitive)
- Removed@ribajs/core@1.9.0-alpha.2(transitive)
- Removed@ribajs/extras@1.9.0-alpha.2(transitive)
- Removed@ribajs/utils@1.9.0-alpha.2(transitive)
Updated@ribajs/cache@1.9.0-alpha.10
Updated@ribajs/core@1.9.0-alpha.10
Updated@ribajs/utils@1.9.0-alpha.10
Updatedbootstrap@^4.5.2