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
Youen Toupin
3 years ago
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