Skip to content

Commit

Permalink
⚡ 🐛 makes cei backward compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
jaandrle committed Aug 6, 2024
1 parent 29dd6c3 commit b90736d
Show file tree
Hide file tree
Showing 4 changed files with 317 additions and 292 deletions.
6 changes: 3 additions & 3 deletions bs/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ $.api("", true)
outfile: file_umd,
plugins: [ umdPlugin ],
});
customElementsInitiator(file_umd, outdir);
customElementsInitiator(pkg.main, outdir);
echo("%c"+outdir.toLowerCase(), css.success);
$.exit();
})
.parse();

function customElementsInitiator(file_umd, outdir){
function customElementsInitiator(file, outdir){
let usage= s.cat("README.md").trim();
const idx_usage= usage.indexOf("## Usage")+8;
usage= usage.slice(idx_usage, usage.indexOf("##", idx_usage))
.trimEnd()
.replaceAll("\n", "\n * ");
usage+= "\n *\n * version: "+pkg.version;
usage+= "\n * source: "+pkg.homepage;
const component= s.cat(file_umd).trim();
const component= s.cat(file).trim().replaceAll("export ", "");
const template= s.cat("src/customElementsInitiator.js")
.trim()
.replace("\n// USAGE", usage)
Expand Down
269 changes: 127 additions & 142 deletions lib/CBoxLine.cei.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,125 +10,124 @@
* - by default the box is moved to `0 0` and the wheel to `100 100` (see `attributes`)
* - all configuration options see `getComponentConfig` (and type `config` and `attributes`)
*
* version: 1.2.0
* version: 1.2.1
* source: https://github.com/IndigoMultimediaTeam/c-box-line
*/
(typeof customElementsInitiator==="function" ? customElementsInitiator : function customElementsInitiator(component, when= "now"){
if(when==="DOMContentLoaded"&&document.readyState==="loading")
return document.addEventListener(when, component.bind(this));
component.call(this);
})(function component(){
(function (g, f) {
if ("object" == typeof exports && "object" == typeof module) {
module.exports = f();
} else if ("function" == typeof define && define.amd) {
define("CBoxLine", [], f);
} else if ("object" == typeof exports) {
exports["CBoxLine"] = f();
} else {
g["CBoxLine"] = f();
}
}(this, () => {
var exports = {};
var module = { exports };
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// CBoxLine.js
var CBoxLine_exports = {};
__export(CBoxLine_exports, {
CBoxLine: () => CBoxLine
});
module.exports = __toCommonJS(CBoxLine_exports);
var { min, max, abs } = Math;
var createElement = document.createElement.bind(document);
var createElementNS = document.createElementNS.bind(document, "http://www.w3.org/2000/svg");
var CBoxLine = class extends HTMLElement {
static get tagName() {
return "c-box-line";
}
static get attributes() {
return [
{ name: "position-bubble", initial: "0 0" },
{ name: "position-circle", initial: "100 100" },
{ name: "stroke-width", initial: "2" }
];
}
connectedCallback() {
const config = getComponentConfig(this);
this._shadow.appendChild(Object.assign(createElement("style"), {
innerHTML: getStyleContent(config)
}));
this._shadow.appendChild(getTemplate(config));
this._ready = true;
}
/* this is more for debugging - e.g. styles are regenerated whole */
static get observedAttributes() {
return this.attributes.map(({ name }) => name);
}
attributeChangedCallback(_, value_old, value_new) {
if (!this._ready || value_new === value_old)
return false;
const config = getComponentConfig(this);
this._shadow.querySelector("style").innerHTML = getStyleContent(config);
assignLineConfig(this._shadow.querySelector("line"), config);
}
/* only constructor with Shadow Root locked */
constructor() {
super();
this._shadow = this.attachShadow({ mode: "closed" });
}
};
customElements.define(CBoxLine.tagName, CBoxLine);
function getLine12(size) {
switch (true) {
case size === 0:
return ["50%", "50%"];
case size < 0:
return ["100%", "0"];
default:
return ["0", "100%"];
}
/* global customElements */
const /* utility pro mat. operace & vytváření elementů HTML/SVG */
{ min, max, abs }= Math,
createElement= document.createElement.bind(document),
createElementNS= document.createElementNS.bind(document, "http://www.w3.org/2000/svg");
/**
* Static values of `CBoxLine` ... just a hint
* @typedef CBoxLine_static
* @type {HTMLElement & { constructor: { attributes: { name: string, initial: string }[], tagName: string } }}
*/
class CBoxLine extends HTMLElement {
static get tagName(){ /* see CBoxLine_static */ return "c-box-line"; }
static get attributes(){ /* see CBoxLine_static */ return [
{ name: "position-bubble", initial: "0 0" },
{ name: "position-circle", initial: "100 100" },
{ name: "stroke-width", initial: "2" }
]; }
connectedCallback(){
const config= getComponentConfig(this);
this._shadow.appendChild(Object.assign(createElement("style"), {
innerHTML: getStyleContent(config)
}));
this._shadow.appendChild(getTemplate(config));
this._ready= true;
}
/* this is more for debugging - e.g. styles are regenerated whole */
static get observedAttributes() { return this.attributes.map(({ name })=> name); }
attributeChangedCallback(_, value_old, value_new){
if(!this._ready||value_new===value_old) return false;
const config= getComponentConfig(this);
this._shadow.querySelector("style")
.innerHTML= getStyleContent(config);
assignLineConfig(this._shadow.querySelector("line"), config);
}
/* only constructor with Shadow Root locked */
constructor(){ super(); this._shadow= this.attachShadow({ mode: "closed" }); }
}
function assignLineConfig(el, { line: [deltaX, deltaY] }) {
const attributes = ["x1", "x2", "y1", "y2"];
const from_x1_to_y2 = getLine12(deltaX).concat(getLine12(deltaY));
for (let i = 0, key; key = attributes[i]; i++) {
el.setAttribute(key, from_x1_to_y2[i]);
}
return el;
customElements.define(CBoxLine.tagName, CBoxLine);

/**
* The i-th coordinate of the line vector decides how the line will be positioned.
*
* In the result (by combining X and Y) the line goes from the top-left to the bottom-right corner, or from the top-right …, from the middle …, etc.
* @param {number} size
* @returns {[ string, string ]}
*/
function getLine12(size){
switch(true){
case size===0: return [ "50%", "50%" ];
case size<0: return [ "100%", "0" ];
default: return [ "0", "100%" ];
}
}
/**
* Analogy `Object.assign` only for `<line>` (in the loop `*.setAttribute` is applied) and
* `config` is used as input not directly for native parameters (from there it calculates `x1`, ...)
* @param {SVGLineElement} el
* @param {config} config
* @returns {SVGLineElement} `el`
*/
function assignLineConfig(el, { line: [ deltaX, deltaY ] }){
const attributes= [ "x1", "x2", "y1", "y2" ];
const from_x1_to_y2= getLine12(deltaX).concat(getLine12(deltaY));
for(let i=0, key;( key= attributes[i] ); i++){
el.setAttribute(key, from_x1_to_y2[i]);
}
return el;
}
function getComponentConfig(el) {
const [bubble, circle, strokeWidth] = el.constructor.attributes.map(({ name, initial }) => el.getAttribute(name) || initial);
const [bX, bY] = bubble.trim().split(" ").map((n) => Number(n)), [cX, cY] = circle.trim().split(" ").map((n) => Number(n));
const deltaX = cX - bX, deltaY = cY - bY;
return {
color: "#ffcc00",
stroke: parseInt(strokeWidth),
bubble: [bX, bY],
circle: [cX, cY],
line: [deltaX, deltaY]
};

/**
* Represents the state of the component (color, position of individual elements). The source is the function {@link getComponentConfig}.
* @typedef {object} config
* @property {string} [color="#ffcc00"] hex color of lines and fill (for line and circle)
* @property {number} [stroke=2] width of lines
* @property {[number, number]} bubble `[ X, Y ]` bubble position
* @property {[number, number]} circle `[ X, Y ]` wheel position
* @property {[number, number]} line `[ deltaX, deltaY ]` vector representation of a line
*/
/**
* Returns component parameters
* @param {CBoxLine_static} el
* @returns {config}
*/
function getComponentConfig(el){
const /* atributtes */
[ bubble, circle, strokeWidth ]= el.constructor.attributes
.map(({ name, initial })=> el.getAttribute(name)||initial);
const /* pozitions */
[ bX, bY ]= bubble.trim().split(" ").map(n=> Number(n)),
[ cX, cY ]= circle.trim().split(" ").map(n=> Number(n));
const /* computed – area for a line */
deltaX= cX-bX,
deltaY= cY-bY;
return {
color: "#ffcc00",
stroke: parseInt(strokeWidth),
bubble: [ bX, bY ],
circle: [ cX, cY ],
line: [ deltaX, deltaY ]
};
}
function getStyleContent({ color, stroke, bubble, circle, line: pre_line }) {
const line = pre_line.map((v) => max(0.25, abs(v))).map((v) => v === 0.25 ? stroke + "px" : v + "%");
const [color_line, color_circle] = ["line", "circle"].map((type) => `var(--cboxline-color-${type}, ${color})`);
return `

/**
* @param {config} config
* @returns {string} It is expected as an argument for {@link HTMLStyleElement.innerHTML}
*/
function getStyleContent({ color, stroke, bubble, circle, line: pre_line }){
const line= pre_line.map(v=> max(0.25, abs(v))).map(v=> v===0.25 ? stroke+"px" : v+"%"); // hypothetically negative size or zero (vertical/horizontal line)
const [ color_line, color_circle ]= [ "line", "circle" ].map(type=> `var(--cboxline-color-${type}, ${color})`);
return (`
:host{
position: absolute;
top: 0;
Expand Down Expand Up @@ -164,39 +163,25 @@ function getStyleContent({ color, stroke, bubble, circle, line: pre_line }) {
width: 1rem;
transform: translate(-50%, -50%);
}
`.split("\n").map((l) => l.trim()).filter(Boolean).join("");
}
function getTemplate(config) {
const fragment = document.createDocumentFragment();
fragment.appendChild(
createElement("slot")
);
const el_svg = fragment.appendChild(
createElementNS("svg")
);
el_svg.appendChild(
assignLineConfig(createElementNS("line"), config)
);
fragment.appendChild(
Object.assign(createElement("div"), { className: "circle" })
);
return fragment;
`).split("\n").map(l=> l.trim()).filter(Boolean).join("");
}
if (typeof module.exports == "object" && typeof exports == "object") {
var __cp = (to, from, except, desc) => {
if ((from && typeof from === "object") || typeof from === "function") {
for (let key of Object.getOwnPropertyNames(from)) {
if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except)
Object.defineProperty(to, key, {
get: () => from[key],
enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable,
});
}
}
return to;
};
module.exports = __cp(module.exports, exports);

/**
* Generates `<><slot/><svg><line/></svg><div.circle/></>`
* @param {config} config
* @returns {DocumentFragment}
*/
function getTemplate(config){
const fragment= document.createDocumentFragment();

fragment.appendChild(
createElement("slot"));
const el_svg= fragment.appendChild(
createElementNS("svg"));
el_svg.appendChild(
assignLineConfig(createElementNS("line"), config));
fragment.appendChild(
Object.assign(createElement("div"), { className: "circle" }));
return fragment;
}
return module.exports;
}))
}, "now");
Loading

0 comments on commit b90736d

Please sign in to comment.