Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge commit '9933ec6' into localize-msgdesc
- Loading branch information
Showing
35 changed files
with
389 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
development/ | ||
node_modules/ | ||
index.* | ||
/development/ | ||
/node_modules/ | ||
/index.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
decorators/ | ||
demo/**/*.d.ts | ||
demo/**/*.d.ts.map | ||
demo/**/*.js | ||
demo/**/*.js.map | ||
development/ | ||
node_modules/ | ||
test/ | ||
decorators.* | ||
hydrate-support.* | ||
lit-element.* | ||
lit.min.* | ||
platform-support.* | ||
/decorators/ | ||
/demo/**/*.d.ts | ||
/demo/**/*.d.ts.map | ||
/demo/**/*.js | ||
/demo/**/*.js.map | ||
/development/ | ||
/node_modules/ | ||
/test/ | ||
/decorators.* | ||
/hydrate-support.* | ||
/lit-element.* | ||
/lit.min.* | ||
/platform-support.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
development/ | ||
directives/ | ||
node_modules/ | ||
test/ | ||
hydrate.* | ||
lit-html.* | ||
parts.* | ||
platform-support.* | ||
private-ssr-support.* | ||
/development/ | ||
/directives/ | ||
/node_modules/ | ||
/test/ | ||
/hydrate.* | ||
/lit-html.* | ||
/parts.* | ||
/platform-support.* | ||
/private-ssr-support.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2020 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/ | ||
import {html as coreHtml, svg as coreSvg, TemplateResult} from './lit-html.js'; | ||
|
||
/** | ||
* Wraps a string so that it behaves like part of the static template | ||
* strings instead of a dynamic value. | ||
* | ||
* This is a very unsafe operation and may break templates if changes | ||
* the structure of a template. Do not pass user input to this function | ||
* without sanitizing it. | ||
* | ||
* Static values can be changed, but they will cause a complete re-render | ||
* since they effectively create a new template. | ||
*/ | ||
export const unsafeStatic = (value: string) => ({ | ||
_$litStatic$: value, | ||
}); | ||
|
||
type StaticValue = ReturnType<typeof unsafeStatic>; | ||
|
||
const stringsCache = new Map<string, TemplateStringsArray>(); | ||
|
||
/** | ||
* Wraps a lit-html template tag (`html` or `svg`) to add static value support. | ||
*/ | ||
export const withStatic = (coreTag: typeof coreHtml) => ( | ||
strings: TemplateStringsArray, | ||
...values: unknown[] | ||
): TemplateResult => { | ||
const l = values.length; | ||
let staticValue: string | undefined; | ||
let dynamicValue: unknown; | ||
const staticStrings: Array<string> = []; | ||
const dynamicValues: Array<unknown> = []; | ||
let i = 0; | ||
let hasStatics = false; | ||
let s: string; | ||
|
||
while (i < l) { | ||
s = strings[i]; | ||
// Collect any unsafeStatic values, and their following template strings | ||
// so that we treat a run of template strings and unsafe static values as | ||
// a single template string. | ||
while ( | ||
i < l && | ||
((dynamicValue = values[i]), | ||
(staticValue = (dynamicValue as StaticValue)?._$litStatic$)) !== undefined | ||
) { | ||
s += staticValue + strings[++i]; | ||
hasStatics = true; | ||
} | ||
dynamicValues.push(dynamicValue); | ||
staticStrings.push(s); | ||
i++; | ||
} | ||
// If the last value isn't static (which would have consumed the last | ||
// string), then we need to add the last string. | ||
if (i === l) { | ||
staticStrings.push(strings[l]); | ||
} | ||
|
||
if (hasStatics) { | ||
const key = staticStrings.join('$$lit$$'); | ||
strings = stringsCache.get(key)!; | ||
if (strings === undefined) { | ||
stringsCache.set( | ||
key, | ||
(strings = (staticStrings as unknown) as TemplateStringsArray) | ||
); | ||
} | ||
values = dynamicValues; | ||
} | ||
return coreTag(strings, ...values); | ||
}; | ||
|
||
/** | ||
* Interprets a template literal as an HTML template that can efficiently | ||
* render to and update a container. | ||
* | ||
* Includes static value support from `lit-html/static.js`. | ||
*/ | ||
export const html = withStatic(coreHtml); | ||
|
||
/** | ||
* Interprets a template literal as an SVG template that can efficiently | ||
* render to and update a container. | ||
* | ||
* Includes static value support from `lit-html/static.js`. | ||
*/ | ||
export const svg = withStatic(coreSvg); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2020 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/ | ||
import {render} from '../lit-html.js'; | ||
import {html, unsafeStatic} from '../static.js'; | ||
import {assert} from '@esm-bundle/chai'; | ||
import {stripExpressionComments} from './test-utils/strip-markers.js'; | ||
|
||
suite('static', () => { | ||
let container: HTMLElement; | ||
|
||
setup(() => { | ||
container = document.createElement('div'); | ||
}); | ||
|
||
test('static text binding', () => { | ||
render(html`${unsafeStatic('<p>Hello</p>')}`, container); | ||
// If this were a dynamic binding, the tags would be escaped | ||
assert.equal(stripExpressionComments(container.innerHTML), '<p>Hello</p>'); | ||
}); | ||
|
||
test('static attribute binding', () => { | ||
render(html`<div class="${unsafeStatic('cool')}"></div>`, container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div class="cool"></div>' | ||
); | ||
// TODO: test that this is actually static. It's not currently possible with | ||
// the public API | ||
}); | ||
|
||
test('static tag binding', () => { | ||
const tagName = unsafeStatic('div'); | ||
render(html`<${tagName}>${'A'}</${tagName}>`, container); | ||
assert.equal(stripExpressionComments(container.innerHTML), '<div>A</div>'); | ||
}); | ||
|
||
test('static attribute name binding', () => { | ||
render(html`<div ${unsafeStatic('foo')}="${'bar'}"></div>`, container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div foo="bar"></div>' | ||
); | ||
|
||
render(html`<div x-${unsafeStatic('foo')}="${'bar'}"></div>`, container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div x-foo="bar"></div>' | ||
); | ||
}); | ||
|
||
test('static attribute name binding', () => { | ||
render( | ||
html`<div ${unsafeStatic('foo')}="${unsafeStatic('bar')}"></div>`, | ||
container | ||
); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div foo="bar"></div>' | ||
); | ||
}); | ||
|
||
test('dynamic binding after static text binding', () => { | ||
render(html`${unsafeStatic('<p>Hello</p>')}${'<p>World</p>'}`, container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<p>Hello</p><p>World</p>' | ||
); | ||
|
||
// Make sure `null` is handled | ||
render(html`${unsafeStatic('<p>Hello</p>')}${null}`, container); | ||
assert.equal(stripExpressionComments(container.innerHTML), '<p>Hello</p>'); | ||
}); | ||
|
||
test('static bindings are keyed by static values', () => { | ||
// A template with a bound tag name. We should be able to re-render | ||
// this template with different tag names and have the tag names update. | ||
// New tag names will act as different templates. | ||
const t = (tag: string, text: string) => | ||
html`<${unsafeStatic(tag)}>${text}</${unsafeStatic(tag)}>`; | ||
|
||
render(t('div', 'abc'), container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div>abc</div>' | ||
); | ||
const div = container.querySelector('div'); | ||
assert.isNotNull(div); | ||
|
||
render(t('div', 'def'), container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div>def</div>' | ||
); | ||
const div2 = container.querySelector('div'); | ||
// Static values are stable between renders like static template strings | ||
assert.strictEqual(div2, div); | ||
|
||
render(t('span', 'abc'), container); | ||
// Rendering with a new static value should work, though it re-renders | ||
// since we have a new template. | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<span>abc</span>' | ||
); | ||
const span = container.querySelector('span'); | ||
assert.isNotNull(span); | ||
|
||
render(t('span', 'def'), container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<span>def</span>' | ||
); | ||
const span2 = container.querySelector('span'); | ||
assert.strictEqual(span2, span); | ||
|
||
render(t('div', 'abc'), container); | ||
assert.equal( | ||
stripExpressionComments(container.innerHTML), | ||
'<div>abc</div>' | ||
); | ||
const div3 = container.querySelector('div'); | ||
// Static values do not have any caching behavior. Re-rendering with a | ||
// previously used value does not restore static DOM | ||
assert.notStrictEqual(div3, div); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
demo/ | ||
lib/ | ||
node_modules/ | ||
test/ | ||
index.* | ||
/demo/ | ||
/lib/ | ||
/node_modules/ | ||
/test/ | ||
/index.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
lib/ | ||
lib_client/ | ||
node_modules/ | ||
testdata/*/output/ | ||
tests/ | ||
.tsbuildinfo.client | ||
lit-localize.* | ||
localized-element.* | ||
examples/*/node_modules/ | ||
/lib/ | ||
/lib_client/ | ||
/node_modules/ | ||
/testdata/*/output/ | ||
/tests/ | ||
/.tsbuildinfo.client | ||
/lit-localize.* | ||
/localized-element.* | ||
/examples/*/node_modules/ | ||
/fnv1a64.* | ||
/id-generation.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.