From c651227202a48d061feb32687584ff3cd6c5cbed Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Tue, 25 Aug 2015 13:47:45 +0200 Subject: [PATCH] Allow to unbind onload/onerror callback handlers Assigning `null` to handlers removes them, this mimic the behaviour from Google Chrome. From Chrome's Developer Tools: ```js > function handler(evt) { console.log('img handler: %s', evt.type); } < undefined > var img = document.createElement('img') < undefined > img.onload = handler < handler(evt) > img.onerror = handler < handler(evt) > img.src = 'https://www.google.com/images/errors/logo_sm_2.png'; true < true < img handler: load > img.src = 'https://www.google.com/images/errors/logo_sm_2.png'; true < true < img handler: load > img.src = 'https://example.com/404.png'; true < true < img handler: error > img.src = 'https://example.com/404.png'; true < true < img handler: error > img.onload = null < null > img.onerror = null < null > img.src = 'https://www.google.com/images/errors/logo_sm_2.png'; true < true > img.src = 'https://example.com/404.png'; true < true ``` --- src/Image.cc | 12 +++++++++++ test/image.test.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/Image.cc b/src/Image.cc index d9c70ba..70f32f9 100644 --- a/src/Image.cc +++ b/src/Image.cc @@ -268,6 +268,12 @@ NAN_SETTER(Image::SetOnload) { if (value->IsFunction()) { Image *img = Nan::ObjectWrap::Unwrap(info.This()); img->onload = new Nan::Callback(value.As()); + } else if (value->IsNull()) { + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + if (img->onload) { + delete img->onload; + } + img->onload = NULL; } } @@ -292,6 +298,12 @@ NAN_SETTER(Image::SetOnerror) { if (value->IsFunction()) { Image *img = Nan::ObjectWrap::Unwrap(info.This()); img->onerror = new Nan::Callback(value.As()); + } else if (value->IsNull()) { + Image *img = Nan::ObjectWrap::Unwrap(info.This()); + if (img->onerror) { + delete img->onerror; + } + img->onerror = NULL; } } diff --git a/test/image.test.js b/test/image.test.js index 4f8ee32..10c98fe 100644 --- a/test/image.test.js +++ b/test/image.test.js @@ -150,4 +150,56 @@ describe('Image', function () { image.src = new Buffer(0); image.src = new Buffer(''); }); + + it('should unbind Image#onload', function() { + var img = new Image + , onloadCalled = 0; + + img.onload = function() { + onloadCalled += 1; + }; + + img.src = png_checkers; + assert.equal(img.src, png_checkers); + assert.strictEqual(true, img.complete); + assert.strictEqual(2, img.width); + assert.strictEqual(2, img.height); + + assert.equal(onloadCalled, 1); + + onloadCalled = 0; + img.onload = null; + img.src = png_clock; + assert.equal(img.src, png_clock); + assert.strictEqual(true, img.complete); + assert.strictEqual(320, img.width); + assert.strictEqual(320, img.height); + + assert.equal(onloadCalled, 0); + }); + + it('should unbind Image#onerror', function() { + var img = new Image + , onerrorCalled = 0; + + + img.onload = function() { + assert.fail('called onload'); + }; + + img.onerror = function() { + onerrorCalled += 1; + }; + + img.src = png_clock + 's1'; + assert.equal(img.src, png_clock + 's1'); + + assert.equal(onerrorCalled, 1); + + onerrorCalled = 0; + img.onerror = null; + img.src = png_clock + 's3'; + assert.equal(img.src, png_clock + 's3'); + assert.equal(onerrorCalled, 0); + }); });