| /******************************************************** |
| * Deals with mouse events for clicking, drag-to-select |
| *******************************************************/ |
| |
| Controller.open(function(_) { |
| Options.p.ignoreNextMousedown = noop; |
| _.delegateMouseEvents = function() { |
| var ultimateRootjQ = this.root.jQ; |
| //drag-to-select event handling |
| this.container.bind('mousedown.mathquill', function(e) { |
| var rootjQ = $(e.target).closest('.mq-root-block'); |
| var root = Node.byId[rootjQ.attr(mqBlockId) || ultimateRootjQ.attr(mqBlockId)]; |
| var ctrlr = root.controller, cursor = ctrlr.cursor, blink = cursor.blink; |
| var textareaSpan = ctrlr.textareaSpan, textarea = ctrlr.textarea; |
| |
| e.preventDefault(); // doesn't work in IE≤8, but it's a one-line fix: |
| e.target.unselectable = true; // http://jsbin.com/yagekiji/1 |
| |
| if (cursor.options.ignoreNextMousedown(e)) return; |
| else cursor.options.ignoreNextMousedown = noop; |
| |
| var target; |
| function mousemove(e) { target = $(e.target); } |
| function docmousemove(e) { |
| if (!cursor.anticursor) cursor.startSelection(); |
| ctrlr.seek(target, e.pageX, e.pageY).cursor.select(); |
| target = undefined; |
| } |
| // outside rootjQ, the MathQuill node corresponding to the target (if any) |
| // won't be inside this root, so don't mislead Controller::seek with it |
| |
| function mouseup(e) { |
| cursor.blink = blink; |
| if (!cursor.selection) { |
| if (ctrlr.editable) { |
| cursor.show(); |
| } |
| else { |
| textareaSpan.detach(); |
| } |
| } |
| |
| // delete the mouse handlers now that we're not dragging anymore |
| rootjQ.unbind('mousemove', mousemove); |
| $(e.target.ownerDocument).unbind('mousemove', docmousemove).unbind('mouseup', mouseup); |
| } |
| |
| if (ctrlr.blurred) { |
| if (!ctrlr.editable) rootjQ.prepend(textareaSpan); |
| textarea.focus(); |
| } |
| |
| cursor.blink = noop; |
| ctrlr.seek($(e.target), e.pageX, e.pageY).cursor.startSelection(); |
| |
| rootjQ.mousemove(mousemove); |
| $(e.target.ownerDocument).mousemove(docmousemove).mouseup(mouseup); |
| // listen on document not just body to not only hear about mousemove and |
| // mouseup on page outside field, but even outside page, except iframes: https://github.com/mathquill/mathquill/commit/8c50028afcffcace655d8ae2049f6e02482346c5#commitcomment-6175800 |
| }); |
| } |
| }); |
| |
| Controller.open(function(_) { |
| _.seek = function(target, pageX, pageY) { |
| var cursor = this.notify('select').cursor; |
| |
| if (target) { |
| var nodeId = target.attr(mqBlockId) || target.attr(mqCmdId); |
| if (!nodeId) { |
| var targetParent = target.parent(); |
| nodeId = targetParent.attr(mqBlockId) || targetParent.attr(mqCmdId); |
| } |
| } |
| var node = nodeId ? Node.byId[nodeId] : this.root; |
| pray('nodeId is the id of some Node that exists', node); |
| |
| // don't clear selection until after getting node from target, in case |
| // target was selection span, otherwise target will have no parent and will |
| // seek from root, which is less accurate (e.g. fraction) |
| cursor.clearSelection().show(); |
| |
| node.seek(pageX, cursor); |
| this.scrollHoriz(); // before .selectFrom when mouse-selecting, so |
| // always hits no-selection case in scrollHoriz and scrolls slower |
| return this; |
| }; |
| }); |