diff --git a/src/core/Emitter.js b/src/core/Emitter.js index db4c53eb..39f0b4a2 100644 --- a/src/core/Emitter.js +++ b/src/core/Emitter.js @@ -85,20 +85,14 @@ var Emitter = { // won't throw us off track here: handlers = handlers.slice(); for (var i = 0, l = handlers.length; i < l; i++) { - var res = handlers[i].apply(this, args); - // Look at the handler's return value to decide how to propagate: - if (res === false) { - // If it returns false, prevent the default behavior and stop - // propagation of the event by calling stop() + if (handlers[i].apply(this, args) === false) { + // If the handler returns false, prevent the default behavior + // and stop propagation of the event by calling stop() if (event && event.stop) event.stop(); // Stop propagation right now! break; - } else if (res === true) { - // If it return true, remember that one handler wants to enforce - // the browser's default behavior. This is handled later. - event._enforced = true; - } + } } return true; }, diff --git a/src/event/Event.js b/src/event/Event.js index 68b13f57..d450221e 100644 --- a/src/event/Event.js +++ b/src/event/Event.js @@ -26,8 +26,6 @@ var Event = Base.extend(/** @lends Event# */{ prevented: false, stopped: false, - // Internal flag indicating whether the default shall be enforced. - _enforced: false, /** * Cancels the event if it is cancelable, without stopping further diff --git a/src/tool/Tool.js b/src/tool/Tool.js index 6def20f0..67a1f3d4 100644 --- a/src/tool/Tool.js +++ b/src/tool/Tool.js @@ -282,9 +282,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{ /** * Private method to handle tool-events. * - * @return {@true if the default event should be prevented}. This is if at - * least one event handler was called and none of the called handlers - * wants to enforce the default. + * @return {@true if at least one event handler was called}. */ _handleEvent: function(type, event, point, mouse) { // Update global reference to this scope. @@ -301,8 +299,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{ // case it is shorter than maxDistance, as this would produce weird // results. matchMaxDistance controls this. matchMaxDistance = false, - called = false, // Has at least one handler been called? - enforced = false, // Does a handler want to enforce the default? + called = false, tool = this; function update(start, minDistance, maxDistance) { @@ -348,14 +345,9 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{ } function emit() { - if (tool.responds(type)) { - var toolEvent = new ToolEvent(tool, type, event); - if (tool.emit(type, toolEvent)) { - called = true; - if (toolEvent._enforced) - enforced = true; - } - } + called = tool.responds(type) + && tool.emit(type, new ToolEvent(tool, type, event)) + || called; } if (mouse.down) { @@ -383,7 +375,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{ } } } - return called && !enforced; + return called; } /** * {@grouptitle Event Handling} diff --git a/src/view/View.js b/src/view/View.js index 106e933f..97c1dd30 100644 --- a/src/view/View.js +++ b/src/view/View.js @@ -838,8 +838,7 @@ new function() { // Injection scope for mouse events on the browser * with support for bubbling (event-propagation). */ - var called = false, // Has at least one handler been called? - enforced = false, // Does a handler want to enforce the default? + var called = false, // Event fallbacks for "virutal" events, e.g. if an item doesn't respond // to doubleclick, fall back to click: fallbacks = { @@ -847,8 +846,7 @@ new function() { // Injection scope for mouse events on the browser mousedrag: 'mousemove' }; - // Returns true if event was stopped, false otherwise, whether handler was - // called or not! + // Returns true if event was stopped, false otherwise. function emitEvent(obj, type, event, point, prevPoint, stopItem) { var target = obj, mouseEvent; @@ -865,8 +863,6 @@ new function() { // Injection scope for mouse events on the browser } if (obj.emit(type, mouseEvent)) { called = true; - if (mouseEvent._enforced) - enforced = true; // Bail out if propagation is stopped if (mouseEvent.stopped) return true; @@ -887,13 +883,11 @@ new function() { // Injection scope for mouse events on the browser return false; } - // Returns true if event was stopped, false otherwise, whether handler was - // called or not! + // Returns true if event was stopped, false otherwise. function emitEvents(view, item, type, event, point, prevPoint) { - // Set enforced and called to false, so it will reflect if the following - // calls to emitEvent() have called a handler, and if at least one of - // the handlers wants to enforce default. - called = enforced = false; + // Set called to false, so it will reflect if the following calls to + // emitEvent() have called a handler. + called = false; // First handle the drag-item and its parents, through bubbling. return (dragItem && emitEvent(dragItem, type, event, point, prevPoint) @@ -958,7 +952,7 @@ new function() { // Injection scope for mouse events on the browser var handleItems = this._itemEvents[type], project = paper.project, tool = this._scope.tool; - // If it's a native mousemove event but the mouse is clicke, convert + // If it's a native mousemove event but the mouse is down, convert // it to a mousedrag. // NOTE: emitEvent(), as well as Tool#_handleEvent() fall back to // mousemove if the objects don't respond to mousedrag. @@ -1054,8 +1048,17 @@ new function() { // Injection scope for mouse events on the browser // to only be fired if we're inside the view or if we just left it. // Prevent default if at least one handler was called, and none of // them enforces default, to prevent scrolling on touch devices. - if (handle && tool && tool._handleEvent(type, event, point, mouse) - || called && !enforced) + if (handle && tool) + called = tool._handleEvent(type, event, point, mouse) || called; + // Call preventDefault()`, but only according to this convention: + // - If any of the handlers were called, except for mousemove events + // which need to call `event.preventDefault()` explicitly, or + // `return false;`. + // - If this is a mousedown event, and the view or tools respond to + // mouseup. + var up = 'mouseup'; + if (called && !mouse.move || mouse.down && (this._itemEvents[up] + || this.responds(up) || tool.responds(up))) event.preventDefault(); // In the end we always call update(), which only updates the view // if anything has changed in the above calls.