mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -05:00
Implement new convention when to call event.preventDefault()
after mouse-events:
- 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.
This commit is contained in:
parent
1a6bf972d5
commit
b8a1fbcd67
4 changed files with 28 additions and 41 deletions
|
@ -85,20 +85,14 @@ var Emitter = {
|
||||||
// won't throw us off track here:
|
// won't throw us off track here:
|
||||||
handlers = handlers.slice();
|
handlers = handlers.slice();
|
||||||
for (var i = 0, l = handlers.length; i < l; i++) {
|
for (var i = 0, l = handlers.length; i < l; i++) {
|
||||||
var res = handlers[i].apply(this, args);
|
if (handlers[i].apply(this, args) === false) {
|
||||||
// Look at the handler's return value to decide how to propagate:
|
// If the handler returns false, prevent the default behavior
|
||||||
if (res === false) {
|
// and stop propagation of the event by calling stop()
|
||||||
// If it returns false, prevent the default behavior and stop
|
|
||||||
// propagation of the event by calling stop()
|
|
||||||
if (event && event.stop)
|
if (event && event.stop)
|
||||||
event.stop();
|
event.stop();
|
||||||
// Stop propagation right now!
|
// Stop propagation right now!
|
||||||
break;
|
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;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,8 +26,6 @@ var Event = Base.extend(/** @lends Event# */{
|
||||||
|
|
||||||
prevented: false,
|
prevented: false,
|
||||||
stopped: false,
|
stopped: false,
|
||||||
// Internal flag indicating whether the default shall be enforced.
|
|
||||||
_enforced: false,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the event if it is cancelable, without stopping further
|
* Cancels the event if it is cancelable, without stopping further
|
||||||
|
|
|
@ -282,9 +282,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
||||||
/**
|
/**
|
||||||
* Private method to handle tool-events.
|
* Private method to handle tool-events.
|
||||||
*
|
*
|
||||||
* @return {@true if the default event should be prevented}. This is if at
|
* @return {@true if at least one event handler was called}.
|
||||||
* least one event handler was called and none of the called handlers
|
|
||||||
* wants to enforce the default.
|
|
||||||
*/
|
*/
|
||||||
_handleEvent: function(type, event, point, mouse) {
|
_handleEvent: function(type, event, point, mouse) {
|
||||||
// Update global reference to this scope.
|
// 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
|
// case it is shorter than maxDistance, as this would produce weird
|
||||||
// results. matchMaxDistance controls this.
|
// results. matchMaxDistance controls this.
|
||||||
matchMaxDistance = false,
|
matchMaxDistance = false,
|
||||||
called = false, // Has at least one handler been called?
|
called = false,
|
||||||
enforced = false, // Does a handler want to enforce the default?
|
|
||||||
tool = this;
|
tool = this;
|
||||||
|
|
||||||
function update(start, minDistance, maxDistance) {
|
function update(start, minDistance, maxDistance) {
|
||||||
|
@ -348,14 +345,9 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
||||||
}
|
}
|
||||||
|
|
||||||
function emit() {
|
function emit() {
|
||||||
if (tool.responds(type)) {
|
called = tool.responds(type)
|
||||||
var toolEvent = new ToolEvent(tool, type, event);
|
&& tool.emit(type, new ToolEvent(tool, type, event))
|
||||||
if (tool.emit(type, toolEvent)) {
|
|| called;
|
||||||
called = true;
|
|
||||||
if (toolEvent._enforced)
|
|
||||||
enforced = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mouse.down) {
|
if (mouse.down) {
|
||||||
|
@ -383,7 +375,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return called && !enforced;
|
return called;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* {@grouptitle Event Handling}
|
* {@grouptitle Event Handling}
|
||||||
|
|
|
@ -838,8 +838,7 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
* with support for bubbling (event-propagation).
|
* with support for bubbling (event-propagation).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var called = false, // Has at least one handler been called?
|
var called = false,
|
||||||
enforced = false, // Does a handler want to enforce the default?
|
|
||||||
// Event fallbacks for "virutal" events, e.g. if an item doesn't respond
|
// Event fallbacks for "virutal" events, e.g. if an item doesn't respond
|
||||||
// to doubleclick, fall back to click:
|
// to doubleclick, fall back to click:
|
||||||
fallbacks = {
|
fallbacks = {
|
||||||
|
@ -847,8 +846,7 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
mousedrag: 'mousemove'
|
mousedrag: 'mousemove'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns true if event was stopped, false otherwise, whether handler was
|
// Returns true if event was stopped, false otherwise.
|
||||||
// called or not!
|
|
||||||
function emitEvent(obj, type, event, point, prevPoint, stopItem) {
|
function emitEvent(obj, type, event, point, prevPoint, stopItem) {
|
||||||
var target = obj,
|
var target = obj,
|
||||||
mouseEvent;
|
mouseEvent;
|
||||||
|
@ -865,8 +863,6 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
}
|
}
|
||||||
if (obj.emit(type, mouseEvent)) {
|
if (obj.emit(type, mouseEvent)) {
|
||||||
called = true;
|
called = true;
|
||||||
if (mouseEvent._enforced)
|
|
||||||
enforced = true;
|
|
||||||
// Bail out if propagation is stopped
|
// Bail out if propagation is stopped
|
||||||
if (mouseEvent.stopped)
|
if (mouseEvent.stopped)
|
||||||
return true;
|
return true;
|
||||||
|
@ -887,13 +883,11 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if event was stopped, false otherwise, whether handler was
|
// Returns true if event was stopped, false otherwise.
|
||||||
// called or not!
|
|
||||||
function emitEvents(view, item, type, event, point, prevPoint) {
|
function emitEvents(view, item, type, event, point, prevPoint) {
|
||||||
// Set enforced and called to false, so it will reflect if the following
|
// Set called to false, so it will reflect if the following calls to
|
||||||
// calls to emitEvent() have called a handler, and if at least one of
|
// emitEvent() have called a handler.
|
||||||
// the handlers wants to enforce default.
|
called = false;
|
||||||
called = enforced = false;
|
|
||||||
// First handle the drag-item and its parents, through bubbling.
|
// First handle the drag-item and its parents, through bubbling.
|
||||||
return (dragItem && emitEvent(dragItem, type, event, point,
|
return (dragItem && emitEvent(dragItem, type, event, point,
|
||||||
prevPoint)
|
prevPoint)
|
||||||
|
@ -958,7 +952,7 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
var handleItems = this._itemEvents[type],
|
var handleItems = this._itemEvents[type],
|
||||||
project = paper.project,
|
project = paper.project,
|
||||||
tool = this._scope.tool;
|
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.
|
// it to a mousedrag.
|
||||||
// NOTE: emitEvent(), as well as Tool#_handleEvent() fall back to
|
// NOTE: emitEvent(), as well as Tool#_handleEvent() fall back to
|
||||||
// mousemove if the objects don't respond to mousedrag.
|
// 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.
|
// 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
|
// Prevent default if at least one handler was called, and none of
|
||||||
// them enforces default, to prevent scrolling on touch devices.
|
// them enforces default, to prevent scrolling on touch devices.
|
||||||
if (handle && tool && tool._handleEvent(type, event, point, mouse)
|
if (handle && tool)
|
||||||
|| called && !enforced)
|
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();
|
event.preventDefault();
|
||||||
// In the end we always call update(), which only updates the view
|
// In the end we always call update(), which only updates the view
|
||||||
// if anything has changed in the above calls.
|
// if anything has changed in the above calls.
|
||||||
|
|
Loading…
Reference in a new issue