From 08acf51be000396cb31ea3b8e47c6b113827c99f Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Thu, 18 Feb 2021 16:07:26 +0200 Subject: [PATCH] FEATURE: Use diffhtml to update composer preview (#11237) Displaying videos, animated GIFs or any kind of rich content in preview used to refresh on every keystroke, which could cause performance problems. --- .../discourse/app/components/d-editor.js | 31 +++++++++++++++ .../discourse/app/lib/link-hashtags.js | 27 ++++++------- .../discourse/app/lib/link-mentions.js | 33 ++++++++-------- .../discourse/app/lib/load-oneboxes.js | 38 ++++++++++++------- .../discourse/app/lib/public-js-versions.js | 1 + .../app/templates/components/d-editor.hbs | 6 ++- .../javascripts/pretty-text/addon/oneboxer.js | 11 ++++-- .../pretty-text/addon/upload-short-url.js | 17 +++++++-- config/locales/server.en.yml | 2 + config/site_settings.yml | 4 ++ lib/tasks/javascript.rake | 3 ++ package.json | 1 + public/javascripts/diffhtml.min.js | 1 + .../diffhtml/1.0.0-beta.18/diffhtml.min.js | 1 + yarn.lock | 7 ++++ 15 files changed, 129 insertions(+), 54 deletions(-) create mode 100644 public/javascripts/diffhtml.min.js create mode 100644 public/javascripts/diffhtml/1.0.0-beta.18/diffhtml.min.js diff --git a/app/assets/javascripts/discourse/app/components/d-editor.js b/app/assets/javascripts/discourse/app/components/d-editor.js index eb0e074b94..bb610eb5a7 100644 --- a/app/assets/javascripts/discourse/app/components/d-editor.js +++ b/app/assets/javascripts/discourse/app/components/d-editor.js @@ -24,6 +24,11 @@ import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { getRegister } from "discourse-common/lib/get-owner"; import { isEmpty } from "@ember/utils"; import { isTesting } from "discourse-common/config/environment"; +import { linkSeenHashtags } from "discourse/lib/link-hashtags"; +import { linkSeenMentions } from "discourse/lib/link-mentions"; +import { loadOneboxes } from "discourse/lib/load-oneboxes"; +import loadScript from "discourse/lib/load-script"; +import { resolveCachedShortUrls } from "pretty-text/upload-short-url"; import { search as searchCategoryTag } from "discourse/lib/category-tag-search"; import { inject as service } from "@ember/service"; import showModal from "discourse/lib/show-modal"; @@ -389,6 +394,32 @@ export default Component.extend({ } this.set("preview", cooked); + + if (this.siteSettings.enable_diffhtml_preview) { + const cookedElement = document.createElement("div"); + cookedElement.innerHTML = cooked; + + linkSeenHashtags($(cookedElement)); + linkSeenMentions($(cookedElement), this.siteSettings); + resolveCachedShortUrls(this.siteSettings, cookedElement); + loadOneboxes( + cookedElement, + null, + null, + null, + this.siteSettings.max_oneboxes_per_post, + false, + true + ); + + loadScript("/javascripts/diffhtml.min.js").then(() => { + window.diff.innerHTML( + this.element.querySelector(".d-editor-preview"), + cookedElement.innerHTML + ); + }); + } + schedule("afterRender", () => { if (this._state !== "inDOM") { return; diff --git a/app/assets/javascripts/discourse/app/lib/link-hashtags.js b/app/assets/javascripts/discourse/app/lib/link-hashtags.js index c6c633d880..1d6f275a7c 100644 --- a/app/assets/javascripts/discourse/app/lib/link-hashtags.js +++ b/app/assets/javascripts/discourse/app/lib/link-hashtags.js @@ -1,7 +1,6 @@ import { TAG_HASHTAG_POSTFIX } from "discourse/lib/tag-hashtags"; import { ajax } from "discourse/lib/ajax"; import { replaceSpan } from "discourse/lib/category-hashtags"; -import { schedule } from "@ember/runloop"; const categoryHashtags = {}; const tagHashtags = {}; @@ -15,21 +14,19 @@ export function linkSeenHashtags($elem) { const slugs = [...$hashtags.map((_, hashtag) => hashtag.innerText.substr(1))]; - schedule("afterRender", () => { - $hashtags.each((index, hashtag) => { - let slug = slugs[index]; - const hasTagSuffix = slug.endsWith(TAG_HASHTAG_POSTFIX); - if (hasTagSuffix) { - slug = slug.substr(0, slug.length - TAG_HASHTAG_POSTFIX.length); - } + $hashtags.each((index, hashtag) => { + let slug = slugs[index]; + const hasTagSuffix = slug.endsWith(TAG_HASHTAG_POSTFIX); + if (hasTagSuffix) { + slug = slug.substr(0, slug.length - TAG_HASHTAG_POSTFIX.length); + } - const lowerSlug = slug.toLowerCase(); - if (categoryHashtags[lowerSlug] && !hasTagSuffix) { - replaceSpan($(hashtag), slug, categoryHashtags[lowerSlug]); - } else if (tagHashtags[lowerSlug]) { - replaceSpan($(hashtag), slug, tagHashtags[lowerSlug]); - } - }); + const lowerSlug = slug.toLowerCase(); + if (categoryHashtags[lowerSlug] && !hasTagSuffix) { + replaceSpan($(hashtag), slug, categoryHashtags[lowerSlug]); + } else if (tagHashtags[lowerSlug]) { + replaceSpan($(hashtag), slug, tagHashtags[lowerSlug]); + } }); return slugs diff --git a/app/assets/javascripts/discourse/app/lib/link-mentions.js b/app/assets/javascripts/discourse/app/lib/link-mentions.js index fa3ff8ec0b..577a60c4db 100644 --- a/app/assets/javascripts/discourse/app/lib/link-mentions.js +++ b/app/assets/javascripts/discourse/app/lib/link-mentions.js @@ -1,7 +1,6 @@ import { ajax } from "discourse/lib/ajax"; import { formatUsername } from "discourse/lib/utilities"; import getURL from "discourse-common/lib/get-url"; -import { schedule } from "@ember/runloop"; import { userPath } from "discourse/lib/url"; let maxGroupMention; @@ -42,23 +41,21 @@ const checked = {}; const cannotSee = []; function updateFound($mentions, usernames) { - schedule("afterRender", function () { - $mentions.each((i, e) => { - const $e = $(e); - const username = usernames[i]; - if (found[username.toLowerCase()]) { - replaceSpan($e, username, { cannot_see: cannotSee[username] }); - } else if (mentionableGroups[username]) { - replaceSpan($e, username, { - group: true, - mentionable: mentionableGroups[username], - }); - } else if (foundGroups[username]) { - replaceSpan($e, username, { group: true }); - } else if (checked[username]) { - $e.addClass("mention-tested"); - } - }); + $mentions.each((i, e) => { + const $e = $(e); + const username = usernames[i]; + if (found[username.toLowerCase()]) { + replaceSpan($e, username, { cannot_see: cannotSee[username] }); + } else if (mentionableGroups[username]) { + replaceSpan($e, username, { + group: true, + mentionable: mentionableGroups[username], + }); + } else if (foundGroups[username]) { + replaceSpan($e, username, { group: true }); + } else if (checked[username]) { + $e.addClass("mention-tested"); + } }); } diff --git a/app/assets/javascripts/discourse/app/lib/load-oneboxes.js b/app/assets/javascripts/discourse/app/lib/load-oneboxes.js index 7a88039178..29ced7b591 100644 --- a/app/assets/javascripts/discourse/app/lib/load-oneboxes.js +++ b/app/assets/javascripts/discourse/app/lib/load-oneboxes.js @@ -7,7 +7,8 @@ export function loadOneboxes( topicId, categoryId, maxOneboxes, - refresh + refresh, + offline ) { const oneboxes = {}; const inlineOneboxes = {}; @@ -41,17 +42,22 @@ export function loadOneboxes( } }); - let newBoxes = 0; - if (Object.keys(oneboxes).length > 0) { - _loadOneboxes(oneboxes, ajax, newBoxes, topicId, categoryId, refresh); + _loadOneboxes({ + oneboxes, + ajax, + topicId, + categoryId, + refresh, + offline, + }); } if (Object.keys(inlineOneboxes).length > 0) { _loadInlineOneboxes(inlineOneboxes, ajax, topicId, categoryId); } - return newBoxes; + return Object.keys(oneboxes).length + Object.keys(inlineOneboxes).length; } function _loadInlineOneboxes(inline, ajax, topicId, categoryId) { @@ -61,18 +67,24 @@ function _loadInlineOneboxes(inline, ajax, topicId, categoryId) { }); } -function _loadOneboxes(oneboxes, ajax, count, topicId, categoryId, refresh) { +function _loadOneboxes({ + oneboxes, + ajax, + topicId, + categoryId, + refresh, + offline, +}) { Object.values(oneboxes).forEach((onebox) => { - onebox.forEach((o) => { + onebox.forEach((elem) => { load({ - elem: o, - refresh, + elem, ajax, - categoryId: categoryId, - topicId: topicId, + categoryId, + topicId, + refresh, + offline, }); - - count++; }); }); } diff --git a/app/assets/javascripts/discourse/app/lib/public-js-versions.js b/app/assets/javascripts/discourse/app/lib/public-js-versions.js index ba845fe8a7..7130af7359 100644 --- a/app/assets/javascripts/discourse/app/lib/public-js-versions.js +++ b/app/assets/javascripts/discourse/app/lib/public-js-versions.js @@ -6,6 +6,7 @@ export const PUBLIC_JS_VERSIONS = { "Chart.min.js": "chart.js/2.9.3/Chart.min.js", "chartjs-plugin-datalabels.min.js": "chartjs-plugin-datalabels/0.7.0/chartjs-plugin-datalabels.min.js", + "diffhtml.min.js": "diffhtml/1.0.0-beta.18/diffhtml.min.js", "jquery.magnific-popup.min.js": "magnific-popup/1.1.0/jquery.magnific-popup.min.js", "pikaday.js": "pikaday/1.8.0/pikaday.js", diff --git a/app/assets/javascripts/discourse/app/templates/components/d-editor.hbs b/app/assets/javascripts/discourse/app/templates/components/d-editor.hbs index eb54feb5cd..787f1983e1 100644 --- a/app/assets/javascripts/discourse/app/templates/components/d-editor.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/d-editor.hbs @@ -49,7 +49,11 @@
-
{{html-safe preview}}
+
+ {{#unless siteSettings.enable_diffhtml_preview}} + {{html-safe preview}} + {{/unless}} +
{{plugin-outlet name="editor-preview" classNames="d-editor-plugin" args=outletArgs}}
diff --git a/app/assets/javascripts/pretty-text/addon/oneboxer.js b/app/assets/javascripts/pretty-text/addon/oneboxer.js index 77879690de..dad766d216 100644 --- a/app/assets/javascripts/pretty-text/addon/oneboxer.js +++ b/app/assets/javascripts/pretty-text/addon/oneboxer.js @@ -103,11 +103,12 @@ function loadNext(ajax) { // It will insert a loading indicator and remove it when the loading is complete or fails. export function load({ elem, - refresh = true, ajax, - synchronous = false, - categoryId, topicId, + categoryId, + refresh = true, + offline = false, + synchronous = false, }) { const $elem = $(elem); @@ -134,6 +135,10 @@ export function load({ if (failed) { return; } + + if (offline) { + return; + } } // Add the loading CSS class diff --git a/app/assets/javascripts/pretty-text/addon/upload-short-url.js b/app/assets/javascripts/pretty-text/addon/upload-short-url.js index febcbaf319..2438924601 100644 --- a/app/assets/javascripts/pretty-text/addon/upload-short-url.js +++ b/app/assets/javascripts/pretty-text/addon/upload-short-url.js @@ -173,15 +173,24 @@ function _loadShortUrls(uploads, ajax, siteSettings, opts) { ); } +const SHORT_URL_ATTRIBUTES = + "img[data-orig-src], a[data-orig-href], source[data-orig-src]"; + +export function resolveCachedShortUrls(siteSettings, scope, opts) { + let shortUploadElements = scope.querySelectorAll(SHORT_URL_ATTRIBUTES); + + if (shortUploadElements.length > 0) { + _loadCachedShortUrls(shortUploadElements, siteSettings, opts); + } +} + export function resolveAllShortUrls(ajax, siteSettings, scope, opts) { - const attributes = - "img[data-orig-src], a[data-orig-href], source[data-orig-src]"; - let shortUploadElements = scope.querySelectorAll(attributes); + let shortUploadElements = scope.querySelectorAll(SHORT_URL_ATTRIBUTES); if (shortUploadElements.length > 0) { _loadCachedShortUrls(shortUploadElements, siteSettings, opts); - shortUploadElements = scope.querySelectorAll(attributes); + shortUploadElements = scope.querySelectorAll(SHORT_URL_ATTRIBUTES); if (shortUploadElements.length > 0) { // this is carefully batched so we can do a leading debounce (trigger right away) return discourseDebounce( diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 142172c672..c7c554cba8 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -2184,6 +2184,8 @@ en: max_allowed_message_recipients: "Maximum recipients allowed in a message." watched_words_regular_expressions: "Watched words are regular expressions." + enable_diffhtml_preview: "Experimental feature which uses diffHTML to sync preview instead of full re-render" + old_post_notice_days: "Days before post notice becomes old" new_user_notice_tl: "Minimum trust level required to see new user post notices." returning_user_notice_tl: "Minimum trust level required to see returning user post notices." diff --git a/config/site_settings.yml b/config/site_settings.yml index 415094f9bf..7481295072 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -976,6 +976,10 @@ posting: hidden: true default: false client: true + enable_diffhtml_preview: + hidden: true + default: false + client: true old_post_notice_days: default: 14 max: 36500 diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake index e77d8e8227..db865f2995 100644 --- a/lib/tasks/javascript.rake +++ b/lib/tasks/javascript.rake @@ -76,6 +76,9 @@ def dependencies }, { source: 'chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.min.js', public: true + }, { + source: 'diffhtml/dist/diffhtml.min.js', + public: true }, { source: 'magnific-popup/dist/jquery.magnific-popup.min.js', public: true diff --git a/package.json b/package.json index 8255e5da1f..f1e0b4e31e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "bootstrap": "v3.4.1", "chart.js": "2.9.3", "chartjs-plugin-datalabels": "^0.7.0", + "diffhtml": "^1.0.0-beta.18", "eslint-config-discourse": "^1.1.8", "handlebars": "^4.7.0", "highlight.js": "https://github.com/highlightjs/highlight.js", diff --git a/public/javascripts/diffhtml.min.js b/public/javascripts/diffhtml.min.js new file mode 100644 index 0000000000..292f2654b5 --- /dev/null +++ b/public/javascripts/diffhtml.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):(e=e||self,t(e.diff={}))}(this,function(e){"use strict";function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r3?x-3:0),C=3;C2&&void 0!==arguments[2]?arguments[2]:{};r.parser||(r.parser={}),t||(t=ue);var n=new Set(r.parser.rawElements?r.parser.rawElements:pe),a=new Set(r.parser.selfClosingElements||ve),o=/)-->|<(\/?)([a-z\-\_][a-z0-9\-\_]*)\s*([^>]*?)(\/?)>/gi,i=f("#document-fragment",null,[]),s=[i],d=i,c=-1;if(!e.includes("<")&&e)return Ne(d,e,t),i;for(var l,u,h=0;l=o.exec(e);h++){c>-1&&c+l[0].length0){var v=e.slice(0,p);v&&!ce.exec(v)&&Ne(d,v,t)}if(c=o.lastIndex,"!"!==l[0][1]){var m=le.exec(l[2]),g=m&&t.tags[m[1]],N=g?g.name||g:l[2];if(!l[1]&&(!l[4]&&me[d.rawNodeName]&&me[d.rawNodeName][N]&&(s.pop(),d=s[s.length-1]),d=d.childNodes[d.childNodes.push(ye(l[2],l[3],t))-1],s.push(d),r.parser.strict||n.has(N))){var y=""),b=e.indexOf(y,o.lastIndex);if(n.has(N)){-1===b?c=o.lastIndex=e.length+1:(c=b+y.length,o.lastIndex=c,l[1]=" ");var T=e.slice(l.index+l[0].length,b);Ne(d,T,t)}}if(l[1]||l[4]||a.has(N))for(;d;){if("/"===l[4]&&m){s.pop(),d=s[s.length-1];break}if(g&&d.rawNodeName===N){s.pop(),d=s[s.length-1];break}if(d.rawNodeName===N){s.pop(),d=s[s.length-1];break}var E=ge[d.rawNodeName];{if(!E||!E[N])break;s.pop(),d=s[s.length-1]}}}}var w=e.slice(-1===c?0:c);if(w&&Ne(d,w,t),i.childNodes.length&&"html"===i.childNodes[0].nodeName){var k={before:[],after:[]},S={after:[]},O=i.childNodes[0],x=!0,_=!0;if(O.childNodes=O.childNodes.filter(function(e){if("body"===e.nodeName||"head"===e.nodeName)return"head"===e.nodeName&&(x=!1),"body"===e.nodeName&&(_=!1),!0;1===e.nodeType&&(x&&_?k.before.push(e):!x&&_?k.after.push(e):_||S.after.push(e))}),O.childNodes[0]&&"head"===O.childNodes[0].nodeName){var C=O.childNodes[0].childNodes;C.unshift.apply(C,k.before),C.push.apply(C,k.after)}else{var A=f("head",null,[]);if(A){var R=A.childNodes;R.unshift.apply(R,k.before),R.push.apply(R,k.after),O.childNodes.unshift(A)}}if(O.childNodes[1]&&"body"===O.childNodes[1].nodeName){var I=O.childNodes[1].childNodes;I.push.apply(I,S.after)}else{var j=f("body",null,[]);if(j){var M=j.childNodes;M.push.apply(M,S.after),O.childNodes.push(j)}}}return i}function p(e){be(e);for(var t=0;t2&&void 0!==arguments[2]?arguments[2]:[],n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};e||(e=Ae),t||(t=Ae);var a=n.svgElements,o=void 0===a?new Set:a,i=(e.nodeName,11===t.nodeType||e.nodeType,e===Ae),s="svg"===t.nodeName||o.has(t),d=null;if(q.forEach(function(r){var n=r(e,t);n&&n===e?d=!0:n&&(t=n)}),d)return r;for(var c={old:new Map,new:new Map},l=0;lx&&O.splice(V,1),E(null,C,r,n),r.push(D.REPLACE_CHILD,C,_)}}else O.push(C),E(null,C,r,n),r.push(D.INSERT_BEFORE,e,C,null)}if(O.length!==k.length){for(var L=k.length;L1&&void 0!==arguments[1]?arguments[1]:Le,r=arguments.length>2?arguments[2]:void 0,n=f(e),a=B.get(n);if(a)return a;var o=n.nodeName,i=n.rawNodeName,s=void 0===i?o:i,d=n.childNodes,c=void 0===d?[]:d;r=r||"svg"===o;var l=null;$.forEach(function(e,t){(t=e(n))&&(l=t)}),null===l&&(l="#text"===o?t.createTextNode(n.nodeValue||""):"#document-fragment"===o?t.createDocumentFragment():r?t.createElementNS(Ve,s):t.createElement(s),"script"===o&&(l.type="no-execute"));var u=l;B.set(n,u);for(var h=0;h1?n-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:{},r=[],n=t.ownerDocument,a=t.svgElements,o=void 0===a?new Set:a,s=e.length,d=0;;){var c=e[d];if(d===s)break;switch(c){case D.SET_ATTRIBUTE:if("break"===function(){var t=e[d+1],a=e[d+2],s=_(e[d+3]);d+=4;var c=o.has(t),l=w(t,n,c),u=l.getAttribute(a),f=x("attributeChanged",t,a,u,s);return p(t),f.length?(Promise.all(f).then(function(){return Fe(t,l,a,s)}),r.push.apply(r,i(f))):Fe(t,l,a,s),"break"}())break;case D.REMOVE_ATTRIBUTE:if("break"===function(){var t=e[d+1],a=e[d+2];d+=3;var s=o.has(t),c=w(t,n,s),l=c.getAttribute(a),u=x("attributeChanged",t,a,l,null);return p(t),u.length?(Promise.all(u).then(function(){return Ye(c,a)}),r.push.apply(r,i(u))):Ye(c,a),"break"}())break;case D.NODE_VALUE:if("break"===function(){var t=e[d+1],a=e[d+2],s=e[d+3],c=o.has(t);d+=4;var l=w(t,n,c);p(t);var u=x("textChanged",t,s,a);return u.length?(Promise.all(u).then(function(){return $e(l,a)}),r.push.apply(r,i(u))):$e(l,a),"break"}())break;case D.INSERT_BEFORE:var l=e[d+1],u=e[d+2],f=e[d+3];d+=4;var h=B.get(l);if(!h)break;var m=o.has(u);p(u);var g=f&&w(f,n,m),N=w(u,n,m);h.insertBefore(N,g||null),r.push.apply(r,i(x("attached",u)));break;case D.REPLACE_CHILD:if("break"===function(){var t=e[d+1],a=e[d+2];d+=3;var s=o.has(t),c=B.get(a),l=w(t,n,s);if(!c||!c.parentNode)return"break";p(t);var u=U.get("attached").size,f=U.get("detached").size,h=U.get("replaced").size;if(!u&&!f&&!h)return c.parentNode&&(v(a),c.parentNode.replaceChild(l,c)),"break";c.parentNode&&c.parentNode.insertBefore(l,c);var m=x("attached",t),g=x("detached",a),N=x("replaced",a,l),y=[].concat(i(m),i(g),i(N));return y.length?(Promise.all(y).then(function(){c.parentNode&&c.parentNode.removeChild(c),v(a)}),r.push.apply(r,i(y))):(c.parentNode&&c.parentNode.removeChild(c),v(a)),"break"}())break;case D.REMOVE_CHILD:if("break"===function(){var t=e[d+1];d+=2;var n=B.get(t);if(!n||!n.parentNode)return"break";var a=x("detached",t);return a.length?(Promise.all(a).then(function(){n.parentNode&&n.parentNode.removeChild(n),v(t)}),r.push.apply(r,i(a))):(n.parentNode&&n.parentNode.removeChild(n),v(t)),"break"}())break}}return r}function A(e){var t=e.domNode,r=e.state,n=e.state,a=n.measure,o=n.scriptsToExecute,s=e.patches,d=t.ownerDocument,c=e.promises||[];r.ownerDocument=d||document;var l=function(e){"script"===e.nodeName&&(o.set(e,e.attributes.type),e.attributes.type="no-execute")};$.add(l),a("patch node"),c.push.apply(c,i(C(s,r))),a("patch node"),$.delete(l),e.promises=c}function R(e){var t=e.promises;return t&&t.length?e.promise=Promise.all(t).then(function(){return e.end()}):e.promise=Promise.resolve(e.end())}function I(e){var t=e.state,r=e.markup,n=e.options,a=t.measure,o=n.inner;if("string"==typeof r){a("parsing markup for new tree");var i=h(r,void 0,n),s=i.childNodes,d=f(o?s:s[0]||s);d&&(e.newTree=d),a("parsing markup for new tree")}}function j(e){return e.replace(/[&<>]/g,function(e){return"&#".concat(e.charCodeAt(0),";")})}function M(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.inner=!0,r.executeScripts=!("executeScripts"in r)||r.executeScripts,r.tasks=r.tasks||qe,Je.create(e,t,r).start()}function V(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.inner=!1,r.tasks=r.tasks||qe,r.executeScripts=!("executeScripts"in r)||r.executeScripts,Je.create(e,t,r).start()}function L(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n")1?t-1:0),n=1;n/i,le=new RegExp("".concat(de,"([^_]*)__")),ue={tags:[],attributes:{},children:{}},fe=Object.assign,he=Array.isArray,pe=["script","noscript","style","code","template"],ve=["meta","img","link","input","area","br","hr","area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],me={li:{li:!0},p:{p:!0,div:!0},td:{td:!0,th:!0},th:{td:!0,th:!0}},ge={li:{ul:!0,ol:!0},a:{div:!0},b:{div:!0},i:{div:!0},p:{div:!0},td:{tr:!0,table:!0},th:{tr:!0,table:!0}},Ne=function(e,t,r){var n;if(!("childNodes"in e.attributes)){if(t&&!ce.test(t)&&!le.test(t))return e.childNodes.push(f("#text",t));for(var a=[],o=t.split(le),s=0;s0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0,r=B.get(t);e?r.setAttribute("type",e):r.removeAttribute("type")}),t.previousMarkup="outerHTML"in r?r.outerHTML:"",n.executeScripts&&i.forEach(function(e,r){var n=B.get(r),a=n.cloneNode(!0);z.has(n)&&(b(n),z.set(a,t)),B.set(r,a),n.parentNode.replaceChild(a,n)}),i.clear(),a("finalize"),a("render"),m(),this.endedCallbacks.forEach(function(t){return t(e)}),this.endedCallbacks.clear(),this}},{key:"onceEnded",value:function(e){this.endedCallbacks.add(e)}}]),e}(),Ke=function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r3?x-3:0),C=3;C2&&void 0!==arguments[2]?arguments[2]:{};r.parser||(r.parser={}),t||(t=ue);var n=new Set(r.parser.rawElements?r.parser.rawElements:pe),a=new Set(r.parser.selfClosingElements||ve),o=/)-->|<(\/?)([a-z\-\_][a-z0-9\-\_]*)\s*([^>]*?)(\/?)>/gi,i=f("#document-fragment",null,[]),s=[i],d=i,c=-1;if(!e.includes("<")&&e)return Ne(d,e,t),i;for(var l,u,h=0;l=o.exec(e);h++){c>-1&&c+l[0].length0){var v=e.slice(0,p);v&&!ce.exec(v)&&Ne(d,v,t)}if(c=o.lastIndex,"!"!==l[0][1]){var m=le.exec(l[2]),g=m&&t.tags[m[1]],N=g?g.name||g:l[2];if(!l[1]&&(!l[4]&&me[d.rawNodeName]&&me[d.rawNodeName][N]&&(s.pop(),d=s[s.length-1]),d=d.childNodes[d.childNodes.push(ye(l[2],l[3],t))-1],s.push(d),r.parser.strict||n.has(N))){var y=""),b=e.indexOf(y,o.lastIndex);if(n.has(N)){-1===b?c=o.lastIndex=e.length+1:(c=b+y.length,o.lastIndex=c,l[1]=" ");var T=e.slice(l.index+l[0].length,b);Ne(d,T,t)}}if(l[1]||l[4]||a.has(N))for(;d;){if("/"===l[4]&&m){s.pop(),d=s[s.length-1];break}if(g&&d.rawNodeName===N){s.pop(),d=s[s.length-1];break}if(d.rawNodeName===N){s.pop(),d=s[s.length-1];break}var E=ge[d.rawNodeName];{if(!E||!E[N])break;s.pop(),d=s[s.length-1]}}}}var w=e.slice(-1===c?0:c);if(w&&Ne(d,w,t),i.childNodes.length&&"html"===i.childNodes[0].nodeName){var k={before:[],after:[]},S={after:[]},O=i.childNodes[0],x=!0,_=!0;if(O.childNodes=O.childNodes.filter(function(e){if("body"===e.nodeName||"head"===e.nodeName)return"head"===e.nodeName&&(x=!1),"body"===e.nodeName&&(_=!1),!0;1===e.nodeType&&(x&&_?k.before.push(e):!x&&_?k.after.push(e):_||S.after.push(e))}),O.childNodes[0]&&"head"===O.childNodes[0].nodeName){var C=O.childNodes[0].childNodes;C.unshift.apply(C,k.before),C.push.apply(C,k.after)}else{var A=f("head",null,[]);if(A){var R=A.childNodes;R.unshift.apply(R,k.before),R.push.apply(R,k.after),O.childNodes.unshift(A)}}if(O.childNodes[1]&&"body"===O.childNodes[1].nodeName){var I=O.childNodes[1].childNodes;I.push.apply(I,S.after)}else{var j=f("body",null,[]);if(j){var M=j.childNodes;M.push.apply(M,S.after),O.childNodes.push(j)}}}return i}function p(e){be(e);for(var t=0;t2&&void 0!==arguments[2]?arguments[2]:[],n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};e||(e=Ae),t||(t=Ae);var a=n.svgElements,o=void 0===a?new Set:a,i=(e.nodeName,11===t.nodeType||e.nodeType,e===Ae),s="svg"===t.nodeName||o.has(t),d=null;if(q.forEach(function(r){var n=r(e,t);n&&n===e?d=!0:n&&(t=n)}),d)return r;for(var c={old:new Map,new:new Map},l=0;lx&&O.splice(V,1),E(null,C,r,n),r.push(D.REPLACE_CHILD,C,_)}}else O.push(C),E(null,C,r,n),r.push(D.INSERT_BEFORE,e,C,null)}if(O.length!==k.length){for(var L=k.length;L1&&void 0!==arguments[1]?arguments[1]:Le,r=arguments.length>2?arguments[2]:void 0,n=f(e),a=B.get(n);if(a)return a;var o=n.nodeName,i=n.rawNodeName,s=void 0===i?o:i,d=n.childNodes,c=void 0===d?[]:d;r=r||"svg"===o;var l=null;$.forEach(function(e,t){(t=e(n))&&(l=t)}),null===l&&(l="#text"===o?t.createTextNode(n.nodeValue||""):"#document-fragment"===o?t.createDocumentFragment():r?t.createElementNS(Ve,s):t.createElement(s),"script"===o&&(l.type="no-execute"));var u=l;B.set(n,u);for(var h=0;h1?n-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:{},r=[],n=t.ownerDocument,a=t.svgElements,o=void 0===a?new Set:a,s=e.length,d=0;;){var c=e[d];if(d===s)break;switch(c){case D.SET_ATTRIBUTE:if("break"===function(){var t=e[d+1],a=e[d+2],s=_(e[d+3]);d+=4;var c=o.has(t),l=w(t,n,c),u=l.getAttribute(a),f=x("attributeChanged",t,a,u,s);return p(t),f.length?(Promise.all(f).then(function(){return Fe(t,l,a,s)}),r.push.apply(r,i(f))):Fe(t,l,a,s),"break"}())break;case D.REMOVE_ATTRIBUTE:if("break"===function(){var t=e[d+1],a=e[d+2];d+=3;var s=o.has(t),c=w(t,n,s),l=c.getAttribute(a),u=x("attributeChanged",t,a,l,null);return p(t),u.length?(Promise.all(u).then(function(){return Ye(c,a)}),r.push.apply(r,i(u))):Ye(c,a),"break"}())break;case D.NODE_VALUE:if("break"===function(){var t=e[d+1],a=e[d+2],s=e[d+3],c=o.has(t);d+=4;var l=w(t,n,c);p(t);var u=x("textChanged",t,s,a);return u.length?(Promise.all(u).then(function(){return $e(l,a)}),r.push.apply(r,i(u))):$e(l,a),"break"}())break;case D.INSERT_BEFORE:var l=e[d+1],u=e[d+2],f=e[d+3];d+=4;var h=B.get(l);if(!h)break;var m=o.has(u);p(u);var g=f&&w(f,n,m),N=w(u,n,m);h.insertBefore(N,g||null),r.push.apply(r,i(x("attached",u)));break;case D.REPLACE_CHILD:if("break"===function(){var t=e[d+1],a=e[d+2];d+=3;var s=o.has(t),c=B.get(a),l=w(t,n,s);if(!c||!c.parentNode)return"break";p(t);var u=U.get("attached").size,f=U.get("detached").size,h=U.get("replaced").size;if(!u&&!f&&!h)return c.parentNode&&(v(a),c.parentNode.replaceChild(l,c)),"break";c.parentNode&&c.parentNode.insertBefore(l,c);var m=x("attached",t),g=x("detached",a),N=x("replaced",a,l),y=[].concat(i(m),i(g),i(N));return y.length?(Promise.all(y).then(function(){c.parentNode&&c.parentNode.removeChild(c),v(a)}),r.push.apply(r,i(y))):(c.parentNode&&c.parentNode.removeChild(c),v(a)),"break"}())break;case D.REMOVE_CHILD:if("break"===function(){var t=e[d+1];d+=2;var n=B.get(t);if(!n||!n.parentNode)return"break";var a=x("detached",t);return a.length?(Promise.all(a).then(function(){n.parentNode&&n.parentNode.removeChild(n),v(t)}),r.push.apply(r,i(a))):(n.parentNode&&n.parentNode.removeChild(n),v(t)),"break"}())break}}return r}function A(e){var t=e.domNode,r=e.state,n=e.state,a=n.measure,o=n.scriptsToExecute,s=e.patches,d=t.ownerDocument,c=e.promises||[];r.ownerDocument=d||document;var l=function(e){"script"===e.nodeName&&(o.set(e,e.attributes.type),e.attributes.type="no-execute")};$.add(l),a("patch node"),c.push.apply(c,i(C(s,r))),a("patch node"),$.delete(l),e.promises=c}function R(e){var t=e.promises;return t&&t.length?e.promise=Promise.all(t).then(function(){return e.end()}):e.promise=Promise.resolve(e.end())}function I(e){var t=e.state,r=e.markup,n=e.options,a=t.measure,o=n.inner;if("string"==typeof r){a("parsing markup for new tree");var i=h(r,void 0,n),s=i.childNodes,d=f(o?s:s[0]||s);d&&(e.newTree=d),a("parsing markup for new tree")}}function j(e){return e.replace(/[&<>]/g,function(e){return"&#".concat(e.charCodeAt(0),";")})}function M(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.inner=!0,r.executeScripts=!("executeScripts"in r)||r.executeScripts,r.tasks=r.tasks||qe,Je.create(e,t,r).start()}function V(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return r.inner=!1,r.tasks=r.tasks||qe,r.executeScripts=!("executeScripts"in r)||r.executeScripts,Je.create(e,t,r).start()}function L(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n")1?t-1:0),n=1;n/i,le=new RegExp("".concat(de,"([^_]*)__")),ue={tags:[],attributes:{},children:{}},fe=Object.assign,he=Array.isArray,pe=["script","noscript","style","code","template"],ve=["meta","img","link","input","area","br","hr","area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],me={li:{li:!0},p:{p:!0,div:!0},td:{td:!0,th:!0},th:{td:!0,th:!0}},ge={li:{ul:!0,ol:!0},a:{div:!0},b:{div:!0},i:{div:!0},p:{div:!0},td:{tr:!0,table:!0},th:{tr:!0,table:!0}},Ne=function(e,t,r){var n;if(!("childNodes"in e.attributes)){if(t&&!ce.test(t)&&!le.test(t))return e.childNodes.push(f("#text",t));for(var a=[],o=t.split(le),s=0;s0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0,r=B.get(t);e?r.setAttribute("type",e):r.removeAttribute("type")}),t.previousMarkup="outerHTML"in r?r.outerHTML:"",n.executeScripts&&i.forEach(function(e,r){var n=B.get(r),a=n.cloneNode(!0);z.has(n)&&(b(n),z.set(a,t)),B.set(r,a),n.parentNode.replaceChild(a,n)}),i.clear(),a("finalize"),a("render"),m(),this.endedCallbacks.forEach(function(t){return t(e)}),this.endedCallbacks.clear(),this}},{key:"onceEnded",value:function(e){this.endedCallbacks.add(e)}}]),e}(),Ke=function(e){for(var t=1;t