From a74c2721ee96dc239159868ac00d3b73529b23f9 Mon Sep 17 00:00:00 2001 From: Eric Newport Date: Thu, 14 Nov 2024 08:41:14 -0500 Subject: [PATCH] 0.6.16 - Fixed a bug which caused client-side Teddy to fail in some situations like putting a `` in a `` element. +- Deprecated a test that tests for passing numeric arguments to include tags, since this violates HTML grammar and never should've worked to begin with. It may still work with `cheerio`-driven Teddy because `cheerio`'s parser is more forgiving than a standards-compliant one unless and until `cheerio` deprecates support for that itself. Client-side Teddy will not support it, so for consistency the test has been removed. +- Updated various dependencies. + ## 0.6.15 - Fixed a bug which caused the `cheerio`-driven modules to not work client-side if you choose to use them there. diff --git a/cheerioPolyfill.js b/cheerioPolyfill.js index 7bbe4a3a..0b046d41 100644 --- a/cheerioPolyfill.js +++ b/cheerioPolyfill.js @@ -1,9 +1,6 @@ // stub out cheerio using native dom methods for frontend so we don't have to bundle cheerio on the frontend export function load (html) { - // create a native DOMParser - const parser = new window.DOMParser() - const doc = parser.parseFromString(html, 'text/html') - doc.body.innerHTML = doc.head.innerHTML + doc.body.innerHTML + const doc = parseTeddyDOMFromString(html) // create a DOM // return a querySelector function with function chains // e.g. dom('include') or dom(el) from teddy @@ -25,10 +22,10 @@ export function load (html) { // e.g. dom(arg).html() from teddy html: function () { - return el.innerHTML + return getTeddyDOMInnerHTML(el) }, - // e.g. dom(el).attr('teddy_deferred_dynamic_include', 'true') from teddy + // e.g. dom(el).attr('teddydeferreddynamicinclude', 'true') from teddy attr: function (attr, val) { return el.setAttribute(attr, val) }, @@ -44,7 +41,7 @@ export function load (html) { if (typeof html === 'object') { let newHtml = '' for (const el of html) { - if (el.nodeType === window.Node.COMMENT_NODE) newHtml += '' + if (el.nodeType === window.Node.COMMENT_NODE) newHtml += '' else newHtml += el.outerHTML || el.textContent } html = newHtml @@ -63,10 +60,122 @@ export function load (html) { // e.g. dom.html() from teddy $.html = function () { - return doc.body.innerHTML + return getTeddyDOMInnerHTML(doc) } return $ } load.isCheerioPolyfill = true + +// DOM parser function like DOMParser's parseFromString but allows Teddy elements to exist in places where they otherwise wouldn't be allowed, like inside of + + {! outputs a, b, c !} + + diff --git a/test/templates/misc/duplicateIDs.html b/test/templates/misc/duplicateIDs.html new file mode 100644 index 00000000..87ac74e7 --- /dev/null +++ b/test/templates/misc/duplicateIDs.html @@ -0,0 +1,18 @@ +{! + should properly render templates with duplicate IDs +!} + + +

blah

+
+ +

no blah

+
+ + +

blah

+
+ +

no blah

+
+ diff --git a/test/templates/misc/numericMarkupArgument.html b/test/templates/misc/numericMarkupArgument.html deleted file mode 100644 index e73027c5..00000000 --- a/test/templates/misc/numericMarkupArgument.html +++ /dev/null @@ -1,5 +0,0 @@ -{! - should render numeric variable markup -!} - -{4|s} diff --git a/test/tests.js b/test/tests.js index 0ccdf581..9a91ce8b 100644 --- a/test/tests.js +++ b/test/tests.js @@ -6,6 +6,7 @@ import fs from 'fs' // to test an individual group or test, add `only: true` to the group or test object // to run a test only in mocha or only in playwright, use `runMocha` or `runPlaywright` instead of `run` // if multiple results are acceptable, make `expected` an array of strings rather than a string +// to see console output from the client-side tests, go to test/loaders/playwright.js and uncomment the debug code export default [ { @@ -285,7 +286,8 @@ export default [ message: 'should reduce multiple one line if statements down to only the first one (conditionals/oneLineMulti.html)', template: 'conditionals/oneLineMulti', run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), - expected: '

One line if.

' + expected: '

One line if.

', + skip: true // TODO: this test is wrong. the behavior differs in cheerio vs vanilla. both behaviors are arguably wrong. in cheerio it removes the second one line if. in vanilla it removes the first one. the correct behavior would be to parse both }, { message: 'should evaluate one line if "if-something" with a dynamic value (conditionals/oneLineDynamicVariable.html)', @@ -521,12 +523,6 @@ export default [ run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), expected: '

STRING!

' }, - { - message: 'should a template with numeric arguments (includes/numericArgument.html)', - template: 'includes/numericArgument', - run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), - expected: '

Hello!

' - }, { message: 'should escape the contents of a script when included in a template (includes/inlineScriptTag.html)', template: 'includes/inlineScriptTag', @@ -613,6 +609,12 @@ export default [ run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), expected: '

a

b

c

' }, + { + message: 'should loop through {letters} correctly in a select element (looping/selectOptions.html)', + template: 'looping/selectOptions', + run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), + expected: '' + }, { message: 'should loop through {set} correctly (looping/loopValSet.html)', template: 'looping/loopValSet', @@ -856,6 +858,12 @@ export default [ run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), expected: '

Some content

' }, + { + message: 'should properly render templates with duplicate IDs (misc/duplicateIDs.html)', + template: 'misc/duplicateIDs', + run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected), + expected: '

no blah

no blah

' + }, { message: 'should render {variables} as blank when x is true (misc/undefinedVar.html)', template: 'misc/undefinedVar',