mirror of
https://gitlab.com/octtspacc/sitoctt
synced 2025-06-05 22:09:20 +02:00
.
This commit is contained in:
234
node_modules/@mixmark-io/domino/CSSStyleDeclaration.js
generated
vendored
Normal file
234
node_modules/@mixmark-io/domino/CSSStyleDeclaration.js
generated
vendored
Normal file
@ -0,0 +1,234 @@
|
||||
"use strict";
|
||||
|
||||
const { parse } = require('./style_parser');
|
||||
|
||||
module.exports = function (elt) {
|
||||
const style = new CSSStyleDeclaration(elt)
|
||||
const handler = {
|
||||
get: function(target, property) {
|
||||
return property in target ? target[property] : target.getPropertyValue(dasherizeProperty(property));
|
||||
},
|
||||
has: function(target, key) {
|
||||
return true;
|
||||
},
|
||||
set: function(target, property, value) {
|
||||
if (property in target) {
|
||||
target[property] = value;
|
||||
} else {
|
||||
target.setProperty(dasherizeProperty(property), value ?? undefined);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return new Proxy(style, handler);
|
||||
};
|
||||
|
||||
function dasherizeProperty(property) {
|
||||
return property.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
function CSSStyleDeclaration(elt) {
|
||||
this._element = elt;
|
||||
}
|
||||
|
||||
const IMPORTANT_BANG = '!important';
|
||||
|
||||
// Utility function for parsing style declarations
|
||||
// Pass in a string like "margin-left: 5px; border-style: solid"
|
||||
// and this function returns an object like
|
||||
// {"margin-left":"5px", "border-style":"solid"}
|
||||
function parseStyles(value) {
|
||||
const result = {
|
||||
property: {},
|
||||
priority: {},
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const styleValues = parse(value);
|
||||
if (styleValues.length < 2) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (let i = 0; i < styleValues.length; i += 2) {
|
||||
const name = styleValues[i];
|
||||
let value = styleValues[i+1];
|
||||
|
||||
if (value.endsWith(IMPORTANT_BANG)) {
|
||||
result.priority[name] = 'important';
|
||||
value = value.slice(0, -IMPORTANT_BANG.length).trim();
|
||||
}
|
||||
|
||||
result.property[name] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var NO_CHANGE = {}; // Private marker object
|
||||
|
||||
CSSStyleDeclaration.prototype = Object.create(Object.prototype, {
|
||||
|
||||
// Return the parsed form of the element's style attribute.
|
||||
// If the element's style attribute has never been parsed
|
||||
// or if it has changed since the last parse, then reparse it
|
||||
// Note that the styles don't get parsed until they're actually needed
|
||||
_parsed: { get: function() {
|
||||
if (!this._parsedStyles || this.cssText !== this._lastParsedText) {
|
||||
var text = this.cssText;
|
||||
this._parsedStyles = parseStyles(text);
|
||||
this._lastParsedText = text;
|
||||
delete this._names;
|
||||
}
|
||||
return this._parsedStyles;
|
||||
}},
|
||||
|
||||
// Call this method any time the parsed representation of the
|
||||
// style changes. It converts the style properties to a string and
|
||||
// sets cssText and the element's style attribute
|
||||
_serialize: { value: function() {
|
||||
var styles = this._parsed;
|
||||
var s = "";
|
||||
|
||||
for(var name in styles.property) {
|
||||
if (s) s += " ";
|
||||
s += name + ": " + styles.property[name];
|
||||
if (styles.priority[name]) {
|
||||
s += " !" + styles.priority[name];
|
||||
}
|
||||
s += ";";
|
||||
}
|
||||
|
||||
this.cssText = s; // also sets the style attribute
|
||||
this._lastParsedText = s; // so we don't reparse
|
||||
delete this._names;
|
||||
}},
|
||||
|
||||
cssText: {
|
||||
get: function() {
|
||||
// XXX: this is a CSSStyleDeclaration for an element.
|
||||
// A different impl might be necessary for a set of styles
|
||||
// associated returned by getComputedStyle(), e.g.
|
||||
return this._element.getAttribute("style");
|
||||
},
|
||||
set: function(value) {
|
||||
// XXX: I should parse and serialize the value to
|
||||
// normalize it and remove errors. FF and chrome do that.
|
||||
this._element.setAttribute("style", value);
|
||||
}
|
||||
},
|
||||
|
||||
length: { get: function() {
|
||||
if (!this._names)
|
||||
this._names = Object.getOwnPropertyNames(this._parsed.property);
|
||||
return this._names.length;
|
||||
}},
|
||||
|
||||
item: { value: function(n) {
|
||||
if (!this._names)
|
||||
this._names = Object.getOwnPropertyNames(this._parsed.property);
|
||||
return this._names[n];
|
||||
}},
|
||||
|
||||
getPropertyValue: { value: function(property) {
|
||||
property = property.toLowerCase();
|
||||
return this._parsed.property[property] || "";
|
||||
}},
|
||||
|
||||
getPropertyPriority: { value: function(property) {
|
||||
property = property.toLowerCase();
|
||||
return this._parsed.priority[property] || "";
|
||||
}},
|
||||
|
||||
setProperty: { value: function(property, value, priority) {
|
||||
property = property.toLowerCase();
|
||||
if (value === null || value === undefined) {
|
||||
value = "";
|
||||
}
|
||||
if (priority === null || priority === undefined) {
|
||||
priority = "";
|
||||
}
|
||||
|
||||
// String coercion
|
||||
if (value !== NO_CHANGE) {
|
||||
value = "" + value;
|
||||
}
|
||||
|
||||
value = value.trim();
|
||||
if (value === "") {
|
||||
this.removeProperty(property);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priority !== "" && priority !== NO_CHANGE &&
|
||||
!/^important$/i.test(priority)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var styles = this._parsed;
|
||||
if (value === NO_CHANGE) {
|
||||
if (!styles.property[property]) {
|
||||
return; // Not a valid property name.
|
||||
}
|
||||
if (priority !== "") {
|
||||
styles.priority[property] = "important";
|
||||
} else {
|
||||
delete styles.priority[property];
|
||||
}
|
||||
} else {
|
||||
// We don't just accept the property value. Instead
|
||||
// we parse it to ensure that it is something valid.
|
||||
// If it contains a semicolon it is invalid
|
||||
if (value.indexOf(";") !== -1) return;
|
||||
|
||||
var newprops = parseStyles(property + ":" + value);
|
||||
if (Object.getOwnPropertyNames(newprops.property).length === 0) {
|
||||
return; // no valid property found
|
||||
}
|
||||
if (Object.getOwnPropertyNames(newprops.priority).length !== 0) {
|
||||
return; // if the value included '!important' it wasn't valid.
|
||||
}
|
||||
|
||||
// XXX handle shorthand properties
|
||||
|
||||
for (var p in newprops.property) {
|
||||
styles.property[p] = newprops.property[p];
|
||||
if (priority === NO_CHANGE) {
|
||||
continue;
|
||||
} else if (priority !== "") {
|
||||
styles.priority[p] = "important";
|
||||
} else if (styles.priority[p]) {
|
||||
delete styles.priority[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize and update cssText and element.style!
|
||||
this._serialize();
|
||||
}},
|
||||
|
||||
setPropertyValue: { value: function(property, value) {
|
||||
return this.setProperty(property, value, NO_CHANGE);
|
||||
}},
|
||||
|
||||
setPropertyPriority: { value: function(property, priority) {
|
||||
return this.setProperty(property, NO_CHANGE, priority);
|
||||
}},
|
||||
|
||||
removeProperty: { value: function(property) {
|
||||
property = property.toLowerCase();
|
||||
var styles = this._parsed;
|
||||
if (property in styles.property) {
|
||||
delete styles.property[property];
|
||||
delete styles.priority[property];
|
||||
|
||||
// Serialize and update cssText and element.style!
|
||||
this._serialize();
|
||||
}
|
||||
}},
|
||||
});
|
Reference in New Issue
Block a user