| /* |
| * 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; |
| }); |