@@ -286,91 +286,97 @@ $(() => {
286286 }
287287 } ) ;
288288
289- $postFields
290- . on (
291- 'focus keyup paste change markdown' ,
292- ( ( ) => {
293- let previous = null ;
294- return ( evt ) => {
295- const $tgt = $ ( evt . target ) ;
296- const text = $ ( evt . target ) . val ( ) ;
297- // Don't bother re-rendering if nothing's changed
298- if ( text === previous ) {
299- return ;
300- }
301- previous = text ;
302- if ( ! window . converter ) {
303- window . converter = window . markdownit ( {
304- html : true ,
305- breaks : false ,
306- linkify : true ,
307- } ) ;
308- window . converter . use ( window . markdownitFootnote ) ;
309- window . converter . use ( window . latexEscape ) ;
310- }
311- window . setTimeout ( ( ) => {
312- const converter = window . converter ;
313- const unsafe_html = converter . render ( text ) ;
314- const html = DOMPurify . sanitize ( unsafe_html , {
315- ALLOWED_TAGS : QPixel . ALLOWED_POST_TAGS ,
316- ALLOWED_ATTR : QPixel . ALLOWED_POST_ATTRS ,
317- } ) ;
318-
319- const removedElements = [
320- ...new Set (
321- DOMPurify . removed
322- . filter ( ( entry ) => entry . element && ! IGNORE_UNSUPPORTED . some ( ( ctor ) => entry . element instanceof ctor ) )
323- . map ( ( entry ) => entry . element . localName ) ,
324- ) ,
325- ] ;
326-
327- const removedAttributes = [
328- ...new Set (
329- DOMPurify . removed
330- . filter ( ( entry ) => entry . attribute )
331- . map ( ( entry ) => [
332- entry . attribute . name + ( entry . attribute . value ? `='${ entry . attribute . value } '` : '' ) ,
333- entry . from . localName ,
334- ] ) ,
335- ) ,
336- ] ;
337-
338- $tgt
339- . parents ( 'form' )
340- . find ( '.rejected-elements' )
341- . toggleClass ( 'hide' , removedElements . length === 0 && removedAttributes . length === 0 )
342- . find ( 'ul' )
343- . empty ( )
344- . append (
345- removedElements . map ( ( name ) => $ ( `<li><code><${ name } ></code></li>` ) ) ,
346- removedAttributes . map ( ( [ attr , elName ] ) =>
347- $ ( `<li><code>${ attr } </code> (in <code><${ elName } ></code>)</li>` ) ,
348- ) ,
349- ) ;
350-
351- $tgt . parents ( '.form-group' ) . siblings ( '.post-preview' ) . html ( html ) ;
352- $tgt
353- . parents ( 'form' )
354- . find ( '.js-post-html[name="__html"]' )
355- . val ( html + '<!-- g: js, mdit -->' ) ;
356- } , 0 ) ;
357-
358- if ( featureTimeout ) {
359- clearTimeout ( featureTimeout ) ;
360- }
361-
362- featureTimeout = setTimeout ( ( ) => {
363- if ( window [ 'MathJax' ] ) {
364- MathJax . typeset ( ) ;
365- }
366- if ( window [ 'hljs' ] ) {
367- hljs . highlightAll ( ) ;
368- }
369- } , 1000 ) ;
370- } ;
371- } ) ( ) ,
372- )
373- . trigger ( 'markdown' ) ;
289+ const onPostFieldChange = ( ( ) => {
290+ /** @type {string | null } */
291+ let previous = null ;
292+
293+ /**
294+ * @param {JQuery.EventBase } evt
295+ */
296+ return ( evt ) => {
297+ const $tgt = $ ( evt . target ) ;
298+ const text = $ ( evt . target ) . val ( ) ;
299+
300+ // Don't bother re-rendering if nothing's changed
301+ if ( text === previous ) {
302+ return ;
303+ }
304+
305+ previous = text ;
306+
307+ if ( ! window . converter ) {
308+ window . converter = window . markdownit ( {
309+ html : true ,
310+ breaks : false ,
311+ linkify : true ,
312+ } ) ;
313+ window . converter . use ( window . markdownitFootnote ) ;
314+ window . converter . use ( window . latexEscape ) ;
315+ }
316+
317+ window . setTimeout ( ( ) => {
318+ const converter = window . converter ;
319+ const unsafe_html = converter . render ( text ) ;
320+ const html = DOMPurify . sanitize ( unsafe_html , {
321+ ALLOWED_TAGS : QPixel . ALLOWED_POST_TAGS ,
322+ ALLOWED_ATTR : QPixel . ALLOWED_POST_ATTRS ,
323+ } ) ;
324+
325+ const removedElements = [
326+ ...new Set (
327+ DOMPurify . removed
328+ . filter ( ( entry ) => entry . element && ! IGNORE_UNSUPPORTED . some ( ( ctor ) => entry . element instanceof ctor ) )
329+ . map ( ( entry ) => entry . element . localName ) ,
330+ ) ,
331+ ] ;
332+
333+ const removedAttributes = [
334+ ...new Set (
335+ DOMPurify . removed
336+ . filter ( ( entry ) => entry . attribute )
337+ . map ( ( entry ) => [
338+ entry . attribute . name + ( entry . attribute . value ? `='${ entry . attribute . value } '` : '' ) ,
339+ entry . from . localName ,
340+ ] ) ,
341+ ) ,
342+ ] ;
343+
344+ $tgt
345+ . parents ( 'form' )
346+ . find ( '.rejected-elements' )
347+ . toggleClass ( 'hide' , removedElements . length === 0 && removedAttributes . length === 0 )
348+ . find ( 'ul' )
349+ . empty ( )
350+ . append (
351+ removedElements . map ( ( name ) => $ ( `<li><code><${ name } ></code></li>` ) ) ,
352+ removedAttributes . map ( ( [ attr , elName ] ) =>
353+ $ ( `<li><code>${ attr } </code> (in <code><${ elName } ></code>)</li>` ) ,
354+ ) ,
355+ ) ;
356+
357+ $tgt . parents ( '.form-group' ) . siblings ( '.post-preview' ) . html ( html ) ;
358+ $tgt
359+ . parents ( 'form' )
360+ . find ( '.js-post-html[name="__html"]' )
361+ . val ( html + '<!-- g: js, mdit -->' ) ;
362+ } , 0 ) ;
363+
364+ if ( featureTimeout ) {
365+ clearTimeout ( featureTimeout ) ;
366+ }
367+
368+ featureTimeout = setTimeout ( ( ) => {
369+ if ( window [ 'MathJax' ] ) {
370+ MathJax . typeset ( ) ;
371+ }
372+ if ( window [ 'hljs' ] ) {
373+ hljs . highlightAll ( ) ;
374+ }
375+ } , 1000 ) ;
376+ } ;
377+ } ) ( ) ;
378+
379+ $postFields . on ( 'focus keyup paste change markdown' , onPostFieldChange ) . trigger ( 'markdown' ) ;
374380
375381 $postFields . parents ( 'form' ) . on ( 'submit' , async ( ev ) => {
376382 const $tgt = $ ( ev . target ) ;
0 commit comments