blob: 52a0095faac6657c4d77c74a861e15ccf6217f4b [file] [log] [blame]
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.CodeMirrorDragToAlterNumberController = function(codeMirror)
{
this._codeMirror = codeMirror;
this._active = false;
this._dragging = false;
this._enabled = false;
this._tracksMouseClickAndDrag = false;
};
WebInspector.CodeMirrorDragToAlterNumberController.StyleClassName = "drag-to-adjust";
WebInspector.CodeMirrorDragToAlterNumberController.prototype = {
constructor: WebInspector.CodeMirrorDragToAlterNumberController,
// Public
set enabled(enabled)
{
if (this._enabled === enabled)
return;
this._element = this._codeMirror.getWrapperElement();
if (enabled) {
this._element.addEventListener("mouseenter", this);
this._element.addEventListener("mouseleave", this);
} else {
this._element.removeEventListener("mouseenter", this);
this._element.removeEventListener("mouseleave", this);
}
},
// Protected
handleEvent: function(event)
{
switch(event.type) {
case "mouseenter":
if (!this._dragging)
this._setActive(true);
break;
case "mouseleave":
if (!this._dragging)
this._setActive(false);
break;
case "mousemove":
if (this._dragging)
this._mouseWasDragged(event);
else
this._mouseMoved(event);
break;
case "mousedown":
this._mouseWasPressed(event);
break;
case "mouseup":
this._mouseWasReleased(event);
break;
case "contextmenu":
event.preventDefault();
break;
}
},
// Private
_setActive: function(active)
{
if (this._active === active || this._codeMirror.getOption("readOnly"))
return;
if (active) {
WebInspector.notifications.addEventListener(WebInspector.Notification.GlobalModifierKeysDidChange, this._modifiersDidChange, this);
this._element.addEventListener("mousemove", this);
} else {
WebInspector.notifications.removeEventListener(WebInspector.Notification.GlobalModifierKeysDidChange, this._modifiersDidChange, this);
this._element.removeEventListener("mousemove", this);
this._hoveredTokenInfo = null;
this._setTracksMouseClickAndDrag(false);
}
this._active = active;
},
_setDragging: function(dragging)
{
if (this._dragging === dragging)
return;
console.assert(window.event);
if (dragging)
WebInspector.elementDragStart(this._element, this, this, window.event, "col-resize", window);
else
WebInspector.elementDragEnd(window.event);
this._dragging = dragging;
},
_setTracksMouseClickAndDrag: function(tracksMouseClickAndDrag)
{
if (this._tracksMouseClickAndDrag === tracksMouseClickAndDrag)
return;
if (tracksMouseClickAndDrag) {
this._element.classList.add(WebInspector.CodeMirrorDragToAlterNumberController.StyleClassName);
window.addEventListener("mousedown", this, true);
window.addEventListener("contextmenu", this, true);
} else {
this._element.classList.remove(WebInspector.CodeMirrorDragToAlterNumberController.StyleClassName);
window.removeEventListener("mousedown", this, true);
window.removeEventListener("contextmenu", this, true);
this._setDragging(false);
}
this._tracksMouseClickAndDrag = tracksMouseClickAndDrag;
},
_modifiersDidChange: function(event)
{
this._setTracksMouseClickAndDrag(this._hoveredTokenInfo && this._hoveredTokenInfo.containsNumber && WebInspector.modifierKeys.altKey);
},
_mouseMoved: function(event)
{
var position = this._codeMirror.coordsChar({left: event.pageX, top: event.pageY});
var token = this._codeMirror.getTokenAt(position);
if (!token || !token.type || !token.string) {
if (this._hoveredTokenInfo)
this._reset();
return;
}
// Stop right here if we're hovering the same token as we were last time.
if (this._hoveredTokenInfo && this._hoveredTokenInfo.line === position.line &&
this._hoveredTokenInfo.token.start === token.start && this._hoveredTokenInfo.token.end === token.end)
return;
var containsNumber = token.type.indexOf("number") !== -1;
this._hoveredTokenInfo = {
token: token,
line: position.line,
containsNumber: containsNumber,
startPosition: {
ch: token.start,
line: position.line
},
endPosition: {
ch: token.end,
line: position.line
}
};
this._setTracksMouseClickAndDrag(containsNumber && event.altKey);
},
_mouseWasPressed: function(event)
{
this._lastX = event.screenX;
this._setDragging(true);
event.preventDefault();
event.stopPropagation();
},
_mouseWasDragged: function(event)
{
var x = event.screenX;
var amount = x - this._lastX;
if (Math.abs(amount) < 1)
return;
this._lastX = x;
if (event.ctrlKey)
amount /= 10;
else if (event.shiftKey)
amount *= 10;
this._codeMirror.alterNumberInRange(amount, this._hoveredTokenInfo.startPosition, this._hoveredTokenInfo.endPosition, false);
event.preventDefault();
event.stopPropagation();
},
_mouseWasReleased: function(event)
{
this._setDragging(false);
event.preventDefault();
event.stopPropagation();
this._reset();
},
_reset: function()
{
this._hoveredTokenInfo = null;
this._setTracksMouseClickAndDrag(false);
this._element.classList.remove(WebInspector.CodeMirrorDragToAlterNumberController.StyleClassName);
}
};
CodeMirror.defineOption("dragToAdjustNumbers", true, function(codeMirror, value, oldValue) {
if (!codeMirror.dragToAlterNumberController)
codeMirror.dragToAlterNumberController = new WebInspector.CodeMirrorDragToAlterNumberController(codeMirror);
codeMirror.dragToAlterNumberController.enabled = value;
});