stop double binding (#3983)

* stop double binding
This commit is contained in:
Andrea Bogazzi 2017-06-07 14:07:38 +02:00 committed by GitHub
parent 2b1ffd45cc
commit 9cae49510f
6 changed files with 175 additions and 6 deletions

View file

@ -6,5 +6,5 @@ node_js:
script: 'npm run build && npm run test && npm run lint && npm run lint_tests'
before_install:
- sudo apt-get update -qq
- sudo apt-get install libc6 -qq
- sudo apt-get install -qq libc6 libgif-dev libpng-dev libjpeg8-dev libpango1.0-dev libcairo2-dev
dist: trusty

View file

@ -61,7 +61,7 @@ fabric.DPI = 96;
fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)';
fabric.fontPaths = { };
fabric.iMatrix = [1, 0, 0, 1, 0, 0];
fabric.canvasModule = 'canvas-prebuilt';
fabric.canvasModule = 'canvas';
/**
* Cache Object for widths of chars in text rendering.
*/

View file

@ -36,7 +36,7 @@
"license": "MIT",
"scripts": {
"build": "node build.js modules=ALL exclude=json,gestures",
"build:watch": "onchange 'src/**/**' 'test/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export",
"build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export",
"build_with_gestures": "node build.js modules=ALL exclude=json",
"build_export": "npm run build && npm run export_dist_to_site",
"test": "node test.js",
@ -47,7 +47,7 @@
"all": "npm run build && npm run test && npm run lint && npm run lint_tests && npm run export_dist_to_site && npm run export_tests_to_site"
},
"optionalDependencies": {
"canvas-prebuilt": "1.6.5-prerelease.1",
"canvas": "1.6.x",
"jsdom": "9.x.x",
"xmldom": "0.1.x"
},

View file

@ -1277,7 +1277,13 @@
_createUpperCanvas: function () {
var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, '');
this.upperCanvasEl = this._createCanvasElement();
// there is no need to create a new upperCanvas element if we have already one.
if (this.upperCanvasEl) {
this.upperCanvasEl.className = '';
}
else {
this.upperCanvasEl = this._createCanvasElement();
}
fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass);
this.wrapperEl.appendChild(this.upperCanvasEl);

View file

@ -40,7 +40,10 @@
* @private
*/
_initEventListeners: function () {
// in case we initialized the class twice. This should not happen normally
// but in some kind of applications where the canvas element may be changed
// this is a workaround to having double listeners.
this.removeListeners();
this._bindEvents();
addListener(fabric.window, 'resize', this._onResize);
@ -70,6 +73,10 @@
* @private
*/
_bindEvents: function() {
if (this.eventsBinded) {
// for any reason we pass here twice we do not want to bind events twice.
return;
}
this._onMouseDown = this._onMouseDown.bind(this);
this._onMouseMove = this._onMouseMove.bind(this);
this._onMouseUp = this._onMouseUp.bind(this);
@ -83,6 +90,7 @@
this._onMouseOut = this._onMouseOut.bind(this);
this._onMouseEnter = this._onMouseEnter.bind(this);
this._onContextMenu = this._onContextMenu.bind(this);
this.eventsBinded = true;
},
/**

View file

@ -1829,4 +1829,159 @@
canvas.__onMouseUp(e2);
equal(isClick, false, 'moving the pointer, the click is false');
});
test('avoid multiple bindings', function() {
var el2 = fabric.document.createElement('canvas');
var c = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
var eventsArray = [
c._onMouseDown,
c._onMouseMove,
c._onMouseUp,
c._onResize,
c._onGesture,
c._onDrag,
c._onShake,
c._onLongPress,
c._onOrientationChange,
c._onMouseWheel,
c._onMouseOut,
c._onMouseEnter,
c._onContextMenu
];
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
var eventsArray2 = [
c._onMouseDown,
c._onMouseMove,
c._onMouseUp,
c._onResize,
c._onGesture,
c._onDrag,
c._onShake,
c._onLongPress,
c._onOrientationChange,
c._onMouseWheel,
c._onMouseOut,
c._onMouseEnter,
c._onContextMenu
];
deepEqual(eventsArray, eventsArray2, 'after first initialize, functions do not change.');
});
test('avoid multiple registration - mousedown', function() {
var el2 = fabric.document.createElement('canvas');
var originalMouseDown = fabric.Canvas.prototype._onMouseDown;
var counter = 0;
fabric.Canvas.prototype._onMouseDown = function() {
counter++;
};
var c = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
var event = fabric.document.createEvent('MouseEvent');
event.initEvent('mousedown', true, true);
c.upperCanvasEl.dispatchEvent(event);
equal(counter, 1, 'listener executed once');
fabric.Canvas.prototype._onMouseDown = originalMouseDown;
});
test('avoid multiple registration - mousemove', function() {
var el2 = fabric.document.createElement('canvas');
var originalMouseMove = fabric.Canvas.prototype._onMouseMove;
var counter = 0;
fabric.Canvas.prototype._onMouseMove = function() {
counter++;
};
var c = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
var event = fabric.document.createEvent('MouseEvent');
event.initEvent('mousemove', true, true);
c.upperCanvasEl.dispatchEvent(event);
equal(counter, 1, 'listener executed once');
fabric.Canvas.prototype._onMouseMove = originalMouseMove;
});
asyncTest('avoid multiple registration - mouseup', function() {
var el2 = fabric.document.createElement('canvas');
var originalMouseUp = fabric.Canvas.prototype._onMouseUp;
var counter = 0;
fabric.Canvas.prototype._onMouseUp = function() {
counter++;
};
var c = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
// a mouse down is necessary to register mouse up.
var _event = fabric.document.createEvent('MouseEvent');
_event.initEvent('mousedown', true, true);
c.upperCanvasEl.dispatchEvent(_event);
setTimeout(function() {
var event = fabric.document.createEvent('MouseEvent');
event.initEvent('mouseup', true, true);
fabric.document.dispatchEvent(event);
equal(counter, 1, 'listener executed once');
fabric.Canvas.prototype._onMouseUp = originalMouseUp;
start();
}, 200);
});
test('avoid multiple registration - mouseout', function() {
var el2 = fabric.document.createElement('canvas');
var originalMouseOut = fabric.Canvas.prototype._onMouseOut;
var counter = 0;
fabric.Canvas.prototype._onMouseOut = function() {
counter++;
};
var c = this.canvas = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
var event = fabric.document.createEvent('MouseEvent');
event.initEvent('mouseout', true, true);
c.upperCanvasEl.dispatchEvent(event);
equal(counter, 1, 'listener executed once');
fabric.Canvas.prototype._onMouseOut = originalMouseOut;
});
test('avoid multiple registration - mouseenter', function() {
var el2 = fabric.document.createElement('canvas');
var originalMouseEnter = fabric.Canvas.prototype._onMouseEnter;
var counter = 0;
fabric.Canvas.prototype._onMouseEnter = function() {
counter++;
};
var c = this.canvas = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
var event = fabric.document.createEvent('MouseEvent');
event.initEvent('mouseenter', true, true);
c.upperCanvasEl.dispatchEvent(event);
equal(counter, 1, 'listener executed once');
fabric.Canvas.prototype._onMouseEnter = originalMouseEnter;
});
test('avoid multiple events on window', function() {
var el2 = fabric.document.createElement('canvas');
var originalResize = fabric.Canvas.prototype._onResize;
var counter = 0;
fabric.Canvas.prototype._onResize = function() {
counter++;
};
var c = this.canvas = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.Canvas(el2);
// initialize canvas more than once
c.initialize(el2);
c.initialize(el2);
var event = fabric.document.createEvent('UIEvents');
event.initUIEvent('resize', true, false, fabric.window, 0);
fabric.window.dispatchEvent(event);
equal(counter, 1, 'listener on window executed once');
fabric.Canvas.prototype._onResize = originalResize;
});
})();