Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions assets/javascripts/discourse/lib/rich-editor-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,28 @@ function wrapInTag(state, node, tag) {
state.closeBlock(node);
}

// the cook writes a classless span holding a single declaration; anything
// looser is styling the browser inlined at copy time, not authored bbcode
function styledSpan(property, getAttrs) {
return {
tag: "span[style]:not([class])",
getAttrs: (dom) => {
const { style } = dom;
return style.length === 1 && style.item(0) === property
? getAttrs(style.getPropertyValue(property))
: false;
},
};
}

function colorMark(property) {
return {
attrs: { color: {} },
parseDOM: [
{
style: property,
getAttrs: (value) => {
const color = normalizeColor(value);
return color ? { color } : false;
},
},
styledSpan(property, (value) => {
const color = normalizeColor(value);
return color ? { color } : false;
}),
],
toDOM: (mark) => ["span", { style: `${property}:${mark.attrs.color}` }, 0],
};
Expand All @@ -224,24 +235,19 @@ const extension = {
bbcode_size: {
attrs: { size: {} },
parseDOM: [
{
style: "font-size",
getAttrs: (value) =>
SIZE_VALUE.test(value) ? { size: parseInt(value, 10) } : false,
},
styledSpan("font-size", (value) =>
SIZE_VALUE.test(value) ? { size: parseInt(value, 10) } : false
),
],
toDOM: (mark) => ["span", { style: `font-size:${mark.attrs.size}%` }, 0],
},
bbcode_font: {
attrs: { font: {} },
parseDOM: [
{
style: "font-family",
getAttrs: (value) => {
const font = unquoteFont(value);
return font ? { font } : false;
},
},
styledSpan("font-family", (value) => {
const font = unquoteFont(value);
return font ? { font } : false;
}),
],
toDOM: (mark) => [
"span",
Expand All @@ -256,7 +262,7 @@ const extension = {
toDOM: () => ["span", { class: "highlight" }, 0],
},
bbcode_small: {
parseDOM: [{ style: "font-size=x-small" }],
parseDOM: [styledSpan("font-size", (value) => value === "x-small" && {})],
toDOM: () => ["span", { style: "font-size:x-small" }, 0],
},
bbcode_aname: {
Expand Down
8 changes: 8 additions & 0 deletions test/javascripts/integration/rich-editor-extension-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ module(
'<p><span style="font-family: Arial, sans-serif;">stacked</span></p>',
"stacked",
],
"pasted multi-declaration span html is not claimed": [
'<p><span style="color: red; background-color: yellow;">calm</span></p>',
"calm",
],
"pasted classed span html is not claimed": [
'<p><span class="themed" style="color: red;">calm</span></p>',
"calm",
],
"pasted generic font html is not claimed": [
'<p><span style="font-family: monospace;">mono</span></p>',
"mono",
Expand Down
34 changes: 34 additions & 0 deletions test/javascripts/unit/lib/to-markdown-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { setupTest } from "ember-qunit";
import { module, test } from "qunit";
import {
registerRichEditorExtension,
resetRichEditorExtensions,
} from "discourse/lib/composer/rich-editor-extensions";
import toMarkdown from "discourse/lib/to-markdown";
import richEditorExtension from "discourse/plugins/discourse-bbcode/discourse/lib/rich-editor-extension";

module("discourse-bbcode | Unit | to-markdown", function (hooks) {
setupTest(hooks);

hooks.beforeEach(async function () {
await resetRichEditorExtensions();
registerRichEditorExtension(richEditorExtension);
});

// copying rendered content inlines theme colors onto the copied elements
test("ignores styles the browser inlined on copied content", async function (assert) {
assert.strictEqual(
await toMarkdown(
`<a class="mention" href="/u/someone" style="color: #112233; background-color: #eef2ee;">@someone</a> <code style="color: #112233; background-color: #f4f4f4;">a command</code>`
),
"@someone `a command`"
);
});

test("keeps a cooked bbcode span", async function (assert) {
assert.strictEqual(
await toMarkdown(`<span style="color:red">red</span> text`),
"[color=red]red[/color] text"
);
});
});