mirror of
https://github.com/discourse/discourse.git
synced 2024-12-01 00:13:45 +08:00
Merge pull request #561 from ZogStriP/fix-quote-reply-gets-in-the-way
FIX: "Quote Reply" button gets in the way
This commit is contained in:
commit
865cf011a2
|
@ -10,7 +10,6 @@
|
||||||
**/
|
**/
|
||||||
Discourse.QuoteButtonController = Discourse.Controller.extend({
|
Discourse.QuoteButtonController = Discourse.Controller.extend({
|
||||||
needs: ['topic', 'composer'],
|
needs: ['topic', 'composer'],
|
||||||
started: null,
|
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
this._super();
|
this._super();
|
||||||
|
@ -19,42 +18,56 @@ Discourse.QuoteButtonController = Discourse.Controller.extend({
|
||||||
|
|
||||||
// If the buffer is cleared, clear out other state (post)
|
// If the buffer is cleared, clear out other state (post)
|
||||||
bufferChanged: (function() {
|
bufferChanged: (function() {
|
||||||
if (this.blank('buffer')) {
|
if (this.blank('buffer')) this.set('post', null);
|
||||||
return this.set('post', null);
|
|
||||||
}
|
|
||||||
}).observes('buffer'),
|
}).observes('buffer'),
|
||||||
|
|
||||||
mouseDown: function(e) {
|
|
||||||
this.started = [e.pageX, e.pageY];
|
|
||||||
},
|
|
||||||
|
|
||||||
mouseUp: function(e) {
|
|
||||||
if (this.started[1] > e.pageY) {
|
|
||||||
this.started = [e.pageX, e.pageY];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
selectText: function(e) {
|
selectText: function(e) {
|
||||||
var $quoteButton, left, selectedText, top;
|
// anonymous users cannot "quote-reply"
|
||||||
if (!Discourse.get('currentUser')) return;
|
if (!Discourse.get('currentUser')) return;
|
||||||
|
// there is no need to display the "quote-reply" button if we can't create a post
|
||||||
if (!this.get('controllers.topic.content.can_create_post')) return;
|
if (!this.get('controllers.topic.content.can_create_post')) return;
|
||||||
|
|
||||||
selectedText = Discourse.Utilities.selectedText();
|
// retrieve the selected range
|
||||||
|
var range = window.getSelection().getRangeAt(0).cloneRange();
|
||||||
|
|
||||||
|
// do not be present the "quote reply" button if you select text spanning two posts
|
||||||
|
// this basically look for the first "DIV" container...
|
||||||
|
var commonDivAncestorContainer = range.commonAncestorContainer;
|
||||||
|
while (commonDivAncestorContainer.nodeName !== 'DIV') commonDivAncestorContainer = commonDivAncestorContainer.parentNode;
|
||||||
|
// ... and check it has the 'cooked' class (which indicates we're in a post)
|
||||||
|
if (commonDivAncestorContainer.className.indexOf('cooked') === -1) return;
|
||||||
|
|
||||||
|
var selectedText = Discourse.Utilities.selectedText();
|
||||||
if (this.get('buffer') === selectedText) return;
|
if (this.get('buffer') === selectedText) return;
|
||||||
if (this.get('lastSelected') === selectedText) return;
|
if (this.get('lastSelected') === selectedText) return;
|
||||||
|
|
||||||
this.set('post', e.context);
|
this.set('post', e.context);
|
||||||
this.set('buffer', selectedText);
|
this.set('buffer', selectedText);
|
||||||
top = e.pageY + 5;
|
|
||||||
left = e.pageX + 5;
|
// collapse the range at the beginning of the selection
|
||||||
$quoteButton = $('.quote-button');
|
// (ie. moves the end point to the start point)
|
||||||
if (this.started) {
|
range.collapse(true);
|
||||||
top = this.started[1] - 50;
|
|
||||||
left = ((left - this.started[0]) / 2) + this.started[0] - ($quoteButton.width() / 2);
|
// create a marker element containing a single invisible character
|
||||||
}
|
var markerElement = document.createElement("span");
|
||||||
$quoteButton.css({ top: top, left: left });
|
markerElement.appendChild(document.createTextNode("\ufeff"));
|
||||||
this.started = null;
|
// insert it at the beginning of our range
|
||||||
return false;
|
range.insertNode(markerElement);
|
||||||
|
|
||||||
|
// find marker position (cf. http://www.quirksmode.org/js/findpos.html)
|
||||||
|
var obj = markerElement, left = 0, top = 0;
|
||||||
|
do {
|
||||||
|
left += obj.offsetLeft;
|
||||||
|
top += obj.offsetTop;
|
||||||
|
obj = obj.offsetParent;
|
||||||
|
} while (obj.offsetParent);
|
||||||
|
|
||||||
|
// move the quote button at the beginning of the selection
|
||||||
|
var $quoteButton = $('.quote-button');
|
||||||
|
$quoteButton.css({ top: top - $quoteButton.outerHeight(), left: left });
|
||||||
|
|
||||||
|
// remove the marker
|
||||||
|
markerElement.parentNode.removeChild(markerElement);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,8 +29,7 @@ Discourse.PostView = Discourse.View.extend({
|
||||||
}).property('parentView'),
|
}).property('parentView'),
|
||||||
|
|
||||||
postTypeClass: (function() {
|
postTypeClass: (function() {
|
||||||
if (this.get('post.post_type') === Discourse.get('site.post_types.moderator_action')) return 'moderator';
|
return this.get('post.post_type') === Discourse.get('site.post_types.moderator_action') ? 'moderator' : 'regular';
|
||||||
return 'regular';
|
|
||||||
}).property('post.post_type'),
|
}).property('post.post_type'),
|
||||||
|
|
||||||
// If the cooked content changed, add the quote controls
|
// If the cooked content changed, add the quote controls
|
||||||
|
@ -59,12 +58,7 @@ Discourse.PostView = Discourse.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
selectText: (function() {
|
selectText: (function() {
|
||||||
if (this.get('post.selected')) {
|
return this.get('post.selected') ? Em.String.i18n('topic.multi_select.selected', { count: this.get('controller.selectedCount') }) : Em.String.i18n('topic.multi_select.select');
|
||||||
return Em.String.i18n('topic.multi_select.selected', {
|
|
||||||
count: this.get('controller.selectedCount')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Em.String.i18n('topic.multi_select.select');
|
|
||||||
}).property('post.selected', 'controller.selectedCount'),
|
}).property('post.selected', 'controller.selectedCount'),
|
||||||
|
|
||||||
repliesHidden: (function() {
|
repliesHidden: (function() {
|
||||||
|
@ -198,10 +192,9 @@ Discourse.PostView = Discourse.View.extend({
|
||||||
var postView = this;
|
var postView = this;
|
||||||
|
|
||||||
return this.$('aside.quote').each(function(i, e) {
|
return this.$('aside.quote').each(function(i, e) {
|
||||||
var $aside, $title;
|
var $aside = $(e);
|
||||||
$aside = $(e);
|
|
||||||
postView.updateQuoteElements($aside, 'chevron-down');
|
postView.updateQuoteElements($aside, 'chevron-down');
|
||||||
$title = $('.title', $aside);
|
var $title = $('.title', $aside);
|
||||||
|
|
||||||
// Unless it's a full quote, allow click to expand
|
// Unless it's a full quote, allow click to expand
|
||||||
if (!($aside.data('full') || $title.data('has-quote-controls'))) {
|
if (!($aside.data('full') || $title.data('has-quote-controls'))) {
|
||||||
|
@ -261,5 +254,3 @@ Discourse.PostView = Discourse.View.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,23 +16,21 @@ Discourse.QuoteButtonView = Discourse.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
hasBuffer: (function() {
|
hasBuffer: (function() {
|
||||||
if (this.present('controller.buffer')) return 'visible';
|
return this.present('controller.buffer') ? 'visible' : null;
|
||||||
return null;
|
|
||||||
}).property('controller.buffer'),
|
}).property('controller.buffer'),
|
||||||
|
|
||||||
willDestroyElement: function() {
|
willDestroyElement: function() {
|
||||||
$(document).unbind("mousedown.quote-button");
|
$(document).off("mousedown.quote-button");
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement: function() {
|
didInsertElement: function() {
|
||||||
// Clear quote button if they click elsewhere
|
// Clear quote button if they click elsewhere
|
||||||
var quoteButtonView = this;
|
var quoteButtonView = this;
|
||||||
return $(document).bind("mousedown.quote-button", function(e) {
|
$(document).on("mousedown.quote-button", function(e) {
|
||||||
if ($(e.target).hasClass('quote-button')) return;
|
if ($(e.target).hasClass('quote-button')) return;
|
||||||
if ($(e.target).hasClass('create')) return;
|
if ($(e.target).hasClass('create')) return;
|
||||||
quoteButtonView.controller.mouseDown(e);
|
|
||||||
quoteButtonView.set('controller.lastSelected', quoteButtonView.get('controller.buffer'));
|
quoteButtonView.set('controller.lastSelected', quoteButtonView.get('controller.buffer'));
|
||||||
return quoteButtonView.set('controller.buffer', '');
|
quoteButtonView.set('controller.buffer', '');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -42,5 +40,3 @@ Discourse.QuoteButtonView = Discourse.View.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,6 @@
|
||||||
border: 5px solid rgba(0, 0, 0, 0.75);
|
border: 5px solid rgba(0, 0, 0, 0.75);
|
||||||
top: 10px;
|
top: 10px;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
z-index: 99999;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
display: none;
|
||||||
@include border-radius-all(4px);
|
@include border-radius-all(4px);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user