mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 13:03:39 +08:00
FEATURE: Convert HTML to Markdown while pasting in composer
This commit is contained in:
parent
067d454937
commit
6e054b2572
|
@ -9,6 +9,8 @@ import { emojiUrlFor } from 'discourse/lib/text';
|
|||
import { getRegister } from 'discourse-common/lib/get-owner';
|
||||
import { findRawTemplate } from 'discourse/lib/raw-templates';
|
||||
import { determinePostReplaceSelection, clipboardData } from 'discourse/lib/utilities';
|
||||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
import deprecated from 'discourse-common/lib/deprecated';
|
||||
|
||||
// Our head can be a static string or a function that returns a string
|
||||
|
@ -616,7 +618,7 @@ export default Ember.Component.extend({
|
|||
Ember.run.scheduleOnce("afterRender", () => $textarea.focus());
|
||||
},
|
||||
|
||||
_detectTable(text) {
|
||||
_extractTable(text) {
|
||||
if (text.endsWith("\n")) {
|
||||
text = text.substring(0, text.length - 1);
|
||||
}
|
||||
|
@ -639,21 +641,43 @@ export default Ember.Component.extend({
|
|||
|
||||
paste(e) {
|
||||
const clipboard = clipboardData(e);
|
||||
const types = clipboard.types;
|
||||
let preventDefault = false;
|
||||
const placeholder = `${ I18n.t('pasting') }`;
|
||||
let plainText = clipboard.getData("text/plain");
|
||||
const html = clipboard.getData("text/html");
|
||||
let handled = false;
|
||||
|
||||
if (types.some(t => t === "text/plain")) {
|
||||
const text = clipboard.getData("text/plain");
|
||||
const table = this._detectTable(text);
|
||||
if (plainText) {
|
||||
plainText = plainText.trim();
|
||||
const table = this._extractTable(plainText);
|
||||
if (table) {
|
||||
this._addText(this._getSelected(), table);
|
||||
preventDefault = true;
|
||||
handled = true;
|
||||
}
|
||||
} else if (types.some(t => t === "Files")) {
|
||||
preventDefault = true;
|
||||
}
|
||||
|
||||
if (preventDefault) {
|
||||
if (html && !handled) {
|
||||
const self = this;
|
||||
|
||||
this.appEvents.trigger('composer:insert-text', placeholder);
|
||||
handled = true;
|
||||
|
||||
ajax('/composer/parse_html', {
|
||||
type: 'POST',
|
||||
data: { html }
|
||||
}).then(response => {
|
||||
self.appEvents.trigger('composer:replace-text', placeholder, response.markdown);
|
||||
}).catch(error => {
|
||||
if (plainText) {
|
||||
self.appEvents.trigger('composer:replace-text', placeholder, plainText);
|
||||
} else {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const uploadFiles = clipboard.types.includes("Files") && !plainText && !html;
|
||||
|
||||
if (handled || uploadFiles) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
|
|
12
app/controllers/composer_controller.rb
Normal file
12
app/controllers/composer_controller.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
require_dependency 'html_to_markdown'
|
||||
|
||||
class ComposerController < ApplicationController
|
||||
|
||||
before_action :ensure_logged_in
|
||||
|
||||
def parse_html
|
||||
markdown_text = HtmlToMarkdown.new(params[:html]).to_markdown
|
||||
|
||||
render json: { markdown: markdown_text }
|
||||
end
|
||||
end
|
|
@ -309,6 +309,8 @@ en:
|
|||
uploading_filename: "Uploading {{filename}}..."
|
||||
uploaded: "Uploaded!"
|
||||
|
||||
pasting: "Pasting..."
|
||||
|
||||
enable: "Enable"
|
||||
disable: "Disable"
|
||||
undo: "Undo"
|
||||
|
|
|
@ -301,6 +301,7 @@ Discourse::Application.routes.draw do
|
|||
get "session/current" => "session#current"
|
||||
get "session/csrf" => "session#csrf"
|
||||
get "composer_messages" => "composer_messages#index"
|
||||
post "composer/parse_html" => "composer#parse_html"
|
||||
|
||||
resources :static
|
||||
post "login" => "static#enter", constraints: { format: /(json|html)/ }
|
||||
|
|
26
spec/requests/composer_controller_spec.rb
Normal file
26
spec/requests/composer_controller_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ComposerController do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
describe '#parse_html' do
|
||||
|
||||
it "should not be able access without sign in" do
|
||||
expect {
|
||||
post "/composer/parse_html.json", params: {
|
||||
html: "<strong>hello</strong>"
|
||||
}
|
||||
}.to raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
it "should convert html tags to markdown text" do
|
||||
sign_in(user)
|
||||
|
||||
post "/composer/parse_html.json", params: {
|
||||
html: "<strong>hello</strong>"
|
||||
}
|
||||
|
||||
expect(response.body).to eq("{\"markdown\":\"**hello**\"}")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user