mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 20:42:43 +00:00
Merge branch 'master' into RPG-Awesome-Redux
This commit is contained in:
@@ -14,6 +14,9 @@ const NotificationPopup = require('./notificationPopup/notificationPopup.jsx');
|
||||
const Frame = require('react-frame-component').default;
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
const DOMPurify = require('dompurify');
|
||||
const purifyConfig = { FORCE_BODY: true, SANITIZE_DOM: false };
|
||||
|
||||
const Themes = require('themes/themes.json');
|
||||
|
||||
const PAGE_HEIGHT = 1056;
|
||||
@@ -33,8 +36,9 @@ const BrewPage = (props)=>{
|
||||
index : 0,
|
||||
...props
|
||||
};
|
||||
const cleanText = DOMPurify.sanitize(props.contents, purifyConfig);
|
||||
return <div className={props.className} id={`p${props.index + 1}`} >
|
||||
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: props.contents }} />
|
||||
<div className='columnWrapper' dangerouslySetInnerHTML={{ __html: cleanText }} />
|
||||
</div>;
|
||||
};
|
||||
|
||||
@@ -102,13 +106,6 @@ const BrewRenderer = (props)=>{
|
||||
return false;
|
||||
};
|
||||
|
||||
const sanitizeScriptTags = (content)=>{
|
||||
return content
|
||||
?.replace(/<script/ig, '<script')
|
||||
.replace(/<\/script>/ig, '</script>')
|
||||
|| '';
|
||||
};
|
||||
|
||||
const renderPageInfo = ()=>{
|
||||
return <div className='pageInfo' ref={mainRef}>
|
||||
<div>
|
||||
@@ -128,19 +125,18 @@ const BrewRenderer = (props)=>{
|
||||
|
||||
const renderStyle = ()=>{
|
||||
if(!props.style) return;
|
||||
const cleanStyle = sanitizeScriptTags(props.style);
|
||||
const cleanStyle = DOMPurify.sanitize(props.style, purifyConfig);
|
||||
//return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style>@layer styleTab {\n${sanitizeScriptTags(props.style)}\n} </style>` }} />;
|
||||
return <div style={{ display: 'none' }} dangerouslySetInnerHTML={{ __html: `<style> ${cleanStyle} </style>` }} />;
|
||||
};
|
||||
|
||||
const renderPage = (pageText, index)=>{
|
||||
let cleanPageText = sanitizeScriptTags(pageText);
|
||||
if(props.renderer == 'legacy') {
|
||||
const html = MarkdownLegacy.render(cleanPageText);
|
||||
const html = MarkdownLegacy.render(pageText);
|
||||
return <BrewPage className='page phb' index={index} key={index} contents={html} />;
|
||||
} else {
|
||||
cleanPageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
|
||||
const html = Markdown.render(cleanPageText, index);
|
||||
pageText += `\n\n \n\\column\n `; //Artificial column break at page end to emulate column-fill:auto (until `wide` is used, when column-fill:balance will reappear)
|
||||
const html = Markdown.render(pageText, index);
|
||||
return <BrewPage className='page' index={index} key={index} contents={html} />;
|
||||
}
|
||||
};
|
||||
@@ -211,11 +207,11 @@ const BrewRenderer = (props)=>{
|
||||
<RenderWarnings />
|
||||
<NotificationPopup />
|
||||
</div>
|
||||
<link href={`/themes/${rendererPath}/Blank/style.css`} type="text/css" rel='stylesheet'/>
|
||||
<link href={`/themes/${rendererPath}/Blank/style.css`} type='text/css' rel='stylesheet'/>
|
||||
{baseThemePath &&
|
||||
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type="text/css" rel='stylesheet'/>
|
||||
<link href={`/themes/${rendererPath}/${baseThemePath}/style.css`} type='text/css' rel='stylesheet'/>
|
||||
}
|
||||
<link href={`/themes/${rendererPath}/${themePath}/style.css`} type="text/css" rel='stylesheet'/>
|
||||
<link href={`/themes/${rendererPath}/${themePath}/style.css`} type='text/css' rel='stylesheet'/>
|
||||
|
||||
{/* Apply CSS from Style tab and render pages from Markdown tab */}
|
||||
{state.isMounted
|
||||
|
||||
@@ -5,6 +5,7 @@ const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
const Markdown = require('../../../shared/naturalcrit/markdown.js');
|
||||
|
||||
const CodeEditor = require('naturalcrit/codeEditor/codeEditor.jsx');
|
||||
const SnippetBar = require('./snippetbar/snippetbar.jsx');
|
||||
@@ -219,6 +220,34 @@ const Editor = createClass({
|
||||
endCh = match.index+match[0].length;
|
||||
codeMirror.markText({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: endCh }, { className: 'block' });
|
||||
}
|
||||
|
||||
// Emojis
|
||||
if(line.match(/:[^\s:]+:/g)) {
|
||||
let startIndex = line.indexOf(':');
|
||||
const emojiRegex = /:[^\s:]+:/gy;
|
||||
|
||||
while (startIndex >= 0) {
|
||||
emojiRegex.lastIndex = startIndex;
|
||||
let match = emojiRegex.exec(line);
|
||||
if (match) {
|
||||
let tokens = Markdown.marked.lexer(match[0]);
|
||||
tokens = tokens[0].tokens.filter(t => t.type == 'emoji')
|
||||
if (!tokens.length)
|
||||
return;
|
||||
|
||||
let startPos = { line: lineNumber, ch: match.index };
|
||||
let endPos = { line: lineNumber, ch: match.index + match[0].length };
|
||||
|
||||
// Iterate over conflicting marks and clear them
|
||||
var marks = codeMirror.findMarks(startPos, endPos);
|
||||
marks.forEach(function(marker) {
|
||||
marker.clear();
|
||||
});
|
||||
codeMirror.markText(startPos, endPos, { className: 'emoji' });
|
||||
}
|
||||
startIndex = line.indexOf(':', Math.max(startIndex + 1, emojiRegex.lastIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,6 +43,16 @@
|
||||
font-weight : bold;
|
||||
color : green;
|
||||
}
|
||||
.emoji:not(.cm-comment) {
|
||||
margin-left : 2px;
|
||||
color : #360034;
|
||||
background : #ffc8ff;
|
||||
border-radius : 6px;
|
||||
font-weight : bold;
|
||||
padding-bottom : 1px;
|
||||
outline-offset : -2px;
|
||||
outline : solid 2px #ff96fc;
|
||||
}
|
||||
.superscript:not(.cm-comment) {
|
||||
font-weight : bold;
|
||||
color : goldenrod;
|
||||
|
||||
@@ -1,41 +1,25 @@
|
||||
require('./errorPage.less');
|
||||
const React = require('react');
|
||||
const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
|
||||
const UIPage = require('../basePages/uiPage/uiPage.jsx');
|
||||
|
||||
const Markdown = require('../../../../shared/naturalcrit/markdown.js');
|
||||
|
||||
const React = require('react');
|
||||
const UIPage = require('../basePages/uiPage/uiPage.jsx');
|
||||
const Markdown = require('../../../../shared/naturalcrit/markdown.js');
|
||||
const ErrorIndex = require('./errors/errorIndex.js');
|
||||
|
||||
const ErrorPage = createClass({
|
||||
displayName : 'ErrorPage',
|
||||
const ErrorPage = ({ brew })=>{
|
||||
// Retrieving the error text based on the brew's error code from ErrorIndex
|
||||
const errorText = ErrorIndex({ brew })[brew.HBErrorCode.toString()] || '';
|
||||
|
||||
getDefaultProps : function() {
|
||||
return {
|
||||
ver : '0.0.0',
|
||||
errorId : '',
|
||||
text : '# Oops \n We could not find a brew with that id. **Sorry!**',
|
||||
error : {}
|
||||
};
|
||||
},
|
||||
|
||||
render : function(){
|
||||
const errorText = ErrorIndex(this.props)[this.props.brew.HBErrorCode.toString()] || '';
|
||||
|
||||
return <UIPage brew={{ title: 'Crit Fail!' }}>
|
||||
return (
|
||||
<UIPage brew={{ title: 'Crit Fail!' }}>
|
||||
<div className='dataGroup'>
|
||||
<div className='errorTitle'>
|
||||
<h1>{`Error ${this.props.brew.status || '000'}`}</h1>
|
||||
<h4>{this.props.brew.text || 'No error text'}</h4>
|
||||
<h1>{`Error ${brew?.status || '000'}`}</h1>
|
||||
<h4>{brew?.text || 'No error text'}</h4>
|
||||
</div>
|
||||
<hr />
|
||||
<div dangerouslySetInnerHTML={{ __html: Markdown.render(errorText) }} />
|
||||
</div>
|
||||
</UIPage>;
|
||||
}
|
||||
});
|
||||
</UIPage>
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = ErrorPage;
|
||||
|
||||
@@ -47,6 +47,19 @@ const SharePage = createClass({
|
||||
this.props.brew.shareId;
|
||||
},
|
||||
|
||||
renderEditLink : function(){
|
||||
if(!this.props.brew.editId) return;
|
||||
|
||||
let editLink = this.props.brew.editId;
|
||||
if(this.props.brew.googleId && !this.props.brew.stubbed) {
|
||||
editLink = this.props.brew.googleId + editLink;
|
||||
}
|
||||
|
||||
return <Nav.item color='orange' icon='fas fa-pencil-alt' href={`/edit/${editLink}`}>
|
||||
edit
|
||||
</Nav.item>;
|
||||
},
|
||||
|
||||
render : function(){
|
||||
return <div className='sharePage sitePage'>
|
||||
<Meta name='robots' content='noindex, nofollow' />
|
||||
@@ -64,13 +77,14 @@ const SharePage = createClass({
|
||||
<Nav.item color='red' icon='fas fa-code'>
|
||||
source
|
||||
</Nav.item>
|
||||
<Nav.item color='blue' href={`/source/${this.processShareId()}`}>
|
||||
<Nav.item color='blue' icon='fas fa-eye' href={`/source/${this.processShareId()}`}>
|
||||
view
|
||||
</Nav.item>
|
||||
<Nav.item color='blue' href={`/download/${this.processShareId()}`}>
|
||||
{this.renderEditLink()}
|
||||
<Nav.item color='blue' icon='fas fa-download' href={`/download/${this.processShareId()}`}>
|
||||
download
|
||||
</Nav.item>
|
||||
<Nav.item color='blue' href={`/new/${this.processShareId()}`}>
|
||||
<Nav.item color='blue' icon='fas fa-clone' href={`/new/${this.processShareId()}`}>
|
||||
clone to new
|
||||
</Nav.item>
|
||||
</Nav.dropdown>
|
||||
|
||||
30314
package-lock.json
generated
30314
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@@ -27,11 +27,12 @@
|
||||
"test:dev": "jest --verbose --watch",
|
||||
"test:basic": "jest tests/markdown/basic.test.js --verbose",
|
||||
"test:variables": "jest tests/markdown/variables.test.js --verbose",
|
||||
"test:mustache-syntax": "jest '.*(mustache-syntax).*' --verbose --noStackTrace",
|
||||
"test:mustache-syntax:inline": "jest '.*(mustache-syntax).*' -t '^Inline:.*' --verbose --noStackTrace",
|
||||
"test:mustache-syntax:block": "jest '.*(mustache-syntax).*' -t '^Block:.*' --verbose --noStackTrace",
|
||||
"test:mustache-syntax:injection": "jest '.*(mustache-syntax).*' -t '^Injection:.*' --verbose --noStackTrace",
|
||||
"test:mustache-syntax": "jest \".*(mustache-syntax).*\" --verbose --noStackTrace",
|
||||
"test:mustache-syntax:inline": "jest \".*(mustache-syntax).*\" -t '^Inline:.*' --verbose --noStackTrace",
|
||||
"test:mustache-syntax:block": "jest \".*(mustache-syntax).*\" -t '^Block:.*' --verbose --noStackTrace",
|
||||
"test:mustache-syntax:injection": "jest \".*(mustache-syntax).*\" -t '^Injection:.*' --verbose --noStackTrace",
|
||||
"test:definition-lists": "jest tests/markdown/definition-lists.test.js --verbose --noStackTrace",
|
||||
"test:emojis": "jest tests/markdown/emojis.test.js --verbose --noStackTrace",
|
||||
"test:route": "jest tests/routes/static-pages.test.js --verbose",
|
||||
"phb": "node scripts/phb.js",
|
||||
"prod": "set NODE_ENV=production && npm run build",
|
||||
@@ -81,17 +82,18 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.24.4",
|
||||
"@babel/core": "^7.24.5",
|
||||
"@babel/plugin-transform-runtime": "^7.24.3",
|
||||
"@babel/preset-env": "^7.24.4",
|
||||
"@babel/preset-env": "^7.24.5",
|
||||
"@babel/preset-react": "^7.24.1",
|
||||
"@googleapis/drive": "^8.7.0",
|
||||
"@googleapis/drive": "^8.8.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"classnames": "^2.5.1",
|
||||
"codemirror": "^5.65.6",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"create-react-class": "^15.7.0",
|
||||
"dedent-tabs": "^0.10.3",
|
||||
"dompurify": "^3.1.1",
|
||||
"expr-eval": "^2.0.2",
|
||||
"express": "^4.19.2",
|
||||
"express-async-handler": "^1.2.0",
|
||||
@@ -108,20 +110,20 @@
|
||||
"marked-smartypants-lite": "^1.0.2",
|
||||
"markedLegacy": "npm:marked@^0.3.19",
|
||||
"moment": "^2.30.1",
|
||||
"mongoose": "^8.3.1",
|
||||
"mongoose": "^8.3.3",
|
||||
"nanoid": "3.3.4",
|
||||
"nconf": "^0.12.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-frame-component": "^4.1.3",
|
||||
"react-router-dom": "6.22.3",
|
||||
"react-router-dom": "6.23.0",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"superagent": "^8.1.2",
|
||||
"superagent": "^9.0.2",
|
||||
"vitreum": "git+https://git@github.com/calculuschild/vitreum.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-jest": "^28.2.0",
|
||||
"eslint-plugin-jest": "^28.5.0",
|
||||
"eslint-plugin-react": "^7.34.1",
|
||||
"jest": "^29.7.0",
|
||||
"jest-expect-message": "^1.1.3",
|
||||
@@ -130,6 +132,6 @@
|
||||
"stylelint-config-recess-order": "^4.6.0",
|
||||
"stylelint-config-recommended": "^13.0.0",
|
||||
"stylelint-stylistic": "^0.4.3",
|
||||
"supertest": "^6.3.4"
|
||||
"supertest": "^7.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ const { splitTextStyleAndMetadata } = require('../shared/helpers.js');
|
||||
const sanitizeBrew = (brew, accessType)=>{
|
||||
brew._id = undefined;
|
||||
brew.__v = undefined;
|
||||
if(accessType !== 'edit'){
|
||||
if(accessType !== 'edit' && accessType !== 'shareAuthor') {
|
||||
brew.editId = undefined;
|
||||
}
|
||||
}
|
||||
return brew;
|
||||
};
|
||||
|
||||
@@ -307,7 +307,6 @@ app.get('/new/:id', asyncHandler(getBrew('share')), (req, res, next)=>{
|
||||
//Share Page
|
||||
app.get('/share/:id', asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{
|
||||
const { brew } = req;
|
||||
|
||||
req.ogMeta = { ...defaultMetaTags,
|
||||
title : req.brew.title || 'Untitled Brew',
|
||||
description : req.brew.description || 'No description.',
|
||||
@@ -326,7 +325,8 @@ app.get('/share/:id', asyncHandler(getBrew('share')), asyncHandler(async (req, r
|
||||
await HomebrewModel.increaseView({ shareId: brew.shareId });
|
||||
}
|
||||
};
|
||||
sanitizeBrew(req.brew, 'share');
|
||||
|
||||
brew.authors.includes(req.account?.username) ? sanitizeBrew(req.brew, 'shareAuthor') : sanitizeBrew(req.brew, 'share');
|
||||
splitTextStyleAndMetadata(req.brew);
|
||||
return next();
|
||||
}));
|
||||
|
||||
82
shared/naturalcrit/codeEditor/autocompleteEmoji.js
Normal file
82
shared/naturalcrit/codeEditor/autocompleteEmoji.js
Normal file
@@ -0,0 +1,82 @@
|
||||
const diceFont = require('../../../themes/fonts/iconFonts/diceFont.js');
|
||||
const elderberryInn = require('../../../themes/fonts/iconFonts/elderberryInn.js');
|
||||
const fontAwesome = require('../../../themes/fonts/iconFonts/fontAwesome.js');
|
||||
|
||||
const emojis = {
|
||||
...diceFont,
|
||||
...elderberryInn,
|
||||
...fontAwesome
|
||||
};
|
||||
|
||||
const showAutocompleteEmoji = function(CodeMirror, editor) {
|
||||
CodeMirror.commands.autocomplete = function(editor) {
|
||||
editor.showHint({
|
||||
completeSingle : false,
|
||||
hint : function(editor) {
|
||||
const cursor = editor.getCursor();
|
||||
const line = cursor.line;
|
||||
const lineContent = editor.getLine(line);
|
||||
const start = lineContent.lastIndexOf(':', cursor.ch - 1) + 1;
|
||||
const end = cursor.ch;
|
||||
const currentWord = lineContent.slice(start, end);
|
||||
|
||||
|
||||
const list = Object.keys(emojis).filter(function(emoji) {
|
||||
return emoji.toLowerCase().indexOf(currentWord.toLowerCase()) >= 0;
|
||||
}).sort((a, b)=>{
|
||||
const lowerA = a.replace(/\d+/g, function(match) { // Temporarily convert any numbers in emoji string
|
||||
return match.padStart(4, '0'); // to 4-digits, left-padded with 0's, to aid in
|
||||
}).toLowerCase(); // sorting numbers, i.e., "d6, d10, d20", not "d10, d20, d6"
|
||||
const lowerB = b.replace(/\d+/g, function(match) { // Also make lowercase for case-insensitive alpha sorting
|
||||
return match.padStart(4, '0');
|
||||
}).toLowerCase();
|
||||
|
||||
if(lowerA < lowerB)
|
||||
return -1;
|
||||
return 1;
|
||||
}).map(function(emoji) {
|
||||
return {
|
||||
text : `${emoji}:`, // Text to output to editor when option is selected
|
||||
render : function(element, self, data) { // How to display the option in the dropdown
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = `<i class="emojiPreview ${emojis[emoji]}"></i> ${emoji}`;
|
||||
element.appendChild(div);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
list : list.length ? list : [],
|
||||
from : CodeMirror.Pos(line, start),
|
||||
to : CodeMirror.Pos(line, end)
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
editor.on('inputRead', function(instance, change) {
|
||||
const cursor = editor.getCursor();
|
||||
const line = editor.getLine(cursor.line);
|
||||
|
||||
// Get the text from the start of the line to the cursor
|
||||
const textToCursor = line.slice(0, cursor.ch);
|
||||
|
||||
// Do not autosuggest emojis in curly span/div/injector properties
|
||||
if(line.includes('{')) {
|
||||
const curlyToCursor = textToCursor.slice(textToCursor.indexOf(`{`));
|
||||
const curlySpanRegex = /{(?=((?:[:=](?:"[\w,\-()#%. ]*"|[\w\-()#%.]*)|[^"':={}\s]*)*))\1$/g;
|
||||
|
||||
if(curlySpanRegex.test(curlyToCursor))
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the text ends with ':xyz'
|
||||
if(/:[^\s:]+$/.test(textToCursor)) {
|
||||
CodeMirror.commands.autocomplete(editor);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
showAutocompleteEmoji
|
||||
};
|
||||
@@ -5,7 +5,7 @@ const createClass = require('create-react-class');
|
||||
const _ = require('lodash');
|
||||
const cx = require('classnames');
|
||||
const closeTag = require('./close-tag');
|
||||
const autoCompleteEmojis = require('./autocomplete-emoji');
|
||||
const autoCompleteEmoji = require('./autocompleteEmoji');
|
||||
|
||||
let CodeMirror;
|
||||
if(typeof window !== 'undefined'){
|
||||
@@ -180,10 +180,10 @@ const CodeEditor = createClass({
|
||||
// return el;
|
||||
// }
|
||||
});
|
||||
|
||||
|
||||
// Add custom behaviors (auto-close curlies and auto-complete emojis)
|
||||
closeTag.autoCloseCurlyBraces(CodeMirror, this.codeMirror);
|
||||
autoCompleteEmojis.showEmojiAutocomplete(CodeMirror, this.codeMirror);
|
||||
autoCompleteEmoji.showAutocompleteEmoji(CodeMirror, this.codeMirror);
|
||||
|
||||
// Note: codeMirror passes a copy of itself in this callback. cm === this.codeMirror. Either one works.
|
||||
this.codeMirror.on('change', (cm)=>{this.props.onChange(cm.getValue());});
|
||||
@@ -442,7 +442,7 @@ const CodeEditor = createClass({
|
||||
|
||||
render : function(){
|
||||
return <>
|
||||
<link href={`../homebrew/cm-themes/${this.props.editorTheme}.css`} type="text/css" rel='stylesheet' />
|
||||
<link href={`../homebrew/cm-themes/${this.props.editorTheme}.css`} type='text/css' rel='stylesheet' />
|
||||
<div className='codeEditor' ref='editor' style={this.props.style}/>
|
||||
</>;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
@import (less) 'codemirror/addon/hint/show-hint.css';
|
||||
|
||||
//Icon fonts included so they can appear in emoji autosuggest dropdown
|
||||
@import (less) './themes/fonts/icon fonts/diceFont.less';
|
||||
@import (less) './themes/fonts/icon fonts/elderberryInn.less';
|
||||
@import (less) './themes/fonts/icon fonts/raRedux.less';
|
||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
||||
@import (less) './themes/fonts/iconFonts/raRedux.less';
|
||||
|
||||
@keyframes sourceMoveAnimation {
|
||||
50% {background-color: red; color: white;}
|
||||
|
||||
@@ -4,12 +4,13 @@ const Marked = require('marked');
|
||||
const MarkedExtendedTables = require('marked-extended-tables');
|
||||
const { markedSmartypantsLite: MarkedSmartypantsLite } = require('marked-smartypants-lite');
|
||||
const { gfmHeadingId: MarkedGFMHeadingId } = require('marked-gfm-heading-id');
|
||||
const { markedEmoji: MarkedEmojis} = require('marked-emoji');
|
||||
const { markedEmoji: MarkedEmojis } = require('marked-emoji');
|
||||
|
||||
//Icon fonts included so they can appear in emoji autosuggest dropdown
|
||||
const diceFont = require('../../themes/fonts/icon fonts/diceFont.js');
|
||||
const elderberryInn = require('../../themes/fonts/icon fonts/elderberryInn.js');
|
||||
const raRedux = require('../../themes/fonts/icon fonts/raRedux.js');
|
||||
const diceFont = require('../../themes/fonts/iconFonts/diceFont.js');
|
||||
const elderberryInn = require('../../themes/fonts/iconFonts/elderberryInn.js');
|
||||
const fontAwesome = require('../../themes/fonts/iconFonts/fontAwesome.js');
|
||||
const raRedux = require('../../themes/fonts/iconFonts/raRedux.js');
|
||||
|
||||
const MathParser = require('expr-eval').Parser;
|
||||
const renderer = new Marked.Renderer();
|
||||
@@ -57,7 +58,7 @@ renderer.html = function (html) {
|
||||
return html;
|
||||
};
|
||||
|
||||
// Don't wrap {{ Divs or {{ empty Spans in <p> tags
|
||||
// Don't wrap {{ Spans alone on a line, or {{ Divs in <p> tags
|
||||
renderer.paragraph = function(text){
|
||||
let match;
|
||||
if(text.startsWith('<div') || text.startsWith('</div'))
|
||||
@@ -106,13 +107,13 @@ const mustacheSpans = {
|
||||
if(match) {
|
||||
//Find closing delimiter
|
||||
let blockCount = 0;
|
||||
let tags = '';
|
||||
let tags = {};
|
||||
let endTags = 0;
|
||||
let endToken = 0;
|
||||
let delim;
|
||||
while (delim = inlineRegex.exec(match[0])) {
|
||||
if(!tags) {
|
||||
tags = `${processStyleTags(delim[0].substring(2))}`;
|
||||
if(_.isEmpty(tags)) {
|
||||
tags = processStyleTags(delim[0].substring(2));
|
||||
endTags = delim[0].length;
|
||||
}
|
||||
if(delim[0].startsWith('{{')) {
|
||||
@@ -141,7 +142,14 @@ const mustacheSpans = {
|
||||
}
|
||||
},
|
||||
renderer(token) {
|
||||
return `<span class="inline-block${token.tags}>${this.parser.parseInline(token.tokens)}</span>`; // parseInline to turn child tokens into HTML
|
||||
const tags = token.tags;
|
||||
tags.classes = ['inline-block', tags.classes].join(' ').trim();
|
||||
return `<span` +
|
||||
`${tags.classes ? ` class="${tags.classes}"` : ''}` +
|
||||
`${tags.id ? ` id="${tags.id}"` : ''}` +
|
||||
`${tags.styles ? ` style="${tags.styles}"` : ''}` +
|
||||
`${tags.attributes ? ` ${Object.entries(tags.attributes).map(([key, value])=>`${key}="${value}"`).join(' ')}` : ''}` +
|
||||
`>${this.parser.parseInline(token.tokens)}</span>`; // parseInline to turn child tokens into HTML
|
||||
}
|
||||
};
|
||||
|
||||
@@ -156,13 +164,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('{{')) {
|
||||
@@ -190,7 +198,14 @@ const mustacheDivs = {
|
||||
}
|
||||
},
|
||||
renderer(token) {
|
||||
return `<div class="block${token.tags}>${this.parser.parse(token.tokens)}</div>`; // parseInline to turn child tokens into HTML
|
||||
const tags = token.tags;
|
||||
tags.classes = ['block', tags.classes].join(' ').trim();
|
||||
return `<div` +
|
||||
`${tags.classes ? ` class="${tags.classes}"` : ''}` +
|
||||
`${tags.id ? ` id="${tags.id}"` : ''}` +
|
||||
`${tags.styles ? ` style="${tags.styles}"` : ''}` +
|
||||
`${tags.attributes ? ` ${Object.entries(tags.attributes).map(([key, value])=>`${key}="${value}"`).join(' ')}` : ''}` +
|
||||
`>${this.parser.parse(token.tokens)}</div>`; // parse to turn child tokens into HTML
|
||||
}
|
||||
};
|
||||
|
||||
@@ -206,23 +221,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;
|
||||
}
|
||||
@@ -242,7 +273,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
|
||||
@@ -256,9 +287,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;
|
||||
}
|
||||
@@ -311,13 +355,13 @@ const definitionListsSingleLine = {
|
||||
let endIndex = 0;
|
||||
const definitions = [];
|
||||
while (match = regex.exec(src)) {
|
||||
let originalLine = match[0]; // This line and below to handle conflict with emojis
|
||||
const originalLine = match[0]; // This line and below to handle conflict with emojis
|
||||
let firstLine = originalLine; // Remove in V4 when definitionListsInline updated to
|
||||
this.lexer.inlineTokens(firstLine.trim()) // require spaces around `::`
|
||||
.filter(t => t.type == 'emoji')
|
||||
.map(emoji => firstLine = firstLine.replace(emoji.raw, 'x'.repeat(emoji.raw.length)));
|
||||
.filter((t)=>t.type == 'emoji')
|
||||
.map((emoji)=>firstLine = firstLine.replace(emoji.raw, 'x'.repeat(emoji.raw.length)));
|
||||
|
||||
let newMatch = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym.exec(firstLine);
|
||||
const newMatch = /^([^\n]*?)::([^\n]*)(?:\n|$)/ym.exec(firstLine);
|
||||
if(newMatch) {
|
||||
definitions.push({
|
||||
dt : this.lexer.inlineTokens(originalLine.slice(0, newMatch[1].length).trim()),
|
||||
@@ -633,15 +677,22 @@ function MarkedVariables() {
|
||||
//^=====--------------------< Variable Handling >-------------------=====^//
|
||||
|
||||
// Emoji options
|
||||
// To add more icon fonts, need to do these things
|
||||
// 1) Add the font file as .woff2 to themes/fonts/iconFonts folder
|
||||
// 2) Create a .less file mapping CSS class names to the font character
|
||||
// 3) Create a .js file mapping Autosuggest names to CSS class names
|
||||
// 4) Import the .less file into shared/naturalcrit/codeEditor/codeEditor.less
|
||||
// 5) Import the .less file into themes/V3/blank.style.less
|
||||
// 6) Import the .js file to shared/naturalcrit/codeEditor/autocompleteEmoji.js and add to `emojis` object
|
||||
// 7) Import the .js file here to markdown.js, and add to `emojis` object below
|
||||
const MarkedEmojiOptions = {
|
||||
emojis: {
|
||||
emojis : {
|
||||
...diceFont,
|
||||
...elderberryInn,
|
||||
...fontAwesome
|
||||
...raRedux,
|
||||
"fas-heart": "fa-solid fa-heart",
|
||||
"fas-star": "fa-solid fa-star"
|
||||
},
|
||||
renderer: (token) => `<i class="${token.emoji}"></i>`
|
||||
renderer : (token)=>`<i class="${token.emoji}"></i>`
|
||||
};
|
||||
|
||||
Marked.use(MarkedVariables());
|
||||
@@ -715,15 +766,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 = {};
|
||||
|
||||
58
tests/markdown/emojis.test.js
Normal file
58
tests/markdown/emojis.test.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const Markdown = require('naturalcrit/markdown.js');
|
||||
const dedent = require('dedent-tabs').default;
|
||||
|
||||
// Marked.js adds line returns after closing tags on some default tokens.
|
||||
// This removes those line returns for comparison sake.
|
||||
String.prototype.trimReturns = function(){
|
||||
return this.replace(/\r?\n|\r/g, '');
|
||||
};
|
||||
|
||||
const emoji = 'df_d12_2';
|
||||
|
||||
describe(`When emojis/icons are active`, ()=>{
|
||||
it('when a word is between two colons (:word:), and a matching emoji exists, it is rendered as an emoji', function() {
|
||||
const source = `:${emoji}:`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><i class="df d12-2"></i></p>`);
|
||||
});
|
||||
|
||||
it('when a word is between two colons (:word:), and no matching emoji exists, it is not parsed', function() {
|
||||
const source = `:invalid:`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p>:invalid:</p>`);
|
||||
});
|
||||
|
||||
it('two valid emojis with no whitespace are prioritized over definition lists', function() {
|
||||
const source = `:${emoji}::${emoji}:`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><i class="df d12-2"></i><i class="df d12-2"></i></p>`);
|
||||
});
|
||||
|
||||
it('definition lists that are not also part of an emoji can coexist with normal emojis', function() {
|
||||
const source = `definition :: term ${emoji}::${emoji}:`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<dl><dt>definition</dt><dd>term df_d12_2:<i class="df d12-2"></i></dd></dl>`);
|
||||
});
|
||||
|
||||
it('A valid emoji is compatible with curly injectors', function() {
|
||||
const source = `:${emoji}:{color:blue,myClass}`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><i class="df d12-2 myClass" style="color:blue;"></i></p>`);
|
||||
});
|
||||
|
||||
it('Emojis are not parsed inside of curly span CSS blocks', function() {
|
||||
const source = `{{color:${emoji} text}}`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<span class="inline-block" style="color:df_d12_2;">text</span>`);
|
||||
});
|
||||
|
||||
it('Emojis are not parsed inside of curly div CSS blocks', function() {
|
||||
const source = dedent`{{color:${emoji}
|
||||
text
|
||||
}}`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<div class="block" style="color:df_d12_2;"><p>text</p></div>`);
|
||||
});
|
||||
|
||||
// another test of the editor to confirm an autocomplete menu opens
|
||||
});
|
||||
@@ -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(`<div class="block"><p>text</p></div>`);
|
||||
});
|
||||
@@ -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(`<div class="block"></div>`);
|
||||
});
|
||||
|
||||
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(`<p>{{}}</p>`);
|
||||
});
|
||||
@@ -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(`<div class="block cat"></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block cat"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block cat dog"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block" style="color:red;"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block" style="--stringVariable:'string';"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block" style="--stringVariable:'string';"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block cat" style="color:red;"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block cat" id="dog" style="color:red;"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block" id="cat"><p>Sample text.</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class=\"block cat\" id=\"dog\" style=\"color:red;\" a=\"b and c\" d=\"e\"><p>Sample text.</p></div>`);
|
||||
});
|
||||
@@ -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('<span class="inline-block">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block ClassName">text</span>');
|
||||
});
|
||||
|
||||
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('<span a="b and c" class="inline-block ">text</span>');
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<span class="inline-block" a="b and c">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block" style="color:red;">text</span>');
|
||||
});
|
||||
|
||||
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(`<span class="inline-block" style="--stringVariable:'string';">text</span>`);
|
||||
});
|
||||
|
||||
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('<span class="inline-block" style="color:red; background:blue;">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block" id="newId">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block" attrA="new" attrB="old" attrC="new">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block" attrA="new" attrB="old" attrC="new">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block" style="color:blue; height:10px; width:10px; color:red;">text</span>');
|
||||
});
|
||||
|
||||
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('<span class="inline-block classA classB classA classC">text</span>');
|
||||
});
|
||||
|
||||
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('<p><em class="big">emphasis</em></p>');
|
||||
});
|
||||
|
||||
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('<p><code style="background:gray;">code</code></p>');
|
||||
});
|
||||
|
||||
it.failing('Renders an image element with injected style', function() {
|
||||
it('Renders an image element with injected style', function() {
|
||||
const source = '{position:absolute}';
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p><img src="http://i.imgur.com/hMna6G0.png" alt="homebrew mug" style="position:absolute;"></p>');
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<p><img style="position:absolute;" src="http://i.imgur.com/hMna6G0.png" alt="alt text"></p>');
|
||||
});
|
||||
|
||||
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('<p><span class="inline-block" style="color:red;">text</span>{background:blue}</p>');
|
||||
@@ -306,61 +336,106 @@ describe('Injection: When an injection tag follows an element', ()=>{
|
||||
it('Renders an image with added attributes', function() {
|
||||
const source = ` {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(`<p><img class="" style="position:absolute; bottom:20px; left:130px; width:220px;" a="b and c" d="e" src="https://i.imgur.com/hMna6G0.png" alt="homebrew mug"></p>`);
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<p><img style="position:absolute; bottom:20px; left:130px; width:220px;" src="https://i.imgur.com/hMna6G0.png" alt="homebrew mug" a="b and c" d="e"></p>`);
|
||||
});
|
||||
});
|
||||
|
||||
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('<div class="block"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<div class="block ClassName"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<div class="block" style="color:red;"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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(`<div class="block" style="color:red; background:blue"><p>text</p></div>`);
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<div class="block" style="color:red; background:blue;"><p>text</p></div>`);
|
||||
});
|
||||
|
||||
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(`<div class="block" style="--stringVariable:'string'"><p>text</p></div>`);
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`<div class="block" style="--stringVariable:'string';"><p>text</p></div>`);
|
||||
});
|
||||
|
||||
it.failing('renders an h2 header "text" with injected class name', function() {
|
||||
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('<div class="block" id="newId"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<div class="block" attrA="new" attrB="old" attrC="new"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<div class="block" attrA="new" attrB="old" attrC="new"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<div class="block" style="color:blue; height:10px; width:10px; color:red;"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<div class="block classA classB classA classC"><p>text</p></div>');
|
||||
});
|
||||
|
||||
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('<h2 class="ClassName">text</h2>');
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<h2 class="ClassName" id="text">text</h2>');
|
||||
});
|
||||
|
||||
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(`<table class="ClassName"><thead><tr><th align=left>Experience Points</th><th align=center>Level</th></tr></thead><tbody><tr><td align=left>0</td><td align=center>1</td></tr><tr><td align=left>300</td><td align=center>2</td></tr></tbody></table>`);
|
||||
});
|
||||
@@ -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 <ul>? Currently injects into last <li>
|
||||
// });
|
||||
|
||||
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('<h2 class="ClassName">text</h2><p>{secondInjection}</p>');
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('<h2 class="ClassName" id="text">text</h2><p>{secondInjection}</p>');
|
||||
});
|
||||
|
||||
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('<div class="block outerDiv"><p>outer text</p><div class="block innerDiv"><p>inner text</p></div></div>');
|
||||
});
|
||||
|
||||
@@ -329,7 +329,7 @@ describe('Normal Links and Images', ()=>{
|
||||
const source = `{width:100px}`;
|
||||
const rendered = Markdown.render(source).trimReturns();
|
||||
expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(dedent`
|
||||
<p><img class="" style="width:100px;" src="url" alt="alt text"></p>`.trimReturns());
|
||||
<p><img style="width:100px;" src="url" alt="alt text"></p>`.trimReturns());
|
||||
});
|
||||
|
||||
it('Renders normal links', function() {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
@import (less) './themes/assets/assets.less';
|
||||
@import (less) './themes/fonts/icon fonts/elderberryInn.less';
|
||||
@import (less) './themes/fonts/icon fonts/diceFont.less';
|
||||
|
||||
:root {
|
||||
//Colors
|
||||
@@ -543,10 +541,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 +550,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 +597,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;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@import (less) './themes/fonts/5e/fonts.less';
|
||||
@import (less) './themes/assets/assets.less';
|
||||
@import (less) './themes/fonts/icon fonts/diceFont.less';
|
||||
@import (less) './themes/fonts/iconFonts/elderberryInn.less';
|
||||
@import (less) './themes/fonts/iconFonts/diceFont.less';
|
||||
|
||||
:root {
|
||||
//Colors
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
const diceFont = {
|
||||
"df-F" : "df F",
|
||||
"df-F-minus" : "df F-minus",
|
||||
"df-F-plus" : "df F-plus",
|
||||
"df-F-zero" : "df F-zero",
|
||||
"df-d10" : "df d10",
|
||||
"df-d10-1" : "df d10-1",
|
||||
"df-d10-10" : "df d10-10",
|
||||
"df-d10-2" : "df d10-2",
|
||||
"df-d10-3" : "df d10-3",
|
||||
"df-d10-4" : "df d10-4",
|
||||
"df-d10-5" : "df d10-5",
|
||||
"df-d10-6" : "df d10-6",
|
||||
"df-d10-7" : "df d10-7",
|
||||
"df-d10-8" : "df d10-8",
|
||||
"df-d10-9" : "df d10-9",
|
||||
"df-d12" : "df d12",
|
||||
"df-d12-1" : "df d12-1",
|
||||
"df-d12-10" : "df d12-10",
|
||||
"df-d12-11" : "df d12-11",
|
||||
"df-d12-12" : "df d12-12",
|
||||
"df-d12-2" : "df d12-2",
|
||||
"df-d12-3" : "df d12-3",
|
||||
"df-d12-4" : "df d12-4",
|
||||
"df-d12-5" : "df d12-5",
|
||||
"df-d12-6" : "df d12-6",
|
||||
"df-d12-7" : "df d12-7",
|
||||
"df-d12-8" : "df d12-8",
|
||||
"df-d12-9" : "df d12-9",
|
||||
"df-d2" : "df d2",
|
||||
"df-d2-1" : "df d2-1",
|
||||
"df-d2-2" : "df d2-2",
|
||||
"df-d20" : "df d20",
|
||||
"df-d20-1" : "df d20-1",
|
||||
"df-d20-10" : "df d20-10",
|
||||
"df-d20-11" : "df d20-11",
|
||||
"df-d20-12" : "df d20-12",
|
||||
"df-d20-13" : "df d20-13",
|
||||
"df-d20-14" : "df d20-14",
|
||||
"df-d20-15" : "df d20-15",
|
||||
"df-d20-16" : "df d20-16",
|
||||
"df-d20-17" : "df d20-17",
|
||||
"df-d20-18" : "df d20-18",
|
||||
"df-d20-19" : "df d20-19",
|
||||
"df-d20-2" : "df d20-2",
|
||||
"df-d20-20" : "df d20-20",
|
||||
"df-d20-3" : "df d20-3",
|
||||
"df-d20-4" : "df d20-4",
|
||||
"df-d20-5" : "df d20-5",
|
||||
"df-d20-6" : "df d20-6",
|
||||
"df-d20-7" : "df d20-7",
|
||||
"df-d20-8" : "df d20-8",
|
||||
"df-d20-9" : "df d20-9",
|
||||
"df-d4" : "df d4",
|
||||
"df-d4-1" : "df d4-1",
|
||||
"df-d4-2" : "df d4-2",
|
||||
"df-d4-3" : "df d4-3",
|
||||
"df-d4-4" : "df d4-4",
|
||||
"df-d6" : "df d6",
|
||||
"df-d6-1" : "df d6-1",
|
||||
"df-d6-2" : "df d6-2",
|
||||
"df-d6-3" : "df d6-3",
|
||||
"df-d6-4" : "df d6-4",
|
||||
"df-d6-5" : "df d6-5",
|
||||
"df-d6-6" : "df d6-6",
|
||||
"df-d8" : "df d8",
|
||||
"df-d8-1" : "df d8-1",
|
||||
"df-d8-2" : "df d8-2",
|
||||
"df-d8-3" : "df d8-3",
|
||||
"df-d8-4" : "df d8-4",
|
||||
"df-d8-5" : "df d8-5",
|
||||
"df-d8-6" : "df d8-6",
|
||||
"df-d8-7" : "df d8-7",
|
||||
"df-d8-8" : "df d8-8",
|
||||
"df-dot-d6" : "df dot-d6",
|
||||
"df-dot-d6-1" : "df dot-d6-1",
|
||||
"df-dot-d6-2" : "df dot-d6-2",
|
||||
"df-dot-d6-3" : "df dot-d6-3",
|
||||
"df-dot-d6-4" : "df dot-d6-4",
|
||||
"df-dot-d6-5" : "df dot-d6-5",
|
||||
"df-dot-d6-6" : "df dot-d6-6",
|
||||
"df-small-dot-d6-1" : "df small-dot-d6-1",
|
||||
"df-small-dot-d6-2" : "df small-dot-d6-2",
|
||||
"df-small-dot-d6-3" : "df small-dot-d6-3",
|
||||
"df-small-dot-d6-4" : "df small-dot-d6-4",
|
||||
"df-small-dot-d6-5" : "df small-dot-d6-5",
|
||||
"df-small-dot-d6-6" : "df small-dot-d6-6",
|
||||
"df-solid-small-dot-d6-1" : "df solid-small-dot-d6-1",
|
||||
"df-solid-small-dot-d6-2" : "df solid-small-dot-d6-2",
|
||||
"df-solid-small-dot-d6-3" : "df solid-small-dot-d6-3",
|
||||
"df-solid-small-dot-d6-4" : "df solid-small-dot-d6-4",
|
||||
"df-solid-small-dot-d6-5" : "df solid-small-dot-d6-5",
|
||||
"df-solid-small-dot-d6-6" : "df solid-small-dot-d6-6"
|
||||
}
|
||||
|
||||
module.exports = diceFont;
|
||||
@@ -1,208 +0,0 @@
|
||||
const elderberryInn = {
|
||||
"EiBook" : "ei book",
|
||||
"EiScreen" : "ei screen",
|
||||
|
||||
/* Spell levels */
|
||||
"EiSpell-0" : "ei spell-0",
|
||||
"EiSpell-1" : "ei spell-1",
|
||||
"EiSpell-2" : "ei spell-2",
|
||||
"EiSpell-3" : "ei spell-3",
|
||||
"EiSpell-4" : "ei spell-4",
|
||||
"EiSpell-5" : "ei spell-5",
|
||||
"EiSpell-6" : "ei spell-6",
|
||||
"EiSpell-7" : "ei spell-7",
|
||||
"EiSpell-8" : "ei spell-8",
|
||||
"EiSpell-9" : "ei spell-9",
|
||||
|
||||
/* Damage types */
|
||||
"EiAcid" : "ei acid",
|
||||
"EiBludgeoning" : "ei bludgeoning",
|
||||
"EiCold" : "ei cold",
|
||||
"EiFire" : "ei fire",
|
||||
"EiForce" : "ei force",
|
||||
"EiLightning" : "ei lightning",
|
||||
"EiNecrotic" : "ei necrotic",
|
||||
"EiPiercing" : "ei piercing",
|
||||
"EiPoison" : "ei poison",
|
||||
"EiPsychic" : "ei psychic",
|
||||
"EiRadiant" : "ei radiant",
|
||||
"EiSlashing" : "ei slashing",
|
||||
"EiThunder" : "ei thunder",
|
||||
|
||||
/* DnD Conditions */
|
||||
"EiBlinded" : "ei blinded",
|
||||
"EiCharmed" : "ei charmed",
|
||||
"EiDeafened" : "ei deafened",
|
||||
"EiExhaust1" : "ei exhaust-1",
|
||||
"EiBlinded" : "ei blinded",
|
||||
"EiExhaust2" : "ei exhaust-2",
|
||||
"EiExhaust3" : "ei exhaust-3",
|
||||
"EiExhaust4" : "ei exhaust-4",
|
||||
"EiExhaust5" : "ei exhaust-5",
|
||||
"EiExhaust6" : "ei exhaust-6",
|
||||
"EiFrightened" : "ei frightened",
|
||||
"EiGrappled" : "ei grappled",
|
||||
"EiIncapacitated" : "ei incapacitated",
|
||||
"EiInvisible" : "ei invisible",
|
||||
"EiParalyzed" : "ei paralyzed",
|
||||
"EiPetrified" : "ei petrified",
|
||||
"EiPoisoned" : "ei poisoned",
|
||||
"EiProne" : "ei prone",
|
||||
"EiRestrained" : "ei restrained",
|
||||
"EiStunned" : "ei stunned",
|
||||
"EiUnconscious" : "ei unconscious",
|
||||
|
||||
/* Character Classes and Features */
|
||||
"EiBarbarianRage" : "ei barbarian-rage",
|
||||
"EiBarbarianRecklessAttack" : "ei barbarian-reckless-attack",
|
||||
"EiBardicInspiration" : "ei bardic-inspiration",
|
||||
"EiClericChannelDivinity" : "ei cleric-channel-divinity",
|
||||
"EiDruidWildShape" : "ei druid-wild-shape",
|
||||
"EiFighterActionSurge" : "ei fighter-action-surge",
|
||||
"EiFighterSecondWind" : "ei fighter-second-wind",
|
||||
"EiMonkFlurryBlows" : "ei monk-flurry-blows",
|
||||
"EiMonkPatientDefense" : "ei monk-patient-defense",
|
||||
"EiMonkStepOfTheWind" : "ei monk-step-of-the-wind",
|
||||
"EiMonkStepOfTheWind2" : "ei monk-step-of-the-wind-2",
|
||||
"EiMonkStepOfTheWind3" : "ei monk-step-of-the-wind-3",
|
||||
"EiMonkStunningStrike" : "ei monk-stunning-strike",
|
||||
"EiMonkStunningStrike2" : "ei monk-stunning-strike-2",
|
||||
"EiPaladinDivineSmite" : "ei paladin-divine-smite",
|
||||
"EiPaladinLayOnHands" : "ei paladin-lay-on-hands",
|
||||
"EiBarbarianAbilities" : "ei barbarian-abilities",
|
||||
"EiBarbarian" : "ei barbarian",
|
||||
"EiBardAbilities" : "ei bard-abilities",
|
||||
"EiBard" : "ei bard",
|
||||
"EiClericAbilities" : "ei cleric-abilities",
|
||||
"EiCleric" : "ei cleric",
|
||||
"EiDruidAbilities" : "ei druid-abilities",
|
||||
"EiDruid" : "ei druid",
|
||||
"EiFighterAbilities" : "ei fighter-abilities",
|
||||
"EiFighter" : "ei fighter",
|
||||
"EiMonkAbilities" : "ei monk-abilities",
|
||||
"EiMonk" : "ei monk",
|
||||
"EiPaladinAbilities" : "ei paladin-abilities",
|
||||
"EiPaladin" : "ei paladin",
|
||||
"EiRangerAbilities" : "ei ranger-abilities",
|
||||
"EiRanger" : "ei ranger",
|
||||
"EiRogueAbilities" : "ei rogue-abilities",
|
||||
"EiRogue" : "ei rogue",
|
||||
"EiSorcererAbilities" : "ei sorcerer-abilities",
|
||||
"EiSorcerer" : "ei sorcerer",
|
||||
"EiWarlockAbilities" : "ei warlock-abilities",
|
||||
"EiWarlock" : "ei warlock",
|
||||
"EiWizardAbilities" : "ei wizard-abilities",
|
||||
"EiWizard" : "ei wizard",
|
||||
|
||||
/* Types of actions */
|
||||
"EiMovement" : "ei movement",
|
||||
"EiAction" : "ei action",
|
||||
"EiBonusAction" : "ei bonus-action",
|
||||
"EiReaction" : "ei reaction",
|
||||
|
||||
/* SRD Spells */
|
||||
"EiAcidArrow" : "ei acid-arrow",
|
||||
"EiAction1" : "ei action-1",
|
||||
"EiAlterSelf" : "ei alter-self",
|
||||
"EiAlterSelf2" : "ei alter-self-2",
|
||||
"EiAnimalFriendship" : "ei animal-friendship",
|
||||
"EiAnimateDead" : "ei animate-dead",
|
||||
"EiAnimateObjects" : "ei animate-objects",
|
||||
"EiAnimateObjects2" : "ei animate-objects-2",
|
||||
"EiBane" : "ei bane",
|
||||
"EiBless" : "ei bless",
|
||||
"EiBlur" : "ei blur",
|
||||
"EiBonus" : "ei bonus",
|
||||
"EiBrandingSmite" : "ei branding-smite",
|
||||
"EiBurningHands" : "ei burning-hands",
|
||||
"EiCharmPerson" : "ei charm-person",
|
||||
"EiChillTouch" : "ei chill-touch",
|
||||
"EiCloudkill" : "ei cloudkill",
|
||||
"EiComprehendLanguages" : "ei comprehend-languages",
|
||||
"EiConeOfCold" : "ei cone-of-cold",
|
||||
"EiConjureElemental" : "ei conjure-elemental",
|
||||
"EiConjureMinorElemental" : "ei conjure-minor-elemental",
|
||||
"EiControlWater" : "ei control-water",
|
||||
"EiCounterspell" : "ei counterspell",
|
||||
"EiCureWounds" : "ei cure-wounds",
|
||||
"EiDancingLights" : "ei dancing-lights",
|
||||
"EiDarkness" : "ei darkness",
|
||||
"EiDetectMagic" : "ei detect-magic",
|
||||
"EiDisguiseSelf" : "ei disguise-self",
|
||||
"EiDisintegrate" : "ei disintegrate",
|
||||
"EiDispelEvilAndGood" : "ei dispel-evil-and-good",
|
||||
"EiDispelMagic" : "ei dispel-magic",
|
||||
"EiDominateMonster" : "ei dominate-monster",
|
||||
"EiDominatePerson" : "ei dominate-person",
|
||||
"EiEldritchBlast" : "ei eldritch-blast",
|
||||
"EiEnlargeReduce" : "ei enlarge-reduce",
|
||||
"EiEntangle" : "ei entangle",
|
||||
"EiFaerieFire" : "ei faerie-fire",
|
||||
"EiFaerieFire2" : "ei faerie-fire2",
|
||||
"EiFeatherFall" : "ei feather-fall",
|
||||
"EiFindFamiliar" : "ei find-familiar",
|
||||
"EiFingerOfDeath" : "ei finger-of-death",
|
||||
"EiFireball" : "ei fireball",
|
||||
"EiFloatingDisk" : "ei floating-disk",
|
||||
"EiFly" : "ei fly",
|
||||
"EiFogCloud" : "ei fog-cloud",
|
||||
"EiGaseousForm" : "ei gaseous-form",
|
||||
"EiGaseousForm2" : "ei gaseous-form2",
|
||||
"EiGentleRepose" : "ei gentle-repose",
|
||||
"EiGentleRepose2" : "ei gentle-repose2",
|
||||
"EiGlobeOfInvulnerability" : "ei globe-of-invulnerability",
|
||||
"EiGuidingBolt" : "ei guiding-bolt",
|
||||
"EiHealingWord" : "ei healing-word",
|
||||
"EiHeatMetal" : "ei heat-metal",
|
||||
"EiHellishRebuke" : "ei hellish-rebuke",
|
||||
"EiHeroesFeast" : "ei heroes-feast",
|
||||
"EiHeroism" : "ei heroism",
|
||||
"EiHideousLaughter" : "ei hideous-laughter",
|
||||
"EiIdentify" : "ei identify",
|
||||
"EiIllusoryScript" : "ei illusory-script",
|
||||
"EiInflictWounds" : "ei inflict-wounds",
|
||||
"EiLight" : "ei light",
|
||||
"EiLongstrider" : "ei longstrider",
|
||||
"EiMageArmor" : "ei mage-armor",
|
||||
"EiMageHand" : "ei mage-hand",
|
||||
"EiMagicMissile" : "ei magic-missile",
|
||||
"EiMassCureWounds" : "ei mass-cure-wounds",
|
||||
"EiMassHealingWord" : "ei mass-healing-word",
|
||||
"EiMending" : "ei Mending",
|
||||
"EiMessage" : "ei message",
|
||||
"EiMinorIllusion" : "ei Minor-illusion",
|
||||
"EiMovement1" : "ei movement1",
|
||||
"EiPolymorph" : "ei polymorph",
|
||||
"EiPowerWordKill" : "ei power-word-kill",
|
||||
"EiPowerWordStun" : "ei power-word-stun",
|
||||
"EiPrayerOfHealing" : "ei prayer-of-healing",
|
||||
"EiPrestidigitation" : "ei prestidigitation",
|
||||
"EiProtectionFromEvilAndGood" : "ei protection-from-evil-and-good",
|
||||
"EiRaiseDead" : "ei raise-dead",
|
||||
"EiRaiseDead2" : "ei raise-dead2",
|
||||
"EiReaction1" : "ei reaction1",
|
||||
"EiResurrection" : "ei resurrection",
|
||||
"EiResurrection2" : "ei resurrection2",
|
||||
"EiRevivify" : "ei revivify",
|
||||
"EiRevivify2" : "ei revivify2",
|
||||
"EiSacredFlame" : "ei sacred-flame",
|
||||
"EiSanctuary" : "ei sanctuary",
|
||||
"EiScorchingRay" : "ei scorching-ray",
|
||||
"EiSending" : "ei sending",
|
||||
"EiShatter" : "ei shatter",
|
||||
"EiShield" : "ei shield",
|
||||
"EiSilentImage" : "ei silent-image",
|
||||
"EiSleep" : "ei sleep",
|
||||
"EiSpeakWithAnimals" : "ei speak-with-animals",
|
||||
"EiTelekinesis" : "ei telekinesis",
|
||||
"EiTrueStrike" : "ei true-strike",
|
||||
"EiViciousMockery" : "ei vicious-mockery",
|
||||
"EiWallOfFire" : "ei wall-of-fire",
|
||||
"EiWallOfForce" : "ei wall-of-force",
|
||||
"EiWallOfIce" : "ei wall-of-ice",
|
||||
"EiWallOfStone" : "ei wall-of-stone",
|
||||
"EiWallOfThorns" : "ei wall-of-thorns",
|
||||
"EiWish" : "ei wish"
|
||||
}
|
||||
|
||||
module.exports = elderberryInn;
|
||||
96
themes/fonts/iconFonts/diceFont.js
Normal file
96
themes/fonts/iconFonts/diceFont.js
Normal file
@@ -0,0 +1,96 @@
|
||||
const diceFont = {
|
||||
'df_f' : 'df F',
|
||||
'df_f_minus' : 'df F-minus',
|
||||
'df_f_plus' : 'df F-plus',
|
||||
'df_f_zero' : 'df F-zero',
|
||||
'df_d10' : 'df d10',
|
||||
'df_d10_1' : 'df d10-1',
|
||||
'df_d10_10' : 'df d10-10',
|
||||
'df_d10_2' : 'df d10-2',
|
||||
'df_d10_3' : 'df d10-3',
|
||||
'df_d10_4' : 'df d10-4',
|
||||
'df_d10_5' : 'df d10-5',
|
||||
'df_d10_6' : 'df d10-6',
|
||||
'df_d10_7' : 'df d10-7',
|
||||
'df_d10_8' : 'df d10-8',
|
||||
'df_d10_9' : 'df d10-9',
|
||||
'df_d12' : 'df d12',
|
||||
'df_d12_1' : 'df d12-1',
|
||||
'df_d12_10' : 'df d12-10',
|
||||
'df_d12_11' : 'df d12-11',
|
||||
'df_d12_12' : 'df d12-12',
|
||||
'df_d12_2' : 'df d12-2',
|
||||
'df_d12_3' : 'df d12-3',
|
||||
'df_d12_4' : 'df d12-4',
|
||||
'df_d12_5' : 'df d12-5',
|
||||
'df_d12_6' : 'df d12-6',
|
||||
'df_d12_7' : 'df d12-7',
|
||||
'df_d12_8' : 'df d12-8',
|
||||
'df_d12_9' : 'df d12-9',
|
||||
'df_d2' : 'df d2',
|
||||
'df_d2_1' : 'df d2-1',
|
||||
'df_d2_2' : 'df d2-2',
|
||||
'df_d20' : 'df d20',
|
||||
'df_d20_1' : 'df d20-1',
|
||||
'df_d20_10' : 'df d20-10',
|
||||
'df_d20_11' : 'df d20-11',
|
||||
'df_d20_12' : 'df d20-12',
|
||||
'df_d20_13' : 'df d20-13',
|
||||
'df_d20_14' : 'df d20-14',
|
||||
'df_d20_15' : 'df d20-15',
|
||||
'df_d20_16' : 'df d20-16',
|
||||
'df_d20_17' : 'df d20-17',
|
||||
'df_d20_18' : 'df d20-18',
|
||||
'df_d20_19' : 'df d20-19',
|
||||
'df_d20_2' : 'df d20-2',
|
||||
'df_d20_20' : 'df d20-20',
|
||||
'df_d20_3' : 'df d20-3',
|
||||
'df_d20_4' : 'df d20-4',
|
||||
'df_d20_5' : 'df d20-5',
|
||||
'df_d20_6' : 'df d20-6',
|
||||
'df_d20_7' : 'df d20-7',
|
||||
'df_d20_8' : 'df d20-8',
|
||||
'df_d20_9' : 'df d20-9',
|
||||
'df_d4' : 'df d4',
|
||||
'df_d4_1' : 'df d4-1',
|
||||
'df_d4_2' : 'df d4-2',
|
||||
'df_d4_3' : 'df d4-3',
|
||||
'df_d4_4' : 'df d4-4',
|
||||
'df_d6' : 'df d6',
|
||||
'df_d6_1' : 'df d6-1',
|
||||
'df_d6_2' : 'df d6-2',
|
||||
'df_d6_3' : 'df d6-3',
|
||||
'df_d6_4' : 'df d6-4',
|
||||
'df_d6_5' : 'df d6-5',
|
||||
'df_d6_6' : 'df d6-6',
|
||||
'df_d8' : 'df d8',
|
||||
'df_d8_1' : 'df d8-1',
|
||||
'df_d8_2' : 'df d8-2',
|
||||
'df_d8_3' : 'df d8-3',
|
||||
'df_d8_4' : 'df d8-4',
|
||||
'df_d8_5' : 'df d8-5',
|
||||
'df_d8_6' : 'df d8-6',
|
||||
'df_d8_7' : 'df d8-7',
|
||||
'df_d8_8' : 'df d8-8',
|
||||
'df_dot_d6' : 'df dot-d6',
|
||||
'df_dot_d6_1' : 'df dot-d6-1',
|
||||
'df_dot_d6_2' : 'df dot-d6-2',
|
||||
'df_dot_d6_3' : 'df dot-d6-3',
|
||||
'df_dot_d6_4' : 'df dot-d6-4',
|
||||
'df_dot_d6_5' : 'df dot-d6-5',
|
||||
'df_dot_d6_6' : 'df dot-d6-6',
|
||||
'df_small_dot_d6_1' : 'df small-dot-d6-1',
|
||||
'df_small_dot_d6_2' : 'df small-dot-d6-2',
|
||||
'df_small_dot_d6_3' : 'df small-dot-d6-3',
|
||||
'df_small_dot_d6_4' : 'df small-dot-d6-4',
|
||||
'df_small_dot_d6_5' : 'df small-dot-d6-5',
|
||||
'df_small_dot_d6_6' : 'df small-dot-d6-6',
|
||||
'df_solid_small_dot_d6_1' : 'df solid-small-dot-d6-1',
|
||||
'df_solid_small_dot_d6_2' : 'df solid-small-dot-d6-2',
|
||||
'df_solid_small_dot_d6_3' : 'df solid-small-dot-d6-3',
|
||||
'df_solid_small_dot_d6_4' : 'df solid-small-dot-d6-4',
|
||||
'df_solid_small_dot_d6_5' : 'df solid-small-dot-d6-5',
|
||||
'df_solid_small_dot_d6_6' : 'df solid-small-dot-d6-6'
|
||||
};
|
||||
|
||||
module.exports = diceFont;
|
||||
@@ -3,7 +3,7 @@
|
||||
font-family : 'DiceFont';
|
||||
font-style : normal;
|
||||
font-weight : normal;
|
||||
src : url('../../../fonts/icon fonts/diceFont.woff2');
|
||||
src : url('../../../fonts/iconFonts/diceFont.woff2');
|
||||
}
|
||||
|
||||
.df {
|
||||
208
themes/fonts/iconFonts/elderberryInn.js
Normal file
208
themes/fonts/iconFonts/elderberryInn.js
Normal file
@@ -0,0 +1,208 @@
|
||||
const elderberryInn = {
|
||||
'ei_book' : 'ei book',
|
||||
'ei_screen' : 'ei screen',
|
||||
|
||||
/* Spell levels */
|
||||
'ei_spell_0' : 'ei spell-0',
|
||||
'ei_spell_1' : 'ei spell-1',
|
||||
'ei_spell_2' : 'ei spell-2',
|
||||
'ei_spell_3' : 'ei spell-3',
|
||||
'ei_spell_4' : 'ei spell-4',
|
||||
'ei_spell_5' : 'ei spell-5',
|
||||
'ei_spell_6' : 'ei spell-6',
|
||||
'ei_spell_7' : 'ei spell-7',
|
||||
'ei_spell_8' : 'ei spell-8',
|
||||
'ei_spell_9' : 'ei spell-9',
|
||||
|
||||
/* Damage types */
|
||||
'ei_acid' : 'ei acid',
|
||||
'ei_bludgeoning' : 'ei bludgeoning',
|
||||
'ei_cold' : 'ei cold',
|
||||
'ei_fire' : 'ei fire',
|
||||
'ei_force' : 'ei force',
|
||||
'ei_lightning' : 'ei lightning',
|
||||
'ei_necrotic' : 'ei necrotic',
|
||||
'ei_piercing' : 'ei piercing',
|
||||
'ei_poison' : 'ei poison',
|
||||
'ei_psychic' : 'ei psychic',
|
||||
'ei_radiant' : 'ei radiant',
|
||||
'ei_slashing' : 'ei slashing',
|
||||
'ei_thunder' : 'ei thunder',
|
||||
|
||||
/* DnD Donditions */
|
||||
'ei_blinded' : 'ei blinded',
|
||||
'ei_charmed' : 'ei charmed',
|
||||
'ei_deafened' : 'ei deafened',
|
||||
'ei_exhaust1' : 'ei exhaust-1',
|
||||
'ei_blinded' : 'ei blinded',
|
||||
'ei_exhaust2' : 'ei exhaust-2',
|
||||
'ei_exhaust3' : 'ei exhaust-3',
|
||||
'ei_exhaust4' : 'ei exhaust-4',
|
||||
'ei_exhaust5' : 'ei exhaust-5',
|
||||
'ei_exhaust6' : 'ei exhaust-6',
|
||||
'ei_frightened' : 'ei frightened',
|
||||
'ei_grappled' : 'ei grappled',
|
||||
'ei_incapacitated' : 'ei incapacitated',
|
||||
'ei_invisible' : 'ei invisible',
|
||||
'ei_paralyzed' : 'ei paralyzed',
|
||||
'ei_petrified' : 'ei petrified',
|
||||
'ei_poisoned' : 'ei poisoned',
|
||||
'ei_prone' : 'ei prone',
|
||||
'ei_restrained' : 'ei restrained',
|
||||
'ei_stunned' : 'ei stunned',
|
||||
'ei_unconscious' : 'ei unconscious',
|
||||
|
||||
/* Character Classes and Features */
|
||||
'ei_barbarian_rage' : 'ei barbarian-rage',
|
||||
'ei_barbarian_reckless_attack' : 'ei barbarian-reckless-attack',
|
||||
'ei_bardic_inspiration' : 'ei bardic-inspiration',
|
||||
'ei_cleric_channel_divinity' : 'ei cleric-channel-divinity',
|
||||
'ei_druid_wild_shape' : 'ei druid-wild-shape',
|
||||
'ei_fighter_action_surge' : 'ei fighter-action-surge',
|
||||
'ei_fighter_second_wind' : 'ei fighter-second-wind',
|
||||
'ei_monk_flurry_blows' : 'ei monk-flurry-blows',
|
||||
'ei_monk_patient_defense' : 'ei monk-patient-defense',
|
||||
'ei_monk_step_of_the_wind' : 'ei monk-step-of-the-wind',
|
||||
'ei_monk_step_of_the_wind2' : 'ei monk-step-of-the-wind-2',
|
||||
'ei_monk_step_of_the_wind3' : 'ei monk-step-of-the-wind-3',
|
||||
'ei_monk_stunning_strike' : 'ei monk-stunning-strike',
|
||||
'ei_monk_stunning_strike2' : 'ei monk-stunning-strike-2',
|
||||
'ei_paladin_divine_smite' : 'ei paladin-divine-smite',
|
||||
'ei_paladin_lay_on_hands' : 'ei paladin-lay-on-hands',
|
||||
'ei_barbarian_abilities' : 'ei barbarian-abilities',
|
||||
'ei_barbarian' : 'ei barbarian',
|
||||
'ei_bard_abilities' : 'ei bard-abilities',
|
||||
'ei_bard' : 'ei bard',
|
||||
'ei_cleric_abilities' : 'ei cleric-abilities',
|
||||
'ei_cleric' : 'ei cleric',
|
||||
'ei_druid_abilities' : 'ei druid-abilities',
|
||||
'ei_druid' : 'ei druid',
|
||||
'ei_fighter_abilities' : 'ei fighter-abilities',
|
||||
'ei_fighter' : 'ei fighter',
|
||||
'ei_monk_abilities' : 'ei monk-abilities',
|
||||
'ei_monk' : 'ei monk',
|
||||
'ei_paladin_abilities' : 'ei paladin-abilities',
|
||||
'ei_paladin' : 'ei paladin',
|
||||
'ei_ranger_abilities' : 'ei ranger-abilities',
|
||||
'ei_ranger' : 'ei ranger',
|
||||
'ei_rogue_abilities' : 'ei rogue-abilities',
|
||||
'ei_rogue' : 'ei rogue',
|
||||
'ei_sorcerer_abilities' : 'ei sorcerer-abilities',
|
||||
'ei_sorcerer' : 'ei sorcerer',
|
||||
'ei_warlock_abilities' : 'ei warlock-abilities',
|
||||
'ei_warlock' : 'ei warlock',
|
||||
'ei_wizard_abilities' : 'ei wizard-abilities',
|
||||
'ei_wizard' : 'ei wizard',
|
||||
|
||||
/* Types of actions */
|
||||
'ei_movement' : 'ei movement',
|
||||
'ei_action' : 'ei action',
|
||||
'ei_bonus_action' : 'ei bonus-action',
|
||||
'ei_reaction' : 'ei reaction',
|
||||
|
||||
/* SRD Spells */
|
||||
'ei_acid_arrow' : 'ei acid-arrow',
|
||||
'ei_action1' : 'ei action-1',
|
||||
'ei_alter_self' : 'ei alter-self',
|
||||
'ei_alter_self2' : 'ei alter-self-2',
|
||||
'ei_animal_friendship' : 'ei animal-friendship',
|
||||
'ei_animate_dead' : 'ei animate-dead',
|
||||
'ei_animate_objects' : 'ei animate-objects',
|
||||
'ei_animate_objects2' : 'ei animate-objects-2',
|
||||
'ei_bane' : 'ei bane',
|
||||
'ei_bless' : 'ei bless',
|
||||
'ei_blur' : 'ei blur',
|
||||
'ei_bonus' : 'ei bonus',
|
||||
'ei_branding_smite' : 'ei branding-smite',
|
||||
'ei_burning_hands' : 'ei burning-hands',
|
||||
'ei_charm_person' : 'ei charm-person',
|
||||
'ei_chill_touch' : 'ei chill-touch',
|
||||
'ei_cloudkill' : 'ei cloudkill',
|
||||
'ei_comprehend_languages' : 'ei comprehend-languages',
|
||||
'ei_cone_of_cold' : 'ei cone-of-cold',
|
||||
'ei_conjure_elemental' : 'ei conjure-elemental',
|
||||
'ei_conjure_minor_elemental' : 'ei conjure-minor-elemental',
|
||||
'ei_control_water' : 'ei control-water',
|
||||
'ei_counterspell' : 'ei counterspell',
|
||||
'ei_cure_wounds' : 'ei cure-wounds',
|
||||
'ei_dancing_lights' : 'ei dancing-lights',
|
||||
'ei_darkness' : 'ei darkness',
|
||||
'ei_detect_magic' : 'ei detect-magic',
|
||||
'ei_disguise_self' : 'ei disguise-self',
|
||||
'ei_disintegrate' : 'ei disintegrate',
|
||||
'ei_dispel_evil_and_good' : 'ei dispel-evil-and-good',
|
||||
'ei_dispel_magic' : 'ei dispel-magic',
|
||||
'ei_dominate_monster' : 'ei dominate-monster',
|
||||
'ei_dominate_person' : 'ei dominate-person',
|
||||
'ei_eldritch_blast' : 'ei eldritch-blast',
|
||||
'ei_enlarge_reduce' : 'ei enlarge-reduce',
|
||||
'ei_entangle' : 'ei entangle',
|
||||
'ei_faerie_fire' : 'ei faerie-fire',
|
||||
'ei_faerie_fire2' : 'ei faerie-fire2',
|
||||
'ei_feather_fall' : 'ei feather-fall',
|
||||
'ei_find_familiar' : 'ei find-familiar',
|
||||
'ei_finger_of_death' : 'ei finger-of-death',
|
||||
'ei_fireball' : 'ei fireball',
|
||||
'ei_floating_disk' : 'ei floating-disk',
|
||||
'ei_fly' : 'ei fly',
|
||||
'ei_fog_cloud' : 'ei fog-cloud',
|
||||
'ei_gaseous_form' : 'ei gaseous-form',
|
||||
'ei_gaseous_form2' : 'ei gaseous-form2',
|
||||
'ei_gentle_repose' : 'ei gentle-repose',
|
||||
'ei_gentle_repose2' : 'ei gentle-repose2',
|
||||
'ei_globe_of_invulnerability' : 'ei globe-of-invulnerability',
|
||||
'ei_guiding_bolt' : 'ei guiding-bolt',
|
||||
'ei_healing_word' : 'ei healing-word',
|
||||
'ei_heat_metal' : 'ei heat-metal',
|
||||
'ei_hellish_rebuke' : 'ei hellish-rebuke',
|
||||
'ei_heroes_feast' : 'ei heroes-feast',
|
||||
'ei_heroism' : 'ei heroism',
|
||||
'ei_hideous_laughter' : 'ei hideous-laughter',
|
||||
'ei_identify' : 'ei identify',
|
||||
'ei_illusory_script' : 'ei illusory-script',
|
||||
'ei_inflict_wounds' : 'ei inflict-wounds',
|
||||
'ei_light' : 'ei light',
|
||||
'ei_longstrider' : 'ei longstrider',
|
||||
'ei_mage_armor' : 'ei mage-armor',
|
||||
'ei_mage_hand' : 'ei mage-hand',
|
||||
'ei_magic_missile' : 'ei magic-missile',
|
||||
'ei_mass_cure_wounds' : 'ei mass-cure-wounds',
|
||||
'ei_mass_healing_word' : 'ei mass-healing-word',
|
||||
'ei_mending' : 'ei _mending',
|
||||
'ei_message' : 'ei message',
|
||||
'ei_minor_illusion' : 'ei _minor-illusion',
|
||||
'ei_movement1' : 'ei movement1',
|
||||
'ei_polymorph' : 'ei polymorph',
|
||||
'ei_power_word_kill' : 'ei power-word-kill',
|
||||
'ei_power_word_stun' : 'ei power-word-stun',
|
||||
'ei_prayer_of_healing' : 'ei prayer-of-healing',
|
||||
'ei_prestidigitation' : 'ei prestidigitation',
|
||||
'ei_protection_from_evil_and_good' : 'ei protection-from-evil-and-good',
|
||||
'ei_raise_dead' : 'ei raise-dead',
|
||||
'ei_raise_dead2' : 'ei raise-dead2',
|
||||
'ei_reaction1' : 'ei reaction1',
|
||||
'ei_resurrection' : 'ei resurrection',
|
||||
'ei_resurrection2' : 'ei resurrection2',
|
||||
'ei_revivify' : 'ei revivify',
|
||||
'ei_revivify2' : 'ei revivify2',
|
||||
'ei_sacred_flame' : 'ei sacred-flame',
|
||||
'ei_sanctuary' : 'ei sanctuary',
|
||||
'ei_scorching_ray' : 'ei scorching-ray',
|
||||
'ei_sending' : 'ei sending',
|
||||
'ei_shatter' : 'ei shatter',
|
||||
'ei_shield' : 'ei shield',
|
||||
'ei_silent_image' : 'ei silent-image',
|
||||
'ei_sleep' : 'ei sleep',
|
||||
'ei_speak_with_animals' : 'ei speak-with-animals',
|
||||
'ei_telekinesis' : 'ei telekinesis',
|
||||
'ei_true_strike' : 'ei true-strike',
|
||||
'ei_vicious_mockery' : 'ei vicious-mockery',
|
||||
'ei_wall_of_fire' : 'ei wall-of-fire',
|
||||
'ei_wall_of_force' : 'ei wall-of-force',
|
||||
'ei_wall_of_ice' : 'ei wall-of-ice',
|
||||
'ei_wall_of_stone' : 'ei wall-of-stone',
|
||||
'ei_wall_of_thorns' : 'ei wall-of-thorns',
|
||||
'ei_wish' : 'ei wish'
|
||||
};
|
||||
|
||||
module.exports = elderberryInn;
|
||||
@@ -3,7 +3,7 @@
|
||||
font-family : 'Elderberry-Inn';
|
||||
font-style : normal;
|
||||
font-weight : normal;
|
||||
src : url('../../../fonts/icon fonts/elderberryInn.woff2');
|
||||
src : url('../../../fonts/iconFonts/elderberryInn.woff2');
|
||||
}
|
||||
|
||||
.ei {
|
||||
@@ -39,8 +39,8 @@
|
||||
&.force::before { content : '\E910'; }
|
||||
&.lightning::before { content : '\E911'; }
|
||||
&.necrotic::before { content : '\E912'; }
|
||||
&.piercing::before { content : '\E914'; }
|
||||
&.poison::before { content : '\E913'; }
|
||||
&.piercing::before { content : '\E913'; }
|
||||
&.poison::before { content : '\E914'; }
|
||||
&.psychic::before { content : '\E915'; }
|
||||
&.radiant::before { content : '\E916'; }
|
||||
&.slashing::before { content : '\E917'; }
|
||||
2054
themes/fonts/iconFonts/fontAwesome.js
Normal file
2054
themes/fonts/iconFonts/fontAwesome.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user