Socket
Socket
Sign inDemoInstall

@pap-it/system-base

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pap-it/system-base - npm Package Compare versions

Comparing version 1.0.11 to 1.0.12

441

dist/src/component.js

@@ -1,440 +0,1 @@

import { __decorate } from "tslib";
import { NextParent, property, debounce, convertFromString } from "@pap-it/system-utils";
// NOTE should this be there?
// export interface Base extends HTMLElement { }
export class Base extends HTMLElement {
// class functions
constructor(config) {
super();
this.callAfterUpdate = [];
this.render_mode = 'smart';
this.render_style_mode = 'lazy';
this.hasrendered = false;
this.attributeinit = false;
this.delayedAttributes = {};
this.connected = false;
this.originalHTML = "";
this.hasFocus = false;
// event handlers
this.handleblur = () => {
this.hasFocus = false;
};
this.handlefocus = () => {
this.hasFocus = true;
};
this.originalHTML = this.outerHTML;
if (!(config === null || config === void 0 ? void 0 : config.noblur))
this.addEventListener('blur', this.handleblur);
if (!(config === null || config === void 0 ? void 0 : config.nofocus))
this.addEventListener('focus', this.handlefocus);
this.styleComperator = document.createElement('style');
this.templateComperator = document.createElement('template');
this.debouncedRequestUpdate = debounce(this.requestUpdate, 100);
this.attachShadow({ mode: 'open', ...(config ? config : {}) });
// TODO should implement the function that calls then if fails calls later too
this.updateAttribute = debounce(this.updateAttribute, 10);
this.callAfterUpdate.push(this.firstUpdate);
return this;
}
connectedCallback() {
this.attributeinit = false;
this.debouncedRequestUpdate();
this.connected = true;
this.dispatchEvent(new Event('connected'));
}
disconnectedCallback() {
this.connected = false;
this.dispatchEvent(new Event('disconnected'));
}
attributeChangedCallback(name, oldValue, newValue) {
// if (this.tagName === "PAP-INPUT") console.log(name, oldValue === newValue)
if (oldValue === newValue) {
delete this.delayedAttributes[name];
return;
}
// implement something
if (!this.delayedAttributes[name]) {
// console.log('delayed attribute found', name, Base.Properties[name])
if (Base.Properties[name]) {
// (this as any)[name + "internal"] = true;
this[Base.Properties[name].propertyKey] = convertFromString(newValue, Base.Properties[name].type);
}
else {
console.warn("[BASE]: not delayed not prop options", name);
}
}
else {
// this[Base.Properties[name].propertyKey as keyof this] = convertFromString(newValue, Base.Properties[name].type);
delete this.delayedAttributes[name];
}
}
firstUpdate() {
this.hasrendered = true;
this.updateAttribute();
}
getProperties() {
const properties = {};
for (let attribute in Base.Properties) {
properties[Base.Properties[attribute].propertyKey] = Base.Properties[attribute];
}
return properties;
}
getStyle() {
var _a;
// Get the constructor of the child class
const childConstructor = this.constructor;
// Access the static property on the child class
const styles = [
...((_a = childConstructor.styles) !== null && _a !== void 0 ? _a : []),
...(typeof childConstructor.style === "string" ? [childConstructor.style] : []),
];
return styles.join(' ');
}
querySelector(selector) {
if (!selector) {
console.log('empty string');
return null;
}
if (this.shadowRoot)
return this.shadowRoot.querySelector(selector);
return null;
}
shadow_closest(selector) {
let parent = NextParent(this);
while (parent) {
// check if parent is our selector
const closest = parent.closest(selector);
if (closest)
return closest;
const target = parent.querySelector(selector);
if (target)
return target;
if (parent === document.documentElement)
break;
parent = NextParent(parent);
}
}
requestUpdate() {
if (!this.shadowRoot) {
// TODO wait until shadowRoot is here !
return;
}
const initalrender = this.shadowRoot.innerHTML === "";
this.renderStyle();
const content = this.render();
if (initalrender || this.render_mode === "greedy") {
this.flushHTML(this.shadowRoot);
this.renderContent(content, this.shadowRoot);
}
else {
this.renderHTML(content);
}
let info;
const reverse = this.callAfterUpdate.reverse();
while (info = reverse.pop()) {
if (typeof info === "object") {
info.callback.call(this, ...info.args);
}
if (info instanceof Function) {
info.call(this);
}
}
this.callAfterUpdate = [];
}
debouncedRequestUpdate() { }
render(config) {
return 'Hello From Base Class';
}
// helper functions
initAttributes() {
if (this.attributeinit)
return;
this.attributeinit = true;
// we need to check if we have any initial values ?
const a = this.attributes;
for (let i = 0; i < a.length; i++) {
const name = a[i].name;
if (Base.Properties[name]) {
let value = a[i].value;
if (value === "")
value = "true";
this[Base.Properties[name].propertyKey] = convertFromString(value, Base.Properties[name].type);
}
}
}
updateAttribute() {
if (this.hasrendered) {
// we call this each time but it will probably just cancel anyway..
this.initAttributes();
for (let name in this.delayedAttributes) {
const value = this.delayedAttributes[name];
if (value === undefined)
this.removeAttribute(name);
else {
this.setAttribute(name, value);
}
}
}
}
flushHTML(node) {
node.childNodes.forEach(child => {
if (child.nodeName !== "STYLE") {
node.removeChild(child);
}
});
}
renderStyle() {
if (!this.shadowRoot)
return;
// check if style is different
let targetElement = this.shadowRoot.querySelector('style');
if (!targetElement) {
targetElement = document.createElement("style");
targetElement.innerHTML = this.getStyle();
this.shadowRoot.appendChild(targetElement);
return;
}
// NOTE most cases would never require style to be changed
if (this.render_style_mode === "lazy")
return;
this.styleComperator.innerHTML = this.getStyle();
if (this.styleComperator.innerHTML !== targetElement.innerHTML) {
targetElement.innerHTML = this.styleComperator.innerHTML;
}
}
/**
* this element is made so we can find if the current element should be inserted infront a element
* so we dont just blindly append to end of parent using the appendChild
*
* so we need to traverser the next sibling and check if it exists in the real element
*/
getNextElement(clone, node) {
if (node.nextElementSibling) {
const path = this.getComposedPath(clone, node.nextElementSibling);
const shadowNode = this.querySelector(path.join(" > "));
if (shadowNode) {
return shadowNode;
}
return this.getNextElement(clone, node.nextElementSibling);
}
return null;
}
renderHTML(content) {
if (!this.shadowRoot)
return;
this.hasrendered = true;
// flush the html
while (this.templateComperator.firstChild) {
this.templateComperator.removeChild(this.templateComperator.firstChild);
}
this.templateComperator.appendChild(this.styleComperator);
// NOTE we render to template first
// and then we clone, which results in loss of event stuff (this)
this.renderContent(content, this.templateComperator);
// TODO figure out the reason why we clone, there was a very strong reason but I dont remember..
// akward but it was the previous mentioned comment no? (that)
const clone = this.templateComperator.cloneNode(true);
clone.querySelectorAll('*:not(style)').forEach(node => {
const path = this.getComposedPath(clone, node);
const shadowNode = this.querySelector(path.join(" > "));
if (!shadowNode) {
// we need to traverse up the path until we find one node then insert until the end
let shadowtarget = this.shadowRoot;
let target = node;
if (path.length > 1) {
for (let i = path.length - 1; i >= 0; i--) { // we need not to start at end as this case has just been checked
const _shadownode = this.querySelector(path.slice(0, i).join(' > '));
if (_shadownode) {
// we found a node, now we can start inserting until we reach end of path (i==path.lenght - 1)
shadowtarget = _shadownode;
break;
}
else {
target = node.parentElement;
}
}
}
if (target) {
// we check if we can insert it before a element
// this function selects this element (if exists by traversing the next until its found in targetShadow)
const nextElement = this.getNextElement(clone, node);
if (nextElement) {
shadowtarget === null || shadowtarget === void 0 ? void 0 : shadowtarget.insertBefore(target, nextElement);
}
else {
shadowtarget === null || shadowtarget === void 0 ? void 0 : shadowtarget.appendChild(target);
}
// reapplyEventListeners(target);
}
else {
console.error('[ERROR] this case should not happen');
console.log({ shadowtarget, node, target, path });
}
}
else {
// check if it has changed !
// need to keep track of which we already looked at so we know which to remove later !
// const passedAttributes:string[] = [];
// attributes first
// look if changes or new attributes added
for (let i = 0; i < node.attributes.length; i++) {
const name = node.attributes[i].name;
const value = node.attributes[i].value;
// passedAttributes.push(name);
const shadowValue = shadowNode.getAttribute(name);
if (shadowValue !== value) {
// TODO mayby we want to keep its value? O.o
shadowNode.setAttribute(name, value);
}
}
// NOTE
// this is dangerous as many attributes are dynamically added on render
// plus is very rare we would have a case where we should remove attributes.. however if yes then rethink this !
// // remove the left over attributes
// for (let i=0; i<shadowNode.attributes.length; i++)
// {
// const name = shadowNode.attributes[i].name;
// if (!passedAttributes.includes(name))
// {
// console.log(shadowNode, 'removing attribute', name, passedAttributes)
// shadowNode.removeAttribute(name);
// }
// }
// then content - also tricky case as we are interessted in only Text change
// as the rest would get also covered !
node.childNodes.forEach((child, key) => {
var _a;
if (child.nodeType === Node.TEXT_NODE) {
// check if its just this weird html fillers
if (((_a = child.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === "")
return;
const shadowTextNode = shadowNode.childNodes[key];
if (shadowTextNode) {
if (shadowTextNode.nodeType === Node.TEXT_NODE) {
if (shadowTextNode.textContent !== child.textContent) {
shadowTextNode.textContent = child.textContent;
}
}
else {
// NOTE this case seems not to show up really thus not implement for now
console.error('[ERROR] if this can be seen we must update (1)');
console.log({ shadowTextNode, child, content: child.textContent });
}
}
else {
if (shadowNode.childNodes.length === 0) {
shadowNode.textContent = child.textContent;
}
else {
console.error('[ERROR] if this can be seen we must update (2)');
console.log({ child, content: child.textContent, shadowNode });
}
}
}
});
}
});
this.shadowRoot.querySelectorAll('*:not(style)').forEach(node => {
// NOTE this node can already been removed now from a previous deletion
// (as it could be a child within a child)
if (!node.parentNode)
return;
// determine which one should leave !
const path = this.getComposedPath(this.shadowRoot, node);
const templateNode = this.templateComperator.querySelector(path.join(" > "));
if (!templateNode) {
// needs to go! (if not render-greedy)
if (!path.some(p => /render-greedy/.test(p))) {
node.parentNode.removeChild(node);
}
}
});
// compare each node to shadowroot and check if anything has changed !
}
/**
* This function will get the composed path based on a base element
* - templateComperator & potentially shadowRoot
* returns the CSS selector path
*
* @param base Element
* @param target Element
* @returns string - CSS selector
*/
getComposedPath(base, target) {
const path = [];
while (target !== base) {
path.push(this.getSelector(target));
let nexttarget = target.parentElement;
if (nexttarget)
target = nexttarget;
else
break;
}
return path.reverse();
}
/**
* This function will return the selector for a element, tries to use the common things
* - included key as React does for array
* OBS: if no special selector found it will base it on child index if parent has more then 1 child
*
* @param node Element
* @returns string
*/
getSelector(node) {
const selector = [node.tagName];
if (node.id)
selector.push("#" + node.id);
else if (node.hasAttribute("key"))
selector.push(`[key="${node.getAttribute("key")}"]`);
else if (node.hasAttribute("part"))
selector.push(`[part="${node.getAttribute("part")}"]`);
else if (typeof node.className === "string" && node.className) {
selector.push("." + node.className.trim().replace(/ /g, "."));
}
// we store the render greedy so we need not to traverse DOM
if (node.hasAttribute('render-greedy'))
selector.push('[render-greedy]');
// NOTE there's a big problem with class selection when a class can dynamically arrive..
if (selector.length === 1) {
// need to get child index then !
if (node.parentNode) {
if (node.parentNode.children.length > 1) {
let index = 0;
for (let i = 0; i < node.parentNode.children.length; i++) {
if (node.parentNode.children[i] === node) {
index = i;
break;
}
}
selector.push(`:nth-child(${index + 1})`);
}
}
}
return selector.join("");
}
renderContent(content, parent) {
if (["string", "number", "boolean"].includes(typeof content)) {
const strcontent = content.toString();
if (/</.test(strcontent) && />/.test(strcontent)) {
// If it's HTML, set it directly
// NOTE this is not the best comperator nor the best way but its the easiest !
parent.innerHTML = parent.innerHTML + strcontent;
}
else {
// If it's plain text, create and append a text node
const textNode = document.createTextNode(strcontent);
parent.appendChild(textNode);
}
}
else if (content instanceof DocumentFragment) {
parent.appendChild(content);
}
else if (content instanceof Array) {
content.forEach(child => this.renderContent(child, parent));
}
}
}
Base.Properties = {};
__decorate([
property({ rerender: false, type: Boolean })
], Base.prototype, "hasFocus", void 0);
"use strict";import{__decorate as p}from"tslib";import{NextParent as h,property as c,debounce as d,convertFromString as u}from"@pap-it/system-utils";export class Base extends HTMLElement{constructor(e){return super(),this.callAfterUpdate=[],this.render_mode="smart",this.render_style_mode="lazy",this.hasrendered=!1,this.attributeinit=!1,this.delayedAttributes={},this.connected=!1,this.originalHTML="",this.hasFocus=!1,this.handleblur=()=>{this.hasFocus=!1},this.handlefocus=()=>{this.hasFocus=!0},this.originalHTML=this.outerHTML,e!=null&&e.noblur||this.addEventListener("blur",this.handleblur),e!=null&&e.nofocus||this.addEventListener("focus",this.handlefocus),this.styleComperator=document.createElement("style"),this.templateComperator=document.createElement("template"),this.debouncedRequestUpdate=d(this.requestUpdate,100),this.attachShadow({mode:"open",...e||{}}),this.updateAttribute=d(this.updateAttribute,10),this.callAfterUpdate.push(this.firstUpdate),this}connectedCallback(){this.attributeinit=!1,this.debouncedRequestUpdate(),this.connected=!0,this.dispatchEvent(new Event("connected"))}disconnectedCallback(){this.connected=!1,this.dispatchEvent(new Event("disconnected"))}attributeChangedCallback(e,t,r){if(t===r){delete this.delayedAttributes[e];return}this.delayedAttributes[e]?delete this.delayedAttributes[e]:Base.Properties[e]?this[Base.Properties[e].propertyKey]=u(r,Base.Properties[e].type):console.warn("[BASE]: not delayed not prop options",e)}firstUpdate(){this.hasrendered=!0,this.updateAttribute()}getProperties(){const e={};for(let t in Base.Properties)e[Base.Properties[t].propertyKey]=Base.Properties[t];return e}getStyle(){var e;const t=this.constructor;return[...(e=t.styles)!==null&&e!==void 0?e:[],...typeof t.style=="string"?[t.style]:[]].join(" ")}querySelector(e){return e?this.shadowRoot?this.shadowRoot.querySelector(e):null:(console.log("empty string"),null)}shadow_closest(e){let t=h(this);for(;t;){const r=t.closest(e);if(r)return r;const s=t.querySelector(e);if(s)return s;if(t===document.documentElement)break;t=h(t)}}requestUpdate(){if(!this.shadowRoot)return;const e=this.shadowRoot.innerHTML==="";this.renderStyle();const t=this.render();e||this.render_mode==="greedy"?(this.flushHTML(this.shadowRoot),this.renderContent(t,this.shadowRoot)):this.renderHTML(t);let r;const s=this.callAfterUpdate.reverse();for(;r=s.pop();)typeof r=="object"&&r.callback.call(this,...r.args),r instanceof Function&&r.call(this);this.callAfterUpdate=[]}debouncedRequestUpdate(){}render(e){return"Hello From Base Class"}initAttributes(){if(this.attributeinit)return;this.attributeinit=!0;const e=this.attributes;for(let t=0;t<e.length;t++){const r=e[t].name;if(Base.Properties[r]){let s=e[t].value;s===""&&(s="true"),this[Base.Properties[r].propertyKey]=u(s,Base.Properties[r].type)}}}updateAttribute(){if(this.hasrendered){this.initAttributes();for(let e in this.delayedAttributes){const t=this.delayedAttributes[e];t===void 0?this.removeAttribute(e):this.setAttribute(e,t)}}}flushHTML(e){e.childNodes.forEach(t=>{t.nodeName!=="STYLE"&&e.removeChild(t)})}renderStyle(){if(!this.shadowRoot)return;let e=this.shadowRoot.querySelector("style");if(!e){e=document.createElement("style"),e.innerHTML=this.getStyle(),this.shadowRoot.appendChild(e);return}this.render_style_mode!=="lazy"&&(this.styleComperator.innerHTML=this.getStyle(),this.styleComperator.innerHTML!==e.innerHTML&&(e.innerHTML=this.styleComperator.innerHTML))}getNextElement(e,t){if(t.nextElementSibling){const r=this.getComposedPath(e,t.nextElementSibling),s=this.querySelector(r.join(" > "));return s||this.getNextElement(e,t.nextElementSibling)}return null}renderHTML(e){if(!this.shadowRoot)return;for(this.hasrendered=!0;this.templateComperator.firstChild;)this.templateComperator.removeChild(this.templateComperator.firstChild);this.templateComperator.appendChild(this.styleComperator),this.renderContent(e,this.templateComperator);const t=this.templateComperator.cloneNode(!0);t.querySelectorAll("*:not(style)").forEach(r=>{const s=this.getComposedPath(t,r),a=this.querySelector(s.join(" > "));if(a){for(let i=0;i<r.attributes.length;i++){const n=r.attributes[i].name,o=r.attributes[i].value;a.getAttribute(n)!==o&&a.setAttribute(n,o)}r.childNodes.forEach((i,n)=>{var o;if(i.nodeType===Node.TEXT_NODE){if(((o=i.textContent)===null||o===void 0?void 0:o.trim())==="")return;const l=a.childNodes[n];l?l.nodeType===Node.TEXT_NODE?l.textContent!==i.textContent&&(l.textContent=i.textContent):(console.error("[ERROR] if this can be seen we must update (1)"),console.log({shadowTextNode:l,child:i,content:i.textContent})):a.childNodes.length===0?a.textContent=i.textContent:(console.error("[ERROR] if this can be seen we must update (2)"),console.log({child:i,content:i.textContent,shadowNode:a}))}})}else{let i=this.shadowRoot,n=r;if(s.length>1)for(let o=s.length-1;o>=0;o--){const l=this.querySelector(s.slice(0,o).join(" > "));if(l){i=l;break}else n=r.parentElement}if(n){const o=this.getNextElement(t,r);o?i==null||i.insertBefore(n,o):i==null||i.appendChild(n)}else console.error("[ERROR] this case should not happen"),console.log({shadowtarget:i,node:r,target:n,path:s})}}),this.shadowRoot.querySelectorAll("*:not(style)").forEach(r=>{if(!r.parentNode)return;const s=this.getComposedPath(this.shadowRoot,r);this.templateComperator.querySelector(s.join(" > "))||s.some(i=>/render-greedy/.test(i))||r.parentNode.removeChild(r)})}getComposedPath(e,t){const r=[];for(;t!==e;){r.push(this.getSelector(t));let s=t.parentElement;if(s)t=s;else break}return r.reverse()}getSelector(e){const t=[e.tagName];if(e.id?t.push("#"+e.id):e.hasAttribute("key")?t.push(`[key="${e.getAttribute("key")}"]`):e.hasAttribute("part")?t.push(`[part="${e.getAttribute("part")}"]`):typeof e.className=="string"&&e.className&&t.push("."+e.className.trim().replace(/ /g,".")),e.hasAttribute("render-greedy")&&t.push("[render-greedy]"),t.length===1&&e.parentNode&&e.parentNode.children.length>1){let r=0;for(let s=0;s<e.parentNode.children.length;s++)if(e.parentNode.children[s]===e){r=s;break}t.push(`:nth-child(${r+1})`)}return t.join("")}renderContent(e,t){if(["string","number","boolean"].includes(typeof e)){const r=e.toString();if(/</.test(r)&&/>/.test(r))t.innerHTML=t.innerHTML+r;else{const s=document.createTextNode(r);t.appendChild(s)}}else e instanceof DocumentFragment?t.appendChild(e):e instanceof Array&&e.forEach(r=>this.renderContent(r,t))}}Base.Properties={},p([c({rerender:!1,type:Boolean})],Base.prototype,"hasFocus",void 0);

3

dist/src/index.js

@@ -1,2 +0,1 @@

export * from './component';
export * from './types';
"use strict";export*from"./component";export*from"./types";

@@ -1,9 +0,1 @@

import { Base } from './component.js';
// Register the element with the browser
const cElements = customElements !== null && customElements !== void 0 ? customElements : window === null || window === void 0 ? void 0 : window.customElements;
if (!cElements) {
throw new Error('Custom Elements not supported');
}
if (!cElements.get('pap-base')) {
cElements.define('pap-base', Base);
}
"use strict";import{Base as o}from"./component.js";const e=customElements!=null?customElements:window==null?void 0:window.customElements;if(!e)throw new Error("Custom Elements not supported");e.get("pap-base")||e.define("pap-base",o);

@@ -1,1 +0,1 @@

export {};
"use strict";export{};
{
"name": "@pap-it/system-base",
"version": "1.0.11",
"version": "1.0.12",
"scripts": {

@@ -22,3 +22,3 @@ "init": "sh .scripts/init.sh",

"./wc": "./dist/register.bundle.mjs",
"./react": "./dist/react/index.ts"
"./react": "./dist/react/index.js"
},

@@ -38,8 +38,8 @@ "author": "Henry Pap",

"@pap-it/system-utils": "1.0.10",
"@pap-it/system-react": "0.0.5"
"@pap-it/system-react": "0.0.6"
},
"devDependencies": {
"eslint": "^8.53.0",
"@pap-it/system-showcase": "1.0.11",
"@pap-it/typography": "1.0.11",
"@pap-it/system-showcase": "1.0.12",
"@pap-it/typography": "1.0.12",
"esbuild": "^0.17.18",

@@ -46,0 +46,0 @@ "node-html-parser": "^6.1.5",

@@ -5,6 +5,7 @@ # Base

Version: Version: Version: 1.0.11
Version: Version: Version: 1.0.12
## Development

@@ -11,0 +12,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc