Browse Source
- using a <div> container instead of an <iframe> (simplifies the build system, avoids the quirks iframes) - Bulma CSS is encapsulated in the #simulator ID to avoid polluting the rest of the page, as well as increasing the chances to override the page CSSmaster
14 changed files with 1645 additions and 178 deletions
File diff suppressed because it is too large
Load Diff
@ -1,50 +0,0 @@
|
||||
input[type=number] { |
||||
-moz-appearance:textfield; |
||||
} |
||||
|
||||
.wide-label .field-label { |
||||
flex-grow: 2.5; |
||||
} |
||||
|
||||
.dropdown.is-fullwidth { |
||||
display: flex; |
||||
} |
||||
|
||||
.dropdown.is-fullwidth .dropdown-trigger, |
||||
.dropdown.is-fullwidth .dropdown-menu { |
||||
width: 100%; |
||||
} |
||||
|
||||
.dropdown-trigger.with-dropdown-icon::after { |
||||
border: 3px solid black; |
||||
border-radius: 2px; |
||||
border-right: 0; |
||||
border-top: 0; |
||||
content: " "; |
||||
display: block; |
||||
height: 0.625em; |
||||
margin-top: -0.4375em; |
||||
pointer-events: none; |
||||
position: absolute; |
||||
top: 50%; |
||||
right: 15px; |
||||
transform: rotate(-45deg); |
||||
transform-origin: center; |
||||
width: 0.625em; |
||||
} |
||||
|
||||
.climate-zone { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
svg g { |
||||
filter: drop-shadow( 4px 4px 3px rgba(0, 0, 0, .7)); |
||||
} |
||||
|
||||
.climate-zone:hover { |
||||
filter: brightness(1.2); |
||||
} |
||||
|
||||
svg text { |
||||
pointer-events: none; |
||||
} |
@ -1,34 +0,0 @@
|
||||
function closest (el: Element, predicate: (e: Element) => boolean) { |
||||
do if (predicate(el)) return el; |
||||
while (el = el && <Element>el.parentNode); |
||||
} |
||||
|
||||
document.addEventListener('DOMContentLoaded', function() { |
||||
// Load CSS
|
||||
document.getElementsByTagName('head')[0].innerHTML += (<any>window)['app.css']; |
||||
|
||||
// In order to be able to style SVG elements with CSS, and register events with javascript, we must use inline SVG (we can't use an img tag)
|
||||
// For this purpose, the SVG file contents are embedded in a javascript file
|
||||
document.getElementById('zones-map').innerHTML = (<any>window)['climate-zones-map.svg']; |
||||
|
||||
document.querySelectorAll("[data-activate-modal]").forEach(elt => { |
||||
elt.addEventListener('click', e => { |
||||
document.getElementById(elt.getAttribute('data-activate-modal')).classList.toggle('is-active', true); |
||||
}); |
||||
}); |
||||
|
||||
document.querySelectorAll('.modal-close, .modal-card-head .delete').forEach(elt => { |
||||
elt.addEventListener('click', e => { |
||||
closest(elt, e => e.classList.contains('modal')).classList.toggle('is-active', false); |
||||
}); |
||||
}); |
||||
|
||||
let zoneSelector = <HTMLSelectElement>document.getElementById('zone-selector'); |
||||
document.querySelectorAll('.climate-zone').forEach(elt => { |
||||
elt.addEventListener('click', e => { |
||||
let zoneName = elt.getAttribute('id'); |
||||
zoneSelector.value = zoneName; |
||||
closest(elt, e => e.classList.contains('modal')).classList.toggle('is-active', false); |
||||
}); |
||||
}); |
||||
}); |
@ -1,11 +0,0 @@
|
||||
{ |
||||
"compilerOptions": { |
||||
"module": "system", |
||||
"noImplicitAny": true, |
||||
"removeComments": true, |
||||
"preserveConstEnums": true, |
||||
"outFile": "../../.intermediate/app.js", |
||||
"sourceMap": false |
||||
}, |
||||
"include": ["./**/*", "../../.intermediate/app/**/*"] |
||||
} |
@ -1,12 +0,0 @@
|
||||
.modal-background { |
||||
display: none; |
||||
} |
||||
|
||||
.modal-card-head { |
||||
border-top-left-radius: 0; |
||||
border-top-right-radius: 0; |
||||
} |
||||
|
||||
.modal-card { |
||||
box-shadow: 4px 3px 10px 3px rgba(0,0,0,0.7); |
||||
} |
@ -0,0 +1,77 @@
|
||||
#simulator { |
||||
@import "3rdparty/bulma/bulma.sass"; |
||||
|
||||
// properties that Bulma would set on the <html> tag |
||||
font-size: $body-size; |
||||
text-rendering: $body-rendering; |
||||
box-sizing: border-box; |
||||
margin: 0; |
||||
padding: 0; |
||||
background-color: $body-background-color; |
||||
-moz-osx-font-smoothing: grayscale; |
||||
-webkit-font-smoothing: antialiased; |
||||
min-width: $body-min-width; |
||||
overflow-x: hidden; |
||||
overflow-y: auto; |
||||
text-size-adjust: 100%; |
||||
|
||||
// properties that Bulma would set on the <body> tag |
||||
font-weight: $body-weight; |
||||
line-height: $body-line-height; |
||||
font-family: $body-family; |
||||
color: $body-color; |
||||
& > section, & > footer { |
||||
font-size: $body-font-size; // we must set this on each direct child of the #simulator div, because if it's specified in em, it's multiplied by the parent font-size |
||||
} |
||||
|
||||
input[type=number] { |
||||
-moz-appearance:textfield; |
||||
} |
||||
|
||||
.wide-label .field-label { |
||||
flex-grow: 2.5; |
||||
} |
||||
|
||||
.dropdown.is-fullwidth { |
||||
display: flex; |
||||
} |
||||
|
||||
.dropdown.is-fullwidth .dropdown-trigger, |
||||
.dropdown.is-fullwidth .dropdown-menu { |
||||
width: 100%; |
||||
} |
||||
|
||||
.dropdown-trigger.with-dropdown-icon::after { |
||||
border: 3px solid black; |
||||
border-radius: 2px; |
||||
border-right: 0; |
||||
border-top: 0; |
||||
content: " "; |
||||
display: block; |
||||
height: 0.625em; |
||||
margin-top: -0.4375em; |
||||
pointer-events: none; |
||||
position: absolute; |
||||
top: 50%; |
||||
right: 15px; |
||||
transform: rotate(-45deg); |
||||
transform-origin: center; |
||||
width: 0.625em; |
||||
} |
||||
|
||||
.climate-zone { |
||||
cursor: pointer; |
||||
} |
||||
|
||||
svg g { |
||||
filter: drop-shadow( 4px 4px 3px rgba(0, 0, 0, .7)); |
||||
} |
||||
|
||||
.climate-zone:hover { |
||||
filter: brightness(1.2); |
||||
} |
||||
|
||||
svg text { |
||||
pointer-events: none; |
||||
} |
||||
} |
@ -1,26 +1,36 @@
|
||||
function closest (el: Element, predicate: (e: Element) => boolean) { |
||||
do if (predicate(el)) return el; |
||||
while (el = el && <Element>el.parentNode); |
||||
} |
||||
|
||||
document.addEventListener('DOMContentLoaded', function() { |
||||
let frame = <HTMLIFrameElement>document.querySelector('iframe#simulator'); |
||||
let doc = frame.contentWindow.document; |
||||
let container = document.getElementById('simulator'); |
||||
|
||||
frame.style.width = '100%'; |
||||
frame.style.border = 'none'; |
||||
frame.setAttribute('scrolling', 'no'); |
||||
// Insert HTML code in the container
|
||||
container.innerHTML += (<any>window)['simulator.html']; |
||||
|
||||
// Insert HTML code in the iframe
|
||||
doc.open(); |
||||
doc.write((<any>window)['simulator.html']); |
||||
doc.close(); |
||||
// In order to be able to style SVG elements with CSS, and register events with javascript, we must use inline SVG (we can't use an img tag)
|
||||
// For this purpose, the SVG file contents are embedded in a javascript file
|
||||
document.getElementById('zones-map').innerHTML = (<any>window)['climate-zones-map.svg']; |
||||
|
||||
// Load iframe specific CSS
|
||||
doc.head.innerHTML += (<any>window)['simulator-in-iframe.css']; |
||||
document.querySelectorAll("[data-activate-modal]").forEach(elt => { |
||||
elt.addEventListener('click', e => { |
||||
document.getElementById(elt.getAttribute('data-activate-modal')).classList.toggle('is-active', true); |
||||
}); |
||||
}); |
||||
|
||||
// Add script inside frame
|
||||
let script = doc.createElement('script'); |
||||
script.type = "text/javascript"; |
||||
script.innerText = (<any>window)['app.js']; |
||||
doc.body.appendChild(script); |
||||
document.querySelectorAll('.modal-close, .modal-card-head .delete').forEach(elt => { |
||||
elt.addEventListener('click', e => { |
||||
closest(elt, e => e.classList.contains('modal')).classList.toggle('is-active', false); |
||||
}); |
||||
}); |
||||
|
||||
setInterval(() => { |
||||
frame.height = Math.max(doc.body.scrollHeight, 700) + 'px'; |
||||
}, 100); |
||||
let zoneSelector = <HTMLSelectElement>document.getElementById('zone-selector'); |
||||
document.querySelectorAll('.climate-zone').forEach(elt => { |
||||
elt.addEventListener('click', e => { |
||||
let zoneName = elt.getAttribute('id'); |
||||
zoneSelector.value = zoneName; |
||||
closest(elt, e => e.classList.contains('modal')).classList.toggle('is-active', false); |
||||
}); |
||||
}); |
||||
}); |
||||
|
@ -1,21 +0,0 @@
|
||||
let fs = require('fs') |
||||
|
||||
function embedJs(src, dst) { |
||||
fs.readFile(src, 'utf8', function(err, data) { |
||||
if(err) throw err; |
||||
|
||||
data = data.replace(/\\"/g, '\\\\"'); |
||||
data = "(<any>window)['"+src.replace(/^.*[\\\/]/, '')+"'] = `" + data + "`;"; |
||||
|
||||
fs.writeFile(dst, data, function(err) { |
||||
if(err) throw err; |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
let toolsDir = __dirname; |
||||
let dataDir = toolsDir + "/../data"; |
||||
let srcDir = toolsDir + "/../src"; |
||||
let intermediateDir = toolsDir + "/../.intermediate"; |
||||
|
||||
embedJs(intermediateDir+'/app.js', intermediateDir+'/app.js.ts'); |
Loading…
Reference in new issue