UNPKG

html-document

Version:

Partial implementation of document, HTMLElement for node

155 lines (140 loc) 4.67 kB
class CSSStyleRule { constructor(propertyName: string, value: string, important: boolean) { this.name = propertyName; this.value = value; this.important = important; } } /** * CSSStyleDeclaration represents a collection of CSS property-value pairs. It is used in a few APIs * * - HTMLElement.style - to manipulate the style of a single element (<elem style="...">); * - (TODO: reword) is an interface to the declaration block returned by the style * property of a cssRule in a stylesheet, when the rule is a CSSStyleRule. * - CSSStyleDeclaration is also a read-only interface to the result of window.getComputedStyle(). */ export default class AbstractCSSStyleDeclaration { /** * @type {String} */ get cssText() { return this._value; } /** * @param {String} style */ set cssText(style) { this._parse(style); } /** * Parse style * * @internal * @param {String} style */ _parse(style) { this._properties = []; this._propertiesMap = {}; style.split(';').forEach((part) => { part = part.trim(); if (!part) { return; } const important = !!part.match(/!important$/); if (important) { part = part.slice(0, -'!important'.length); } const splitPoint = part.indexOf(':'); if (splitPoint) { const key = part.slice(0, splitPoint).trim(); const value = part.slice(splitPoint + 1).trim(); this._setProperty(key, value, important && 'important'); } }); this._stringify(); } /** * Parse style * * @internal */ _stringify() { let stylified = ''; this._properties.forEach((s) => { stylified += s.name + ':' + s.value + (s.important && '!important' || '') + ';'; }); this._value = stylified; } /** * Returns the optional priority, "important". Example: priString= styleObj.getPropertyPriority('color') * * @param {String} propertyName * @param {String|undefined|false} important */ getPropertyPriority(propertyName) { return this._propertiesMap[propertyName] && this._propertiesMap[propertyName].important && 'important'; } /** * Returns the optional priority, "important". Example: priString= styleObj.getPropertyPriority('color') * * @param {String} propertyName * @return {*} propertyValue */ getPropertyValue(propertyName) { return this._propertiesMap[propertyName] && this._propertiesMap[propertyName].value; } /** * Returns a property name. Example: nameString= styleObj.item(0) Alternative: nameString= styleObj[0] * * @param {Number} index * @return {String} propertyName */ item(index) { return this._properties[index] && this._properties[index].name; } /** * Returns the value deleted. Example: valString= styleObj.removeProperty('color') * * @param {String} propertyName * @return {*} propertyValue */ removeProperty(propertyName) { if (this._propertiesMap[propertyName]) { const value = this._propertiesMap[propertyName]; this._properties.splice(this._properties.indexOf(value), 1); delete this._propertiesMap[propertyName]; this._stringify(); return value.value; } } /** * No return. Example: styleObj.setProperty('color', 'red', 'important') * * @param {String} propertyName * @param {String} value * @param {String} important */ setProperty(propertyName, value, important) { this._setProperty(propertyName, value, important); this._stringify(); } /** * No return. Example: styleObj.setProperty('color', 'red', 'important') * * @param {String} propertyName * @param {String} value * @param {String} important */ _setProperty(propertyName, value, important) { if (!propertyName.match(/^[a-z\-]+$/)) { throw new Error('Not valid property name: ' + propertyName); } const cssRule = new CSSStyleRule(propertyName, value, important === 'important'); if (this._propertiesMap[propertyName]) { this._properties.splice(this._properties.indexOf(this._propertiesMap[propertyName]), 1, cssRule); } else { this._properties.push(cssRule); } this._propertiesMap[propertyName] = cssRule; } }