`${key}="${value}"`).join(' ')}` : ''}` +
+ `>${this.parser.parseInline(token.tokens)}`; // parseInline to turn child tokens into HTML
}
};
@@ -149,13 +156,13 @@ const mustacheDivs = {
if(match) {
//Find closing delimiter
let blockCount = 0;
- let tags = '';
+ let tags = {};
let endTags = 0;
let endToken = 0;
let delim;
while (delim = blockRegex.exec(match[0])?.[0].trim()) {
- if(!tags) {
- tags = `${processStyleTags(delim.substring(2))}`;
+ if(_.isEmpty(tags)) {
+ tags = processStyleTags(delim.substring(2));
endTags = delim.length + src.indexOf(delim);
}
if(delim.startsWith('{{')) {
@@ -183,7 +190,14 @@ const mustacheDivs = {
}
},
renderer(token) {
- return `
`${key}="${value}"`).join(' ')}` : ''}` +
+ `>${this.parser.parse(token.tokens)}
`; // parse to turn child tokens into HTML
}
};
@@ -199,23 +213,39 @@ const mustacheInjectInline = {
if(!lastToken || lastToken.type == 'mustacheInjectInline')
return false;
- const tags = `${processStyleTags(match[1])}`;
+ const tags = processStyleTags(match[1]);
lastToken.originalType = lastToken.type;
lastToken.type = 'mustacheInjectInline';
- lastToken.tags = tags;
+ lastToken.injectedTags = tags;
return {
- type : 'text', // Should match "name" above
+ type : 'mustacheInjectInline', // Should match "name" above
raw : match[0], // Text to consume from the source
text : ''
};
}
},
renderer(token) {
+ if(!token.originalType){
+ return;
+ }
token.type = token.originalType;
const text = this.parser.parseInline([token]);
- const openingTag = /(<[^\s<>]+)([^\n<>]*>.*)/s.exec(text);
+ const originalTags = extractHTMLStyleTags(text);
+ const injectedTags = token.injectedTags;
+ const tags = {
+ id : injectedTags.id || originalTags.id || null,
+ classes : [originalTags.classes, injectedTags.classes].join(' ').trim() || null,
+ styles : [originalTags.styles, injectedTags.styles].join(' ').trim() || null,
+ attributes : Object.assign(originalTags.attributes ?? {}, injectedTags.attributes ?? {})
+ };
+ const openingTag = /(<[^\s<>]+)[^\n<>]*(>.*)/s.exec(text);
if(openingTag) {
- return `${openingTag[1]} class="${token.tags}${openingTag[2]}`;
+ return `${openingTag[1]}` +
+ `${tags.classes ? ` class="${tags.classes}"` : ''}` +
+ `${tags.id ? ` id="${tags.id}"` : ''}` +
+ `${tags.styles ? ` style="${tags.styles}"` : ''}` +
+ `${!_.isEmpty(tags.attributes) ? ` ${Object.entries(tags.attributes).map(([key, value]) => `${key}="${value}"`).join(' ')}` : ''}` +
+ `${openingTag[2]}`; // parse to turn child tokens into HTML
}
return text;
}
@@ -235,7 +265,7 @@ const mustacheInjectBlock = {
return false;
lastToken.originalType = 'mustacheInjectBlock';
- lastToken.tags = `${processStyleTags(match[1])}`;
+ lastToken.injectedTags = processStyleTags(match[1]);
return {
type : 'mustacheInjectBlock', // Should match "name" above
raw : match[0], // Text to consume from the source
@@ -249,9 +279,22 @@ const mustacheInjectBlock = {
}
token.type = token.originalType;
const text = this.parser.parse([token]);
- const openingTag = /(<[^\s<>]+)([^\n<>]*>.*)/s.exec(text);
+ const originalTags = extractHTMLStyleTags(text);
+ const injectedTags = token.injectedTags;
+ const tags = {
+ id : injectedTags.id || originalTags.id || null,
+ classes : [originalTags.classes, injectedTags.classes].join(' ').trim() || null,
+ styles : [originalTags.styles, injectedTags.styles].join(' ').trim() || null,
+ attributes : Object.assign(originalTags.attributes ?? {}, injectedTags.attributes ?? {})
+ };
+ const openingTag = /(<[^\s<>]+)[^\n<>]*(>.*)/s.exec(text);
if(openingTag) {
- return `${openingTag[1]} class="${token.tags}${openingTag[2]}`;
+ return `${openingTag[1]}` +
+ `${tags.classes ? ` class="${tags.classes}"` : ''}` +
+ `${tags.id ? ` id="${tags.id}"` : ''}` +
+ `${tags.styles ? ` style="${tags.styles}"` : ''}` +
+ `${!_.isEmpty(tags.attributes) ? ` ${Object.entries(tags.attributes).map(([key, value]) => `${key}="${value}"`).join(' ')}` : ''}` +
+ `${openingTag[2]}`; // parse to turn child tokens into HTML
}
return text;
}
@@ -687,15 +730,45 @@ const processStyleTags = (string)=>{
//TODO: can we simplify to just split on commas?
const tags = string.match(/(?:[^, ":=]+|[:=](?:"[^"]*"|))+/g);
- const id = _.remove(tags, (tag)=>tag.startsWith('#')).map((tag)=>tag.slice(1))[0];
- const classes = _.remove(tags, (tag)=>(!tag.includes(':')) && (!tag.includes('=')));
- const attributes = _.remove(tags, (tag)=>(tag.includes('='))).map((tag)=>tag.replace(/="?([^"]*)"?/g, '="$1"'));
- const styles = tags?.length ? tags.map((tag)=>tag.replace(/:"?([^"]*)"?/g, ':$1;').trim()) : [];
+ const id = _.remove(tags, (tag)=>tag.startsWith('#')).map((tag)=>tag.slice(1))[0] || null;
+ const classes = _.remove(tags, (tag)=>(!tag.includes(':')) && (!tag.includes('='))).join(' ') || null;
+ const attributes = _.remove(tags, (tag)=>(tag.includes('='))).map((tag)=>tag.replace(/="?([^"]*)"?/g, '="$1"'))
+ ?.filter(attr => !attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
+ .reduce((obj, attr) => {
+ let [key, value] = attr.split("=");
+ value = value.replace(/"/g, '');
+ obj[key] = value;
+ return obj;
+ }, {}) || null;
+ const styles = tags?.length ? tags.map((tag)=>tag.replace(/:"?([^"]*)"?/g, ':$1;').trim()).join(' ') : null;
- return `${classes?.length ? ` ${classes.join(' ')}` : ''}"` +
- `${id ? ` id="${id}"` : ''}` +
- `${styles?.length ? ` style="${styles.join(' ')}"` : ''}` +
- `${attributes?.length ? ` ${attributes.join(' ')}` : ''}`;
+ return {
+ id : id,
+ classes : classes,
+ styles : styles,
+ attributes : _.isEmpty(attributes) ? null : attributes
+ };
+};
+
+const extractHTMLStyleTags = (htmlString)=> {
+ const id = htmlString.match(/id="([^"]*)"/)?.[1] || null;
+ const classes = htmlString.match(/class="([^"]*)"/)?.[1] || null;
+ const styles = htmlString.match(/style="([^"]*)"/)?.[1] || null;
+ const attributes = htmlString.match(/[a-zA-Z]+="[^"]*"/g)
+ ?.filter(attr => !attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="'))
+ .reduce((obj, attr) => {
+ let [key, value] = attr.split("=");
+ value = value.replace(/"/g, '');
+ obj[key] = value;
+ return obj;
+ }, {}) || null;
+
+ return {
+ id : id,
+ classes : classes,
+ styles : styles,
+ attributes : _.isEmpty(attributes) ? null : attributes
+ };
};
const globalVarsList = {};
diff --git a/tests/markdown/mustache-syntax.test.js b/tests/markdown/mustache-syntax.test.js
index 835bcc575b..b32876353c 100644
--- a/tests/markdown/mustache-syntax.test.js
+++ b/tests/markdown/mustache-syntax.test.js
@@ -130,8 +130,8 @@ describe('Inline: When using the Inline syntax {{ }}', ()=>{
describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
it('Renders a div with text only', function() {
const source = dedent`{{
- text
- }}`;
+ text
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -139,14 +139,14 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
it('Renders an empty div', function() {
const source = dedent`{{
- }}`;
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a single paragraph with opening and closing brackets', function() {
const source = dedent`{{
- }}`;
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
{{}}
`);
});
@@ -154,79 +154,79 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
it('Renders a div with a single class', function() {
const source = dedent`{{cat
- }}`;
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with a single class and text', function() {
const source = dedent`{{cat
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with two classes and text', function() {
const source = dedent`{{cat,dog
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with a style and text', function() {
const source = dedent`{{color:red
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with a style that has a string variable, and text', function() {
const source = dedent`{{--stringVariable:"'string'"
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with a style that has a string variable, and text', function() {
const source = dedent`{{--stringVariable:"'string'"
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with a class, style and text', function() {
const source = dedent`{{cat,color:red
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with an ID, class, style and text (different order)', function() {
const source = dedent`{{color:red,cat,#dog
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with a single ID', function() {
const source = dedent`{{#cat,#dog
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
it('Renders a div with an ID, class, style and text, and a variable assignment', function() {
const source = dedent`{{color:red,cat,#dog,a="b and c",d="e"
- Sample text.
- }}`;
+ Sample text.
+ }}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
@@ -243,61 +243,91 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{
describe('Injection: When an injection tag follows an element', ()=>{
// FIXME: Most of these fail because injections currently replace attributes, rather than append to. Or just minor extra whitespace issues.
describe('and that element is an inline-block', ()=>{
- it.failing('Renders a span "text" with no injection', function() {
+ it('Renders a span "text" with no injection', function() {
const source = '{{ text}}{}';
const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
- it.failing('Renders a span "text" with injected Class name', function() {
+ it('Renders a span "text" with injected Class name', function() {
const source = '{{ text}}{ClassName}';
const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
- it.failing('Renders a span "text" with injected attribute', function() {
+ it('Renders a span "text" with injected attribute', function() {
const source = '{{ text}}{a="b and c"}';
const rendered = Markdown.render(source);
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
- it.failing('Renders a span "text" with injected style', function() {
+ it('Renders a span "text" with injected style', function() {
const source = '{{ text}}{color:red}';
const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
- it.failing('Renders a span "text" with injected style using a string variable', function() {
+ it('Renders a span "text" with injected style using a string variable', function() {
const source = `{{ text}}{--stringVariable:"'string'"}`;
const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
text`);
});
- it.failing('Renders a span "text" with two injected styles', function() {
+ it('Renders a span "text" with two injected styles', function() {
const source = '{{ text}}{color:red,background:blue}';
const rendered = Markdown.render(source);
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
});
- it.failing('Renders an emphasis element with injected Class name', function() {
+ it('Renders a span "text" with its own ID, overwritten with an injected ID', function() {
+ const source = '{{#oldId text}}{#newId}';
+ const rendered = Markdown.render(source);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
+ });
+
+ it('Renders a span "text" with its own attributes, overwritten with an injected attribute, plus a new one', function() {
+ const source = '{{attrA="old",attrB="old" text}}{attrA="new",attrC="new"}';
+ const rendered = Markdown.render(source);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
+ });
+
+ it('Renders a span "text" with its own attributes, overwritten with an injected attribute, ignoring "class", "style", and "id"', function() {
+ const source = '{{attrA="old",attrB="old" text}}{attrA="new",attrC="new",class="new",style="new",id="new"}';
+ const rendered = Markdown.render(source);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
+ });
+
+ it('Renders a span "text" with its own styles, appended with injected styles', function() {
+ const source = '{{color:blue,height:10px text}}{width:10px,color:red}';
+ const rendered = Markdown.render(source);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
+ });
+
+ it('Renders a span "text" with its own classes, appended with injected classes', function() {
+ const source = '{{classA,classB text}}{classA,classC}';
+ const rendered = Markdown.render(source);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text');
+ });
+
+ it('Renders an emphasis element with injected Class name', function() {
const source = '*emphasis*{big}';
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
emphasis
');
});
- it.failing('Renders a code element with injected style', function() {
+ it('Renders a code element with injected style', function() {
const source = '`code`{background:gray}';
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
code
');
});
- it.failing('Renders an image element with injected style', function() {
+ it('Renders an image element with injected style', function() {
const source = '![alt text](http://i.imgur.com/hMna6G0.png){position:absolute}';
const rendered = Markdown.render(source).trimReturns();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
- it.failing('Renders an element modified by only the first of two consecutive injections', function() {
+ it('Renders an element modified by only the first of two consecutive injections', function() {
const source = '{{ text}}{color:red}{background:blue}';
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text{background:blue}
');
@@ -306,61 +336,106 @@ describe('Injection: When an injection tag follows an element', ()=>{
it('Renders an image with added attributes', function() {
const source = `![homebrew mug](https://i.imgur.com/hMna6G0.png) {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e}`;
const rendered = Markdown.render(source).trimReturns();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
});
describe('and that element is a block', ()=>{
- it.failing('renders a div "text" with no injection', function() {
+ it('renders a div "text" with no injection', function() {
const source = '{{\ntext\n}}\n{}';
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
- it.failing('renders a div "text" with injected Class name', function() {
+ it('renders a div "text" with injected Class name', function() {
const source = '{{\ntext\n}}\n{ClassName}';
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
- it.failing('renders a div "text" with injected style', function() {
+ it('renders a div "text" with injected style', function() {
const source = '{{\ntext\n}}\n{color:red}';
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
- it.failing('renders a div "text" with two injected styles', function() {
+ it('renders a div "text" with two injected styles', function() {
const source = dedent`{{
- text
- }}
- {color:red,background:blue}`;
+ text
+ }}
+ {color:red,background:blue}`;
const rendered = Markdown.render(source).trimReturns();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
});
- it.failing('renders a div "text" with injected variable string', function() {
+ it('renders a div "text" with injected variable string', function() {
const source = dedent`{{
- text
- }}
- {--stringVariable:"'string'"}`;
+ text
+ }}
+ {--stringVariable:"'string'"}`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
+ });
+
+ it('Renders a span "text" with its own ID, overwritten with an injected ID', function() {
+ const source = dedent`{{#oldId
+ text
+ }}
+ {#newId}`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
+ });
+
+ it('Renders a span "text" with its own attributes, overwritten with an injected attribute, plus a new one', function() {
+ const source = dedent`{{attrA="old",attrB="old"
+ text
+ }}
+ {attrA="new",attrC="new"}`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
+ });
+
+ it('Renders a span "text" with its own attributes, overwritten with an injected attribute, ignoring "class", "style", and "id"', function() {
+ const source = dedent`{{attrA="old",attrB="old"
+ text
+ }}
+ {attrA="new",attrC="new",class="new",style="new",id="new"}`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
+ });
+
+ it('Renders a span "text" with its own styles, appended with injected styles', function() {
+ const source = dedent`{{color:blue,height:10px
+ text
+ }}
+ {width:10px,color:red}`;
+ const rendered = Markdown.render(source).trimReturns();
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
+ });
+
+ it('Renders a span "text" with its own classes, appended with injected classes', function() {
+ const source = dedent`{{classA,classB
+ text
+ }}
+ {classA,classC}`;
const rendered = Markdown.render(source).trimReturns();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`);
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
');
});
- it.failing('renders an h2 header "text" with injected class name', function() {
+ it('renders an h2 header "text" with injected class name', function() {
const source = dedent`## text
- {ClassName}`;
+ {ClassName}`;
const rendered = Markdown.render(source).trimReturns();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text
');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text
');
});
- it.failing('renders a table with injected class name', function() {
+ it('renders a table with injected class name', function() {
const source = dedent`| Experience Points | Level |
- |:------------------|:-----:|
- | 0 | 1 |
- | 300 | 2 |
+ |:------------------|:-----:|
+ | 0 | 1 |
+ | 300 | 2 |
- {ClassName}`;
+ {ClassName}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
Experience Points | Level |
---|
0 | 1 |
300 | 2 |
`);
});
@@ -376,23 +451,23 @@ describe('Injection: When an injection tag follows an element', ()=>{
// expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`...`); // FIXME: expect this to be injected into
? Currently injects into last -
// });
- it.failing('renders an h2 header "text" with injected class name, and "secondInjection" as regular text on the next line.', function() {
+ it('renders an h2 header "text" with injected class name, and "secondInjection" as regular text on the next line.', function() {
const source = dedent`## text
{ClassName}
{secondInjection}`;
const rendered = Markdown.render(source).trimReturns();
- expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
text
{secondInjection}
');
+ expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text
{secondInjection}
');
});
- it.failing('renders a div nested into another div, the inner with class=innerDiv and the other class=outerDiv', function() {
+ it('renders a div nested into another div, the inner with class=innerDiv and the other class=outerDiv', function() {
const source = dedent`{{
- outer text
- {{
- inner text
- }}
- {innerDiv}
- }}
- {outerDiv}`;
+ outer text
+ {{
+ inner text
+ }}
+ {innerDiv}
+ }}
+ {outerDiv}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('');
});
diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js
index c909dafecb..e6018e19f2 100644
--- a/tests/markdown/variables.test.js
+++ b/tests/markdown/variables.test.js
@@ -329,7 +329,7 @@ describe('Normal Links and Images', ()=>{
const source = `![alt text](url){width:100px}`;
const rendered = Markdown.render(source).trimReturns();
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(dedent`
- `.trimReturns());
+ `.trimReturns());
});
it('Renders normal links', function() {
diff --git a/themes/V3/5ePHB/style.less b/themes/V3/5ePHB/style.less
index 25b784cfcd..57a39e5077 100644
--- a/themes/V3/5ePHB/style.less
+++ b/themes/V3/5ePHB/style.less
@@ -543,10 +543,8 @@
color : white;
text-shadow : unset;
text-transform : uppercase;
- filter : drop-shadow(0 0 1.5px black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black);
+ -webkit-text-stroke: 0.2cm black;
+ paint-order:stroke;
}
h2 {
font-family : 'NodestoCapsCondensed';
@@ -554,10 +552,8 @@
font-weight : normal;
color : white;
letter-spacing : 0.1cm;
- filter : drop-shadow(0 0 1px black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black);
+ -webkit-text-stroke: 0.14cm black;
+ paint-order:stroke;
}
hr {
position : relative;
@@ -603,10 +599,8 @@
font-size : 0.496cm;
color : white;
text-align : center;
- filter : drop-shadow(0 0 0.7px black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black)
- drop-shadow(0 0 0 black) drop-shadow(0 0 0 black);
+ -webkit-text-stroke: 0.1cm black;
+ paint-order:stroke;
}
.logo {
position : absolute;