commit d182ead446f2b7560dbb8183a9f10764acf39edb Author: Qx-blocks Date: Sun May 25 19:37:12 2025 +0200 Update diff --git a/.project b/.project new file mode 100644 index 0000000..e2dd3e6 --- /dev/null +++ b/.project @@ -0,0 +1,24 @@ + + + S8-mktg-aero + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope new file mode 100644 index 0000000..b50aaf2 --- /dev/null +++ b/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..2548702 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..30f7719 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/aero/.DS_Store b/aero/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/aero/.DS_Store differ diff --git a/aero/AeroElement.js b/aero/AeroElement.js new file mode 100644 index 0000000..4b03166 --- /dev/null +++ b/aero/AeroElement.js @@ -0,0 +1,50 @@ + + +export const ON_CSS_LOADED = 0x12; + +export class AeroElement { + + + /** + * @type {boolean} current landscape painting option + */ + isLandscape = false; + + /** + * @type {number} current screen width painting option + */ + screenWidth = 1920; + + /** + * @type {number} current screen height painting option + */ + screenHeight = 1080; + + + static isCSSLoading = false; + + + + + + /** CSS is loaded */ + css_isLoaded = false; + + constructor() { + } + + + onOrientationChanged(isLandscape) { + /* To be overridden */ + this.isLandscape = isLandscape; + } + + onScreenResized(width, height) { + /* To be overridden */ + this.screenWidth = width; + this.screenHeight = height; + } + + + +} \ No newline at end of file diff --git a/aero/AeroMovie.css b/aero/AeroMovie.css new file mode 100644 index 0000000..edef3ac --- /dev/null +++ b/aero/AeroMovie.css @@ -0,0 +1,40 @@ +/* */ +section[class^="aero-movie-"] { + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + width: 100%; +} + +section[class^="aero-movie-"]>div.text { + margin: 0px 0px 0px 0px; + padding: 8px 16% 8px 16%; +} + + +/* */ + +.aero-movie { + background-color: rgb(255, 255, 255); + width: 100%; + /*overflow: auto;*/ +} + + +.aero-movie[loaded = "false"] { + aspect-ratio: 16 / 9; + background-color: aqua; + position: relative; +} + +.aero-movie[loaded = "true"] { + height: fit-content; + background-color: white; + position: relative; +} + +.aero-movie-video{ + width: 100%; + /*overflow: auto;*/ +} + + diff --git a/aero/AeroMovie.js b/aero/AeroMovie.js new file mode 100644 index 0000000..00246a9 --- /dev/null +++ b/aero/AeroMovie.js @@ -0,0 +1,146 @@ +import { AeroElement } from "./AeroElement.js"; + +import { WebPage } from "./WebPage.js"; +import { LoadHandler } from "./aero.js"; +import { createSpinner } from "./boot.js"; + + + + +/* + Turn this: + { + _type: "aero-slide-prime", + theme: "dark", + title: `The power of tomorrow`, + subtitle: "Hi There", + paragraph: `this is a very + long text indeed that spread on multiple lines`, + background : { + _type : "pic", + source : "assets/truc0002.jpg" + } + }, + + into this: + +
+
+

Say Hello to OCTOFAN

+

The world's first H2-powered multirole heavy duty drone with + switchable nacelles

+
+
+
+
+*/ + + + +export const LOW_RESOLUTION_TAG = "-low"; +export const HIGH_RESOLUTION_TAG = "-high"; + +export class AeroMovie extends AeroElement { + + /** @type {HTMLElement } */ + sectionNode; + + type; + + props; + + /** @type{boolean} */ + hasBackgroundImage = false; + + /** @type{boolean} */ + isBackgroundImageLoaded = false; + + /** @type{string} */ + backgroundImagePath; + + /** @type{boolean} */ + hasAssetImage = false; + + /** @type{boolean} */ + isAssetImageLoaded = false; + + /** @type{string} */ + assetImagePath; + + /** @type {HTMLDivElement} */ + assetNode; + + + constructor(type, props) { + super(); + this.type = type; + this.props = props; + } + + + initializeNodes(handler, state) { + this.sectionNode = document.createElement("section"); + this.sectionNode.classList.add("aero-movie"); + this.sectionNode.setAttribute("loaded", "false"); + const spinnerNode = createSpinner(); + this.sectionNode.appendChild(spinnerNode); + + /* */ + + return this.sectionNode; + } + + + + render() { + if (!this.isInitialized) { + this.draw(); + this.isInitialized = true; + } + } + + draw() { + + } + + + run() { + this.videoNode.play(); + } + + generateNextSourceNode() { + if (this.sequenceIndex >= this.sequences.length) { this.sequenceIndex = 0; } + + } + + +} diff --git a/aero/AeroUtilities.js b/aero/AeroUtilities.js new file mode 100644 index 0000000..233a889 --- /dev/null +++ b/aero/AeroUtilities.js @@ -0,0 +1,81 @@ + + + + +export const AeroUtilities = { + + + /** + * + * @param {*} target + * @param {*} pathname + * @param {*} onLoaded + */ + loadBackgroundImage : function(target, pathname, onLoaded) { + + const backgroundImageBuffer = new Image(); + + const _this = this; + backgroundImageBuffer.onload = function () { + + /* assign image from buffer */ + target.style.backgroundImage = `url(${backgroundImageBuffer.src})`; + + /* notify handler */ + if(onLoaded){ onLoaded(); } + }; + + /* trigger loading */ + backgroundImageBuffer.src = pathname; + }, + + + getResourceFromOrigin : function(requestPath, responseType, responseCallback){ + this.sendRequest_HTTP_GET(window.location.origin + requestPath, responseType, responseCallback); + }, + + + + /** + * + * @param {string} requestPath + * @param {string} responseType + * @param {Function} responseCallback + */ + sendRequest_HTTP_GET : function(requestPath, responseType, responseCallback) { + + /** + * Relies on browser cache for speeding things up + */ + let xhr = new XMLHttpRequest(); + + // first line + xhr.open("GET", requestPath, true); + xhr.responseType = responseType; + + // headers + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.setRequestHeader('Access-Control-Allow-Origin', "*"); + xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); + xhr.setRequestHeader('Access-Control-Allow-Methods', 'X-Requested-With'); + xhr.setRequestHeader('Access-Control-Allow-Headers', 'Cookie, Content-Type, Authorization, Content-Length, X-Requested-With'); + xhr.setRequestHeader('Access-Control-Expose-Headers', 'Set-Cookie, X-Powered-By'); + + + let _this = this; + // Hook the event that gets called as the request progresses + xhr.onreadystatechange = function () { + // If the request is "DONE" (completed or failed) + if (xhr.readyState == 4) { + // If we got HTTP status 200 (OK) + if (xhr.status == 200) { + responseCallback(xhr.responseText); + } + } + }; + + // fire request + xhr.send(null); + } + +} diff --git a/aero/CodeBlock.css b/aero/CodeBlock.css new file mode 100644 index 0000000..5b3a742 --- /dev/null +++ b/aero/CodeBlock.css @@ -0,0 +1,25 @@ + + +.code-block-section { + background-color: rgb(63, 63, 63); + padding: 32px max(15%, 16px) 32px max(15%, 16px); +} + +.code-block-window { + background-color: rgb(33, 23, 59); + border-radius: 8px; + padding: 16px 24px; + color: rgb(87, 211, 211); +} + +.code-block-window pre { + margin: 0; + padding: 0; + overflow-x: scroll; + tab-size: 2; +} + +.code-block-window code { + margin: 0; + padding: 0; +} diff --git a/aero/CodeBlock.js b/aero/CodeBlock.js new file mode 100644 index 0000000..5f90267 --- /dev/null +++ b/aero/CodeBlock.js @@ -0,0 +1,85 @@ +import { AeroElement } from "./AeroElement.js"; +import { WebPage } from "./WebPage.js"; + + +// Using ES6 import syntax +import hljs from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/es/highlight.min.js'; +// and it's easy to individually load additional languages +import java from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/es/languages/java.min.js'; +import xml from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/es/languages/xml.min.js'; +import { AeroUtilities } from "./AeroUtilities.js"; + + + + +export class CodeBlock extends AeroElement { + + static isLanguageLoaded = false; + + + constructor(sourcePathname) { + super(); + this.sourcePathname = sourcePathname; + + if (!this.isLanguageLoaded) { + + // Then register the languages you need + hljs.registerLanguage('java', java); + hljs.registerLanguage('xml', xml); + this.isLanguageLoaded = true; + } + } + + /** + * + * @param {WebPage} page + */ + build(page) { + //page.css_requireStylesheet("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/default.min.css"); + page.css_requireStylesheet("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/atom-one-dark.css"); + + page.css_requireStylesheet("/aero/CodeBlock.css"); + + + + + const sectionNode = document.createElement("section"); + sectionNode.classList.add("code-block-section"); + + const windowNode = document.createElement("div"); + windowNode.classList.add("code-block-window"); + // windowNode.classList.add("theme-atom-one-dark"); + + const preNode = document.createElement("pre"); + //preNode.classList.add("theme-atom-one-dark"); + + const spanNode = document.createElement("span"); + //spanNode.classList.add("language-java"); + // spanNode.classList.add("hljs"); + const codeNode = document.createElement("code"); + //codeNode.innerHTML = highlightedCode; + + + spanNode.appendChild(codeNode); + preNode.appendChild(spanNode); + windowNode.appendChild(preNode); + sectionNode.appendChild(windowNode); + + AeroUtilities.getResourceFromOrigin(this.sourcePathname, "text", sourceCode => { + const highlightedSourceCode = hljs.highlight(sourceCode, { language: 'java' }).value; + codeNode.innerHTML = highlightedSourceCode; + }) + + + return (this.sectionNode = sectionNode); + } + + + /** + * + * @param {WebPage} page + */ + render(page) { + /* do nothing */ + } +} \ No newline at end of file diff --git a/aero/Deck.css b/aero/Deck.css new file mode 100644 index 0000000..92ec6eb --- /dev/null +++ b/aero/Deck.css @@ -0,0 +1,79 @@ + +.aero-deck { + padding: 16px 8% 16px 8%; + display: flex; + flex-wrap: wrap; + background-color: rgb(128, 128, 128); +} + + +.aero-deck-card-space { + margin: 8px; +} + +.aero-deck-card { + border-radius: 8px; + border: solid 2px rgb(200, 200, 200); +} + + +.aero-deck-card-photo { + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + height: 160px; + width: 160px; + z-index: 2; + border-radius: 6px 6px 0px 0px; +} + +.aero-deck-card-name { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 16px; + font-weight: bold; + width: 152px; + padding: 4px 4px 4px 4px; + background-color: white; + text-align: center; +} + +.aero-deck-card-role { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 16px; + font-weight: normal; + width: 152px; + padding: 4px 4px 4px 4px; + background-color: white; + text-align: center; +} + +.aero-deck-card-bio { + font-family: Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 12px; + width: 144px; + padding: 8px 8px 8px 8px; + font-weight: normal; + background-color: white; + border-radius: 0px 0px 6px 6px; +} + + + + +@media (orientation : landscape) { + .aero-deck { + padding: 16px 10% 16px 10%; + } +} + +@media (max-width: 480px) { + .aero-deck { + padding: 0px calc(50vw - 180px) 0px calc(50vw - 180px); + } +} + + diff --git a/aero/Deck.js b/aero/Deck.js new file mode 100644 index 0000000..df8eb18 --- /dev/null +++ b/aero/Deck.js @@ -0,0 +1,100 @@ +import { AeroElement } from "./AeroElement.js"; + +import { WebPage } from "./WebPage.js"; + + +/** + * aero-deck + */ +export class Deck extends AeroElement { + + /** @type {HTMLElement } */ + sectionNode; + + props; + + constructor(props) { + super(); + this.props = props; + } + + + /** + * + * @param {WebPage} page + * @returns {HTMLElement} + */ + build(page) { + + /* CSS requirements */ + page.css_requireStylesheet("/aero/Deck.css"); + + /* build nodes */ + this.sectionNode = document.createElement("section"); + this.sectionNode.classList.add("aero-deck"); + + this.props.cards.forEach(cardProps => { + let cardSpaceNode = document.createElement("div"); + cardSpaceNode.classList.add("aero-deck-card-space"); + + cardSpaceNode.appendChild(createCard(cardProps)); + + this.sectionNode.appendChild(cardSpaceNode); + }); + + /* return wrapper node */ + return this.sectionNode; + } + + + /** + * + * @param {WebPage} page + */ + render(page) { + if (!this.isInitialized) { + this.draw(); + this.isInitialized = true; + } + } + + + getEnveloppe() { + return this.sectionNode; + } + + + isLoaded(){ + return this.isInitialized; + } + + +} + +const createCard = function(props){ + + let cardNode = document.createElement("div"); + cardNode.classList.add("aero-deck-card"); + + let photoNode = document.createElement("div"); + photoNode.classList.add("aero-deck-card-photo"); + photoNode.style.backgroundImage = `url('${props.photo}')`; + cardNode.appendChild(photoNode); + + let nameNode = document.createElement("div"); + nameNode.classList.add("aero-deck-card-name"); + nameNode.innerHTML = props.name; + cardNode.appendChild(nameNode); + + let roleNode = document.createElement("div"); + roleNode.classList.add("aero-deck-card-role"); + roleNode.innerHTML = props.role; + cardNode.appendChild(roleNode); + + let bioNode = document.createElement("div"); + bioNode.classList.add("aero-deck-card-bio"); + bioNode.innerHTML = props.bio; + cardNode.appendChild(bioNode); + + return cardNode; +} diff --git a/aero/Documentation.css b/aero/Documentation.css new file mode 100644 index 0000000..3525f2c --- /dev/null +++ b/aero/Documentation.css @@ -0,0 +1,301 @@ +/* */ + +.aero-doc{ + margin: 0px; + padding: 0px; + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; +} + +.aero-doc-header { + margin: 0px; + padding: 8px; + width: 100%; + font-size: 16px; + font-weight: bold; + color: grey; + background-color: rgb(232, 238, 232); + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; +} + +.aero-doc-main { + margin: 0px; + padding: 0px; + width: 100%; + display: flex; + flex-direction: row; + background-color: white; + border-top: solid 1px rgb(169, 169, 169); +} + +.aero-doc-table { + width: 24%; + padding: 8px 16px 8px 16px; +} + +.aero-doc-content { + width: 76%; + padding: 8px 16px 8px 16px; + height: calc(100vh - 128px); + overflow-y: scroll; + border-left: solid 1px rgb(169, 169, 169); +} + +.aero-doc-table > div { + padding: 6px 12px; + border-bottom: solid 1px rgb(225, 217, 255); +} + +.aero-doc-table > div > a{ + font-size: 24px; + font-weight: bold; + color: rgb(104, 106, 105); +} + + +@media (orientation : landscape) { + + .aero-doc { + border-top: solid 1px rgb(169, 169, 169); + } + + .aero-doc-content { + margin: 0px 0px 0px 0px; + padding: 16px 32px 16px 32px; + } +} + + +@media (orientation : portrait) { + .aero-doc-content { + margin: 0px 0px 0px 0px; + padding: 8px 16px 8px 16px; + } +} + + + + + + +/*

*/ +.aero-doc-h1 { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-weight: lighter; + max-width: 92%; + padding: 8px; + border-radius: 4px; + margin: 0px; + z-index: 8; + text-align: left; +} + +@media (orientation : landscape) { + .aero-doc-h1 { + font-size: 64px; + line-height: 64px; + } +} + +@media (orientation : portrait) { + .aero-doc-h1 { + font-size: 48px; + line-height: 48px; + } +} + +.aero-doc-h1>span.emphasis { + font-weight: bold; +} + +.aero-doc-h1 { + padding: 32px 8px 16px 8px; +} + +/*

*/ + + +/*

*/ +.aero-doc-h2 { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 24px; + line-height: 24px; + font-weight: bold; + max-width: 92%; + padding: 16px 8px 8px 8px; + border-radius: 4px; + /*white-space: nowrap;*/ + margin: 0px; + z-index: 6; + text-align: left; +} + +@media (orientation : landscape) { + .aero-doc-h2 { + font-size: 24px; + line-height: 24px; + } +} + +@media (orientation : portrait) { + .aero-doc-h2 { + font-size: 20px; + line-height: 20px; + } +} + +/*

*/ + +/*

*/ +.aero-doc-p { + font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", + sans-serif; + font-size: 20px; + font-weight: normal; + text-align: justify; + z-index: 4; + padding: 0px 0px 0px 0px; + padding: 6px 6px 6px 8px; + border-radius: 4px; + margin: 0px; +} + + +/*

*/ +.aero-doc-p, .aero-doc-ul { + font-size: 16px; +} + +.aero-doc-ul>li { + padding: 8px 8px 8px 16px; +} + + +@media (orientation : landscape) { + .aero-doc-p { + font-size: 16px; + } +} + +@media (orientation : portrait) { + .aero-doc-p { + font-size: 13px; + } +} + +/*

*/ + +.aero-slide>a { + position: absolute; + z-index: 10; + overflow: hidden; + padding: 12px 24px; + font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", + sans-serif; + font-size: 20px; + font-weight: normal; + line-height: 16px; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + user-select: none; + background-repeat: repeat-x; + background-position: -1px -1px; + background-size: 110% 110%; + border: 1px solid rgba(240, 240, 255, 1.0); + border-radius: 8px; + appearance: none; + /* appearance */ + color: #ffffff; + background-color: rgba(28, 77, 45, 0.16); + background-image: linear-gradient(-180deg, rgb(46 46 46/ 52%) 0%, + rgb(16 16 16/ 67%) 90%); + backdrop-filter: blur(2px); + text-decoration: none; +} + +.aero-slide>a:hover { + background-color: #269f42; + background-image: linear-gradient(-180deg, #2fcb53 0%, #269f42 90%); + background-position: -.5em; + border-color: rgba(27, 31, 35, 0.5); + text-decoration: none; +} + +.aero-slide>a:focus { + box-shadow: 0 0 0 0.2em rgba(52, 208, 88, 0.4); + text-decoration: none; +} + +.aero-slide>a:active { + background-color: #279f43; + background-image: none; + border-color: rgba(27, 31, 35, 0.5); + box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15); + text-decoration: none; +} + + + +/* */ +.aero-doc[theme="light"] { + color: black; + /*background-color: rgba(255, 255, 255, 0.24);*/ + /*backdrop-filter: blur(12px);*/ + /*text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.75);*/ + /*text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.75);*/ +} + +.aero-doc[theme="dark"] { + color: white; + /*background-color: rgba(0, 0, 0, 0.16);*/ + /*backdrop-filter: blur(12px);*/ + /*text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.75);*/ +} + +/* */ + + +/* */ +.aero-doc-pic-svg { + padding: 32px 16px 32px 16px; +} + +.aero-doc-pic-svg svg { + fill: black; + stroke: black; +} + +/* */ + + + +/* */ + + +.aero-doc-code-section { + padding: 24px max(5%, 16px) 24px max(5%, 16px); +} + +.aero-doc-code-window { + background-color: rgb(33, 23, 59); + border-radius: 16px; + padding: 16px 32px; + color: rgb(87, 211, 211); + font-size: 13px; +} + +.aero-doc-code-window pre { + margin: 0; + padding: 0; + overflow-x: scroll; + tab-size: 2; +} + +.aero-doc-code-window code { + margin: 0; + padding: 0; +} \ No newline at end of file diff --git a/aero/DocumentationV2.js b/aero/DocumentationV2.js new file mode 100644 index 0000000..ad1da5d --- /dev/null +++ b/aero/DocumentationV2.js @@ -0,0 +1,338 @@ +import { AeroElement } from "./AeroElement.js"; +import { AeroUtilities } from "./AeroUtilities.js"; +import { Icon } from "./Icon.js"; +import { WebPage } from "./WebPage.js"; +import { WebPageV2 } from "./WebPageV2.js"; + + +// Using ES6 import syntax +import hljs from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/es/highlight.min.js'; +// and it's easy to individually load additional languages +import java from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/es/languages/java.min.js'; +import xml from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/es/languages/xml.min.js'; + + + + + +/* + Turn this: + { + _type: "aero-slide-prime", + theme: "dark", + title: `The power of tomorrow`, + subtitle: "Hi There", + paragraph: `this is a very + long text indeed that spread on multiple lines`, + background : { + _type : "pic", + source : "assets/truc0002.jpg" + } + }, + + into this: + +
+
+

Say Hello to OCTOFAN

+

The world's first H2-powered multirole heavy duty drone with + switchable nacelles

+
+
+
+
+*/ + + + +export const LOW_RESOLUTION_TAG = "-low"; +export const HIGH_RESOLUTION_TAG = "-high"; + +export class DocumentationV2 extends AeroElement { + + /** @type {HTMLElement } */ + sectionNode; + + type; + + /** + * @type{List} + */ + elements = new Array(); + + /** @type{boolean} */ + hasBackgroundImage = false; + + /** @type{boolean} */ + isBackgroundImageLoaded = false; + + /** @type{string} */ + backgroundImagePath; + + /** @type{boolean} */ + hasAssetImage = false; + + /** @type{boolean} */ + isAssetImageLoaded = false; + + /** @type{string} */ + assetImagePath; + + /** @type {HTMLDivElement} */ + assetNode; + + + /** + * + * @param {WebPageV2} page + * @param {HTMLElement} sources + */ + constructor(page, sources){ + super(); + + /* CSS requirements */ + page.css_requireStylesheet("/aero/Documentation.css"); + + /* build nodes */ + this.sectionNode = document.createElement("section"); + this.sectionNode.classList.add("aero-doc"); + + this.headerNode = document.createElement("div"); + this.headerNode.classList.add("aero-doc-header"); + this.sectionNode.appendChild(this.headerNode); + + this.mainNode = document.createElement("div"); + this.mainNode.classList.add("aero-doc-main"); + + this.tableOfContentsNode = document.createElement("div"); + this.tableOfContentsNode.classList.add("aero-doc-table"); + this.mainNode.appendChild(this.tableOfContentsNode); + + this.contentNode = document.createElement("div"); + this.contentNode.classList.add("aero-doc-content"); + this.mainNode.appendChild(this.contentNode); + + this.sectionNode.appendChild(this.mainNode); + + + this.headerNode.innerHTML = "header zone"; + + let val; + this.arrangement = (val = sources.getAttribute("arrangement")) ? val : "std"; + this.sectionNode.setAttribute("arrangement", this.arrangement); + + /* */ + if (sources.id != undefined) { this.sectionNode.id = sources.id; } + /* */ + + + /* */ + let node = sources.firstChild; + let index = 2; + while(node){ + let type = node.nodeName.toLowerCase(); + switch(type){ + case "h1" : this.elements.push(new DocHeader1(page, node, "doc-h1-"+(index++))); break; + case "h2" : this.elements.push(new DocHeader2(page, node)); break; + case "p" : this.elements.push(new DocParagraph(page, node)); break; + case "svg" : this.elements.push(new DocSVG(page, node)); break; + case "code" : this.elements.push(new DocCodeBlock(page, node)); break; + } + + node = node.nextSibling; + } + + this.elements.forEach(element => this.contentNode.appendChild(element.html_getNode())); + this.elements.forEach(element => element.html_appendTableEntry(this.tableOfContentsNode)); + /* */ + } + + + html_getNode(){ + /* return wrapper node */ + return this.sectionNode; + } + + + + /** + * + * @param {WebPage} page + */ + render(page) { + if (!this.isInitialized) { + this.draw(); + this.isInitialized = true; + } + else if (this.isInitialized && page.imageResolution == 1) { + this.redrawHighRes(); + } + } + + draw() { + + } + +} + +export class DocElement { + + constructor(sources) { + + } + +} + +export class DocHeader1 extends DocElement { + + constructor(page, sources, id) { + super(sources); + this.id = id; + this.name = sources.innerHTML; + + const headerNode = document.createElement("h1"); + headerNode.id = id; + headerNode.classList.add("aero-doc-h1"); + headerNode.innerHTML = this.name; + this.headerNode = headerNode; + } + + html_getNode() { return this.headerNode; } + + html_appendTableEntry(tableOfContentsNode) { + const entryNode = document.createElement("div"); + const linkNode = document.createElement("a"); + linkNode.href = "#"+this.id; + linkNode.innerHTML = this.name; + entryNode.appendChild(linkNode); + tableOfContentsNode.appendChild(entryNode); + } +} + + +export class DocHeader2 extends DocElement { + + constructor(page, sources) { + super(sources); + const headerNode = document.createElement("h2"); + headerNode.classList.add("aero-doc-h2"); + headerNode.innerHTML = sources.innerHTML; + this.headerNode = headerNode; + } + + html_getNode() { return this.headerNode; } + html_appendTableEntry() { /* nothing to add */} +} + + +export class DocParagraph extends DocElement { + + constructor(page, sources) { + super(sources); + const headerNode = document.createElement("p"); + headerNode.classList.add("aero-doc-p"); + headerNode.innerHTML = sources.innerHTML; + this.headerNode = headerNode; + } + + html_getNode() { return this.headerNode; } + html_appendTableEntry() { /* nothing to add */} +} + + +export class DocSVG extends DocElement { + + constructor(page, sources) { + super(sources); + this.pathname = sources.getAttribute("path"); + + const wrapperNode = document.createElement("div"); + wrapperNode.classList.add("aero-doc-pic-svg"); + //if (this.isMobileHideable) { headerNode.classList.add("txbk-mobile-hideable"); } + + let val; + const width = (val = sources.getAttribute("width")) ? parseInt(val) : 128; + const height = (val = sources.getAttribute("height")) ? parseInt(val) : 128; + this.icon = new Icon(this.pathname, { width: width, height: height }); + wrapperNode.appendChild(this.icon.build()); + + this.wrapperNode = wrapperNode; + } + + html_getNode() { return this.wrapperNode; } + html_appendTableEntry() { /* nothing to add */} + +} + + +export class DocCodeBlock extends DocElement { + + static isLanguageLoaded = false; + + /** + * + * @param {WebPageV2} page + * @param {HTMLElement} sources + */ + constructor(page, sources){ + super(sources); + + this.sourcePathname = sources.getAttribute("path"); + + if (!this.isLanguageLoaded) { + + // Then register the languages you need + hljs.registerLanguage('java', java); + hljs.registerLanguage('xml', xml); + this.isLanguageLoaded = true; + } + + //page.css_requireStylesheet("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/default.min.css"); + page.css_requireStylesheet("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/atom-one-dark.css"); + + + const wrapperNode = document.createElement("div"); + wrapperNode.classList.add("aero-doc-code-section"); + + const windowNode = document.createElement("div"); + windowNode.classList.add("aero-doc-code-window"); + // windowNode.classList.add("theme-atom-one-dark"); + + const preNode = document.createElement("pre"); + //preNode.classList.add("theme-atom-one-dark"); + + const spanNode = document.createElement("span"); + //spanNode.classList.add("language-java"); + // spanNode.classList.add("hljs"); + + const codeNode = document.createElement("code"); + //codeNode.innerHTML = highlightedCode; + + + spanNode.appendChild(codeNode); + preNode.appendChild(spanNode); + windowNode.appendChild(preNode); + wrapperNode.appendChild(windowNode); + + AeroUtilities.getResourceFromOrigin(this.sourcePathname, "text", sourceCode => { + const highlightedSourceCode = hljs.highlight(sourceCode, { language: 'java' }).value; + codeNode.innerHTML = highlightedSourceCode; + }) + + this.wrapperNode = wrapperNode; + } + + + html_getNode() { return this.wrapperNode; } + html_appendTableEntry() { /* nothing to add */} + + + /** + * + * @param {WebPage} page + */ + render(page) { + /* do nothing */ + } +} diff --git a/aero/Footer.css b/aero/Footer.css new file mode 100644 index 0000000..b36d31c --- /dev/null +++ b/aero/Footer.css @@ -0,0 +1,130 @@ +/*
*/ +footer { + background-color: rgb(64, 64, 64); + width: 100%; + color: rgb(128, 128, 128); +} + +/*
*/ + + + +.aero-footer { + background: #2c3840; + color: #8aa0ae; + padding: 0; + margin: 0; + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 16px; + font-weight: bold; +} + +.aero-footer .marketing-site-footer-menu-social a { + color: #fefefe; +} + +.aero-footer .column-block { + margin-bottom: 30px; +} + +.aero-footer-row { + margin-bottom: 1rem; + display: flex; + padding: 0 8% 0 8%; +} + +.aero-footer-column { + padding: 0px 4% 0px 4%; +} + +.aero-footer-social > a > img { + width: 64px; + height: 64px; + margin: 0px 20px 0px 20px; +} + +@media screen and (max-width: 39.9375em) { + .aero-footer .columns { + margin-bottom: 2rem; + } +} + +.marketing-site-footer-name { + color: #fefefe; + margin-bottom: 1rem; + font-size: 2rem; +} + +.marketing-site-footer-title { + color: #fefefe; + margin-bottom: 1rem; + font-size: 1.25rem; +} + +.marketing-site-footer-block { + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + margin-bottom: 1rem; +} + +.marketing-site-footer-block .fa { + font-size: 2rem; + color: #020304; +} + +.marketing-site-footer-block p { + margin-left: 1rem; + line-height: 1.125rem; +} + +.aero-footer-bottom { + background: #020304; + padding: 8px 8% 8px 8%; + margin-bottom: 0; + color: white; +} +.aero-footer-bottom > a { + display: inline-block; + padding: 2px 8px 2px 8px; + margin: 0px 0px 0px 0px; + border-left: solid 1px #8aa0ae; + text-decoration: none; + color: rgb(128, 128, 128); + font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 14px; + font-weight: normal; +} + +.aero-footer-bottom > a:hover { + text-decoration: underline; +} + +.marketing-site-footer-bottom .marketing-site-footer-bottom-links a { + color: #8aa0ae; +} + +@media screen and (max-width: 63.9375em) { + .marketing-site-footer-bottom .marketing-site-footer-bottom-links { + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + } +} + +@media screen and (max-width: 63.9375em) { + .marketing-site-footer-bottom { + text-align: center; + } +} + + + +/* */ + +.aero-footer-social-link { + width: 64px; + height: 64px; + margin: 0px 20px 0px 20px; +} \ No newline at end of file diff --git a/aero/Footer.js b/aero/Footer.js new file mode 100644 index 0000000..88f0bef --- /dev/null +++ b/aero/Footer.js @@ -0,0 +1,48 @@ +import { AeroElement } from "./AeroElement.js"; +import { AeroUtilities } from "./AeroUtilities.js"; + + +export class Footer extends AeroElement { + + /** @type{HTMLElement} */ + footerNode; + + + props; + + constructor(contentPathname, props) { + super(); + this.contentPathname = contentPathname + this.props = props; + } + + /** + * + * @param {WebPage} page + * @returns {HTMLElement} + */ + build(page) { + + /* CSS requirements */ + page.css_requireStylesheet("/aero/Footer.css"); + + /* build nodes */ + this.footerNode = document.createElement('footer'); + this.footerNode.classList.add('aero-footer'); + + AeroUtilities.sendRequest_HTTP_GET(this.contentPathname, "text", content => { + this.footerNode.innerHTML = content; + }); + + /* return wrapper node */ + return this.footerNode; + } + + /** + * + * @param {WebPage} page + */ + render(page) { + + } +} \ No newline at end of file diff --git a/aero/FooterV2.js b/aero/FooterV2.js new file mode 100644 index 0000000..3776286 --- /dev/null +++ b/aero/FooterV2.js @@ -0,0 +1,46 @@ +import { AeroElement } from "./AeroElement.js"; +import { AeroUtilities } from "./AeroUtilities.js"; +import { WebPageV2 } from "./WebPageV2.js"; + + +export class FooterV2 extends AeroElement { + + /** @type{HTMLElement} */ + footerNode; + + + /** + * + * @param {WebPageV2} page + * @param {HTMLElement} sources + */ + constructor(page, sources) { + super(); + /* CSS requirements */ + page.css_requireStylesheet("/aero/Footer.css"); + + /* build nodes */ + this.footerNode = document.createElement('footer'); + this.footerNode.classList.add('aero-footer'); + + this.contentPathname = sources.getAttribute("path"); + + AeroUtilities.sendRequest_HTTP_GET(this.contentPathname, "text", content => { + this.footerNode.innerHTML = content; + }); + } + + html_getNode() { + /* return wrapper node */ + return this.footerNode; + } + + + /** + * + * @param {WebPageV2} page + */ + render(page) { + + } +} \ No newline at end of file diff --git a/aero/Grid.css b/aero/Grid.css new file mode 100644 index 0000000..898e5db --- /dev/null +++ b/aero/Grid.css @@ -0,0 +1,348 @@ +/* */ +.aero-grid { + margin: 0px 0px 0px 0px; + padding: 0px 0px 0px 0px; + width: 100%; +} + +.aero-grid > div.text { + margin: 0px 0px 0px 0px; + padding: 8px 16% 8px 16%; +} + + +/* */ + +div.aero-grid-asset { + margin: 0px 0px 0px 0px; + padding: 8px 12% 8px 12%; + background-size: contain; + background-repeat: no-repeat; + background-position: center; + height: 600px; + z-index: 2; + /*overflow: auto;*/ +} + +@media (orientation : landscape) { + div.aero-grid-asset { + height: 600px; + padding: 8px 12% 8px 12%; + } +} + +@media (orientation : portrait) { + div.aero-grid-asset { + height: 320px; + padding: 4px 0px 4px 0px; + } +} + + +/* */ + + +/* */ +div.aero-grid[type = "metrics"] { + margin: 0px 0px 0px 0px; + padding: 8px 12% 8px 12%; + display: inline-flex; + background-color: black; + z-index: 2; + /*overflow: auto;*/ +} + + +div.aero-grid-metrics-item { + flex: auto; + padding: 20px; +} + +div.aero-grid-metrics-item * { + padding: 0px; + margin: 0px; +} + +div.aero-grid-metrics-item-value>span { + vertical-align: baseline; + color: #9fffa5; +} + +div.aero-grid-metrics-item-value>span.modifier { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 64px; + font-weight: normal; +} + +div.aero-grid-metrics-item-value>span.number { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 64px; + font-weight: bold; + padding: 0px 4px 0px 4px; +} + +div.aero-grid-metrics-item-value>span.unit { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 32px; + font-weight: bold; +} + +div.aero-grid-metrics-item-parameter { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 16px; + font-weight: normal; + padding: 8px; + color: #6be8ea; +} + + +@media (orientation : landscape) { + /* default */ + + div.aero-grid-metrics-item { + border-left: 1px solid rgba(64, 64, 64, 0.92); + } + + div.aero-grid[type = "metrics"]>div.aero-grid-metrics-item:first-child { + border-left: none; + } +} + +@media (orientation : portrait) { + div.aero-grid[type="metrics"] { + display: flex; + flex-wrap: wrap; + } + div.aero-grid-metrics-item { + border-top: 1px solid rgba(64, 64, 64, 0.92); + } + + div.aero-grid[type = "metrics"] > div.aero-grid-metrics-item:first-child { + border-top: none; + } +} + + +/* */ + +/*

*/ +.aero-grid h1 { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-weight: lighter; + max-width: 92%; + padding: 8px; + border-radius: 4px; + margin: 0px; + z-index: 8; + text-align: center; +} + +@media (orientation : landscape) { + .aero-grid h1{ + font-size: 64px; + line-height: 64px; + } +} + +@media (orientation : portrait) { + aero-grid h1{ + font-size: 48px; + line-height: 48px; + } +} + +.aero-grid h1 > span.emphasis { + font-weight: bold; +} + +/*

*/ + + +/*

*/ +.aero-grid h2 { + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 24px; + line-height: 24px; + font-weight: bold; + max-width: 92%; + padding: 8px; + border-radius: 4px; + /*white-space: nowrap;*/ + margin: 0px; + z-index: 6; + text-align: center; +} + + +@media (orientation : landscape) { + .aero-grid h2 { + font-size: 24px; + line-height: 24px; + } +} + +@media (orientation : portrait) { + .aero-grid h2 { + font-size: 20px; + line-height: 20px; + } +} + +/*

*/ + +.aero-grid p { + font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", + sans-serif; + font-size: 20px; + font-weight: normal; + text-align: justify; + z-index: 4; + padding: 0px 0px 0px 0px; + padding: 6px 6px 6px 8px; + border-radius: 4px; + margin: 0px; +} + +.aero-grid > a { + position: absolute; + z-index: 10; + overflow: hidden; + padding: 12px 24px; + font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", + sans-serif; + font-size: 20px; + font-weight: normal; + line-height: 16px; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + user-select: none; + background-repeat: repeat-x; + background-position: -1px -1px; + background-size: 110% 110%; + border: 1px solid rgba(240, 240, 255, 1.0); + border-radius: 8px; + appearance: none; + /* appearance */ + color: #ffffff; + background-color: rgba(28, 77, 45, 0.16); + background-image: linear-gradient(-180deg, rgb(46 46 46/ 52%) 0%, + rgb(16 16 16/ 67%) 90%); + backdrop-filter: blur(2px); + text-decoration: none; +} + +.aero-grid > a:hover { + background-color: #269f42; + background-image: linear-gradient(-180deg, #2fcb53 0%, #269f42 90%); + background-position: -.5em; + border-color: rgba(27, 31, 35, 0.5); + text-decoration: none; +} + +.aero-grid > a:focus { + box-shadow: 0 0 0 0.2em rgba(52, 208, 88, 0.4); + text-decoration: none; +} + +.aero-grid > a:active { + background-color: #279f43; + background-image: none; + border-color: rgba(27, 31, 35, 0.5); + box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15); + text-decoration: none; +} + +@media (orientation : landscape) {} + +@media (orientation : portrait) { + .aero-grid h1 { + font-size: 32px; + line-height: 32px; + } + + .aero-grid h2 { + font-size: 18px; + line-height: 18px; + } + + .aero-grid p { + font-size: 16px; + } +} + +.aero-grid-paragraph { + font-size: 16px; + padding: 32px 0px 32px 0px; +} + +/* */ + +/* */ + +/* */ + + + +/* */ +.aero-grid[theme = "light"] { + color: black; + /*background-color: rgba(255, 255, 255, 0.24);*/ + /*backdrop-filter: blur(12px);*/ + /*text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.75);*/ + /*text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.75);*/ +} + +.aero-grid[theme = "dark"] { + color: white; + /*background-color: rgba(0, 0, 0, 0.16);*/ + /*backdrop-filter: blur(12px);*/ + /*text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.75);*/ +} + +/* */ + + +/* */ +.background-color { + background-repeat: no-repeat; +} + + +.background-pic { + background-repeat: no-repeat; + background-size: cover; + background-position: center; +} +/* */ + +.aero-grid-deck { + left: 50%; + position: relative; + transform: translateX(-50vw); + margin: 64px; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(240px, auto)); + /* flex-wrap: wrap; */ + gap: 32px; + align-items: center; +} + +/* */ + +.aero-grid-card { + width: 240px; + aspect-ratio: 2.5 / 3.5; + border: none; + border-radius: 16px; + box-shadow: 0px 0px 8px rgba(75, 75, 75, 0.532); +} + + +/* */ diff --git a/aero/Grid.js b/aero/Grid.js new file mode 100644 index 0000000..c1b0f0f --- /dev/null +++ b/aero/Grid.js @@ -0,0 +1,208 @@ +import { AeroElement } from "./AeroElement.js"; +import { WebPage } from "./WebPage.js"; +import { LoadHandler } from "./aero.js"; + +import { AeroUtilities } from "./AeroUtilities.js"; + + + + + +/* + Turn this: + { + _type: "aero-slide-prime", + theme: "dark", + title: `The power of tomorrow`, + subtitle: "Hi There", + paragraph: `this is a very + long text indeed that spread on multiple lines`, + background : { + _type : "pic", + source : "assets/truc0002.jpg" + } + }, + + into this: + +
+
+

Say Hello to OCTOFAN

+

The world's first H2-powered multirole heavy duty drone with + switchable nacelles

+
+
+
+
+*/ + + + +export class Grid extends AeroElement { + + /** @type {HTMLElement } */ + sectionNode; + + type; + + props; + + /** @type {HTMLDivElement} */ + deckNode; + + + /** @type{boolean} */ + hasBackgroundImage = false; + + /** @type{boolean} */ + isBackgroundImageLoaded = false; + + /** @type{string} */ + backgroundImagePath; + + constructor(type, props) { + super(); + this.type = type; + this.props = props; + } + + + /** + * + * @param {WebPage} page + * @param {*} state + * @returns + */ + build(page) { + + /* CSS requirements */ + page.css_requireStylesheet("/aero/Grid.css"); + + /* build nodes */ + this.sectionNode = document.createElement("section"); + this.sectionNode.classList.add("aero-grid"); + + this.setType(this.type); + this.setTheme(this.props.theme ? this.props.theme : "light"); + + + /* */ + if (this.props.backgroundImage) { + this.sectionNode.classList.add("background-pic"); + AeroUtilities.loadBackgroundImage(this.sectionNode, this.props.backgroundImage); + } + else if (this.props.backgroundColor) { + this.sectionNode.classList.add("background-colo"); + this.sectionNode.style.backgroundColor = this.props.backgroundColor; + } + /* */ + + /* */ + + this.deckNode = document.createElement("div"); + this.deckNode.classList.add("aero-grid-deck"); + + this.props.cards.forEach(card => this.deckNode.appendChild(card.build(page))); + + this.sectionNode.appendChild(this.deckNode); + + + /* */ + + return this.sectionNode; + } + + + setType(type) { + this.sectionNode.setAttribute("type", type); + } + + setTheme(theme) { + this.sectionNode.setAttribute("theme", theme); + } + + + render(state) { + if (!this.isInitialized) { + this.draw(); + this.isInitialized = true; + } + } + + draw() { + + } + +} + + +export class GridCard extends AeroElement { + + /** @type {HTMLDivElement } */ + cardNode; + + type; + + props; + + /** @type {HTMLDivElement} */ + assetNode; + + + /** @type{boolean} */ + hasBackgroundImage = false; + + /** @type{boolean} */ + isBackgroundImageLoaded = false; + + /** @type{string} */ + backgroundImagePath; + + constructor(type, props) { + super(); + this.type = type; + this.props = props; + } + + /** + * + * @param {LoadHandler} handler + * @param {*} state + * @returns + */ + build(page) { + this.cardNode = document.createElement("div"); + this.cardNode.classList.add("aero-grid-card"); + + + /* */ + if (this.props.backgroundImage) { + this.cardNode.classList.add("background-pic"); + AeroUtilities.loadBackgroundImage(this.cardNode, this.props.backgroundImage); + } + else if (this.props.backgroundColor) { + this.cardNode.classList.add("background-color"); + this.cardNode.style.backgroundColor = this.props.backgroundColor; + } + /* */ + + + this.setType(this.type); + this.setTheme(this.props.theme ? this.props.theme : "light"); + + return this.cardNode; + } + + + setType(type) { + this.cardNode.setAttribute("type", type); + } + + setTheme(theme) { + this.cardNode.setAttribute("theme", theme); + } + + + +} \ No newline at end of file diff --git a/aero/Header.css b/aero/Header.css new file mode 100644 index 0000000..9605034 --- /dev/null +++ b/aero/Header.css @@ -0,0 +1,320 @@ +/*
*/ +header { + background-color: rgb(255, 255, 255); + /*width: 100%;*/ + width: 100vw; + color: black; +} + +.aero-header-placeholder { + width: 100vw; + height: 64px; +} + +.aero-header-flying { + width: 100vw; + height: 64px; + position: fixed; + top: 0px; + left: 0px; + z-index: 128; +} + +.aero-header-bar { + height: 64px; +} + +/* */ +header[theme="light"] > .aero-header-placeholder { + background-color: rgb(255, 255, 255); + color: black; +} + +header[theme="dark"] > .aero-header-placeholder { + background-color: rgb(0, 0, 0); + color: rgb(255, 255, 255); +} +/* */ + + +/* */ +header[theme="light"] > .aero-header-flying { + background-color: rgb(255, 255, 255); +} + +header[theme="dark"] > .aero-header-flying { + background-color: rgb(0, 0, 0); +} +/* */ + + +/* */ +header[theme="light"] .aero-header-bar { + background-color: rgb(255, 255, 255); + color: black; + border-bottom: solid 1px rgba(192, 192, 192, 0.76); +} + +header[theme="dark"] .aero-header-bar { + background-color: rgb(0, 0, 0); + color: rgb(255, 255, 255); + border-bottom: solid 1px rgba(64, 64, 64, 0.76); +} +/* */ + + +header[theme="dark"] > .aero-header-bar, header[theme="dark"] > .aero-header-placeholder { + background-color: rgb(0, 0, 0); + color: rgb(255, 255, 255); +} + + + +.aero-header-menu>a { + color: rgb(64, 64, 64); + text-decoration: none; + font-family: "HelveticaNeue-Light", "Helvetica Neue Light", + "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; + font-size: 14px; + font-weight: bold; +} + + +.menu-login { + width: 64px; + cursor: pointer; +} + +.menu-login:hover>img { + fill: blue; +} + +.menu-login>img>svg { + fill: black; +} + + + + +/* */ + +/*
*/ \ No newline at end of file diff --git a/aero/HeaderV2.js b/aero/HeaderV2.js new file mode 100644 index 0000000..dc32bf2 --- /dev/null +++ b/aero/HeaderV2.js @@ -0,0 +1,402 @@ +import { AeroElement } from "./AeroElement.js"; +import { WebPage } from "./WebPage.js"; +import { clearChildNodes } from "./aero.js"; + +/* +export const MENUS = ["Home", "Technology", "Applications", "Team", "Contact"]; +export const HREF = ["/index.html", "/technology.html", "/applications.html", "/team.html", "/contact.html"]; +*/ + +/** + * + */ +export class HeaderV2 extends AeroElement { + + /** @type{HTMLHeadElement} */ + headerNode; + + /** + * @type{Nav} + */ + nav; + + /** + * @type{Social} + */ + social; + + /** + * @type {boolean} + */ + isNavVisible; + + + /** + * @type{String} + * Color of the flat elements (icon/logo) + */ + flatColor; + + /** + * + * @param {HTMLElement} sources + */ + constructor(page, sources) { + super(); + + this.flatColor = "black"; + let val; + this.theme = (val = sources.getAttribute("theme")) ? val : "light"; + switch (this.theme) { + default: + case "light": this.flatColor = "black"; break; + case "dark": this.flatColor = "white"; break; + } + + this.logo = (val = sources.getAttribute("logo")) ? val : "light"; + + /* CSS requirements */ + page.css_requireStylesheet("/aero/Header.css"); + + /* build nodes */ + this.headerNode = document.createElement('header'); + this.headerNode.setAttribute("theme", this.theme); + this.isLandscape = page.isLandscape; + + /* build menus */ + let node = sources.firstChild; + while (node) { + if (node.nodeName.toLowerCase() == "nav") { + this.nav = new Nav(node); + } + else if (node.nodeName.toLowerCase() == "social") { + this.social = new Social(node); + } + + /* save next node */ + node = node.nextSibling; + } + + this.draw(page, sources); + } + + + /** + * + * @param {WebPage} page + * @param {HTMLElement} sourceNode + * + * @returns {HTMLElement} + */ + html_getNode() { + + /* return wrapper node */ + return this.headerNode; + } + + load() { /* nothing to load here */ } + + /** + * + * @param {WebPage} page + * @returns {} + */ + render(page) { + if (page.isLandscape != this.isLandscape) { // repaint + this.isLandscape = page.isLandscape; + clearChildNodes(this.headerNode); + this.draw(); + } + } + + draw() { + + const placeholderNode = document.createElement("div"); + placeholderNode.classList.add("aero-header-placeholder"); + this.headerNode.appendChild(placeholderNode); + + const flyingNode = document.createElement("div"); + flyingNode.classList.add("aero-header-flying"); + + const barNode = document.createElement("div"); + barNode.classList.add("aero-header-bar"); + if (this.isLandscape) { + this.drawLandscape(barNode); + } + else { + this.drawPortrait(barNode); + } + flyingNode.appendChild(barNode); + this.headerNode.appendChild(flyingNode); + + + + let lastKnowScrollY = 0; + let deltaScrollY = 0; + let upwardDeltaScrollY = 0; + let ticking = false; + let barPositionY = 0; + let previousMove = 0; /* O :undefined, -1:upward, +1:downward */ + + + const udpateBarPosition = function (y) { flyingNode.style.top = `${y}px`; } + + window.addEventListener("scroll", function (e) { + deltaScrollY = window.scrollY - lastKnowScrollY; + lastKnowScrollY = window.scrollY; + + if (deltaScrollY < 0) { /* going upward, deltaScrollY < 0 */ + //if(previousMove != -1){ barPositionY = -68; } + barPositionY -= deltaScrollY; + + //previousMove = -1; + } + else { /* downward, deltaScrollY > 0 */ + barPositionY -= deltaScrollY; + + //previousMove = 1; + } + if (barPositionY > 0) { barPositionY = 0; } + if (barPositionY < -65) { barPositionY = -65; } + console.log(`barPositionY: ${barPositionY}`); + + if (!ticking) { + window.requestAnimationFrame(function () { + udpateBarPosition(barPositionY); + ticking = false; + }); + } + + ticking = true; + }); + } + + + drawLandscape(barNode) { + + /* */ + let menuLogoNode = document.createElement("div"); + menuLogoNode.classList.add("aero-header-logo"); + let frontImgNode = document.createElement("img"); + frontImgNode.src = this.logo; + frontImgNode.alt = "logo"; + menuLogoNode.appendChild(frontImgNode); + barNode.appendChild(menuLogoNode); + /* */ + + /* */ + + /* */ + if(this.social){ + barNode.appendChild(this.social.html_getNode()); + } + + /* */ + } + + + drawPortrait(barNode) { + + let iconsWrapperNode = document.createElement("div"); + iconsWrapperNode.classList.add("aero-menu-icons-wrapper"); + + /* */ + let menuHandlerNode = document.createElement("div"); + menuHandlerNode.classList.add("menu-handler"); + let menuHandlerImgNode = document.createElement("img"); + menuHandlerImgNode.src = `/icons/menu-${this.flatColor}.svg`; + menuHandlerImgNode.alt = "menu"; + menuHandlerNode.appendChild(menuHandlerImgNode); + iconsWrapperNode.appendChild(menuHandlerNode); + /* */ + + /* */ + let menuLogoNode = document.createElement("div"); + menuLogoNode.classList.add("aero-header-logo"); + let frontImgNode = document.createElement("img"); + frontImgNode.src = this.logo; + frontImgNode.alt = "logo"; + menuLogoNode.appendChild(frontImgNode); + iconsWrapperNode.appendChild(menuLogoNode); + /* */ + + barNode.appendChild(iconsWrapperNode); + + let navNode = this.nav.html_getNode(); + + barNode.appendChild(navNode); + + this.isNavVisible = false; // hidden by default in portrait + navNode.style.visibility = "hidden"; + let _this = this; + menuHandlerNode.addEventListener("click", function () { + navNode.style.visibility = _this.isNavVisible ? "hidden" : "visible"; + _this.isNavVisible = !_this.isNavVisible; + }, false); + + /* */ + iconsWrapperNode.appendChild(this.social.html_getNode()); + /* */ + } + + + + buildNavNode() { + + /* */ + + return navNode; + } + + + buildLoginNode() { + /* */ + const loginNode = document.createElement("a"); + + loginNode.href = "https://app.alphaventor.com"; + + loginNode.classList.add("menu-login"); + let loginImgNode = document.createElement("img"); + loginImgNode.src = `/icons/login-${this.flatColor}.svg`; + loginImgNode.alt = "login"; + loginNode.appendChild(loginImgNode); + return loginNode; + /* */ + } + + /** + * + * @param {AeroWebPage} page + */ + link(page) { + this.page = page; + page.import_CSS("aero/AeroHeader.css"); + } + + isLoaded() { + return this.isInitialized; + } +} + + + +class Nav { + + /** + * @type{Array} + */ + menus = new Array(); + + constructor(sources){ + let node = sources.firstChild; + while (node) { + if (node.nodeName.toLowerCase() == "menu") { + this.menus.push(new Menu(node)); + } + + /* save next node */ + node = node.nextSibling; + } + + /* */ + + this.navNode = navNode; + } + + html_getNode(){ return this.navNode; } + +} + + +class Menu { + + constructor(source){ + let listItemNode = document.createElement('li'); + listItemNode.classList.add("aero-header-menu") + + let isSelected = (source.getAttribute("selected") != undefined); + if (isSelected) { + listItemNode.setAttribute("selected", ""); + } + + let aNode = document.createElement("a"); + aNode.href = isSelected ? "/" : source.getAttribute("to"); + aNode.innerHTML = source.innerHTML; + listItemNode.appendChild(aNode); + this.listItemNode = listItemNode; + } + + + html_getNode(){ + return this.listItemNode; + } + +} + + +class Social { + + + /** + * @type{Array} + */ + links = new Array(); + + constructor(sources){ + let node = sources.firstChild; + while (node) { + if (node.nodeName.toLowerCase() == "a") { + this.links.push(new Link(node)); + } + + /* save next node */ + node = node.nextSibling; + } + + /* */ + let socialNode = document.createElement('div'); + socialNode.classList.add("aero-header-social"); + this.links.forEach(link => socialNode.appendChild(link.html_getNode())); + /* */ + + this.socialNode = socialNode; + } + + html_getNode(){ return this.socialNode; } +} + +class Link { + + constructor(sources){ + /* */ + const loginNode = document.createElement("a"); + + loginNode.href = sources.getAttribute("to"); + + loginNode.classList.add("aero-header-social-link"); + let loginImgNode = document.createElement("img"); + loginImgNode.src = sources.getAttribute("pic"); + loginImgNode.alt = "login"; + loginNode.appendChild(loginImgNode); + this.loginNode = loginNode; + /* */ + } + + html_getNode(){ return this.loginNode; } + +} \ No newline at end of file diff --git a/aero/Icon.js b/aero/Icon.js new file mode 100644 index 0000000..5cf6c62 --- /dev/null +++ b/aero/Icon.js @@ -0,0 +1,45 @@ +import { AeroUtilities } from "./AeroUtilities.js"; + + + + +export class Icon { + + constructor(pathname, props) { + this.pathname = pathname; + this.props = props; + + this.width = props.width ? props.width : 64; + this.height = props.height ? props.height : 64; + + } + + build() { + + this.wrapperNode = document.createElement("div"); + + AeroUtilities.getResourceFromOrigin(this.pathname, "text", responseText => { + this.wrapperNode.innerHTML = responseText; + let svgNode = this.wrapperNode.getElementsByTagName("svg")[0]; + svgNode.setAttribute("width", this.width); + svgNode.setAttribute("height", this.height); + this.svgNode = svgNode; + this.isSVGNodeLoaded = true; + }); + + return this.wrapperNode; + } + + getEnvelope(){ return this.wrapperNode; } + +} + + +export function SVG_inject(target, pathname, width, height){ + AeroUtilities.getResourceFromOrigin(pathname, "text", responseText => { + target.innerHTML = responseText; + const svgNode = target.getElementsByTagName("svg")[0]; + svgNode.setAttribute("width", width ? width : 64); + svgNode.setAttribute("height", height ? height : 64); + }); +} \ No newline at end of file diff --git a/aero/ModalBox.css b/aero/ModalBox.css new file mode 100644 index 0000000..fcff057 --- /dev/null +++ b/aero/ModalBox.css @@ -0,0 +1,141 @@ +/* modal box */ + + +.modalbox-overlay { + position: fixed; + top: 0px; + left: 0px; + width: 100vw; + height: 100vh; + background-color: #808080d9; + z-index: 64; +} + +.modalbox { + position: absolute; + top: 50vh; + left: 50vw; + transform: translate(-50%, -50%); + width: 600px; + background-color: rgb(240, 240, 240); + border-radius: 16px; + border: 1px solid grey; + box-shadow: rgba(64, 64, 64, 0.507) 0px 4px 16px; + display: flex; + flex-direction: row; + padding: 24px; + z-index: 68; +} + + +.modalbox-icon { + width: 120px; + margin: 24px; + background-size: contain; + background-repeat: no-repeat; +} + +.modalbox-icon>svg { + fill: rgb(241, 241, 41); + filter: drop-shadow(0px 1px 4px rgb(0 0 0 / 0.4)); +} + + +.modalbox-main { + font-family: Arial, Helvetica, sans-serif; + display: flex; + flex-direction: column; + padding: 0px; +} + +.modalbox-main>div:last-child { + margin-top: auto; +} + +.modalbox-message { + font-size: 20px; + font-weight: bold; + margin-bottom: 80px; +} + +.modalbox-message>h1 { + margin: 16px 8px 16px 8px; + font-size: 32px; + font-weight: bold; +} + +.modalbox-message>p { + margin: 32px 8px 8px 8px; + font-size: 16px; + font-weight: normal; +} + +.modalbox-validation { + padding: 8px; + display: flex; + flex-direction: row; + justify-content: end; + /* Pack items from the end */ +} + +.modalbox-validation>* { + margin: 2px 8px 2px 8px; + padding: 0px; +} + +.modalbox-button { + border: solid 1px green; + padding: 12px 24px 12px 24px; + border-radius: 8px; + background-color: rgb(18, 173, 18); + color: white; + outline: solid 8px rgba(166, 213, 180, 0.588); + cursor: pointer; + font-size: 20px; +} + +.modalbox-button:hover { + border: solid 1px rgb(1, 144, 1); + background-color: rgb(17, 197, 17); +} + + + + +/*