mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-29 13:22:34 +00:00
161 lines
5.4 KiB
JavaScript
161 lines
5.4 KiB
JavaScript
|
/* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Distributed under the BSD license:
|
||
|
*
|
||
|
* Copyright (c) 2010, Ajax.org B.V.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
* * Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* * 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.
|
||
|
* * Neither the name of Ajax.org B.V. nor the
|
||
|
* names of its contributors may be used to endorse or promote products
|
||
|
* derived from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 AJAX.ORG B.V. 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.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
|
||
|
define(function(require, exports, module) {
|
||
|
|
||
|
var event = require("../lib/event");
|
||
|
|
||
|
|
||
|
// mouse
|
||
|
function isSamePoint(p1, p2) {
|
||
|
return p1.row == p2.row && p1.column == p2.column;
|
||
|
}
|
||
|
|
||
|
function onMouseDown(e) {
|
||
|
var ev = e.domEvent;
|
||
|
var alt = ev.altKey;
|
||
|
var shift = ev.shiftKey;
|
||
|
var ctrl = e.getAccelKey();
|
||
|
var button = e.getButton();
|
||
|
|
||
|
if (e.editor.inMultiSelectMode && button == 2) {
|
||
|
e.editor.textInput.onContextMenu(e.domEvent);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!ctrl && !alt) {
|
||
|
if (button == 0 && e.editor.inMultiSelectMode)
|
||
|
e.editor.exitMultiSelectMode();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var editor = e.editor;
|
||
|
var selection = editor.selection;
|
||
|
var isMultiSelect = editor.inMultiSelectMode;
|
||
|
var pos = e.getDocumentPosition();
|
||
|
var cursor = selection.getCursor();
|
||
|
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
|
||
|
|
||
|
|
||
|
var mouseX = e.x, mouseY = e.y;
|
||
|
var onMouseSelection = function(e) {
|
||
|
mouseX = e.clientX;
|
||
|
mouseY = e.clientY;
|
||
|
};
|
||
|
|
||
|
var blockSelect = function() {
|
||
|
var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
|
||
|
var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
|
||
|
|
||
|
if (isSamePoint(screenCursor, newCursor)
|
||
|
&& isSamePoint(cursor, selection.selectionLead))
|
||
|
return;
|
||
|
screenCursor = newCursor;
|
||
|
|
||
|
editor.selection.moveCursorToPosition(cursor);
|
||
|
editor.selection.clearSelection();
|
||
|
editor.renderer.scrollCursorIntoView();
|
||
|
|
||
|
editor.removeSelectionMarkers(rectSel);
|
||
|
rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
|
||
|
rectSel.forEach(editor.addSelectionMarker, editor);
|
||
|
editor.updateSelectionMarkers();
|
||
|
};
|
||
|
|
||
|
var session = editor.session;
|
||
|
var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
|
||
|
var screenCursor = screenAnchor;
|
||
|
|
||
|
|
||
|
|
||
|
if (ctrl && !shift && !alt && button == 0) {
|
||
|
if (!isMultiSelect && inSelection)
|
||
|
return; // dragging
|
||
|
|
||
|
if (!isMultiSelect) {
|
||
|
var range = selection.toOrientedRange();
|
||
|
editor.addSelectionMarker(range);
|
||
|
}
|
||
|
|
||
|
var oldRange = selection.rangeList.rangeAtPoint(pos);
|
||
|
|
||
|
editor.once("mouseup", function() {
|
||
|
var tmpSel = selection.toOrientedRange();
|
||
|
|
||
|
if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
|
||
|
selection.substractPoint(tmpSel.cursor);
|
||
|
else {
|
||
|
if (range) {
|
||
|
editor.removeSelectionMarker(range);
|
||
|
selection.addRange(range);
|
||
|
}
|
||
|
selection.addRange(tmpSel);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
} else if (alt && button == 0) {
|
||
|
e.stop();
|
||
|
|
||
|
if (isMultiSelect && !ctrl)
|
||
|
selection.toSingleRange();
|
||
|
else if (!isMultiSelect && ctrl)
|
||
|
selection.addRange();
|
||
|
|
||
|
var rectSel = [];
|
||
|
if (shift) {
|
||
|
screenAnchor = session.documentToScreenPosition(selection.lead);
|
||
|
blockSelect();
|
||
|
} else {
|
||
|
selection.moveCursorToPosition(pos);
|
||
|
selection.clearSelection();
|
||
|
}
|
||
|
|
||
|
|
||
|
var onMouseSelectionEnd = function(e) {
|
||
|
clearInterval(timerId);
|
||
|
editor.removeSelectionMarkers(rectSel);
|
||
|
for (var i = 0; i < rectSel.length; i++)
|
||
|
selection.addRange(rectSel[i]);
|
||
|
};
|
||
|
|
||
|
var onSelectionInterval = blockSelect;
|
||
|
|
||
|
event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
|
||
|
var timerId = setInterval(function() {onSelectionInterval();}, 20);
|
||
|
|
||
|
return e.preventDefault();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
exports.onMouseDown = onMouseDown;
|
||
|
|
||
|
});
|