Skip to content

Commit 8b16741

Browse files
committed
Use the CSS content property to populate an element's src, value, inner-text, etc
1 parent e0c3df8 commit 8b16741

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,19 @@ const html = cssToHtml(css);
2929
Input:
3030
```css
3131
h1 {
32+
content: 'Awesome!';
3233
color: grey;
3334
}
3435
p > button.rounded {
36+
content: 'Click here';
3537
background: #fff;
3638
border-radius: 8px;
3739
}
3840
p > button.rounded:hover {
3941
background: #ddd;
4042
}
4143
a img#logo {
44+
content: 'https://example.com/image';
4245
display: block;
4346
width: 1.5em;
4447
height: 1.5em;
@@ -48,10 +51,10 @@ a img#logo {
4851
Output:
4952
```html
5053
<body>
51-
<h1></h1>
54+
<h1>Awesome!</h1>
5255
<p>
53-
<button class="rounded"></button>
56+
<button class="rounded">Click here</button>
5457
</p>
55-
<a><img id="logo"></a>
58+
<a><img src="https://example.com/image" id="logo"></a>
5659
</body>
5760
```

src/Generator.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,49 @@ export function cssToHtml(css: CSSRuleList | string): HTMLBodyElement {
138138
descriptor.clear();
139139
}
140140
}
141+
142+
// If the rule has a `content` property, populate the element with the specified content appropriately.
143+
let content = rule.style.content;
144+
const element = descriptor.previousElement;
145+
if (content && element) {
146+
// Strip any quote marks from around the content string.
147+
if (/(?:'|")/.test(content.charAt(0)) && /(?:'|")/.test(content.charAt(content.length - 1))) {
148+
content = content.substring(1, content.length - 1);
149+
}
150+
// Place the content in the `href` property of anchor elements.
151+
if (element instanceof HTMLAnchorElement) {
152+
element.href = content;
153+
}
154+
// Place the content in the `src` property of audio, iframe, image, and video elements.
155+
else if (
156+
element instanceof HTMLAudioElement
157+
|| element instanceof HTMLIFrameElement
158+
|| element instanceof HTMLImageElement
159+
|| element instanceof HTMLVideoElement
160+
) {
161+
element.src = content;
162+
}
163+
// Place the content in the `placeholder` property of input and textarea elements.
164+
else if (
165+
element instanceof HTMLInputElement
166+
|| element instanceof HTMLTextAreaElement
167+
) {
168+
element.placeholder = content;
169+
}
170+
// Use the content as inner-text and place it in the `value` property of option elements.
171+
else if (element instanceof HTMLOptionElement) {
172+
element.innerText = content;
173+
element.value = content;
174+
}
175+
// Place the content in the `value` property of select elements.
176+
else if (element instanceof HTMLSelectElement) {
177+
element.value = content;
178+
}
179+
// Use the content as inner-text for all other elements.
180+
else {
181+
element.innerText = content;
182+
}
183+
}
141184
}
142185

143186
return output;

tests/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ const input = `
88
box-sizing: border-box;
99
}
1010
a {
11+
content: 'https://example.com/';
1112
border-radius: 10px;
1213
}
1314
button {
15+
content: 'Click me';
1416
background-color: red;
1517
}
1618
button:hover {
@@ -22,6 +24,7 @@ button:hover {
2224
background-color: red;
2325
}
2426
nav a#logo.icon> img {
27+
content: 'https://example.com/image';
2528
display: block;
2629
}
2730
.pie .pastry.crenelations {

0 commit comments

Comments
 (0)