mirror of
https://github.com/discourse/discourse.git
synced 2025-03-26 03:45:34 +08:00
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
// we don't want to deselect when we click on buttons that use it
|
|
function ignoreElements(e) {
|
|
const $target = $(e.target);
|
|
return $target.hasClass('quote-button') ||
|
|
$target.closest('.create').length ||
|
|
$target.closest('.reply-new').length;
|
|
}
|
|
|
|
export default Ember.View.extend({
|
|
classNames: ['quote-button'],
|
|
classNameBindings: ['visible'],
|
|
isMouseDown: false,
|
|
isTouchInProgress: false,
|
|
|
|
/**
|
|
The button is visible whenever there is something in the buffer
|
|
(ie. something has been selected)
|
|
**/
|
|
visible: Em.computed.notEmpty('controller.buffer'),
|
|
|
|
render(buffer) {
|
|
buffer.push(I18n.t("post.quote_reply"));
|
|
},
|
|
|
|
/**
|
|
Binds to the following global events:
|
|
- `mousedown` to clear the quote button if they click elsewhere.
|
|
- `mouseup` to trigger the display of the quote button.
|
|
- `selectionchange` to make the selection work under iOS
|
|
|
|
@method didInsertElement
|
|
**/
|
|
didInsertElement() {
|
|
const controller = this.get('controller'),
|
|
view = this;
|
|
|
|
var onSelectionChanged = function() {
|
|
view.selectText(window.getSelection().anchorNode, controller);
|
|
};
|
|
|
|
// Windows Phone hack, it is not firing the touch events
|
|
// best we can do is debounce this so we dont keep locking up
|
|
// the selection when we add the caret to measure where we place
|
|
// the quote reply widget
|
|
//
|
|
// Same hack applied to Android cause it has unreliable touchend
|
|
const isAndroid = this.capabilities.isAndroid;
|
|
if (this.capabilities.isWinphone || isAndroid) {
|
|
onSelectionChanged = _.debounce(onSelectionChanged, 500);
|
|
}
|
|
|
|
$(document)
|
|
.on("mousedown.quote-button", function(e) {
|
|
view.set('isMouseDown', true);
|
|
|
|
if (ignoreElements(e)) { return; }
|
|
|
|
// deselects only when the user left click
|
|
// (allows anyone to `extend` their selection using shift+click)
|
|
if (!window.getSelection().isCollapsed &&
|
|
e.which === 1 &&
|
|
!e.shiftKey) controller.deselectText();
|
|
})
|
|
.on('mouseup.quote-button', function(e) {
|
|
if (ignoreElements(e)) { return; }
|
|
|
|
view.selectText(e.target, controller);
|
|
view.set('isMouseDown', false);
|
|
})
|
|
.on('selectionchange', function() {
|
|
// there is no need to handle this event when the mouse is down
|
|
// or if there a touch in progress
|
|
if (view.get('isMouseDown') || view.get('isTouchInProgress')) return;
|
|
// `selection.anchorNode` is used as a target
|
|
onSelectionChanged();
|
|
});
|
|
|
|
// Android is dodgy, touchend often will not fire
|
|
// https://code.google.com/p/android/issues/detail?id=19827
|
|
if (!isAndroid) {
|
|
$(document)
|
|
.on('touchstart.quote-button', function(){
|
|
view.set('isTouchInProgress', true);
|
|
})
|
|
.on('touchend.quote-button', function(){
|
|
view.set('isTouchInProgress', false);
|
|
});
|
|
}
|
|
},
|
|
|
|
selectText(target, controller) {
|
|
const $target = $(target);
|
|
// breaks if quoting has been disabled by the user
|
|
if (!Discourse.User.currentProp('enable_quoting')) return;
|
|
// retrieve the post id from the DOM
|
|
const postId = $target.closest('.boxed, .reply').data('post-id');
|
|
// select the text
|
|
if (postId) controller.selectText(postId);
|
|
},
|
|
|
|
willDestroyElement() {
|
|
$(document)
|
|
.off("mousedown.quote-button")
|
|
.off("mouseup.quote-button")
|
|
.off("touchstart.quote-button")
|
|
.off("touchend.quote-button")
|
|
.off("selectionchange");
|
|
},
|
|
|
|
click(e) {
|
|
e.stopPropagation();
|
|
return this.get('controller').quoteText(e);
|
|
}
|
|
|
|
});
|