Refactored
This commit is contained in:
parent
f9867525d3
commit
1f17d344fa
25 changed files with 2096 additions and 512 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
11
README.md
Normal file
11
README.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# My Spells (5e)
|
||||||
|
...is a user friendly mobile responsive app designed to do one thing well: _View Spells_.
|
||||||
|
|
||||||
|
[Check it out on github.io](https://sharpshark28.github.io/my_spells/)!
|
||||||
|
|
||||||
|
## For Developers
|
||||||
|
1. Clone/Fork Repo
|
||||||
|
2. `npm install`
|
||||||
|
3. `npm run develop`
|
||||||
|
|
||||||
|
You may wish to run a local http server such as [http-server](https://github.com/indexzero/http-server).
|
BIN
assets/.DS_Store
vendored
Normal file
BIN
assets/.DS_Store
vendored
Normal file
Binary file not shown.
181
assets/app.css
Normal file
181
assets/app.css
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
body {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.do-nothing {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdl-layout-title i {
|
||||||
|
position: relative;
|
||||||
|
bottom: -.125em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#empty {
|
||||||
|
padding-bottom: 100%;
|
||||||
|
text-align: center;
|
||||||
|
background: url('wand.svg') no-repeat top center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdl-navigation .mdl-textfield__label i {
|
||||||
|
vertical-align: top;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdl-navigation .mdl-textfield__input {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdl-navigation .mdl-textfield__label {
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .mdl-grid {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content .mdl-cell {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-template=spell-details] {
|
||||||
|
transition: margin-top 500ms ease-out;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-template=spell-details] .description {
|
||||||
|
max-height: 13em;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdl-layout__header [data-action-details=""] {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
height: 4rem;
|
||||||
|
width: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdl-layout__header [data-action-details=""] i {
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-template=spell-details] [data-action-details=""] {
|
||||||
|
position: absolute;
|
||||||
|
top: .5rem;
|
||||||
|
right: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 840px) {
|
||||||
|
[data-template=spell-details] {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spell-list-container,
|
||||||
|
[data-template=spell-details] {
|
||||||
|
transition: left 250ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spell-list-container {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.details #spell-list-container {
|
||||||
|
left: -95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.details #spell-list-container::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: black;
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-template=spell-details] {
|
||||||
|
position: fixed;
|
||||||
|
width: 95%;
|
||||||
|
left: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: calc(100% - 56px)
|
||||||
|
}
|
||||||
|
|
||||||
|
body.details [data-template=spell-details] {
|
||||||
|
left: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.details .mdl-layout__header [data-action-details=""] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.details .mdl-layout__header .mdl-layout__drawer-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.details [data-template=spell-details] [data-action-details=""] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-action-details] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-action-sort],
|
||||||
|
[data-template=class-list] label,
|
||||||
|
.classes,
|
||||||
|
.spell-level,
|
||||||
|
.spell-name,
|
||||||
|
.spell-school {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-action-sort] {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-action-sort]:hover {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-action-sort] i.material-icons.mdl-list__item-icon {
|
||||||
|
position: relative;
|
||||||
|
bottom: -.25em;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#share-url {
|
||||||
|
padding-left: 2em;
|
||||||
|
}
|
123
assets/wand.svg
Normal file
123
assets/wand.svg
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1"
|
||||||
|
id="svg7404" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="232 -592.3 824.9 1155"
|
||||||
|
style="enable-background:new 232 -592.3 824.9 1155;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#EDF9F7;}
|
||||||
|
.st1{fill:#7BCBBF;}
|
||||||
|
.st2{fill:#9BD8D0;}
|
||||||
|
.st3{fill:#CBE9E4;}
|
||||||
|
.st4{fill:#6EC3BB;}
|
||||||
|
.st5{fill:#FFFFFF;}
|
||||||
|
.st6{fill:#EED7B2;}
|
||||||
|
.st7{fill:#DAC4BF;}
|
||||||
|
.st8{fill:#CCDBB9;}
|
||||||
|
.st9{fill:#DBEFBE;}
|
||||||
|
.st10{fill:#D4E6BC;}
|
||||||
|
.st11{fill:#F9FBF5;}
|
||||||
|
.st12{fill:#D6C2BE;}
|
||||||
|
.st13{fill:#E0E4DD;}
|
||||||
|
.st14{fill:#B3D3C8;}
|
||||||
|
.st15{fill:#9FCABF;}
|
||||||
|
.st16{fill:#D3DBD9;}
|
||||||
|
.st17{fill:#A6C9C4;}
|
||||||
|
.st18{fill:#BCD1CD;}
|
||||||
|
.st19{fill:#92C0BB;}
|
||||||
|
.st20{fill:#DFEAE9;}
|
||||||
|
</style>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M544.6-229L544.6-229L544.6-229 M501.7-241.2L501.7-241.2l-19.1,22.8l31.1,13c0.1-1.1,0.4-2.1,1.1-2.9
|
||||||
|
c1-1.2,2.4-1.8,4-1.8c1.4,0,2.9,0.5,4.1,1.5c0.9,0.7,1.5,1.6,1.9,2.6l19.4-23.3L501.7-241.2"/>
|
||||||
|
<polyline class="st1" points="474.8,-209.1 447.4,-176.2 466.8,-136.4 489.6,-163.7 465.5,-197.8 474.9,-209.1 474.8,-209.1 "/>
|
||||||
|
<path class="st2" d="M544.5-229.4l-0.2,0.2l-19.4,23.3c0.7,1.8,0.5,3.9-0.7,5.4c-0.3,0.4-0.7,0.7-1.1,0.9l21.1,32.6l19.3-23.1
|
||||||
|
L544.6-229l0,0L544.5-229.4"/>
|
||||||
|
<polyline class="st3" points="489.9,-163.8 489.7,-163.6 489.6,-163.7 466.8,-136.4 466.7,-136.2 508.6,-124.3 508.6,-124.3
|
||||||
|
527,-146.3 489.9,-163.8 "/>
|
||||||
|
<path class="st2" d="M482.6-218.4l-7.8,9.3l-9.4,11.3l24.2,34.1l0.1,0.1l0.2-0.2l-0.2-0.1l29.3-35c-1-0.2-2-0.7-2.9-1.4
|
||||||
|
c-1.6-1.3-2.4-3.3-2.3-5.1L482.6-218.4L482.6-218.4"/>
|
||||||
|
<path class="st4" d="M523.1-199.6c-0.8,0.6-1.9,0.8-2.9,0.8c-0.4,0-0.8,0-1.2-0.1l-29.3,35l0.2,0.1l37.1,17.5l8.2-9.7l9.1-10.9
|
||||||
|
L523.1-199.6"/>
|
||||||
|
<path class="st5" d="M518.9-210c-1.5,0-3,0.6-4,1.8c-0.7,0.8-1.1,1.9-1.1,2.9c-0.1,1.8,0.7,3.7,2.3,5.1c0.9,0.7,1.9,1.2,2.9,1.4
|
||||||
|
c0.4,0.1,0.8,0.1,1.2,0.1c1,0,2.1-0.3,2.9-0.8c0.4-0.3,0.7-0.6,1.1-0.9c1.2-1.5,1.4-3.5,0.7-5.4c-0.4-1-1-1.9-1.9-2.6
|
||||||
|
C521.7-209.5,520.3-210,518.9-210"/>
|
||||||
|
<path class="st6" d="M874.4,91.9c-2,9.3-4.7,18-7.1,25.7l133.5,111.7l-2.3,2.7l0,0l13.2-15.9L874.4,91.9 M577.3-176.6l2.2,53.4
|
||||||
|
L624-86.1c4.1-1.9,9-2.9,14.2-2.9c3.2,0,6.5,0.4,9.6,1.2c13,3.4,19.8,12.9,15,21.2c-0.3,0.5-0.6,1-1,1.5c-0.7,2.4-1.5,5.5-2.1,8.9
|
||||||
|
L839.8,94.6c0-0.9,0-1.9-0.1-2.8l0,0c0,0,0,0,0,0c0.3-13.5,2-27.5-1.3-32.3L577.3-176.6"/>
|
||||||
|
<path class="st7" d="M867.3,117.6c-2.8,8.9-5.1,16.4-5.1,21.9c-0.1,3.7,0.4,6.8,1.2,9.5L987.6,245l10.9-13.1l2.3-2.7L867.3,117.6
|
||||||
|
M659.7-56.2c-3,16.4-2.7,42.8,21.9,63.4c2.2,1.8,4.6,3.4,7,4.5l67.1,52.1l0,0c-0.5,0.2-1,0.4-1.5,0.7l87.3,67.6
|
||||||
|
c-0.9-10.2-1.3-22.6-1.7-37.4L659.7-56.2 M579.6-123.3l0.1,2.5l-55.1,7.4L614-44.1c-0.6-5.7-0.7-10.8-0.7-15
|
||||||
|
c0-8.5,0.7-13.6,0.7-13.6s0-0.1,0.1-0.3c-0.1-2,0.4-4,1.5-6c1.7-3,4.7-5.4,8.4-7.1L579.6-123.3"/>
|
||||||
|
<path class="st8" d="M839.8,91.7L839.8,91.7c0,1,0,1.9,0.1,2.8c0.4,14.8,0.8,27.2,1.7,37.4c1.9,21.5,6,33.3,17.1,36.7
|
||||||
|
c3.4,1.1,6.4,1.5,9,1.5c4.4,0,7.6-1.2,9.9-2.6c-2.3,1.4-5.5,2.6-9.9,2.6c-2.6,0-5.6-0.4-9-1.5C841.9,163.6,841,139.4,839.8,91.7
|
||||||
|
M806.6-3.9c-10.8,0-21.9,2-32.8,4.7l23.9,21.6c1,0,2.1-0.1,3.1-0.1c21.4,0,38,9.1,49.3,22.5c12.8,15.3,3.1,56.1,3.9,79
|
||||||
|
c0.9,22.4-5.4,36.8,27.2,40.6c0.4-0.5,0.6-0.8,0.6-0.8s-14.1-0.8-18.4-14.8c-0.8-2.7-1.3-5.8-1.2-9.5c0.1-5.4,2.4-13,5.1-21.9
|
||||||
|
c2.4-7.7,5.1-16.4,7.1-25.7c5.4-25.7,5-55.8-24.9-80.8C836.3,0,821.7-3.9,806.6-3.9 M613.2-59.1c0,4.2,0.2,9.3,0.7,15
|
||||||
|
c2.5,25.9,12.6,64.3,47.8,93.6c20.4,17,39.5,23,56.7,23c13.2,0,25.2-3.5,35.8-8.1c0.5-0.2,1-0.4,1.5-0.7l0,0
|
||||||
|
c-10.9,4.9-23.5,8.7-37.2,8.7c-17.2,0-36.3-5.9-56.7-23C618.9,13.7,613.2-35.6,613.2-59.1 M661.9-65.1c-4.1,5.4-12.5,8.6-21.6,8.6
|
||||||
|
c-1.7,0-3.4-0.1-5.1-0.3c-0.8,25.1,5.1,61.8,29.9,82.4c10.6,8.8,25.2,11.8,40.9,11.8c4.8,0,9.7-0.3,14.7-0.8l35,27.1l-67.1-52.1
|
||||||
|
c-2.3-1.1-4.7-2.6-7-4.5c-24.6-20.5-24.9-46.9-21.9-63.4C660.3-59.7,661.1-62.7,661.9-65.1"/>
|
||||||
|
<path class="st9" d="M800.8,22.4c-1,0-2.1,0-3.1,0.1c0,0-0.1,0-0.1,0l40,36c0.3,0.3,0.6,0.6,0.8,0.9c3.3,4.9,1.6,18.9,1.3,32.3l0,0
|
||||||
|
c1.2,47.7,2.2,71.8,18.9,77c3.4,1.1,6.4,1.5,9,1.5c4.4,0,7.6-1.2,9.9-2.6c1.8-1.1,3-2.3,3.7-3.1c0,0,0,0,0,0
|
||||||
|
c-32.6-3.8-26.3-18.2-27.2-40.6c-0.8-22.9,8.9-63.7-3.9-79C838.8,31.5,822.2,22.4,800.8,22.4 M614.1-73c-0.1,0.2-0.1,0.3-0.1,0.3
|
||||||
|
s-0.7,5.1-0.7,13.6c0,23.6,5.7,72.8,48.5,108.6c20.4,17,39.5,23,56.7,23c13.8,0,26.3-3.8,37.2-8.7l0,0l-35-27.1
|
||||||
|
c-4.9,0.5-9.9,0.8-14.7,0.8c-15.7,0-30.3-3.1-40.9-11.8c-24.8-20.7-30.8-57.4-29.9-82.4c-1.5-0.2-3-0.5-4.5-0.9
|
||||||
|
C620.6-60.3,614.3-66.5,614.1-73"/>
|
||||||
|
<path class="st10" d="M638.2-59.6c-2,0-4.1-0.7-5.9-2.2c-3.7-3.1-4.4-8.2-1.7-11.4c1.4-1.7,3.5-2.5,5.7-2.5c2,0,4.1,0.7,5.9,2.2
|
||||||
|
c3.7,3.1,4.4,8.2,1.7,11.4C642.5-60.5,640.4-59.6,638.2-59.6 M638.2-89c-5.2,0-10.1,1-14.2,2.9c-3.7,1.7-6.7,4.2-8.4,7.1
|
||||||
|
c-1.1,2-1.6,4-1.5,6c0.3,6.5,6.6,12.7,16.5,15.3c1.5,0.4,3,0.7,4.5,0.9c1.7,0.2,3.4,0.3,5.1,0.3c9.1,0,17.5-3.2,21.6-8.6
|
||||||
|
c0.4-0.5,0.7-1,1-1.5c4.7-8.3-2-17.8-15-21.2C644.6-88.6,641.4-89,638.2-89"/>
|
||||||
|
<path class="st11" d="M636.3-75.8c-2.2,0-4.3,0.9-5.7,2.5c-2.7,3.3-2,8.4,1.7,11.4c1.8,1.5,3.9,2.2,5.9,2.2c2.2,0,4.3-0.9,5.7-2.5
|
||||||
|
c2.7-3.3,2-8.4-1.7-11.4C640.5-75.1,638.4-75.8,636.3-75.8"/>
|
||||||
|
<polyline class="st12" points="577.3,-178.5 549.7,-145.7 522.2,-113.1 524.5,-113.4 579.7,-120.8 579.6,-123.3 577.3,-176.6
|
||||||
|
577.3,-178.5 "/>
|
||||||
|
<polyline class="st13" points="563.6,-190 563.5,-190 564.1,-188.9 537.9,-157.6 550.6,-147 577.1,-178.7 563.6,-190 "/>
|
||||||
|
<polyline class="st14" points="563.5,-190 544.2,-166.9 544.4,-166.7 537.2,-158.2 537.9,-157.6 564.1,-188.9 563.5,-190 "/>
|
||||||
|
<polyline class="st15" points="544.2,-166.9 535.1,-156 537,-158.3 537.2,-158.2 544.4,-166.7 544.2,-166.9 "/>
|
||||||
|
<polyline class="st16" points="537.9,-157.6 536.7,-156.1 536.7,-156.1 509.7,-124 508.6,-124.3 522.1,-113 550.6,-147
|
||||||
|
537.9,-157.6 "/>
|
||||||
|
<polyline class="st17" points="537.2,-158.2 536.6,-157.4 537.3,-156.8 536.7,-156.1 536.7,-156.1 537.9,-157.6 537.2,-158.2 "/>
|
||||||
|
<polyline class="st18" points="536.6,-157.4 527.2,-146.2 527,-146.3 508.6,-124.3 508.6,-124.3 509.7,-124 536.7,-156.1
|
||||||
|
537.3,-156.8 536.6,-157.4 "/>
|
||||||
|
<polyline class="st19" points="537,-158.3 535.1,-156 527,-146.3 527.2,-146.2 536.6,-157.4 537.2,-158.2 537,-158.3 "/>
|
||||||
|
<polygon class="st20" points="362.8,-106.5 366.8,-137.1 394.1,-151.2 366.3,-164.3 361.4,-194.7 340.3,-172.4 309.9,-177.1
|
||||||
|
324.6,-150 310.7,-122.6 341,-128.3 "/>
|
||||||
|
<polygon class="st20" points="394.7,-386.8 409.4,-403.2 431.2,-400.3 420.2,-419.4 429.7,-439.2 408.2,-434.6 392.3,-449.7
|
||||||
|
390,-427.9 370.7,-417.4 390.7,-408.5 "/>
|
||||||
|
<polygon class="st20" points="457,20.4 461.6,-14.7 493.1,-30.9 461.1,-46.1 455.4,-81.1 431,-55.3 396,-60.7 413,-29.6 397,2
|
||||||
|
431.8,-4.5 "/>
|
||||||
|
<polygon class="st20" points="634.6,-418.3 636.7,-434.1 650.9,-441.4 636.5,-448.2 633.9,-463.9 623,-452.4 607.2,-454.8
|
||||||
|
614.9,-440.8 607.7,-426.6 623.3,-429.5 "/>
|
||||||
|
<polygon class="st20" points="803.5,-10.6 800.3,-33.9 817.8,-49.6 794.6,-53.9 785,-75.3 773.8,-54.7 750.5,-52.1 766.7,-35.1
|
||||||
|
761.9,-12.1 783.1,-22.3 "/>
|
||||||
|
<polygon class="st20" points="608.2,41.7 610.5,23.5 626.9,15.1 610.3,7.2 607.4,-10.9 594.7,2.5 576.6,-0.4 585.4,15.8
|
||||||
|
577.1,32.1 595.1,28.8 "/>
|
||||||
|
<polygon class="st20" points="267.8,88.3 269.8,72.5 284,65.2 269.6,58.4 267,42.6 256.1,54.2 240.4,51.8 248,65.8 240.8,80
|
||||||
|
256.5,77.1 "/>
|
||||||
|
<polygon class="st20" points="489.7,348 497.5,334.2 513.4,332.8 502.6,321 506.2,305.5 491.7,312.1 478,303.9 479.8,319.7
|
||||||
|
467.8,330.2 483.4,333.4 "/>
|
||||||
|
<polygon class="st20" points="989.4,-441.9 997.3,-455.7 1013.1,-457.1 1002.4,-468.9 1005.9,-484.4 991.4,-477.8 977.8,-486
|
||||||
|
979.6,-470.2 967.5,-459.7 983.2,-456.5 "/>
|
||||||
|
<polygon class="st20" points="934.4,137.9 939.1,126.4 951.4,123.8 941.9,115.7 943.1,103.3 932.5,109.8 921.1,104.8 924,116.9
|
||||||
|
915.7,126.2 928.2,127.1 "/>
|
||||||
|
<polygon class="st20" points="326.5,108.6 324.9,96.3 334.1,87.9 321.8,85.6 316.8,74.3 310.8,85.2 298.5,86.6 307.1,95.6
|
||||||
|
304.5,107.8 315.7,102.4 "/>
|
||||||
|
<polygon class="st20" points="530.6,104.7 532,93.7 541.9,88.7 531.9,83.9 530.1,73 522.5,81 511.6,79.3 516.9,89 511.9,98.9
|
||||||
|
522.7,96.9 "/>
|
||||||
|
<polygon class="st20" points="742.1,-272 745.1,-282.7 755.5,-286.3 746.3,-292.4 746.1,-303.5 737.4,-296.6 726.8,-299.8
|
||||||
|
730.7,-289.5 724.3,-280.4 735.4,-280.9 "/>
|
||||||
|
<polygon class="st20" points="939.7,-208.2 950.1,-211.9 959.1,-205.5 958.7,-216.6 967.5,-223.3 956.9,-226.3 953.4,-236.7
|
||||||
|
947.2,-227.6 936.1,-227.4 943,-218.7 "/>
|
||||||
|
<polygon class="st20" points="825.7,-570.5 829.8,-574.5 835.4,-573.5 832.8,-578.6 835.5,-583.7 829.9,-582.8 825.9,-587
|
||||||
|
825,-581.3 819.8,-578.8 824.9,-576.2 "/>
|
||||||
|
<polygon class="st20" points="862.9,475.8 867,471.8 872.6,472.8 870,467.7 872.7,462.6 867.1,463.5 863.1,459.3 862.2,465
|
||||||
|
857,467.5 862.1,470.1 "/>
|
||||||
|
<polygon class="st20" points="503.3,-554 507.4,-558 513.1,-557 510.5,-562.1 513.2,-567.2 507.5,-566.3 503.6,-570.5
|
||||||
|
502.7,-564.8 497.4,-562.3 502.6,-559.7 "/>
|
||||||
|
<polygon class="st20" points="706.5,302 710.6,297.9 716.3,299 713.6,293.8 716.4,288.7 710.7,289.6 706.7,285.5 705.8,291.1
|
||||||
|
700.6,293.6 705.7,296.2 "/>
|
||||||
|
<polygon class="st20" points="328,488.5 333.8,487.9 337.6,492.2 338.7,486.5 344,484.2 339,481.4 338.4,475.7 334.2,479.6
|
||||||
|
328.6,478.3 331,483.6 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9.2 KiB |
BIN
dist/.DS_Store
vendored
Normal file
BIN
dist/.DS_Store
vendored
Normal file
Binary file not shown.
279
dist/app.js
vendored
Normal file
279
dist/app.js
vendored
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
/**
|
||||||
|
* Misc helper functions
|
||||||
|
*/
|
||||||
|
Object.values = x => Object.keys(x).reduce((y, z) => y.push(x[z]) && y, []);
|
||||||
|
const debounce = (func, wait, immediate) => {
|
||||||
|
let timeout;
|
||||||
|
return function () {
|
||||||
|
let context = this,
|
||||||
|
args = arguments;
|
||||||
|
let later = function () {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) func.apply(context, args);
|
||||||
|
};
|
||||||
|
let callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) func.apply(context, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const el = id => $(`[data-template=${ id }]`)[0] || console.error('Unable to render to', id);
|
||||||
|
const clone = obj => JSON.parse(JSON.stringify(obj));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global store and view holders
|
||||||
|
*/
|
||||||
|
let store = {};
|
||||||
|
let view = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init Local Storage
|
||||||
|
*/
|
||||||
|
const localStorageDefault = (key, val) => {
|
||||||
|
if (localStorage.getItem(key) === null) localStorage.setItem(key, val);
|
||||||
|
};
|
||||||
|
let defaults = {
|
||||||
|
tableSortName: 'name',
|
||||||
|
tableSortRev: false,
|
||||||
|
classes: [],
|
||||||
|
search: ''
|
||||||
|
};
|
||||||
|
for (let cur in defaults) localStorageDefault(cur, defaults[cur]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Table Sort
|
||||||
|
*/
|
||||||
|
store.tableSort = {
|
||||||
|
data: ['name', 'school', 'level'],
|
||||||
|
current: localStorage.getItem('tableSortName'),
|
||||||
|
rev: localStorage.getItem('tableSortRev') !== 'false'
|
||||||
|
};
|
||||||
|
view.table_sort = Monkberry.render(table_sort, el('table-sort'));
|
||||||
|
view.table_sort.update(store.tableSort);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Spell List
|
||||||
|
*/
|
||||||
|
view.spell_list = Monkberry.render(spell_list, el('spell-list'));
|
||||||
|
view.spell_list.update({});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Spell Details
|
||||||
|
*/
|
||||||
|
view.spell_details = Monkberry.render(spell_details, el('spell-details'));
|
||||||
|
view.spell_details.update({ data: {} });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Class List
|
||||||
|
*/
|
||||||
|
store.classes = {
|
||||||
|
data: [],
|
||||||
|
current: localStorage.getItem('classes') ? localStorage.getItem('classes').split(',') : []
|
||||||
|
};
|
||||||
|
view.class_list = Monkberry.render(class_list, el('class-list'));
|
||||||
|
view.class_list.update(store.classes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Search
|
||||||
|
*/
|
||||||
|
store.search = localStorage.getItem('search');
|
||||||
|
view.search_field = Monkberry.render(search_field, el('search-field'));
|
||||||
|
view.search_field.update({ data: store.search });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discover Classes
|
||||||
|
*/
|
||||||
|
const discoverClasses = spells => {
|
||||||
|
let classes = [];
|
||||||
|
spells.forEach(spell => {
|
||||||
|
if (!spell.classes) return;
|
||||||
|
spell.classes.forEach(current => {
|
||||||
|
if (!classes.includes(current)) classes.push(current);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return classes.sort((a, b) => a > b);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emphasis on important string bits
|
||||||
|
* @param {string} string
|
||||||
|
*/
|
||||||
|
const emphasis = str => {
|
||||||
|
let keywords = ['constitution', 'con', 'intelligence', 'int', 'wisdom', 'wis', 'strength', 'str', 'dexterity', 'dex', 'charisma', 'cha', 'comeliness', 'com', 'saving throw', 'ability check', 'skill check'];
|
||||||
|
keywords.forEach(word => {
|
||||||
|
let r = new RegExp(` ${ word } `, 'gi');
|
||||||
|
str = str.replace(r, o => `<em class="mdl-color-text--teal-600">${ o }</em>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
str = str.replace(/[\s()<>]+\d+d*\d*(th)*[\s()<>]+/gi, o => `<strong>${ o }</strong>`);
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init Spells
|
||||||
|
*/
|
||||||
|
const initSpells = s => s.map((spell, i) => {
|
||||||
|
spell.selected = false;
|
||||||
|
spell.ranking = 0;
|
||||||
|
spell.level = parseInt(spell.level) ? spell.level : 0;
|
||||||
|
spell.prettyLevel = spell.level === 0 ? 'C' : spell.level;
|
||||||
|
return spell;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort Spells
|
||||||
|
*/
|
||||||
|
const sortSpells = (s, sortBy, reverse) => s.sort((a, b) => {
|
||||||
|
let hasFilters = store.classes.current.length || store.search.length;
|
||||||
|
let by = sortBy || hasFilters ? 'ranking' : store.tableSort.current;
|
||||||
|
let rev = reverse || hasFilters ? false : store.tableSort.rev;
|
||||||
|
if (by) {
|
||||||
|
if (a[by] < b[by]) return rev ? 1 : -1;
|
||||||
|
if (a[by] > b[by]) return rev ? -1 : 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search Spells
|
||||||
|
* @param {Array} spells
|
||||||
|
* @param {String} ex 'acid spray'
|
||||||
|
* @return {Array} filtered spells
|
||||||
|
*/
|
||||||
|
const searchSpells = (spells, search) => {
|
||||||
|
// Convert search to array of words
|
||||||
|
search = search.split(' ');
|
||||||
|
// Clone spells so we don't affect the original
|
||||||
|
spells = clone(spells);
|
||||||
|
// Reset rankings
|
||||||
|
spells = spells.map(s => {
|
||||||
|
s.ranking = 0;
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
// Rank spells by # of occurances of search terms
|
||||||
|
spells = spells.map(spell => {
|
||||||
|
search.forEach(term => {
|
||||||
|
let spellText = Object.values(spell).join(' ');
|
||||||
|
let regFind = new RegExp(term, 'gi');
|
||||||
|
spell.ranking += (spellText.match(regFind) || []).length;
|
||||||
|
});
|
||||||
|
return spell;
|
||||||
|
});
|
||||||
|
// Return spells that matched at least something
|
||||||
|
return spells.filter(spell => spell.ranking);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter Spells by Class
|
||||||
|
*/
|
||||||
|
const filterSpellsByClass = (spells, classes) => {
|
||||||
|
// If no classes, default to all classes
|
||||||
|
classes = classes.length ? classes : store.classes.data;
|
||||||
|
// Clone spells so we don't affect the original
|
||||||
|
spells = clone(spells);
|
||||||
|
return spells.filter(spell => {
|
||||||
|
let spellClasses = spell.classes.join(' ');
|
||||||
|
let match = false;
|
||||||
|
classes.forEach(c => {
|
||||||
|
if (spellClasses.indexOf(c) >= 0) {
|
||||||
|
match = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply Filters
|
||||||
|
* @returns {Array} of spells ranked based on searches and filters
|
||||||
|
*/
|
||||||
|
let applyFilters = () => sortSpells(searchSpells(filterSpellsByClass(store.spells, store.classes.current), store.search));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spell Details Updating
|
||||||
|
*/
|
||||||
|
const spellDetails = name => {
|
||||||
|
if (!name) {
|
||||||
|
view.spell_details.update({ data: {} });
|
||||||
|
$('body').removeClass('details');
|
||||||
|
} else {
|
||||||
|
let data = store.spells.find(spell => name === spell.name);
|
||||||
|
data.description = emphasis(data.description);
|
||||||
|
view.spell_details.update({
|
||||||
|
data,
|
||||||
|
url: window.location.href
|
||||||
|
});
|
||||||
|
$('body').addClass('details');
|
||||||
|
let clipboard = new Clipboard('.copy-to-clipboard');
|
||||||
|
clipboard.on('success', e => $('#toast')[0].MaterialSnackbar.showSnackbar({ message: 'Copied link' })).on('error', e => $('#toast')[0].MaterialSnackbar.showSnackbar({ message: 'Sorry! Unable to copy link' }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Event Bindings
|
||||||
|
*/
|
||||||
|
// Listen for header sorts
|
||||||
|
$('body').on('click', '[data-action-sort]', e => {
|
||||||
|
let name = $(e.currentTarget).attr('data-action-sort');
|
||||||
|
let rev = store.tableSort.current === name && !store.tableSort.rev;
|
||||||
|
store.tableSort.current = name;
|
||||||
|
store.tableSort.rev = rev;
|
||||||
|
localStorage.setItem('tableSortName', name);
|
||||||
|
localStorage.setItem('tableSortRev', rev);
|
||||||
|
view.spell_list.update({ data: sortSpells(store.spells) });
|
||||||
|
view.table_sort.update(store.tableSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for checkbox changes to filter spells
|
||||||
|
$('body').on('change', '[data-action-classtoggle]', e => {
|
||||||
|
let name = $(e.currentTarget).attr('data-action-classtoggle');
|
||||||
|
let add = $(e.currentTarget).prop('checked');
|
||||||
|
let index = store.classes.current.indexOf(name);
|
||||||
|
if (index === -1 && add) {
|
||||||
|
store.classes.current.push(name);
|
||||||
|
} else if (!add) store.classes.current.splice(index, 1);
|
||||||
|
store.tableSort.current = store.classes.current.length || store.search.length ? 'ranking' : null;
|
||||||
|
localStorage.setItem('tableSortName', store.tableSort.current);
|
||||||
|
localStorage.setItem('classes', store.classes.current);
|
||||||
|
view.spell_list.update({ data: applyFilters() });
|
||||||
|
view.table_sort.update({ current: store.tableSort.current });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen to search to filter by
|
||||||
|
$('body').on('change keyup cut paste', '[data-action-search]', e => {
|
||||||
|
setTimeout(() => {
|
||||||
|
// Delay for value to change
|
||||||
|
store.search = $(e.currentTarget).val();
|
||||||
|
store.tableSort.current = store.search.length || store.classes.current.length ? 'ranking' : null;
|
||||||
|
store.tableSort.rev = false;
|
||||||
|
localStorage.setItem('search', store.search);
|
||||||
|
localStorage.setItem('tableSortName', store.tableSort.current);
|
||||||
|
localStorage.setItem('tableSortRev', store.tableSort.rev);
|
||||||
|
view.spell_list.update({ data: applyFilters() });
|
||||||
|
view.table_sort.update(store.tableSort);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for click on spells to open details
|
||||||
|
$('body').on('click', '[data-action-details]', e => {
|
||||||
|
let name = $(e.currentTarget).attr('data-action-details');
|
||||||
|
window.location.hash = name;
|
||||||
|
spellDetails(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Article Scroll with User
|
||||||
|
$('.mdl-layout__content').on('scroll', debounce(() => {
|
||||||
|
let distance = $('.mdl-layout__content')[0].scrollTop;
|
||||||
|
$('[data-template=spell-details]').css('margin-top', distance);
|
||||||
|
}, 10));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Spells
|
||||||
|
*/
|
||||||
|
fetch('./spells.json').then(response => response.json()).then(spells => initSpells(spells)).then(spells => {
|
||||||
|
store.spells = spells;
|
||||||
|
store.classes.data = discoverClasses(spells);
|
||||||
|
view.spell_list.update({ data: applyFilters() });
|
||||||
|
view.class_list.update(store.classes);
|
||||||
|
if (window.location.hash) spellDetails(window.location.hash.substr(1));
|
||||||
|
}).catch(reason => console.error('Unable to retrieve spells list:', reason));
|
974
dist/view.js
vendored
Normal file
974
dist/view.js
vendored
Normal file
|
@ -0,0 +1,974 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function class_list() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var for0 = document.createComment('if');
|
||||||
|
var child0 = {};
|
||||||
|
var child1 = {};
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
var result;
|
||||||
|
result = Monkberry.cond(_this, for0, child0, class_list_if0, data);
|
||||||
|
Monkberry.cond(_this, for0, child1, class_list_else1, !result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child1.ref) {
|
||||||
|
child1.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [for0];
|
||||||
|
}
|
||||||
|
class_list.prototype = Object.create(Monkberry.prototype);
|
||||||
|
class_list.prototype.constructor = class_list;
|
||||||
|
class_list.pool = [];
|
||||||
|
class_list.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function class_list_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var for0 = document.createComment('for');
|
||||||
|
var children0 = new Monkberry.Map();
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
Monkberry.loop(_this, for0, children0, class_list_if0_for0, data, {"value":"cur"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
children0.forEach(function (view) {
|
||||||
|
view.update(__data__);
|
||||||
|
view.update(view.__state__);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [for0];
|
||||||
|
}
|
||||||
|
class_list_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
class_list_if0.prototype.constructor = class_list_if0;
|
||||||
|
class_list_if0.pool = [];
|
||||||
|
class_list_if0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function class_list_if0_for0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
this.__cache__ = {};
|
||||||
|
this.__state__ = {};
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var label0 = document.createElement('label');
|
||||||
|
var div1 = document.createElement('div');
|
||||||
|
var for0 = document.createComment('if');
|
||||||
|
var child0 = {};
|
||||||
|
var child1 = {};
|
||||||
|
var span2 = document.createElement('span');
|
||||||
|
var text3 = document.createTextNode('');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
span2.appendChild(text3);
|
||||||
|
span2.setAttribute("class", "mdl-switch__label");
|
||||||
|
div1.appendChild(for0);
|
||||||
|
div1.appendChild(span2);
|
||||||
|
div1.setAttribute("class", "mdl-switch mdl-js-switch mdl-js-ripple-effect");
|
||||||
|
label0.appendChild(div1);
|
||||||
|
label0.setAttribute("class", "mdl-navigation__link");
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
cur_current: function (cur, current) {
|
||||||
|
var result;
|
||||||
|
result = Monkberry.cond(_this, for0, child0, class_list_if0_for0_if0, current.includes(cur));
|
||||||
|
Monkberry.cond(_this, for0, child1, class_list_if0_for0_else1, !result);
|
||||||
|
},
|
||||||
|
cur: function (cur) {
|
||||||
|
text3.textContent = cur;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child1.ref) {
|
||||||
|
child1.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [label0];
|
||||||
|
}
|
||||||
|
class_list_if0_for0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
class_list_if0_for0.prototype.constructor = class_list_if0_for0;
|
||||||
|
class_list_if0_for0.pool = [];
|
||||||
|
class_list_if0_for0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.cur !== undefined && __data__.__index__ !== undefined) {
|
||||||
|
this.__cache__.cur = __data__.cur;
|
||||||
|
this.__update__.cur(__data__.cur);
|
||||||
|
}
|
||||||
|
if (__data__.current !== undefined) {
|
||||||
|
this.__cache__.current = __data__.current;
|
||||||
|
}
|
||||||
|
if (this.__cache__.cur !== undefined && this.__cache__.current !== undefined) {
|
||||||
|
this.__update__.cur_current(this.__cache__.cur, this.__cache__.current);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function class_list_if0_for0_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var input0 = document.createElement('input');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
input0.checked = true;
|
||||||
|
input0.setAttribute("name", "class");
|
||||||
|
input0.setAttribute("type", "checkbox");
|
||||||
|
input0.setAttribute("class", "mdl-switch__input");
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
cur: function (cur) {
|
||||||
|
input0.setAttribute("data-action-classtoggle", cur);;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [input0];
|
||||||
|
}
|
||||||
|
class_list_if0_for0_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
class_list_if0_for0_if0.prototype.constructor = class_list_if0_for0_if0;
|
||||||
|
class_list_if0_for0_if0.pool = [];
|
||||||
|
class_list_if0_for0_if0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.cur !== undefined) {
|
||||||
|
this.__update__.cur(__data__.cur);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function class_list_if0_for0_else1() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var input0 = document.createElement('input');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
input0.setAttribute("name", "class");
|
||||||
|
input0.setAttribute("type", "checkbox");
|
||||||
|
input0.setAttribute("class", "mdl-switch__input");
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
cur: function (cur) {
|
||||||
|
input0.setAttribute("data-action-classtoggle", cur);;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [input0];
|
||||||
|
}
|
||||||
|
class_list_if0_for0_else1.prototype = Object.create(Monkberry.prototype);
|
||||||
|
class_list_if0_for0_else1.prototype.constructor = class_list_if0_for0_else1;
|
||||||
|
class_list_if0_for0_else1.pool = [];
|
||||||
|
class_list_if0_for0_else1.prototype.update = function (__data__) {
|
||||||
|
if (__data__.cur !== undefined) {
|
||||||
|
this.__update__.cur(__data__.cur);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function class_list_else1() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var div0 = document.createElement('div');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
div0.setAttribute("class", "mdl-spinner mdl-js-spinner is-active");
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [div0];
|
||||||
|
}
|
||||||
|
class_list_else1.prototype = Object.create(Monkberry.prototype);
|
||||||
|
class_list_else1.prototype.constructor = class_list_else1;
|
||||||
|
class_list_else1.pool = [];
|
||||||
|
class_list_else1.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
window.class_list = class_list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function search_field() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var input0 = document.createElement('input');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
input0.setAttribute("class", "mdl-textfield__input");
|
||||||
|
input0.setAttribute("data-action-search", "");
|
||||||
|
input0.setAttribute("type", "text");
|
||||||
|
input0.setAttribute("name", "sample");
|
||||||
|
input0.id = "fixed-header-drawer-exp";
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
input0.value = data;;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [input0];
|
||||||
|
}
|
||||||
|
search_field.prototype = Object.create(Monkberry.prototype);
|
||||||
|
search_field.prototype.constructor = search_field;
|
||||||
|
search_field.pool = [];
|
||||||
|
search_field.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.search_field = search_field;
|
||||||
|
|
||||||
|
var __unsafe = function unsafe(root, nodes, html) {var node,j,i = nodes.length,element = document.createElement('div');element.innerHTML = html;while (i-- > 0) {nodes[i].parentNode.removeChild(nodes.pop());}for (i = j = element.childNodes.length - 1; j >= 0; j--) {nodes.push(element.childNodes[j]);}++i;if (root.nodeType == 8) {if (root.parentNode) while (i-- > 0) {root.parentNode.insertBefore(nodes[i], root);} else throw "Can not insert child view into parent node. You need append your view first and then update.";} else while (i-- > 0) {root.appendChild(nodes[i]);}};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_details() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var for0 = document.createComment('if');
|
||||||
|
var child0 = {};
|
||||||
|
var child1 = {};
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
var result;
|
||||||
|
result = Monkberry.cond(_this, for0, child0, spell_details_if0, data.name);
|
||||||
|
Monkberry.cond(_this, for0, child1, spell_details_else1, !result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child1.ref) {
|
||||||
|
child1.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [for0];
|
||||||
|
}
|
||||||
|
spell_details.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_details.prototype.constructor = spell_details;
|
||||||
|
spell_details.pool = [];
|
||||||
|
spell_details.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_details_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var button0 = document.createElement('button');
|
||||||
|
var i1 = document.createElement('i');
|
||||||
|
var h52 = document.createElement('h5');
|
||||||
|
var text3 = document.createTextNode('');
|
||||||
|
var p4 = document.createElement('p');
|
||||||
|
var unsafeNodes0 = [];
|
||||||
|
var div5 = document.createElement('div');
|
||||||
|
var ul6 = document.createElement('ul');
|
||||||
|
var li7 = document.createElement('li');
|
||||||
|
var strong8 = document.createElement('strong');
|
||||||
|
var text9 = document.createTextNode('');
|
||||||
|
var li10 = document.createElement('li');
|
||||||
|
var strong11 = document.createElement('strong');
|
||||||
|
var text12 = document.createTextNode('');
|
||||||
|
var li13 = document.createElement('li');
|
||||||
|
var strong14 = document.createElement('strong');
|
||||||
|
var text15 = document.createTextNode('');
|
||||||
|
var for0 = document.createComment('if');
|
||||||
|
var child0 = {};
|
||||||
|
var ul16 = document.createElement('ul');
|
||||||
|
var li17 = document.createElement('li');
|
||||||
|
var strong18 = document.createElement('strong');
|
||||||
|
var text19 = document.createTextNode('');
|
||||||
|
var li20 = document.createElement('li');
|
||||||
|
var strong21 = document.createElement('strong');
|
||||||
|
var text22 = document.createTextNode('Cantrip');
|
||||||
|
var li23 = document.createElement('li');
|
||||||
|
var strong24 = document.createElement('strong');
|
||||||
|
var span25 = document.createElement('span');
|
||||||
|
var text26 = document.createTextNode('');
|
||||||
|
var for1 = document.createComment('if');
|
||||||
|
var child2 = {};
|
||||||
|
var div27 = document.createElement('div');
|
||||||
|
var label28 = document.createElement('label');
|
||||||
|
var i29 = document.createElement('i');
|
||||||
|
var input30 = document.createElement('input');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
i1.appendChild(document.createTextNode("close"));
|
||||||
|
i1.setAttribute("class", "material-icons");
|
||||||
|
button0.appendChild(i1);
|
||||||
|
button0.setAttribute("data-action-details", "");
|
||||||
|
button0.setAttribute("class", "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab");
|
||||||
|
h52.appendChild(text3);
|
||||||
|
h52.setAttribute("class", "mdl-typography--display-1 mdl-color-text--teal-600");
|
||||||
|
p4.setAttribute("class", "description");
|
||||||
|
strong8.appendChild(document.createTextNode("Range: "));
|
||||||
|
li7.appendChild(strong8);
|
||||||
|
li7.appendChild(text9);
|
||||||
|
strong11.appendChild(document.createTextNode("Casting Time: "));
|
||||||
|
li10.appendChild(strong11);
|
||||||
|
li10.appendChild(text12);
|
||||||
|
strong14.appendChild(document.createTextNode("Duration: "));
|
||||||
|
li13.appendChild(strong14);
|
||||||
|
li13.appendChild(text15);
|
||||||
|
ul6.appendChild(li7);
|
||||||
|
ul6.appendChild(li10);
|
||||||
|
ul6.appendChild(li13);
|
||||||
|
ul6.appendChild(for0);
|
||||||
|
ul6.setAttribute("class", "right mdl-cell mdl-cell--6-col");
|
||||||
|
strong18.appendChild(document.createTextNode("School: "));
|
||||||
|
li17.appendChild(strong18);
|
||||||
|
li17.appendChild(text19);
|
||||||
|
strong21.appendChild(document.createTextNode("Spell Level: "));
|
||||||
|
li20.appendChild(strong21);
|
||||||
|
li20.appendChild(text22);
|
||||||
|
strong24.appendChild(document.createTextNode("Class: "));
|
||||||
|
span25.appendChild(text26);
|
||||||
|
span25.setAttribute("class", "classes");
|
||||||
|
li23.appendChild(strong24);
|
||||||
|
li23.appendChild(span25);
|
||||||
|
ul16.appendChild(li17);
|
||||||
|
ul16.appendChild(li20);
|
||||||
|
ul16.appendChild(li23);
|
||||||
|
ul16.appendChild(for1);
|
||||||
|
ul16.setAttribute("class", "left mdl-cell mdl-cell--6-col");
|
||||||
|
i29.appendChild(document.createTextNode("content_copy"));
|
||||||
|
i29.setAttribute("class", "material-icons");
|
||||||
|
label28.appendChild(i29);
|
||||||
|
label28.setAttribute("class", "mdl-button mdl-js-button mdl-button--icon copy-to-clipboard");
|
||||||
|
label28.setAttribute("for", "share-url");
|
||||||
|
label28.setAttribute("data-clipboard-target", "#share-url");
|
||||||
|
input30.setAttribute("readonly", "");
|
||||||
|
input30.setAttribute("class", "mdl-textfield__input");
|
||||||
|
input30.setAttribute("type", "text");
|
||||||
|
input30.id = "share-url";
|
||||||
|
div27.appendChild(label28);
|
||||||
|
div27.appendChild(input30);
|
||||||
|
div27.setAttribute("class", "mdl-textfield mdl-js-textfield");
|
||||||
|
div5.appendChild(ul6);
|
||||||
|
div5.appendChild(ul16);
|
||||||
|
div5.appendChild(div27);
|
||||||
|
div5.setAttribute("class", "mdl-grid");
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
text3.textContent = data.name;
|
||||||
|
__unsafe(p4, unsafeNodes0, data.description);
|
||||||
|
text9.textContent = data.range;
|
||||||
|
text12.textContent = data.casting_time;
|
||||||
|
text15.textContent = data.duration;
|
||||||
|
Monkberry.cond(_this, for0, child0, spell_details_if0_if0, data.ritual);
|
||||||
|
text19.textContent = data.school;
|
||||||
|
text22.textContent = (data.level) || ('Cantrip');
|
||||||
|
text26.textContent = data.classes.join(', ');
|
||||||
|
Monkberry.cond(_this, for1, child2, spell_details_if0_if2, (data.components) && (data.components.raw));
|
||||||
|
},
|
||||||
|
url: function (url) {
|
||||||
|
input30.value = url;;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child2.ref) {
|
||||||
|
child2.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [button0, h52, p4, div5];
|
||||||
|
}
|
||||||
|
spell_details_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_details_if0.prototype.constructor = spell_details_if0;
|
||||||
|
spell_details_if0.pool = [];
|
||||||
|
spell_details_if0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
if (__data__.url !== undefined) {
|
||||||
|
this.__update__.url(__data__.url);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_details_if0_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var li0 = document.createElement('li');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
li0.appendChild(document.createTextNode("Ritual"));
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [li0];
|
||||||
|
}
|
||||||
|
spell_details_if0_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_details_if0_if0.prototype.constructor = spell_details_if0_if0;
|
||||||
|
spell_details_if0_if0.pool = [];
|
||||||
|
spell_details_if0_if0.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_details_if0_if2() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var li0 = document.createElement('li');
|
||||||
|
var strong1 = document.createElement('strong');
|
||||||
|
var text2 = document.createTextNode('');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
strong1.appendChild(document.createTextNode("Components: "));
|
||||||
|
li0.appendChild(strong1);
|
||||||
|
li0.appendChild(text2);
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
text2.textContent = data.components.raw;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [li0];
|
||||||
|
}
|
||||||
|
spell_details_if0_if2.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_details_if0_if2.prototype.constructor = spell_details_if0_if2;
|
||||||
|
spell_details_if0_if2.pool = [];
|
||||||
|
spell_details_if0_if2.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_details_else1() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var div0 = document.createElement('div');
|
||||||
|
var h61 = document.createElement('h6');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
h61.appendChild(document.createTextNode(" Choose a Spell "));
|
||||||
|
h61.setAttribute("class", "mdl-typography--title");
|
||||||
|
div0.appendChild(h61);
|
||||||
|
div0.id = "empty";
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [div0];
|
||||||
|
}
|
||||||
|
spell_details_else1.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_details_else1.prototype.constructor = spell_details_else1;
|
||||||
|
spell_details_else1.pool = [];
|
||||||
|
spell_details_else1.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
window.spell_details = spell_details;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_list() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var for0 = document.createComment('if');
|
||||||
|
var child0 = {};
|
||||||
|
var child1 = {};
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
var result;
|
||||||
|
result = Monkberry.cond(_this, for0, child0, spell_list_if0, data.length);
|
||||||
|
Monkberry.cond(_this, for0, child1, spell_list_else1, !result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child1.ref) {
|
||||||
|
child1.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [for0];
|
||||||
|
}
|
||||||
|
spell_list.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_list.prototype.constructor = spell_list;
|
||||||
|
spell_list.pool = [];
|
||||||
|
spell_list.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_list_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var for0 = document.createComment('for');
|
||||||
|
var children0 = new Monkberry.Map();
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
Monkberry.loop(_this, for0, children0, spell_list_if0_for0, data, {"value":"spell"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
children0.forEach(function (view) {
|
||||||
|
view.update(__data__);
|
||||||
|
view.update(view.__state__);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [for0];
|
||||||
|
}
|
||||||
|
spell_list_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_list_if0.prototype.constructor = spell_list_if0;
|
||||||
|
spell_list_if0.pool = [];
|
||||||
|
spell_list_if0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_list_if0_for0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
this.__state__ = {};
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var tr0 = document.createElement('tr');
|
||||||
|
var td1 = document.createElement('td');
|
||||||
|
var strong2 = document.createElement('strong');
|
||||||
|
var text3 = document.createTextNode('');
|
||||||
|
var td4 = document.createElement('td');
|
||||||
|
var text5 = document.createTextNode('');
|
||||||
|
var td6 = document.createElement('td');
|
||||||
|
var text7 = document.createTextNode('');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
strong2.appendChild(text3);
|
||||||
|
td1.appendChild(strong2);
|
||||||
|
td1.setAttribute("class", "spell-name mdl-data-table__cell--non-numeric");
|
||||||
|
td4.appendChild(text5);
|
||||||
|
td4.setAttribute("class", "spell-school mdl-data-table__cell--non-numeric");
|
||||||
|
td6.appendChild(text7);
|
||||||
|
td6.setAttribute("class", "spell-level");
|
||||||
|
tr0.appendChild(td1);
|
||||||
|
tr0.appendChild(td4);
|
||||||
|
tr0.appendChild(td6);
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
spell: function (spell) {
|
||||||
|
text3.textContent = spell.name;
|
||||||
|
text5.textContent = spell.school;
|
||||||
|
text7.textContent = spell.prettyLevel;
|
||||||
|
tr0.setAttribute("data-action-details", spell.name);;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [tr0];
|
||||||
|
}
|
||||||
|
spell_list_if0_for0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_list_if0_for0.prototype.constructor = spell_list_if0_for0;
|
||||||
|
spell_list_if0_for0.pool = [];
|
||||||
|
spell_list_if0_for0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.spell !== undefined && __data__.__index__ !== undefined) {
|
||||||
|
this.__update__.spell(__data__.spell);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_list_else1() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var tr0 = document.createElement('tr');
|
||||||
|
var td1 = document.createElement('td');
|
||||||
|
var child0 = {};
|
||||||
|
var child1 = {};
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
td1.setAttribute("colspan", "4");
|
||||||
|
tr0.appendChild(td1);
|
||||||
|
tr0.setAttribute("class", "do-nothing");
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
var result;
|
||||||
|
result = Monkberry.cond(_this, td1, child0, spell_list_else1_if0, data);
|
||||||
|
Monkberry.cond(_this, td1, child1, spell_list_else1_else1, !result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child1.ref) {
|
||||||
|
child1.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [tr0];
|
||||||
|
}
|
||||||
|
spell_list_else1.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_list_else1.prototype.constructor = spell_list_else1;
|
||||||
|
spell_list_else1.pool = [];
|
||||||
|
spell_list_else1.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_list_else1_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var div0 = document.createElement('div');
|
||||||
|
var i1 = document.createElement('i');
|
||||||
|
var h52 = document.createElement('h5');
|
||||||
|
var h63 = document.createElement('h6');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
i1.appendChild(document.createTextNode(" warning "));
|
||||||
|
i1.setAttribute("class", "material-icons mdl-list__item-icon mdl-color-text--orange-600");
|
||||||
|
h52.appendChild(document.createTextNode("No Results"));
|
||||||
|
h63.appendChild(document.createTextNode("Try refining your filters in the sidebar."));
|
||||||
|
div0.appendChild(i1);
|
||||||
|
div0.appendChild(h52);
|
||||||
|
div0.appendChild(h63);
|
||||||
|
div0.setAttribute("class", "text-center");
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [div0];
|
||||||
|
}
|
||||||
|
spell_list_else1_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_list_else1_if0.prototype.constructor = spell_list_else1_if0;
|
||||||
|
spell_list_else1_if0.pool = [];
|
||||||
|
spell_list_else1_if0.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function spell_list_else1_else1() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var div0 = document.createElement('div');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
div0.setAttribute("class", "mdl-spinner mdl-js-spinner is-active");
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [div0];
|
||||||
|
}
|
||||||
|
spell_list_else1_else1.prototype = Object.create(Monkberry.prototype);
|
||||||
|
spell_list_else1_else1.prototype.constructor = spell_list_else1_else1;
|
||||||
|
spell_list_else1_else1.pool = [];
|
||||||
|
spell_list_else1_else1.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
window.spell_list = spell_list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function table_sort() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var for0 = document.createComment('for');
|
||||||
|
var children0 = new Monkberry.Map();
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
data: function (data) {
|
||||||
|
Monkberry.loop(_this, for0, children0, table_sort_for0, data, {"value":"name"});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
children0.forEach(function (view) {
|
||||||
|
view.update(__data__);
|
||||||
|
view.update(view.__state__);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [for0];
|
||||||
|
}
|
||||||
|
table_sort.prototype = Object.create(Monkberry.prototype);
|
||||||
|
table_sort.prototype.constructor = table_sort;
|
||||||
|
table_sort.pool = [];
|
||||||
|
table_sort.prototype.update = function (__data__) {
|
||||||
|
if (__data__.data !== undefined) {
|
||||||
|
this.__update__.data(__data__.data);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function table_sort_for0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
this.__cache__ = {};
|
||||||
|
this.__state__ = {};
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
|
// Create elements
|
||||||
|
var th0 = document.createElement('th');
|
||||||
|
var i1 = document.createElement('i');
|
||||||
|
var for0 = document.createComment('if');
|
||||||
|
var child0 = {};
|
||||||
|
var for1 = document.createComment('if');
|
||||||
|
var child2 = {};
|
||||||
|
var for2 = document.createComment('if');
|
||||||
|
var child4 = {};
|
||||||
|
var span2 = document.createElement('span');
|
||||||
|
var text3 = document.createTextNode('');
|
||||||
|
var i4 = document.createElement('i');
|
||||||
|
var text5 = document.createTextNode('');
|
||||||
|
|
||||||
|
// Construct dom
|
||||||
|
i1.appendChild(for0);
|
||||||
|
i1.appendChild(for1);
|
||||||
|
i1.appendChild(for2);
|
||||||
|
i1.setAttribute("class", "material-icons mdl-list__item-icon");
|
||||||
|
span2.appendChild(document.createTextNode(" "));
|
||||||
|
span2.appendChild(text3);
|
||||||
|
i4.appendChild(text5);
|
||||||
|
i4.setAttribute("class", "material-icons mdl-color-text--teal-600 mdl-list__item-icon ");
|
||||||
|
th0.appendChild(i1);
|
||||||
|
th0.appendChild(span2);
|
||||||
|
th0.appendChild(i4);
|
||||||
|
th0.setAttribute("class", "mdl-data-table__cell--non-numeric ");
|
||||||
|
|
||||||
|
// Update functions
|
||||||
|
this.__update__ = {
|
||||||
|
name: function (name) {
|
||||||
|
Monkberry.cond(_this, for0, child0, table_sort_for0_if0, (name) === ('level'));
|
||||||
|
Monkberry.cond(_this, for1, child2, table_sort_for0_if2, (name) === ('name'));
|
||||||
|
Monkberry.cond(_this, for2, child4, table_sort_for0_if4, (name) === ('school'));
|
||||||
|
text3.textContent = name;
|
||||||
|
th0.setAttribute("data-action-sort", name);;
|
||||||
|
},
|
||||||
|
rev: function (rev) {
|
||||||
|
text5.textContent = (rev) ? 'keyboard_arrow_up' : 'keyboard_arrow_down';
|
||||||
|
},
|
||||||
|
current_name: function (current, name) {
|
||||||
|
i4.setAttribute("class", ("material-icons mdl-color-text--teal-600 mdl-list__item-icon ") + (((name) === (current)) ? 'mdl-color-text--teal-600' : 'mdl-color-text--grey-300'));;
|
||||||
|
},
|
||||||
|
current: function (current) {
|
||||||
|
th0.setAttribute("class", ("mdl-data-table__cell--non-numeric ") + (((current) === ('ranking')) ? 'mdl-color-text--grey-200 do-nothing' : ''));;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// On update actions
|
||||||
|
this.onUpdate = function (__data__) {
|
||||||
|
if (child0.ref) {
|
||||||
|
child0.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child2.ref) {
|
||||||
|
child2.ref.update(__data__);
|
||||||
|
}
|
||||||
|
if (child4.ref) {
|
||||||
|
child4.ref.update(__data__);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [th0];
|
||||||
|
}
|
||||||
|
table_sort_for0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
table_sort_for0.prototype.constructor = table_sort_for0;
|
||||||
|
table_sort_for0.pool = [];
|
||||||
|
table_sort_for0.prototype.update = function (__data__) {
|
||||||
|
if (__data__.name !== undefined && __data__.__index__ !== undefined) {
|
||||||
|
this.__cache__.name = __data__.name;
|
||||||
|
this.__update__.name(__data__.name);
|
||||||
|
}
|
||||||
|
if (__data__.rev !== undefined) {
|
||||||
|
this.__update__.rev(__data__.rev);
|
||||||
|
}
|
||||||
|
if (__data__.current !== undefined) {
|
||||||
|
this.__cache__.current = __data__.current;
|
||||||
|
this.__update__.current(__data__.current);
|
||||||
|
}
|
||||||
|
if (this.__cache__.current !== undefined && this.__cache__.name !== undefined) {
|
||||||
|
this.__update__.current_name(this.__cache__.current, this.__cache__.name);
|
||||||
|
}
|
||||||
|
this.onUpdate(__data__);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function table_sort_for0_if0() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [document.createTextNode(" exposure ")];
|
||||||
|
}
|
||||||
|
table_sort_for0_if0.prototype = Object.create(Monkberry.prototype);
|
||||||
|
table_sort_for0_if0.prototype.constructor = table_sort_for0_if0;
|
||||||
|
table_sort_for0_if0.pool = [];
|
||||||
|
table_sort_for0_if0.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function table_sort_for0_if2() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [document.createTextNode(" flash_on ")];
|
||||||
|
}
|
||||||
|
table_sort_for0_if2.prototype = Object.create(Monkberry.prototype);
|
||||||
|
table_sort_for0_if2.prototype.constructor = table_sort_for0_if2;
|
||||||
|
table_sort_for0_if2.pool = [];
|
||||||
|
table_sort_for0_if2.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
function table_sort_for0_if4() {
|
||||||
|
Monkberry.call(this);
|
||||||
|
|
||||||
|
// Set root nodes
|
||||||
|
this.nodes = [document.createTextNode(" school ")];
|
||||||
|
}
|
||||||
|
table_sort_for0_if4.prototype = Object.create(Monkberry.prototype);
|
||||||
|
table_sort_for0_if4.prototype.constructor = table_sort_for0_if4;
|
||||||
|
table_sort_for0_if4.pool = [];
|
||||||
|
table_sort_for0_if4.prototype.update = function (__data__) {
|
||||||
|
};
|
||||||
|
|
||||||
|
window.table_sort = table_sort;
|
||||||
|
//# sourceMappingURL=view.js.map
|
1
dist/view.js.map
vendored
Normal file
1
dist/view.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"sources":["class-list.monk","search-field.monk","spell-details.monk","spell-list.monk","table-sort.monk"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mEAAM,IAAN,C;AAAA,oE;;;;;;AAAA;AAAA;AAAA,K;AAAA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACI,kEAAc,IAAd,kB;;;;;;AAAA;AAAA;AAAA;AAAA,O;;;;;;;;;;;;;;;;;;;;;;;;;;EACI,6C;EACI,yC;;;;EAMI,2C;;;;;EAAM,4BAAO,mBAAP,E;;;EANL,2BAAO,+CAAP,E;;EADF,6BAAO,sBAAP,E;;;;;;AAEC,4EAAM,QAAQ,QAAR,CAAiB,GAAjB,CAAN,C;AAAA,6E;;;AAMI,0BAAG,G;;;;;;AANP;AAAA;AAAA,K;AAAA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EACI,6C;;;EAAO,sB;EAA4C,4BAAM,OAAN,E;EAAa,4BAAM,UAAN,E;EAAgB,6BAAO,mBAAP,E;;;;;AAAjE,qDAA4B,GAA5B,E;;;;;;;;;;;;;;;;;;;;;;;EAEf,6C;;;EAA2C,4BAAM,OAAN,E;EAAa,4BAAM,UAAN,E;EAAgB,6BAAO,mBAAP,E;;;;;AAAjE,qDAA4B,GAA5B,E;;;;;;;;;;;;;;;;;;;;;;;EASvB,yC;;;EAAK,2BAAO,sCAAP,E;;;;;;;;;;AAhBT;AAAA;;;;;;;;;ECAA,6C;;;EAA0B,6BAAO,sBAAP,E;EAA6B,8C;EAAmB,4BAAM,MAAN,E;EAAY,4BAAM,QAAN,E;EAAc,YAAI,yBAAJ,C;;;;;AAA7F,qBAAU,IAAV,C;;;;;;;;;;;;;;;AAAP;AAAA;;;;;;;;;;;;;;;;;;;;ACAA,sEAAM,KAAK,IAAX,C;AAAA,uE;;;;;;AAAA;AAAA;AAAA,K;AAAA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;;EACI,+C;EACE,qC;EAEF,uC;;EACA,qC;;EACA,yC;EACI,uC;EACI,uC;EACI,+C;;EAGJ,wC;EACI,gD;;EAGJ,wC;EACI,gD;;;;EAOR,wC;EACI,wC;EACI,gD;;EAGJ,wC;EACI,gD;;EAGJ,wC;EACI,gD;EACA,4C;;;;EAUR,0C;EACI,8C;EACI,sC;EAEJ,8C;;;;EA/CH,yBAAO,gBAAP,E;;EADG,gD;EAAuB,8BAAO,+DAAP,E;;EAG3B,0BAAO,oDAAP,E;EACD,yBAAO,aAAP,E;;;;;;;;;;;;;;EAEK,0BAAO,gCAAP,E;;;;;;;;;EA4BU,6BAAO,SAAP,E;;;;;;;EAXV,2BAAO,+BAAP,E;;EAuBO,0BAAO,gBAAP,E;;EADA,8BAAO,6DAAP,E;EAAoE,4BAAK,WAAL,E;EAAgB,8CAAuB,YAAvB,E;EAGpF,qC;EAAS,8BAAO,sBAAP,E;EAA6B,6BAAM,MAAN,E;EAAY,aAAI,WAAJ,C;;;EAJxD,4BAAO,gCAAP,E;;;;EAvCJ,2BAAO,UAAP,E;;;;;AAF0D,0BAAG,KAAK,I;AAChD,iCAAU,KAAK,WAAf,C;AAKX,0BAAG,KAAK,K;AAIR,2BAAG,KAAK,Y;AAIR,2BAAG,KAAK,Q;AAEZ,iEAAM,KAAK,MAAX,C;AAOI,2BAAG,KAAK,M;AAIR,2BAAG,MAAK,KAAL,gB;AAImB,2BAAG,KAAK,OAAL,CAAa,IAAb,CAAkB,IAAlB,C;AAE7B,iEAAM,MAAK,UAAL,0BAAN,C;;;AAYwE,sBAAU,GAAV,C;;;;;;AA7BxE;AAAA;AAAA,K;AAiBA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;;;;EAhBI,uC;;;;;;;;;;;;;;;;;;;;;EAiBA,uC;EACI,+C;;;;;;;;;;;AACA,0BAAG,KAAK,UAAL,CAAgB,G;;;;;;;;;;;;;;;;;;;;;;;EAanC,yC;EACI,uC;;;;EAAI,0BAAO,uBAAP,E;;EADH,UAAI,OAAJ,C;;;;;;;;;;AArDT;AAAA;;;;;;;;;;;;;;;;;;ACAA,mEAAM,KAAK,MAAX,C;AAAA,oE;;;;;;AAAA;AAAA;AAAA,K;AAAA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACI,kEAAgB,IAAhB,oB;;;;;;AAAA;AAAA;AAAA;AAAA,O;;;;;;;;;;;;;;;;;;;;;;;;EACI,uC;EACI,uC;EACI,+C;;EAIJ,uC;;EAGA,uC;;;;;;EARI,0BAAO,8CAAP,E;;EAKA,0BAAO,gDAAP,E;;EAGA,0BAAO,aAAP,E;;;;;;;;AANI,0BAAG,MAAM,I;AAIb,0BAAG,MAAM,M;AAGT,0BAAG,MAAM,W;AAVb,8CAAwB,MAAM,IAA9B,E;;;;;;;;;;;;;;;;;;;;;;;;EAeR,uC;EACI,uC;;;;;EAAI,4BAAS,GAAT,E;;EADJ,0BAAO,YAAP,E;;;;;;AAEI,wEAAM,IAAN,C;AAAA,yE;;;;;;AAAA;AAAA;AAAA,K;AAAA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;EACI,yC;EACI,qC;EAGA,uC;EACA,uC;;;;EAJG,yBAAO,+DAAP,E;;;;;;EADF,2BAAO,aAAP,E;;;;;;;;;;;;;;;;;;EAQL,yC;;;EAAK,2BAAO,sCAAP,E;;;;;;;;;;AA5BrB;AAAA;;;;;;;;;;;;;;;;ACAA,8DAAe,IAAf,mB;;;;;;AAAA;AAAA;AAAA;AAAA,O;;;;;;;;;;;;;;;;;;;;;;;;;;EACI,uC;EACI,qC;;;;;;;EAYA,2C;;EAIA,qC;;;;;;;EAhBG,yBAAO,oCAAP,E;;;;EAgBA,yBAAO,8DAAP,E;;;;EAjB2B,0BAAO,oCAAP,E;;;;;AAE1B,+DAAM,YAAS,OAAT,CAAN,C;AAGA,+DAAM,YAAS,MAAT,CAAN,C;AAGA,+DAAM,YAAS,QAAT,CAAN,C;AAMO,0BAAG,I;AAdd,2CAAqB,IAArB,E;;;AAkBI,0BAAG,QAAM,mBAAN,GAA4B,qB;;;AADhC,gCAAO,8DAAP,KAAsE,aAAS,OAAT,KAAmB,0BAAnB,GAAgD,0BAAtH,G;;;AAjB2B,iCAAO,oCAAP,KAA4C,gBAAY,SAAZ,KAAwB,qCAAxB,GAAgE,EAA5G,G;;;;;;AAE1B;AAAA;AAAA,K;AAGA;AAAA;AAAA,K;AAGA;AAAA;AAAA,K;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBANyB,qC;;;;;;;;;;;;;;;gBAGD,qC;;;;;;;;;;;;;;;gBAGE,mC;;;;;;;AATtC;AAAA","file":"view.js"}
|
81
index.html
Normal file
81
index.html
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>My Spells 5e</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||||
|
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.teal-pink.min.css" />
|
||||||
|
<link rel="stylesheet" href="./assets/app.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
|
||||||
|
<header class="mdl-layout__header">
|
||||||
|
<div class="mdl-layout__header-row">
|
||||||
|
<div class="mdl-layout-spacer"></div>
|
||||||
|
<nav class="mdl-navigation">
|
||||||
|
<a class="mdl-navigation__link" href="https://dark12222000.github.io/lootsplit/">
|
||||||
|
<i class="material-icons">local_atm</i>
|
||||||
|
Loot Split
|
||||||
|
</a>
|
||||||
|
<a class="mdl-navigation__link" href="http://paulvmoreau.github.io/BeltFedNPCs/">
|
||||||
|
<i class="material-icons">people</i>
|
||||||
|
NPC Generator
|
||||||
|
</a>
|
||||||
|
<a class="mdl-navigation__link mdl-color-text--teal-100" href="https://github.com/sharpshark28/my_spells">
|
||||||
|
<i class="material-icons">code</i>
|
||||||
|
Fork Me On Github
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<div data-action-details="" role="button" tabindex="0"><i class="material-icons">keyboard_arrow_left</i></div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<aside class="mdl-layout__drawer">
|
||||||
|
<span class="mdl-layout-title mdl-color-text--pink-600">
|
||||||
|
<i class="material-icons">whatshot</i>
|
||||||
|
My Spells
|
||||||
|
</span>
|
||||||
|
<nav class="mdl-navigation">
|
||||||
|
<form>
|
||||||
|
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||||
|
<div data-template="search-field"></div>
|
||||||
|
<label class="mdl-textfield__label" for="sample3">
|
||||||
|
<i class="material-icons">search</i>
|
||||||
|
Search
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form data-template="class-list">
|
||||||
|
</form>
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
<main class="mdl-layout__content">
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="mdl-grid">
|
||||||
|
<table id="spell-list-container" class="mdl-cell mdl-cell--12-col mdl-cell--6-col-desktop mdl-data-table mdl-shadow--2dp">
|
||||||
|
<thead>
|
||||||
|
<tr data-template="table-sort"></tr>
|
||||||
|
</thead>
|
||||||
|
<tbody data-template="spell-list"></tbody>
|
||||||
|
</table>
|
||||||
|
<article data-template="spell-details" class="mdl-cell mdl-cell--12-col mdl-cell--6-col-desktop mdl-color-text--grey-600"></article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div id="toast" class="mdl-js-snackbar mdl-snackbar">
|
||||||
|
<div class="mdl-snackbar__text"></div>
|
||||||
|
<button class="mdl-snackbar__action" type="button"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://code.getmdl.io/1.1.3/material.min.js"></script>
|
||||||
|
<script src="./node_modules/jquery/dist/jquery.min.js"></script>
|
||||||
|
<script src="./node_modules/monkberry/monkberry.js"></script>
|
||||||
|
<script src="./node_modules/clipboard/dist/clipboard.min.js"></script>
|
||||||
|
<script src="./dist/view.js"></script>
|
||||||
|
<script src="./dist/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
21
package.json
21
package.json
|
@ -3,11 +3,26 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "5e Spells by Class",
|
"description": "5e Spells by Class",
|
||||||
"main": "",
|
"main": "",
|
||||||
|
"watch": {
|
||||||
|
"views": "views/*.monk"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"views": "monkberry src/views/*.monk --source-map --output dist/view.js",
|
||||||
|
"js": "babel src/app.js --out-file dist/app.js",
|
||||||
|
"develop": "nodemon --watch src -e monk,js --exec 'npm run views && npm run js'"
|
||||||
},
|
},
|
||||||
"author": "Joe Wroten <sharpshark28@gmail.com>",
|
"author": "Joe Wroten <sharpshark28@gmail.com>",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {},
|
"devDependencies": {
|
||||||
"dependencies": {}
|
"babel-cli": "^6.11.4",
|
||||||
|
"babel-plugin-transform-runtime": "^6.12.0",
|
||||||
|
"babel-preset-es2017": "^1.6.1",
|
||||||
|
"nodemon": "^1.10.0",
|
||||||
|
"npm-watch": "^0.1.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"clipboard": "^1.5.12",
|
||||||
|
"jquery": "^3.1.0",
|
||||||
|
"monkberry": "^4.0.7"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
.has-tooltip {
|
|
||||||
cursor: help;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mdl-dialog.card {
|
|
||||||
width: 500px;
|
|
||||||
padding: 0;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mdl-dialog .mdl-card {
|
|
||||||
overflow: visible;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*.mdl-dialog [data-id-spelldetail=description] {*/
|
|
||||||
/*max-height: 3.5em;*/
|
|
||||||
/*overflow-y: scroll;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
#spell-list [data-action-dialog] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#class-list label span {
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left.clear {
|
|
||||||
clear: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right.clear {
|
|
||||||
clear: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-id-spelldetail="components"] {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-id-spelldetail="components"] li:not(:last-of-type) {
|
|
||||||
padding-right: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-id-spelldetail="components"] li:not(:last-of-type)::after {
|
|
||||||
content: ','
|
|
||||||
}
|
|
283
public/app.js
283
public/app.js
|
@ -1,283 +0,0 @@
|
||||||
/**
|
|
||||||
* Capitalize Helper
|
|
||||||
**/
|
|
||||||
let capitalize = str => str ? str.charAt(0).toUpperCase() + str.slice(1) : '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tooltip Counter
|
|
||||||
*/
|
|
||||||
let tooltipCount = 1;
|
|
||||||
let tooltipCounter = () => tooltipCount++;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Discover Classes
|
|
||||||
*/
|
|
||||||
const DISCOVERCLASSES = spells => {
|
|
||||||
let classes = [];
|
|
||||||
spells.forEach(spell => {
|
|
||||||
if (!spell.classes) return;
|
|
||||||
spell.classes.forEach(current => {
|
|
||||||
if (!classes.includes(current)) classes.push(current);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
classes = classes.sort((a, b) => a > b);
|
|
||||||
return {spells, classes}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dom Helper
|
|
||||||
*/
|
|
||||||
const DOMHELPER = {
|
|
||||||
emphasis (str) {
|
|
||||||
let keywords = ['intelligence', 'int', 'wisdom', 'wis', 'strength', 'str', 'dexterity', 'dex', 'charisma', 'cha', 'comeliness', 'com', 'saving throw', 'ability check', 'skill check'];
|
|
||||||
keywords.forEach(word => {
|
|
||||||
let r = new RegExp(` ${word} `, 'gi');
|
|
||||||
str = str.replace(r, o => `<em class="mdl-color-text--teal-600">${o}</em>`);
|
|
||||||
});
|
|
||||||
|
|
||||||
str = str.replace(/[\s()<>]+\d+d*\d*(th)*[\s()<>]+/gi, o => `<strong>${o}</strong>`);
|
|
||||||
return str;
|
|
||||||
},
|
|
||||||
level (lvl) {
|
|
||||||
let cantrip = lvl.toLowerCase() === 'cantrip';
|
|
||||||
let invalid = isNaN(lvl) && !cantrip;
|
|
||||||
if (invalid) return '?';
|
|
||||||
else return cantrip ? 'C' : lvl;
|
|
||||||
},
|
|
||||||
components (components) {
|
|
||||||
let dom = '';
|
|
||||||
let types = ['verbal', 'somatic', 'material'];
|
|
||||||
let typesDescriptions = [
|
|
||||||
'Spoken word/prayer. Mouth must be free and not mute.',
|
|
||||||
'Physical gestures, usually hand movements. Must not be bound.',
|
|
||||||
'Items consumed upon casting spell.'
|
|
||||||
];
|
|
||||||
|
|
||||||
types.forEach((type, i) => {
|
|
||||||
if (!!components[type]) {
|
|
||||||
let currentTooltip = tooltipCounter();
|
|
||||||
dom += `
|
|
||||||
<li class="left has-tooltip" id="tooltip-${currentTooltip}">${types[i].charAt(0).toUpperCase()}</li>
|
|
||||||
<label class="mdl-tooltip" for="tooltip-${currentTooltip}">
|
|
||||||
<strong>${capitalize(type)}</strong><br />
|
|
||||||
${typesDescriptions[i]}
|
|
||||||
</label>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return dom;
|
|
||||||
},
|
|
||||||
classes (classes) {
|
|
||||||
let dom = '';
|
|
||||||
classes.forEach(x => {
|
|
||||||
dom += `<a>${capitalize(x)}</a> `;
|
|
||||||
});
|
|
||||||
return dom;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of Selected Spells
|
|
||||||
*/
|
|
||||||
const SELECTEDSPELLS = () => $('#form-spells').serializeArray().map(spell => parseInt(spell.value));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add Spells to Page
|
|
||||||
*/
|
|
||||||
const RENDERSPELLS = (x) => {
|
|
||||||
let dom = '';
|
|
||||||
let spells = x ? x.spells.slice(0) : data;
|
|
||||||
spells = CLASSSPELLS(spells);
|
|
||||||
spells = SEARCHSPELLS(spells);
|
|
||||||
spells = spells.sort((a, b) => b.ranking - a.ranking);
|
|
||||||
spells.forEach(spell => {
|
|
||||||
let el = $('#spell-item').html();
|
|
||||||
let $el = $(el);
|
|
||||||
|
|
||||||
$('[data-id-spellitem=level]', $el)[0].innerHTML
|
|
||||||
= DOMHELPER.level(spell.level);
|
|
||||||
$('[data-id-spellitem=name]', $el)[0].innerHTML
|
|
||||||
= spell.name;
|
|
||||||
$('[data-id-spellitem=school]', $el)[0].innerHTML
|
|
||||||
= capitalize(spell.school);
|
|
||||||
$('[data-id-spellitem=checkbox]', $el).attr('value', spell.id).attr('id', `sel-${spell.id}`);
|
|
||||||
$('[data-id-spellitem=checklabel]', $el).attr('for', `sel-${spell.id}`);
|
|
||||||
$el.attr('data-action-dialog', spell.id);
|
|
||||||
|
|
||||||
dom += $el.prop('outerHTML');
|
|
||||||
});
|
|
||||||
$('#spell-list').html(dom);
|
|
||||||
componentHandler.upgradeDom();
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render Spell Details to Dialog
|
|
||||||
*/
|
|
||||||
const RENDERSPELLDIALOG = spell => {
|
|
||||||
let el = $('#spell-detail').html();
|
|
||||||
let $el = $(`<div>${el}</div>`);
|
|
||||||
|
|
||||||
$('[data-id-spelldetail=name]', $el)[0].innerHTML
|
|
||||||
= spell.name;
|
|
||||||
$('[data-action-select]', $el).attr('data-action-select', spell.id);
|
|
||||||
$('[data-action-select] input[type="checkbox"]', $el).attr('checked', SELECTEDSPELLS().includes(spell.id));
|
|
||||||
if (spell.description) {
|
|
||||||
$('[data-id-spelldetail=description]', $el)[0].innerHTML
|
|
||||||
= DOMHELPER.emphasis(spell.description);
|
|
||||||
}
|
|
||||||
if (spell.tags) {
|
|
||||||
$('[data-id-spelldetail=classes]', $el)[0].innerHTML
|
|
||||||
= DOMHELPER.classes(spell.classes);
|
|
||||||
}
|
|
||||||
if (spell.components) {
|
|
||||||
$('[data-id-spelldetail=components]', $el)[0].innerHTML
|
|
||||||
= DOMHELPER.components(spell.components);
|
|
||||||
}
|
|
||||||
if (spell.components.materials_needed) {
|
|
||||||
$('[data-id-spelldetail=materials]', $el)[0].innerHTML
|
|
||||||
= spell.components.materials_needed.join(', ');
|
|
||||||
}
|
|
||||||
if (spell.level) {
|
|
||||||
$('[data-id-spelldetail=level]', $el)[0].innerHTML
|
|
||||||
= 'Level ' + spell.level;
|
|
||||||
}
|
|
||||||
if (spell.duration) {
|
|
||||||
$('[data-id-spelldetail=duration]', $el)[0].innerHTML
|
|
||||||
= spell.duration;
|
|
||||||
}
|
|
||||||
if (spell.casting_time) {
|
|
||||||
$('[data-id-spelldetail=castingtime]', $el)[0].innerHTML
|
|
||||||
= spell.casting_time;
|
|
||||||
}
|
|
||||||
if (spell.range) {
|
|
||||||
$('[data-id-spelldetail=range]', $el)[0].innerHTML
|
|
||||||
= spell.range;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#spell-detail-container').html($el.prop('outerHTML'));
|
|
||||||
componentHandler.upgradeDom();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch Classes from Spells
|
|
||||||
*/
|
|
||||||
const RENDERCLASSES = data => {
|
|
||||||
let dom = '';
|
|
||||||
data.classes.forEach(item => {
|
|
||||||
let el = $('#class-toggle').html();
|
|
||||||
let $el = $(el);
|
|
||||||
|
|
||||||
$('[data-action-classtoggle]', $el).attr('value', item);
|
|
||||||
$('[data-id-classtoggle=name]', $el)[0].innerHTML = item;
|
|
||||||
dom += $el.prop('outerHTML');
|
|
||||||
});
|
|
||||||
$('#class-list').html(dom);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
const SEARCHSPELLS = (spells, search = $('[data-action-search]').val()) => {
|
|
||||||
search = search.toLowerCase();
|
|
||||||
if (search.length >= 3) {
|
|
||||||
spells = spells.filter(spell => {
|
|
||||||
let regFind = new RegExp(search, 'gi');
|
|
||||||
let spellName = spell.name.toLowerCase();
|
|
||||||
let spellDescription = spell.description ? spell.description.toLowerCase() : '';
|
|
||||||
let spellMaterials = spell.components && spell.components.materials_needed || [];
|
|
||||||
|
|
||||||
let matches = 0
|
|
||||||
+ spellName.indexOf(search) > -1 ? 20 : 0
|
|
||||||
+ (spellDescription.match(regFind) || []).length
|
|
||||||
+ (spellMaterials).filter(com => com.indexOf(search) > -1).length * 10;
|
|
||||||
|
|
||||||
spell.ranking = matches;
|
|
||||||
return spell.ranking > 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return spells;
|
|
||||||
};
|
|
||||||
|
|
||||||
const CLASSSPELLS = (spells, classes) => {
|
|
||||||
classes = classes || $('#class-list').serializeArray().map(x => x.value);
|
|
||||||
return classes.length ? spells.filter(spell => {
|
|
||||||
for(let i = 0; i < classes.length; i++) {
|
|
||||||
if (spell.classes.indexOf(classes[i]) >= 0) return true;
|
|
||||||
}
|
|
||||||
}) : spells;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve Spells
|
|
||||||
*/
|
|
||||||
let data;
|
|
||||||
|
|
||||||
fetch('./spells.json')
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(spells => spells.map((spell, i) => {
|
|
||||||
spell.id = i;
|
|
||||||
spell.ranking = 0; // Default to equal ranking
|
|
||||||
return spell;
|
|
||||||
}))
|
|
||||||
.then(spells => data = spells)
|
|
||||||
.then(spells => DISCOVERCLASSES(spells))
|
|
||||||
.then(data => RENDERCLASSES(data))
|
|
||||||
.then(data => RENDERSPELLS(data))
|
|
||||||
.catch(reason => console.error('Unable to retrieve spells list:', reason));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Details Popup
|
|
||||||
*/
|
|
||||||
let $dialog = $('dialog');
|
|
||||||
|
|
||||||
if (!$dialog[0].showModal) {
|
|
||||||
dialogPolyfill.registerDialog($dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#spell-list').on('click', '[data-action-dialog]', e => {
|
|
||||||
let id = $(e.target).closest('tr').data('action-dialog');
|
|
||||||
RENDERSPELLDIALOG(data[id]);
|
|
||||||
$dialog[0].showModal();
|
|
||||||
}).on('click', '.dontprop', e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
$dialog.on('click', '[data-action-close]', () => {
|
|
||||||
$dialog[0].close();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bind Checkbox Selection Action
|
|
||||||
*/
|
|
||||||
$('body').on('change', '[data-action-select] input', e => {
|
|
||||||
let id = $(e.target).closest('label').attr('data-action-select');
|
|
||||||
if (id) $('#sel-' + id).click();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bind Toggle All Checkbox
|
|
||||||
*/
|
|
||||||
$('label[for=table-header]').on('change', 'input[type="checkbox"]', e => {
|
|
||||||
$(e.target).closest('form').find('[data-id-spellitem=checkbox]').each(function() {
|
|
||||||
this.checked = e.target.checked;
|
|
||||||
if(this.checked) $(this).closest('label').addClass('is-checked');
|
|
||||||
else $(this).closest('label').removeClass('is-checked');
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bind Class Filter Switches
|
|
||||||
*/
|
|
||||||
$('body').on('change', '[data-action-classtoggle]', e => {
|
|
||||||
RENDERSPELLS();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search
|
|
||||||
*/
|
|
||||||
$('body').on('change keyup cut paste', '[data-action-search]', e => {
|
|
||||||
setTimeout(function() {
|
|
||||||
RENDERSPELLS();
|
|
||||||
}, 0);
|
|
||||||
});
|
|
|
@ -1,134 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>My Spells 5e</title>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:300,400,500,700" type="text/css">
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
|
||||||
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.teal-pink.min.css" />
|
|
||||||
<link rel="stylesheet" href="./app.css" />
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
|
|
||||||
<header class="mdl-layout__header">
|
|
||||||
<div class="mdl-layout__header-row">
|
|
||||||
<div class="mdl-layout-spacer"></div>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable mdl-textfield--floating-label mdl-textfield--align-right">
|
|
||||||
<label class="mdl-button mdl-js-button mdl-button--icon" for="fixed-header-drawer-exp">
|
|
||||||
<i class="material-icons">search</i>
|
|
||||||
</label>
|
|
||||||
<div class="mdl-textfield__expandable-holder">
|
|
||||||
<input class="mdl-textfield__input" data-action-search type="text" name="sample" id="fixed-header-drawer-exp" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<aside class="mdl-layout__drawer">
|
|
||||||
<span class="mdl-layout-title">My Spells</span>
|
|
||||||
<nav class="mdl-navigation">
|
|
||||||
<form id="class-list">
|
|
||||||
</form>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<main class="mdl-layout__content">
|
|
||||||
<div class="page-content">
|
|
||||||
<form id="form-spells">
|
|
||||||
<table class="mdl-data-table mdl-shadow--2dp">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect mdl-data-table__select" for="table-header">
|
|
||||||
<input type="checkbox" id="table-header" class="mdl-checkbox__input" />
|
|
||||||
</label>
|
|
||||||
</th>
|
|
||||||
<th>Level</th>
|
|
||||||
<th class="mdl-data-table__cell--non-numeric">Name</th>
|
|
||||||
<th class="mdl-data-table__cell--non-numeric">School</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="spell-list">
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<div id="loader" class="mdl-spinner mdl-js-spinner is-active"></div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<dialog class="mdl-dialog card">
|
|
||||||
<article id="spell-detail-container"></article>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- SPELL DETAILS -->
|
|
||||||
<script id="spell-detail" type="x-template">
|
|
||||||
<div class="mdl-card">
|
|
||||||
<div class="mdl-card__title mdl-color--pink-600 mdl-color-text--white">
|
|
||||||
<h2 class="mdl-card__title-text" data-id-spelldetail="name"></h2>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-card__supporting-text">
|
|
||||||
<p data-id-spelldetail="classes"></p>
|
|
||||||
<p data-id-spelldetail="description"></p>
|
|
||||||
|
|
||||||
<div class="left">
|
|
||||||
<div data-id-spelldetail="level"></div>
|
|
||||||
<div data-id-spelldetail="castingtime"></div>
|
|
||||||
<div data-id-spelldetail="duration"></div>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<div class="right" data-id-spelldetail="range"></div>
|
|
||||||
<ul class="right clear" data-id-spelldetail="components"></ul>
|
|
||||||
<div class="clear" data-id-spelldetail="materials"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-card__menu">
|
|
||||||
<button data-action-close class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
|
|
||||||
<i class="material-icons mdl-color-text--white">close</i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<footer class="mdl-card__actions mdl-card--border">
|
|
||||||
<label data-action-select class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect">
|
|
||||||
<input type="checkbox" class="mdl-checkbox__input">
|
|
||||||
</label>
|
|
||||||
<!--<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">-->
|
|
||||||
<!--TODO-->
|
|
||||||
<!--</a>-->
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- SPELL -->
|
|
||||||
<script id="spell-item" type="x-template">
|
|
||||||
<tr data-action-dialog>
|
|
||||||
<td>
|
|
||||||
<label data-id-spellitem="checklabel" class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect mdl-data-table__select dontprop">
|
|
||||||
<input type="checkbox" name="id" value="" data-id-spellitem="checkbox" class="mdl-checkbox__input dontprop" />
|
|
||||||
</label>
|
|
||||||
</td>
|
|
||||||
<td data-id-spellitem="level"></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
<strong data-id-spellitem="name"></strong>
|
|
||||||
</td>
|
|
||||||
<td data-id-spellitem="school" class="mdl-data-table__cell--non-numeric"></td>
|
|
||||||
</tr>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script id="class-toggle" type="x-template">
|
|
||||||
<label class="mdl-navigation__link">
|
|
||||||
<div class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
|
||||||
<input data-action-classtoggle name="class" type="checkbox" class="mdl-switch__input">
|
|
||||||
<span data-id-classtoggle="name" class="mdl-switch__label"></span>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script src="https://code.getmdl.io/1.1.3/material.min.js"></script>
|
|
||||||
<script src="https://code.jquery.com/jquery-3.0.0.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script>
|
|
||||||
<script src="./app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
1
public/redux.min.js
vendored
1
public/redux.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,18 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
let newSpells = [];
|
|
||||||
let spells = require('./spells.json');
|
|
||||||
//spells.forEach(spell => {
|
|
||||||
//if (spell.tags) {
|
|
||||||
//spell.classes = [];
|
|
||||||
//spell.tags.forEach(tag => {
|
|
||||||
//let classes = ['cleric', 'fighter', 'rogue', 'wizard', 'barbarian', 'bard', 'druid', 'monk', 'paladin', 'ranger', 'sorcerer', 'warlock'];
|
|
||||||
//classes.forEach(x => {
|
|
||||||
//if (tag.indexOf(x) > -1) spell.classes.push(x);
|
|
||||||
//});
|
|
||||||
//});
|
|
||||||
//}
|
|
||||||
//newSpells.push(spell);
|
|
||||||
//});
|
|
||||||
|
|
||||||
require('fs').writeFileSync('./newSpells.json', JSON.stringify(newSpells));
|
|
BIN
src/.DS_Store
vendored
Normal file
BIN
src/.DS_Store
vendored
Normal file
Binary file not shown.
293
src/app.js
Normal file
293
src/app.js
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
/**
|
||||||
|
* Misc helper functions
|
||||||
|
*/
|
||||||
|
Object.values = x =>
|
||||||
|
Object.keys(x).reduce((y, z) =>
|
||||||
|
y.push(x[z]) && y, []);
|
||||||
|
const debounce = (func, wait, immediate) => {
|
||||||
|
let timeout;
|
||||||
|
return function() {
|
||||||
|
let context = this, args = arguments;
|
||||||
|
let later = function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) func.apply(context, args);
|
||||||
|
};
|
||||||
|
let callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) func.apply(context, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const el = id => $(`[data-template=${id}]`)[0] || console.error('Unable to render to', id);
|
||||||
|
const clone = obj => JSON.parse(JSON.stringify(obj));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global store and view holders
|
||||||
|
*/
|
||||||
|
let store = {};
|
||||||
|
let view = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init Local Storage
|
||||||
|
*/
|
||||||
|
const localStorageDefault = (key, val) => {
|
||||||
|
if (localStorage.getItem(key) === null) localStorage.setItem(key, val);
|
||||||
|
};
|
||||||
|
let defaults = {
|
||||||
|
tableSortName: 'name',
|
||||||
|
tableSortRev: false,
|
||||||
|
classes: [],
|
||||||
|
search: ''
|
||||||
|
};
|
||||||
|
for (let cur in defaults) localStorageDefault(cur, defaults[cur]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Table Sort
|
||||||
|
*/
|
||||||
|
store.tableSort = {
|
||||||
|
data: ['name', 'school', 'level'],
|
||||||
|
current: localStorage.getItem('tableSortName'),
|
||||||
|
rev: localStorage.getItem('tableSortRev') !== 'false'
|
||||||
|
};
|
||||||
|
view.table_sort = Monkberry.render(table_sort, el('table-sort'));
|
||||||
|
view.table_sort.update(store.tableSort);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Spell List
|
||||||
|
*/
|
||||||
|
view.spell_list = Monkberry.render(spell_list, el('spell-list'));
|
||||||
|
view.spell_list.update({});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Spell Details
|
||||||
|
*/
|
||||||
|
view.spell_details = Monkberry.render(spell_details, el('spell-details'));
|
||||||
|
view.spell_details.update({data: {}});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Class List
|
||||||
|
*/
|
||||||
|
store.classes = {
|
||||||
|
data: [],
|
||||||
|
current: localStorage.getItem('classes') ? localStorage.getItem('classes').split(',') : []
|
||||||
|
};
|
||||||
|
view.class_list = Monkberry.render(class_list, el('class-list'));
|
||||||
|
view.class_list.update(store.classes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Search
|
||||||
|
*/
|
||||||
|
store.search = localStorage.getItem('search');
|
||||||
|
view.search_field = Monkberry.render(search_field, el('search-field'));
|
||||||
|
view.search_field.update({data: store.search});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discover Classes
|
||||||
|
*/
|
||||||
|
const discoverClasses = spells => {
|
||||||
|
let classes = [];
|
||||||
|
spells.forEach(spell => {
|
||||||
|
if (!spell.classes) return;
|
||||||
|
spell.classes.forEach(current => {
|
||||||
|
if (!classes.includes(current)) classes.push(current);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return classes.sort((a, b) => a > b);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emphasis on important string bits
|
||||||
|
* @param {string} string
|
||||||
|
*/
|
||||||
|
const emphasis = str => {
|
||||||
|
let keywords = ['constitution', 'con', 'intelligence', 'int', 'wisdom', 'wis', 'strength', 'str', 'dexterity', 'dex', 'charisma', 'cha', 'comeliness', 'com', 'saving throw', 'ability check', 'skill check'];
|
||||||
|
keywords.forEach(word => {
|
||||||
|
let r = new RegExp(` ${word} `, 'gi');
|
||||||
|
str = str.replace(r, o => `<em class="mdl-color-text--teal-600">${o}</em>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
str = str.replace(/[\s()<>]+\d+d*\d*(th)*[\s()<>]+/gi, o => `<strong>${o}</strong>`);
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init Spells
|
||||||
|
*/
|
||||||
|
const initSpells = s => s.map((spell, i) => {
|
||||||
|
spell.selected = false;
|
||||||
|
spell.ranking = 0;
|
||||||
|
spell.level = parseInt(spell.level) ? spell.level : 0;
|
||||||
|
spell.prettyLevel = spell.level === 0 ? 'C' : spell.level;
|
||||||
|
return spell;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort Spells
|
||||||
|
*/
|
||||||
|
const sortSpells = (s, sortBy, reverse) => s.sort((a, b) => {
|
||||||
|
let hasFilters = store.classes.current.length || store.search.length;
|
||||||
|
let by = sortBy || hasFilters ? 'ranking' : store.tableSort.current;
|
||||||
|
let rev = reverse || hasFilters ? false : store.tableSort.rev;
|
||||||
|
if (by) {
|
||||||
|
if (a[by] < b[by]) return rev ? 1 : -1;
|
||||||
|
if (a[by] > b[by]) return rev ? -1 : 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search Spells
|
||||||
|
* @param {Array} spells
|
||||||
|
* @param {String} ex 'acid spray'
|
||||||
|
* @return {Array} filtered spells
|
||||||
|
*/
|
||||||
|
const searchSpells = (spells, search) => {
|
||||||
|
// Convert search to array of words
|
||||||
|
search = search.split(' ');
|
||||||
|
// Clone spells so we don't affect the original
|
||||||
|
spells = clone(spells);
|
||||||
|
// Reset rankings
|
||||||
|
spells = spells.map(s => {
|
||||||
|
s.ranking = 0;
|
||||||
|
return s;
|
||||||
|
});
|
||||||
|
// Rank spells by # of occurances of search terms
|
||||||
|
spells = spells.map(spell => {
|
||||||
|
search.forEach(term => {
|
||||||
|
let spellText = Object.values(spell).join(' ');
|
||||||
|
let regFind = new RegExp(term, 'gi');
|
||||||
|
spell.ranking += (spellText.match(regFind) || []).length;
|
||||||
|
});
|
||||||
|
return spell;
|
||||||
|
});
|
||||||
|
// Return spells that matched at least something
|
||||||
|
return spells.filter(spell => spell.ranking);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter Spells by Class
|
||||||
|
*/
|
||||||
|
const filterSpellsByClass = (spells, classes) => {
|
||||||
|
// If no classes, default to all classes
|
||||||
|
classes = classes.length ? classes : store.classes.data;
|
||||||
|
// Clone spells so we don't affect the original
|
||||||
|
spells = clone(spells);
|
||||||
|
return spells.filter(spell => {
|
||||||
|
let spellClasses = spell.classes.join(' ');
|
||||||
|
let match = false;
|
||||||
|
classes.forEach(c => {
|
||||||
|
if (spellClasses.indexOf(c) >= 0) {
|
||||||
|
match = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply Filters
|
||||||
|
* @returns {Array} of spells ranked based on searches and filters
|
||||||
|
*/
|
||||||
|
let applyFilters = () => sortSpells(
|
||||||
|
searchSpells(
|
||||||
|
filterSpellsByClass(
|
||||||
|
store.spells,
|
||||||
|
store.classes.current
|
||||||
|
),
|
||||||
|
store.search
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spell Details Updating
|
||||||
|
*/
|
||||||
|
const spellDetails = name => {
|
||||||
|
if (!name) {
|
||||||
|
view.spell_details.update({data: {}});
|
||||||
|
$('body').removeClass('details');
|
||||||
|
} else {
|
||||||
|
let data = store.spells.find(spell => name === spell.name);
|
||||||
|
data.description = emphasis(data.description);
|
||||||
|
view.spell_details.update({
|
||||||
|
data,
|
||||||
|
url: window.location.href
|
||||||
|
});
|
||||||
|
$('body').addClass('details');
|
||||||
|
let clipboard = new Clipboard('.copy-to-clipboard');
|
||||||
|
clipboard
|
||||||
|
.on('success', e => $('#toast')[0].MaterialSnackbar.showSnackbar({message: 'Copied link'}))
|
||||||
|
.on('error', e => $('#toast')[0].MaterialSnackbar.showSnackbar({message: 'Sorry! Unable to copy link'}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Event Bindings
|
||||||
|
*/
|
||||||
|
// Listen for header sorts
|
||||||
|
$('body').on('click', '[data-action-sort]', e => {
|
||||||
|
let name = $(e.currentTarget).attr('data-action-sort');
|
||||||
|
let rev = store.tableSort.current === name && !store.tableSort.rev;
|
||||||
|
store.tableSort.current = name;
|
||||||
|
store.tableSort.rev = rev;
|
||||||
|
localStorage.setItem('tableSortName', name);
|
||||||
|
localStorage.setItem('tableSortRev', rev);
|
||||||
|
view.spell_list.update({data: sortSpells(store.spells)});
|
||||||
|
view.table_sort.update(store.tableSort);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for checkbox changes to filter spells
|
||||||
|
$('body').on('change', '[data-action-classtoggle]', e => {
|
||||||
|
let name = $(e.currentTarget).attr('data-action-classtoggle');
|
||||||
|
let add = $(e.currentTarget).prop('checked');
|
||||||
|
let index = store.classes.current.indexOf(name);
|
||||||
|
if (index === -1 && add) {
|
||||||
|
store.classes.current.push(name);
|
||||||
|
} else if (!add) store.classes.current.splice(index, 1);
|
||||||
|
store.tableSort.current = store.classes.current.length || store.search.length ? 'ranking' : null;
|
||||||
|
localStorage.setItem('tableSortName', store.tableSort.current);
|
||||||
|
localStorage.setItem('classes', store.classes.current);
|
||||||
|
view.spell_list.update({data: applyFilters()});
|
||||||
|
view.table_sort.update({current: store.tableSort.current});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen to search to filter by
|
||||||
|
$('body').on('change keyup cut paste', '[data-action-search]', e => {
|
||||||
|
setTimeout(() => { // Delay for value to change
|
||||||
|
store.search = $(e.currentTarget).val();
|
||||||
|
store.tableSort.current = store.search.length || store.classes.current.length ? 'ranking' : null;
|
||||||
|
store.tableSort.rev = false;
|
||||||
|
localStorage.setItem('search', store.search);
|
||||||
|
localStorage.setItem('tableSortName', store.tableSort.current);
|
||||||
|
localStorage.setItem('tableSortRev', store.tableSort.rev);
|
||||||
|
view.spell_list.update({data: applyFilters()});
|
||||||
|
view.table_sort.update(store.tableSort);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for click on spells to open details
|
||||||
|
$('body').on('click', '[data-action-details]', e => {
|
||||||
|
let name = $(e.currentTarget).attr('data-action-details');
|
||||||
|
window.location.hash = name;
|
||||||
|
spellDetails(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Article Scroll with User
|
||||||
|
$('.mdl-layout__content').on('scroll', debounce(() => {
|
||||||
|
let distance = $('.mdl-layout__content')[0].scrollTop;
|
||||||
|
$('[data-template=spell-details]').css('margin-top', distance);
|
||||||
|
}, 10));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch Spells
|
||||||
|
*/
|
||||||
|
fetch('./spells.json')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(spells => initSpells(spells))
|
||||||
|
.then(spells => {
|
||||||
|
store.spells = spells;
|
||||||
|
store.classes.data = discoverClasses(spells);
|
||||||
|
view.spell_list.update({data: applyFilters()});
|
||||||
|
view.class_list.update(store.classes);
|
||||||
|
if (window.location.hash) spellDetails(window.location.hash.substr(1));
|
||||||
|
})
|
||||||
|
.catch(reason => console.error('Unable to retrieve spells list:', reason));
|
19
src/views/class-list.monk
Normal file
19
src/views/class-list.monk
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{% if data %}
|
||||||
|
{% for cur of data %}
|
||||||
|
<label class="mdl-navigation__link">
|
||||||
|
<div class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
|
{% if current.includes(cur) %}
|
||||||
|
<input checked data-action-classtoggle="{{ cur }}" name="class" type="checkbox" class="mdl-switch__input" />
|
||||||
|
{% else %}
|
||||||
|
<input data-action-classtoggle="{{ cur }}" name="class" type="checkbox" class="mdl-switch__input" />
|
||||||
|
{% endif %}
|
||||||
|
<span class="mdl-switch__label">
|
||||||
|
{{ cur }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="mdl-spinner mdl-js-spinner is-active"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
1
src/views/search-field.monk
Normal file
1
src/views/search-field.monk
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<input value="{{ data }}" class="mdl-textfield__input" data-action-search type="text" name="sample" id="fixed-header-drawer-exp" />
|
59
src/views/spell-details.monk
Normal file
59
src/views/spell-details.monk
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
{% if data.name %}
|
||||||
|
<button data-action-details="" class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab">
|
||||||
|
<i class="material-icons">close</i>
|
||||||
|
</button>
|
||||||
|
<h5 class="mdl-typography--display-1 mdl-color-text--teal-600">{{ data.name }}</h5>
|
||||||
|
<p class="description">{% unsafe data.description %}</p>
|
||||||
|
<div class="mdl-grid">
|
||||||
|
<ul class="right mdl-cell mdl-cell--6-col">
|
||||||
|
<li>
|
||||||
|
<strong>Range: </strong>
|
||||||
|
{{ data.range }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Casting Time: </strong>
|
||||||
|
{{ data.casting_time }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Duration: </strong>
|
||||||
|
{{ data.duration }}
|
||||||
|
</li>
|
||||||
|
{% if data.ritual %}
|
||||||
|
<li>Ritual</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
<ul class="left mdl-cell mdl-cell--6-col">
|
||||||
|
<li>
|
||||||
|
<strong>School: </strong>
|
||||||
|
{{ data.school }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Spell Level: </strong>
|
||||||
|
{{ data.level || 'Cantrip' }}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Class: </strong>
|
||||||
|
<span class="classes">{{ data.classes.join(', ') }}</span>
|
||||||
|
</li>
|
||||||
|
{% if data.components && data.components.raw %}
|
||||||
|
<li>
|
||||||
|
<strong>Components: </strong>
|
||||||
|
{{ data.components.raw }}
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="mdl-textfield mdl-js-textfield">
|
||||||
|
<label class="mdl-button mdl-js-button mdl-button--icon copy-to-clipboard" for="share-url" data-clipboard-target="#share-url">
|
||||||
|
<i class="material-icons">content_copy</i>
|
||||||
|
</label>
|
||||||
|
<input readonly class="mdl-textfield__input" type="text" id="share-url" value="{{ url }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div id="empty">
|
||||||
|
<h6 class="mdl-typography--title">
|
||||||
|
Choose a Spell
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
33
src/views/spell-list.monk
Normal file
33
src/views/spell-list.monk
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{% if data.length %}
|
||||||
|
{% for spell of data %}
|
||||||
|
<tr data-action-details="{{ spell.name }}">
|
||||||
|
<td class="spell-name mdl-data-table__cell--non-numeric">
|
||||||
|
<strong>
|
||||||
|
{{ spell.name }}
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
<td class="spell-school mdl-data-table__cell--non-numeric">
|
||||||
|
{{ spell.school }}
|
||||||
|
</td>
|
||||||
|
<td class="spell-level">
|
||||||
|
{{ spell.prettyLevel }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<tr class="do-nothing">
|
||||||
|
<td colspan="4">
|
||||||
|
{% if data %}
|
||||||
|
<div class="text-center">
|
||||||
|
<i class="material-icons mdl-list__item-icon mdl-color-text--orange-600">
|
||||||
|
warning
|
||||||
|
</i>
|
||||||
|
<h5>No Results</h5>
|
||||||
|
<h6>Try refining your filters in the sidebar.</h6>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="mdl-spinner mdl-js-spinner is-active"></div>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
23
src/views/table-sort.monk
Normal file
23
src/views/table-sort.monk
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{% for name of data %}
|
||||||
|
<th data-action-sort="{{ name }}" class="mdl-data-table__cell--non-numeric {{ current === 'ranking' ? 'mdl-color-text--grey-200 do-nothing' : '' }}">
|
||||||
|
<i class="material-icons mdl-list__item-icon">
|
||||||
|
{% if name === 'level' %}
|
||||||
|
exposure
|
||||||
|
{% endif %}
|
||||||
|
{% if name === 'name' %}
|
||||||
|
flash_on
|
||||||
|
{% endif %}
|
||||||
|
{% if name === 'school' %}
|
||||||
|
school
|
||||||
|
{% endif %}
|
||||||
|
</i>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
{{ name }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<i class="material-icons mdl-color-text--teal-600 mdl-list__item-icon {{ name === current ? 'mdl-color-text--teal-600' : 'mdl-color-text--grey-300' }}">
|
||||||
|
{{ rev ? 'keyboard_arrow_up' : 'keyboard_arrow_down' }}
|
||||||
|
</i>
|
||||||
|
</th>
|
||||||
|
{% endfor %}
|
Loading…
Add table
Reference in a new issue