As far as I know, there is no real way to override the native cssText
getter on a CSSStyleDeclaration
object.
Let's have a look why:
var s = document.createElement('style'),
style = s.style;
style instanceof CSSStyleDeclaration; //true
So far so good, however when we try to set the cssText
property:
style.cssText = 'something';
style.cssText; //(empty string), the native setter did not allow setting an invalid style
As we can see, the cssText
property implements native getters/setters that are invoked when we try to get/set the cssText
property.
Ok, fine! Let's just redefine the custom CSSStyleDeclaration.prototype.cssText
getter/setter. Well that doesn't work because it seems the cssText
property doesn't come from the prototype and even if it would there's no way to get custom getters/setters using Object.getOwnPropertyDescriptor
so we would not be able to invoke the native setter from our custom function.
Let's have a look anyway:
Object.defineProperty(CSSStyleDeclaration.prototype, 'cssText', {
get: function () { return 'overrided'; }
});
document.createElement('style').style.cssText; //(empty string)
Is there a solution then? Well there's probably no safe solution to do it yet, but your best bet would be to replace the style
property with a custom accessor on the newly created element. That accessor would return an object that implements the same interface a CSSStyleDeclaration
instance would, but all the accessors/functions would have been replaced to delegate the operations to the original style object.
The returned object would basically act as a proxy object for the real style object. That would be the only way since we cannot access native getters/setters functions, otherwise we could have redefined the cssText
accessor only on the native style object of the element.
In the following example, I demonstrate the idea by only proxying the cssText
property.
Note: The reason we create an instance of CSSStyleDeclaration.prototype
is to make sure that styleProxy instanceof CSSStyleDeclaration
remains true.
THE IMPLEMENTATION IS INCOMPLETE AND NOT SAFE TO USE
document.createElement = (function (doc, nativeCreateEl) {
return function() {
var el = nativeCreateEl.apply(doc, arguments),
nativeStyle = el.style,
styleProxy = Object.create(CSSStyleDeclaration.prototype);
Object.defineProperty(el, 'style', {
get: function () {
return styleProxy;
}
});
Object.defineProperty(styleProxy, 'cssText', {
set: function (styles) {
console.log('setting cssText');
nativeStyle.cssText = styles;
},
get: function () {
return nativeStyle.cssText;
}
});
return el;
};
})(document, document.createElement);
var el = document.createElement('div'),
s = el.style;
s.cssText = 'test'; //logs setting cssText
s.cssText; //(empty string) -> this is expected
s.cssText = 'color: red;'; //logs setting cssText
s.cssText; //color: red;