feat(ipub): base elements on IPUBElement
This makes the random hex ID logic shared between all elements
This commit is contained in:
@@ -1,19 +1,46 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
function hashString(str) {
|
||||
return Array.from(str).reduce(
|
||||
(s, c) => (Math.imul(31, s) + c.charCodeAt(0)) | 0,
|
||||
0,
|
||||
);
|
||||
class IPUBElement extends HTMLElement {
|
||||
static observedAttributes = ["id"];
|
||||
|
||||
connectedCallback() {
|
||||
this.ensureID();
|
||||
}
|
||||
|
||||
attributeChangedCallback(_name, _oldValue, _newValue) {
|
||||
this.ensureID();
|
||||
}
|
||||
|
||||
ensureID() {
|
||||
if (this.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// INFO: Hash algorithm by Joe Freeman & Cristian Sanchez at StackOverflow:
|
||||
// https://stackoverflow.com/a/16348977
|
||||
// https://stackoverflow.com/a/3426956
|
||||
//
|
||||
// Licensed under CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0/)
|
||||
|
||||
let hash = 0;
|
||||
this.innerHTML.split("").forEach((char) => {
|
||||
hash = char.charCodeAt(0) + ((hash << 5) - hash);
|
||||
});
|
||||
|
||||
let id = "";
|
||||
for (let i = 0; i < 3; i++) {
|
||||
id += ((hash >> (i * 8)) & 0xff).toString(16).padStart(2, "0");
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
class IPUBBackground extends HTMLElement {
|
||||
class IPUBBackground extends IPUBElement {
|
||||
static elementName = "ipub-background";
|
||||
static observedAttributes = ["sticky", "fade", "id"];
|
||||
static observedAttributes = ["sticky", "fade"].concat(
|
||||
super.observedAttributes,
|
||||
);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -63,37 +90,23 @@ class IPUBBackground extends HTMLElement {
|
||||
})();
|
||||
|
||||
attributeChangedCallback(name, _oldValue, _newValue) {
|
||||
console.debug("IPUBBackground: attribute changed", name);
|
||||
switch (name) {
|
||||
case "id": {
|
||||
if (!this.id) {
|
||||
console.warn(
|
||||
`IPUBBackground: no ID specified, assigning one based on innerHTML`,
|
||||
this,
|
||||
);
|
||||
this.id = hashString(this.innerHTML);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "fade": {
|
||||
const image = this.querySelector("img");
|
||||
if (image) {
|
||||
console.debug(
|
||||
`IPUBBackground: ipub-background#${this.id} to observer`,
|
||||
);
|
||||
super.attributeChangedCallback();
|
||||
|
||||
if (this.hasAttribute("fade")) {
|
||||
IPUBBackground.#observer.observe(image);
|
||||
} else {
|
||||
IPUBBackground.#observer.unobserve(image);
|
||||
}
|
||||
if (name === "fade") {
|
||||
const image = this.querySelector("img");
|
||||
if (image) {
|
||||
console.debug(`IPUBBackground: ipub-background#${this.id} to observer`);
|
||||
|
||||
const perc = getPercentageInView(image);
|
||||
if (perc > 0) {
|
||||
this.fade(perc);
|
||||
}
|
||||
if (this.hasAttribute("fade")) {
|
||||
IPUBBackground.#observer.observe(image);
|
||||
} else {
|
||||
IPUBBackground.#observer.unobserve(image);
|
||||
}
|
||||
|
||||
const perc = getPercentageInView(image);
|
||||
if (perc > 0) {
|
||||
this.fade(perc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,11 +135,11 @@ class IPUBBackground extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
class IPUBContent extends HTMLElement {
|
||||
class IPUBContent extends IPUBElement {
|
||||
static elementName = "ipub-content";
|
||||
}
|
||||
|
||||
class IPUBImage extends HTMLElement {
|
||||
class IPUBImage extends IPUBElement {
|
||||
static elementName = "ipub-image";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user