mirror of
https://github.com/discourse/discourse.git
synced 2025-02-04 17:40:46 +08:00
57f97880e6
`Discourse.User.current()`
146 lines
4.2 KiB
JavaScript
146 lines
4.2 KiB
JavaScript
/*global assetPath:true */
|
|
|
|
/**
|
|
This controller supports the pop up quote button
|
|
|
|
@class QuoteButtonController
|
|
@extends Discourse.Controller
|
|
@namespace Discourse
|
|
@module Discourse
|
|
**/
|
|
Discourse.QuoteButtonController = Discourse.Controller.extend({
|
|
needs: ['topic', 'composer'],
|
|
|
|
init: function() {
|
|
this._super();
|
|
$LAB.script(assetPath('defer/html-sanitizer-bundle'));
|
|
},
|
|
|
|
/**
|
|
If the buffer is cleared, clear out other state (post)
|
|
**/
|
|
bufferChanged: function() {
|
|
if (this.blank('buffer')) this.set('post', null);
|
|
}.observes('buffer'),
|
|
|
|
/**
|
|
Save the currently selected text and displays the
|
|
"quote reply" button
|
|
|
|
@method selectText
|
|
**/
|
|
selectText: function(postId) {
|
|
// anonymous users cannot "quote-reply"
|
|
if (!Discourse.User.current()) return;
|
|
|
|
// don't display the "quote-reply" button if we can't create a post
|
|
if (!this.get('controllers.topic.content.can_create_post')) return;
|
|
|
|
var selection = window.getSelection();
|
|
// no selections
|
|
if (selection.rangeCount === 0) return;
|
|
// retrieve the selected range
|
|
var range = selection.getRangeAt(0),
|
|
cloned = range.cloneRange(),
|
|
$ancestor = $(range.commonAncestorContainer);
|
|
|
|
// don't display the "quote reply" button if you select text spanning two posts
|
|
// note: the ".contents" is here to prevent selection of the topic summary
|
|
if ($ancestor.closest('.topic-body > .contents').length === 0) {
|
|
this.set('buffer', '');
|
|
return;
|
|
}
|
|
|
|
var selectedText = Discourse.Utilities.selectedText();
|
|
if (this.get('buffer') === selectedText) return;
|
|
|
|
// we need to retrieve the post data from the posts collection in the topic controller
|
|
var posts = this.get('controllers.topic.posts'),
|
|
length = posts.length,
|
|
post;
|
|
|
|
for (var p = 0; p < length; p++) {
|
|
if (posts[p].id === postId) { post = posts[p]; break; }
|
|
}
|
|
|
|
this.set('post', post);
|
|
this.set('buffer', selectedText);
|
|
|
|
// collapse the range at the beginning of the selection
|
|
// (ie. moves the end point to the start point)
|
|
range.collapse(true);
|
|
|
|
// create a marker element containing a single invisible character
|
|
var markerElement = document.createElement("span");
|
|
markerElement.appendChild(document.createTextNode("\ufeff"));
|
|
// insert it at the beginning of our range
|
|
range.insertNode(markerElement);
|
|
|
|
// work around chrome that would sometimes lose the selection
|
|
var sel = window.getSelection();
|
|
sel.removeAllRanges();
|
|
sel.addRange(cloned);
|
|
|
|
// move the quote button at the beginning of the selection
|
|
var markerOffset = $(markerElement).offset(),
|
|
$quoteButton = $('.quote-button');
|
|
|
|
|
|
Em.run.schedule('afterRender', function() {
|
|
$quoteButton.offset({
|
|
top: markerOffset.top - $quoteButton.outerHeight() - 5,
|
|
left: markerOffset.left
|
|
});
|
|
});
|
|
|
|
// remove the marker
|
|
markerElement.parentNode.removeChild(markerElement);
|
|
},
|
|
|
|
/**
|
|
Quote the currently selected text
|
|
|
|
@method quoteText
|
|
**/
|
|
quoteText: function() {
|
|
var post = this.get('post');
|
|
var composerController = this.get('controllers.composer');
|
|
var composerOpts = {
|
|
post: post,
|
|
action: Discourse.Composer.REPLY,
|
|
draftKey: this.get('post.topic.draft_key')
|
|
};
|
|
|
|
// If the composer is associated with a different post, we don't change it.
|
|
var composerPost = composerController.get('content.post');
|
|
if (composerPost && (composerPost.get('id') !== this.get('post.id'))) {
|
|
composerOpts.post = composerPost;
|
|
}
|
|
|
|
var buffer = this.get('buffer');
|
|
var quotedText = Discourse.BBCode.buildQuoteBBCode(post, buffer);
|
|
if (composerController.wouldLoseChanges()) {
|
|
composerController.appendText(quotedText);
|
|
} else {
|
|
composerController.open(composerOpts).then(function() {
|
|
return composerController.appendText(quotedText);
|
|
});
|
|
}
|
|
this.set('buffer', '');
|
|
return false;
|
|
},
|
|
|
|
/**
|
|
Deselect the currently selected text
|
|
|
|
@method deselectText
|
|
**/
|
|
deselectText: function() {
|
|
// clear selected text
|
|
window.getSelection().removeAllRanges();
|
|
// clean up the buffer
|
|
this.set('buffer', '');
|
|
}
|
|
|
|
});
|