Reputation: 997
Are there any way I can set getters and setters of src attribute of all HTMLSourceElements? I'm thinking about using this as an extra security measures for my web app which uses JS from other websites. By "setters of src attribute of all HTMLSourceElements", I mean that the setter should be called on code like: SomeVideoElement.src = "/static/somevideo.mp4"
So far, I've tried:
HTMLElement.prototype.__defineGetter__("src", function () {
console.log("getter called!");
debugger;
});
HTMLElement.prototype.__defineSetter__("src", function (val) {
debugger;
});
//tested at chrome, didn't yield any logs (getters and setters not called)
and
HTMLSourceElement.prototype._setAttribute = HTMLSourceElement.prototype.setAttribute;
HTMLSourceElement.prototype._getAttribute = HTMLSourceElement.prototype.getAttribute;
HTMLSourceElement.prototype.setAttribute = function(){
console.log("HTMLSourceElement.setAttribute called!");
debugger;
HTMLSourceElement.prototype._setAttribute.apply(this, arguments);
}
//tested at chrome. Called only for codes like: SomeVidElem.setAttribute("src",someurl)
are there any way to do this? Or is this simply impossible? Thanks : )
Upvotes: 4
Views: 2531
Reputation: 193301
You should play with MutationObserver
. For example this is how you can watch image properties changes:
var target = document.querySelector('#image');
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function(mutation) {
console.log(mutation);
alert('Change: ' + mutation.attributeName + ', ' + mutation.oldValue);
});
});
observer.observe(target, {
attributes: true,
attributeOldValue: true
});
Support: all modern browsers and IE11+.
Upvotes: 2
Reputation: 33409
__defineGetter__
and __defineSetter__
are deprecated and possibly obsolete. Object.defineProperty(parentObject, 'propName', {})
is the new way.
I couldn't get it to work, but maybe someone else can?
Object.defineProperty(HTMLSourceElement.prototype, 'src', {
enumerable: true,
configurable: true,
get: function(){
return this.getAttribute('src')
},
set: function(newval){
console.log('being set');
this.setAttribute('src',newval);
}
});
EDIT: After a bit of experimentation, this should work if you then delete
the src
property of every element that you need to. A bit hacky, but the best i could do.
EDIT2: With this, a user could still theoretically overwrite your get/set functions. To stop that, try removing configurable: true
(it will default to false). I'm not sure, but from past experience, it seems like they can't even redefine it on an instance.
Upvotes: 5
Reputation: 3765
var srcElements = document.querySelectorAll('[src]');
for(var i = 0; i < srcElements.length; i++){
if( typeof(srcElements[i].src) != 'undefined' ){
console.log(srcElements[i] + ' has a src property');
}
}
Upvotes: 0