Merge pull request #4272 from tgxworld/add_details_to_popup_menu

FEATURE: Add details to popup menu options.
This commit is contained in:
Guo Xiang Tan 2016-06-17 16:04:57 +08:00 committed by GitHub
commit 44b691a1b4
7 changed files with 161 additions and 27 deletions

View file

@ -388,6 +388,9 @@ export default Ember.Component.extend({
left = replyWidth - popupWidth - 40; left = replyWidth - popupWidth - 40;
} }
const selected = toolbarEvent.selected;
toolbarEvent.selectText(selected.start, selected.end - selected.start);
this.sendAction('showOptions', toolbarEvent, this.sendAction('showOptions', toolbarEvent,
{ position: "absolute", left, top }); { position: "absolute", left, top });
}, },

View file

@ -461,7 +461,7 @@ export default Ember.Component.extend({
this.set('value', `${pre}${contents}${post}`); this.set('value', `${pre}${contents}${post}`);
if (lines.length === 1 && tlen > 0) { if (lines.length === 1 && tlen > 0) {
this._selectText(sel.start + hlen, contents.length - hlen - hlen); this._selectText(sel.start + hlen, sel.value.length);
} else { } else {
this._selectText(sel.start, contents.length); this._selectText(sel.start, contents.length);
} }
@ -507,6 +507,7 @@ export default Ember.Component.extend({
const selected = this._getSelected(button.trimLeading); const selected = this._getSelected(button.trimLeading);
const toolbarEvent = { const toolbarEvent = {
selected, selected,
selectText: (from, length) => this._selectText(from, length),
applySurround: (head, tail, exampleKey) => this._applySurround(selected, head, tail, exampleKey), applySurround: (head, tail, exampleKey) => this._applySurround(selected, head, tail, exampleKey),
applyList: (head, exampleKey) => this._applyList(selected, head, exampleKey), applyList: (head, exampleKey) => this._applyList(selected, head, exampleKey),
addText: text => this._addText(selected, text), addText: text => this._addText(selected, text),

View file

@ -62,19 +62,6 @@ export default Ember.Controller.extend({
topic: null, topic: null,
linkLookup: null, linkLookup: null,
init() {
this._super();
addPopupMenuOptionsCallback(function() {
return {
action: 'toggleWhisper',
icon: 'eye-slash',
label: 'composer.toggle_whisper',
condition: "canWhisper"
};
});
},
showToolbar: Em.computed({ showToolbar: Em.computed({
get(){ get(){
const keyValueStore = this.container.lookup('key-value-store:main'); const keyValueStore = this.container.lookup('key-value-store:main');
@ -116,10 +103,7 @@ export default Ember.Controller.extend({
return popupMenuOptions ? popupMenuOptions.some(option => option.condition) : false; return popupMenuOptions ? popupMenuOptions.some(option => option.condition) : false;
}, },
@computed("model.composeState") _setupPopupMenuOption(callback) {
popupMenuOptions(composeState) {
if (composeState === 'open') {
return _popupMenuOptionsCallbacks.map(callback => {
let option = callback(); let option = callback();
if (option.condition) { if (option.condition) {
@ -129,7 +113,25 @@ export default Ember.Controller.extend({
} }
return option; return option;
}); },
@computed("model.composeState")
popupMenuOptions(composeState) {
if (composeState === 'open') {
let options = [];
options.push(this._setupPopupMenuOption(() => {
return {
action: 'toggleWhisper',
icon: 'eye-slash',
label: 'composer.toggle_whisper',
condition: "canWhisper"
};
}));
return options.concat(_popupMenuOptionsCallbacks.map(callback => {
return this._setupPopupMenuOption(callback);
}));
} }
}, },

View file

@ -231,7 +231,7 @@ class PluginApi {
* Example: * Example:
* *
* ``` * ```
* api.addToolbarPopupMenuOptionsCallback(function() { * api.addToolbarPopupMenuOptionsCallback(() => {
* return { * return {
* action: 'toggleWhisper', * action: 'toggleWhisper',
* icon: 'eye-slash', * icon: 'eye-slash',

View file

@ -1,11 +1,35 @@
import { withPluginApi } from 'discourse/lib/plugin-api'; import { withPluginApi } from 'discourse/lib/plugin-api';
function initializeDetails(api) {
api.decorateCooked($elem => $("details", $elem).details());
api.addToolbarPopupMenuOptionsCallback(() => {
return {
action: 'insertDetails',
icon: 'caret-right',
label: 'details.title'
};
});
const ComposerController = api.container.lookup("controller:composer");
ComposerController.reopen({
actions: {
insertDetails() {
this.get("toolbarEvent").applySurround(
"[details=",
`]${I18n.t("composer.details_text")}[/details]`,
"details_title")
;
}
}
});
}
export default { export default {
name: "apply-details", name: "apply-details",
initialize() { initialize() {
withPluginApi('0.1', api => { withPluginApi('0.1', initializeDetails);
api.decorateCooked($elem => $("details", $elem).details());
});
} }
}; };

View file

@ -0,0 +1,8 @@
en:
js:
details:
title: Insert Details
composer:
details_title: Summary
details_text: "This text will be hidden"

View file

@ -0,0 +1,96 @@
import { acceptance } from "helpers/qunit-helpers";
acceptance('composer', { loggedIn: true });
function findTextarea() {
return find(".d-editor-input")[0];
}
test('details button', () => {
visit("/");
andThen(() => {
ok(exists('#create-topic'), 'the create button is visible');
});
click('#create-topic');
click('button.options');
click('.popup-menu .fa-caret-right');
andThen(() => {
equal(
find(".d-editor-input").val(),
`[details=${I18n.t("composer.details_title")}]${I18n.t("composer.details_text")}[/details]`,
'it should contain the right output'
);
});
fillIn('.d-editor-input', "This is my title");
andThen(() => {
const textarea = findTextarea();
textarea.selectionStart = 0;
textarea.selectionEnd = textarea.value.length;
});
click('button.options');
click('.popup-menu .fa-caret-right');
andThen(() => {
equal(
find(".d-editor-input").val(),
`[details=This is my title]${I18n.t("composer.details_text")}[/details]`,
'it should contain the right output'
);
const textarea = findTextarea();
equal(textarea.selectionStart, 9, 'it should start highlighting at the right position');
equal(textarea.selectionEnd, 25, 'it should end highlighting at the right position');
});
fillIn('.d-editor-input', "Before some text in between After");
andThen(() => {
const textarea = findTextarea();
textarea.selectionStart = 7;
textarea.selectionEnd = 28;
});
click('button.options');
click('.popup-menu .fa-caret-right');
andThen(() => {
equal(
find(".d-editor-input").val(),
`Before [details=some text in between]${I18n.t("composer.details_text")}[/details] After`,
'it should contain the right output'
);
const textarea = findTextarea();
equal(textarea.selectionStart, 16, 'it should start highlighting at the right position');
equal(textarea.selectionEnd, 36, 'it should end highlighting at the right position');
});
fillIn('.d-editor-input', "Before\nsome text in between\nAfter");
andThen(() => {
const textarea = findTextarea();
textarea.selectionStart = 7;
textarea.selectionEnd = 28;
});
click('button.options');
click('.popup-menu .fa-caret-right');
andThen(() => {
equal(
find(".d-editor-input").val(),
`Before\n[details=some text in between]${I18n.t("composer.details_text")}[/details]\nAfter`,
'it should contain the right output'
);
const textarea = findTextarea();
equal(textarea.selectionStart, 16, 'it should start highlighting at the right position');
equal(textarea.selectionEnd, 36, 'it should end highlighting at the right position');
});
});