diff --git a/app/assets/javascripts/discourse/app/components/d-editor.js b/app/assets/javascripts/discourse/app/components/d-editor.js index 87cec774a95..b8fda2c5b8e 100644 --- a/app/assets/javascripts/discourse/app/components/d-editor.js +++ b/app/assets/javascripts/discourse/app/components/d-editor.js @@ -9,7 +9,7 @@ import discourseComputed, { } from "discourse-common/utils/decorators"; import { categoryHashtagTriggerRule } from "discourse/lib/category-hashtags"; import { search as searchCategoryTag } from "discourse/lib/category-tag-search"; -import { cookAsync } from "discourse/lib/text"; +import { generateCookFunction } from "discourse/lib/text"; import { getRegister } from "discourse-common/lib/get-owner"; import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { siteDir } from "discourse/lib/text-direction"; @@ -344,15 +344,26 @@ export default Component.extend({ return toolbar; }, + cachedCookAsync(text) { + if (this._cachedCookFunction) { + return Promise.resolve(this._cachedCookFunction(text)); + } + + const markdownOptions = this.markdownOptions || {}; + return generateCookFunction(markdownOptions).then(cook => { + this._cachedCookFunction = cook; + return cook(text); + }); + }, + _updatePreview() { if (this._state !== "inDOM") { return; } const value = this.value; - const markdownOptions = this.markdownOptions || {}; - cookAsync(value, markdownOptions).then(cooked => { + this.cachedCookAsync(value).then(cooked => { if (this.isDestroyed) { return; } diff --git a/app/assets/javascripts/discourse/app/lib/text.js b/app/assets/javascripts/discourse/app/lib/text.js index afca9415f71..a6d5bf21efa 100644 --- a/app/assets/javascripts/discourse/app/lib/text.js +++ b/app/assets/javascripts/discourse/app/lib/text.js @@ -38,6 +38,15 @@ export function cookAsync(text, options) { return loadMarkdownIt().then(() => cook(text, options)); } +// Warm up pretty text with a set of options and return a function +// which can be used to cook without rebuilding prettytext every time +export function generateCookFunction(options) { + return loadMarkdownIt().then(() => { + const prettyText = createPrettyText(options); + return text => prettyText.cook(text); + }); +} + export function sanitize(text, options) { return textSanitize(text, new WhiteLister(options)); }