Skip to content

Commit 7debd79

Browse files
committed
1.0.1
- Fixed a bug that caused client-side Teddy to try to fetch resources from the server inappropriately while parsing the template. - Updated dependencies.
1 parent f7fe726 commit 7debd79

8 files changed

Lines changed: 63 additions & 22 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
- Put your changes here...
66

7+
## 1.0.1
8+
9+
- Fixed a bug that caused client-side Teddy to try to fetch resources from the server inappropriately while parsing the template.
10+
- Updated dependencies.
11+
712
## 1.0.0
813

914
- Added support for a new `<!--! server-side comments -->` syntax.

cheerioPolyfill.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,16 @@ function parseTeddyDOMFromString (html) {
102102
} else {
103103
// handle tags
104104
const [fullMatch, tagName, attrString] = match
105+
const lowerCaseTagName = tagName.toLowerCase()
105106
const isClosingTag = fullMatch.startsWith('</')
106107
if (isClosingTag) {
107-
if (selfClosingTags.has(tagName.toLowerCase())) {
108+
if (selfClosingTags.has(lowerCaseTagName)) {
108109
// convert incorrect closing tag for self-closing tag to self-closing tag
109110
const element = document.createElement(tagName)
110111
dom[dom.length - 1].appendChild(element)
111112
} else {
112113
// check if the closing tag matches the most recent open tag
113-
if (openTags.length > 0 && openTags[openTags.length - 1] === tagName.toLowerCase()) {
114+
if (openTags.length > 0 && openTags[openTags.length - 1] === lowerCaseTagName) {
114115
openTags.pop()
115116
dom.pop()
116117
}
@@ -141,7 +142,24 @@ function parseTeddyDOMFromString (html) {
141142
// apply attributes to the element
142143
for (const [name, value] of attrMap) {
143144
try {
144-
element.setAttribute(name, value || '')
145+
// replace elements with `src` attributes with `data-teddy-defer-attr-src` so the browser doesn't try to prefetch the asset
146+
// this is needed because the value of the `src` attribute could be a {teddyVariable} and that fetch won't resolve
147+
switch (lowerCaseTagName) {
148+
case 'img':
149+
case 'video':
150+
case 'audio':
151+
case 'iframe':
152+
case 'script':
153+
if (name === 'src') element.setAttribute('data-teddy-defer-attr-src', value) // replace src with data-teddy-defer-attr-src
154+
else element.setAttribute(name, value || '')
155+
break
156+
case 'link':
157+
if (name === 'href') element.setAttribute('data-teddy-defer-attr-href', value) // replace src with data-teddy-defer-attr-href
158+
else element.setAttribute(name, value || '')
159+
break
160+
default:
161+
element.setAttribute(name, value || '')
162+
}
145163
} catch (e) {
146164
console.warn('Error parsing an element attribute. You might have a typo in your HTML. A common cause is two spaces between element attributes.')
147165
}
@@ -151,9 +169,9 @@ function parseTeddyDOMFromString (html) {
151169
dom[dom.length - 1].appendChild(element)
152170

153171
// push the new element to the dom if it's not self-closing
154-
if (!selfClosingTags.has(tagName.toLowerCase()) && !fullMatch.endsWith('/>')) {
172+
if (!selfClosingTags.has(lowerCaseTagName) && !fullMatch.endsWith('/>')) {
155173
dom.push(element)
156-
openTags.push(tagName.toLowerCase())
174+
openTags.push(lowerCaseTagName)
157175
}
158176
}
159177
}

package-lock.json

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"url": "https://github.com/rooseveltframework/teddy/graphs/contributors"
99
}
1010
],
11-
"version": "1.0.0",
11+
"version": "1.0.1",
1212
"files": [
1313
"dist"
1414
],

teddy.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,13 @@ function render (template, model, callback) {
12651265
renderedTemplate = renderedTemplate.replace(`<noteddy id="${blockId}"></noteddy>`, () => model._noTeddyBlocks[blockId])
12661266
}
12671267

1268-
// fix double-encoding html entity bug in client-side mode
1269-
if (browser) renderedTemplate = reverseDoubleEncodedEntities(renderedTemplate)
1268+
if (browser) {
1269+
// fix double-encoding html entity bug in client-side mode
1270+
renderedTemplate = reverseDoubleEncodedEntities(renderedTemplate)
1271+
1272+
// now that we're done with the render, reset data-teddy-defer-attr-src and data-teddy-defer-attr-href to native attributes
1273+
renderedTemplate = renderedTemplate.replaceAll('data-teddy-defer-attr-src', 'src').replaceAll('data-teddy-defer-attr-href', 'href')
1274+
}
12701275

12711276
// cache the template
12721277
if (cacheKey === 'none') {

test/model.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export default function makeModel () {
106106
templateLiteralWithNonexistentVar: '${nonexistentVar}', // eslint-disable-line
107107
inlineStyles: 'body { font-family: sans-serif; }',
108108
inlineScript: 'console.log("hello")',
109+
imgSrc: 'hello.jpg',
109110
complexJSONString: '{"content":{"appTitle":"Some App","pageTitle":"{content.appTitle}"},"currentYear":1858,"mainDomain":"localhost:43711","NODE_ENV":"development"}',
110111
obj: {
111112
one: {

test/templates/misc/imgSrc.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{!
2+
should render img tags correctly
3+
!}
4+
5+
<img src="something.jpg">
6+
<img src="{imgSrc}">

test/tests.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,12 @@ export default [
16581658
run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected),
16591659
expected: '<div><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p><p>test</p></div>'
16601660
},
1661+
{
1662+
message: 'should render img tags correctly (misc/imgSrc.html)',
1663+
template: 'misc/imgSrc',
1664+
run: async (teddy, template, model, assert, expected) => assert(teddy.render(template, model), expected),
1665+
expected: '<img src="something.jpg"><img src="hello.jpg">'
1666+
},
16611667
{
16621668
message: 'should parse embedded script tag correctly (misc/scriptWithEmptyObject.html)',
16631669
template: 'misc/scriptWithEmptyObject',

0 commit comments

Comments
 (0)