Solo
Solo

Reputation: 6957

Change Image prototype

How does one augment setAttribute of Image? I did try few things but quickly ran into issues.

  var originalSetAttribute = Image.prototype.setAttribute;

  Image.prototype.setAttribute = function (key, value) {
    console.log('set attribute', key, ' -> ', value);

    var val = (key === 'src') ? getCorrectSrc(value) : value;

    // first attempt
    originalSetAttribute(key, val);
    // second attempt
    Image.prototype.__proto__.setAttribute(key, val);
  };

I get Uncaught TypeError: Illegal invocation.

JSFiddle


Please no "this is bad practise" comments, sometimes in life you're in a situation where you have no choice but to hack your way through the worst possible situations because the specific IT area you work in is messed up and full of weird standards.

Besides, I'll put this logic into iframe, so that it doesn't mess up the top window Image.

Goal:

Third-party library adds images using the following APIs:

var img = new Image; 
img.src = '..'; 
img.setAttribute('src', '..');

src values are inlined into their code but I need to use other src values. It's much easier to hack the Image compared to parsing their JS files and doing expensive and complex string searches and replacements.

Plus points if you can help me with Image src setter as well. Thank you!

Upvotes: 0

Views: 282

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370689

You need to .call the original setAttribute function with the this that your patched setAttribute was called with:

return originalSetAttribute.call(this, key, val);

To patch the setter (and getter):

const { get, set } = Object.getOwnPropertyDescriptor(Image.prototype, 'src');
Object.defineProperty(Image.prototype, 'src', {
  set(newVal) {
    return set.call(this, getCorrectSrc(newVal));
  },
  get() {
    return get.call(this);
  }
});

Upvotes: 2

Related Questions