FIX: linting

This commit is contained in:
Tony Air 2021-08-18 20:51:15 +02:00
parent ac87faa1a8
commit 54b03920c5
110 changed files with 3409 additions and 3363 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "4.2.2", "version": "4.2.3",
"name": "@a2nt/ss-bootstrap-ui-webpack-boilerplate-react", "name": "@a2nt/ss-bootstrap-ui-webpack-boilerplate-react",
"description": "This UI Kit allows you to build Bootstrap 5 webapp with some extra UI features. It's easy to extend and easy to convert HTML templates to CMS templates.", "description": "This UI Kit allows you to build Bootstrap 5 webapp with some extra UI features. It's easy to extend and easy to convert HTML templates to CMS templates.",
"icons": { "icons": {

View File

@ -1,5 +1,5 @@
{ {
"version": "4.2.2", "version": "4.2.3",
"api_version": 1, "api_version": 1,
"layout": { "layout": {
"logo": "yandex-browser-50x50.png", "logo": "yandex-browser-50x50.png",

24
dist/index.html vendored
View File

@ -1,15 +1,15 @@
<!doctype html><html lang="en"><head><title>Webpack Bootstrap 4 UI Demo</title><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="description" content="UI Kit"/><meta name="author" content="Tony Air <tony@twma.pro>"/><meta name="ping" content="/Security/ping"/><meta name="api_url" content="http://127.0.0.1/graphql"/><meta name="api_static_domain" content="http://127.0.0.1"/><meta name="swversion" content="sw-1629311676872"/><base href=""/><script defer="defer" src="js/app.js"></script><script defer="defer" src="js/app_sw.js"></script><script defer="defer" src="js/app_map.api.js"></script><link href="css/app.css" rel="stylesheet"/><link href="css/app_map.api.css" rel="stylesheet"/></head><body data-default-lng="0" data-default-lat="0"><div class="wrapper"><style>@keyframes lds-ellipsis1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes lds-ellipsis2{0%{transform:translate(0,0)}100%{transform:translate(1.35rem,0)}}body,html{font-size:14px;margin:0;padding:0;background:#fff;color:#333;overflow-x:hidden}@media (min-width:2000px){body,html{font-size:.9vw}}#PageLoading{position:fixed;left:0;top:0;margin:0;width:100%!important;height:100%!important;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;z-index:2000;will-change:opacity;background:#212529;color:#212529}#PageLoading .logo{filter:invert(1);margin-left:20px;margin-left:2vw;width:100px;width:12.5vw}#PageLoading .tagline{color:#fff;font-size:1.8rem;font-size:4vh;letter-spacing:.25em}.main-bn{position:fixed;top:0;left:0;width:100%;z-index:99999999;padding:.5rem 1rem;text-align:center;color:#fff;background:red}iframe,img{max-width:100%}.loading-spinner{text-align:center}.lds-ellipsis{display:inline-block;position:relative;width:4.57rem;height:1rem;color:#fff}.lds-ellipsis div{position:absolute;top:.15rem;width:.78rem;height:.78rem;border-radius:50%;background:#888;animation-timing-function:cubic-bezier(0,1,1,0)}.lds-ellipsis div:nth-child(1){left:.42rem;animation:lds-ellipsis1 .6s infinite}.lds-ellipsis div:nth-child(2){left:.9rem;animation:lds-ellipsis2 .6s infinite}.lds-ellipsis div:nth-child(3){left:1.85rem;animation:lds-ellipsis2 .6s infinite}.lds-ellipsis div:nth-child(4){left:3.21rem;animation:lds-ellipsis3 .6s infinite}@keyframes lds-text{from{font-size:1em}to{font-size:1.5em}}.lds-text{position:absolute;top:50%;left:50%;margin-left:-5rem;margin-top:8rem;font-size:.8rem;letter-spacing:.25em;color:#fff}.lds-text b{font-weight:300;animation:lds-text 5s ease infinite alternate}.lds-text b:nth-child(1){animation-delay:.5s}.lds-text b:nth-child(2){animation-delay:1s}.lds-text b:nth-child(3){animation-delay:1.5s}.lds-text b:nth-child(4){animation-delay:2s}.lds-text b:nth-child(5){animation-delay:2.5s}.lds-text b:nth-child(6){animation-delay:3s}.lds-text b:nth-child(7){animation-delay:3.5s}.lds-text b:nth-child(8){animation-delay:4s}.lds-text b:nth-child(9){animation-delay:4.5s}.lds-text b:nth-child(10){animation-delay:5s}@media (orientation:portrait){#PageLoading .logo{width:50vw}#PageLoading .tagline{font-size:4vw}}</style><div id="PageLoading"><div class="loading-spinner"><img class="logo" src="../img/logo.svg" width="200" alt="UI Kit"/><br/><div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div><br/><div class="lds-placeholder">LOADING...</div><div class="lds-text"><b>L</b> <b>O</b> <b>A</b> <b>D</b> <b>I</b> <b>N</b> <b>G</b> <b>.</b> <b>.</b> <b>.</b></div></div></div><div id="SiteWideAlerts" class="offline-message"><div class="alert alert-danger alert-offline alert-dismissible fade show" role="alert"><div class="typography">The Internet connection is missing right now, but you're able to browse previously opened pages offline.</div><button type="button" class="btn btn-danger btn-close" data-bs-dismiss="alert" aria-label="Close"><i class="fas fa-times"></i></button></div><noscript><div class="main-bn alert alert-fixed-top alert-danger" role="alert">Please, enable javascript.</div></noscript><!--[if lt IE 11 <!doctype html><html lang="en"><head><title>Webpack Bootstrap 4 UI Demo</title><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="description" content="UI Kit"/><meta name="author" content="Tony Air <tony@twma.pro>"/><meta name="ping" content="/Security/ping"/><meta name="api_url" content="http://127.0.0.1/graphql"/><meta name="api_static_domain" content="http://127.0.0.1"/><meta name="swversion" content="sw-1629312515135"/><base href=""/><script defer="defer" src="js/app.js"></script><script defer="defer" src="js/app_sw.js"></script><script defer="defer" src="js/app_map.api.js"></script><link href="css/app.css" rel="stylesheet"/><link href="css/app_map.api.css" rel="stylesheet"/></head><body data-default-lng="0" data-default-lat="0"><div class="wrapper"><style>@keyframes lds-ellipsis1{0%{transform:scale(0)}100%{transform:scale(1)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}100%{transform:scale(0)}}@keyframes lds-ellipsis2{0%{transform:translate(0,0)}100%{transform:translate(1.35rem,0)}}body,html{font-size:14px;margin:0;padding:0;background:#fff;color:#333;overflow-x:hidden}@media (min-width:2000px){body,html{font-size:.9vw}}#PageLoading{position:fixed;left:0;top:0;margin:0;width:100%!important;height:100%!important;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;z-index:2000;will-change:opacity;background:#212529;color:#212529}#PageLoading .logo{filter:invert(1);margin-left:20px;margin-left:2vw;width:100px;width:12.5vw}#PageLoading .tagline{color:#fff;font-size:1.8rem;font-size:4vh;letter-spacing:.25em}.main-bn{position:fixed;top:0;left:0;width:100%;z-index:99999999;padding:.5rem 1rem;text-align:center;color:#fff;background:red}iframe,img{max-width:100%}.loading-spinner{text-align:center}.lds-ellipsis{display:inline-block;position:relative;width:4.57rem;height:1rem;color:#fff}.lds-ellipsis div{position:absolute;top:.15rem;width:.78rem;height:.78rem;border-radius:50%;background:#888;animation-timing-function:cubic-bezier(0,1,1,0)}.lds-ellipsis div:nth-child(1){left:.42rem;animation:lds-ellipsis1 .6s infinite}.lds-ellipsis div:nth-child(2){left:.9rem;animation:lds-ellipsis2 .6s infinite}.lds-ellipsis div:nth-child(3){left:1.85rem;animation:lds-ellipsis2 .6s infinite}.lds-ellipsis div:nth-child(4){left:3.21rem;animation:lds-ellipsis3 .6s infinite}@keyframes lds-text{from{font-size:1em}to{font-size:1.5em}}.lds-text{position:absolute;top:50%;left:50%;margin-left:-5rem;margin-top:8rem;font-size:.8rem;letter-spacing:.25em;color:#fff}.lds-text b{font-weight:300;animation:lds-text 5s ease infinite alternate}.lds-text b:nth-child(1){animation-delay:.5s}.lds-text b:nth-child(2){animation-delay:1s}.lds-text b:nth-child(3){animation-delay:1.5s}.lds-text b:nth-child(4){animation-delay:2s}.lds-text b:nth-child(5){animation-delay:2.5s}.lds-text b:nth-child(6){animation-delay:3s}.lds-text b:nth-child(7){animation-delay:3.5s}.lds-text b:nth-child(8){animation-delay:4s}.lds-text b:nth-child(9){animation-delay:4.5s}.lds-text b:nth-child(10){animation-delay:5s}@media (orientation:portrait){#PageLoading .logo{width:50vw}#PageLoading .tagline{font-size:4vw}}</style><div id="PageLoading"><div class="loading-spinner"><img class="logo" src="../img/logo.svg" width="200" alt="UI Kit"/><br/><div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div><br/><div class="lds-placeholder">LOADING...</div><div class="lds-text"><b>L</b> <b>O</b> <b>A</b> <b>D</b> <b>I</b> <b>N</b> <b>G</b> <b>.</b> <b>.</b> <b>.</b></div></div></div><div id="SiteWideAlerts" class="offline-message"><div class="alert alert-danger alert-offline alert-dismissible fade show" role="alert"><div class="typography">The Internet connection is missing right now, but you're able to browse previously opened pages offline.</div><button type="button" class="btn btn-danger btn-close" data-bs-dismiss="alert" aria-label="Close"><i class="fas fa-times"></i></button></div><noscript><div class="main-bn alert alert-fixed-top alert-danger" role="alert">Please, enable javascript.</div></noscript><!--[if lt IE 11
]><div class="main-bn alert alert-danger" role="alert"> ]><div class="main-bn alert alert-danger" role="alert">
<a <a
href="https://www.google.com/chrome/browser/desktop/" href="https://www.google.com/chrome/browser/desktop/"
classs="alert-link" classs="alert-link"
> >
You are using an outdated browser. For a faster, safer browsing You are using an outdated browser. For a faster, safer browsing
experience, upgrade for free today. experience, upgrade for free today.
</a> </a>
</div><! </div><!
[endif]--></div><noscript><div class="main-bn">Please, enable javascript.</div></noscript><div id="PageTopAnchor"></div><div class="flyout-FlyoutUI"><i class="fas fa-times flyout-FlyoutUI__close"></i><h2 class="flyout-FlyoutUI__title"><i class="fas fa-asterisk"></i> Flyout Demo</h2><div class="flyout-FlyoutUI__content typography"><p>Lipsum .... .... ....</p></div></div><header id="Header" class="stiky-top"><nav id="Navigation" class="navbar navbar-expand-lg"><div class="container"><a class="navbar-brand" href="#">UI Kit</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#NavbarResponsive" aria-controls="NavbarResponsive" aria-expanded="false" aria-label="Toggle navigation"><i class="navbar-toggler-icon fa fas fa-bars"></i></button><div id="NavbarResponsive" class="collapse navbar-collapse"><ul class="navbar-nav"><li class="nav-item active"><a class="nav-link js-scrollTo" href="#PageTopAnchor" data-text="Home">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link js-scrollTo" href="#Slider" data-text="Slider">Slider</a></li><li class="nav-item dropdown dropdown-hover"><a id="NavbarDropdown" class="nav-link dropdown-toggle-fl dropdown-toggle-notouch" href="#" data-text="Dropdown">Dropdown </a><button class="nav-link dropdown-toggle dropdown-toggle-sm dropdown-toggle-touch" role="button" data-bs-toggle="dropdown" aria-expanded="false" type="button">Dropdown</button><div class="dropdown-menu" aria-labelledby="NavbarDropdown"><a class="dropdown-item" href="#">Action</a> <a class="dropdown-item js-scrollTo" href="#AccordionList">Scroll to AccordionList</a><div class="dropdown-divider"></div><a class="dropdown-item" href="https://google.com" target="_blank" rel="nofollow">Go to Google.com</a><div class="dropdown-divider"></div><a class="dropdown-item graphql-page" href="/home">Test dropdown hide on GraphQL</a></div></li><li class="nav-item"><a id="LoadGraphQL" class="nav-link graphql-page" href="/home">Load GraphQL</a></li><li class="nav-item"><a class="nav-link graphql-page" href="/en/aquascaping">Load GraphQL #2</a></li><li class="nav-item"><a class="nav-link js-scrollTo" href="#AccordionList">Accordion List</a></li><li><form class="form-inline my-2 my-lg-0"><input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"/> <button class="btn btn-outline-success my-2 my-sm-0" type="submit"><i class="fas fa-search"></i> <span class="sr-only">Search</span></button></form></li></ul></div></div></nav></header><main id="MainContent" class="page-content"><div class="elemental-area"><div class="element page-header-element"><div class="element-container container"><h1 class="page-header">Webpack Bootstrap 4 UI Demo</h1></div></div><section id="Slider" class="element site__elements__sliderelement"><div class="element-container container-fluid"><div id="Carousel{$ID}" class="carousel slide js-carousel d-none d-sm-block" data-indicators="true" data-arrows="true"><div class="carousel-inner"><div class="carousel-item active"><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"><img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"></a><div class="carousel-caption"><div class="carousel-caption-container"><h2 class="carousel-title">$Headline #1</h2><p class="carousel-content">$Description</p><p><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg"><i class="fas fa-bars"></i> Learn More</a></p></div></div></div><div class="carousel-item"><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"><img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"></a><div class="carousel-caption"><div class="carousel-caption-container"><h2 class="carousel-title">$Headline #2</h2><p class="carousel-content">$Description</p><p><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg"><i class="fas fa-bars"></i> Learn More</a></p></div></div></div><div class="carousel-item"><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"><img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"></a><div class="carousel-caption"><div class="carousel-caption-container"><h2 class="carousel-title">$Headline #3</h2><p class="carousel-content">$Description</p><p><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg"><i class="fas fa-bars"></i> Learn More</a></p></div></div></div></div></div></div></section><section id="Lightbox" class="element dnadesign__elemental__models__elementcontent"><div class="element-container container"><div class="content-element__content"><h2 class="content-element__title">Lightbox Demo</h2><style>[data-toggle=lightbox]:focus,[data-toggle=lightbox]:hover{text-decoration:underline}</style><div id="MetaLightboxContainer"><div class="typography"><h2>Loading data</h2><p><a href="https://via.placeholder.com/1200x600" data-toggle="lightbox" data-gallery="demo" data-title="That's first link">Load an Image</a><br/><a href="public/src/test.json" data-toggle="lightbox">Load JSON</a></p><style>[data-toggle=lightbox]:focus,[data-toggle=lightbox]:hover{text-decoration:underline}</style><br/><a href="public/src/test-pajax.html" data-toggle="lightbox">Load Partial AJAX HTML</a><br/><a href="public/src/not-found.html" data-toggle="lightbox">Not Found test</a><p></p><h2>Embeds</h2><p><a href="https://www.youtube.com/watch?v=WYvZZYthDRI" data-toggle="lightbox" data-embed="true">Embed Youtube link</a><br/><a href="https://vimeo.com/26216129" data-toggle="lightbox" data-embed="true">Embed Vimeo link</a><br/><a href="https://soundcloud.com/littlenapoleon/led-zeppelin-vs-rolling-stones" data-toggle="lightbox" data-embed="true">Embed SoundCloud link</a><br/><a href="https://www.instagram.com/p/CKl5n87hf7R/" data-toggle="lightbox" data-embed="true">Embed Instagram</a></p><h2>Other</h2><p><a href="https://via.placeholder.com/600x600.svg?text=SVG%20Image" data-toggle="lightbox" data-gallery="demo">Use [data-toggle="lightbox"] attribute to attach lightbox action and [href] to specify URL.</a></p><p><a href="https://via.placeholder.com/600x1200.jpg?text=JPG%20Image" data-toggle="lightbox" data-gallery="demo" data-title="Use data-title attribute to specify lightbox title">Use [data-gallery="YOUR_GALLERY_NAME"] to group ligthboxes with next/prev arrows</a></p><p><a href="https://via.placeholder.com/1400x700.png?text=PNG%20Image" data-toggle="lightbox" data-gallery="demo" data-title="Use data-title attribute to specify lightbox title">Use [data-gallery="YOUR_GALLERY_NAME"] to group ligthboxes with next/prev arrows</a></p><p data-toggle="lightbox" data-href="https://youtu.be/GgnClrx8N2k" data-gallery="demo" data-title="Yes you can link vimeo and youtube videos as long as AJAX content">Use [data-toggle="lightbox"] + [data-href] attribute to toggle lightbox on regular elements. <b>Click me!</b></p></div><div id="MetaLightboxApp"></div></div></div></div></section><section id="Content" class="element dnadesign__elemental__models__elementcontent"><div class="element-container container"><div class="content-element__content"><h2 class="content-element__title">Content Demo</h2><div class="typography"><h3><i class="fas fa-search"></i> Quick start</h3><ol><li><p>Clone quick start repository</p><pre> [endif]--></div><noscript><div class="main-bn">Please, enable javascript.</div></noscript><div id="PageTopAnchor"></div><div class="flyout-FlyoutUI"><i class="fas fa-times flyout-FlyoutUI__close"></i><h2 class="flyout-FlyoutUI__title"><i class="fas fa-asterisk"></i> Flyout Demo</h2><div class="flyout-FlyoutUI__content typography"><p>Lipsum .... .... ....</p></div></div><header id="Header" class="stiky-top"><nav id="Navigation" class="navbar navbar-expand-lg"><div class="container"><a class="navbar-brand" href="#">UI Kit</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#NavbarResponsive" aria-controls="NavbarResponsive" aria-expanded="false" aria-label="Toggle navigation"><i class="navbar-toggler-icon fa fas fa-bars"></i></button><div id="NavbarResponsive" class="collapse navbar-collapse"><ul class="navbar-nav"><li class="nav-item active"><a class="nav-link js-scrollTo" href="#PageTopAnchor" data-text="Home">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link js-scrollTo" href="#Slider" data-text="Slider">Slider</a></li><li class="nav-item dropdown dropdown-hover"><a id="NavbarDropdown" class="nav-link dropdown-toggle-fl dropdown-toggle-notouch" href="#" data-text="Dropdown">Dropdown </a><button class="nav-link dropdown-toggle dropdown-toggle-sm dropdown-toggle-touch" role="button" data-bs-toggle="dropdown" aria-expanded="false" type="button">Dropdown</button><div class="dropdown-menu" aria-labelledby="NavbarDropdown"><a class="dropdown-item" href="#">Action</a> <a class="dropdown-item js-scrollTo" href="#AccordionList">Scroll to AccordionList</a><div class="dropdown-divider"></div><a class="dropdown-item" href="https://google.com" target="_blank" rel="nofollow">Go to Google.com</a><div class="dropdown-divider"></div><a class="dropdown-item graphql-page" href="/home">Test dropdown hide on GraphQL</a></div></li><li class="nav-item"><a id="LoadGraphQL" class="nav-link graphql-page" href="/home">Load GraphQL</a></li><li class="nav-item"><a class="nav-link graphql-page" href="/en/aquascaping">Load GraphQL #2</a></li><li class="nav-item"><a class="nav-link js-scrollTo" href="#AccordionList">Accordion List</a></li><li><form class="form-inline my-2 my-lg-0"><input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"/> <button class="btn btn-outline-success my-2 my-sm-0" type="submit"><i class="fas fa-search"></i> <span class="sr-only">Search</span></button></form></li></ul></div></div></nav></header><main id="MainContent" class="page-content"><div class="elemental-area"><div class="element page-header-element"><div class="element-container container"><h1 class="page-header">Webpack Bootstrap 4 UI Demo</h1></div></div><section id="Slider" class="element site__elements__sliderelement"><div class="element-container container-fluid"><div id="Carousel{$ID}" class="carousel slide js-carousel d-none d-sm-block" data-indicators="true" data-arrows="true"><div class="carousel-inner"><div class="carousel-item active"><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"><img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"/></a><div class="carousel-caption"><div class="carousel-caption-container"><h2 class="carousel-title">$Headline #1</h2><p class="carousel-content">$Description</p><p><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg"><i class="fas fa-bars"></i> Learn More</a></p></div></div></div><div class="carousel-item"><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"><img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"/></a><div class="carousel-caption"><div class="carousel-caption-container"><h2 class="carousel-title">$Headline #2</h2><p class="carousel-content">$Description</p><p><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg"><i class="fas fa-bars"></i> Learn More</a></p></div></div></div><div class="carousel-item"><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"><img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"/></a><div class="carousel-caption"><div class="carousel-caption-container"><h2 class="carousel-title">$Headline #3</h2><p class="carousel-content">$Description</p><p><a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg"><i class="fas fa-bars"></i> Learn More</a></p></div></div></div></div></div></div></section><section id="Lightbox" class="element dnadesign__elemental__models__elementcontent"><div class="element-container container"><div class="content-element__content"><h2 class="content-element__title">Lightbox Demo</h2><style>[data-toggle=lightbox]:focus,[data-toggle=lightbox]:hover{text-decoration:underline}</style><div id="MetaLightboxContainer"><div class="typography"><h2>Loading data</h2><p><a href="https://via.placeholder.com/1200x600" data-toggle="lightbox" data-gallery="demo" data-title="That's first link">Load an Image</a><br/><a href="public/src/test.json" data-toggle="lightbox">Load JSON</a></p><style>[data-toggle=lightbox]:focus,[data-toggle=lightbox]:hover{text-decoration:underline}</style><br/><a href="public/src/test-pajax.html" data-toggle="lightbox">Load Partial AJAX HTML</a><br/><a href="public/src/not-found.html" data-toggle="lightbox">Not Found test</a><p></p><h2>Embeds</h2><p><a href="https://www.youtube.com/watch?v=WYvZZYthDRI" data-toggle="lightbox" data-embed="true">Embed Youtube link</a><br/><a href="https://vimeo.com/26216129" data-toggle="lightbox" data-embed="true">Embed Vimeo link</a><br/><a href="https://soundcloud.com/littlenapoleon/led-zeppelin-vs-rolling-stones" data-toggle="lightbox" data-embed="true">Embed SoundCloud link</a><br/><a href="https://www.instagram.com/p/CKl5n87hf7R/" data-toggle="lightbox" data-embed="true">Embed Instagram</a></p><h2>Other</h2><p><a href="https://via.placeholder.com/600x600.svg?text=SVG%20Image" data-toggle="lightbox" data-gallery="demo">Use [data-toggle="lightbox"] attribute to attach lightbox action and [href] to specify URL.</a></p><p><a href="https://via.placeholder.com/600x1200.jpg?text=JPG%20Image" data-toggle="lightbox" data-gallery="demo" data-title="Use data-title attribute to specify lightbox title">Use [data-gallery="YOUR_GALLERY_NAME"] to group ligthboxes with next/prev arrows</a></p><p><a href="https://via.placeholder.com/1400x700.png?text=PNG%20Image" data-toggle="lightbox" data-gallery="demo" data-title="Use data-title attribute to specify lightbox title">Use [data-gallery="YOUR_GALLERY_NAME"] to group ligthboxes with next/prev arrows</a></p><p data-toggle="lightbox" data-href="https://youtu.be/GgnClrx8N2k" data-gallery="demo" data-title="Yes you can link vimeo and youtube videos as long as AJAX content">Use [data-toggle="lightbox"] + [data-href] attribute to toggle lightbox on regular elements. <b>Click me!</b></p></div><div id="MetaLightboxApp"></div></div></div></div></section><section id="Content" class="element dnadesign__elemental__models__elementcontent"><div class="element-container container"><div class="content-element__content"><h2 class="content-element__title">Content Demo</h2><div class="typography"><h3><i class="fas fa-search"></i> Quick start</h3><ol><li><p>Clone quick start repository</p><pre>
git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre></li><li><p>Install npm packages</p><pre> git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre></li><li><p>Install npm packages</p><pre>
cd ./webpack-bootstrap-ui-kit-quick-start.git cd ./webpack-bootstrap-ui-kit-quick-start.git
npm install npm install
</pre></li><li><p>Edit ./src files</p></li><li><p>Start development server at https://127.0.0.1:8001/:</p><pre>yarn start</pre><p>Compile:</p><pre>yarn build</pre></li></ol><h2><i class="fas fa-search"></i> Header #2 <i class="fas fa-search"></i></h2><p><img src="https://via.placeholder.com/200x200" alt="Test Image" class="image right"/>Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p><ol><li>First<ul><li>First</li><li>Second<ol><li>First</li><li>Second</li><li>Third</li></ol><ul><li>First</li><li>Second</li><li>Third</li></ul></li><li><p>Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p></li></ul></li><li><p>{paragraph} Second</p><p>{paragraph} Second #2</p></li><li><p>Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p></li></ol><h2 class="text-center">Responsive Table #1: Default</h2><table><thead><tr><th>Header #1</th><th>Header #2</th><th>Header #3</th></tr></thead><tbody><tr><td data-label="Header #1">#1-1</td><td data-label="Header #2">#1-2</td><td data-label="Header #3">#1-3</td></tr><tr><td data-label="Header #1">#2-1</td><td data-label="Header #2">#2-2</td><td data-label="Header #3">#2-3</td></tr><tr><td data-label="Header #1">#3-1</td><td data-label="Header #2">#3-2</td><td data-label="Header #3">#3-3</td></tr></tbody></table><p class="text-justify">Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p><h2 class="text-center">Responsive Table #2: Border-less</h2><table class="table-none"><thead><tr><th>Header #1</th><th>Header #2</th><th>Header #3</th></tr></thead><tbody><tr><td data-label="Header #1">#1-1</td><td data-label="Header #2">#1-2</td><td data-label="Header #3">#1-3</td></tr><tr><td data-label="Header #1">#2-1</td><td data-label="Header #2">#2-2</td><td data-label="Header #3">#2-3</td></tr><tr><td data-label="Header #1">#3-1</td><td data-label="Header #2">#3-2</td><td data-label="Header #3">#3-3</td></tr></tbody></table></div></div></div></section><section id="List" class="element dnadesign__elementallist__model__elementlist bg-dark"><div class="element-container container"><h2 class="list-element__title">Content Header</h2><div class="typography">Some content ...</div><div class="list-element__container row" data-listelement-count="4"><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div></div></div></section><section id="AccordionList" class="element site__elements__accordion"><div class="element-container container"><h2 class="list-element__title">Accordion demo</h2><div class="typography">Some content ...</div><div id="AccordionExample" class="list-element__container accordion" data-listelement-count="4"><div class="accordion-item"><h2 class="accordion-header" id="headingOne"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">Accordion Item #1</button></h2><div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#AccordionExample"><div class="accordion-body"><strong>This is the first item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.</div></div></div><div class="accordion-item"><h2 class="accordion-header" id="headingTwo"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">Accordion Item #2</button></h2><div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#AccordionExample"><div class="accordion-body"><strong>This is the second item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.</div></div></div><div class="accordion-item"><h2 class="accordion-header" id="headingThree"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">Accordion Item #3</button></h2><div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#AccordionExample"><div class="accordion-body"><strong>This is the third item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.</div></div></div></div></div></section><section id="MapElement" class="element site__elements__mapelement"><div class="element-container container"><h2 class="content-element__title">Find Location</h2><div class="typography"><p>Use _consts.js to change Google Maps to Mapbox.</p></div><div class="mapAPI-map-container" data-map-zoom="12" data-key="" data-map-style="mapbox://styles/mapbox/streets-v9" data-geojson="{&quot;type&quot;:&quot;MarkerCollection&quot;,&quot;features&quot;:[{&quot;id&quot;:4,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin4\&quot; data-id=\&quot;4\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #1&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;17 Lakeside Drive&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8827743,-74.4276612\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-74.4276612,40.8827743]}},{&quot;id&quot;:3,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin3\&quot; data-id=\&quot;3\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #2&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;Flower Hill Cemetery&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; N&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.7884708,-74.0249253\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-74.0249253,40.7884708]}},{&quot;id&quot;:2,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin2\&quot; data-id=\&quot;2\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #3&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;555 Phoenix Road&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8527479,-78.2475576\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-78.2475576,40.8527479]}},{&quot;id&quot;:1,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin1\&quot; data-id=\&quot;1\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #4&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;15 East Hadley Road&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/42.3297023,-72.5552186\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-72.5552186,42.3297023]}}]}" data-fly-to-marker="true" data-fly-to-bounds="false"><div class="mapAPI-map"></div></div><div class="locations"><div class="row"><div class="col-sm-3"><div id="MapPin4" data-id="4" class="location"><div class="fn">Office #1</div><div class="addr">17 Lakeside Drive</div><div class="d-none">U</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/40.8827743,-74.4276612" target="_blank">Get Directions &raquo;</a></div></div></div><div class="col-sm-3"><div id="MapPin3" data-id="3" class="location"><div class="fn">Office #2</div><div class="addr">Flower Hill Cemetery</div><div class="d-none">N</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/40.7884708,-74.0249253" target="_blank">Get Directions &raquo;</a></div></div></div><div class="col-sm-3"><div id="MapPin2" data-id="2" class="location"><div class="fn">Office #3</div><div class="addr">555 Phoenix Road</div><div class="d-none">U</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/40.8527479,-78.2475576" target="_blank">Get Directions &raquo;</a></div></div></div><div class="col-sm-3"><div id="MapPin1" data-id="1" class="location"><div class="fn">Office #4</div><div class="addr">15 East Hadley Road</div><div class="d-none">U</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/42.3297023,-72.5552186" target="_blank">Get Directions &raquo;</a></div></div></div></div></div></div></section></div></main></div><footer id="Footer" class="footer site-footer"><div class="wrapper"><div class="container"><div class="row"><div class="col-sm-3">Col #1</div><div class="col-sm-3">Col #2</div><div class="col-sm-3">Col #3</div><div class="col-sm-3">Col #4</div></div></div></div><div class="footer"><div class="container"><div class="row"><div class="col-sm-8 d-md-flex"><div class="copyright">Copyright &copy; 2019 - Tony Air (A2nt) Webpack Bootstrap 4 UI Kit</div><nav class="footer-nav"><ul class="list-inline d-flex"><li><a href="#">Sitemap</a></li><li><a href="#">Privacy Policy</a></li></ul></nav></div><div class="col-sm-4"><div class="text-end credits footer__credits"><a href="https://github.com/a2nt" target="_blank" rel="nofollow"><span>Developed by</span> Tony Air</a></div></div></div></div></div></footer><script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css" media="all"/></body></html> </pre></li><li><p>Edit ./src files</p></li><li><p>Start development server at https://127.0.0.1:8001/:</p><pre>yarn start</pre><p>Compile:</p><pre>yarn build</pre></li></ol><h2><i class="fas fa-search"></i> Header #2 <i class="fas fa-search"></i></h2><p><img src="https://via.placeholder.com/200x200" alt="Test Image" class="image right"/>Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p><ol><li>First<ul><li>First</li><li>Second<ol><li>First</li><li>Second</li><li>Third</li></ol><ul><li>First</li><li>Second</li><li>Third</li></ul></li><li><p>Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p></li></ul></li><li><p>{paragraph} Second</p><p>{paragraph} Second #2</p></li><li><p>Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p></li></ol><h2 class="text-center">Responsive Table #1: Default</h2><table><thead><tr><th>Header #1</th><th>Header #2</th><th>Header #3</th></tr></thead><tbody><tr><td data-label="Header #1">#1-1</td><td data-label="Header #2">#1-2</td><td data-label="Header #3">#1-3</td></tr><tr><td data-label="Header #1">#2-1</td><td data-label="Header #2">#2-2</td><td data-label="Header #3">#2-3</td></tr><tr><td data-label="Header #1">#3-1</td><td data-label="Header #2">#3-2</td><td data-label="Header #3">#3-3</td></tr></tbody></table><p class="text-justify">Content Text Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p><h2 class="text-center">Responsive Table #2: Border-less</h2><table class="table-none"><thead><tr><th>Header #1</th><th>Header #2</th><th>Header #3</th></tr></thead><tbody><tr><td data-label="Header #1">#1-1</td><td data-label="Header #2">#1-2</td><td data-label="Header #3">#1-3</td></tr><tr><td data-label="Header #1">#2-1</td><td data-label="Header #2">#2-2</td><td data-label="Header #3">#2-3</td></tr><tr><td data-label="Header #1">#3-1</td><td data-label="Header #2">#3-2</td><td data-label="Header #3">#3-3</td></tr></tbody></table></div></div></div></section><section id="List" class="element dnadesign__elementallist__model__elementlist bg-dark"><div class="element-container container"><h2 class="list-element__title">Content Header</h2><div class="typography">Some content ...</div><div class="list-element__container row" data-listelement-count="4"><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div><div class="element dnadesign__elemental__models__elementcontent block col-md-3"><div class="element-container"><div class="content-element__content"><div class="typography"><img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100"/></div></div></div></div></div></div></section><section id="AccordionList" class="element site__elements__accordion"><div class="element-container container"><h2 class="list-element__title">Accordion demo</h2><div class="typography">Some content ...</div><div id="AccordionExample" class="list-element__container accordion" data-listelement-count="4"><div class="accordion-item"><h2 class="accordion-header" id="headingOne"><button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">Accordion Item #1</button></h2><div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#AccordionExample"><div class="accordion-body"><strong>This is the first item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.</div></div></div><div class="accordion-item"><h2 class="accordion-header" id="headingTwo"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">Accordion Item #2</button></h2><div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#AccordionExample"><div class="accordion-body"><strong>This is the second item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.</div></div></div><div class="accordion-item"><h2 class="accordion-header" id="headingThree"><button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">Accordion Item #3</button></h2><div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#AccordionExample"><div class="accordion-body"><strong>This is the third item's accordion body.</strong> It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the <code>.accordion-body</code>, though the transition does limit overflow.</div></div></div></div></div></section><section id="MapElement" class="element site__elements__mapelement"><div class="element-container container"><h2 class="content-element__title">Find Location</h2><div class="typography"><p>Use _consts.js to change Google Maps to Mapbox.</p></div><div class="mapAPI-map-container" data-map-zoom="12" data-key="" data-map-style="mapbox://styles/mapbox/streets-v9" data-geojson='{"type":"MarkerCollection","features":[{"id":4,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin4\" data-id=\"4\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #1&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;17 Lakeside Drive&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8827743,-74.4276612\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-74.4276612,40.8827743]}},{"id":3,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin3\" data-id=\"3\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #2&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;Flower Hill Cemetery&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; N&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.7884708,-74.0249253\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-74.0249253,40.7884708]}},{"id":2,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin2\" data-id=\"2\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #3&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;555 Phoenix Road&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8527479,-78.2475576\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-78.2475576,40.8527479]}},{"id":1,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin1\" data-id=\"1\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #4&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;15 East Hadley Road&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/42.3297023,-72.5552186\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-72.5552186,42.3297023]}}]}' data-fly-to-marker="true" data-fly-to-bounds="false"><div class="mapAPI-map"></div></div><div class="locations"><div class="row"><div class="col-sm-3"><div id="MapPin4" data-id="4" class="location"><div class="fn">Office #1</div><div class="addr">17 Lakeside Drive</div><div class="d-none">U</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/40.8827743,-74.4276612" target="_blank">Get Directions &raquo;</a></div></div></div><div class="col-sm-3"><div id="MapPin3" data-id="3" class="location"><div class="fn">Office #2</div><div class="addr">Flower Hill Cemetery</div><div class="d-none">N</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/40.7884708,-74.0249253" target="_blank">Get Directions &raquo;</a></div></div></div><div class="col-sm-3"><div id="MapPin2" data-id="2" class="location"><div class="fn">Office #3</div><div class="addr">555 Phoenix Road</div><div class="d-none">U</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/40.8527479,-78.2475576" target="_blank">Get Directions &raquo;</a></div></div></div><div class="col-sm-3"><div id="MapPin1" data-id="1" class="location"><div class="fn">Office #4</div><div class="addr">15 East Hadley Road</div><div class="d-none">U</div><div class="dir-link"><a href="https://www.google.com/maps/dir/Current+Location/42.3297023,-72.5552186" target="_blank">Get Directions &raquo;</a></div></div></div></div></div></div></section></div></main></div><footer id="Footer" class="footer site-footer"><div class="wrapper"><div class="container"><div class="row"><div class="col-sm-3">Col #1</div><div class="col-sm-3">Col #2</div><div class="col-sm-3">Col #3</div><div class="col-sm-3">Col #4</div></div></div></div><div class="footer"><div class="container"><div class="row"><div class="col-sm-8 d-md-flex"><div class="copyright">Copyright &copy; 2019 - Tony Air (A2nt) Webpack Bootstrap 4 UI Kit</div><nav class="footer-nav"><ul class="list-inline d-flex"><li><a href="#">Sitemap</a></li><li><a href="#">Privacy Policy</a></li></ul></nav></div><div class="col-sm-4"><div class="text-end credits footer__credits"><a href="https://github.com/a2nt" target="_blank" rel="nofollow"><span>Developed by</span> Tony Air</a></div></div></div></div></div></footer><script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script><script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css" media="all"/></body></html>

2
dist/js/app.js vendored

File diff suppressed because one or more lines are too long

2
dist/js/app_sw.js vendored
View File

@ -1 +1 @@
!function(){var e={857:function(e){e.exports=function log(e){false}},287:function(e){Cache.prototype.add||(Cache.prototype.add=function add(e){return this.addAll([e])}),Cache.prototype.addAll||(Cache.prototype.addAll=function addAll(e){var t=this;function NetworkError(e){this.name="NetworkError",this.code=19,this.message=e}return NetworkError.prototype=Object.create(Error.prototype),Promise.resolve().then((function(){if(arguments.length<1)throw new TypeError;return e=e.map((function(e){return e instanceof Request?e:String(e)})),Promise.all(e.map((function(e){"string"===typeof e&&(e=new Request(e));var t=new URL(e.url).protocol;if("http:"!==t&&"https:"!==t)throw new NetworkError("Invalid scheme");return fetch(e.clone())})))})).then((function(n){return Promise.all(n.map((function(n,r){return t.put(e[r],n)})))})).then((function(){}))}),CacheStorage.prototype.match||(CacheStorage.prototype.match=function match(e,t){var n=this;return this.keys().then((function(r){var o;return r.reduce((function(r,a){return r.then((function(){return o||n.open(a).then((function(n){return n.match(e,t)})).then((function(e){return o=e}))}))}),Promise.resolve())}))}),e.exports=self.caches}},t={};function __webpack_require__(n){var r=t[n];if(void 0!==r)return r.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,__webpack_require__),o.exports}!function(){var e="".concat("@a2nt/ss-bootstrap-ui-webpack-boilerplate-react","-sw"),t="".concat("4.2.2","-sw"),n=__webpack_require__(857),r=__webpack_require__(287);if("string"!==typeof e)throw new Error("Cache Name cannot be empty");self.addEventListener("fetch",(function(t){if("GET"===t.request.method){var o=new URL(t.request.url);if(o.pathname.indexOf("admin")>=0||o.pathname.indexOf("Security")>=0||o.pathname.indexOf("/dev")>=0)n("SW: skip admin ".concat(t.request.url));else{var a=t.request.clone(),c=t.request.clone();t.respondWith(fetch(a).then((function(n){var o=n.clone();return r.open(e).then((function(e){var n=t.request.clone();e.put(n,o)})),n})).catch((function(e){return n("SW: fetch failed"),r.match(c)})))}}})),self.addEventListener("activate",(function(o){n("SW: activated: ".concat(t)),o.waitUntil(r.delete(e))})),self.addEventListener("install",(function(e){n("SW: installing version: ".concat(t))}))}()}(); !function(){var e={857:function(e){e.exports=function log(e){false}},287:function(e){Cache.prototype.add||(Cache.prototype.add=function add(e){return this.addAll([e])}),Cache.prototype.addAll||(Cache.prototype.addAll=function addAll(e){var t=this;function NetworkError(e){this.name="NetworkError",this.code=19,this.message=e}return NetworkError.prototype=Object.create(Error.prototype),Promise.resolve().then((function(){if(arguments.length<1)throw new TypeError;return e=e.map((function(e){return e instanceof Request?e:String(e)})),Promise.all(e.map((function(e){"string"===typeof e&&(e=new Request(e));var t=new URL(e.url).protocol;if("http:"!==t&&"https:"!==t)throw new NetworkError("Invalid scheme");return fetch(e.clone())})))})).then((function(n){return Promise.all(n.map((function(n,r){return t.put(e[r],n)})))})).then((function(){}))}),CacheStorage.prototype.match||(CacheStorage.prototype.match=function match(e,t){var n=this;return this.keys().then((function(r){var o;return r.reduce((function(r,a){return r.then((function(){return o||n.open(a).then((function(n){return n.match(e,t)})).then((function(e){return o=e}))}))}),Promise.resolve())}))}),e.exports=self.caches}},t={};function __webpack_require__(n){var r=t[n];if(void 0!==r)return r.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,__webpack_require__),o.exports}!function(){var e="".concat("@a2nt/ss-bootstrap-ui-webpack-boilerplate-react","-sw"),t="".concat("4.2.3","-sw"),n=__webpack_require__(857),r=__webpack_require__(287);if("string"!==typeof e)throw new Error("Cache Name cannot be empty");self.addEventListener("fetch",(function(t){if("GET"===t.request.method){var o=new URL(t.request.url);if(o.pathname.indexOf("admin")>=0||o.pathname.indexOf("Security")>=0||o.pathname.indexOf("/dev")>=0)n("SW: skip admin ".concat(t.request.url));else{var a=t.request.clone(),c=t.request.clone();t.respondWith(fetch(a).then((function(n){var o=n.clone();return r.open(e).then((function(e){var n=t.request.clone();e.put(n,o)})),n})).catch((function(e){return n("SW: fetch failed"),r.match(c)})))}}})),self.addEventListener("activate",(function(o){n("SW: activated: ".concat(t)),o.waitUntil(r.delete(e))})),self.addEventListener("install",(function(e){n("SW: installing version: ".concat(t))}))}()}();

54
dist/records.json vendored
View File

@ -73,60 +73,6 @@
898 898
] ]
}, },
"mini-css-extract-plugin /mnt/data/srv/dist/repositories/webpack-bootstrap-ui-kit/node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/.pnpm/resolve-url-loader@4.0.0/node_modules/resolve-url-loader/index.js!./node_modules/.pnpm/sass-loader@12.1.0_sass@1.38.0+webpack@5.50.0/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./node_modules/.pnpm/@a2nt+meta-lightbox-js@4.0.8_debug@4.3.2/node_modules/@a2nt/meta-lightbox-js/src/scss/app.scss": [
{
"chunks": {
"byName": {
"child": 396
},
"bySource": {
"0 child": 396
},
"usedIds": [
396
]
},
"modules": {
"byIdentifier": {
"./node_modules/.pnpm/babel-loader@8.2.2_6a7208b678074d97b8e10779794541f1/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!./node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/runtime/api.js": 149,
"./node_modules/.pnpm/babel-loader@8.2.2_6a7208b678074d97b8e10779794541f1/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!./node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/runtime/cssWithMappingToString.js": 686,
"./node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/.pnpm/resolve-url-loader@4.0.0/node_modules/resolve-url-loader/index.js!./node_modules/.pnpm/sass-loader@12.1.0_sass@1.38.0+webpack@5.50.0/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./node_modules/.pnpm/@a2nt+meta-lightbox-js@4.0.8_debug@4.3.2/node_modules/@a2nt/meta-lightbox-js/src/scss/app.scss": 218
},
"usedIds": [
149,
218,
686
]
}
}
],
"mini-css-extract-plugin /mnt/data/srv/dist/repositories/webpack-bootstrap-ui-kit/node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/.pnpm/resolve-url-loader@4.0.0/node_modules/resolve-url-loader/index.js!./node_modules/.pnpm/sass-loader@12.1.0_sass@1.38.0+webpack@5.50.0/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./node_modules/.pnpm/@a2nt+meta-lightbox-js@4.0.8_debug@4.3.2/node_modules/@a2nt/meta-lightbox-js/src/scss/test-build.scss": [
{
"chunks": {
"byName": {
"child": 396
},
"bySource": {
"0 child": 396
},
"usedIds": [
396
]
},
"modules": {
"byIdentifier": {
"./node_modules/.pnpm/babel-loader@8.2.2_6a7208b678074d97b8e10779794541f1/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!./node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/runtime/api.js": 149,
"./node_modules/.pnpm/babel-loader@8.2.2_6a7208b678074d97b8e10779794541f1/node_modules/babel-loader/lib/index.js??ruleSet[1].rules[0].use!./node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/runtime/cssWithMappingToString.js": 686,
"./node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/.pnpm/resolve-url-loader@4.0.0/node_modules/resolve-url-loader/index.js!./node_modules/.pnpm/sass-loader@12.1.0_sass@1.38.0+webpack@5.50.0/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./node_modules/.pnpm/@a2nt+meta-lightbox-js@4.0.8_debug@4.3.2/node_modules/@a2nt/meta-lightbox-js/src/scss/test-build.scss": 513
},
"usedIds": [
149,
513,
686
]
}
}
],
"mini-css-extract-plugin /mnt/data/srv/dist/repositories/webpack-bootstrap-ui-kit/node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/.pnpm/resolve-url-loader@4.0.0/node_modules/resolve-url-loader/index.js!./node_modules/.pnpm/sass-loader@12.1.0_sass@1.38.0+webpack@5.50.0/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./src/scss/test-build.scss": [ "mini-css-extract-plugin /mnt/data/srv/dist/repositories/webpack-bootstrap-ui-kit/node_modules/.pnpm/css-loader@6.2.0_webpack@5.50.0/node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[1].use[1]!./node_modules/.pnpm/resolve-url-loader@4.0.0/node_modules/resolve-url-loader/index.js!./node_modules/.pnpm/sass-loader@12.1.0_sass@1.38.0+webpack@5.50.0/node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./src/scss/test-build.scss": [
{ {
"chunks": { "chunks": {

4
dist/report.html vendored

File diff suppressed because one or more lines are too long

View File

@ -8,118 +8,118 @@
* - Please do NOT serve this file on production. * - Please do NOT serve this file on production.
*/ */
const INTEGRITY_CHECKSUM = 'f0a916b13c8acc2b526a03a6d26df85f' const INTEGRITY_CHECKSUM = "f0a916b13c8acc2b526a03a6d26df85f";
const bypassHeaderName = 'x-msw-bypass' const bypassHeaderName = "x-msw-bypass";
const activeClientIds = new Set() const activeClientIds = new Set();
self.addEventListener('install', function () { self.addEventListener("install", function () {
return self.skipWaiting() return self.skipWaiting();
}) });
self.addEventListener('activate', async function (event) { self.addEventListener("activate", async function (event) {
return self.clients.claim() return self.clients.claim();
}) });
self.addEventListener('message', async function (event) { self.addEventListener("message", async function (event) {
const clientId = event.source.id const clientId = event.source.id;
if (!clientId || !self.clients) { if (!clientId || !self.clients) {
return return;
} }
const client = await self.clients.get(clientId) const client = await self.clients.get(clientId);
if (!client) { if (!client) {
return return;
} }
const allClients = await self.clients.matchAll() const allClients = await self.clients.matchAll();
switch (event.data) { switch (event.data) {
case 'KEEPALIVE_REQUEST': { case "KEEPALIVE_REQUEST": {
sendToClient(client, { sendToClient(client, {
type: 'KEEPALIVE_RESPONSE', type: "KEEPALIVE_RESPONSE",
}) });
break break;
} }
case 'INTEGRITY_CHECK_REQUEST': { case "INTEGRITY_CHECK_REQUEST": {
sendToClient(client, { sendToClient(client, {
type: 'INTEGRITY_CHECK_RESPONSE', type: "INTEGRITY_CHECK_RESPONSE",
payload: INTEGRITY_CHECKSUM, payload: INTEGRITY_CHECKSUM,
}) });
break break;
} }
case 'MOCK_ACTIVATE': { case "MOCK_ACTIVATE": {
activeClientIds.add(clientId) activeClientIds.add(clientId);
sendToClient(client, { sendToClient(client, {
type: 'MOCKING_ENABLED', type: "MOCKING_ENABLED",
payload: true, payload: true,
}) });
break break;
} }
case 'MOCK_DEACTIVATE': { case "MOCK_DEACTIVATE": {
activeClientIds.delete(clientId) activeClientIds.delete(clientId);
break break;
} }
case 'CLIENT_CLOSED': { case "CLIENT_CLOSED": {
activeClientIds.delete(clientId) activeClientIds.delete(clientId);
const remainingClients = allClients.filter((client) => { const remainingClients = allClients.filter((client) => {
return client.id !== clientId return client.id !== clientId;
}) });
// Unregister itself when there are no more clients // Unregister itself when there are no more clients
if (remainingClients.length === 0) { if (remainingClients.length === 0) {
self.registration.unregister() self.registration.unregister();
} }
break break;
} }
} }
}) });
// Resolve the "master" client for the given event. // Resolve the "master" client for the given event.
// Client that issues a request doesn't necessarily equal the client // Client that issues a request doesn't necessarily equal the client
// that registered the worker. It's with the latter the worker should // that registered the worker. It's with the latter the worker should
// communicate with during the response resolving phase. // communicate with during the response resolving phase.
async function resolveMasterClient(event) { async function resolveMasterClient(event) {
const client = await self.clients.get(event.clientId) const client = await self.clients.get(event.clientId);
if (client.frameType === 'top-level') { if (client.frameType === "top-level") {
return client return client;
} }
const allClients = await self.clients.matchAll() const allClients = await self.clients.matchAll();
return allClients return allClients
.filter((client) => { .filter((client) => {
// Get only those clients that are currently visible. // Get only those clients that are currently visible.
return client.visibilityState === 'visible' return client.visibilityState === "visible";
}) })
.find((client) => { .find((client) => {
// Find the client ID that's recorded in the // Find the client ID that's recorded in the
// set of clients that have registered the worker. // set of clients that have registered the worker.
return activeClientIds.has(client.id) return activeClientIds.has(client.id);
}) });
} }
async function handleRequest(event, requestId) { async function handleRequest(event, requestId) {
const client = await resolveMasterClient(event) const client = await resolveMasterClient(event);
const response = await getResponse(event, client, requestId) const response = await getResponse(event, client, requestId);
// Send back the response clone for the "response:*" life-cycle events. // Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise // Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely. // this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) { if (client && activeClientIds.has(client.id)) {
;(async function () { (async function () {
const clonedResponse = response.clone() const clonedResponse = response.clone();
sendToClient(client, { sendToClient(client, {
type: 'RESPONSE', type: "RESPONSE",
payload: { payload: {
requestId, requestId,
type: clonedResponse.type, type: clonedResponse.type,
@ -131,21 +131,21 @@ async function handleRequest(event, requestId) {
headers: serializeHeaders(clonedResponse.headers), headers: serializeHeaders(clonedResponse.headers),
redirected: clonedResponse.redirected, redirected: clonedResponse.redirected,
}, },
}) });
})() })();
} }
return response return response;
} }
async function getResponse(event, client, requestId) { async function getResponse(event, client, requestId) {
const { request } = event const { request } = event;
const requestClone = request.clone() const requestClone = request.clone();
const getOriginalResponse = () => fetch(requestClone) const getOriginalResponse = () => fetch(requestClone);
// Bypass mocking when the request client is not active. // Bypass mocking when the request client is not active.
if (!client) { if (!client) {
return getOriginalResponse() return getOriginalResponse();
} }
// Bypass initial page load requests (i.e. static assets). // Bypass initial page load requests (i.e. static assets).
@ -153,29 +153,29 @@ async function getResponse(event, client, requestId) {
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
// and is not ready to handle requests. // and is not ready to handle requests.
if (!activeClientIds.has(client.id)) { if (!activeClientIds.has(client.id)) {
return await getOriginalResponse() return await getOriginalResponse();
} }
// Bypass requests with the explicit bypass header // Bypass requests with the explicit bypass header
if (requestClone.headers.get(bypassHeaderName) === 'true') { if (requestClone.headers.get(bypassHeaderName) === "true") {
const cleanRequestHeaders = serializeHeaders(requestClone.headers) const cleanRequestHeaders = serializeHeaders(requestClone.headers);
// Remove the bypass header to comply with the CORS preflight check. // Remove the bypass header to comply with the CORS preflight check.
delete cleanRequestHeaders[bypassHeaderName] delete cleanRequestHeaders[bypassHeaderName];
const originalRequest = new Request(requestClone, { const originalRequest = new Request(requestClone, {
headers: new Headers(cleanRequestHeaders), headers: new Headers(cleanRequestHeaders),
}) });
return fetch(originalRequest) return fetch(originalRequest);
} }
// Send the request to the client-side MSW. // Send the request to the client-side MSW.
const reqHeaders = serializeHeaders(request.headers) const reqHeaders = serializeHeaders(request.headers);
const body = await request.text() const body = await request.text();
const clientMessage = await sendToClient(client, { const clientMessage = await sendToClient(client, {
type: 'REQUEST', type: "REQUEST",
payload: { payload: {
id: requestId, id: requestId,
url: request.url, url: request.url,
@ -193,31 +193,31 @@ async function getResponse(event, client, requestId) {
bodyUsed: request.bodyUsed, bodyUsed: request.bodyUsed,
keepalive: request.keepalive, keepalive: request.keepalive,
}, },
}) });
switch (clientMessage.type) { switch (clientMessage.type) {
case 'MOCK_SUCCESS': { case "MOCK_SUCCESS": {
return delayPromise( return delayPromise(
() => respondWithMock(clientMessage), () => respondWithMock(clientMessage),
clientMessage.payload.delay, clientMessage.payload.delay
) );
} }
case 'MOCK_NOT_FOUND': { case "MOCK_NOT_FOUND": {
return getOriginalResponse() return getOriginalResponse();
} }
case 'NETWORK_ERROR': { case "NETWORK_ERROR": {
const { name, message } = clientMessage.payload const { name, message } = clientMessage.payload;
const networkError = new Error(message) const networkError = new Error(message);
networkError.name = name networkError.name = name;
// Rejecting a request Promise emulates a network error. // Rejecting a request Promise emulates a network error.
throw networkError throw networkError;
} }
case 'INTERNAL_ERROR': { case "INTERNAL_ERROR": {
const parsedBody = JSON.parse(clientMessage.payload.body) const parsedBody = JSON.parse(clientMessage.payload.body);
console.error( console.error(
`\ `\
@ -228,54 +228,54 @@ ${parsedBody.location}
This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\ This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\
`, `,
request.method, request.method,
request.url, request.url
) );
return respondWithMock(clientMessage) return respondWithMock(clientMessage);
} }
} }
return getOriginalResponse() return getOriginalResponse();
} }
self.addEventListener('fetch', function (event) { self.addEventListener("fetch", function (event) {
const { request } = event const { request } = event;
const accept = request.headers.get('accept') || '' const accept = request.headers.get("accept") || "";
// Bypass server-sent events. // Bypass server-sent events.
if (accept.includes('text/event-stream')) { if (accept.includes("text/event-stream")) {
return return;
} }
// Bypass navigation requests. // Bypass navigation requests.
if (request.mode === 'navigate') { if (request.mode === "navigate") {
return return;
} }
// Opening the DevTools triggers the "only-if-cached" request // Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests. // that cannot be handled by the worker. Bypass such requests.
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { if (request.cache === "only-if-cached" && request.mode !== "same-origin") {
return return;
} }
// Bypass all requests when there are no active clients. // Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests // Prevents the self-unregistered worked from handling requests
// after it's been deleted (still remains active until the next reload). // after it's been deleted (still remains active until the next reload).
if (activeClientIds.size === 0) { if (activeClientIds.size === 0) {
return return;
} }
const requestId = uuidv4() const requestId = uuidv4();
return event.respondWith( return event.respondWith(
handleRequest(event, requestId).catch((error) => { handleRequest(event, requestId).catch((error) => {
if (error.name === 'NetworkError') { if (error.name === "NetworkError") {
console.warn( console.warn(
'[MSW] Successfully emulated a network error for the "%s %s" request.', '[MSW] Successfully emulated a network error for the "%s %s" request.',
request.method, request.method,
request.url, request.url
) );
return return;
} }
// At this point, any exception indicates an issue with the original request/response. // At this point, any exception indicates an issue with the original request/response.
@ -284,55 +284,55 @@ self.addEventListener('fetch', function (event) {
[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
request.method, request.method,
request.url, request.url,
`${error.name}: ${error.message}`, `${error.name}: ${error.message}`
) );
}), })
) );
}) });
function serializeHeaders(headers) { function serializeHeaders(headers) {
const reqHeaders = {} const reqHeaders = {};
headers.forEach((value, name) => { headers.forEach((value, name) => {
reqHeaders[name] = reqHeaders[name] reqHeaders[name] = reqHeaders[name]
? [].concat(reqHeaders[name]).concat(value) ? [].concat(reqHeaders[name]).concat(value)
: value : value;
}) });
return reqHeaders return reqHeaders;
} }
function sendToClient(client, message) { function sendToClient(client, message) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const channel = new MessageChannel() const channel = new MessageChannel();
channel.port1.onmessage = (event) => { channel.port1.onmessage = (event) => {
if (event.data && event.data.error) { if (event.data && event.data.error) {
return reject(event.data.error) return reject(event.data.error);
} }
resolve(event.data) resolve(event.data);
} };
client.postMessage(JSON.stringify(message), [channel.port2]) client.postMessage(JSON.stringify(message), [channel.port2]);
}) });
} }
function delayPromise(cb, duration) { function delayPromise(cb, duration) {
return new Promise((resolve) => { return new Promise((resolve) => {
setTimeout(() => resolve(cb()), duration) setTimeout(() => resolve(cb()), duration);
}) });
} }
function respondWithMock(clientMessage) { function respondWithMock(clientMessage) {
return new Response(clientMessage.payload.body, { return new Response(clientMessage.payload.body, {
...clientMessage.payload, ...clientMessage.payload,
headers: clientMessage.payload.headers, headers: clientMessage.payload.headers,
}) });
} }
function uuidv4() { function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0 const r = (Math.random() * 16) | 0;
const v = c == 'x' ? r : (r & 0x3) | 0x8 const v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16) return v.toString(16);
}) });
} }

View File

@ -1,66 +1,101 @@
<h2 class="list-element__title">Accordion demo</h2> <h2 class="list-element__title">Accordion demo</h2>
<div class="typography"> <div class="typography">Some content ...</div>
Some content ... <div
</div> id="AccordionExample"
<div id="AccordionExample" class="list-element__container accordion" data-listelement-count="4"> class="list-element__container accordion"
<div class="accordion-item"> data-listelement-count="4"
<h2 class="accordion-header" id="headingOne"> >
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne"> <div class="accordion-item">
Accordion Item #1 <h2 class="accordion-header" id="headingOne">
</button> <button
</h2> class="accordion-button"
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#AccordionExample"> type="button"
<div class="accordion-body"> data-bs-toggle="collapse"
<strong>This is the first item's accordion body.</strong> It is data-bs-target="#collapseOne"
hidden by default, until the collapse plugin adds the aria-expanded="true"
appropriate classes that we use to style each element. These aria-controls="collapseOne"
classes control the overall appearance, as well as the showing >
and hiding via CSS transitions. You can modify any of this with Accordion Item #1
custom CSS or overriding our default variables. It's also worth </button>
noting that just about any HTML can go within the </h2>
<code>.accordion-body</code>, though the transition does limit <div
overflow. id="collapseOne"
</div> class="accordion-collapse collapse show"
</div> aria-labelledby="headingOne"
</div> data-bs-parent="#AccordionExample"
<div class="accordion-item"> >
<h2 class="accordion-header" id="headingTwo"> <div class="accordion-body">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo"> <strong>This is the first item's accordion body.</strong> It is hidden
Accordion Item #2 by default, until the collapse plugin adds the appropriate classes that
</button> we use to style each element. These classes control the overall
</h2> appearance, as well as the showing and hiding via CSS transitions. You
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#AccordionExample"> can modify any of this with custom CSS or overriding our default
<div class="accordion-body"> variables. It's also worth noting that just about any HTML can go within
<strong>This is the second item's accordion body.</strong> It is the <code>.accordion-body</code>, though the transition does limit
hidden by default, until the collapse plugin adds the overflow.
appropriate classes that we use to style each element. These </div>
classes control the overall appearance, as well as the showing </div>
and hiding via CSS transitions. You can modify any of this with </div>
custom CSS or overriding our default variables. It's also worth <div class="accordion-item">
noting that just about any HTML can go within the <h2 class="accordion-header" id="headingTwo">
<code>.accordion-body</code>, though the transition does limit <button
overflow. class="accordion-button collapsed"
</div> type="button"
</div> data-bs-toggle="collapse"
</div> data-bs-target="#collapseTwo"
<div class="accordion-item"> aria-expanded="false"
<h2 class="accordion-header" id="headingThree"> aria-controls="collapseTwo"
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree"> >
Accordion Item #3 Accordion Item #2
</button> </button>
</h2> </h2>
<div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#AccordionExample"> <div
<div class="accordion-body"> id="collapseTwo"
<strong>This is the third item's accordion body.</strong> It is class="accordion-collapse collapse"
hidden by default, until the collapse plugin adds the aria-labelledby="headingTwo"
appropriate classes that we use to style each element. These data-bs-parent="#AccordionExample"
classes control the overall appearance, as well as the showing >
and hiding via CSS transitions. You can modify any of this with <div class="accordion-body">
custom CSS or overriding our default variables. It's also worth <strong>This is the second item's accordion body.</strong> It is hidden
noting that just about any HTML can go within the by default, until the collapse plugin adds the appropriate classes that
<code>.accordion-body</code>, though the transition does limit we use to style each element. These classes control the overall
overflow. appearance, as well as the showing and hiding via CSS transitions. You
</div> can modify any of this with custom CSS or overriding our default
</div> variables. It's also worth noting that just about any HTML can go within
</div> the <code>.accordion-body</code>, though the transition does limit
overflow.
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="headingThree">
<button
class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapseThree"
aria-expanded="false"
aria-controls="collapseThree"
>
Accordion Item #3
</button>
</h2>
<div
id="collapseThree"
class="accordion-collapse collapse"
aria-labelledby="headingThree"
data-bs-parent="#AccordionExample"
>
<div class="accordion-body">
<strong>This is the third item's accordion body.</strong> It is hidden
by default, until the collapse plugin adds the appropriate classes that
we use to style each element. These classes control the overall
appearance, as well as the showing and hiding via CSS transitions. You
can modify any of this with custom CSS or overriding our default
variables. It's also worth noting that just about any HTML can go within
the <code>.accordion-body</code>, though the transition does limit
overflow.
</div>
</div>
</div>
</div> </div>

View File

@ -1,165 +1,167 @@
<div class="content-element__content"> <div class="content-element__content">
<h2 class="content-element__title">Content Demo</h2> <h2 class="content-element__title">Content Demo</h2>
<div class="typography"> <div class="typography">
<h3><i class="fas fa-search"></i> Quick start</h3> <h3><i class="fas fa-search"></i> Quick start</h3>
<ol> <ol>
<li> <li>
<p>Clone quick start repository</p> <p>Clone quick start repository</p>
<pre> <pre>
git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre> git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre
</li> >
<li> </li>
<p>Install npm packages</p> <li>
<pre> <p>Install npm packages</p>
<pre>
cd ./webpack-bootstrap-ui-kit-quick-start.git cd ./webpack-bootstrap-ui-kit-quick-start.git
npm install npm install
</pre> </pre
</li> >
<li> </li>
<p>Edit ./src files</p> <li>
</li> <p>Edit ./src files</p>
<li> </li>
<p>Start development server at https://127.0.0.1:8001/:</p> <li>
<pre>yarn start</pre> <p>Start development server at https://127.0.0.1:8001/:</p>
<p>Compile:</p> <pre>yarn start</pre>
<pre>yarn build</pre> <p>Compile:</p>
</li> <pre>yarn build</pre>
</ol> </li>
<h2> </ol>
<i class="fas fa-search"></i> Header #2 <h2>
<i class="fas fa-search"></i> <i class="fas fa-search"></i> Header #2
</h2> <i class="fas fa-search"></i>
</h2>
<p>
<img
src="https://via.placeholder.com/200x200"
alt="Test Image"
class="image right"
/>Content Text Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry's standard dummy
text ever since the 1500s, when an unknown printer took a galley of type
and scrambled it to make a type specimen book. It has survived not only
five centuries, but also the leap into electronic typesetting, remaining
essentially unchanged. It was popularised in the 1960s with the release of
Letraset sheets containing Lorem Ipsum passages, and more recently with
desktop publishing software like Aldus PageMaker including versions of
Lorem Ipsum.
</p>
<ol>
<li>
First
<ul>
<li>First</li>
<li>
Second
<ol>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ol>
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
</li>
<li>
<p>
Content Text Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when an unknown printer took a
galley of type and scrambled it to make a type specimen book. It
has survived not only five centuries, but also the leap into
electronic typesetting, remaining essentially unchanged. It was
popularised in the 1960s with the release of Letraset sheets
containing Lorem Ipsum passages, and more recently with desktop
publishing software like Aldus PageMaker including versions of
Lorem Ipsum.
</p>
</li>
</ul>
</li>
<li>
<p>{paragraph} Second</p>
<p>{paragraph} Second #2</p>
</li>
<li>
<p> <p>
<img src="https://via.placeholder.com/200x200" alt="Test Image" class="image right" />Content Text Lorem Ipsum is simply dummy text of the printing and Content Text Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry's standard typesetting industry. Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when an unknown printer took a dummy text ever since the 1500s, when an unknown printer took a galley
galley of type and scrambled it to make a type specimen book. It has of type and scrambled it to make a type specimen book. It has survived
survived not only five centuries, but also the leap into electronic not only five centuries, but also the leap into electronic
typesetting, remaining essentially unchanged. It was popularised in typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum the 1960s with the release of Letraset sheets containing Lorem Ipsum
passages, and more recently with desktop publishing software like passages, and more recently with desktop publishing software like
Aldus PageMaker including versions of Lorem Ipsum. Aldus PageMaker including versions of Lorem Ipsum.
</p> </p>
<ol> </li>
<li> </ol>
First <h2 class="text-center">Responsive Table #1: Default</h2>
<ul> <table>
<li>First</li> <thead>
<li> <tr>
Second <th>Header #1</th>
<ol> <th>Header #2</th>
<li>First</li> <th>Header #3</th>
<li>Second</li> </tr>
<li>Third</li> </thead>
</ol> <tbody>
<ul> <tr>
<li>First</li> <td data-label="Header #1">#1-1</td>
<li>Second</li> <td data-label="Header #2">#1-2</td>
<li>Third</li> <td data-label="Header #3">#1-3</td>
</ul> </tr>
</li> <tr>
<li> <td data-label="Header #1">#2-1</td>
<p> <td data-label="Header #2">#2-2</td>
Content Text Lorem Ipsum is simply dummy text of the <td data-label="Header #3">#2-3</td>
printing and typesetting industry. Lorem Ipsum has </tr>
been the industry's standard dummy text ever since <tr>
the 1500s, when an unknown printer took a galley of <td data-label="Header #1">#3-1</td>
type and scrambled it to make a type specimen book. <td data-label="Header #2">#3-2</td>
It has survived not only five centuries, but also <td data-label="Header #3">#3-3</td>
the leap into electronic typesetting, remaining </tr>
essentially unchanged. It was popularised in the </tbody>
1960s with the release of Letraset sheets containing </table>
Lorem Ipsum passages, and more recently with desktop <p class="text-justify">
publishing software like Aldus PageMaker including Content Text Lorem Ipsum is simply dummy text of the printing and
versions of Lorem Ipsum. typesetting industry. Lorem Ipsum has been the industry's standard dummy
</p> text ever since the 1500s, when an unknown printer took a galley of type
</li> and scrambled it to make a type specimen book. It has survived not only
</ul> five centuries, but also the leap into electronic typesetting, remaining
</li> essentially unchanged. It was popularised in the 1960s with the release of
<li> Letraset sheets containing Lorem Ipsum passages, and more recently with
<p>{paragraph} Second</p> desktop publishing software like Aldus PageMaker including versions of
<p>{paragraph} Second #2</p> Lorem Ipsum.
</li> </p>
<li> <h2 class="text-center">Responsive Table #2: Border-less</h2>
<p> <table class="table-none">
Content Text Lorem Ipsum is simply dummy text of the <thead>
printing and typesetting industry. Lorem Ipsum has been the <tr>
industry's standard dummy text ever since the 1500s, when an <th>Header #1</th>
unknown printer took a galley of type and scrambled it to <th>Header #2</th>
make a type specimen book. It has survived not only five <th>Header #3</th>
centuries, but also the leap into electronic typesetting, </tr>
remaining essentially unchanged. It was popularised in the </thead>
1960s with the release of Letraset sheets containing Lorem <tbody>
Ipsum passages, and more recently with desktop publishing <tr>
software like Aldus PageMaker including versions of Lorem <td data-label="Header #1">#1-1</td>
Ipsum. <td data-label="Header #2">#1-2</td>
</p> <td data-label="Header #3">#1-3</td>
</li> </tr>
</ol> <tr>
<h2 class="text-center">Responsive Table #1: Default</h2> <td data-label="Header #1">#2-1</td>
<table> <td data-label="Header #2">#2-2</td>
<thead> <td data-label="Header #3">#2-3</td>
<tr> </tr>
<th>Header #1</th> <tr>
<th>Header #2</th> <td data-label="Header #1">#3-1</td>
<th>Header #3</th> <td data-label="Header #2">#3-2</td>
</tr> <td data-label="Header #3">#3-3</td>
</thead> </tr>
<tbody> </tbody>
<tr> </table>
<td data-label="Header #1">#1-1</td> </div>
<td data-label="Header #2">#1-2</td>
<td data-label="Header #3">#1-3</td>
</tr>
<tr>
<td data-label="Header #1">#2-1</td>
<td data-label="Header #2">#2-2</td>
<td data-label="Header #3">#2-3</td>
</tr>
<tr>
<td data-label="Header #1">#3-1</td>
<td data-label="Header #2">#3-2</td>
<td data-label="Header #3">#3-3</td>
</tr>
</tbody>
</table>
<p class="text-justify">
Content Text Lorem Ipsum is simply dummy text of the printing and
typesetting industry. Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when an unknown printer took a
galley of type and scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap into electronic
typesetting, remaining essentially unchanged. It was popularised in
the 1960s with the release of Letraset sheets containing Lorem Ipsum
passages, and more recently with desktop publishing software like
Aldus PageMaker including versions of Lorem Ipsum.
</p>
<h2 class="text-center">Responsive Table #2: Border-less</h2>
<table class="table-none">
<thead>
<tr>
<th>Header #1</th>
<th>Header #2</th>
<th>Header #3</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Header #1">#1-1</td>
<td data-label="Header #2">#1-2</td>
<td data-label="Header #3">#1-3</td>
</tr>
<tr>
<td data-label="Header #1">#2-1</td>
<td data-label="Header #2">#2-2</td>
<td data-label="Header #3">#2-3</td>
</tr>
<tr>
<td data-label="Header #1">#3-1</td>
<td data-label="Header #2">#3-2</td>
<td data-label="Header #3">#3-3</td>
</tr>
</tbody>
</table>
</div>
</div> </div>

View File

@ -1,42 +1,64 @@
<h2 class="list-element__title">Content Header</h2> <h2 class="list-element__title">Content Header</h2>
<div class="typography"> <div class="typography">Some content ...</div>
Some content ...
</div>
<div class="list-element__container row" data-listelement-count="4"> <div class="list-element__container row" data-listelement-count="4">
<div class="element dnadesign__elemental__models__elementcontent block col-md-3"> <div
<div class="element-container"> class="element dnadesign__elemental__models__elementcontent block col-md-3"
<div class="content-element__content"> >
<div class="typography"> <div class="element-container">
<img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100" /> <div class="content-element__content">
</div> <div class="typography">
</div> <img
src="https://via.placeholder.com/300x300"
alt="Some kind image"
class="w-100"
/>
</div> </div>
</div>
</div> </div>
<div class="element dnadesign__elemental__models__elementcontent block col-md-3"> </div>
<div class="element-container"> <div
<div class="content-element__content"> class="element dnadesign__elemental__models__elementcontent block col-md-3"
<div class="typography"> >
<img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100" /> <div class="element-container">
</div> <div class="content-element__content">
</div> <div class="typography">
<img
src="https://via.placeholder.com/300x300"
alt="Some kind image"
class="w-100"
/>
</div> </div>
</div>
</div> </div>
<div class="element dnadesign__elemental__models__elementcontent block col-md-3"> </div>
<div class="element-container"> <div
<div class="content-element__content"> class="element dnadesign__elemental__models__elementcontent block col-md-3"
<div class="typography"> >
<img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100" /> <div class="element-container">
</div> <div class="content-element__content">
</div> <div class="typography">
<img
src="https://via.placeholder.com/300x300"
alt="Some kind image"
class="w-100"
/>
</div> </div>
</div>
</div> </div>
<div class="element dnadesign__elemental__models__elementcontent block col-md-3"> </div>
<div class="element-container"> <div
<div class="content-element__content"> class="element dnadesign__elemental__models__elementcontent block col-md-3"
<div class="typography"> >
<img src="https://via.placeholder.com/300x300" alt="Some kind image" class="w-100" /> <div class="element-container">
</div> <div class="content-element__content">
</div> <div class="typography">
<img
src="https://via.placeholder.com/300x300"
alt="Some kind image"
class="w-100"
/>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>

View File

@ -1,59 +1,75 @@
<h2 class="content-element__title">Find Location</h2> <h2 class="content-element__title">Find Location</h2>
<div class="typography"> <div class="typography">
<p>Use _consts.js to change Google Maps to Mapbox.</p> <p>Use _consts.js to change Google Maps to Mapbox.</p>
</div> </div>
<div <div
class="mapAPI-map-container" class="mapAPI-map-container"
data-map-zoom="12" data-map-zoom="12"
data-key="" data-key=""
data-map-style="mapbox://styles/mapbox/streets-v9" data-map-style="mapbox://styles/mapbox/streets-v9"
data-geojson="{&quot;type&quot;:&quot;MarkerCollection&quot;,&quot;features&quot;:[{&quot;id&quot;:4,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin4\&quot; data-id=\&quot;4\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #1&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;17 Lakeside Drive&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8827743,-74.4276612\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-74.4276612,40.8827743]}},{&quot;id&quot;:3,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin3\&quot; data-id=\&quot;3\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #2&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;Flower Hill Cemetery&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; N&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.7884708,-74.0249253\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-74.0249253,40.7884708]}},{&quot;id&quot;:2,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin2\&quot; data-id=\&quot;2\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #3&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;555 Phoenix Road&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8527479,-78.2475576\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-78.2475576,40.8527479]}},{&quot;id&quot;:1,&quot;type&quot;:&quot;Feature&quot;,&quot;icon&quot;:&quot;&lt;i class=\&quot;fas fa-map-marker-alt\&quot;&gt;&lt;\/i&gt;&quot;,&quot;properties&quot;:{&quot;content&quot;:&quot;&lt;div id=\&quot;MapPin1\&quot; data-id=\&quot;1\&quot; class=\&quot;location\&quot;&gt;\n &lt;div class=\&quot;fn\&quot;&gt;Office #4&lt;\/div&gt;\n &lt;div class=\&quot;addr\&quot;&gt;15 East Hadley Road&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;d-none\&quot;&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\&quot;dir-link\&quot;&gt;\n &lt;a href=\&quot;https:\/\/www.google.com\/maps\/dir\/Current+Location\/42.3297023,-72.5552186\&quot; target=\&quot;_blank\&quot;&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n&quot;},&quot;geometry&quot;:{&quot;type&quot;:&quot;Point&quot;,&quot;coordinates&quot;:[-72.5552186,42.3297023]}}]}" data-geojson='{"type":"MarkerCollection","features":[{"id":4,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin4\" data-id=\"4\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #1&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;17 Lakeside Drive&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8827743,-74.4276612\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-74.4276612,40.8827743]}},{"id":3,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin3\" data-id=\"3\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #2&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;Flower Hill Cemetery&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; N&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.7884708,-74.0249253\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-74.0249253,40.7884708]}},{"id":2,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin2\" data-id=\"2\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #3&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;555 Phoenix Road&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/40.8527479,-78.2475576\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-78.2475576,40.8527479]}},{"id":1,"type":"Feature","icon":"&lt;i class=\"fas fa-map-marker-alt\"&gt;&lt;\/i&gt;","properties":{"content":"&lt;div id=\"MapPin1\" data-id=\"1\" class=\"location\"&gt;\n &lt;div class=\"fn\"&gt;Office #4&lt;\/div&gt;\n &lt;div class=\"addr\"&gt;15 East Hadley Road&lt;\/div&gt;\n \n \n \n &lt;div class=\"d-none\"&gt; U&lt;\/div&gt;\n \n \n \n &lt;div class=\"dir-link\"&gt;\n &lt;a href=\"https:\/\/www.google.com\/maps\/dir\/Current+Location\/42.3297023,-72.5552186\" target=\"_blank\"&gt;Get Directions &amp;raquo;&lt;\/a&gt;\n &lt;\/div&gt;\n&lt;\/div&gt;\n"},"geometry":{"type":"Point","coordinates":[-72.5552186,42.3297023]}}]}'
data-fly-to-marker="true" data-fly-to-marker="true"
data-fly-to-bounds="false" data-fly-to-bounds="false"
> >
<div class="mapAPI-map"></div> <div class="mapAPI-map"></div>
</div> </div>
<div class="locations"> <div class="locations">
<div class="row"> <div class="row">
<div class="col-sm-3"> <div class="col-sm-3">
<div id="MapPin4" data-id="4" class="location"> <div id="MapPin4" data-id="4" class="location">
<div class="fn">Office #1</div> <div class="fn">Office #1</div>
<div class="addr">17 Lakeside Drive</div> <div class="addr">17 Lakeside Drive</div>
<div class="d-none"> U</div> <div class="d-none">U</div>
<div class="dir-link"> <div class="dir-link">
<a href="https://www.google.com/maps/dir/Current+Location/40.8827743,-74.4276612" target="_blank">Get Directions &raquo;</a> <a
</div> href="https://www.google.com/maps/dir/Current+Location/40.8827743,-74.4276612"
</div> target="_blank"
</div> >Get Directions &raquo;</a
<div class="col-sm-3"> >
<div id="MapPin3" data-id="3" class="location"> </div>
<div class="fn">Office #2</div> </div>
<div class="addr">Flower Hill Cemetery</div> </div>
<div class="d-none"> N</div> <div class="col-sm-3">
<div class="dir-link"> <div id="MapPin3" data-id="3" class="location">
<a href="https://www.google.com/maps/dir/Current+Location/40.7884708,-74.0249253" target="_blank">Get Directions &raquo;</a> <div class="fn">Office #2</div>
</div> <div class="addr">Flower Hill Cemetery</div>
</div> <div class="d-none">N</div>
</div> <div class="dir-link">
<div class="col-sm-3"> <a
<div id="MapPin2" data-id="2" class="location"> href="https://www.google.com/maps/dir/Current+Location/40.7884708,-74.0249253"
<div class="fn">Office #3</div> target="_blank"
<div class="addr">555 Phoenix Road</div> >Get Directions &raquo;</a
<div class="d-none"> U</div> >
<div class="dir-link"> </div>
<a href="https://www.google.com/maps/dir/Current+Location/40.8527479,-78.2475576" target="_blank">Get Directions &raquo;</a> </div>
</div> </div>
</div> <div class="col-sm-3">
</div> <div id="MapPin2" data-id="2" class="location">
<div class="col-sm-3"> <div class="fn">Office #3</div>
<div id="MapPin1" data-id="1" class="location"> <div class="addr">555 Phoenix Road</div>
<div class="fn">Office #4</div> <div class="d-none">U</div>
<div class="addr">15 East Hadley Road</div> <div class="dir-link">
<div class="d-none"> U</div> <a
<div class="dir-link"> href="https://www.google.com/maps/dir/Current+Location/40.8527479,-78.2475576"
<a href="https://www.google.com/maps/dir/Current+Location/42.3297023,-72.5552186" target="_blank">Get Directions &raquo;</a> target="_blank"
</div> >Get Directions &raquo;</a
</div> >
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-3">
<div id="MapPin1" data-id="1" class="location">
<div class="fn">Office #4</div>
<div class="addr">15 East Hadley Road</div>
<div class="d-none">U</div>
<div class="dir-link">
<a
href="https://www.google.com/maps/dir/Current+Location/42.3297023,-72.5552186"
target="_blank"
>Get Directions &raquo;</a
>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,2 +1,2 @@
<noscript><div class="main-bn">Please, enable javascript.</div></noscript> <noscript><div class="main-bn">Please, enable javascript.</div></noscript>
<div id="PageTopAnchor"></div> <div id="PageTopAnchor"></div>

View File

@ -1,50 +1,38 @@
<div class="wrapper"> <div class="wrapper">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-sm-3"> <div class="col-sm-3">Col #1</div>
Col #1 <div class="col-sm-3">Col #2</div>
</div> <div class="col-sm-3">Col #3</div>
<div class="col-sm-3"> <div class="col-sm-3">Col #4</div>
Col #2 </div>
</div> </div>
<div class="col-sm-3">
Col #3
</div>
<div class="col-sm-3">
Col #4
</div>
</div>
</div>
</div> </div>
<div class="footer"> <div class="footer">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-sm-8 d-md-flex"> <div class="col-sm-8 d-md-flex">
<div class="copyright"> <div class="copyright">
Copyright &copy; 2019 - Tony Air (A2nt) Webpack Bootstrap 4 Copyright &copy; 2019 - Tony Air (A2nt) Webpack Bootstrap 4 UI Kit
UI Kit </div>
</div> <nav class="footer-nav">
<nav class="footer-nav"> <ul class="list-inline d-flex">
<ul class="list-inline d-flex"> <li>
<li> <a href="#">Sitemap</a>
<a href="#">Sitemap</a> </li>
</li> <li>
<li> <a href="#">Privacy Policy</a>
<a href="#">Privacy Policy</a> </li>
</li> </ul>
</ul> </nav>
</nav> </div>
</div> <div class="col-sm-4">
<div class="col-sm-4"> <div class="text-end credits footer__credits">
<div class="text-end credits footer__credits"> <a href="https://github.com/a2nt" target="_blank" rel="nofollow"
<a ><span>Developed by</span> Tony Air</a
href="https://github.com/a2nt" >
target="_blank" </div>
rel="nofollow" </div>
><span>Developed by</span> Tony Air</a </div>
> </div>
</div>
</div>
</div>
</div>
</div> </div>

View File

@ -1,7 +1,7 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta <meta
name="viewport" name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no" content="width=device-width, initial-scale=1, shrink-to-fit=no"
/> />
<meta name="description" content="UI Kit" /> <meta name="description" content="UI Kit" />
<meta name="author" content="Tony Air <tony@twma.pro>" /> <meta name="author" content="Tony Air <tony@twma.pro>" />

View File

@ -6,8 +6,8 @@
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
/ --> / -->
<link <link
rel="stylesheet" rel="stylesheet"
type="text/css" type="text/css"
href="https://use.fontawesome.com/releases/v5.12.0/css/all.css" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css"
media="all" media="all"
/> />

View File

@ -1,114 +1,103 @@
<nav id="Navigation" class="navbar navbar-expand-lg"> <nav id="Navigation" class="navbar navbar-expand-lg">
<div class="container"> <div class="container">
<a class="navbar-brand" href="#">UI Kit</a> <a class="navbar-brand" href="#">UI Kit</a>
<button <button
class="navbar-toggler" class="navbar-toggler"
type="button" type="button"
data-bs-toggle="collapse" data-bs-toggle="collapse"
data-bs-target="#NavbarResponsive" data-bs-target="#NavbarResponsive"
aria-controls="NavbarResponsive" aria-controls="NavbarResponsive"
aria-expanded="false" aria-expanded="false"
aria-label="Toggle navigation" aria-label="Toggle navigation"
> >
<i class="navbar-toggler-icon fa fas fa-bars"></i> <i class="navbar-toggler-icon fa fas fa-bars"></i>
</button> </button>
<div id="NavbarResponsive" class="collapse navbar-collapse"> <div id="NavbarResponsive" class="collapse navbar-collapse">
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item active"> <li class="nav-item active">
<a <a class="nav-link js-scrollTo" href="#PageTopAnchor" data-text="Home"
class="nav-link js-scrollTo" >Home <span class="sr-only">(current)</span></a
href="#PageTopAnchor" >
data-text="Home" </li>
>Home <span class="sr-only">(current)</span></a <li class="nav-item">
> <a class="nav-link js-scrollTo" href="#Slider" data-text="Slider"
</li> >Slider</a
<li class="nav-item"> >
<a </li>
class="nav-link js-scrollTo" <li class="nav-item dropdown dropdown-hover">
href="#Slider" <a
data-text="Slider" id="NavbarDropdown"
>Slider</a class="nav-link dropdown-toggle-fl dropdown-toggle-notouch"
> href="#"
</li> data-text="Dropdown"
<li class="nav-item dropdown dropdown-hover"> >
<a Dropdown
id="NavbarDropdown" </a>
class="nav-link dropdown-toggle-fl dropdown-toggle-notouch"
href="#"
data-text="Dropdown"
>
Dropdown
</a>
<button <button
class="nav-link dropdown-toggle dropdown-toggle-sm dropdown-toggle-touch" class="
role="button" nav-link
data-bs-toggle="dropdown" dropdown-toggle dropdown-toggle-sm dropdown-toggle-touch
aria-expanded="false" "
type="button" role="button"
> data-bs-toggle="dropdown"
Dropdown aria-expanded="false"
</button> type="button"
>
Dropdown
</button>
<div class="dropdown-menu" aria-labelledby="NavbarDropdown"> <div class="dropdown-menu" aria-labelledby="NavbarDropdown">
<a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Action</a>
<a <a class="dropdown-item js-scrollTo" href="#AccordionList"
class="dropdown-item js-scrollTo" >Scroll to AccordionList</a
href="#AccordionList" >
>Scroll to AccordionList</a <div class="dropdown-divider"></div>
> <a
<div class="dropdown-divider"></div> class="dropdown-item"
<a href="https://google.com"
class="dropdown-item" target="_blank"
href="https://google.com" rel="nofollow"
target="_blank" >Go to Google.com</a
rel="nofollow" >
>Go to Google.com</a <div class="dropdown-divider"></div>
> <a class="dropdown-item graphql-page" href="/home"
<div class="dropdown-divider"></div> >Test dropdown hide on GraphQL</a
<a class="dropdown-item graphql-page" href="/home" >
>Test dropdown hide on GraphQL</a </div>
> </li>
</div> <li class="nav-item">
</li> <a id="LoadGraphQL" class="nav-link graphql-page" href="/home"
<li class="nav-item"> >Load GraphQL</a
<a >
id="LoadGraphQL" </li>
class="nav-link graphql-page" <li class="nav-item">
href="/home" <a class="nav-link graphql-page" href="/en/aquascaping"
>Load GraphQL</a >Load GraphQL #2</a
> >
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link graphql-page" href="/en/aquascaping" <a class="nav-link js-scrollTo" href="#AccordionList"
>Load GraphQL #2</a >Accordion List</a
> >
</li> </li>
<li class="nav-item"> <li>
<a class="nav-link js-scrollTo" href="#AccordionList" <form class="form-inline my-2 my-lg-0">
>Accordion List</a <input
> class="form-control mr-sm-2"
</li> type="search"
<li> placeholder="Search"
<form class="form-inline my-2 my-lg-0"> aria-label="Search"
<input />
class="form-control mr-sm-2" <button class="btn btn-outline-success my-2 my-sm-0" type="submit">
type="search" <i class="fas fa-search"></i>
placeholder="Search" <span class="sr-only">Search</span>
aria-label="Search" </button>
/> </form>
<button </li>
class="btn btn-outline-success my-2 my-sm-0" </ul>
type="submit" </div>
> </div>
<i class="fas fa-search"></i>
<span class="sr-only">Search</span>
</button>
</form>
</li>
</ul>
</div>
</div>
</nav> </nav>

View File

@ -1,65 +1,106 @@
<!-- if $SlideShow --> <!-- if $SlideShow -->
<div id="Carousel{$ID}" class="carousel slide js-carousel d-none d-sm-block" data-indicators="true" data-arrows="true"> <div
<div class="carousel-inner"> id="Carousel{$ID}"
<!-- loop $SlideShow --> class="carousel slide js-carousel d-none d-sm-block"
<!-- Slide #1 --> data-indicators="true"
<div class="carousel-item active"> data-arrows="true"
<a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary"> >
<img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline"> <div class="carousel-inner">
<!-- loop $SlideShow -->
<!-- Slide #1 -->
<div class="carousel-item active">
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn-primary"
>
<img
class="d-block w-100"
src="https://via.placeholder.com/1200x600"
alt="$Headline"
/>
</a>
<div class="carousel-caption">
<div class="carousel-caption-container">
<h2 class="carousel-title">$Headline #1</h2>
<p class="carousel-content">$Description</p>
<p>
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn btn-default btn-lg"
>
<i class="fas fa-bars"></i>
Learn More
</a> </a>
<div class="carousel-caption"> </p>
<div class="carousel-caption-container">
<h2 class="carousel-title">$Headline #1</h2>
<p class="carousel-content">$Description</p>
<p>
<a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg">
<i class="fas fa-bars"></i>
Learn More
</a>
</p>
</div>
</div>
</div> </div>
<!-- /Slide #1 --> </div>
<!-- Slide #2 -->
<div class="carousel-item">
<a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary">
<img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline">
</a>
<div class="carousel-caption">
<div class="carousel-caption-container">
<h2 class="carousel-title">$Headline #2</h2>
<p class="carousel-content">$Description</p>
<p>
<a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg">
<i class="fas fa-bars"></i>
Learn More
</a>
</p>
</div>
</div>
</div>
<!-- /Slide #2 -->
<!-- Slide #3 -->
<div class="carousel-item">
<a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn-primary">
<img class="d-block w-100" src="https://via.placeholder.com/1200x600" alt="$Headline">
</a>
<div class="carousel-caption">
<div class="carousel-caption-container">
<h2 class="carousel-title">$Headline #3</h2>
<p class="carousel-content">$Description</p>
<p>
<a href="$PageLink.Link" title="$PageLink.MenuTitle.XML" class="btn btn-default btn-lg">
<i class="fas fa-bars"></i>
Learn More
</a>
</p>
</div>
</div>
</div>
<!-- /Slide #3 -->
<!-- end_loop -->
</div> </div>
<!-- /Slide #1 -->
<!-- Slide #2 -->
<div class="carousel-item">
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn-primary"
>
<img
class="d-block w-100"
src="https://via.placeholder.com/1200x600"
alt="$Headline"
/>
</a>
<div class="carousel-caption">
<div class="carousel-caption-container">
<h2 class="carousel-title">$Headline #2</h2>
<p class="carousel-content">$Description</p>
<p>
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn btn-default btn-lg"
>
<i class="fas fa-bars"></i>
Learn More
</a>
</p>
</div>
</div>
</div>
<!-- /Slide #2 -->
<!-- Slide #3 -->
<div class="carousel-item">
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn-primary"
>
<img
class="d-block w-100"
src="https://via.placeholder.com/1200x600"
alt="$Headline"
/>
</a>
<div class="carousel-caption">
<div class="carousel-caption-container">
<h2 class="carousel-title">$Headline #3</h2>
<p class="carousel-content">$Description</p>
<p>
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn btn-default btn-lg"
>
<i class="fas fa-bars"></i>
Learn More
</a>
</p>
</div>
</div>
</div>
<!-- /Slide #3 -->
<!-- end_loop -->
</div>
</div> </div>
<!-- end_if --> <!-- end_if -->

View File

@ -1,36 +1,36 @@
<div id="SiteWideAlerts" class="offline-message"> <div id="SiteWideAlerts" class="offline-message">
<div <div
class="alert alert-danger alert-offline alert-dismissible fade show" class="alert alert-danger alert-offline alert-dismissible fade show"
role="alert" role="alert"
> >
<div class="typography"> <div class="typography">
The Internet connection is missing right now, but you're able to The Internet connection is missing right now, but you're able to browse
browse previously opened pages offline. previously opened pages offline.
</div> </div>
<button <button
type="button" type="button"
class="btn btn-danger btn-close" class="btn btn-danger btn-close"
data-bs-dismiss="alert" data-bs-dismiss="alert"
aria-label="Close" aria-label="Close"
> >
<i class="fas fa-times"></i> <i class="fas fa-times"></i>
</button> </button>
</div> </div>
<noscript> <noscript>
<div class="main-bn alert alert-fixed-top alert-danger" role="alert"> <div class="main-bn alert alert-fixed-top alert-danger" role="alert">
Please, enable javascript. Please, enable javascript.
</div> </div>
</noscript> </noscript>
<!--[if lt IE 11 <!--[if lt IE 11
]><div class="main-bn alert alert-danger" role="alert"> ]><div class="main-bn alert alert-danger" role="alert">
<a <a
href="https://www.google.com/chrome/browser/desktop/" href="https://www.google.com/chrome/browser/desktop/"
classs="alert-link" classs="alert-link"
> >
You are using an outdated browser. For a faster, safer browsing You are using an outdated browser. For a faster, safer browsing
experience, upgrade for free today. experience, upgrade for free today.
</a> </a>
</div><! </div><!
[endif]--> [endif]-->
</div> </div>

View File

@ -1,10 +1,10 @@
<div class="flyout-FlyoutUI"> <div class="flyout-FlyoutUI">
<i class="fas fa-times flyout-FlyoutUI__close"></i> <i class="fas fa-times flyout-FlyoutUI__close"></i>
<h2 class="flyout-FlyoutUI__title"> <h2 class="flyout-FlyoutUI__title">
<i class="fas fa-asterisk"></i> <i class="fas fa-asterisk"></i>
Flyout Demo Flyout Demo
</h2> </h2>
<div class="flyout-FlyoutUI__content typography"> <div class="flyout-FlyoutUI__content typography">
<p>Lipsum .... .... ....</p> <p>Lipsum .... .... ....</p>
</div> </div>
</div> </div>

View File

@ -1,213 +1,208 @@
<style> <style>
@keyframes lds-ellipsis1 { @keyframes lds-ellipsis1 {
0% { 0% {
transform: scale(0); transform: scale(0);
} }
100% { 100% {
transform: scale(1); transform: scale(1);
} }
} }
@keyframes lds-ellipsis3 { @keyframes lds-ellipsis3 {
0% { 0% {
transform: scale(1); transform: scale(1);
} }
100% { 100% {
transform: scale(0); transform: scale(0);
} }
} }
@keyframes lds-ellipsis2 { @keyframes lds-ellipsis2 {
0% { 0% {
transform: translate(0, 0); transform: translate(0, 0);
} }
100% { 100% {
transform: translate(1.35rem, 0); transform: translate(1.35rem, 0);
} }
} }
body, body,
html { html {
font-size: 14px; font-size: 14px;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: #fff; background: #fff;
color: #333; color: #333;
overflow-x: hidden; overflow-x: hidden;
} }
@media (min-width: 2000px) { @media (min-width: 2000px) {
html, html,
body { body {
font-size: 0.9vw; font-size: 0.9vw;
} }
} }
#PageLoading { #PageLoading {
position: fixed; position: fixed;
left: 0; left: 0;
top: 0; top: 0;
margin: 0; margin: 0;
width: 100% !important; width: 100% !important;
height: 100% !important; height: 100% !important;
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
-ms-flex-pack: center; -ms-flex-pack: center;
justify-content: center; justify-content: center;
z-index: 2000; z-index: 2000;
will-change: opacity; will-change: opacity;
background: #212529; background: #212529;
color: #212529; color: #212529;
} }
#PageLoading .logo { #PageLoading .logo {
filter: invert(1); filter: invert(1);
margin-left: 20px; margin-left: 20px;
margin-left: 2vw; margin-left: 2vw;
width: 100px; width: 100px;
width: 12.5vw; width: 12.5vw;
} }
#PageLoading .tagline { #PageLoading .tagline {
color: #fff; color: #fff;
font-size: 1.8rem; font-size: 1.8rem;
font-size: 4vh; font-size: 4vh;
letter-spacing: 0.25em; letter-spacing: 0.25em;
} }
.main-bn { .main-bn {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
z-index: 99999999; z-index: 99999999;
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
text-align: center; text-align: center;
color: #fff; color: #fff;
background: #ff0000; background: #ff0000;
} }
img, img,
iframe { iframe {
max-width: 100%; max-width: 100%;
} }
.loading-spinner { .loading-spinner {
text-align: center; text-align: center;
} }
.lds-ellipsis { .lds-ellipsis {
display: inline-block; display: inline-block;
position: relative; position: relative;
width: 4.57rem; width: 4.57rem;
height: 1rem; height: 1rem;
color: #fff; color: #fff;
} }
.lds-ellipsis div { .lds-ellipsis div {
position: absolute; position: absolute;
top: 0.15rem; top: 0.15rem;
width: 0.78rem; width: 0.78rem;
height: 0.78rem; height: 0.78rem;
border-radius: 50%; border-radius: 50%;
background: #888; background: #888;
animation-timing-function: cubic-bezier(0, 1, 1, 0); animation-timing-function: cubic-bezier(0, 1, 1, 0);
} }
.lds-ellipsis div:nth-child(1) { .lds-ellipsis div:nth-child(1) {
left: 0.42rem; left: 0.42rem;
animation: lds-ellipsis1 0.6s infinite; animation: lds-ellipsis1 0.6s infinite;
} }
.lds-ellipsis div:nth-child(2) { .lds-ellipsis div:nth-child(2) {
left: 0.9rem; left: 0.9rem;
animation: lds-ellipsis2 0.6s infinite; animation: lds-ellipsis2 0.6s infinite;
} }
.lds-ellipsis div:nth-child(3) { .lds-ellipsis div:nth-child(3) {
left: 1.85rem; left: 1.85rem;
animation: lds-ellipsis2 0.6s infinite; animation: lds-ellipsis2 0.6s infinite;
} }
.lds-ellipsis div:nth-child(4) { .lds-ellipsis div:nth-child(4) {
left: 3.21rem; left: 3.21rem;
animation: lds-ellipsis3 0.6s infinite; animation: lds-ellipsis3 0.6s infinite;
} }
@keyframes lds-text { @keyframes lds-text {
from { from {
font-size: 1em; font-size: 1em;
} }
to { to {
font-size: 1.5em; font-size: 1.5em;
} }
} }
.lds-text { .lds-text {
position: absolute; position: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
margin-left: -5rem; margin-left: -5rem;
margin-top: 8rem; margin-top: 8rem;
font-size: 0.8rem; font-size: 0.8rem;
letter-spacing: 0.25em; letter-spacing: 0.25em;
color: #fff; color: #fff;
} }
.lds-text b { .lds-text b {
font-weight: 300; font-weight: 300;
animation: lds-text 5s ease infinite alternate; animation: lds-text 5s ease infinite alternate;
} }
.lds-text b:nth-child(1) { .lds-text b:nth-child(1) {
animation-delay: 0.5s; animation-delay: 0.5s;
} }
.lds-text b:nth-child(2) { .lds-text b:nth-child(2) {
animation-delay: 1s; animation-delay: 1s;
} }
.lds-text b:nth-child(3) { .lds-text b:nth-child(3) {
animation-delay: 1.5s; animation-delay: 1.5s;
} }
.lds-text b:nth-child(4) { .lds-text b:nth-child(4) {
animation-delay: 2s; animation-delay: 2s;
} }
.lds-text b:nth-child(5) { .lds-text b:nth-child(5) {
animation-delay: 2.5s; animation-delay: 2.5s;
} }
.lds-text b:nth-child(6) { .lds-text b:nth-child(6) {
animation-delay: 3s; animation-delay: 3s;
} }
.lds-text b:nth-child(7) { .lds-text b:nth-child(7) {
animation-delay: 3.5s; animation-delay: 3.5s;
} }
.lds-text b:nth-child(8) { .lds-text b:nth-child(8) {
animation-delay: 4s; animation-delay: 4s;
} }
.lds-text b:nth-child(9) { .lds-text b:nth-child(9) {
animation-delay: 4.5s; animation-delay: 4.5s;
} }
.lds-text b:nth-child(10) { .lds-text b:nth-child(10) {
animation-delay: 5s; animation-delay: 5s;
} }
@media (orientation: portrait) { @media (orientation: portrait) {
#PageLoading .logo { #PageLoading .logo {
width: 50vw; width: 50vw;
} }
#PageLoading .tagline { #PageLoading .tagline {
font-size: 4vw; font-size: 4vw;
} }
} }
</style> </style>
<div id="PageLoading"> <div id="PageLoading">
<div class="loading-spinner"> <div class="loading-spinner">
<img <img class="logo" src="../../img/logo.svg" width="200" alt="UI Kit" /><br />
class="logo" <div class="lds-ellipsis">
src="../../img/logo.svg" <div></div>
width="200" <div></div>
alt="UI Kit" <div></div>
/><br /> <div></div>
<div class="lds-ellipsis"> </div>
<div></div> <br />
<div></div> <div class="lds-placeholder">LOADING...</div>
<div></div> <div class="lds-text">
<div></div> <b>L</b>
</div> <b>O</b>
<br /> <b>A</b>
<div class="lds-placeholder">LOADING...</div> <b>D</b>
<div class="lds-text"> <b>I</b>
<b>L</b> <b>N</b>
<b>O</b> <b>G</b>
<b>A</b> <b>.</b>
<b>D</b> <b>.</b>
<b>I</b> <b>.</b>
<b>N</b> </div>
<b>G</b> </div>
<b>.</b>
<b>.</b>
<b>.</b>
</div>
</div>
</div> </div>

View File

@ -1,7 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<head>
<title>Webpack Bootstrap 4 UI Demo</title> <title>Webpack Bootstrap 4 UI Demo</title>
<%= require('html-loader!./html/Head.html').default %> <%= require('html-loader!./html/Head.html').default %>
<meta name="ping" content="/Security/ping" /> <meta name="ping" content="/Security/ping" />
@ -9,93 +8,90 @@
<meta name="api_static_domain" content="<%= STATIC_URL %>" /> <meta name="api_static_domain" content="<%= STATIC_URL %>" />
<meta name="swversion" content="<%= SWVERSION %>" /> <meta name="swversion" content="<%= SWVERSION %>" />
<base href="<%= BASE_HREF %>" /> <base href="<%= BASE_HREF %>" />
</head> </head>
<body data-default-lng="0" data-default-lat="0"> <body data-default-lng="0" data-default-lat="0">
<div class="wrapper"> <div class="wrapper">
<%= require('html-loader!./html/_components/LoadingSpinner.html').default %> <%= require('html-loader!./html/_components/LoadingSpinner.html').default
<%= require('html-loader!./html/_components/Alerts.html').default %> %> <%= require('html-loader!./html/_components/Alerts.html').default %>
<%= <%= require('html-loader!./html/First.html').default %> <%=
require('html-loader!./html/First.html').default %> require('html-loader!./html/_components/Flyout.html').default %>
<%= <header id="Header" class="stiky-top">
require('html-loader!./html/_components/Flyout.html').default %> <%= require('html-loader!./html/Navigation.html').default %>
<header id="Header" class="stiky-top"> </header>
<%= require('html-loader!./html/Navigation.html').default %> <main id="MainContent" class="page-content">
</header> <div class="elemental-area">
<main id="MainContent" class="page-content"> <div class="element page-header-element">
<div class="elemental-area"> <div class="element-container container">
<div class="element page-header-element"> <h1 class="page-header">Webpack Bootstrap 4 UI Demo</h1>
<div class="element-container container">
<h1 class="page-header">
Webpack Bootstrap 4 UI Demo
</h1>
</div>
</div>
<!-- Slider -->
<section id="Slider" class="element site__elements__sliderelement">
<div class="element-container container-fluid">
<%= require('html-loader!./html/Slider.html').default %>
</div>
</section>
<!-- /Slider -->
<!-- Lightbox -->
<section id="Lightbox" class="element dnadesign__elemental__models__elementcontent">
<div class="element-container container">
<div class="content-element__content">
<h2 class="content-element__title">
Lightbox Demo
</h2>
<%=
require('html-loader!../node_modules/@a2nt/meta-lightbox-js/src/html/meta-lightbox.html').default
%>
</div>
</div>
</section>
<!-- /Lightbox -->
<!-- Content -->
<section id="Content" class="element dnadesign__elemental__models__elementcontent">
<div class="element-container container">
<%=
require('html-loader!./html/Elements/Content.html').default
%>
</div>
</section>
<!-- /Content -->
<!-- List -->
<section id="List" class="element dnadesign__elementallist__model__elementlist bg-dark">
<div class="element-container container">
<%=
require('html-loader!./html/Elements/ElementsList.html').default
%>
</div>
</section>
<!-- /List -->
<!-- Accordion List -->
<section id="AccordionList" class="element site__elements__accordion">
<div class="element-container container">
<%=
require('html-loader!./html/Elements/Accordion.html').default
%>
</div>
</section>
<!-- /Accordion List -->
<!-- Map Element -->
<section id="MapElement" class="element site__elements__mapelement">
<div class="element-container container">
<%= require('html-loader!./html/Elements/Map.html').default
%>
</div>
</section>
<!-- /Map Element -->
</div> </div>
</main> </div>
<!-- Slider -->
<section id="Slider" class="element site__elements__sliderelement">
<div class="element-container container-fluid">
<%= require('html-loader!./html/Slider.html').default %>
</div>
</section>
<!-- /Slider -->
<!-- Lightbox -->
<section
id="Lightbox"
class="element dnadesign__elemental__models__elementcontent"
>
<div class="element-container container">
<div class="content-element__content">
<h2 class="content-element__title">Lightbox Demo</h2>
<%=
require('html-loader!../node_modules/@a2nt/meta-lightbox-js/src/html/meta-lightbox.html').default
%>
</div>
</div>
</section>
<!-- /Lightbox -->
<!-- Content -->
<section
id="Content"
class="element dnadesign__elemental__models__elementcontent"
>
<div class="element-container container">
<%= require('html-loader!./html/Elements/Content.html').default %>
</div>
</section>
<!-- /Content -->
<!-- List -->
<section
id="List"
class="element dnadesign__elementallist__model__elementlist bg-dark"
>
<div class="element-container container">
<%=
require('html-loader!./html/Elements/ElementsList.html').default
%>
</div>
</section>
<!-- /List -->
<!-- Accordion List -->
<section id="AccordionList" class="element site__elements__accordion">
<div class="element-container container">
<%= require('html-loader!./html/Elements/Accordion.html').default
%>
</div>
</section>
<!-- /Accordion List -->
<!-- Map Element -->
<section id="MapElement" class="element site__elements__mapelement">
<div class="element-container container">
<%= require('html-loader!./html/Elements/Map.html').default %>
</div>
</section>
<!-- /Map Element -->
</div>
</main>
</div> </div>
<footer id="Footer" class="footer site-footer"> <footer id="Footer" class="footer site-footer">
<%= require('html-loader!./html/Footer.html').default %> <%= require('html-loader!./html/Footer.html').default %>
</footer> </footer>
<!-- React is required --> <!-- React is required -->
<%= REACT_SCRIPTS %> <%= REACT_SCRIPTS %> <%= require('html-loader!./html/Last.html').default %>
<%= require('html-loader!./html/Last.html').default %> </body>
</body>
</html> </html>

View File

@ -6,7 +6,7 @@
//import MAP_DRIVER from './_components/drivers/_map.mapbox'; //import MAP_DRIVER from './_components/drivers/_map.mapbox';
const CONSTS = { const CONSTS = {
ENVS: ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'], ENVS: ["xs", "sm", "md", "lg", "xl", "xxl", "xxxl"],
//MAP_DRIVER, //MAP_DRIVER,
}; };

View File

@ -3,42 +3,42 @@
*/ */
export default { export default {
APOLLO_ERROR: 'apollo-error', APOLLO_ERROR: "apollo-error",
AJAX: 'ajax-load', AJAX: "ajax-load",
AJAXMAIN: 'ajax-main-load', AJAXMAIN: "ajax-main-load",
MAININIT: 'main-init', MAININIT: "main-init",
TABHIDDEN: 'tab-hidden', TABHIDDEN: "tab-hidden",
TABFOCUSED: 'tab-focused', TABFOCUSED: "tab-focused",
OFFLINE: 'offline', OFFLINE: "offline",
ONLINE: 'online', ONLINE: "online",
BACKONLINE: 'back-online', BACKONLINE: "back-online",
TOUCHENABLE: 'touch-enabled', TOUCHENABLE: "touch-enabled",
TOUCHDISABLED: 'touch-disabled', TOUCHDISABLED: "touch-disabled",
LOADED: 'load', LOADED: "load",
SWIPELEFT: 'swipeleft panleft', SWIPELEFT: "swipeleft panleft",
SWIPERIGHT: 'swiperight panright', SWIPERIGHT: "swiperight panright",
ALLERTAPPEARED: 'alert-appeared', ALLERTAPPEARED: "alert-appeared",
ALERTREMOVED: 'alert-removed', ALERTREMOVED: "alert-removed",
LODEDANDREADY: 'load-ready', LODEDANDREADY: "load-ready",
LAZYIMAGEREADY: 'image-lazy-bg-loaded', LAZYIMAGEREADY: "image-lazy-bg-loaded",
LAZYIMAGESREADY: 'images-lazy-loaded', LAZYIMAGESREADY: "images-lazy-loaded",
MAPLOADED: 'map-loaded', MAPLOADED: "map-loaded",
MAPAPILOADED: 'map-api-loaded', MAPAPILOADED: "map-api-loaded",
MAPMARKERCLICK: 'map-marker-click', MAPMARKERCLICK: "map-marker-click",
MAPPOPUPCLOSE: 'map-popup-close', MAPPOPUPCLOSE: "map-popup-close",
SCROLL: 'scroll', SCROLL: "scroll",
RESIZE: 'resize', RESIZE: "resize",
CAROUSEL_READY: 'bs.carousel.ready', CAROUSEL_READY: "bs.carousel.ready",
SET_TARGET_UPDATE: 'set-target-update', SET_TARGET_UPDATE: "set-target-update",
RESTORE_FIELD: 'restore-field', RESTORE_FIELD: "restore-field",
FORM_INIT_BASICS: 'form-basics', FORM_INIT_BASICS: "form-basics",
FORM_INIT_STEPPED: 'form-init-stepped', FORM_INIT_STEPPED: "form-init-stepped",
FORM_INIT_VALIDATE: 'form-init-validate', FORM_INIT_VALIDATE: "form-init-validate",
FORM_INIT_VALIDATE_FIELD: 'form-init-validate-field', FORM_INIT_VALIDATE_FIELD: "form-init-validate-field",
FORM_INIT_STORAGE: 'form-init-storage', FORM_INIT_STORAGE: "form-init-storage",
FORM_VALIDATION_FAILED: 'form-validation-failed', FORM_VALIDATION_FAILED: "form-validation-failed",
FORM_STEPPED_NEW_STEP: 'form-new-step', FORM_STEPPED_NEW_STEP: "form-new-step",
FORM_STEPPED_FIRST_STEP: 'form-first-step', FORM_STEPPED_FIRST_STEP: "form-first-step",
FORM_STEPPED_LAST_STEP: 'form-last-step', FORM_STEPPED_LAST_STEP: "form-last-step",
FORM_FIELDS: 'input,textarea,select', FORM_FIELDS: "input,textarea,select",
}; };

View File

@ -1,13 +1,8 @@
import { import { InMemoryCache } from "@apollo/client";
InMemoryCache,
} from '@apollo/client';
//import { IonicStorageModule } from '@ionic/storage'; //import { IonicStorageModule } from '@ionic/storage';
//import { persistCache, IonicStorageWrapper } from 'apollo3-cache-persist'; //import { persistCache, IonicStorageWrapper } from 'apollo3-cache-persist';
import { import { persistCacheSync, LocalStorageWrapper } from "apollo3-cache-persist";
persistCacheSync,
LocalStorageWrapper,
} from 'apollo3-cache-persist';
const cache = new InMemoryCache(); const cache = new InMemoryCache();
@ -16,11 +11,9 @@ const cache = new InMemoryCache();
persistCacheSync({ persistCacheSync({
cache, cache,
storage: new LocalStorageWrapper(window.localStorage), storage: new LocalStorageWrapper(window.localStorage),
key: 'web-persist', key: "web-persist",
maxSize: 1048576, // 1Mb maxSize: 1048576, // 1Mb
//new IonicStorageWrapper(IonicStorageModule), //new IonicStorageWrapper(IonicStorageModule),
}); });
export { export { cache };
cache,
};

View File

@ -1,25 +1,21 @@
import Events from '../../_events'; import Events from "../../_events";
import { import { cache } from "./cache";
cache,
} from './cache';
import { import {
from, from,
ApolloClient, ApolloClient,
HttpLink, HttpLink,
ApolloLink, ApolloLink,
concat, concat,
} from '@apollo/client'; } from "@apollo/client";
import { import { onError } from "@apollo/client/link/error";
onError, const NAME = "appolo";
} from '@apollo/client/link/error';
const NAME = 'appolo';
const API_META = document.querySelector('meta[name="api_url"]'); const API_META = document.querySelector('meta[name="api_url"]');
const API_URL = API_META ? const API_URL = API_META
API_META.getAttribute('content') : ? API_META.getAttribute("content")
`${window.location.protocol }//${ window.location.host }/graphql`; : `${window.location.protocol}//${window.location.host}/graphql`;
const authMiddleware = new ApolloLink((operation, forward) => { const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers // add the authorization to the headers
@ -32,7 +28,7 @@ const authMiddleware = new ApolloLink((operation, forward) => {
return forward(operation); return forward(operation);
}); });
console.info(`%cAPI: ${API_URL}`, 'color:green;font-size:10px'); console.info(`%cAPI: ${API_URL}`, "color:green;font-size:10px");
const link = from([ const link = from([
authMiddleware, authMiddleware,
@ -42,28 +38,18 @@ const link = from([
}); });
return forward(operation); return forward(operation);
}), }),
onError(({ onError(({ operation, response, graphQLErrors, networkError, forward }) => {
operation, if (operation.operationName === "IgnoreErrorsQuery") {
response,
graphQLErrors,
networkError,
forward,
}) => {
if (operation.operationName === 'IgnoreErrorsQuery') {
console.error(`${NAME}: IgnoreErrorsQuery`); console.error(`${NAME}: IgnoreErrorsQuery`);
response.errors = null; response.errors = null;
return; return;
} }
if (graphQLErrors) { if (graphQLErrors) {
graphQLErrors.forEach(({ graphQLErrors.forEach(({ message, locations, path }) =>
message,
locations,
path,
}) =>
console.error( console.error(
`${NAME}: [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`, `${NAME}: [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
), )
); );
} }
@ -91,7 +77,7 @@ const link = from([
// data from a previous link // data from a previous link
const time = new Date() - operation.getContext().start; const time = new Date() - operation.getContext().start;
console.log( console.log(
`${NAME}: operation ${operation.operationName} took ${time} ms to complete`, `${NAME}: operation ${operation.operationName} took ${time} ms to complete`
); );
window.dispatchEvent(new Event(Events.ONLINE)); window.dispatchEvent(new Event(Events.ONLINE));
@ -104,8 +90,8 @@ const link = from([
// Use explicit `window.fetch` so tha outgoing requests // Use explicit `window.fetch` so tha outgoing requests
// are captured and deferred until the Service Worker is ready. // are captured and deferred until the Service Worker is ready.
fetch: (...args) => fetch(...args), fetch: (...args) => fetch(...args),
credentials: 'same-origin', //'include', credentials: "same-origin", //'include',
connectToDevTools: process.env.NODE_ENV === 'development' ? true : false, connectToDevTools: process.env.NODE_ENV === "development" ? true : false,
}), }),
]); ]);
@ -117,6 +103,4 @@ const client = new ApolloClient({
link, link,
}); });
export { export { client };
client,
};

View File

@ -1,19 +1,19 @@
// browser tab visibility state detection // browser tab visibility state detection
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
const axios = require('axios'); const axios = require("axios");
export default ((W) => { export default ((W) => {
const NAME = 'main.lazy-images'; const NAME = "main.lazy-images";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
const API_STATIC = document.querySelector('meta[name="api_static_domain"]'); const API_STATIC = document.querySelector('meta[name="api_static_domain"]');
const API_STATIC_URL = API_STATIC ? const API_STATIC_URL = API_STATIC
API_STATIC.getAttribute('content') : ? API_STATIC.getAttribute("content")
`${window.location.protocol}//${window.location.host}`; : `${window.location.protocol}//${window.location.host}`;
console.log(`${NAME} [static url]: ${API_STATIC_URL}`); console.log(`${NAME} [static url]: ${API_STATIC_URL}`);
@ -21,26 +21,26 @@ export default ((W) => {
console.log(`${NAME}: Load lazy images`); console.log(`${NAME}: Load lazy images`);
D.querySelectorAll(`[data-lazy-src]`).forEach((el) => { D.querySelectorAll(`[data-lazy-src]`).forEach((el) => {
el.classList.remove('empty'); el.classList.remove("empty");
el.classList.add('loading'); el.classList.add("loading");
el.classList.remove('loading__network-error'); el.classList.remove("loading__network-error");
const attr = el.getAttribute('data-lazy-src'); const attr = el.getAttribute("data-lazy-src");
const imageUrl = attr.startsWith('http') ? attr : API_STATIC_URL + attr; const imageUrl = attr.startsWith("http") ? attr : API_STATIC_URL + attr;
// offline response will be served by caching service worker // offline response will be served by caching service worker
axios axios
.get(imageUrl, { .get(imageUrl, {
responseType: 'blob', responseType: "blob",
}) })
.then((response) => { .then((response) => {
const reader = new FileReader(); // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/FileReader const reader = new FileReader(); // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/FileReader
reader.readAsDataURL(response.data); reader.readAsDataURL(response.data);
reader.onload = () => { reader.onload = () => {
const imageDataUrl = reader.result; const imageDataUrl = reader.result;
el.setAttribute('src', imageDataUrl); el.setAttribute("src", imageDataUrl);
el.classList.remove('loading'); el.classList.remove("loading");
el.classList.add('loading__success'); el.classList.add("loading__success");
}; };
}) })
.catch((e) => { .catch((e) => {
@ -49,27 +49,27 @@ export default ((W) => {
if (e.response) { if (e.response) {
switch (e.response.status) { switch (e.response.status) {
case 404: case 404:
msg = 'Not Found.'; msg = "Not Found.";
break; break;
case 500: case 500:
msg = 'Server issue, please try again latter.'; msg = "Server issue, please try again latter.";
break; break;
default: default:
msg = 'Something went wrong.'; msg = "Something went wrong.";
break; break;
} }
console.error(`${NAME} [${imageUrl}]: ${msg}`); console.error(`${NAME} [${imageUrl}]: ${msg}`);
} else if (e.request) { } else if (e.request) {
msg = 'No response received'; msg = "No response received";
console.error(`${NAME} [${imageUrl}]: ${msg}`); console.error(`${NAME} [${imageUrl}]: ${msg}`);
} else { } else {
console.error(`${NAME} [${imageUrl}]: ${e.message}`); console.error(`${NAME} [${imageUrl}]: ${e.message}`);
} }
el.classList.remove('loading'); el.classList.remove("loading");
el.classList.add('loading__network-error'); el.classList.add("loading__network-error");
el.classList.add('empty'); el.classList.add("empty");
}); });
}); });
}; };

View File

@ -1,188 +1,182 @@
// browser tab visibility state detection // browser tab visibility state detection
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
import Page from './models/page.jsx'; import Page from "./models/page.jsx";
import { import { getParents } from "../main/funcs";
getParents,
} from '../main/funcs';
import { import { Collapse } from "bootstrap";
Collapse,
} from 'bootstrap';
import SpinnerUI from '../main/loading-spinner'; import SpinnerUI from "../main/loading-spinner";
const MainUILinks = ((W) => { const MainUILinks = ((W) => {
const NAME = 'main.links'; const NAME = "main.links";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
class MainUILinks { class MainUILinks {
window window;
static init() { static init() {
const ui = this; const ui = this;
ui.GraphPage = null; ui.GraphPage = null;
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
ui.loaded(); ui.loaded();
// history state switch // history state switch
W.addEventListener('popstate', (e) => { W.addEventListener("popstate", (e) => {
ui.popState(e); ui.popState(e);
}); });
} }
static loaded() { static loaded() {
const ui = this; const ui = this;
D.querySelectorAll('.graphql-page').forEach((el, i) => { D.querySelectorAll(".graphql-page").forEach((el, i) => {
const el_id = el.getAttribute('href'); const el_id = el.getAttribute("href");
el.setAttribute(`data-${ui.name}-id`, el_id); el.setAttribute(`data-${ui.name}-id`, el_id);
el.addEventListener('click', ui.loadClick); el.addEventListener("click", ui.loadClick);
}); });
} }
static setActiveLinks(link) { static setActiveLinks(link) {
const ui = this; const ui = this;
D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach( D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach((el) => {
(el) => { el.classList.add("active");
el.classList.add('active'); });
}, }
static reset() {
// reset focus
D.activeElement.blur();
// remove active and loading classes
D.querySelectorAll(".graphql-page,.nav-item").forEach((el2) => {
el2.classList.remove("active", "loading");
});
}
static popState(e) {
const ui = this;
SpinnerUI.show();
if (e.state && e.state.page) {
console.log(`${NAME}: [popstate] load`);
const state = JSON.parse(e.state.page);
state.current = null;
state.popstate = true;
ui.reset();
ui.setActiveLinks(e.state.link);
if (!ui.GraphPage) {
console.log(
`${NAME}: [popstate] GraphPage is missing. Have to render it first`
);
ui.GraphPage = ReactDOM.render(
<Page />,
document.getElementById("MainContent")
); );
} }
static reset() { ui.GraphPage.setState(state);
// reset focus SpinnerUI.hide();
D.activeElement.blur();
// remove active and loading classes window.dispatchEvent(new Event(Events.AJAX));
D.querySelectorAll('.graphql-page,.nav-item').forEach((el2) => { } else if (e.state && e.state.landing) {
el2.classList.remove('active', 'loading'); console.log(`${NAME}: [popstate] go to landing`);
}); W.location.href = e.state.landing;
} } else {
console.warn(`${NAME}: [popstate] state is missing`);
console.log(e);
SpinnerUI.hide();
}
}
static popState(e) { // link specific event {this} = current event, not MainUILinks
const ui = this; static loadClick(e) {
console.groupCollapsed(`${NAME}: load on click`);
e.preventDefault();
SpinnerUI.show(); const ui = MainUILinks;
const el = e.currentTarget;
if (e.state && e.state.page) { SpinnerUI.show();
console.log(`${NAME}: [popstate] load`);
const state = JSON.parse(e.state.page);
state.current = null; ui.reset();
state.popstate = true; el.classList.add("loading");
el.classList.remove("response-404", "response-500", "response-523");
BODY.classList.add("ajax-loading");
ui.reset(); // hide parent mobile nav
ui.setActiveLinks(e.state.link); const navs = getParents(el, ".collapse");
if (navs.length) {
if (!ui.GraphPage) { navs.forEach((nav) => {
console.log( const collapseInst = Collapse.getInstance(nav);
`${NAME}: [popstate] GraphPage is missing. Have to render it first`, if (collapseInst) {
); collapseInst.hide();
ui.GraphPage = ReactDOM.render(
<Page />,
document.getElementById('MainContent'),
);
}
ui.GraphPage.setState(state);
SpinnerUI.hide();
window.dispatchEvent(new Event(Events.AJAX));
} else if (e.state && e.state.landing) {
console.log(`${NAME}: [popstate] go to landing`);
W.location.href = e.state.landing;
} else {
console.warn(`${NAME}: [popstate] state is missing`);
console.log(e);
SpinnerUI.hide();
} }
} });
}
// link specific event {this} = current event, not MainUILinks // hide parent dropdown
static loadClick(e) { /*const dropdowns = getParents(el, '.dropdown-menu');
console.groupCollapsed(`${NAME}: load on click`);
e.preventDefault();
const ui = MainUILinks;
const el = e.currentTarget;
SpinnerUI.show();
ui.reset();
el.classList.add('loading');
el.classList.remove('response-404', 'response-500', 'response-523');
BODY.classList.add('ajax-loading');
// hide parent mobile nav
const navs = getParents(el, '.collapse');
if (navs.length) {
navs.forEach((nav) => {
const collapseInst = Collapse.getInstance(nav);
if (collapseInst) {
collapseInst.hide();
}
});
}
// hide parent dropdown
/*const dropdowns = getParents(el, '.dropdown-menu');
if (dropdowns.length) { if (dropdowns.length) {
const DropdownInst = Dropdown.getInstance(dropdowns[0]); const DropdownInst = Dropdown.getInstance(dropdowns[0]);
DropdownInst.hide(); DropdownInst.hide();
}*/ }*/
if (!ui.GraphPage) { if (!ui.GraphPage) {
ui.GraphPage = ReactDOM.render( ui.GraphPage = ReactDOM.render(
<Page />, <Page />,
document.getElementById('MainContent'), document.getElementById("MainContent")
);
}
const link = el.getAttribute("href") || el.getAttribute("data-href");
ui.GraphPage.state.current = el;
ui.GraphPage.load(link)
.then((response) => {
BODY.classList.remove("ajax-loading");
el.classList.remove("loading");
el.classList.add("active");
D.loading_apollo_link = null;
if (ui.GraphPage.state.Link) {
window.history.pushState(
{
page: JSON.stringify(ui.GraphPage.state),
link: el.getAttribute(`data-${ui.name}-id`),
},
ui.GraphPage.state.Title,
ui.GraphPage.state.Link
); );
ui.setActiveLinks(ui.GraphPage.state.Link);
} }
const link = el.getAttribute('href') || el.getAttribute('data-href'); SpinnerUI.hide();
window.dispatchEvent(new Event(Events.AJAX));
console.groupEnd(`${NAME}: load on click`);
})
.catch((e) => {
console.error(`${NAME}: loading error`);
console.log(e);
ui.GraphPage.state.current = el; /*BODY.classList.remove('ajax-loading');
ui.GraphPage.load(link)
.then((response) => {
BODY.classList.remove('ajax-loading');
el.classList.remove('loading');
el.classList.add('active');
D.loading_apollo_link = null;
if (ui.GraphPage.state.Link) {
window.history.pushState({
page: JSON.stringify(ui.GraphPage.state),
link: el.getAttribute(`data-${ui.name}-id`),
},
ui.GraphPage.state.Title,
ui.GraphPage.state.Link,
);
ui.setActiveLinks(ui.GraphPage.state.Link)
}
SpinnerUI.hide();
window.dispatchEvent(new Event(Events.AJAX));
console.groupEnd(`${NAME}: load on click`);
})
.catch((e) => {
console.error(`${NAME}: loading error`);
console.log(e);
/*BODY.classList.remove('ajax-loading');
el.classList.remove('loading');*/ el.classList.remove('loading');*/
el.classList.add('error', `response-${e.status}`); el.classList.add("error", `response-${e.status}`);
/*switch (e.status) { /*switch (e.status) {
case 500: case 500:
break; break;
case 404: case 404:
@ -193,17 +187,17 @@ const MainUILinks = ((W) => {
break; break;
}*/ }*/
//SpinnerUI.hide(); //SpinnerUI.hide();
//window.dispatchEvent(new Event(Events.AJAX)); //window.dispatchEvent(new Event(Events.AJAX));
console.groupEnd(`${NAME}: load on click`); console.groupEnd(`${NAME}: load on click`);
console.log(`${NAME}: reloading page ${link}`); console.log(`${NAME}: reloading page ${link}`);
// fallback loading // fallback loading
W.location.href = link; W.location.href = link;
}); });
} }
} }
W.addEventListener(`${Events.LOADED}`, () => { W.addEventListener(`${Events.LOADED}`, () => {

View File

@ -1,85 +1,79 @@
/* /*
* Lightbox window * Lightbox window
*/ */
import { import { Component } from "react";
Component import Events from "../../events";
} from 'react';
import Events from '../../events';
import { import { client } from "../apollo/init";
client import { gql } from "@apollo/client";
} from '../apollo/init';
import {
gql
} from '@apollo/client';
class Page extends Component { class Page extends Component {
state = { state = {
type: [], type: [],
shown: false, shown: false,
loading: false, loading: false,
error: false, error: false,
current: null, current: null,
ID: null, ID: null,
URLSegment: null, URLSegment: null,
ClassName: 'Page', ClassName: "Page",
CSSClass: null, CSSClass: null,
Title: null, Title: null,
Summary: null, Summary: null,
Link: null, Link: null,
URL: null, URL: null,
Elements: [], Elements: [],
page: null, page: null,
}; };
componentDidUpdate() { componentDidUpdate() {
const ui = this; const ui = this;
if (ui.state.Title) { if (ui.state.Title) {
document.title = ui.state.Title; document.title = ui.state.Title;
if (ui.state.URL) { if (ui.state.URL) {
window.history.pushState( window.history.pushState(
{ {
page: JSON.stringify(ui.state) page: JSON.stringify(ui.state),
}, },
ui.state.Title, ui.state.Title,
ui.state.URL, ui.state.URL
); );
} }
}
if (ui.state.Elements.length) {
window.dispatchEvent(new Event(Events.AJAX));
}
} }
constructor(props) { if (ui.state.Elements.length) {
super(props); window.dispatchEvent(new Event(Events.AJAX));
const ui = this;
ui.name = ui.constructor.name;
console.log(`${ui.name}: init`);
} }
}
reset = () => { constructor(props) {
const ui = this; super(props);
ui.setState({ const ui = this;
type: [], ui.name = ui.constructor.name;
shown: false, console.log(`${ui.name}: init`);
loading: false, }
error: false,
ID: null,
Title: null,
URL: null,
Elements: [],
});
};
load = (link) => { reset = () => {
const ui = this; const ui = this;
const query = gql(`
ui.setState({
type: [],
shown: false,
loading: false,
error: false,
ID: null,
Title: null,
URL: null,
Elements: [],
});
};
load = (link) => {
const ui = this;
const query = gql(`
query Pages { query Pages {
readPages(URLSegment: "home", limit: 1, offset: 0) { readPages(URLSegment: "home", limit: 1, offset: 0) {
edges { edges {
@ -120,110 +114,114 @@ class Page extends Component {
} }
`); `);
ui.reset(); ui.reset();
ui.setState({ ui.setState({
Title: 'Loading ...', Title: "Loading ...",
loading: true, loading: true,
});
console.log(
client.readQuery({
query,
})
);
client
.query({
query: query,
})
.then((resp) => {
const page = resp.data.readPages.edges[0].node;
// write to cache
client.writeQuery({
query,
data: {
resp,
},
}); });
console.log(client.readQuery({ console.log(
query client.readQuery({
})); query,
client })
.query({
query: query,
})
.then((resp) => {
const page = resp.data.readPages.edges[0].node;
// write to cache
client.writeQuery({
query,
data: {
resp
}
});
console.log(client.readQuery({
query
}));
ui.setState({
ID: page.ID,
Title: page.Title,
ClassName: page.ClassName,
URLSegment: page.URLSegment,
CSSClass: page.CSSClass,
Summary: page.Summary,
Link: page.Link,
Elements: page.Elements.edges,
URL: page.Link || link,
loading: false,
});
})
.catch((error) => {
console.error(error);
let msg = '';
if (error.response) {
switch (error.response.status) {
case 404:
msg = 'Not Found.';
break;
case 500:
msg = 'Server issue, please try again latter.';
break;
default:
msg = 'Something went wrong.';
break;
}
} else if (error.request) {
msg = 'No response received';
} else {
console.warn('Error', error.message);
}
ui.setState({
error: msg
});
});
};
getHtml = (html) => {
const decodeHtmlEntity = (input) => {
var doc = new DOMParser().parseFromString(input, 'text/html');
return doc.documentElement.textContent;
};
return {
__html: decodeHtmlEntity(html)
};
};
render() {
const ui = this;
const name = ui.name;
const className = `elemental-area page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
const ElementItem = (props) => (
<div dangerouslySetInnerHTML={props.html}></div>
); );
let html = ''; ui.setState({
if (ui.state.Elements.length) { ID: page.ID,
ui.state.Elements.map((el) => { Title: page.Title,
html += el.node.Render; ClassName: page.ClassName,
}); URLSegment: page.URLSegment,
CSSClass: page.CSSClass,
Summary: page.Summary,
Link: page.Link,
Elements: page.Elements.edges,
URL: page.Link || link,
loading: false,
});
})
.catch((error) => {
console.error(error);
let msg = "";
if (error.response) {
switch (error.response.status) {
case 404:
msg = "Not Found.";
break;
case 500:
msg = "Server issue, please try again latter.";
break;
default:
msg = "Something went wrong.";
break;
}
} else if (error.request) {
msg = "No response received";
} else { } else {
html += '<div class="loading">Loading ...</div>'; console.warn("Error", error.message);
} }
return ( ui.setState({
<div error: msg,
className={className} });
dangerouslySetInnerHTML={ui.getHtml(html)} });
></div> };
);
getHtml = (html) => {
const decodeHtmlEntity = (input) => {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
};
return {
__html: decodeHtmlEntity(html),
};
};
render() {
const ui = this;
const name = ui.name;
const className = `elemental-area page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
const ElementItem = (props) => (
<div dangerouslySetInnerHTML={props.html}></div>
);
let html = "";
if (ui.state.Elements.length) {
ui.state.Elements.map((el) => {
html += el.node.Render;
});
} else {
html += '<div class="loading">Loading ...</div>';
} }
return (
<div
className={className}
dangerouslySetInnerHTML={ui.getHtml(html)}
></div>
);
}
} }
export default Page; export default Page;

View File

@ -1,72 +1,63 @@
/* /*
* page #MainContent area * page #MainContent area
*/ */
import { import { Component } from "react";
Component
} from 'react';
import { import { useQuery, gql } from "@apollo/client";
useQuery, import { client } from "../apollo/init";
gql import { cache } from "../apollo/cache";
} from '@apollo/client';
import {
client
} from '../apollo/init';
import {
cache
} from '../apollo/cache';
const D = document; const D = document;
const BODY = document.body; const BODY = document.body;
class Page extends Component { class Page extends Component {
state = { state = {
type: [], type: [],
shown: false, shown: false,
Title: 'Loading ...', Title: "Loading ...",
loading: true, loading: true,
error: false, error: false,
current: null, current: null,
ID: null, ID: null,
URLSegment: null, URLSegment: null,
ClassName: 'Page', ClassName: "Page",
CSSClass: null, CSSClass: null,
Summary: null, Summary: null,
Link: null, Link: null,
URL: null, URL: null,
HTML: null, HTML: null,
Elements: [], Elements: [],
page: null, page: null,
}; };
componentDidUpdate() { componentDidUpdate() {
const ui = this; const ui = this;
if (ui.state.Title) { if (ui.state.Title) {
document.title = ui.state.Title; document.title = ui.state.Title;
}
} }
}
constructor(props) { constructor(props) {
super(props); super(props);
const ui = this; const ui = this;
ui.name = ui.constructor.name; ui.name = ui.constructor.name;
ui.empty_state = ui.state; ui.empty_state = ui.state;
console.log(`${ui.name}: init`); console.log(`${ui.name}: init`);
} }
isOnline = () => { isOnline = () => {
return BODY.classList.contains('is-online'); return BODY.classList.contains("is-online");
}; };
load = (link) => { load = (link) => {
const ui = this; const ui = this;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const query = gql(`query Pages { const query = gql(`query Pages {
readPages(Link: "${link}") { readPages(Link: "${link}") {
edges { edges {
node { node {
@ -85,149 +76,149 @@ class Page extends Component {
} }
}`); }`);
if (!ui.isOnline()) { if (!ui.isOnline()) {
const data = client.readQuery({ const data = client.readQuery({
query query,
});
if (data && ui.processResponse(data)) {
console.log(`${ui.name}: Offline cached response`);
resolve(data);
} else {
console.log(`${ui.name}: No offline response`);
ui.setState(
Object.assign(ui.empty_state, {
Title: 'Offline',
CSSClass: 'graphql__status-523',
Summary: "You're Offline. The page is not available now.",
loading: false,
}),
);
reject({
status: 523
});
}
} else {
if (!ui.state.loading) {
ui.setState(ui.empty_state);
}
client
.query({
query: query,
fetchPolicy: ui.isOnline() ? 'no-cache' : 'cache-first',
})
.then((resp) => {
// write to cache
const data = resp.data;
client.writeQuery({
query,
data: data
});
if (ui.processResponse(data)) {
console.log(`${ui.name}: got the server response`);
resolve(data);
} else {
console.log(`${ui.name}: not found`);
reject({
status: 404
});
}
})
.catch((error) => {
reject({
status: 500,
error: error
});
});
}
}); });
};
processResponse = (data) => { if (data && ui.processResponse(data)) {
const ui = this; console.log(`${ui.name}: Offline cached response`);
resolve(data);
} else {
console.log(`${ui.name}: No offline response`);
if (!data.readPages.edges.length) { ui.setState(
console.log(`${ui.name}: not found`); Object.assign(ui.empty_state, {
Title: "Offline",
CSSClass: "graphql__status-523",
Summary: "You're Offline. The page is not available now.",
loading: false,
})
);
ui.setState( reject({
Object.assign(ui.empty_state, { status: 523,
Title: 'Not Found', });
CSSClass: 'graphql__status-404', }
Summary: 'The page is not found.', } else {
loading: false, if (!ui.state.loading) {
}), ui.setState(ui.empty_state);
);
return false;
} }
const page = data.readPages.edges[0].node; client
ui.setState({ .query({
ID: page.ID, query: query,
Title: page.Title, fetchPolicy: ui.isOnline() ? "no-cache" : "cache-first",
ClassName: page.ClassName, })
URLSegment: page.URLSegment, .then((resp) => {
CSSClass: page.CSSClass, // write to cache
Summary: page.Summary, const data = resp.data;
Link: page.Link, client.writeQuery({
HTML: page.HTML, query,
Elements: [], //page.Elements.edges, data: data,
loading: false,
});
return true;
};
getHtml = (html) => {
const decodeHtmlEntity = (input) => {
var doc = new DOMParser().parseFromString(input, 'text/html');
return doc.documentElement.textContent;
};
return {
__html: decodeHtmlEntity(html)
};
};
render() {
const ui = this;
const name = ui.name;
const className = `elemental-area graphql__page page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
const ElementItem = (props) => (
<div dangerouslySetInnerHTML={props.html}></div>
);
let html = '';
if (ui.state.HTML) {
console.log(`${ui.name}: HTML only`);
html = ui.state.HTML;
} else if (ui.state.Elements.length) {
console.log(`${ui.name}: render`);
ui.state.Elements.map((el) => {
html += el.node.Render;
}); });
} else if (ui.state.Summary && ui.state.Summary.length) {
console.log(`${ui.name}: summary only`);
html = `<div class="summary">${ui.state.Summary}</div>`;
}
if (ui.state.loading) { if (ui.processResponse(data)) {
const spinner = D.getElementById('PageLoading'); console.log(`${ui.name}: got the server response`);
html = `<div class="loading">Loading ...</div>`; resolve(data);
} } else {
console.log(`${ui.name}: not found`);
reject({
status: 404,
});
}
})
.catch((error) => {
reject({
status: 500,
error: error,
});
});
}
});
};
return ( processResponse = (data) => {
<div const ui = this;
className={className}
dangerouslySetInnerHTML={ui.getHtml(html)} if (!data.readPages.edges.length) {
></div> console.log(`${ui.name}: not found`);
);
ui.setState(
Object.assign(ui.empty_state, {
Title: "Not Found",
CSSClass: "graphql__status-404",
Summary: "The page is not found.",
loading: false,
})
);
return false;
} }
const page = data.readPages.edges[0].node;
ui.setState({
ID: page.ID,
Title: page.Title,
ClassName: page.ClassName,
URLSegment: page.URLSegment,
CSSClass: page.CSSClass,
Summary: page.Summary,
Link: page.Link,
HTML: page.HTML,
Elements: [], //page.Elements.edges,
loading: false,
});
return true;
};
getHtml = (html) => {
const decodeHtmlEntity = (input) => {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
};
return {
__html: decodeHtmlEntity(html),
};
};
render() {
const ui = this;
const name = ui.name;
const className = `elemental-area graphql__page page-${ui.state.CSSClass} url-${ui.state.URLSegment}`;
const ElementItem = (props) => (
<div dangerouslySetInnerHTML={props.html}></div>
);
let html = "";
if (ui.state.HTML) {
console.log(`${ui.name}: HTML only`);
html = ui.state.HTML;
} else if (ui.state.Elements.length) {
console.log(`${ui.name}: render`);
ui.state.Elements.map((el) => {
html += el.node.Render;
});
} else if (ui.state.Summary && ui.state.Summary.length) {
console.log(`${ui.name}: summary only`);
html = `<div class="summary">${ui.state.Summary}</div>`;
}
if (ui.state.loading) {
const spinner = D.getElementById("PageLoading");
html = `<div class="loading">Loading ...</div>`;
}
return (
<div
className={className}
dangerouslySetInnerHTML={ui.getHtml(html)}
></div>
);
}
} }
export default Page; export default Page;

View File

@ -1,12 +1,12 @@
// ping online/offline state switch and detection // ping online/offline state switch and detection
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
const axios = require('axios'); const axios = require("axios");
export default ((W) => { export default ((W) => {
const NAME = 'main.online'; const NAME = "main.online";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
@ -21,7 +21,7 @@ export default ((W) => {
update_online_status_lock = true; update_online_status_lock = true;
if (online) { if (online) {
if (BODY.classList.contains('is-offline')) { if (BODY.classList.contains("is-offline")) {
console.log(`${NAME}: back Online`); console.log(`${NAME}: back Online`);
W.dispatchEvent(new Event(Events.BACKONLINE)); W.dispatchEvent(new Event(Events.BACKONLINE));
} else { } else {
@ -29,8 +29,8 @@ export default ((W) => {
W.dispatchEvent(new Event(Events.ONLINE)); W.dispatchEvent(new Event(Events.ONLINE));
} }
BODY.classList.add('is-online'); BODY.classList.add("is-online");
BODY.classList.remove('is-offline'); BODY.classList.remove("is-offline");
if (PING_META && !pingInterval) { if (PING_META && !pingInterval) {
console.log(`${NAME}: SESSION_PING is active`); console.log(`${NAME}: SESSION_PING is active`);
@ -39,8 +39,8 @@ export default ((W) => {
} else { } else {
console.log(`${NAME}: Offline`); console.log(`${NAME}: Offline`);
BODY.classList.add('is-offline'); BODY.classList.add("is-offline");
BODY.classList.remove('is-online'); BODY.classList.remove("is-online");
clearInterval(pingInterval); clearInterval(pingInterval);
pingInterval = null; pingInterval = null;
@ -54,11 +54,11 @@ export default ((W) => {
// session ping // session ping
let session_ping_lock = false; let session_ping_lock = false;
const SESSION_PING = () => { const SESSION_PING = () => {
if (session_ping_lock || BODY.classList.contains('is-offline')) { if (session_ping_lock || BODY.classList.contains("is-offline")) {
return; return;
} }
const PING_URL = PING_META.getAttribute('content'); const PING_URL = PING_META.getAttribute("content");
console.log(`${NAME}: session ping`); console.log(`${NAME}: session ping`);
session_ping_lock = true; session_ping_lock = true;
@ -80,9 +80,8 @@ export default ((W) => {
// current browser online state // current browser online state
const navigatorStateUpdate = () => { const navigatorStateUpdate = () => {
if (typeof navigator.onLine !== 'undefined') { if (typeof navigator.onLine !== "undefined") {
if (!navigator.onLine) { if (!navigator.onLine) {
UPDATE_ONLINE_STATUS(false); UPDATE_ONLINE_STATUS(false);
} else { } else {

View File

@ -1,31 +1,31 @@
'use strict'; "use strict";
/* /*
* UI Basics * UI Basics
*/ */
//import $ from 'jquery'; //import $ from 'jquery';
import '../scss/app.scss'; import "../scss/app.scss";
import Events from './_events'; import Events from "./_events";
import MainUI from './main'; import MainUI from "./main";
/* /*
* Extra functionality * Extra functionality
*/ */
import '@a2nt/meta-lightbox-js/src/js/app'; import "@a2nt/meta-lightbox-js/src/js/app";
import './ui/carousel'; import "./ui/carousel";
//import './ui/ui.instagram.feed'; //import './ui/ui.instagram.feed';
/* /*
* AJAX functionality * AJAX functionality
*/ */
//import './ajax/links'; //import './ajax/links';
import './ajax/online'; import "./ajax/online";
import './ajax/lazy-images'; import "./ajax/lazy-images";
/* /*
* Site specific modules * Site specific modules
*/ */
import './layout'; import "./layout";
//import 'hammerjs/hammer'; //import 'hammerjs/hammer';
//import 'jquery-hammerjs/jquery.hammer'; //import 'jquery-hammerjs/jquery.hammer';

View File

@ -1,5 +1,5 @@
function _gaLt(event) { function _gaLt(event) {
if (typeof ga !== 'function') { if (typeof ga !== "function") {
return; return;
} }
@ -8,8 +8,8 @@ function _gaLt(event) {
/* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */ /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
while ( while (
el && el &&
(typeof el.tagName == 'undefined' || (typeof el.tagName == "undefined" ||
el.tagName.toLowerCase() != 'a' || el.tagName.toLowerCase() != "a" ||
!el.href) !el.href)
) { ) {
el = el.parentNode; el = el.parentNode;
@ -21,7 +21,7 @@ function _gaLt(event) {
if (link.indexOf(location.host) == -1 && !link.match(/^javascript:/i)) { if (link.indexOf(location.host) == -1 && !link.match(/^javascript:/i)) {
/* external link */ /* external link */
/* HitCallback function to either open link in either same or new window */ /* HitCallback function to either open link in either same or new window */
var hitBack = function(link, target) { var hitBack = function (link, target) {
target ? window.open(link, target) : (window.location.href = link); target ? window.open(link, target) : (window.location.href = link);
}; };
/* Is target set and not _(self|parent|top)? */ /* Is target set and not _(self|parent|top)? */
@ -31,12 +31,12 @@ function _gaLt(event) {
: false; : false;
/* send event with callback */ /* send event with callback */
ga( ga(
'send', "send",
'event', "event",
'Outgoing Links', "Outgoing Links",
link, link,
document.location.pathname + document.location.search, document.location.pathname + document.location.search,
{ hitCallback: hitBack(link, target) }, { hitCallback: hitBack(link, target) }
); );
/* Prevent standard click */ /* Prevent standard click */
@ -49,13 +49,13 @@ function _gaLt(event) {
var w = window; var w = window;
w.addEventListener w.addEventListener
? w.addEventListener( ? w.addEventListener(
'load', "load",
() => { () => {
document.body.addEventListener('click', _gaLt, !1); document.body.addEventListener("click", _gaLt, !1);
}, },
!1, !1
) )
: w.attachEvent && : w.attachEvent &&
w.attachEvent('onload', () => { w.attachEvent("onload", () => {
document.body.attachEvent('onclick', _gaLt); document.body.attachEvent("onclick", _gaLt);
}); });

View File

@ -1,4 +1,4 @@
'use strict'; "use strict";
const Obj = { const Obj = {
init: () => { init: () => {
@ -9,11 +9,9 @@ const Obj = {
ui.setMap(options.map); ui.setMap(options.map);
ui.position = options.position; ui.position = options.position;
ui.html = ui.html = options.html
(options.html ? ? options.html
options.html : : '<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>';
'<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>'
);
ui.divClass = options.divClass; ui.divClass = options.divClass;
ui.align = options.align; ui.align = options.align;
ui.isDebugMode = options.debug; ui.isDebugMode = options.debug;
@ -21,7 +19,7 @@ const Obj = {
ui.onMouseOver = options.onMouseOver; ui.onMouseOver = options.onMouseOver;
ui.isBoolean = (arg) => { ui.isBoolean = (arg) => {
if (typeof arg === 'boolean') { if (typeof arg === "boolean") {
return true; return true;
} else { } else {
return false; return false;
@ -29,7 +27,7 @@ const Obj = {
}; };
ui.isNotUndefined = (arg) => { ui.isNotUndefined = (arg) => {
if (typeof arg !== 'undefined') { if (typeof arg !== "undefined") {
return true; return true;
} else { } else {
return false; return false;
@ -45,7 +43,7 @@ const Obj = {
}; };
ui.isString = (arg) => { ui.isString = (arg) => {
if (typeof arg === 'string') { if (typeof arg === "string") {
return true; return true;
} else { } else {
return false; return false;
@ -53,7 +51,7 @@ const Obj = {
}; };
ui.isFunction = (arg) => { ui.isFunction = (arg) => {
if (typeof arg === 'function') { if (typeof arg === "function") {
return true; return true;
} else { } else {
return false; return false;
@ -64,8 +62,8 @@ const Obj = {
const ui = this; const ui = this;
// Create div element. // Create div element.
ui.div = document.createElement('div'); ui.div = document.createElement("div");
ui.div.style.position = 'absolute'; ui.div.style.position = "absolute";
// Validate and set custom div class // Validate and set custom div class
if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass)) if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass))
@ -81,19 +79,19 @@ const Obj = {
// If debug mode is enabled custom content will be replaced with debug content // If debug mode is enabled custom content will be replaced with debug content
if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) { if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) {
ui.div.className = 'debug-mode'; ui.div.className = "debug-mode";
ui.div.innerHTML = ui.div.innerHTML =
'<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' + '<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' +
'<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>'; '<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>';
ui.div.setAttribute( ui.div.setAttribute(
'style', "style",
'position: absolute;' + "position: absolute;" +
'border: 5px dashed red;' + "border: 5px dashed red;" +
'height: 150px;' + "height: 150px;" +
'width: 150px;' + "width: 150px;" +
'display: flex;' + "display: flex;" +
'justify-content: center;' + "justify-content: center;" +
'align-items: center;' "align-items: center;"
); );
} }
@ -101,14 +99,14 @@ const Obj = {
ui.getPanes().overlayMouseTarget.appendChild(ui.div); ui.getPanes().overlayMouseTarget.appendChild(ui.div);
// Add listeners to the element. // Add listeners to the element.
google.maps.event.addDomListener(ui.div, 'click', (event) => { google.maps.event.addDomListener(ui.div, "click", (event) => {
google.maps.event.trigger(ui, 'click'); google.maps.event.trigger(ui, "click");
if (ui.isFunction(ui.onClick)) ui.onClick(); if (ui.isFunction(ui.onClick)) ui.onClick();
event.stopPropagation(); event.stopPropagation();
}); });
google.maps.event.addDomListener(ui.div, 'mouseover', (event) => { google.maps.event.addDomListener(ui.div, "mouseover", (event) => {
google.maps.event.trigger(ui, 'mouseover'); google.maps.event.trigger(ui, "mouseover");
if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver(); if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver();
event.stopPropagation(); event.stopPropagation();
}); });
@ -118,9 +116,9 @@ const Obj = {
const ui = this; const ui = this;
// Calculate position of div // Calculate position of div
var positionInPixels = ui.getProjection().fromLatLngToDivPixel( var positionInPixels = ui
new google.maps.LatLng(ui.position) .getProjection()
); .fromLatLngToDivPixel(new google.maps.LatLng(ui.position));
// Align HTML overlay relative to original position // Align HTML overlay relative to original position
var divOffset = { var divOffset = {
@ -128,40 +126,40 @@ const Obj = {
x: undefined, x: undefined,
}; };
switch (Array.isArray(ui.align) ? ui.align.join(' ') : '') { switch (Array.isArray(ui.align) ? ui.align.join(" ") : "") {
case 'left top': case "left top":
divOffset.y = ui.div.offsetHeight; divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth; divOffset.x = ui.div.offsetWidth;
break; break;
case 'left center': case "left center":
divOffset.y = ui.div.offsetHeight / 2; divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth; divOffset.x = ui.div.offsetWidth;
break; break;
case 'left bottom': case "left bottom":
divOffset.y = 0; divOffset.y = 0;
divOffset.x = ui.div.offsetWidth; divOffset.x = ui.div.offsetWidth;
break; break;
case 'center top': case "center top":
divOffset.y = ui.div.offsetHeight; divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth / 2; divOffset.x = ui.div.offsetWidth / 2;
break; break;
case 'center center': case "center center":
divOffset.y = ui.div.offsetHeight / 2; divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth / 2; divOffset.x = ui.div.offsetWidth / 2;
break; break;
case 'center bottom': case "center bottom":
divOffset.y = 0; divOffset.y = 0;
divOffset.x = ui.div.offsetWidth / 2; divOffset.x = ui.div.offsetWidth / 2;
break; break;
case 'right top': case "right top":
divOffset.y = ui.div.offsetHeight; divOffset.y = ui.div.offsetHeight;
divOffset.x = 0; divOffset.x = 0;
break; break;
case 'right center': case "right center":
divOffset.y = ui.div.offsetHeight / 2; divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = 0; divOffset.x = 0;
break; break;
case 'right bottom': case "right bottom":
divOffset.y = 0; divOffset.y = 0;
divOffset.x = 0; divOffset.x = 0;
break; break;
@ -171,8 +169,8 @@ const Obj = {
} }
// Set position // Set position
ui.div.style.top = `${positionInPixels.y - divOffset.y }px`; ui.div.style.top = `${positionInPixels.y - divOffset.y}px`;
ui.div.style.left = `${positionInPixels.x - divOffset.x }px`; ui.div.style.left = `${positionInPixels.x - divOffset.x}px`;
} }
getPosition() { getPosition() {
@ -194,6 +192,6 @@ const Obj = {
} }
return GoogleMapsHtmlOverlay; return GoogleMapsHtmlOverlay;
}, },
} };
export default Obj; export default Obj;

View File

@ -1,14 +1,14 @@
'use strict'; "use strict";
import MarkerClusterer from '@googlemaps/markerclustererplus'; import MarkerClusterer from "@googlemaps/markerclustererplus";
import Events from '../_events'; import Events from "../_events";
import MarkerUI from './map.google.marker'; import MarkerUI from "./map.google.marker";
const GoogleMapsDriver = ((window) => { const GoogleMapsDriver = ((window) => {
class GoogleMapsDriver { class GoogleMapsDriver {
getName() { getName() {
return 'GoogleMapsDriver'; return "GoogleMapsDriver";
} }
init(el, config = []) { init(el, config = []) {
@ -22,8 +22,10 @@ const GoogleMapsDriver = ((window) => {
ui.googleApiLoaded(); ui.googleApiLoaded();
}; };
const script = document.createElement('script'); const script = document.createElement("script");
script.src = `https://maps.googleapis.com/maps/api/js?key=${config['key']}&callback=init${ui.getName()}`; script.src = `https://maps.googleapis.com/maps/api/js?key=${
config["key"]
}&callback=init${ui.getName()}`;
script.async = true; script.async = true;
script.defer = true; script.defer = true;
document.head.appendChild(script); document.head.appendChild(script);
@ -34,18 +36,22 @@ const GoogleMapsDriver = ((window) => {
const el = ui.el; const el = ui.el;
const config = ui.config; const config = ui.config;
const mapDiv = el.querySelector('.mapAPI-map'); const mapDiv = el.querySelector(".mapAPI-map");
const zoom = config['mapZoom'] && config['mapZoom'] !== '0' ? parseInt(config['mapZoom']) : 10; const zoom =
const center = config['center'] && config['center'] !== ',' ? config["mapZoom"] && config["mapZoom"] !== "0"
{ ? parseInt(config["mapZoom"])
lat: config['center'][1], : 10;
lng: config['center'][0], const center =
} : config["center"] && config["center"] !== ","
{ ? {
lat: 0, lat: config["center"][1],
lng: 0, lng: config["center"][0],
}; }
const style = config['style'] ? config['style'] : null; : {
lat: 0,
lng: 0,
};
const style = config["style"] ? config["style"] : null;
console.log(`${ui.getName()}: API is loaded`); console.log(`${ui.getName()}: API is loaded`);
// init fontawesome icons // init fontawesome icons
@ -60,27 +66,30 @@ const GoogleMapsDriver = ((window) => {
ui.default_zoom = zoom; ui.default_zoom = zoom;
mapDiv.classList.add('mapboxgl-map'); mapDiv.classList.add("mapboxgl-map");
ui.popup = new ui.MarkerUI({ ui.popup = new ui.MarkerUI({
map: ui.map, map: ui.map,
align: ['center', 'top'], align: ["center", "top"],
divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none', divClass: "mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none",
html: '<div class="mapboxgl-popup-tip"></div><div class="mapboxgl-popup-content">' + html:
'<div class="mapboxgl-popup-close-button" type="button" aria-label="Close popup">×</div>' + '<div class="mapboxgl-popup-tip"></div><div class="mapboxgl-popup-content">' +
'<div class="html"></div>' + '<div class="mapboxgl-popup-close-button" type="button" aria-label="Close popup">×</div>' +
'</div>', '<div class="html"></div>' +
"</div>",
}); });
ui.popup.setMap(ui.map); ui.popup.setMap(ui.map);
ui.geocoder = new google.maps.Geocoder(); ui.geocoder = new google.maps.Geocoder();
ui.cluster = new MarkerClusterer(ui.map, null, { ui.cluster = new MarkerClusterer(ui.map, null, {
styles: [{ styles: [
width: 30, {
height: 30, width: 30,
className: 'mapboxgl-cluster', height: 30,
}], className: "mapboxgl-cluster",
},
],
}); });
el.dispatchEvent(new Event(Events.MAPAPILOADED)); el.dispatchEvent(new Event(Events.MAPAPILOADED));
@ -97,11 +106,11 @@ const GoogleMapsDriver = ((window) => {
const marker = new ui.MarkerUI({ const marker = new ui.MarkerUI({
position: pos, position: pos,
map: ui.map, map: ui.map,
align: ['center', 'top'], align: ["center", "top"],
html: `<div class="mapboxgl-marker"><div id="Marker${config['id']}" data-id="${config['id']}" class="marker">${config['icon']}</div></div>`, html: `<div class="mapboxgl-marker"><div id="Marker${config["id"]}" data-id="${config["id"]}" class="marker">${config["icon"]}</div></div>`,
onClick: () => { onClick: () => {
const el = document.querySelector(`#Marker${config['id']}`); const el = document.querySelector(`#Marker${config["id"]}`);
ui.showPopup(pos, config['content']); ui.showPopup(pos, config["content"]);
el.dispatchEvent(new Event(Events.MAPMARKERCLICK)); el.dispatchEvent(new Event(Events.MAPMARKERCLICK));
}, },
@ -118,38 +127,40 @@ const GoogleMapsDriver = ((window) => {
const ui = this; const ui = this;
const popup = ui.popup.getDiv(); const popup = ui.popup.getDiv();
if (ui.config['flyToMarker']) { if (ui.config["flyToMarker"]) {
ui.map.setCenter(pos); // panTo ui.map.setCenter(pos); // panTo
if (!ui.config['noZoom']) { if (!ui.config["noZoom"]) {
ui.map.setZoom(18); ui.map.setZoom(18);
} }
} }
// keep it hidden to render content // keep it hidden to render content
popup.style.opacity = '0'; popup.style.opacity = "0";
popup.classList.remove('d-none'); popup.classList.remove("d-none");
popup.querySelector('.mapboxgl-popup-content .html').innerHTML = content; popup.querySelector(".mapboxgl-popup-content .html").innerHTML = content;
popup.querySelector('.mapboxgl-popup-close-button').addEventListener('click', (e) => { popup
e.preventDefault(); .querySelector(".mapboxgl-popup-close-button")
ui.hidePopup(); .addEventListener("click", (e) => {
}); e.preventDefault();
ui.hidePopup();
});
// set position when content was rendered // set position when content was rendered
ui.popup.setPosition(pos, ['center', 'top']); ui.popup.setPosition(pos, ["center", "top"]);
// display popup // display popup
popup.style.opacity = '1'; popup.style.opacity = "1";
popup.style['margin-top'] = '-1rem'; popup.style["margin-top"] = "-1rem";
} }
hidePopup() { hidePopup() {
const ui = this; const ui = this;
const popup = ui.popup.getDiv(); const popup = ui.popup.getDiv();
popup.classList.add('d-none'); popup.classList.add("d-none");
if (!ui.config['noRestoreBounds'] || ui.config['flyToBounds']) { if (!ui.config["noRestoreBounds"] || ui.config["flyToBounds"]) {
ui.restoreBounds(); ui.restoreBounds();
} }
@ -164,20 +175,20 @@ const GoogleMapsDriver = ((window) => {
address: addr, address: addr,
}, },
(results, status) => { (results, status) => {
if (status === 'OK') { if (status === "OK") {
//results[0].geometry.location; //results[0].geometry.location;
if (typeof callback === 'function') { if (typeof callback === "function") {
callback(results); callback(results);
} }
return results; return results;
} else { } else {
console.error( console.error(
`${ui.getName()}: Geocode was not successful for the following reason: ${status}`, `${ui.getName()}: Geocode was not successful for the following reason: ${status}`
); );
} }
}, }
); );
} }
@ -189,26 +200,26 @@ const GoogleMapsDriver = ((window) => {
location: latlng, location: latlng,
}, },
(results, status) => { (results, status) => {
if (status === 'OK') { if (status === "OK") {
//results[0].formatted_address; //results[0].formatted_address;
if (typeof callback === 'function') { if (typeof callback === "function") {
callback(results); callback(results);
} }
return results; return results;
} else { } else {
console.error( console.error(
`${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`, `${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`
); );
} }
}, }
); );
} }
addGeoJson(config) { addGeoJson(config) {
const ui = this; const ui = this;
const geojson = JSON.parse(config['geojson']); const geojson = JSON.parse(config["geojson"]);
const firstMarker = geojson.features[0].geometry.coordinates; const firstMarker = geojson.features[0].geometry.coordinates;
//Map.setCenter(firstMarker); //Map.setCenter(firstMarker);
const bounds = new google.maps.LatLngBounds(); const bounds = new google.maps.LatLngBounds();
@ -223,7 +234,7 @@ const GoogleMapsDriver = ((window) => {
id, id,
content, content,
icon: marker.icon, icon: marker.icon,
flyToMarker: config['flyToMarker'], flyToMarker: config["flyToMarker"],
}); });
bounds.extend({ bounds.extend({

View File

@ -1,4 +1,4 @@
'use strict'; "use strict";
const Obj = { const Obj = {
init: () => { init: () => {
@ -10,9 +10,9 @@ const Obj = {
ui.ownerMap = options.map; ui.ownerMap = options.map;
//ui.setMap(options.map); //ui.setMap(options.map);
ui.position = options.position; ui.position = options.position;
ui.html = options.html ? ui.html = options.html
options.html : ? options.html
'<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>'; : '<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>';
ui.divClass = options.divClass; ui.divClass = options.divClass;
ui.align = options.align; ui.align = options.align;
ui.isDebugMode = options.debug; ui.isDebugMode = options.debug;
@ -20,7 +20,7 @@ const Obj = {
ui.onMouseOver = options.onMouseOver; ui.onMouseOver = options.onMouseOver;
ui.isBoolean = (arg) => { ui.isBoolean = (arg) => {
if (typeof arg === 'boolean') { if (typeof arg === "boolean") {
return true; return true;
} else { } else {
return false; return false;
@ -28,7 +28,7 @@ const Obj = {
}; };
ui.isNotUndefined = (arg) => { ui.isNotUndefined = (arg) => {
if (typeof arg !== 'undefined') { if (typeof arg !== "undefined") {
return true; return true;
} else { } else {
return false; return false;
@ -44,7 +44,7 @@ const Obj = {
}; };
ui.isString = (arg) => { ui.isString = (arg) => {
if (typeof arg === 'string') { if (typeof arg === "string") {
return true; return true;
} else { } else {
return false; return false;
@ -52,7 +52,7 @@ const Obj = {
}; };
ui.isFunction = (arg) => { ui.isFunction = (arg) => {
if (typeof arg === 'function') { if (typeof arg === "function") {
return true; return true;
} else { } else {
return false; return false;
@ -63,8 +63,8 @@ const Obj = {
const ui = this; const ui = this;
// Create div element. // Create div element.
ui.div = document.createElement('div'); ui.div = document.createElement("div");
ui.div.style.position = 'absolute'; ui.div.style.position = "absolute";
// Validate and set custom div class // Validate and set custom div class
if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass)) if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass))
@ -73,26 +73,26 @@ const Obj = {
// Validate and set custom HTML // Validate and set custom HTML
if ( if (
ui.isNotUndefined(ui.html) && ui.isNotUndefined(ui.html) &&
ui.hasContent(ui.html) && ui.hasContent(ui.html) &&
ui.isString(ui.html) ui.isString(ui.html)
) )
ui.div.innerHTML = ui.html; ui.div.innerHTML = ui.html;
// If debug mode is enabled custom content will be replaced with debug content // If debug mode is enabled custom content will be replaced with debug content
if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) { if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) {
ui.div.className = 'debug-mode'; ui.div.className = "debug-mode";
ui.div.innerHTML = ui.div.innerHTML =
'<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' + '<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' +
'<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>'; '<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>';
ui.div.setAttribute( ui.div.setAttribute(
'style', "style",
'position: absolute;' + "position: absolute;" +
'border: 5px dashed red;' + "border: 5px dashed red;" +
'height: 150px;' + "height: 150px;" +
'width: 150px;' + "width: 150px;" +
'display: flex;' + "display: flex;" +
'justify-content: center;' + "justify-content: center;" +
'align-items: center;', "align-items: center;"
); );
} }
@ -100,14 +100,14 @@ const Obj = {
ui.getPanes().overlayMouseTarget.appendChild(ui.div); ui.getPanes().overlayMouseTarget.appendChild(ui.div);
// Add listeners to the element. // Add listeners to the element.
google.maps.event.addDomListener(ui.div, 'click', (event) => { google.maps.event.addDomListener(ui.div, "click", (event) => {
google.maps.event.trigger(ui, 'click'); google.maps.event.trigger(ui, "click");
if (ui.isFunction(ui.onClick)) ui.onClick(); if (ui.isFunction(ui.onClick)) ui.onClick();
event.stopPropagation(); event.stopPropagation();
}); });
google.maps.event.addDomListener(ui.div, 'mouseover', (event) => { google.maps.event.addDomListener(ui.div, "mouseover", (event) => {
google.maps.event.trigger(ui, 'mouseover'); google.maps.event.trigger(ui, "mouseover");
if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver(); if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver();
event.stopPropagation(); event.stopPropagation();
}); });
@ -116,7 +116,7 @@ const Obj = {
draw() { draw() {
const ui = this; const ui = this;
let div = document.querySelector('.popup'); let div = document.querySelector(".popup");
if (!div.length) { if (!div.length) {
div = ui.div; div = ui.div;
} }
@ -125,11 +125,13 @@ const Obj = {
const projection = ui.getProjection(); const projection = ui.getProjection();
if (!projection) { if (!projection) {
console.log('GoogleMapsHtmlOverlay: current map is missing'); console.log("GoogleMapsHtmlOverlay: current map is missing");
return null; return null;
} }
const positionInPixels = projection.fromLatLngToDivPixel(ui.getPosition()); const positionInPixels = projection.fromLatLngToDivPixel(
ui.getPosition()
);
// Align HTML overlay relative to original position // Align HTML overlay relative to original position
const offset = { const offset = {
@ -139,40 +141,40 @@ const Obj = {
const divWidth = div.offsetWidth; const divWidth = div.offsetWidth;
const divHeight = div.offsetHeight; const divHeight = div.offsetHeight;
switch (Array.isArray(ui.align) ? ui.align.join(' ') : '') { switch (Array.isArray(ui.align) ? ui.align.join(" ") : "") {
case 'left top': case "left top":
offset.y = divHeight; offset.y = divHeight;
offset.x = divWidth; offset.x = divWidth;
break; break;
case 'left center': case "left center":
offset.y = divHeight / 2; offset.y = divHeight / 2;
offset.x = divWidth; offset.x = divWidth;
break; break;
case 'left bottom': case "left bottom":
offset.y = 0; offset.y = 0;
offset.x = divWidth; offset.x = divWidth;
break; break;
case 'center top': case "center top":
offset.y = divHeight; offset.y = divHeight;
offset.x = divWidth / 2; offset.x = divWidth / 2;
break; break;
case 'center center': case "center center":
offset.y = divHeight / 2; offset.y = divHeight / 2;
offset.x = divWidth / 2; offset.x = divWidth / 2;
break; break;
case 'center bottom': case "center bottom":
offset.y = 0; offset.y = 0;
offset.x = divWidth / 2; offset.x = divWidth / 2;
break; break;
case 'right top': case "right top":
offset.y = divHeight; offset.y = divHeight;
offset.x = 0; offset.x = 0;
break; break;
case 'right center': case "right center":
offset.y = divHeight / 2; offset.y = divHeight / 2;
offset.x = 0; offset.x = 0;
break; break;
case 'right bottom': case "right bottom":
offset.y = 0; offset.y = 0;
offset.x = 0; offset.x = 0;
break; break;

View File

@ -1,40 +1,40 @@
'use strict'; "use strict";
//import $ from 'jquery'; //import $ from 'jquery';
import mapBoxGL from 'mapbox-gl'; import mapBoxGL from "mapbox-gl";
import Events from '../../_events'; import Events from "../../_events";
const MapBoxDriver = (($) => { const MapBoxDriver = (($) => {
class MapBoxDriver { class MapBoxDriver {
getName() { getName() {
return 'MapBoxDriver'; return "MapBoxDriver";
} }
init($el, config = []) { init($el, config = []) {
const ui = this; const ui = this;
mapBoxGL.accessToken = config['key']; mapBoxGL.accessToken = config["key"];
ui.map = new mapBoxGL.Map({ ui.map = new mapBoxGL.Map({
container: $el.find('.mapAPI-map')[0], container: $el.find(".mapAPI-map")[0],
center: config['center'] ? config['center'] : [0, 0], center: config["center"] ? config["center"] : [0, 0],
//hash: true, //hash: true,
style: config['style'] ? style: config["style"]
config['style'] : ? config["style"]
'mapbox://styles/mapbox/streets-v9', : "mapbox://styles/mapbox/streets-v9",
localIdeographFontFamily: config['font-family'], localIdeographFontFamily: config["font-family"],
zoom: config['mapZoom'] ? config['mapZoom'] : 10, zoom: config["mapZoom"] ? config["mapZoom"] : 10,
attributionControl: false, attributionControl: false,
antialias: true, antialias: true,
accessToken: config['key'], accessToken: config["key"],
}) })
.addControl( .addControl(
new mapBoxGL.AttributionControl({ new mapBoxGL.AttributionControl({
compact: true, compact: true,
}), })
) )
.addControl(new mapBoxGL.NavigationControl(), 'top-right') .addControl(new mapBoxGL.NavigationControl(), "top-right")
.addControl( .addControl(
new mapBoxGL.GeolocateControl({ new mapBoxGL.GeolocateControl({
positionOptions: { positionOptions: {
@ -42,24 +42,24 @@ const MapBoxDriver = (($) => {
}, },
trackUserLocation: true, trackUserLocation: true,
}), }),
'bottom-right', "bottom-right"
) )
.addControl( .addControl(
new mapBoxGL.ScaleControl({ new mapBoxGL.ScaleControl({
maxWidth: 80, maxWidth: 80,
unit: 'metric', unit: "metric",
}), }),
'top-left', "top-left"
) )
.addControl(new mapBoxGL.FullscreenControl()); .addControl(new mapBoxGL.FullscreenControl());
ui.map.on('load', (e) => { ui.map.on("load", (e) => {
$el.trigger(Events.MAPAPILOADED); $el.trigger(Events.MAPAPILOADED);
}); });
ui.popup = new mapBoxGL.Popup({ ui.popup = new mapBoxGL.Popup({
closeOnClick: false, closeOnClick: false,
className: 'popup', className: "popup",
}); });
} }
@ -68,16 +68,13 @@ const MapBoxDriver = (($) => {
// create a DOM el for the marker // create a DOM el for the marker
const $el = $( const $el = $(
`<div id="Marker${config['id']}" data-id="${config['id']}" class="marker">${config['icon']}</div>`, `<div id="Marker${config["id"]}" data-id="${config["id"]}" class="marker">${config["icon"]}</div>`
); );
$el.on('click', (e) => { $el.on("click", (e) => {
ui.popup ui.popup.setLngLat(crds).setHTML(config["content"]).addTo(ui.map);
.setLngLat(crds)
.setHTML(config['content'])
.addTo(ui.map);
if (config['flyToMarker']) { if (config["flyToMarker"]) {
ui.map.flyTo({ ui.map.flyTo({
center: crds, center: crds,
zoom: 17, zoom: 17,
@ -135,12 +132,12 @@ const MapBoxDriver = (($) => {
}, labelLayerId); }, labelLayerId);
}*/ }*/
const firstMarker = config['geojson'].features[0].geometry.coordinates; const firstMarker = config["geojson"].features[0].geometry.coordinates;
//Map.setCenter(firstMarker); //Map.setCenter(firstMarker);
const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker); const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker);
// add markers to map // add markers to map
config['geojson'].features.forEach((marker) => { config["geojson"].features.forEach((marker) => {
const id = marker.id; const id = marker.id;
const crds = marker.geometry.coordinates; const crds = marker.geometry.coordinates;
const content = marker.properties.content; const content = marker.properties.content;
@ -149,7 +146,7 @@ const MapBoxDriver = (($) => {
id, id,
content, content,
icon: marker.icon, icon: marker.icon,
flyToMarker: config['flyToMarker'], flyToMarker: config["flyToMarker"],
}); });
bounds.extend(crds); bounds.extend(crds);
@ -159,8 +156,8 @@ const MapBoxDriver = (($) => {
padding: 30, padding: 30,
}); });
ui.popup.on('close', (e) => { ui.popup.on("close", (e) => {
if (config['flyToBounds']) { if (config["flyToBounds"]) {
ui.map.fitBounds(bounds, { ui.map.fitBounds(bounds, {
padding: 30, padding: 30,
}); });

View File

@ -1,19 +1,20 @@
import Events from '../_events'; import Events from "../_events";
const LayoutUI = ((W) => { const LayoutUI = ((W) => {
const NAME = '_layout'; const NAME = "_layout";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
const init_fonts = () => { const init_fonts = () => {
console.log(`${NAME}: init_fonts`); console.log(`${NAME}: init_fonts`);
const css = D.createElement('link'); const css = D.createElement("link");
css.rel = 'stylesheet'; css.rel = "stylesheet";
css.type = 'text/css'; css.type = "text/css";
css.media = 'all'; css.media = "all";
css.href = 'https://fonts.googleapis.com/css?family=Roboto:ital,wght@0,400;0,700;1,400&display=swap'; css.href =
D.getElementsByTagName('head')[0].appendChild(css); "https://fonts.googleapis.com/css?family=Roboto:ital,wght@0,400;0,700;1,400&display=swap";
D.getElementsByTagName("head")[0].appendChild(css);
}; };
const init_analytics = () => { const init_analytics = () => {
@ -40,7 +41,7 @@ const LayoutUI = ((W) => {
); );
ga('create', 'UA-********-*', 'auto'); ga('create', 'UA-********-*', 'auto');
ga('send', 'pageview');*/ ga('send', 'pageview');*/
} };
W.addEventListener(`${Events.LOADED}`, () => { W.addEventListener(`${Events.LOADED}`, () => {
init_fonts(); init_fonts();

View File

@ -1,4 +1,4 @@
var debug = process.env.NODE_ENV === 'development' ? true : false; var debug = process.env.NODE_ENV === "development" ? true : false;
const log = (msg) => { const log = (msg) => {
if (debug) { if (debug) {

View File

@ -1,16 +1,16 @@
// browser tab visibility state detection // browser tab visibility state detection
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
export default ((W) => { export default ((W) => {
const NAME = '_main.css-screen-size'; const NAME = "_main.css-screen-size";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
const detectCSSScreenSize = () => { const detectCSSScreenSize = () => {
const el = D.createElement('div'); const el = D.createElement("div");
el.className = 'env-test'; el.className = "env-test";
BODY.appendChild(el); BODY.appendChild(el);
const envs = [...Consts.ENVS].reverse(); const envs = [...Consts.ENVS].reverse();
@ -21,7 +21,7 @@ export default ((W) => {
const env = envs[i]; const env = envs[i];
el.classList.add(`d-${env}-none`); el.classList.add(`d-${env}-none`);
if (W.getComputedStyle(el).display === 'none') { if (W.getComputedStyle(el).display === "none") {
curEnv = env; curEnv = env;
BODY.classList.add(`${curEnv}`); BODY.classList.add(`${curEnv}`);
break; break;
@ -30,17 +30,17 @@ export default ((W) => {
let landscape = true; let landscape = true;
if (W.innerWidth > W.innerHeight) { if (W.innerWidth > W.innerHeight) {
BODY.classList.add('landscape'); BODY.classList.add("landscape");
BODY.classList.remove('portrait'); BODY.classList.remove("portrait");
} else { } else {
landscape = false; landscape = false;
BODY.classList.add('portrait'); BODY.classList.add("portrait");
BODY.classList.remove('landscape'); BODY.classList.remove("landscape");
} }
console.log( console.log(
`${NAME}: screen size detected ${curEnv} | landscape ${landscape}`, `${NAME}: screen size detected ${curEnv} | landscape ${landscape}`
); );
BODY.removeChild(el); BODY.removeChild(el);

View File

@ -1,7 +1,7 @@
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
import './visibility'; import "./visibility";
import './touch'; import "./touch";
import './css-screen-size'; import "./css-screen-size";
import './main'; import "./main";

View File

@ -1,20 +1,20 @@
// browser tab visibility state detection // browser tab visibility state detection
import Events from '../_events'; import Events from "../_events";
const NAME = '_main.loading-spinner'; const NAME = "_main.loading-spinner";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
const SPINNER = D.getElementById('PageLoading'); const SPINNER = D.getElementById("PageLoading");
class SpinnerUI { class SpinnerUI {
static show() { static show() {
console.log(`${NAME}: show`); console.log(`${NAME}: show`);
SPINNER.classList.remove('d-none'); SPINNER.classList.remove("d-none");
} }
static hide() { static hide() {
console.log(`${NAME}: hide`); console.log(`${NAME}: hide`);
SPINNER.classList.add('d-none'); SPINNER.classList.add("d-none");
} }
} }

View File

@ -1,40 +1,40 @@
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
import SpinnerUI from './loading-spinner'; import SpinnerUI from "./loading-spinner";
const MainUI = ((W) => { const MainUI = ((W) => {
const NAME = '_main'; const NAME = "_main";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
console.info( console.info(
`%cUI Kit ${UINAME} ${UIVERSION}`, `%cUI Kit ${UINAME} ${UIVERSION}`,
'color:yellow;font-size:14px', "color:yellow;font-size:14px"
); );
console.info( console.info(
`%c${UIMetaNAME} ${UIMetaVersion}`, `%c${UIMetaNAME} ${UIMetaVersion}`,
'color:yellow;font-size:12px', "color:yellow;font-size:12px"
); );
console.info( console.info(
`%chttps://github.com/a2nt/webpack-bootstrap-ui-kit by ${UIAUTHOR}`, `%chttps://github.com/a2nt/webpack-bootstrap-ui-kit by ${UIAUTHOR}`,
'color:yellow;font-size:10px', "color:yellow;font-size:10px"
); );
console.info(`%cENV: ${process.env.NODE_ENV}`, 'color:green;font-size:10px'); console.info(`%cENV: ${process.env.NODE_ENV}`, "color:green;font-size:10px");
console.groupCollapsed('Events'); console.groupCollapsed("Events");
Object.keys(Events).forEach((k) => { Object.keys(Events).forEach((k) => {
console.info(`${k}: ${Events[k]}`); console.info(`${k}: ${Events[k]}`);
}); });
console.groupEnd('Events'); console.groupEnd("Events");
console.groupCollapsed('Consts'); console.groupCollapsed("Consts");
Object.keys(Consts).forEach((k) => { Object.keys(Consts).forEach((k) => {
console.info(`${k}: ${Consts[k]}`); console.info(`${k}: ${Consts[k]}`);
}); });
console.groupEnd('Events'); console.groupEnd("Events");
console.groupCollapsed('Init'); console.groupCollapsed("Init");
console.time('init'); console.time("init");
class MainUI { class MainUI {
// first time the website initialization // first time the website initialization
@ -47,7 +47,7 @@ const MainUI = ((W) => {
landing: W.location.href, landing: W.location.href,
}, },
D.title, D.title,
W.location.href, W.location.href
); );
// //
@ -64,11 +64,11 @@ const MainUI = ((W) => {
W.addEventListener(`${Events.LOADED}`, () => { W.addEventListener(`${Events.LOADED}`, () => {
MainUI.init(); MainUI.init();
BODY.classList.add('loaded'); BODY.classList.add("loaded");
SpinnerUI.hide(); SpinnerUI.hide();
console.groupEnd('init'); console.groupEnd("init");
console.timeEnd('init'); console.timeEnd("init");
W.dispatchEvent(new Event(Events.LODEDANDREADY)); W.dispatchEvent(new Event(Events.LODEDANDREADY));
}); });

View File

@ -1,10 +1,10 @@
// touch/mouse detection // touch/mouse detection
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
export default ((W) => { export default ((W) => {
const NAME = '_main.touch'; const NAME = "_main.touch";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
@ -18,15 +18,15 @@ export default ((W) => {
if (bool) { if (bool) {
console.log(`${NAME}: Touch screen enabled`); console.log(`${NAME}: Touch screen enabled`);
BODY.classList.add('is-touch'); BODY.classList.add("is-touch");
BODY.classList.remove('is-mouse'); BODY.classList.remove("is-mouse");
W.dispatchEvent(new Event(Events.TOUCHENABLE)); W.dispatchEvent(new Event(Events.TOUCHENABLE));
} else { } else {
console.log(`${NAME}: Touch screen disabled`); console.log(`${NAME}: Touch screen disabled`);
BODY.classList.add('is-mouse'); BODY.classList.add("is-mouse");
BODY.classList.remove('is-touch'); BODY.classList.remove("is-touch");
W.dispatchEvent(new Event(Events.TOUCHDISABLED)); W.dispatchEvent(new Event(Events.TOUCHDISABLED));
} }
@ -42,29 +42,29 @@ export default ((W) => {
}; };
SET_TOUCH_SCREEN( SET_TOUCH_SCREEN(
'ontouchstart' in W || "ontouchstart" in W ||
navigator.MaxTouchPoints > 0 || navigator.MaxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ||
W.matchMedia('(hover: none)').matches, W.matchMedia("(hover: none)").matches,
'init', "init"
); );
D.addEventListener('touchend', (e) => { D.addEventListener("touchend", (e) => {
let touch = false; let touch = false;
if (e.type !== 'click') { if (e.type !== "click") {
touch = true; touch = true;
} }
SET_TOUCH_SCREEN(touch, 'click-touchend'); SET_TOUCH_SCREEN(touch, "click-touchend");
}); });
// disable touch on mouse events // disable touch on mouse events
D.addEventListener('click', (e) => { D.addEventListener("click", (e) => {
let touch = false; let touch = false;
if (e.type !== 'click') { if (e.type !== "click") {
touch = true; touch = true;
} }
SET_TOUCH_SCREEN(touch, 'click-touchend'); SET_TOUCH_SCREEN(touch, "click-touchend");
}); });
})(window); })(window);

View File

@ -1,32 +1,32 @@
// browser tab visibility state detection // browser tab visibility state detection
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
export default ((W) => { export default ((W) => {
const NAME = '_main.visibility'; const NAME = "_main.visibility";
const D = document; const D = document;
const BODY = D.body; const BODY = D.body;
// update visibility state // update visibility state
// get browser window visibility preferences // get browser window visibility preferences
// Opera 12.10, Firefox >=18, Chrome >=31, IE11 // Opera 12.10, Firefox >=18, Chrome >=31, IE11
const HiddenName = 'hidden'; const HiddenName = "hidden";
const VisibilityChangeEvent = 'visibilitychange'; const VisibilityChangeEvent = "visibilitychange";
D.addEventListener(VisibilityChangeEvent, () => { D.addEventListener(VisibilityChangeEvent, () => {
if (D.visibilityState === HiddenName) { if (D.visibilityState === HiddenName) {
console.log(`${NAME}: Tab: hidden`); console.log(`${NAME}: Tab: hidden`);
BODY.classList.add('is-hidden'); BODY.classList.add("is-hidden");
BODY.classList.remove('is-focused'); BODY.classList.remove("is-focused");
W.dispatchEvent(new Event(Events.TABHIDDEN)); W.dispatchEvent(new Event(Events.TABHIDDEN));
} else { } else {
console.log(`${NAME}: Tab: focused`); console.log(`${NAME}: Tab: focused`);
BODY.classList.add('is-focused'); BODY.classList.add("is-focused");
BODY.classList.remove('is-hidden'); BODY.classList.remove("is-hidden");
W.dispatchEvent(new Event(Events.TABFOCUSED)); W.dispatchEvent(new Event(Events.TABFOCUSED));
} }

View File

@ -1,5 +1,3 @@
import PageControls from './page-controls'; import PageControls from "./page-controls";
export { export { PageControls };
PageControls,
};

View File

@ -1,6 +1,6 @@
export default class PageControls { export default class PageControls {
constructor(store) { constructor(store) {
console.log('page-controls init'); console.log("page-controls init");
console.log(store); console.log(store);
} }
} }

View File

@ -1,8 +1,6 @@
import { import { createStore } from "redux";
createStore, import reducers from "./reducers";
} from 'redux'
import reducers from './reducers'
export default function configure() { export default function configure() {
return createStore(reducers) return createStore(reducers);
} }

View File

@ -1,3 +1,3 @@
export function getItemList(store) { export function getItemList(store) {
return store.getState().items.all return store.getState().items.all;
} }

View File

@ -1,4 +1,4 @@
import configure from './configure' import configure from "./configure";
const store = configure(); const store = configure();
/*import { /*import {
@ -9,11 +9,11 @@ const store = configure();
store.subscribe(() => console.log(store.getState())); store.subscribe(() => console.log(store.getState()));
store.dispatch({ store.dispatch({
type: 'counter/incremented', type: "counter/incremented",
}) });
store.dispatch({ store.dispatch({
type: 'counter/incremented', type: "counter/incremented",
}) });
store.dispatch({ store.dispatch({
type: 'counter/decremented', type: "counter/decremented",
}) });

View File

@ -1,16 +1,19 @@
export default function counter(state = { export default function counter(
value: 0, state = {
}, action) { value: 0,
},
action
) {
switch (action.type) { switch (action.type) {
case 'counter/incremented': case "counter/incremented":
return { return {
value: state.value + 1, value: state.value + 1,
} };
case 'counter/decremented': case "counter/decremented":
return { return {
value: state.value - 1, value: state.value - 1,
} };
default: default:
return state return state;
} }
} }

View File

@ -1,8 +1,6 @@
import { import { combineReducers } from "redux";
combineReducers,
} from 'redux'
import counter from './counter'; import counter from "./counter";
export default combineReducers({ export default combineReducers({
counter, counter,

View File

@ -1,21 +1,21 @@
'use strict'; "use strict";
import '../scss/test-build.scss'; import "../scss/test-build.scss";
import '@a2nt/meta-lightbox-js/src/js/test-build'; import "@a2nt/meta-lightbox-js/src/js/test-build";
import Events from './_events'; import Events from "./_events";
import MainUI from './main'; import MainUI from "./main";
/* /*
* AJAX functionality * AJAX functionality
*/ */
import './ajax/links'; import "./ajax/links";
import './ajax/online'; import "./ajax/online";
import './ajax/lazy-images'; import "./ajax/lazy-images";
import './layout'; import "./layout";
import './store'; import "./store";
/*if (process.env.NODEENV === 'development') { /*if (process.env.NODEENV === 'development') {
// mocking service worker // mocking service worker
@ -46,23 +46,22 @@ import './store';
} }
}}*/ }}*/
function importAll(r) { function importAll(r) {
return r.keys().map(r); return r.keys().map(r);
} }
const images = importAll( const images = importAll(
require.context('../img/', false, /\.(png|jpe?g|svg)$/), require.context("../img/", false, /\.(png|jpe?g|svg)$/)
); );
const fontAwesome = importAll( const fontAwesome = importAll(
require.context('font-awesome', false, /\.(otf|eot|svg|ttf|woff|woff2)$/), require.context("font-awesome", false, /\.(otf|eot|svg|ttf|woff|woff2)$/)
); );
if (module.hot) { if (module.hot) {
module.hot.accept('app.js', () => { module.hot.accept("app.js", () => {
console.log('Accepting the updated printMe module!'); console.log("Accepting the updated printMe module!");
}) });
module.hot.accept('app.scss', () => { module.hot.accept("app.scss", () => {
console.log('Accepting the updated printMe module!'); console.log("Accepting the updated printMe module!");
}) });
} }

View File

@ -1,25 +1,25 @@
// caches polyfill because it is not added to native yet! // caches polyfill because it is not added to native yet!
var CACHE_NAME = `${UINAME}-sw`; var CACHE_NAME = `${UINAME}-sw`;
var debug = process.env.NODE_ENV === 'development' ? true : false; var debug = process.env.NODE_ENV === "development" ? true : false;
var version = `${UIVERSION}-sw`; var version = `${UIVERSION}-sw`;
var log = require('../libs/log'); var log = require("../libs/log");
var caches = require('../../../thirdparty/serviceworker-caches'); var caches = require("../../../thirdparty/serviceworker-caches");
if (debug) { if (debug) {
log('SW: debug is on'); log("SW: debug is on");
log(`SW: CACHE_NAME: ${CACHE_NAME}`); log(`SW: CACHE_NAME: ${CACHE_NAME}`);
//log(`SW: appDomain: ${appDomain}`); //log(`SW: appDomain: ${appDomain}`);
//log(`SW: lang: ${lang}`); //log(`SW: lang: ${lang}`);
} }
if (typeof CACHE_NAME !== 'string') { if (typeof CACHE_NAME !== "string") {
throw new Error('Cache Name cannot be empty'); throw new Error("Cache Name cannot be empty");
} }
self.addEventListener('fetch', (event) => { self.addEventListener("fetch", (event) => {
// skip non-get // skip non-get
if (event.request.method !== 'GET') { if (event.request.method !== "GET") {
return; return;
} }
@ -34,9 +34,9 @@ self.addEventListener('fetch', (event) => {
//Skip admin url's //Skip admin url's
if ( if (
requestURL.pathname.indexOf('admin') >= 0 || requestURL.pathname.indexOf("admin") >= 0 ||
requestURL.pathname.indexOf('Security') >= 0 || requestURL.pathname.indexOf("Security") >= 0 ||
requestURL.pathname.indexOf('/dev') >= 0 requestURL.pathname.indexOf("/dev") >= 0
) { ) {
log(`SW: skip admin ${event.request.url}`); log(`SW: skip admin ${event.request.url}`);
return; return;
@ -58,7 +58,7 @@ self.addEventListener('fetch', (event) => {
event.respondWith( event.respondWith(
// Try fetch // Try fetch
fetch(fetchRequest) fetch(fetchRequest)
// when fetch is successful, we update the cache // when fetch is successful, we update the cache
.then((response) => { .then((response) => {
// A response is a stream and can be consumed only once. // A response is a stream and can be consumed only once.
// Because we want the browser to consume the response, // Because we want the browser to consume the response,
@ -78,25 +78,25 @@ self.addEventListener('fetch', (event) => {
return response; return response;
}) })
// when fetch times out or fails // when fetch times out or fails
.catch((err) => { .catch((err) => {
log('SW: fetch failed'); log("SW: fetch failed");
// Return the promise which // Return the promise which
// resolves on a match in cache for the current request // resolves on a match in cache for the current request
// or rejects if no matches are found // or rejects if no matches are found
return caches.match(cacheRequest); return caches.match(cacheRequest);
}), })
); );
}); });
// Now we need to clean up resources in the previous versions // Now we need to clean up resources in the previous versions
// of Service Worker scripts // of Service Worker scripts
self.addEventListener('activate', (event) => { self.addEventListener("activate", (event) => {
log(`SW: activated: ${version}`); log(`SW: activated: ${version}`);
// Destroy the cache // Destroy the cache
event.waitUntil(caches.delete(CACHE_NAME)); event.waitUntil(caches.delete(CACHE_NAME));
}); });
self.addEventListener('install', (e) => { self.addEventListener("install", (e) => {
log(`SW: installing version: ${version}`); log(`SW: installing version: ${version}`);
}); });

View File

@ -1,8 +1,8 @@
import Events from '../_events'; import Events from "../_events";
import Carousel from 'bootstrap/js/src/carousel'; import Carousel from "bootstrap/js/src/carousel";
const CarouselUI = ((window) => { const CarouselUI = ((window) => {
const NAME = 'js-carousel'; const NAME = "js-carousel";
const init = () => { const init = () => {
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
@ -11,53 +11,55 @@ const CarouselUI = ((window) => {
const carousel = new Carousel(el); const carousel = new Carousel(el);
// create next/prev arrows // create next/prev arrows
if (el.dataset.bsArrows) { if (el.dataset.bsArrows) {
const next = document.createElement('button'); const next = document.createElement("button");
next.classList.add('carousel-control-next'); next.classList.add("carousel-control-next");
next.setAttribute('type', 'button'); next.setAttribute("type", "button");
next.setAttribute('aria-label', 'Next Slide'); next.setAttribute("aria-label", "Next Slide");
next.setAttribute('data-bs-target', el.getAttribute('id')); next.setAttribute("data-bs-target", el.getAttribute("id"));
next.setAttribute('data-bs-slide', 'next'); next.setAttribute("data-bs-slide", "next");
next.addEventListener('click', (e) => { next.addEventListener("click", (e) => {
carousel.next(); carousel.next();
}); });
next.innerHTML = '<span class="carousel-control-next-icon" aria-hidden="true"></span><span class="visually-hidden">Next</span>'; next.innerHTML =
'<span class="carousel-control-next-icon" aria-hidden="true"></span><span class="visually-hidden">Next</span>';
el.appendChild(next); el.appendChild(next);
const prev = document.createElement('button'); const prev = document.createElement("button");
prev.setAttribute('type', 'button'); prev.setAttribute("type", "button");
prev.setAttribute('aria-label', 'Previous Slide'); prev.setAttribute("aria-label", "Previous Slide");
prev.classList.add('carousel-control-prev'); prev.classList.add("carousel-control-prev");
prev.setAttribute('data-bs-target', el.getAttribute('id')); prev.setAttribute("data-bs-target", el.getAttribute("id"));
prev.setAttribute('data-bs-slide', 'prev'); prev.setAttribute("data-bs-slide", "prev");
prev.addEventListener('click', (e) => { prev.addEventListener("click", (e) => {
carousel.prev(); carousel.prev();
}); });
prev.innerHTML = '<span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="visually-hidden">Previous</span>'; prev.innerHTML =
'<span class="carousel-control-prev-icon" aria-hidden="true"></span><span class="visually-hidden">Previous</span>';
el.appendChild(prev); el.appendChild(prev);
} }
if (el.dataset.bsIndicators) { if (el.dataset.bsIndicators) {
const indicators = document.createElement('div'); const indicators = document.createElement("div");
indicators.classList.add('carousel-indicators'); indicators.classList.add("carousel-indicators");
const items = el.querySelectorAll('.carousel-item'); const items = el.querySelectorAll(".carousel-item");
let i = 0; let i = 0;
while (i < items.length) { while (i < items.length) {
const ind = document.createElement('button'); const ind = document.createElement("button");
ind.setAttribute('type', 'button'); ind.setAttribute("type", "button");
ind.setAttribute('aria-label', `Slide to #${ i + 1}`); ind.setAttribute("aria-label", `Slide to #${i + 1}`);
if (i == 0) { if (i == 0) {
ind.classList.add('active'); ind.classList.add("active");
} }
ind.setAttribute('data-bs-target', el.getAttribute('id')); ind.setAttribute("data-bs-target", el.getAttribute("id"));
ind.setAttribute('data-bs-slide-to', i); ind.setAttribute("data-bs-slide-to", i);
ind.addEventListener('click', (e) => { ind.addEventListener("click", (e) => {
const target = e.target; const target = e.target;
carousel.to(target.getAttribute('data-bs-slide-to')); carousel.to(target.getAttribute("data-bs-slide-to"));
indicators.querySelectorAll('.active').forEach((ind2) => { indicators.querySelectorAll(".active").forEach((ind2) => {
ind2.classList.remove('active'); ind2.classList.remove("active");
}); });
target.classList.add('active'); target.classList.add("active");
}); });
indicators.appendChild(ind); indicators.appendChild(ind);
@ -65,15 +67,18 @@ const CarouselUI = ((window) => {
} }
el.appendChild(indicators); el.appendChild(indicators);
el.addEventListener('slide.bs.carousel', (e) => { el.addEventListener("slide.bs.carousel", (e) => {
el.querySelectorAll('.carousel-indicators .active').forEach((ind2) => { el.querySelectorAll(".carousel-indicators .active").forEach(
ind2.classList.remove('active'); (ind2) => {
}); ind2.classList.remove("active");
el.querySelectorAll(`.carousel-indicators [data-bs-slide-to="${ e.to }"]`).forEach((ind2) => { }
ind2.classList.add('active'); );
el.querySelectorAll(
`.carousel-indicators [data-bs-slide-to="${e.to}"]`
).forEach((ind2) => {
ind2.classList.add("active");
}); });
}); });
} }
el.classList.add(`${NAME}-active`); el.classList.add(`${NAME}-active`);
}); });

View File

@ -3,31 +3,31 @@
// Visitor network maybe temporary banned by Instagram because of too many requests from external websites // Visitor network maybe temporary banned by Instagram because of too many requests from external websites
// so it isn't very stable implementation. You should have something for the fall-back. // so it isn't very stable implementation. You should have something for the fall-back.
import Events from '../_events'; import Events from "../_events";
import Consts from '../_consts'; import Consts from "../_consts";
import InstagramFeed from '@jsanahuja/instagramfeed/src/InstagramFeed'; import InstagramFeed from "@jsanahuja/instagramfeed/src/InstagramFeed";
export default ((window) => { export default ((window) => {
const NAME = 'js-instagramfeed'; const NAME = "js-instagramfeed";
const BODY = document.body; const BODY = document.body;
const ig_media_preview = (base64data) => { const ig_media_preview = (base64data) => {
const jpegtpl = const jpegtpl =
'/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABsaGikdKUEmJkFCLy8vQkc/Pj4/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0cBHSkpNCY0PygoP0c/NT9HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//AABEIABQAKgMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AA==', "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABsaGikdKUEmJkFCLy8vQkc/Pj4/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0cBHSkpNCY0PygoP0c/NT9HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//AABEIABQAKgMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AA==",
t = atob(base64data), t = atob(base64data),
p = t.slice(3).split(''), p = t.slice(3).split(""),
o = t o = t
.substring(0, 3) .substring(0, 3)
.split('') .split("")
.map((e) => { .map((e) => {
return e.charCodeAt(0); return e.charCodeAt(0);
}), }),
c = atob(jpegtpl).split(''); c = atob(jpegtpl).split("");
c[162] = String.fromCharCode(o[1]); c[162] = String.fromCharCode(o[1]);
c[160] = String.fromCharCode(o[2]); c[160] = String.fromCharCode(o[2]);
return base64data ? return base64data
`data:image/jpeg;base64,${btoa(c.concat(p).join(''))}` : ? `data:image/jpeg;base64,${btoa(c.concat(p).join(""))}`
null; : null;
}; };
const loadFeed = () => { const loadFeed = () => {
@ -41,41 +41,39 @@ export default ((window) => {
el.classList.remove(`${NAME}-loaded`, `${NAME}-error`); el.classList.remove(`${NAME}-loaded`, `${NAME}-error`);
new InstagramFeed({ new InstagramFeed({
username: dataset['username'], username: dataset["username"],
tag: dataset['tag'] || null, tag: dataset["tag"] || null,
display_profile: dataset['display-profile'], display_profile: dataset["display-profile"],
display_biography: dataset['display-biography'], display_biography: dataset["display-biography"],
display_gallery: dataset['display-gallery'], display_gallery: dataset["display-gallery"],
display_captions: dataset['display-captions'], display_captions: dataset["display-captions"],
cache_time: dataset['cache_time'] || 360, cache_time: dataset["cache_time"] || 360,
items: dataset['items'] || 12, items: dataset["items"] || 12,
styling: false, styling: false,
lazy_load: true, lazy_load: true,
callback: (data) => { callback: (data) => {
console.log(`${NAME}: data response received`); console.log(`${NAME}: data response received`);
const list = document.createElement('div'); const list = document.createElement("div");
list.classList.add(`${NAME}-list`, 'row'); list.classList.add(`${NAME}-list`, "row");
el.appendChild(list); el.appendChild(list);
data['edge_owner_to_timeline_media']['edges'].forEach( data["edge_owner_to_timeline_media"]["edges"].forEach((el, i) => {
(el, i) => { const item = el["node"];
const item = el['node']; const preview = ig_media_preview(item["media_preview"]);
const preview = ig_media_preview(item['media_preview']);
list.innerHTML += list.innerHTML +=
`<div class="a col ${NAME}-item"` + `<div class="a col ${NAME}-item"` +
` data-gallery="${NAME}-${ID}" data-href="${item['display_url']}" data-toggle="lightbox" data-force="image">` + ` data-gallery="${NAME}-${ID}" data-href="${item["display_url"]}" data-toggle="lightbox" data-force="image">` +
`<img id="${NAME}-${ID}-${item['id']}" src="${item['display_url']}" alt="${item['accessibility_caption']}"` + `<img id="${NAME}-${ID}-${item["id"]}" src="${item["display_url"]}" alt="${item["accessibility_caption"]}"` +
`style="background:url(${preview})" />` + `style="background:url(${preview})" />` +
'</div>'; "</div>";
}, });
);
el.classList.remove(`${NAME}-loading`); el.classList.remove(`${NAME}-loading`);
el.classList.add(`${NAME}-loaded`); el.classList.add(`${NAME}-loaded`);
window.dispatchEvent(new Event('MetaWindowindow.initLinks')); window.dispatchEvent(new Event("MetaWindowindow.initLinks"));
window.dispatchEvent(new Event(`${NAME}.loaded`)); window.dispatchEvent(new Event(`${NAME}.loaded`));
}, },
on_error: (e) => { on_error: (e) => {

View File

@ -1,23 +1,23 @@
'use strict'; "use strict";
import Events from '../_events'; import Events from "../_events";
import Consts from 'js/_consts'; import Consts from "js/_consts";
const MapAPI = ((window) => { const MapAPI = ((window) => {
// Constants // Constants
const NAME = 'js-mapapi'; const NAME = "js-mapapi";
const MAP_DRIVER = Consts['MAP_DRIVER']; const MAP_DRIVER = Consts["MAP_DRIVER"];
class MapAPI { class MapAPI {
// Constructor // Constructor
constructor(el) { constructor(el) {
const ui = this; const ui = this;
const Drv = new MAP_DRIVER(); const Drv = new MAP_DRIVER();
const BODY = document.querySelector('body'); const BODY = document.querySelector("body");
const config = el.dataset; const config = el.dataset;
config['center'] = [ config["center"] = [
config['lng'] ? config['lng'] : BODY.dataset['default-lng'], config["lng"] ? config["lng"] : BODY.dataset["default-lng"],
config['lat'] ? config['lat'] : BODY.dataset['default-lat'], config["lat"] ? config["lat"] : BODY.dataset["default-lat"],
]; ];
/*config['style'] = config['style'] ? /*config['style'] = config['style'] ?
@ -26,8 +26,8 @@ const MapAPI = ((window) => {
config['font-family'] = $BODY.css('font-family');*/ config['font-family'] = $BODY.css('font-family');*/
if (!config['icon']) { if (!config["icon"]) {
config['icon'] = '<i class="fas fa-map-marker-alt"></i>'; config["icon"] = '<i class="fas fa-map-marker-alt"></i>';
} }
console.log(`${NAME}: init ${Drv.getName()}...`); console.log(`${NAME}: init ${Drv.getName()}...`);
@ -38,7 +38,7 @@ const MapAPI = ((window) => {
Drv.init(el, config); Drv.init(el, config);
el.addEventListener(Events.MAPAPILOADED, () => { el.addEventListener(Events.MAPAPILOADED, () => {
ui.addMarkers() ui.addMarkers();
}); });
} }
@ -63,20 +63,20 @@ const MapAPI = ((window) => {
ui.map = Drv.getMap(); ui.map = Drv.getMap();
if (config['geojson']) { if (config["geojson"]) {
console.log(`${NAME}: setting up geocode data`); console.log(`${NAME}: setting up geocode data`);
Drv.addGeoJson(config); Drv.addGeoJson(config);
} else if (config['address']) { } else if (config["address"]) {
console.log(config['address']); console.log(config["address"]);
console.log(`${NAME}: setting up address marker`); console.log(`${NAME}: setting up address marker`);
Drv.geocode(config['address'], (results) => { Drv.geocode(config["address"], (results) => {
console.log(results); console.log(results);
const lat = results[0].geometry.location.lat(); const lat = results[0].geometry.location.lat();
const lng = results[0].geometry.location.lng(); const lng = results[0].geometry.location.lng();
console.log( console.log(
`${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`, `${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`
); );
Drv.addMarker([lng, lat], config); Drv.addMarker([lng, lat], config);
@ -85,12 +85,12 @@ const MapAPI = ((window) => {
lng, lng,
}); });
}); });
} else if (config['lat'] && config['lng']) { } else if (config["lat"] && config["lng"]) {
const lat = config['lat']; const lat = config["lat"];
const lng = config['lng']; const lng = config["lng"];
console.log( console.log(
`${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`, `${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`
); );
Drv.addMarker([lng, lat], config); Drv.addMarker([lng, lat], config);
@ -108,7 +108,7 @@ const MapAPI = ((window) => {
document.querySelectorAll(`.${NAME}`).forEach((el, i) => { document.querySelectorAll(`.${NAME}`).forEach((el, i) => {
const map = new MapAPI(el); const map = new MapAPI(el);
}); });
} };
// auto-apply // auto-apply
window.addEventListener(`${Events.LODEDANDREADY}`, init); window.addEventListener(`${Events.LODEDANDREADY}`, init);

View File

@ -1,17 +1,17 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import Spinner from './_ui.spinner'; import Spinner from "./_ui.spinner";
const AjaxUI = (($) => { const AjaxUI = (($) => {
// Constants // Constants
const G = window; const G = window;
const D = document; const D = document;
const $Html = $('html'); const $Html = $("html");
const $Body = $('body'); const $Body = $("body");
const NAME = 'jsAjaxUI'; const NAME = "jsAjaxUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
class AjaxUI { class AjaxUI {
@ -21,23 +21,23 @@ const AjaxUI = (($) => {
const $element = $(this._element); const $element = $(this._element);
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
$element.bind('click', function (e) { $element.bind("click", function (e) {
e.preventDefault(); e.preventDefault();
const $this = $(this); const $this = $(this);
$('.ajax').each(function () { $(".ajax").each(function () {
const $this = $(this); const $this = $(this);
$this.removeClass('active'); $this.removeClass("active");
$this.parents('.nav-item').removeClass('active'); $this.parents(".nav-item").removeClass("active");
}); });
$this.addClass('loading'); $this.addClass("loading");
AjaxUI.load($this.attr('href'), () => { AjaxUI.load($this.attr("href"), () => {
$this.removeClass('loading'); $this.removeClass("loading");
$this.parents('.nav-item').addClass('active'); $this.parents(".nav-item").addClass("active");
$this.addClass('active'); $this.addClass("active");
}); });
}); });
} }
@ -46,14 +46,14 @@ const AjaxUI = (($) => {
static load(url, callback) { static load(url, callback) {
// show spinner // show spinner
Spinner.show(() => { Spinner.show(() => {
$Body.removeClass('loaded'); $Body.removeClass("loaded");
}); });
// update document location // update document location
G.MainUI.updateLocation(url); G.MainUI.updateLocation(url);
const absoluteLocation = const absoluteLocation =
G.URLDetails['base'] + G.URLDetails['relative'].substring(1); G.URLDetails["base"] + G.URLDetails["relative"].substring(1);
if (absoluteLocation !== G.location.href) { if (absoluteLocation !== G.location.href) {
G.history.pushState( G.history.pushState(
{ {
@ -61,7 +61,7 @@ const AjaxUI = (($) => {
page: absoluteLocation, page: absoluteLocation,
}, },
document.title, document.title,
absoluteLocation, absoluteLocation
); );
} }
@ -69,41 +69,41 @@ const AjaxUI = (($) => {
sync: false, sync: false,
async: true, async: true,
url, url,
dataType: 'json', dataType: "json",
method: 'GET', method: "GET",
cache: false, cache: false,
error(jqXHR) { error(jqXHR) {
console.warn(`${NAME}: AJAX request failure: ${jqXHR.statusText}`); console.warn(`${NAME}: AJAX request failure: ${jqXHR.statusText}`);
G.location.href = url; G.location.href = url;
// google analytics // google analytics
if (typeof G.ga === 'function') { if (typeof G.ga === "function") {
G.ga('send', 'event', 'error', 'AJAX ERROR', jqXHR.statusText); G.ga("send", "event", "error", "AJAX ERROR", jqXHR.statusText);
} }
}, },
success(data, status, jqXHR) { success(data, status, jqXHR) {
AjaxUI.process(data, jqXHR, callback); AjaxUI.process(data, jqXHR, callback);
// google analytics // google analytics
if (typeof G.ga === 'function') { if (typeof G.ga === "function") {
G.ga('set', { G.ga("set", {
page: G.URLDetails['relative'] + G.URLDetails['hash'], page: G.URLDetails["relative"] + G.URLDetails["hash"],
title: jqXHR.getResponseHeader('X-Title'), title: jqXHR.getResponseHeader("X-Title"),
}); });
G.ga('send', 'pageview'); G.ga("send", "pageview");
} }
}, },
}); });
} }
static process(data, jqXHR, callback) { static process(data, jqXHR, callback) {
const css = jqXHR.getResponseHeader('X-Include-CSS').split(',') || []; const css = jqXHR.getResponseHeader("X-Include-CSS").split(",") || [];
const js = jqXHR.getResponseHeader('X-Include-JS').split(',') || []; const js = jqXHR.getResponseHeader("X-Include-JS").split(",") || [];
// Replace HTML regions // Replace HTML regions
if (typeof data.regions === 'object') { if (typeof data.regions === "object") {
for (const key in data.regions) { for (const key in data.regions) {
if (typeof data.regions[key] === 'string') { if (typeof data.regions[key] === "string") {
AjaxUI.replaceRegion(data.regions[key], key); AjaxUI.replaceRegion(data.regions[key], key);
} }
} }
@ -111,52 +111,52 @@ const AjaxUI = (($) => {
// remove already loaded scripts // remove already loaded scripts
$('link[type="text/css"]').each(function () { $('link[type="text/css"]').each(function () {
const i = css.indexOf($(this).attr('href')); const i = css.indexOf($(this).attr("href"));
if (i > -1) { if (i > -1) {
css.splice(i, 1); css.splice(i, 1);
} else if (!$Body.data('unload-blocked')) { } else if (!$Body.data("unload-blocked")) {
console.log(`${NAME}: Unloading | ${$(this).attr('href')}`); console.log(`${NAME}: Unloading | ${$(this).attr("href")}`);
$(this).remove(); $(this).remove();
} }
}); });
$('script[type="text/javascript"]').each(function () { $('script[type="text/javascript"]').each(function () {
const i = js.indexOf($(this).attr('src')); const i = js.indexOf($(this).attr("src"));
if (i > -1) { if (i > -1) {
js.splice(i, 1); js.splice(i, 1);
} else if (!$Body.data('unload-blocked')) { } else if (!$Body.data("unload-blocked")) {
console.log(`${NAME}: Unloading | ${$(this).attr('src')}`); console.log(`${NAME}: Unloading | ${$(this).attr("src")}`);
$(this).remove(); $(this).remove();
} }
}); });
// preload CSS // preload CSS
this.preload(css).then(() => { this.preload(css).then(() => {
const $head = $('head'); const $head = $("head");
css.forEach((el) => { css.forEach((el) => {
$head.append( $head.append(
`<link rel="stylesheet" type="text/css" href="${el}" />`, `<link rel="stylesheet" type="text/css" href="${el}" />`
); );
}); });
// preload JS // preload JS
this.preload(js, 'script').then(() => { this.preload(js, "script").then(() => {
js.forEach((el) => { js.forEach((el) => {
$Body.append( $Body.append(
`<script type="text/javascript" charset="UTF-8" src="${el}"></script>`, `<script type="text/javascript" charset="UTF-8" src="${el}"></script>`
); );
}); });
console.log(`${NAME}: New page is loaded!`); console.log(`${NAME}: New page is loaded!`);
// trigger events // trigger events
if (typeof data.events === 'object') { if (typeof data.events === "object") {
for (const eventName in data.events) { for (const eventName in data.events) {
$(D).trigger(eventName, [data.events[eventName]]); $(D).trigger(eventName, [data.events[eventName]]);
} }
} }
if (typeof callback !== 'undefined') { if (typeof callback !== "undefined") {
callback(); callback();
} }
@ -165,7 +165,7 @@ const AjaxUI = (($) => {
}); });
} }
static preload(items, type = 'text', cache = true, itemCallback = false) { static preload(items, type = "text", cache = true, itemCallback = false) {
if (!items.length) { if (!items.length) {
return $.Deferred().resolve().promise(); return $.Deferred().resolve().promise();
} }
@ -233,15 +233,15 @@ const AjaxUI = (($) => {
}; };
// auto-apply // auto-apply
$('.ajax').ready(() => { $(".ajax").ready(() => {
$('.ajax').jsAjaxUI(); $(".ajax").jsAjaxUI();
}); });
// AJAX update browser title // AJAX update browser title
$(D).on('layoutRefresh', (e, data) => { $(D).on("layoutRefresh", (e, data) => {
D.title = data.Title; D.title = data.Title;
$Html.attr('class', ''); $Html.attr("class", "");
if (data.ClassName) { if (data.ClassName) {
$Html.addClass(data.ClassName); $Html.addClass(data.ClassName);
} }
@ -255,9 +255,9 @@ const AjaxUI = (($) => {
if (event.state !== null && event.state.ajax) { if (event.state !== null && event.state.ajax) {
console.log(`${NAME}: GOBACK (AJAX state)`); console.log(`${NAME}: GOBACK (AJAX state)`);
AjaxUI.load(event.state.page); AjaxUI.load(event.state.page);
} else if ($existingLink.length && $existingLink.hasClass('ajax')) { } else if ($existingLink.length && $existingLink.hasClass("ajax")) {
console.log(`${NAME}: GOBACK (AJAX link)`); console.log(`${NAME}: GOBACK (AJAX link)`);
$existingLink.trigger('click'); $existingLink.trigger("click");
} else if (D.location.href !== G.location.href) { } else if (D.location.href !== G.location.href) {
console.log(`${NAME}: GOBACK (HTTP)`); console.log(`${NAME}: GOBACK (HTTP)`);
G.location.href = D.location; G.location.href = D.location;

View File

@ -1,15 +1,15 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import 'hammerjs/hammer'; import "hammerjs/hammer";
import 'jquery-hammerjs/jquery.hammer'; import "jquery-hammerjs/jquery.hammer";
import Events from '../_events'; import Events from "../_events";
const CarouselUI = (($) => { const CarouselUI = (($) => {
// Constants // Constants
const NAME = 'CarouselUI'; const NAME = "CarouselUI";
class CarouselUI { class CarouselUI {
// Static methods // Static methods
@ -28,36 +28,36 @@ const CarouselUI = (($) => {
const $e = $(e), const $e = $(e),
id = `Carousel${i}`; id = `Carousel${i}`;
$e.attr('id', id); $e.attr("id", id);
$e.data('id', i); $e.data("id", i);
const $items = $(e).find('.carousel-item'), const $items = $(e).find(".carousel-item"),
count = $items.length; count = $items.length;
if (!count) { if (!count) {
return; return;
} }
// create carousel-controls // create carousel-controls
if ($e.data('indicators')) { if ($e.data("indicators")) {
const $indicators = $('<ol class="carousel-indicators"></ol>'); const $indicators = $('<ol class="carousel-indicators"></ol>');
$indicators.append( $indicators.append(
`<li data-target="#${id}" data-slide-to="0" class="active"></li>`, `<li data-target="#${id}" data-slide-to="0" class="active"></li>`
); );
for (let i = 1; i < count; i++) { for (let i = 1; i < count; i++) {
$indicators.append( $indicators.append(
`<li data-target="#${id}" data-slide-to="${i}"></li>`, `<li data-target="#${id}" data-slide-to="${i}"></li>`
); );
} }
$e.prepend($indicators); $e.prepend($indicators);
} }
// create arrows // create arrows
if ($e.data('arrows')) { if ($e.data("arrows")) {
$e.prepend( $e.prepend(
`<i class="carousel-control-prev" data-target="#${id}" role="button" data-slide="prev"><i class="fas fa-chevron-left" aria-hidden="true"></i><i class="sr-only">Previous</i></i>`, `<i class="carousel-control-prev" data-target="#${id}" role="button" data-slide="prev"><i class="fas fa-chevron-left" aria-hidden="true"></i><i class="sr-only">Previous</i></i>`
); );
$e.prepend( $e.prepend(
`<i class="carousel-control-next" data-target="#${id}" role="button" data-slide="next"><i class="fas fa-chevron-right" aria-hidden="true"></i><i class="sr-only">Next</i></i>`, `<i class="carousel-control-next" data-target="#${id}" role="button" data-slide="next"><i class="fas fa-chevron-right" aria-hidden="true"></i><i class="sr-only">Next</i></i>`
); );
} }
@ -65,48 +65,48 @@ const CarouselUI = (($) => {
$e.carousel(); $e.carousel();
const $youtubeSlides = $e.find( const $youtubeSlides = $e.find(
'iframe[src^="https://www.youtube.com/embed/"]', 'iframe[src^="https://www.youtube.com/embed/"]'
); );
$e.on('slide.bs.carousel', () => { $e.on("slide.bs.carousel", () => {
if ($youtubeSlides.length) { if ($youtubeSlides.length) {
$youtubeSlides.each((i, e) => { $youtubeSlides.each((i, e) => {
const $e = $(e); const $e = $(e);
try { try {
$e.data( $e.data(
'player', "player",
new YT.Player(e, { new YT.Player(e, {
events: { events: {
onReady: () => { onReady: () => {
$e.data('player').pauseVideo(); $e.data("player").pauseVideo();
}, },
}, },
}), })
); );
$e.data('player').pauseVideo(); $e.data("player").pauseVideo();
} catch (e) {} } catch (e) {}
}); });
} }
}); });
$e.find('.carousel-control-prev').on('click', (e) => { $e.find(".carousel-control-prev").on("click", (e) => {
e.preventDefault(); e.preventDefault();
$e.carousel('prev'); $e.carousel("prev");
}); });
$e.find('.carousel-control-next').on('click', (e) => { $e.find(".carousel-control-next").on("click", (e) => {
e.preventDefault(); e.preventDefault();
$e.carousel('next'); $e.carousel("next");
}); });
// init touch swipes // init touch swipes
$e.hammer().bind(Events.SWIPELEFT, (e) => { $e.hammer().bind(Events.SWIPELEFT, (e) => {
$(event.target).carousel('next'); $(event.target).carousel("next");
}); });
$e.hammer().bind(Events.SWIPERIGHT, (e) => { $e.hammer().bind(Events.SWIPERIGHT, (e) => {
$(event.target).carousel('prev'); $(event.target).carousel("prev");
}); });
/*$e.find('.carousel-item').hammer().bind('tap', (event) => { /*$e.find('.carousel-item').hammer().bind('tap', (event) => {
@ -120,7 +120,7 @@ const CarouselUI = (($) => {
static dispose() { static dispose() {
this.each((i, e) => { this.each((i, e) => {
$(e).carousel('dispose'); $(e).carousel("dispose");
}); });
} }
} }

View File

@ -1,6 +1,6 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
const CookieUI = (($) => { const CookieUI = (($) => {
const D = document; const D = document;
@ -8,16 +8,16 @@ const CookieUI = (($) => {
class CookieUI { class CookieUI {
static get(name) { static get(name) {
return D.cookie.split('; ').reduce((r, v) => { return D.cookie.split("; ").reduce((r, v) => {
const parts = v.split('='); const parts = v.split("=");
return parts[0] === name ? decodeURIComponent(parts[1]) : r; return parts[0] === name ? decodeURIComponent(parts[1]) : r;
}, ''); }, "");
} }
static set(name, value, days = 7, path = '/') { static set(name, value, days = 7, path = "/") {
const expires = new Date(Date.now() + days * 864e5).toUTCString(); const expires = new Date(Date.now() + days * 864e5).toUTCString();
D.cookie = `${name}=${encodeURIComponent( D.cookie = `${name}=${encodeURIComponent(
value, value
)}; expires=${expires}; path=${path}`; )}; expires=${expires}; path=${path}`;
} }
} }

View File

@ -1,16 +1,16 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import CookieUI from './_ui.cookie'; import CookieUI from "./_ui.cookie";
const FlyoutUI = (($) => { const FlyoutUI = (($) => {
const W = window; const W = window;
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'FlyoutUI'; const NAME = "FlyoutUI";
const COOKIE = `${NAME}-hide`; const COOKIE = `${NAME}-hide`;
const TIMEOUT = 2000; const TIMEOUT = 2000;
@ -29,14 +29,14 @@ const FlyoutUI = (($) => {
ui.$modal.data(NAME, ui); ui.$modal.data(NAME, ui);
if ($close.length) { if ($close.length) {
$close.on('click', () => { $close.on("click", () => {
ui.hide(); ui.hide();
}); });
} }
const hide = CookieUI.get(COOKIE); const hide = CookieUI.get(COOKIE);
if (!$close.length || !hide || hide !== 'true') { if (!$close.length || !hide || hide !== "true") {
setTimeout(() => { setTimeout(() => {
ui.show(); ui.show();
}, TIMEOUT); }, TIMEOUT);
@ -52,7 +52,7 @@ const FlyoutUI = (($) => {
static hide(callback) { static hide(callback) {
const ui = this; const ui = this;
CookieUI.set(COOKIE, 'true', 1); CookieUI.set(COOKIE, "true", 1);
ui.$modal.removeClass(`flyout-${NAME}__active`); ui.$modal.removeClass(`flyout-${NAME}__active`);
} }
} }

View File

@ -1,16 +1,16 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import SpinnerUI from './_ui.spinner'; import SpinnerUI from "./_ui.spinner";
import FormFieldUI from './_ui.form.fields'; import FormFieldUI from "./_ui.form.fields";
const FormBasics = (($) => { const FormBasics = (($) => {
// Constants // Constants
const NAME = 'jsFormBasics'; const NAME = "jsFormBasics";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $("html, body");
const W = window; const W = window;
const D = document; const D = document;
@ -37,8 +37,8 @@ const FormBasics = (($) => {
$fields.each((e, el) => { $fields.each((e, el) => {
const $el = $(el); const $el = $(el);
if ($el.hasClass('required') || $el.attr('aria-required')) { if ($el.hasClass("required") || $el.attr("aria-required")) {
$el.closest('.field').addClass('required'); $el.closest(".field").addClass("required");
} }
}); });
@ -46,50 +46,50 @@ const FormBasics = (($) => {
$radioOptions.each((e, el) => { $radioOptions.each((e, el) => {
const $el = $(el); const $el = $(el);
if ($el.is(':checked')) { if ($el.is(":checked")) {
$el.parents('.radio').addClass('checked'); $el.parents(".radio").addClass("checked");
} }
}); });
$radioOptions.on('change', (e) => { $radioOptions.on("change", (e) => {
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const $parent = $el.parents('.radio'); const $parent = $el.parents(".radio");
$parent.siblings('.radio').each((i, el) => { $parent.siblings(".radio").each((i, el) => {
const $el = $(el); const $el = $(el);
if (!$el.find('input').is(':checked')) { if (!$el.find("input").is(":checked")) {
$el.removeClass('checked'); $el.removeClass("checked");
} }
}); });
if ($el.is(':checked')) { if ($el.is(":checked")) {
$parent.addClass('checked'); $parent.addClass("checked");
} }
}); });
$el.on('submit', (e) => { $el.on("submit", (e) => {
setTimeout(() => { setTimeout(() => {
if (!$el.find('.error').length) { if (!$el.find(".error").length) {
SpinnerUI.show(); SpinnerUI.show();
} }
}, 100); }, 100);
}); });
$('.field.password .show-password').on('click', (e) => { $(".field.password .show-password").on("click", (e) => {
console.log(`${NAME}: .field.password .show-password (click)`); console.log(`${NAME}: .field.password .show-password (click)`);
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const $field = $el.siblings('input'); const $field = $el.siblings("input");
const $icon = $el.find('.fas'); const $icon = $el.find(".fas");
const attr = $field.attr('type'); const attr = $field.attr("type");
if (attr === 'password') { if (attr === "password") {
$field.attr('type', 'text'); $field.attr("type", "text");
$icon.removeClass('fa-eye').addClass('fa-eye-slash'); $icon.removeClass("fa-eye").addClass("fa-eye-slash");
} else { } else {
$field.attr('type', 'password'); $field.attr("type", "password");
$icon.removeClass('fa-eye-slash').addClass('fa-eye'); $icon.removeClass("fa-eye-slash").addClass("fa-eye");
} }
}); });
@ -131,7 +131,7 @@ const FormBasics = (($) => {
}; };
const init = () => { const init = () => {
$('form').jsFormBasics(); $("form").jsFormBasics();
}; };
// auto-apply // auto-apply

View File

@ -1,15 +1,15 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import SpinnerUI from './_ui.spinner'; import SpinnerUI from "./_ui.spinner";
import 'croppie/croppie.js'; import "croppie/croppie.js";
import 'exif-js/exif.js'; import "exif-js/exif.js";
const CroppieUI = (($) => { const CroppieUI = (($) => {
const NAME = 'jsCroppieUI'; const NAME = "jsCroppieUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const G = window; const G = window;
@ -18,7 +18,7 @@ const CroppieUI = (($) => {
const jqteOptions = { const jqteOptions = {
color: false, color: false,
fsize: false, fsize: false,
funit: 'em', funit: "em",
format: false, format: false,
rule: false, rule: false,
source: false, source: false,
@ -39,17 +39,17 @@ const CroppieUI = (($) => {
ui.input = $el.find('input[type="file"]'); ui.input = $el.find('input[type="file"]');
//ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />'); //ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />');
ui.width = ui.input.data('width'); ui.width = ui.input.data("width");
ui.height = ui.input.data('height'); ui.height = ui.input.data("height");
$el.append( $el.append(
'<div class="cropper-wrap"><div class="cropper-container"></div>' + '<div class="cropper-wrap"><div class="cropper-container"></div>' +
'<a href="#" class="btn-remove" style="display:none"><i class="fas fa-times"></i> Remove</a></div>', '<a href="#" class="btn-remove" style="display:none"><i class="fas fa-times"></i> Remove</a></div>'
); );
//$el.append(ui.inputData); //$el.append(ui.inputData);
ui.uploadCropWrap = $el.find('.cropper-wrap'); ui.uploadCropWrap = $el.find(".cropper-wrap");
ui.uploadCrop = ui.uploadCropWrap.find('.cropper-container'); ui.uploadCrop = ui.uploadCropWrap.find(".cropper-container");
const ratio = ui.width / (ui.uploadCrop.width() - 32); const ratio = ui.width / (ui.uploadCrop.width() - 32);
ui.uploadCrop.croppie({ ui.uploadCrop.croppie({
@ -63,24 +63,24 @@ const CroppieUI = (($) => {
ui.uploadCrop.hide(); ui.uploadCrop.hide();
ui.input.on('change', (e) => { ui.input.on("change", (e) => {
this.readFile(e.currentTarget); this.readFile(e.currentTarget);
}); });
ui.$btnRemove = $el.find('.btn-remove'); ui.$btnRemove = $el.find(".btn-remove");
ui.$btnRemove.on('click', (e) => { ui.$btnRemove.on("click", (e) => {
e.preventDefault(); e.preventDefault();
ui.uploadCrop.removeClass('ready'); ui.uploadCrop.removeClass("ready");
$el.find('.croppie-image').remove(); $el.find(".croppie-image").remove();
ui.$el.find('input[type="file"]').val(''); ui.$el.find('input[type="file"]').val("");
ui.$el.find('input[type="file"]').change(); ui.$el.find('input[type="file"]').change();
ui.uploadCropWrap.hide(); ui.uploadCropWrap.hide();
}); });
if (ui.$el.find('img.croppie-image').length) { if (ui.$el.find("img.croppie-image").length) {
ui.$btnRemove.show(); ui.$btnRemove.show();
} }
} }
@ -88,14 +88,14 @@ const CroppieUI = (($) => {
readFile(input) { readFile(input) {
const ui = this; const ui = this;
const $el = ui.$el; const $el = ui.$el;
const $form = $el.closest('form'); const $form = $el.closest("form");
if (input.files && input.files[0]) { if (input.files && input.files[0]) {
const reader = new FileReader(); const reader = new FileReader();
reader.onload = (e) => { reader.onload = (e) => {
ui.uploadCrop.addClass('ready'); ui.uploadCrop.addClass("ready");
ui.uploadCrop.croppie('bind', { ui.uploadCrop.croppie("bind", {
url: e.target.result, url: e.target.result,
}); });
@ -106,56 +106,56 @@ const CroppieUI = (($) => {
reader.readAsDataURL(input.files[0]); reader.readAsDataURL(input.files[0]);
$form.off('submit'); $form.off("submit");
$form.on('submit', (e) => { $form.on("submit", (e) => {
console.log(`${NAME}: Processing submission ...`); console.log(`${NAME}: Processing submission ...`);
e.preventDefault(); e.preventDefault();
if ($form.data('locked')) { if ($form.data("locked")) {
console.warn(`${NAME}: Form#${$form.attr('id')} is locked.`); console.warn(`${NAME}: Form#${$form.attr("id")} is locked.`);
return false; return false;
} }
$form.data('locked', true); $form.data("locked", true);
SpinnerUI.show(); SpinnerUI.show();
if (!ui.uploadCrop.hasClass('ready')) { if (!ui.uploadCrop.hasClass("ready")) {
return true; return true;
} }
ui.uploadCrop ui.uploadCrop
.croppie('result', { .croppie("result", {
type: 'blob', type: "blob",
size: { size: {
width: ui.width, width: ui.width,
height: ui.height, height: ui.height,
}, },
format: 'png', format: "png",
}) })
.then((blob) => { .then((blob) => {
const form = e.currentTarget; const form = e.currentTarget;
const data = new FormData(form); const data = new FormData(form);
const name = $(input).attr('name'); const name = $(input).attr("name");
data.delete('BackURL'); data.delete("BackURL");
data.delete(name); data.delete(name);
data.append(name, blob, `${name}-image.png`); data.append(name, blob, `${name}-image.png`);
data.append('ajax', '1'); data.append("ajax", "1");
if (!$(form).data('jsFormValidate').validate()) { if (!$(form).data("jsFormValidate").validate()) {
return false; return false;
} }
$.ajax({ $.ajax({
url: $(form).attr('action'), url: $(form).attr("action"),
data, data,
processData: false, processData: false,
contentType: false, contentType: false,
type: $(form).attr('method'), type: $(form).attr("method"),
success: function (data) { success: function (data) {
$form.data('locked', false); $form.data("locked", false);
let IS_JSON = false; let IS_JSON = false;
let json = {}; let json = {};
@ -167,39 +167,39 @@ const CroppieUI = (($) => {
} }
if (IS_JSON) { if (IS_JSON) {
if (typeof json['status'] !== 'undefined') { if (typeof json["status"] !== "undefined") {
if (json['status'] === 'success') { if (json["status"] === "success") {
MainUI.alert(json['message'], json['status']); MainUI.alert(json["message"], json["status"]);
if (typeof json['link'] !== 'undefined') { if (typeof json["link"] !== "undefined") {
console.log( console.log(
`${NAME}: Finished submission > JSON ... Redirecting to ${json['link']}.`, `${NAME}: Finished submission > JSON ... Redirecting to ${json["link"]}.`
); );
setTimeout(() => { setTimeout(() => {
G.location = json['link']; G.location = json["link"];
}, 2000); }, 2000);
} else { } else {
console.warn( console.warn(
`${NAME}: Finished submission > JSON no redirect link.`, `${NAME}: Finished submission > JSON no redirect link.`
); );
} }
} else if (json['status'] === 'error') { } else if (json["status"] === "error") {
MainUI.alert(json['message'], json['status']); MainUI.alert(json["message"], json["status"]);
} }
} }
if (typeof json['form'] !== 'undefined') { if (typeof json["form"] !== "undefined") {
console.log( console.log(
`${NAME}: Finished submission > JSON. Got new form response.`, `${NAME}: Finished submission > JSON. Got new form response.`
); );
$(form).replaceWith(json['form']); $(form).replaceWith(json["form"]);
$(G).trigger(Events.AJAX); $(G).trigger(Events.AJAX);
} }
} else { } else {
console.log( console.log(
`${NAME}: Finished submission > DATA response.`, `${NAME}: Finished submission > DATA response.`
); );
$(form).replaceWith(data); $(form).replaceWith(data);
@ -216,7 +216,7 @@ const CroppieUI = (($) => {
}); });
} else { } else {
console.log( console.log(
`${NAME}: Sorry - your browser doesn't support the FileReader API.`, `${NAME}: Sorry - your browser doesn't support the FileReader API.`
); );
} }
} }
@ -249,7 +249,7 @@ const CroppieUI = (($) => {
// auto-apply // auto-apply
$(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => {
$('.field.croppie').jsCroppieUI(); $(".field.croppie").jsCroppieUI();
}); });
return CroppieUI; return CroppieUI;

View File

@ -1,19 +1,19 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import 'bootstrap-datepicker/dist/js/bootstrap-datepicker.js'; import "bootstrap-datepicker/dist/js/bootstrap-datepicker.js";
import 'bootstrap-timepicker/js/bootstrap-timepicker.js'; import "bootstrap-timepicker/js/bootstrap-timepicker.js";
const DatetimeUI = (($) => { const DatetimeUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'jsDatetimeUI'; const NAME = "jsDatetimeUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const datepickerOptions = { const datepickerOptions = {
@ -34,56 +34,56 @@ const DatetimeUI = (($) => {
ui._el = el; ui._el = el;
// datepicker // datepicker
if ($el.hasClass('date') || $el.attr('type') === 'date') { if ($el.hasClass("date") || $el.attr("type") === "date") {
const defaultDate = const defaultDate =
$el.attr('name').toLowerCase().indexOf('end') !== -1 ? '+4d' : '+3d'; $el.attr("name").toLowerCase().indexOf("end") !== -1 ? "+4d" : "+3d";
$el.attr('readonly', 'true'); $el.attr("readonly", "true");
$el.datepicker( $el.datepicker(
$.extend( $.extend(
datepickerOptions, datepickerOptions,
{ {
defaultViewDate: defaultDate, defaultViewDate: defaultDate,
multidate: $el.data('multidate'), multidate: $el.data("multidate"),
}, },
$el.data(), $el.data()
), )
); );
} }
// timepicker // timepicker
else if ($el.hasClass('time') || $el.attr('type') === 'time') { else if ($el.hasClass("time") || $el.attr("type") === "time") {
$el.attr('readonly', 'true'); $el.attr("readonly", "true");
$el $el
.timepicker( .timepicker(
$.extend( $.extend(
{ {
snapToStep: true, snapToStep: true,
icons: { icons: {
up: 'fas fa-chevron-up', up: "fas fa-chevron-up",
down: 'fas fa-chevron-down', down: "fas fa-chevron-down",
}, },
}, },
$el.data(), $el.data()
), )
) )
.on('show.timepicker', (e) => { .on("show.timepicker", (e) => {
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const $dropdown = $Body.find('.bootstrap-timepicker-widget'); const $dropdown = $Body.find(".bootstrap-timepicker-widget");
if (!$dropdown.find('[data-action="clear"]').length) { if (!$dropdown.find('[data-action="clear"]').length) {
$dropdown $dropdown
.find('tbody') .find("tbody")
.append( .append(
'<tr><td colspan="5"><a href="#" data-action="clear">Clear</a></td></tr>', '<tr><td colspan="5"><a href="#" data-action="clear">Clear</a></td></tr>'
); );
} }
const $clearBtn = $dropdown.find('[data-action="clear"]'); const $clearBtn = $dropdown.find('[data-action="clear"]');
$clearBtn.on('click', (e) => { $clearBtn.on("click", (e) => {
e.preventDefault(); e.preventDefault();
$el.timepicker('clear'); $el.timepicker("clear");
$el.timepicker('hideWidget'); $el.timepicker("hideWidget");
}); });
}); });
} }
@ -118,7 +118,7 @@ const DatetimeUI = (($) => {
// auto-apply // auto-apply
$(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => {
$( $(
'input.date, input.time,input[type="date"], input[type="time"]', 'input.date, input.time,input[type="date"], input[type="time"]'
).jsDatetimeUI(); ).jsDatetimeUI();
}); });

View File

@ -1,13 +1,13 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const FormFieldUI = (($) => { const FormFieldUI = (($) => {
// Constants // Constants
const NAME = 'jsFormFieldUI'; const NAME = "jsFormFieldUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $("html, body");
class FormFieldUI { class FormFieldUI {
constructor(el) { constructor(el) {
@ -21,23 +21,23 @@ const FormFieldUI = (($) => {
ui.vals = { ui.vals = {
val: ui.$el.val(), val: ui.$el.val(),
checked: ui.$el.is(':checked'), checked: ui.$el.is(":checked"),
}; };
// bootstrap collapse integration // bootstrap collapse integration
ui.$el.parents('.optionset').not('.field').removeClass('collapse'); ui.$el.parents(".optionset").not(".field").removeClass("collapse");
ui.$collapse = ui.$el ui.$collapse = ui.$el
.parents('.field.collapse') .parents(".field.collapse")
.not('.composite') .not(".composite")
.first(); .first();
if (ui.$collapse.length) { if (ui.$collapse.length) {
ui.$el.removeClass('collapse'); ui.$el.removeClass("collapse");
ui.$collapse.on('show.bs.collapse', (e) => { ui.$collapse.on("show.bs.collapse", (e) => {
ui.show(); ui.show();
}); });
ui.$collapse.on('hidden.bs.collapse', (e) => { ui.$collapse.on("hidden.bs.collapse", (e) => {
ui.hide(); ui.hide();
}); });
} }
@ -98,29 +98,29 @@ const FormFieldUI = (($) => {
const $el = ui.$el; const $el = ui.$el;
ui.vals = { ui.vals = {
name: $el.attr('name'), name: $el.attr("name"),
val: $el.val(), val: $el.val(),
checked: $el.is(':checked'), checked: $el.is(":checked"),
}; };
$el.val(''); $el.val("");
$el.prop('checked', false); $el.prop("checked", false);
} }
restore() { restore() {
const ui = this; const ui = this;
const $el = ui.$el; const $el = ui.$el;
const checked = ui.vals['checked']; const checked = ui.vals["checked"];
$el.val(ui.vals['val']); $el.val(ui.vals["val"]);
$el.prop('checked', checked); $el.prop("checked", checked);
} }
addMessage(msg, type = null, scrollTo = true) { addMessage(msg, type = null, scrollTo = true) {
const ui = this; const ui = this;
const $field = ui.$el.closest('.field'); const $field = ui.$el.closest(".field");
$field.addClass('has-message'); $field.addClass("has-message");
if (msg) { if (msg) {
$field.append(`<div class="message alert ${type}">${msg}</div>`); $field.append(`<div class="message alert ${type}">${msg}</div>`);
} }
@ -134,10 +134,10 @@ const FormFieldUI = (($) => {
removeMessages() { removeMessages() {
const ui = this; const ui = this;
const $field = ui.$el.closest('.field'); const $field = ui.$el.closest(".field");
$field.removeClass('has-message'); $field.removeClass("has-message");
$field.find('.message').remove(); $field.find(".message").remove();
} }
static _jQueryInterface() { static _jQueryInterface() {

View File

@ -1,17 +1,17 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import FormBasics from './_ui.form.basics'; import FormBasics from "./_ui.form.basics";
const FormToggleUI = (($) => { const FormToggleUI = (($) => {
// Constants // Constants
const NAME = 'jsFormToggleUI'; const NAME = "jsFormToggleUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const W = window; const W = window;
const $Html = $('html, body'); const $Html = $("html, body");
const FieldUI = 'jsFormFieldUI'; const FieldUI = "jsFormFieldUI";
class FormToggleUI { class FormToggleUI {
constructor($el) { constructor($el) {
@ -40,31 +40,31 @@ const FormToggleUI = (($) => {
const $el = ui.$el; const $el = ui.$el;
return $el.is('[type="radio"],[type="checkbox"]') && return $el.is('[type="radio"],[type="checkbox"]') &&
$el.parents('.optionset,.checkboxset').length $el.parents(".optionset,.checkboxset").length
? $el.parents('.optionset,.checkboxset') ? $el.parents(".optionset,.checkboxset")
: $el; : $el;
} }
getCondition() { getCondition() {
const ui = this; const ui = this;
return ui.getDataEl().data('value-toggle'); return ui.getDataEl().data("value-toggle");
} }
getCurrentVal() { getCurrentVal() {
const ui = this; const ui = this;
const $el = ui.$el; const $el = ui.$el;
if ($el.attr('type') === 'checkbox') { if ($el.attr("type") === "checkbox") {
if ($el.parents('.checkboxset').length && $el.is(':checked')) { if ($el.parents(".checkboxset").length && $el.is(":checked")) {
return $el.val(); return $el.val();
} }
return $el.is(':checked') ? true : false; return $el.is(":checked") ? true : false;
} }
if ($el.attr('type') === 'radio') { if ($el.attr("type") === "radio") {
return $Html.find(`[name="${$el.attr('name')}"]:checked`).val(); return $Html.find(`[name="${$el.attr("name")}"]:checked`).val();
} }
return $el.val(); return $el.val();
@ -75,9 +75,9 @@ const FormToggleUI = (($) => {
const $dataEl = ui.getDataEl(); const $dataEl = ui.getDataEl();
// compatibility params // compatibility params
const target = $dataEl.data('value-toggle-yes'); const target = $dataEl.data("value-toggle-yes");
if (!target || !target.length) { if (!target || !target.length) {
return ui.getElement($dataEl.data('target')); return ui.getElement($dataEl.data("target"));
} }
return ui.getElement(target); return ui.getElement(target);
@ -88,9 +88,9 @@ const FormToggleUI = (($) => {
const $dataEl = ui.getDataEl(); const $dataEl = ui.getDataEl();
// compatibility params // compatibility params
const target = $dataEl.data('value-toggle-no'); const target = $dataEl.data("value-toggle-no");
if (!target || !target.length) { if (!target || !target.length) {
return ui.getElement($dataEl.data('value-toggle-false')); return ui.getElement($dataEl.data("value-toggle-false"));
} }
return ui.getElement(target); return ui.getElement(target);
@ -115,7 +115,7 @@ const FormToggleUI = (($) => {
// yes/no toggler // yes/no toggler
const yesNoVal = const yesNoVal =
(condition === true && val && val !== '' && val !== '0') || (condition === true && val && val !== "" && val !== "0") ||
condition === val condition === val
? true ? true
: false; : false;
@ -124,7 +124,7 @@ const FormToggleUI = (($) => {
const $noTarget = ui.getFalseTarget(); const $noTarget = ui.getFalseTarget();
const elUI = $el.data(FieldUI); const elUI = $el.data(FieldUI);
if ((elUI && !elUI.shown) || typeof val === 'undefined') { if ((elUI && !elUI.shown) || typeof val === "undefined") {
ui.toggleElement($yesTarget, false); ui.toggleElement($yesTarget, false);
ui.toggleElement($noTarget, false); ui.toggleElement($noTarget, false);
@ -146,9 +146,9 @@ const FormToggleUI = (($) => {
} }
const ui = this; const ui = this;
const action = show ? 'show' : 'hide'; const action = show ? "show" : "hide";
$el.filter('div.collapse').each((i, el) => { $el.filter("div.collapse").each((i, el) => {
const $el = $(el); const $el = $(el);
$el.collapse(action); $el.collapse(action);
@ -182,11 +182,11 @@ const FormToggleUI = (($) => {
static validate() { static validate() {
return $(Events.FORM_FIELDS).each((i, el) => { return $(Events.FORM_FIELDS).each((i, el) => {
const $el = $(el); const $el = $(el);
const name = $el.attr('name'); const name = $el.attr("name");
if ($(`[name="${name}"]`).length > 1) { if ($(`[name="${name}"]`).length > 1) {
console.warn( console.warn(
`${NAME}: Module malfunction duplicate "${name}" elements found`, `${NAME}: Module malfunction duplicate "${name}" elements found`
); );
} }
}); });
@ -204,9 +204,9 @@ const FormToggleUI = (($) => {
// auto-apply // auto-apply
$(W).on(`${Events.LODEDANDREADY}`, () => { $(W).on(`${Events.LODEDANDREADY}`, () => {
//FormToggleUI.validate(); //FormToggleUI.validate();
$(Events.FORM_FIELDS).filter('[data-value-toggle]').jsFormToggleUI(); $(Events.FORM_FIELDS).filter("[data-value-toggle]").jsFormToggleUI();
$('[data-value-toggle]') $("[data-value-toggle]")
.not(Events.FORM_FIELDS) .not(Events.FORM_FIELDS)
.find(Events.FORM_FIELDS) .find(Events.FORM_FIELDS)
.jsFormToggleUI(); .jsFormToggleUI();

View File

@ -1,22 +1,22 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import Spinner from '../_components/_ui.spinner'; import Spinner from "../_components/_ui.spinner";
import FormValidateField from './_ui.form.validate.field'; import FormValidateField from "./_ui.form.validate.field";
import '../../thirdparty/jQuery-TE_v.1.4.0/jquery-te-1.4.0.css'; import "../../thirdparty/jQuery-TE_v.1.4.0/jquery-te-1.4.0.css";
import '../../thirdparty/jQuery-TE_v.1.4.0/uncompressed/jquery-te-1.4.0.js'; import "../../thirdparty/jQuery-TE_v.1.4.0/uncompressed/jquery-te-1.4.0.js";
const JqteUI = (($) => { const JqteUI = (($) => {
const NAME = 'jsJqteUI'; const NAME = "jsJqteUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const jqteOptions = { const jqteOptions = {
color: false, color: false,
fsize: false, fsize: false,
funit: 'em', funit: "em",
format: false, format: false,
rule: false, rule: false,
source: false, source: false,
@ -30,7 +30,7 @@ const JqteUI = (($) => {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
const validationUI = $element.data('jsFormValidateField'); const validationUI = $element.data("jsFormValidateField");
ui._element = element; ui._element = element;
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
@ -39,9 +39,9 @@ const JqteUI = (($) => {
// dynamic error control // dynamic error control
if (validationUI) { if (validationUI) {
$element $element
.parents('.jqte') .parents(".jqte")
.find('.jqte_editor') .find(".jqte_editor")
.on('change', (e) => { .on("change", (e) => {
validationUI.validate(); validationUI.validate();
}); });
} }
@ -75,7 +75,7 @@ const JqteUI = (($) => {
// auto-apply // auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('textarea.jqte-field').jsJqteUI(); $("textarea.jqte-field").jsJqteUI();
}); });
return JqteUI; return JqteUI;

View File

@ -1,15 +1,15 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import select2 from 'select2/dist/js/select2.js'; import select2 from "select2/dist/js/select2.js";
import Events from '../_events'; import Events from "../_events";
const FormSelect2 = (($) => { const FormSelect2 = (($) => {
// Constants // Constants
const NAME = 'jsFormSelect2'; const NAME = "jsFormSelect2";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $("html, body");
const W = window; const W = window;
const D = document; const D = document;
@ -27,8 +27,8 @@ const FormSelect2 = (($) => {
const $fields = $el.find(Events.FORM_FIELDS); const $fields = $el.find(Events.FORM_FIELDS);
const $selectFields = $el const $selectFields = $el
.find('select:not([readonly])') .find("select:not([readonly])")
.not('.no-select2'); .not(".no-select2");
$selectFields.each((i, el) => { $selectFields.each((i, el) => {
$(el).select2(); $(el).select2();
@ -46,12 +46,12 @@ const FormSelect2 = (($) => {
const $el = $(ui._el); const $el = $(ui._el);
const $selectFields = $el const $selectFields = $el
.find('select:not([readonly])') .find("select:not([readonly])")
.not('.no-select2'); .not(".no-select2");
$selectFields.each((i, el) => { $selectFields.each((i, el) => {
const $el = $(el); const $el = $(el);
if ($el.hasClass('select2-hidden-accessible')) { if ($el.hasClass("select2-hidden-accessible")) {
$el.select2('destroy'); $el.select2("destroy");
} }
}); });
@ -83,7 +83,7 @@ const FormSelect2 = (($) => {
}; };
const init = () => { const init = () => {
$('form').jsFormSelect2(); $("form").jsFormSelect2();
}; };
// auto-apply // auto-apply

View File

@ -1,15 +1,15 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import LANG from '../lang/_en'; import LANG from "../lang/_en";
import FormValidateField from './_ui.form.validate.field'; import FormValidateField from "./_ui.form.validate.field";
import '../../scss/_components/_ui.form.stepped.scss'; import "../../scss/_components/_ui.form.stepped.scss";
const SteppedForm = (($) => { const SteppedForm = (($) => {
// Constants // Constants
const NAME = 'jsSteppedForm'; const NAME = "jsSteppedForm";
const DATA_KEY = NAME; const DATA_KEY = NAME;
class SteppedForm { class SteppedForm {
@ -21,35 +21,35 @@ const SteppedForm = (($) => {
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
if (!$element.find('.steps-counter').length) { if (!$element.find(".steps-counter").length) {
$element.prepend(LANG['en'][NAME]['STEPCOUNTER']); $element.prepend(LANG["en"][NAME]["STEPCOUNTER"]);
} }
if (!$element.find('.steps-buttons').length) { if (!$element.find(".steps-buttons").length) {
$element.append(LANG['en'][NAME]['STEPBUTTONS']); $element.append(LANG["en"][NAME]["STEPBUTTONS"]);
} }
ui._currentStepCounter = $element.find('.steps-counter .current-step'); ui._currentStepCounter = $element.find(".steps-counter .current-step");
ui._totalStepsCounter = $element.find('.steps-counter .total-steps'); ui._totalStepsCounter = $element.find(".steps-counter .total-steps");
ui._steps = $element.find('.step'); ui._steps = $element.find(".step");
ui._steps.each((i, el) => { ui._steps.each((i, el) => {
const $el = $(el); const $el = $(el);
if (!$el.data('step')) { if (!$el.data("step")) {
$el.data('step', i + 1); $el.data("step", i + 1);
$el.attr('data-step', i + 1); $el.attr("data-step", i + 1);
} }
}); });
ui._stepNext = $element.find('.step-next'); ui._stepNext = $element.find(".step-next");
ui._stepPrev = $element.find('.step-prev'); ui._stepPrev = $element.find(".step-prev");
ui._actions = $element.children('.btn-toolbar,.form-actions'); ui._actions = $element.children(".btn-toolbar,.form-actions");
ui._element = element; ui._element = element;
ui._currentStep = 1; ui._currentStep = 1;
ui._totalSteps = ui._steps.last().data('step') || ui._steps.length; ui._totalSteps = ui._steps.last().data("step") || ui._steps.length;
ui._stepsOrder = []; ui._stepsOrder = [];
ui._totalStepsCounter.text(ui._totalSteps); ui._totalStepsCounter.text(ui._totalSteps);
@ -57,39 +57,39 @@ const SteppedForm = (($) => {
// check if one of the steps already has an error // check if one of the steps already has an error
const $hasError = ui._steps const $hasError = ui._steps
.find( .find(
'.field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good', ".field.error,.field.holder-error,.field.holder-validation,.field.holder-info,.field.holder-warning,.field.holder-good"
) )
.first(); .first();
if ($hasError.length) { if ($hasError.length) {
const $modal = $element.parents('.modal'); const $modal = $element.parents(".modal");
// show modal // show modal
if ($modal.length && typeof $modal.modal !== 'undefined') { if ($modal.length && typeof $modal.modal !== "undefined") {
$modal.modal('show'); $modal.modal("show");
} }
ui._currentStep = ui._currentStep =
$hasError.parents('.step').data('step') || ui._currentStep; $hasError.parents(".step").data("step") || ui._currentStep;
} }
// //
ui.step(`.step[data-step="${ui._currentStep}"]`); ui.step(`.step[data-step="${ui._currentStep}"]`);
ui._stepNext.on('click', (e) => { ui._stepNext.on("click", (e) => {
e.preventDefault(); e.preventDefault();
ui.next(); ui.next();
}); });
ui._stepPrev.on('click', (e) => { ui._stepPrev.on("click", (e) => {
e.preventDefault(); e.preventDefault();
ui.prev(); ui.prev();
}); });
$element.find('.step-toggle').on('click', (e) => { $element.find(".step-toggle").on("click", (e) => {
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
e.preventDefault(); e.preventDefault();
ui.step($el.data('target')); ui.step($el.data("target"));
}); });
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
@ -131,17 +131,17 @@ const SteppedForm = (($) => {
const ui = this; const ui = this;
const $element = $(ui._element); const $element = $(ui._element);
const $target = $element.find(target); const $target = $element.find(target);
const targetStep = parseInt($target.data('step')); const targetStep = parseInt($target.data("step"));
// validate current step // validate current step
let valid = true; let valid = true;
if (targetStep > ui._currentStep) { if (targetStep > ui._currentStep) {
ui.currentStep() ui.currentStep()
.find('input,textarea,select') .find("input,textarea,select")
.each((i, el) => { .each((i, el) => {
const $el = $(el); const $el = $(el);
const fieldUI = $el.data('jsFormValidateField'); const fieldUI = $el.data("jsFormValidateField");
if (fieldUI && !fieldUI.validate()) { if (fieldUI && !fieldUI.validate()) {
valid = false; valid = false;
@ -154,14 +154,14 @@ const SteppedForm = (($) => {
} }
// //
if (parseInt($target.data('step')) <= '1') { if (parseInt($target.data("step")) <= "1") {
ui._stepPrev.hide(); ui._stepPrev.hide();
$element.trigger(Events.FORM_STEPPED_FIRST_STEP); $element.trigger(Events.FORM_STEPPED_FIRST_STEP);
} else { } else {
ui._stepPrev.show(); ui._stepPrev.show();
} }
if (parseInt($target.data('step')) >= ui._totalSteps) { if (parseInt($target.data("step")) >= ui._totalSteps) {
ui._stepNext.hide(); ui._stepNext.hide();
ui._actions.show(); ui._actions.show();
@ -174,8 +174,8 @@ const SteppedForm = (($) => {
ui._currentStep = targetStep; ui._currentStep = targetStep;
ui._stepsOrder[ui._currentStep] = $target; ui._stepsOrder[ui._currentStep] = $target;
ui._steps.removeClass('active'); ui._steps.removeClass("active");
$target.addClass('active'); $target.addClass("active");
ui._currentStepCounter.text(ui._currentStep); ui._currentStepCounter.text(ui._currentStep);
@ -187,7 +187,7 @@ const SteppedForm = (($) => {
const ui = this; const ui = this;
const $element = $(ui._element); const $element = $(ui._element);
return $element.find('.step.active'); return $element.find(".step.active");
} }
static _jQueryInterface() { static _jQueryInterface() {
@ -214,7 +214,7 @@ const SteppedForm = (($) => {
// auto-apply // auto-apply
$(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => {
$('.form-stepped').jsSteppedForm(); $(".form-stepped").jsSteppedForm();
}); });
return SteppedForm; return SteppedForm;

View File

@ -1,11 +1,11 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const FormStorage = (($) => { const FormStorage = (($) => {
// Constants // Constants
const NAME = 'jsFormStorage'; const NAME = "jsFormStorage";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const STORAGE = window.localStorage; const STORAGE = window.localStorage;
@ -15,11 +15,11 @@ const FormStorage = (($) => {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
const $elements = $element.find('input, textarea, select'); const $elements = $element.find("input, textarea, select");
const setRangeValues = function (el) { const setRangeValues = function (el) {
const $el = $(el); const $el = $(el);
$el.siblings('.value').text($el.val()); $el.siblings(".value").text($el.val());
}; };
ui._element = element; ui._element = element;
@ -30,17 +30,17 @@ const FormStorage = (($) => {
// restore form data from localStorage // restore form data from localStorage
$elements.each((i, el) => { $elements.each((i, el) => {
const $el = $(el); const $el = $(el);
const id = $el.attr('id'); const id = $el.attr("id");
const type = $el.attr('type'); const type = $el.attr("type");
const val = STORAGE.getItem(NAME + id); const val = STORAGE.getItem(NAME + id);
if (type === 'file') { if (type === "file") {
return true; return true;
} }
if (id && val && type) { if (id && val && type) {
if (type && (type === 'checkbox' || type === 'radio')) { if (type && (type === "checkbox" || type === "radio")) {
$el.prop('checked', val); $el.prop("checked", val);
} else { } else {
$el.val(val); $el.val(val);
} }
@ -56,40 +56,40 @@ const FormStorage = (($) => {
$element.trigger(Events.RESTORE_FIELD); $element.trigger(Events.RESTORE_FIELD);
$('input[type="range"]').on('change', (e) => { $('input[type="range"]').on("change", (e) => {
setRangeValues(e.currentTarget); setRangeValues(e.currentTarget);
}); });
// store form data into localStorage // store form data into localStorage
$elements.on('change', (e) => { $elements.on("change", (e) => {
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const id = $el.attr('id'); const id = $el.attr("id");
const type = $el.attr('type'); const type = $el.attr("type");
// skip some elements // skip some elements
if ($el.hasClass('no-storage')) { if ($el.hasClass("no-storage")) {
return true; return true;
} }
let val = $el.val(); let val = $el.val();
if (type && (type === 'checkbox' || type === 'radio')) { if (type && (type === "checkbox" || type === "radio")) {
val = !!$el.is(':checked'); val = !!$el.is(":checked");
} }
if (id && type && type !== 'password') { if (id && type && type !== "password") {
STORAGE.setItem(NAME + id, val); STORAGE.setItem(NAME + id, val);
} }
}); });
$element.on('submit', () => { $element.on("submit", () => {
$element.data(DATA_KEY).clear(); $element.data(DATA_KEY).clear();
}); });
$element $element
.find('.btn-toolbar,.form-actions') .find(".btn-toolbar,.form-actions")
.children('button,[type="submit"],[type="clear"]') .children('button,[type="submit"],[type="clear"]')
.on('click', () => { .on("click", () => {
$element.data(DATA_KEY).clear(); $element.data(DATA_KEY).clear();
}); });
@ -111,7 +111,7 @@ const FormStorage = (($) => {
} }
static _jQueryInterface() { static _jQueryInterface() {
if (typeof window.localStorage !== 'undefined') { if (typeof window.localStorage !== "undefined") {
return this.each(function () { return this.each(function () {
// attach functionality to element // attach functionality to element
const $element = $(this); const $element = $(this);
@ -136,11 +136,11 @@ const FormStorage = (($) => {
// auto-apply // auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('form').each((i, el) => { $("form").each((i, el) => {
const $el = $(el); const $el = $(el);
// skip some forms // skip some forms
if ($el.hasClass('no-storage')) { if ($el.hasClass("no-storage")) {
return true; return true;
} }

View File

@ -1,15 +1,15 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const FormValidateField = (($) => { const FormValidateField = (($) => {
// Constants // Constants
const NAME = 'jsFormValidateField'; const NAME = "jsFormValidateField";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Body = $('body'); const $Body = $("body");
const FieldUI = 'jsFormFieldUI'; const FieldUI = "jsFormFieldUI";
class FormValidateField { class FormValidateField {
constructor(el) { constructor(el) {
@ -18,13 +18,13 @@ const FormValidateField = (($) => {
ui.$el = $el; ui.$el = $el;
ui._actions = $el.parents('form').children('.btn-toolbar,.form-actions'); ui._actions = $el.parents("form").children(".btn-toolbar,.form-actions");
$el.data(DATA_KEY, this); $el.data(DATA_KEY, this);
// prevent browsers checks (will do it using JS) // prevent browsers checks (will do it using JS)
$el.attr('novalidate', 'novalidate'); $el.attr("novalidate", "novalidate");
$el.on('change focusout', (e) => { $el.on("change focusout", (e) => {
ui.validate(false); ui.validate(false);
}); });
@ -45,7 +45,7 @@ const FormValidateField = (($) => {
const ui = this; const ui = this;
const $el = ui.$el; const $el = ui.$el;
const $field = $el.closest('.field'); const $field = $el.closest(".field");
const extraChecks = $el.data(`${NAME}-extra`); const extraChecks = $el.data(`${NAME}-extra`);
let valid = true; let valid = true;
let msg = null; let msg = null;
@ -56,58 +56,58 @@ const FormValidateField = (($) => {
if (!ui.$el[0].checkValidity()) { if (!ui.$el[0].checkValidity()) {
valid = false; valid = false;
console.warn( console.warn(
`${NAME}: Browser check validity is failed #${$el.attr('id')}`, `${NAME}: Browser check validity is failed #${$el.attr("id")}`
); );
} }
let unmaskedVal = val; let unmaskedVal = val;
if (typeof $el.inputmask === 'function') { if (typeof $el.inputmask === "function") {
unmaskedVal = $el.inputmask('unmaskedvalue'); unmaskedVal = $el.inputmask("unmaskedvalue");
} }
// required // required
if ( if (
$el.hasClass('required') && $el.hasClass("required") &&
(!unmaskedVal.length || (!unmaskedVal.length ||
!unmaskedVal.trim().length || !unmaskedVal.trim().length ||
(ui.isHtml(val) && !$(unmaskedVal).text().length)) (ui.isHtml(val) && !$(unmaskedVal).text().length))
) { ) {
valid = false; valid = false;
console.warn(`${NAME}: Required field is missing #${$el.attr('id')}`); console.warn(`${NAME}: Required field is missing #${$el.attr("id")}`);
} }
// validate URL // validate URL
if ( if (
$el.hasClass('url') && $el.hasClass("url") &&
unmaskedVal.length && unmaskedVal.length &&
!ui.valideURL(unmaskedVal) !ui.valideURL(unmaskedVal)
) { ) {
valid = false; valid = false;
msg = msg =
'Invalid URL: URL must start with http:// or https://. For example: https://your-domain.com/bla-bla/?p1=b&p2=a#tag'; "Invalid URL: URL must start with http:// or https://. For example: https://your-domain.com/bla-bla/?p1=b&p2=a#tag";
console.warn(`${NAME}: Wrong URL #${$el.attr('id')}`); console.warn(`${NAME}: Wrong URL #${$el.attr("id")}`);
} }
// maxlength // maxlength
const maxLength = $el.attr('maxlength'); const maxLength = $el.attr("maxlength");
if (unmaskedVal.length && maxLength && maxLength.length) { if (unmaskedVal.length && maxLength && maxLength.length) {
if (unmaskedVal.length > maxLength) { if (unmaskedVal.length > maxLength) {
valid = false; valid = false;
msg = `The value is limited to ${maxLength} chars`; msg = `The value is limited to ${maxLength} chars`;
console.warn(`${NAME}: Too long value #${$el.attr('id')}`); console.warn(`${NAME}: Too long value #${$el.attr("id")}`);
} }
} }
// minlength // minlength
const minLength = $el.attr('minlength'); const minLength = $el.attr("minlength");
if (unmaskedVal.length && minLength && minLength.length) { if (unmaskedVal.length && minLength && minLength.length) {
if (unmaskedVal.length < minLength) { if (unmaskedVal.length < minLength) {
valid = false; valid = false;
msg = `The value should contain more than ${minLength} chars`; msg = `The value should contain more than ${minLength} chars`;
console.warn(`${NAME}: Too short value #${$el.attr('id')}`); console.warn(`${NAME}: Too short value #${$el.attr("id")}`);
} }
} }
@ -120,7 +120,7 @@ const FormValidateField = (($) => {
valid = valid && result; valid = valid && result;
if (!result) { if (!result) {
console.log(check); console.log(check);
console.warn(`${NAME}: Extra check is failed #${$el.attr('id')}`); console.warn(`${NAME}: Extra check is failed #${$el.attr("id")}`);
} }
}); });
} }
@ -135,9 +135,9 @@ const FormValidateField = (($) => {
} }
isHtml(str) { isHtml(str) {
const doc = new DOMParser().parseFromString(str, 'text/html'); const doc = new DOMParser().parseFromString(str, "text/html");
return Array.from(doc.body.childNodes).some( return Array.from(doc.body.childNodes).some(
(node) => node.nodeType === 1, (node) => node.nodeType === 1
); );
} }
@ -150,24 +150,24 @@ const FormValidateField = (($) => {
return false; return false;
} }
return url.protocol === 'http:' || url.protocol === 'https:'; return url.protocol === "http:" || url.protocol === "https:";
} }
setError(scrollTo = true, msg = null) { setError(scrollTo = true, msg = null) {
const ui = this; const ui = this;
const fieldUI = ui.$el.data(FieldUI); const fieldUI = ui.$el.data(FieldUI);
const $field = ui.$el.closest('.field'); const $field = ui.$el.closest(".field");
const bodyScroll = $Body.scrollTop(); const bodyScroll = $Body.scrollTop();
const pos = $field[0].getBoundingClientRect().top; //$field.offset().top; const pos = $field[0].getBoundingClientRect().top; //$field.offset().top;
const rowCorrection = parseInt($field.css('font-size')) * 4; const rowCorrection = parseInt($field.css("font-size")) * 4;
ui.removeError(); ui.removeError();
$field.addClass('error'); $field.addClass("error");
if (msg) { if (msg) {
fieldUI.addMessage(msg, 'alert-error alert-danger', scrollTo); fieldUI.addMessage(msg, "alert-error alert-danger", scrollTo);
} else if (pos && scrollTo) { } else if (pos && scrollTo) {
$field.focus(); $field.focus();
$Body.scrollTop(bodyScroll + pos - rowCorrection); $Body.scrollTop(bodyScroll + pos - rowCorrection);
@ -178,13 +178,13 @@ const FormValidateField = (($) => {
const ui = this; const ui = this;
const fieldUI = ui.$el.data(FieldUI); const fieldUI = ui.$el.data(FieldUI);
const $field = ui.$el.closest('.field'); const $field = ui.$el.closest(".field");
$field.removeClass('error'); $field.removeClass("error");
$field.removeClass('holder-error'); $field.removeClass("holder-error");
$field.removeClass('holder-validation'); $field.removeClass("holder-validation");
$field.find('.alert-error').remove(); $field.find(".alert-error").remove();
} }
static _jQueryInterface() { static _jQueryInterface() {

View File

@ -1,40 +1,40 @@
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import FormBasics from './_ui.form.basics'; import FormBasics from "./_ui.form.basics";
import FormValidateField from './_ui.form.validate.field'; import FormValidateField from "./_ui.form.validate.field";
import SpinnerUI from './_ui.spinner'; import SpinnerUI from "./_ui.spinner";
const FormValidate = (($) => { const FormValidate = (($) => {
// Constants // Constants
const NAME = 'jsFormValidate'; const NAME = "jsFormValidate";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $Html = $('html, body'); const $Html = $("html, body");
class FormValidate { class FormValidate {
constructor(element) { constructor(element) {
const ui = this; const ui = this;
const $element = $(element); const $element = $(element);
const $fields = $element.find('input,textarea,select'); const $fields = $element.find("input,textarea,select");
ui._element = element; ui._element = element;
ui.$element = $element; ui.$element = $element;
$element.data(DATA_KEY, this); $element.data(DATA_KEY, this);
ui._fields = $fields; ui._fields = $fields;
ui._stepped_form = $element.data('jsSteppedForm'); ui._stepped_form = $element.data("jsSteppedForm");
// prevent browsers checks (will do it using JS) // prevent browsers checks (will do it using JS)
$element.attr('novalidate', 'novalidate'); $element.attr("novalidate", "novalidate");
$element.on(Events.FORM_INIT_STEPPED, () => { $element.on(Events.FORM_INIT_STEPPED, () => {
ui._stepped_form = $element.data('jsSteppedForm'); ui._stepped_form = $element.data("jsSteppedForm");
}); });
// init fields validation // init fields validation
$fields.each((i, el) => { $fields.each((i, el) => {
// skip some fields here // skip some fields here
if ($(el).attr('role') === 'combobox') { if ($(el).attr("role") === "combobox") {
return; return;
} }
@ -42,16 +42,16 @@ const FormValidate = (($) => {
}); });
// check form // check form
$element.on('submit', (e) => { $element.on("submit", (e) => {
ui.validate(true, () => { ui.validate(true, () => {
e.preventDefault(); e.preventDefault();
// switch to step // switch to step
if (ui._stepped_form) { if (ui._stepped_form) {
const $el = $element.find('.error').first(); const $el = $element.find(".error").first();
if ($el.length) { if ($el.length) {
ui._stepped_form.step($el.parents('.step')); ui._stepped_form.step($el.parents(".step"));
} }
} }
@ -78,14 +78,14 @@ const FormValidate = (($) => {
const ui = this; const ui = this;
let valid = true; let valid = true;
ui._fields.filter(':visible').each((i, el) => { ui._fields.filter(":visible").each((i, el) => {
const $el = $(el); const $el = $(el);
const fieldUI = $el.data('jsFormValidateField'); const fieldUI = $el.data("jsFormValidateField");
if (fieldUI && !fieldUI.validate()) { if (fieldUI && !fieldUI.validate()) {
SpinnerUI.hide(); SpinnerUI.hide();
ui.$element.addClass('error'); ui.$element.addClass("error");
if (badCallback) { if (badCallback) {
badCallback(); badCallback();
@ -123,11 +123,11 @@ const FormValidate = (($) => {
// auto-apply // auto-apply
$(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => {
$('form').each((i, el) => { $("form").each((i, el) => {
const $el = $(el); const $el = $(el);
// skip some forms // skip some forms
if ($el.hasClass('no-validation')) { if ($el.hasClass("no-validation")) {
return true; return true;
} }

View File

@ -1,13 +1,13 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const HeaderUI = (($) => { const HeaderUI = (($) => {
const D = document; const D = document;
const W = window; const W = window;
const $Body = $('html,body'); const $Body = $("html,body");
const NAME = 'HeaderUI'; const NAME = "HeaderUI";
const CLASSNAME = `js${NAME}`; const CLASSNAME = `js${NAME}`;
class HeaderUI { class HeaderUI {
@ -22,9 +22,9 @@ const HeaderUI = (($) => {
const h = $header.height(); const h = $header.height();
const s = $Body.scrollTop(); const s = $Body.scrollTop();
if (s + 50 > h) { if (s + 50 > h) {
$Body.addClass('shrink'); $Body.addClass("shrink");
} else { } else {
$Body.removeClass('shrink'); $Body.removeClass("shrink");
} }
}; };
@ -33,23 +33,23 @@ const HeaderUI = (($) => {
const updateFooter = (i, el) => { const updateFooter = (i, el) => {
const $el = $(el); const $el = $(el);
const footerHeight = $el.height(); const footerHeight = $el.height();
$el.css('height', footerHeight); $el.css("height", footerHeight);
$el.css('margin-top', -footerHeight); $el.css("margin-top", -footerHeight);
$el.siblings('.wrapper').css('padding-bottom', footerHeight); $el.siblings(".wrapper").css("padding-bottom", footerHeight);
}; };
$('.footer,.jsFooterUI').css('height', 'auto'); $(".footer,.jsFooterUI").css("height", "auto");
setTimeout(() => { setTimeout(() => {
$('.footer,.jsFooterUI').each(updateFooter); $(".footer,.jsFooterUI").each(updateFooter);
}, 500); }, 500);
} }
static dispose() { static dispose() {
console.log(`${NAME}: dispose`); console.log(`${NAME}: dispose`);
$Body.removeClass('shrink'); $Body.removeClass("shrink");
$(`#Header,.js${NAME},.footer,.jsFooterUI,.wrapper`).attr('css', ''); $(`#Header,.js${NAME},.footer,.jsFooterUI,.wrapper`).attr("css", "");
} }
} }

View File

@ -1,21 +1,21 @@
/* /*
* Conflicts with 'bootstrap/js/dist/dropdown' * Conflicts with 'bootstrap/js/dist/dropdown'
*/ */
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import 'jquery-hoverintent/jquery.hoverIntent.js'; import "jquery-hoverintent/jquery.hoverIntent.js";
import MainUI from '../_main'; import MainUI from "../_main";
const HoverUI = (($) => { const HoverUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const $Html = $('html'); const $Html = $("html");
const $Body = $('body'); const $Body = $("body");
const NAME = 'jsHoverUI'; const NAME = "jsHoverUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
class HoverUI { class HoverUI {
@ -28,7 +28,7 @@ const HoverUI = (($) => {
if ( if (
$el.is( $el.is(
'[target="_blank"],.external,[data-toggle="lightbox"],[data-lightbox-gallery]', '[target="_blank"],.external,[data-toggle="lightbox"],[data-lightbox-gallery]'
) )
) { ) {
return true; return true;
@ -37,18 +37,18 @@ const HoverUI = (($) => {
ui.$el = $el; ui.$el = $el;
// find parent // find parent
let $parent = $el.parents('.nav-item, .dropdown'); let $parent = $el.parents(".nav-item, .dropdown");
$parent = $parent && $parent.length ? $parent.first() : null; $parent = $parent && $parent.length ? $parent.first() : null;
//$parent = $parent ? $parent : $el.parent(); //$parent = $parent ? $parent : $el.parent();
ui.$parent = $parent; ui.$parent = $parent;
// find target // find target
let $target = $el.data('target'); let $target = $el.data("target");
$target = $target && $target.length ? $target : null; $target = $target && $target.length ? $target : null;
$target = $target $target = $target
? $target ? $target
: $parent : $parent
? $parent.find('.dropdown-menu').first() ? $parent.find(".dropdown-menu").first()
: null; : null;
if (!$target || !$target.length) { if (!$target || !$target.length) {
@ -63,7 +63,7 @@ const HoverUI = (($) => {
ui.$triger = $triger; ui.$triger = $triger;
// integrate with dropdown-toggle // integrate with dropdown-toggle
$('[data-toggle="dropdown"]').on('click touch', (e) => { $('[data-toggle="dropdown"]').on("click touch", (e) => {
console.log(`${NAME}: dropdown click-touch`); console.log(`${NAME}: dropdown click-touch`);
ui.hide(); ui.hide();
}); });
@ -81,15 +81,15 @@ const HoverUI = (($) => {
}); });
} }
$el.off('click touch'); $el.off("click touch");
$el.on('click touch', (e) => { $el.on("click touch", (e) => {
const size = MainUI.detectBootstrapScreenSize(); const size = MainUI.detectBootstrapScreenSize();
console.log(`${NAME}: click-touch size: ${size}`); console.log(`${NAME}: click-touch size: ${size}`);
if ( if (
size === 'xs' || size === "xs" ||
!$el.data('allow-click') || !$el.data("allow-click") ||
(W.IsTouchScreen && !$el.data('allow-touch-click')) (W.IsTouchScreen && !$el.data("allow-touch-click"))
) { ) {
console.log(`${NAME}: click-touch prevent click`); console.log(`${NAME}: click-touch prevent click`);
e.stopPropagation(); e.stopPropagation();
@ -108,29 +108,29 @@ const HoverUI = (($) => {
} }
isShown() { isShown() {
return this.$target.hasClass('show'); return this.$target.hasClass("show");
} }
show() { show() {
const ui = this; const ui = this;
ui.$el ui.$el
.parents('.dropdown') .parents(".dropdown")
.not('.active') .not(".active")
.each((i, el) => { .each((i, el) => {
const $el = $(el); const $el = $(el);
$el.find('.dropdown').removeClass('show'); $el.find(".dropdown").removeClass("show");
$el.addClass('show'); $el.addClass("show");
}); });
ui.$target.addClass('show'); ui.$target.addClass("show");
} }
hide() { hide() {
const ui = this; const ui = this;
const $el = ui.$target; const $el = ui.$target;
$el.removeClass('show'); $el.removeClass("show");
$el.find('.dropdown-menu').removeClass('show'); $el.find(".dropdown-menu").removeClass("show");
$el.parent('.dropdown').removeClass('show'); $el.parent(".dropdown").removeClass("show");
} }
dispose() { dispose() {
@ -176,21 +176,21 @@ const HoverUI = (($) => {
}); });
// rewrite 'bootstrap/js/dist/dropdown' // rewrite 'bootstrap/js/dist/dropdown'
$('[data-toggle="dropdown"]').on('click touch', (e) => { $('[data-toggle="dropdown"]').on("click touch", (e) => {
e.preventDefault(); e.preventDefault();
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const $parent = $el.parent('.dropdown'); const $parent = $el.parent(".dropdown");
// hide siblings // hide siblings
$parent.parent().find('.dropdown, .dropdown-menu').removeClass('show'); $parent.parent().find(".dropdown, .dropdown-menu").removeClass("show");
if ($parent.hasClass('show')) { if ($parent.hasClass("show")) {
$parent.removeClass('show'); $parent.removeClass("show");
$parent.find('.dropdown-menu').removeClass('show'); $parent.find(".dropdown-menu").removeClass("show");
} else { } else {
$parent.addClass('show'); $parent.addClass("show");
$parent.find('.dropdown-menu').addClass('show'); $parent.find(".dropdown-menu").addClass("show");
} }
}); });

View File

@ -1,14 +1,14 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const ImagePositionUI = (($) => { const ImagePositionUI = (($) => {
const D = document; const D = document;
const W = window; const W = window;
const $Body = $('html,body'); const $Body = $("html,body");
const NAME = 'ImagePositionUI'; const NAME = "ImagePositionUI";
const CLASSNAME = `js${NAME}`; const CLASSNAME = `js${NAME}`;
class ImagePositionUI { class ImagePositionUI {
@ -21,7 +21,7 @@ const ImagePositionUI = (($) => {
} }
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
$(`.${CLASSNAME}`).on('click', (e) => { $(`.${CLASSNAME}`).on("click", (e) => {
e.preventDefault(); e.preventDefault();
console.log(e); console.log(e);
}); });

View File

@ -1,13 +1,13 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import 'jquery.instagramFeed/jquery.instagramFeed'; import "jquery.instagramFeed/jquery.instagramFeed";
const InstagramFeed = (($) => { const InstagramFeed = (($) => {
// Constants // Constants
const NAME = 'jsInstagramFeed'; const NAME = "jsInstagramFeed";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const W = window; const W = window;
const D = document; const D = document;
@ -23,15 +23,15 @@ const InstagramFeed = (($) => {
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
$el.data(DATA_KEY, this); $el.data(DATA_KEY, this);
const ID = $el.data('username') + $el.data('tag'); const ID = $el.data("username") + $el.data("tag");
$.instagramFeed({ $.instagramFeed({
username: $el.data('username'), username: $el.data("username"),
tag: $el.data('tag') || null, tag: $el.data("tag") || null,
display_profile: $el.data('display-profile'), display_profile: $el.data("display-profile"),
display_biography: $el.data('display-biography'), display_biography: $el.data("display-biography"),
display_gallery: $el.data('display-gallery'), display_gallery: $el.data("display-gallery"),
display_captions: $el.data('display-captions'), display_captions: $el.data("display-captions"),
cache_time: 120, cache_time: 120,
callback: (data) => { callback: (data) => {
console.log(`${NAME}: data response received`); console.log(`${NAME}: data response received`);
@ -39,27 +39,23 @@ const InstagramFeed = (($) => {
$el.append(`<div class="${NAME}-list row"></div>`); $el.append(`<div class="${NAME}-list row"></div>`);
const $list = $el.find(`.${NAME}-list`); const $list = $el.find(`.${NAME}-list`);
data['edge_owner_to_timeline_media']['edges'].forEach( data["edge_owner_to_timeline_media"]["edges"].forEach((el, i) => {
(el, i) => { const item = el["node"];
const item = el['node']; const preview = ui.ig_media_preview(item["media_preview"]);
const preview = ui.ig_media_preview(
item['media_preview'],
);
$list.append( $list.append(
`<div class="a col ${NAME}-item"` + `<div class="a col ${NAME}-item"` +
` data-lightbox-gallery="${NAME}-${ID}" data-href="${item['display_url']}" data-force="image">` + ` data-lightbox-gallery="${NAME}-${ID}" data-href="${item["display_url"]}" data-force="image">` +
`<img id="${NAME}-${ID}-${item['id']}" src="${item['display_url']}" alt="${item['accessibility_caption']}"` + `<img id="${NAME}-${ID}-${item["id"]}" src="${item["display_url"]}" alt="${item["accessibility_caption"]}"` +
`style="background:url(${preview})" />` + `style="background:url(${preview})" />` +
'</div>', "</div>"
); );
}, });
);
$(W).trigger('MetaLightboxUI.init'); $(W).trigger("MetaLightboxUI.init");
}, },
styling: false, styling: false,
items: $el.data('items'), items: $el.data("items"),
lazy_load: true, lazy_load: true,
on_error: (e) => { on_error: (e) => {
console.error(`${NAME}: ${e}`); console.error(`${NAME}: ${e}`);
@ -71,20 +67,20 @@ const InstagramFeed = (($) => {
ig_media_preview(base64data) { ig_media_preview(base64data) {
var jpegtpl = var jpegtpl =
'/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABsaGikdKUEmJkFCLy8vQkc/Pj4/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0cBHSkpNCY0PygoP0c/NT9HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//AABEIABQAKgMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AA==', "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABsaGikdKUEmJkFCLy8vQkc/Pj4/R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0cBHSkpNCY0PygoP0c/NT9HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//AABEIABQAKgMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AA==",
t = atob(base64data), t = atob(base64data),
p = t.slice(3).split(''), p = t.slice(3).split(""),
o = t o = t
.substring(0, 3) .substring(0, 3)
.split('') .split("")
.map((e) => { .map((e) => {
return e.charCodeAt(0); return e.charCodeAt(0);
}), }),
c = atob(jpegtpl).split(''); c = atob(jpegtpl).split("");
c[162] = String.fromCharCode(o[1]); c[162] = String.fromCharCode(o[1]);
c[160] = String.fromCharCode(o[2]); c[160] = String.fromCharCode(o[2]);
return base64data return base64data
? `data:image/jpeg;base64,${btoa(c.concat(p).join(''))}` ? `data:image/jpeg;base64,${btoa(c.concat(p).join(""))}`
: null; : null;
} }

View File

@ -1,19 +1,19 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import '../../scss/_components/_ui.map.scss'; import "../../scss/_components/_ui.map.scss";
import CONSTS from 'js/_consts'; import CONSTS from "js/_consts";
const MapAPI = (($) => { const MapAPI = (($) => {
// Constants // Constants
const NAME = 'jsMapAPI'; const NAME = "jsMapAPI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $BODY = $('body'); const $BODY = $("body");
const MAP_DRIVER = CONSTS['MAP_DRIVER']; const MAP_DRIVER = CONSTS["MAP_DRIVER"];
const W = window; const W = window;
class MapAPI { class MapAPI {
@ -27,19 +27,19 @@ const MapAPI = (($) => {
const $el = ui.$el; const $el = ui.$el;
const config = $el.data(); const config = $el.data();
config['center'] = [ config["center"] = [
config['lng'] ? config['lng'] : $BODY.data('default-lng'), config["lng"] ? config["lng"] : $BODY.data("default-lng"),
config['lat'] ? config['lat'] : $BODY.data('default-lat'), config["lat"] ? config["lat"] : $BODY.data("default-lat"),
]; ];
config['style'] = config['style'] config["style"] = config["style"]
? jQuery.parseJSON(config['style']) ? jQuery.parseJSON(config["style"])
: null; : null;
config['font-family'] = $BODY.css('font-family'); config["font-family"] = $BODY.css("font-family");
if (!config['icon']) { if (!config["icon"]) {
config['icon'] = '<i class="fas fa-map-marker-alt"></i>'; config["icon"] = '<i class="fas fa-map-marker-alt"></i>';
} }
console.log(`${NAME}: init ${Drv.getName()}...`); console.log(`${NAME}: init ${Drv.getName()}...`);
@ -49,31 +49,31 @@ const MapAPI = (($) => {
$el.on(Events.MAPAPILOADED, (e) => { $el.on(Events.MAPAPILOADED, (e) => {
ui.map = Drv.getMap(); ui.map = Drv.getMap();
if (config['geojson']) { if (config["geojson"]) {
console.log(`${NAME}: setting up geocode data`); console.log(`${NAME}: setting up geocode data`);
Drv.addGeoJson(config); Drv.addGeoJson(config);
} else if (config['address']) { } else if (config["address"]) {
console.log(config['address']); console.log(config["address"]);
console.log(`${NAME}: setting up address marker`); console.log(`${NAME}: setting up address marker`);
Drv.geocode(config['address'], (results) => { Drv.geocode(config["address"], (results) => {
console.log(results); console.log(results);
const lat = results[0].geometry.location.lat(); const lat = results[0].geometry.location.lat();
const lng = results[0].geometry.location.lng(); const lng = results[0].geometry.location.lng();
console.log( console.log(
`${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`, `${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`
); );
Drv.addMarker([lng, lat], config); Drv.addMarker([lng, lat], config);
ui.map.setCenter({ lat, lng }); ui.map.setCenter({ lat, lng });
}); });
} else if (config['lat'] && config['lng']) { } else if (config["lat"] && config["lng"]) {
const lat = config['lat']; const lat = config["lat"];
const lng = config['lng']; const lng = config["lng"];
console.log( console.log(
`${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`, `${NAME}: setting up single lat/lng marker lat: ${lat} lng: ${lng}`
); );
Drv.addMarker([lng, lat], config); Drv.addMarker([lng, lat], config);
@ -102,7 +102,7 @@ const MapAPI = (($) => {
} }
static _jQueryInterface() { static _jQueryInterface() {
if (typeof W.localStorage !== 'undefined') { if (typeof W.localStorage !== "undefined") {
return this.each(() => { return this.each(() => {
// attach functionality to el // attach functionality to el
const $el = $(this); const $el = $(this);
@ -127,7 +127,7 @@ const MapAPI = (($) => {
// auto-apply // auto-apply
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => { $(W).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('.mapAPI-map-container').jsMapAPI(); $(".mapAPI-map-container").jsMapAPI();
}); });
return MapAPI; return MapAPI;

View File

@ -1,10 +1,10 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
const SlidingMenu = (($) => { const SlidingMenu = (($) => {
// Constants // Constants
const NAME = 'jsSlidingMenu'; const NAME = "jsSlidingMenu";
const DATA_KEY = NAME; const DATA_KEY = NAME;
class SlidingMenu { class SlidingMenu {
@ -16,7 +16,7 @@ const SlidingMenu = (($) => {
$element.addClass(`${NAME}-active`); $element.addClass(`${NAME}-active`);
// esc button // esc button
$(window).on('keyup', (e) => { $(window).on("keyup", (e) => {
if (e.which === 27) { if (e.which === 27) {
$element.find('.is-open[data-toggle="offcanvas"]').click(); $element.find('.is-open[data-toggle="offcanvas"]').click();
} }

View File

@ -1,21 +1,21 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
import MainUI from '../_main'; import MainUI from "../_main";
import 'hammerjs/hammer'; import "hammerjs/hammer";
import 'jquery-hammerjs/jquery.hammer'; import "jquery-hammerjs/jquery.hammer";
import '../../scss/_components/_ui.multislider.scss'; import "../../scss/_components/_ui.multislider.scss";
const W = window; const W = window;
const MultiSlider = (($) => { const MultiSlider = (($) => {
// Constants // Constants
const NAME = 'jsMultiSlider'; const NAME = "jsMultiSlider";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const $BODY = $('body'); const $BODY = $("body");
class MultiSlider { class MultiSlider {
// Constructor // Constructor
@ -38,10 +38,10 @@ const MultiSlider = (($) => {
ui.addControls(); ui.addControls();
ui.calculate(); ui.calculate();
$(W).on('resize', () => { $(W).on("resize", () => {
ui.$elContainer ui.$elContainer
.find('.act-slider-prev,.act-slider-next') .find(".act-slider-prev,.act-slider-next")
.removeClass('disabled'); .removeClass("disabled");
ui.calculate(); ui.calculate();
}); });
@ -52,15 +52,15 @@ const MultiSlider = (($) => {
calculate() { calculate() {
const ui = this; const ui = this;
ui.$slides = ui.$el.find('.slide'); ui.$slides = ui.$el.find(".slide");
ui.numberOfSlides = ui.$slides.length; ui.numberOfSlides = ui.$slides.length;
ui.containerWidth = ui.$el.parent().width(); ui.containerWidth = ui.$el.parent().width();
ui.maxPos = ui.numberOfSlides - ui.numToDisplay(); ui.maxPos = ui.numberOfSlides - ui.numToDisplay();
ui.slideWidth = ui.containerWidth / ui.numToDisplay(); ui.slideWidth = ui.containerWidth / ui.numToDisplay();
ui.$slides.css('width', `${ui.slideWidth}px`); ui.$slides.css("width", `${ui.slideWidth}px`);
ui.$el.css('width', ui.slideWidth * ui.numberOfSlides); ui.$el.css("width", ui.slideWidth * ui.numberOfSlides);
ui.currPos = 0; ui.currPos = 0;
ui.slide(0); ui.slide(0);
@ -72,7 +72,7 @@ const MultiSlider = (($) => {
const size = MainUI.detectBootstrapScreenSize(); const size = MainUI.detectBootstrapScreenSize();
let num = ui.$el.data(`length-${size}`); let num = ui.$el.data(`length-${size}`);
num = num ? num : ui.$el.data('length'); num = num ? num : ui.$el.data("length");
console.log(`${NAME}: size ${size} | num ${num}`); console.log(`${NAME}: size ${size} | num ${num}`);
@ -88,26 +88,26 @@ const MultiSlider = (($) => {
'<div class="slider-actions">' + '<div class="slider-actions">' +
'<a href="#" class="act act-slider-prev"><i class="fas fa-chevron-left"></i><b class="sr-only">Prev</b></a>' + '<a href="#" class="act act-slider-prev"><i class="fas fa-chevron-left"></i><b class="sr-only">Prev</b></a>' +
'<a href="#" class="act act-slider-next"><i class="fas fa-chevron-right"></i><b class="sr-only">Next</b></a>' + '<a href="#" class="act act-slider-next"><i class="fas fa-chevron-right"></i><b class="sr-only">Next</b></a>' +
'</div>', "</div>"
); );
ui.$prevBtn = ui.$elContainer.find('.act-slider-prev'); ui.$prevBtn = ui.$elContainer.find(".act-slider-prev");
ui.$nextBtn = ui.$elContainer.find('.act-slider-next'); ui.$nextBtn = ui.$elContainer.find(".act-slider-next");
ui.$prevBtn.on('click', (e) => { ui.$prevBtn.on("click", (e) => {
e.preventDefault(); e.preventDefault();
if ($(e.currentTarget).hasClass('disabled')) { if ($(e.currentTarget).hasClass("disabled")) {
return false; return false;
} }
ui.prev(); ui.prev();
}); });
ui.$nextBtn.on('click', (e) => { ui.$nextBtn.on("click", (e) => {
e.preventDefault(); e.preventDefault();
if ($(e.currentTarget).hasClass('disabled')) { if ($(e.currentTarget).hasClass("disabled")) {
return false; return false;
} }
@ -115,11 +115,11 @@ const MultiSlider = (($) => {
}); });
// init touch swipes // init touch swipes
$e.hammer().bind('swipeleft panleft', (e) => { $e.hammer().bind("swipeleft panleft", (e) => {
ui.next(); ui.next();
}); });
$e.hammer().bind('swiperight panright', (e) => { $e.hammer().bind("swiperight panright", (e) => {
ui.prev(); ui.prev();
}); });
} }
@ -152,17 +152,17 @@ const MultiSlider = (($) => {
ui.sliding = true; ui.sliding = true;
if (ui.$nextBtn.length) { if (ui.$nextBtn.length) {
if (pos >= ui.maxPos) { if (pos >= ui.maxPos) {
ui.$nextBtn.addClass('disabled'); ui.$nextBtn.addClass("disabled");
} else { } else {
ui.$nextBtn.removeClass('disabled'); ui.$nextBtn.removeClass("disabled");
} }
} }
if (ui.$prevBtn.length) { if (ui.$prevBtn.length) {
if (pos <= 0) { if (pos <= 0) {
ui.$prevBtn.addClass('disabled'); ui.$prevBtn.addClass("disabled");
} else { } else {
ui.$prevBtn.removeClass('disabled'); ui.$prevBtn.removeClass("disabled");
} }
} }
@ -170,11 +170,11 @@ const MultiSlider = (($) => {
{ {
left: `${-(pos * ui.slideWidth)}px`, left: `${-(pos * ui.slideWidth)}px`,
}, },
'slow', "slow",
'swing', "swing",
() => { () => {
ui.sliding = false; ui.sliding = false;
}, }
); );
} }
@ -182,11 +182,11 @@ const MultiSlider = (($) => {
const ui = this; const ui = this;
if (ui.$elContainer) { if (ui.$elContainer) {
ui.$el.parent().find('.slider-actions').remove(); ui.$el.parent().find(".slider-actions").remove();
} }
if (ui.$el) { if (ui.$el) {
ui.$el.hammer().unbind('swipeleft panleft swiperight panright'); ui.$el.hammer().unbind("swipeleft panleft swiperight panright");
} }
console.log(`Disposing: ${NAME}`); console.log(`Disposing: ${NAME}`);

View File

@ -1,15 +1,15 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../lib/_events'; import Events from "../lib/_events";
const NoCaptcha = (($) => { const NoCaptcha = (($) => {
// Constants // Constants
const $window = $(window); const $window = $(window);
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'jsNoCaptcha'; const NAME = "jsNoCaptcha";
class NoCaptcha { class NoCaptcha {
static init() { static init() {
@ -18,14 +18,17 @@ const NoCaptcha = (($) => {
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
if ($('.g-recaptcha').length && typeof $window[0].grecaptcha === 'undefined') { if (
$(".g-recaptcha").length &&
typeof $window[0].grecaptcha === "undefined"
) {
console.log(`${NAME}: Loading Captcha API`); console.log(`${NAME}: Loading Captcha API`);
$.getScript( $.getScript(
'https://www.google.com/recaptcha/api.js?render=explicit&hl=en&onload=noCaptchaFieldRender', "https://www.google.com/recaptcha/api.js?render=explicit&hl=en&onload=noCaptchaFieldRender",
() => { () => {
this.renderCaptcha(); this.renderCaptcha();
}, }
); );
} else { } else {
this.renderCaptcha(); this.renderCaptcha();
@ -38,41 +41,44 @@ const NoCaptcha = (($) => {
static renderCaptcha() { static renderCaptcha() {
const grecaptcha = $window[0].grecaptcha; const grecaptcha = $window[0].grecaptcha;
if (typeof grecaptcha === 'undefined' || typeof grecaptcha.render === 'undefined') { if (
typeof grecaptcha === "undefined" ||
typeof grecaptcha.render === "undefined"
) {
return; return;
} }
console.log(`${NAME}: Rendering Captcha`); console.log(`${NAME}: Rendering Captcha`);
const $_noCaptchaFields = $('.g-recaptcha'); const $_noCaptchaFields = $(".g-recaptcha");
if (!$('.g-recaptcha').length) { if (!$(".g-recaptcha").length) {
console.log(`${NAME}: No Captcha fields`); console.log(`${NAME}: No Captcha fields`);
return; return;
} }
const submitListener = (e) => { const submitListener = (e) => {
const $field = $(e.currentTarget).find('.g-recaptcha'); const $field = $(e.currentTarget).find(".g-recaptcha");
grecaptcha.execute($field.data('widgetid')); grecaptcha.execute($field.data("widgetid"));
}; };
$_noCaptchaFields.each((i, field) => { $_noCaptchaFields.each((i, field) => {
const $field = $(field); const $field = $(field);
if ($field.data('widgetid') || $field.html().length) { if ($field.data("widgetid") || $field.html().length) {
return; return;
} }
const $form = $field.data('form') ? const $form = $field.data("form")
$(`#${$field.data('form')}`) : ? $(`#${$field.data("form")}`)
$field.parents('form'); : $field.parents("form");
const widget_id = grecaptcha.render(field, $field.data()); const widget_id = grecaptcha.render(field, $field.data());
$field.data('widgetid', widget_id); $field.data("widgetid", widget_id);
// For the invisible captcha we need to setup some callback listeners // For the invisible captcha we need to setup some callback listeners
if ($field.data('size') === 'invisible' && !$field.data('callback')) { if ($field.data("size") === "invisible" && !$field.data("callback")) {
grecaptcha.execute(widget_id); grecaptcha.execute(widget_id);
$form.on('submit', submitListener); $form.on("submit", submitListener);
} }
}); });
} }

View File

@ -1,18 +1,18 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const OpeningHoursUI = (($) => { const OpeningHoursUI = (($) => {
// Constants // Constants
const NAME = 'OpeningHoursUI'; const NAME = "OpeningHoursUI";
class OpeningHoursUI { class OpeningHoursUI {
// Static methods // Static methods
static each(callback) { static each(callback) {
$('.js-opening-hours').each((i, e) => { $(".js-opening-hours").each((i, e) => {
callback(i, $(e)); callback(i, $(e));
}); });
} }
@ -22,50 +22,50 @@ const OpeningHoursUI = (($) => {
console.log(`${NAME}: init ...`); console.log(`${NAME}: init ...`);
const hours = $.parseJSON($('.oppening-hours-json').html()); const hours = $.parseJSON($(".oppening-hours-json").html());
const date = new Date(); const date = new Date();
const dateYMD = this.Date_toYMD(date); const dateYMD = this.Date_toYMD(date);
const weekday = [ const weekday = [
'Sunday', "Sunday",
'Monday', "Monday",
'Tuesday', "Tuesday",
'Wednesday', "Wednesday",
'Thursday', "Thursday",
'Friday', "Friday",
'Saturday', "Saturday",
]; ];
const today = weekday[date.getDay()]; const today = weekday[date.getDay()];
let html = let html =
'<b class="opening-hours-status opening-hours-status-closed">Closed today</b>'; '<b class="opening-hours-status opening-hours-status-closed">Closed today</b>';
if ( if (
typeof hours['days'] !== 'undefined' && typeof hours["days"] !== "undefined" &&
typeof hours['days'][today] !== 'undefined' && typeof hours["days"][today] !== "undefined" &&
hours['days'][today].length hours["days"][today].length
) { ) {
html = 'Open today '; html = "Open today ";
$.each(hours['days'][today], (i, v) => { $.each(hours["days"][today], (i, v) => {
if (v['DisplayStart'] || v['DisplayEnd']) { if (v["DisplayStart"] || v["DisplayEnd"]) {
if ( if (
(v['DisplayStart'] && (v["DisplayStart"] &&
v['DisplayStart'] <= dateYMD && v["DisplayStart"] <= dateYMD &&
v['DisplayEnd'] && v["DisplayEnd"] &&
v['DisplayEnd'] >= dateYMD) || v["DisplayEnd"] >= dateYMD) ||
(v['DisplayStart'] && (v["DisplayStart"] &&
v['DisplayStart'] <= dateYMD && v["DisplayStart"] <= dateYMD &&
!v['DisplayEnd']) || !v["DisplayEnd"]) ||
(v['DisplayEnd'] && (v["DisplayEnd"] &&
v['DisplayEnd'] >= dateYMD && v["DisplayEnd"] >= dateYMD &&
!v['DisplayStart']) !v["DisplayStart"])
) { ) {
html = `Open today from ${v['From']} to ${v['Till']}`; html = `Open today from ${v["From"]} to ${v["Till"]}`;
return false; return false;
} }
} else { } else {
if (i > 0) { if (i > 0) {
html += ', <br/>'; html += ", <br/>";
} }
html += `from ${v['From']} to ${v['Till']}`; html += `from ${v["From"]} to ${v["Till"]}`;
} }
}); });
@ -73,11 +73,11 @@ const OpeningHoursUI = (($) => {
} }
if ( if (
typeof hours['holidays'] !== 'undefined' && typeof hours["holidays"] !== "undefined" &&
typeof hours['holidays'][dateYMD] !== 'undefined' typeof hours["holidays"][dateYMD] !== "undefined"
) { ) {
html = `<b class="opening-hours-status opening-hours-status-closed">Closed today${ html = `<b class="opening-hours-status opening-hours-status-closed">Closed today${
hours['holidays'][dateYMD] ? ` for ${hours['holidays'][dateYMD]}` : '' hours["holidays"][dateYMD] ? ` for ${hours["holidays"][dateYMD]}` : ""
}</b>`; }</b>`;
} }
@ -104,7 +104,7 @@ const OpeningHoursUI = (($) => {
static dispose() { static dispose() {
console.log(`${NAME}: dispose`); console.log(`${NAME}: dispose`);
this.each((i, e) => { this.each((i, e) => {
$(e).html(''); $(e).html("");
}); });
} }
} }

View File

@ -1,17 +1,17 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
$(() => { $(() => {
const $searchLat = $('[name="search-lat"]'); const $searchLat = $('[name="search-lat"]');
const $searchLng = $('[name="search-lng"]'); const $searchLng = $('[name="search-lng"]');
const $nearbyLat = $('#nearby-lat'); const $nearbyLat = $("#nearby-lat");
const $nearbyLng = $('#nearby-lng'); const $nearbyLng = $("#nearby-lng");
const $radius = $('#distance-radius'); const $radius = $("#distance-radius");
const $category = $('#distance-category'); const $category = $("#distance-category");
const $newLocation = $('[name="newlocation"]'); const $newLocation = $('[name="newlocation"]');
const $setnewlocation = $('#setnewlocation'); const $setnewlocation = $("#setnewlocation");
const $newlocationholder = $('.set-newlocation-holder'); const $newlocationholder = $(".set-newlocation-holder");
const updatePosition = (lat, lng) => { const updatePosition = (lat, lng) => {
$searchLat.val(lat); $searchLat.val(lat);
@ -29,14 +29,14 @@ $(() => {
return; return;
} }
$('.search-location .current-val').text(newLocation); $(".search-location .current-val").text(newLocation);
const geoUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${newLocation}&key=AIzaSyC00L0023LPBhzj12uTCL-4EwJ_6zgwcTU&sensor=true`; const geoUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${newLocation}&key=AIzaSyC00L0023LPBhzj12uTCL-4EwJ_6zgwcTU&sensor=true`;
$.getJSON(geoUrl).done((data) => { $.getJSON(geoUrl).done((data) => {
if (data.status === 'OK') { if (data.status === "OK") {
updatePosition( updatePosition(
data.results[0].geometry.location.lat, data.results[0].geometry.location.lat,
data.results[0].geometry.location.lng, data.results[0].geometry.location.lng
); );
//getCategories(); //getCategories();
} }
@ -44,7 +44,7 @@ $(() => {
}; };
const getCurrentPosition = () => { const getCurrentPosition = () => {
$('.search-location .current-val').text('Current Location'); $(".search-location .current-val").text("Current Location");
navigator.geolocation.getCurrentPosition( navigator.geolocation.getCurrentPosition(
(position) => { (position) => {
@ -52,9 +52,9 @@ $(() => {
//hideDistancesThatDontMatter(); //hideDistancesThatDontMatter();
}, },
() => { () => {
$('.search-location .current-val').text('Unable to get your location'); $(".search-location .current-val").text("Unable to get your location");
updatePosition('', ''); updatePosition("", "");
}, }
); );
}; };
@ -64,7 +64,7 @@ $(() => {
getCurrentPosition(); getCurrentPosition();
} }
$('#Form_SearchForm').on('keyup keypress', (e) => { $("#Form_SearchForm").on("keyup keypress", (e) => {
var keyCode = e.keyCode || e.which; var keyCode = e.keyCode || e.which;
if (keyCode === 13) { if (keyCode === 13) {
e.preventDefault(); e.preventDefault();
@ -72,15 +72,15 @@ $(() => {
} }
}); });
$('.get-current-location').on('click', (e) => { $(".get-current-location").on("click", (e) => {
e.preventDefault(); e.preventDefault();
getCurrentPosition(); getCurrentPosition();
$newlocationholder.toggle(); $newlocationholder.toggle();
$newLocation.val(''); $newLocation.val("");
}); });
$setnewlocation.on('click', (e) => { $setnewlocation.on("click", (e) => {
e.preventDefault(); e.preventDefault();
$newlocationholder.toggle(); $newlocationholder.toggle();
@ -90,14 +90,14 @@ $(() => {
getGeoPosition(); getGeoPosition();
}); });
$('.new-search').on('click', (e) => { $(".new-search").on("click", (e) => {
e.preventDefault(); e.preventDefault();
$('.section-search-secondary').animate( $(".section-search-secondary").animate(
{ {
'max-height': 300, "max-height": 300,
}, },
'slow', "slow"
); );
}); });
@ -129,17 +129,17 @@ $(() => {
}); });
}*/ }*/
const $map = $('#Map'); const $map = $("#Map");
if (typeof google !== 'undefined' && $map.length) { if (typeof google !== "undefined" && $map.length) {
const $directions = $('#DirectionsPanel'), const $directions = $("#DirectionsPanel"),
$fromAddress = $('#FromAddress'), $fromAddress = $("#FromAddress"),
$getDirections = $('#GetDirections'), $getDirections = $("#GetDirections"),
$directionContainer = $('#DirectionContainer'), $directionContainer = $("#DirectionContainer"),
directionsDisplay = new google.maps.DirectionsRenderer(), directionsDisplay = new google.maps.DirectionsRenderer(),
directionsService = new google.maps.DirectionsService(), directionsService = new google.maps.DirectionsService(),
currentPosition = { currentPosition = {
lat: $map.data('lat'), lat: $map.data("lat"),
lng: $map.data('lng'), lng: $map.data("lng"),
}, },
map = new google.maps.Map($map[0], { map = new google.maps.Map($map[0], {
zoom: 15, zoom: 15,
@ -172,7 +172,7 @@ $(() => {
if (status === google.maps.DirectionsStatus.OK) { if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response); directionsDisplay.setDirections(response);
} }
}, }
); );
$directionContainer.slideDown(); $directionContainer.slideDown();

View File

@ -1,43 +1,46 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const ShrinkUI = (($) => { const ShrinkUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const NAME = 'ShrinkUI'; const NAME = "ShrinkUI";
console.log(`${NAME}: init`); console.log(`${NAME}: init`);
$(W).on(`${NAME}.init ${Events.LOADED} ${Events.SCROLL} ${Events.RESIZE}`, () => { $(W).on(
if ($('#Navigation > .navbar-collapse').hasClass('show')) { `${NAME}.init ${Events.LOADED} ${Events.SCROLL} ${Events.RESIZE}`,
return; () => {
} if ($("#Navigation > .navbar-collapse").hasClass("show")) {
return;
}
let h1 = $('#SiteWideMessage').height(); let h1 = $("#SiteWideMessage").height();
if (!h1) { if (!h1) {
h1 = 0; h1 = 0;
} }
let h2 = $('#SiteWideOffline').height(); let h2 = $("#SiteWideOffline").height();
if (!h2) { if (!h2) {
h2 = 0; h2 = 0;
} }
let h3 = $('#Header').height(); let h3 = $("#Header").height();
if (!h3) { if (!h3) {
h3 = 0; h3 = 0;
} }
const headerHeight = h1 + h2 + h3; const headerHeight = h1 + h2 + h3;
if ($(D).scrollTop() > headerHeight) { if ($(D).scrollTop() > headerHeight) {
$('body').addClass('shrink'); $("body").addClass("shrink");
} else { } else {
$('body').removeClass('shrink'); $("body").removeClass("shrink");
}
} }
}); );
return ShrinkUI; return ShrinkUI;
})($); })($);

View File

@ -1,16 +1,16 @@
'use strict'; "use strict";
//import StickySidebar from 'sticky-sidebar/src/sticky-sidebar'; //import StickySidebar from 'sticky-sidebar/src/sticky-sidebar';
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
const SidebarUI = (($) => { const SidebarUI = (($) => {
const D = document; const D = document;
const W = window; const W = window;
const $Body = $('body'); const $Body = $("body");
const NAME = 'SidebarUI'; const NAME = "SidebarUI";
const CLASSNAME = `js${NAME}`; const CLASSNAME = `js${NAME}`;
const CONTENTHOLDER = 'content-holder'; const CONTENTHOLDER = "content-holder";
const INNERWRAPPER = `${CLASSNAME}__inner`; const INNERWRAPPER = `${CLASSNAME}__inner`;
class SidebarUI { class SidebarUI {
@ -50,18 +50,18 @@ const SidebarUI = (($) => {
// normal pos // normal pos
if (contentOffset >= scrollPos) { if (contentOffset >= scrollPos) {
$innerWrapper.attr('style', ''); $innerWrapper.attr("style", "");
} else if ( } else if (
scrollPos >= scrollPos >=
contentOffset + contentOffsetHeight - $innerWrapper[0].offsetHeight contentOffset + contentOffsetHeight - $innerWrapper[0].offsetHeight
) { ) {
// bottom pos // bottom pos
$innerWrapper.attr('style', `position:absolute;bottom:${fontSize}px`); $innerWrapper.attr("style", `position:absolute;bottom:${fontSize}px`);
} else { } else {
// scrolled pos // scrolled pos
$innerWrapper.attr( $innerWrapper.attr(
'style', "style",
`position:fixed;top:${fontSize}px;width:${sidebarWidth}px`, `position:fixed;top:${fontSize}px;width:${sidebarWidth}px`
); );
} }
}); });

View File

@ -1,14 +1,14 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
const SpinnerUI = (($) => { const SpinnerUI = (($) => {
class SpinnerUI { class SpinnerUI {
static show(callback) { static show(callback) {
$('#PageLoading').show(0, callback); $("#PageLoading").show(0, callback);
} }
static hide(callback) { static hide(callback) {
$('#PageLoading').hide('slow', callback); $("#PageLoading").hide("slow", callback);
} }
} }

View File

@ -1,13 +1,13 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import MainUI from '../_main'; import MainUI from "../_main";
import Events from '../_events'; import Events from "../_events";
import SpinnerUI from './_ui.spinner'; import SpinnerUI from "./_ui.spinner";
const VideoPreviewUI = (($) => { const VideoPreviewUI = (($) => {
const NAME = 'jsVideoPreviewUI'; const NAME = "jsVideoPreviewUI";
const DATA_KEY = NAME; const DATA_KEY = NAME;
const G = window; const G = window;
@ -15,16 +15,15 @@ const VideoPreviewUI = (($) => {
class VideoPreviewUI { class VideoPreviewUI {
constructor(el) { constructor(el) {
const ui = this; const ui = this;
ui.$_el = $(el); ui.$_el = $(el);
ui.innerHTML = ui.$_el[0].innerHTML; ui.innerHTML = ui.$_el[0].innerHTML;
ui.$_el.data(DATA_KEY, this); ui.$_el.data(DATA_KEY, this);
const href = ui.$_el.attr('href') || ui.$_el.data('href'); const href = ui.$_el.attr("href") || ui.$_el.data("href");
const YouTubeGetID = (url) => { const YouTubeGetID = (url) => {
const parsedURL = url.split( const parsedURL = url.split(
/(vi\/|v%3D|v=|\/v\/|youtu\.be\/|\/embed\/)/, /(vi\/|v%3D|v=|\/v\/|youtu\.be\/|\/embed\/)/
); );
console.log(`${NAME}: ${parsedURL}`); console.log(`${NAME}: ${parsedURL}`);
return undefined !== parsedURL[2] return undefined !== parsedURL[2]
@ -36,31 +35,31 @@ const VideoPreviewUI = (($) => {
if ( if (
(video = href.match( (video = href.match(
/(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/, /(youtube|youtube-nocookie|youtu|vimeo)\.(com|be)\/(watch\?v=([\w-]+)|([\w-]+))/
)) ))
) { ) {
let video_id; let video_id;
if ( if (
video[1] === 'youtube' || video[1] === "youtube" ||
video[1] === 'youtube-nocookie' || video[1] === "youtube-nocookie" ||
video[1] === 'youtu' video[1] === "youtu"
) { ) {
video_id = YouTubeGetID(href); video_id = YouTubeGetID(href);
} }
if (video[1] == 'vimeo') { if (video[1] == "vimeo") {
video_id = video[3]; video_id = video[3];
ui.$_el.addClass('loading'); ui.$_el.addClass("loading");
$.ajax({ $.ajax({
type: 'GET', type: "GET",
url: `https://vimeo.com/api/v2/video/${video_id}.json`, url: `https://vimeo.com/api/v2/video/${video_id}.json`,
jsonp: 'callback', jsonp: "callback",
dataType: 'jsonp', dataType: "jsonp",
success: function (data) { success: function (data) {
const thumbnail_src = data[0].thumbnail_large; const thumbnail_src = data[0].thumbnail_large;
ui.show(thumbnail_src); ui.show(thumbnail_src);
ui.$_el.removeClass('loading'); ui.$_el.removeClass("loading");
}, },
}); });
@ -75,7 +74,7 @@ const VideoPreviewUI = (($) => {
show(src) { show(src) {
const ui = this; const ui = this;
ui.$_el[0].innerHTML = ''; ui.$_el[0].innerHTML = "";
ui.$_el.append(`<img src="${src}" alt="Video" />`); ui.$_el.append(`<img src="${src}" alt="Video" />`);
} }

View File

@ -1,5 +1,5 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
const G = window; const G = window;
const D = document; const D = document;

View File

@ -1,5 +1,5 @@
function _gaLt(event) { function _gaLt(event) {
if (typeof ga !== 'function') { if (typeof ga !== "function") {
return; return;
} }
@ -8,8 +8,8 @@ function _gaLt(event) {
/* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */ /* Loop up the DOM tree through parent elements if clicked element is not a link (eg: an image inside a link) */
while ( while (
el && el &&
(typeof el.tagName == 'undefined' || (typeof el.tagName == "undefined" ||
el.tagName.toLowerCase() != 'a' || el.tagName.toLowerCase() != "a" ||
!el.href) !el.href)
) { ) {
el = el.parentNode; el = el.parentNode;
@ -21,7 +21,7 @@ function _gaLt(event) {
if (link.indexOf(location.host) == -1 && !link.match(/^javascript:/i)) { if (link.indexOf(location.host) == -1 && !link.match(/^javascript:/i)) {
/* external link */ /* external link */
/* HitCallback function to either open link in either same or new window */ /* HitCallback function to either open link in either same or new window */
var hitBack = function(link, target) { var hitBack = function (link, target) {
target ? window.open(link, target) : (window.location.href = link); target ? window.open(link, target) : (window.location.href = link);
}; };
/* Is target set and not _(self|parent|top)? */ /* Is target set and not _(self|parent|top)? */
@ -31,12 +31,12 @@ function _gaLt(event) {
: false; : false;
/* send event with callback */ /* send event with callback */
ga( ga(
'send', "send",
'event', "event",
'Outgoing Links', "Outgoing Links",
link, link,
document.location.pathname + document.location.search, document.location.pathname + document.location.search,
{ hitCallback: hitBack(link, target) }, { hitCallback: hitBack(link, target) }
); );
/* Prevent standard click */ /* Prevent standard click */
@ -49,13 +49,13 @@ function _gaLt(event) {
var w = window; var w = window;
w.addEventListener w.addEventListener
? w.addEventListener( ? w.addEventListener(
'load', "load",
() => { () => {
document.body.addEventListener('click', _gaLt, !1); document.body.addEventListener("click", _gaLt, !1);
}, },
!1, !1
) )
: w.attachEvent && : w.attachEvent &&
w.attachEvent('onload', () => { w.attachEvent("onload", () => {
document.body.attachEvent('onclick', _gaLt); document.body.attachEvent("onclick", _gaLt);
}); });

View File

@ -1,4 +1,4 @@
'use strict'; "use strict";
const Obj = { const Obj = {
init: () => { init: () => {
@ -9,11 +9,9 @@ const Obj = {
ui.setMap(options.map); ui.setMap(options.map);
ui.position = options.position; ui.position = options.position;
ui.html = ui.html = options.html
(options.html ? ? options.html
options.html : : '<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>';
'<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>'
);
ui.divClass = options.divClass; ui.divClass = options.divClass;
ui.align = options.align; ui.align = options.align;
ui.isDebugMode = options.debug; ui.isDebugMode = options.debug;
@ -21,7 +19,7 @@ const Obj = {
ui.onMouseOver = options.onMouseOver; ui.onMouseOver = options.onMouseOver;
ui.isBoolean = (arg) => { ui.isBoolean = (arg) => {
if (typeof arg === 'boolean') { if (typeof arg === "boolean") {
return true; return true;
} else { } else {
return false; return false;
@ -29,7 +27,7 @@ const Obj = {
}; };
ui.isNotUndefined = (arg) => { ui.isNotUndefined = (arg) => {
if (typeof arg !== 'undefined') { if (typeof arg !== "undefined") {
return true; return true;
} else { } else {
return false; return false;
@ -45,7 +43,7 @@ const Obj = {
}; };
ui.isString = (arg) => { ui.isString = (arg) => {
if (typeof arg === 'string') { if (typeof arg === "string") {
return true; return true;
} else { } else {
return false; return false;
@ -53,7 +51,7 @@ const Obj = {
}; };
ui.isFunction = (arg) => { ui.isFunction = (arg) => {
if (typeof arg === 'function') { if (typeof arg === "function") {
return true; return true;
} else { } else {
return false; return false;
@ -64,8 +62,8 @@ const Obj = {
const ui = this; const ui = this;
// Create div element. // Create div element.
ui.div = document.createElement('div'); ui.div = document.createElement("div");
ui.div.style.position = 'absolute'; ui.div.style.position = "absolute";
// Validate and set custom div class // Validate and set custom div class
if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass)) if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass))
@ -81,19 +79,19 @@ const Obj = {
// If debug mode is enabled custom content will be replaced with debug content // If debug mode is enabled custom content will be replaced with debug content
if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) { if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) {
ui.div.className = 'debug-mode'; ui.div.className = "debug-mode";
ui.div.innerHTML = ui.div.innerHTML =
'<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' + '<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' +
'<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>'; '<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>';
ui.div.setAttribute( ui.div.setAttribute(
'style', "style",
'position: absolute;' + "position: absolute;" +
'border: 5px dashed red;' + "border: 5px dashed red;" +
'height: 150px;' + "height: 150px;" +
'width: 150px;' + "width: 150px;" +
'display: flex;' + "display: flex;" +
'justify-content: center;' + "justify-content: center;" +
'align-items: center;' "align-items: center;"
); );
} }
@ -101,14 +99,14 @@ const Obj = {
ui.getPanes().overlayMouseTarget.appendChild(ui.div); ui.getPanes().overlayMouseTarget.appendChild(ui.div);
// Add listeners to the element. // Add listeners to the element.
google.maps.event.addDomListener(ui.div, 'click', (event) => { google.maps.event.addDomListener(ui.div, "click", (event) => {
google.maps.event.trigger(ui, 'click'); google.maps.event.trigger(ui, "click");
if (ui.isFunction(ui.onClick)) ui.onClick(); if (ui.isFunction(ui.onClick)) ui.onClick();
event.stopPropagation(); event.stopPropagation();
}); });
google.maps.event.addDomListener(ui.div, 'mouseover', (event) => { google.maps.event.addDomListener(ui.div, "mouseover", (event) => {
google.maps.event.trigger(ui, 'mouseover'); google.maps.event.trigger(ui, "mouseover");
if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver(); if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver();
event.stopPropagation(); event.stopPropagation();
}); });
@ -118,9 +116,9 @@ const Obj = {
const ui = this; const ui = this;
// Calculate position of div // Calculate position of div
var positionInPixels = ui.getProjection().fromLatLngToDivPixel( var positionInPixels = ui
new google.maps.LatLng(ui.position) .getProjection()
); .fromLatLngToDivPixel(new google.maps.LatLng(ui.position));
// Align HTML overlay relative to original position // Align HTML overlay relative to original position
var divOffset = { var divOffset = {
@ -128,40 +126,40 @@ const Obj = {
x: undefined, x: undefined,
}; };
switch (Array.isArray(ui.align) ? ui.align.join(' ') : '') { switch (Array.isArray(ui.align) ? ui.align.join(" ") : "") {
case 'left top': case "left top":
divOffset.y = ui.div.offsetHeight; divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth; divOffset.x = ui.div.offsetWidth;
break; break;
case 'left center': case "left center":
divOffset.y = ui.div.offsetHeight / 2; divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth; divOffset.x = ui.div.offsetWidth;
break; break;
case 'left bottom': case "left bottom":
divOffset.y = 0; divOffset.y = 0;
divOffset.x = ui.div.offsetWidth; divOffset.x = ui.div.offsetWidth;
break; break;
case 'center top': case "center top":
divOffset.y = ui.div.offsetHeight; divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth / 2; divOffset.x = ui.div.offsetWidth / 2;
break; break;
case 'center center': case "center center":
divOffset.y = ui.div.offsetHeight / 2; divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth / 2; divOffset.x = ui.div.offsetWidth / 2;
break; break;
case 'center bottom': case "center bottom":
divOffset.y = 0; divOffset.y = 0;
divOffset.x = ui.div.offsetWidth / 2; divOffset.x = ui.div.offsetWidth / 2;
break; break;
case 'right top': case "right top":
divOffset.y = ui.div.offsetHeight; divOffset.y = ui.div.offsetHeight;
divOffset.x = 0; divOffset.x = 0;
break; break;
case 'right center': case "right center":
divOffset.y = ui.div.offsetHeight / 2; divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = 0; divOffset.x = 0;
break; break;
case 'right bottom': case "right bottom":
divOffset.y = 0; divOffset.y = 0;
divOffset.x = 0; divOffset.x = 0;
break; break;
@ -171,8 +169,8 @@ const Obj = {
} }
// Set position // Set position
ui.div.style.top = `${positionInPixels.y - divOffset.y }px`; ui.div.style.top = `${positionInPixels.y - divOffset.y}px`;
ui.div.style.left = `${positionInPixels.x - divOffset.x }px`; ui.div.style.left = `${positionInPixels.x - divOffset.x}px`;
} }
getPosition() { getPosition() {
@ -194,6 +192,6 @@ const Obj = {
} }
return GoogleMapsHtmlOverlay; return GoogleMapsHtmlOverlay;
}, },
} };
export default Obj; export default Obj;

View File

@ -1,16 +1,16 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import MarkerClusterer from '@googlemaps/markerclustererplus'; import MarkerClusterer from "@googlemaps/markerclustererplus";
import Events from '../../_events'; import Events from "../../_events";
import MarkerUI from './_map.google.marker'; import MarkerUI from "./_map.google.marker";
const GoogleMapsDriver = (($) => { const GoogleMapsDriver = (($) => {
class GoogleMapsDriver { class GoogleMapsDriver {
getName() { getName() {
return 'GoogleMapsDriver'; return "GoogleMapsDriver";
} }
init($el, config = []) { init($el, config = []) {
@ -25,10 +25,10 @@ const GoogleMapsDriver = (($) => {
ui.googleApiLoaded(); ui.googleApiLoaded();
}; };
$('body').append( $("body").append(
`<script async defer src="https://maps.googleapis.com/maps/api/js?key=${ `<script async defer src="https://maps.googleapis.com/maps/api/js?key=${
config['key'] config["key"]
}&callback=init${ui.getName()}"></script>`, }&callback=init${ui.getName()}"></script>`
); );
} }
@ -37,19 +37,19 @@ const GoogleMapsDriver = (($) => {
const $el = ui.$el; const $el = ui.$el;
const config = ui.config; const config = ui.config;
const $mapDiv = $el.find('.mapAPI-map'); const $mapDiv = $el.find(".mapAPI-map");
const zoom = config['mapZoom'] ? config['mapZoom'] : 10; const zoom = config["mapZoom"] ? config["mapZoom"] : 10;
const center = config['center'] const center = config["center"]
? { ? {
lat: config['center'][1], lat: config["center"][1],
lng: config['center'][0], lng: config["center"][0],
} }
: { : {
lat: 0, lat: 0,
lng: 0, lng: 0,
}; };
const style = config['style'] ? config['style'] : null; const style = config["style"] ? config["style"] : null;
console.log(`${ui.getName()}: API is loaded`); console.log(`${ui.getName()}: API is loaded`);
// init fontawesome icons // init fontawesome icons
@ -64,28 +64,30 @@ const GoogleMapsDriver = (($) => {
ui.default_zoom = zoom; ui.default_zoom = zoom;
$mapDiv.addClass('mapboxgl-map'); $mapDiv.addClass("mapboxgl-map");
ui.popup = new ui.MarkerUI({ ui.popup = new ui.MarkerUI({
map: ui.map, map: ui.map,
align: ['center', 'top'], align: ["center", "top"],
divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none', divClass: "mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none",
html: html:
'<div class="mapboxgl-popup-tip"></div><div class="mapboxgl-popup-content">' + '<div class="mapboxgl-popup-tip"></div><div class="mapboxgl-popup-content">' +
'<div class="mapboxgl-popup-close-button" type="button" aria-label="Close popup">×</div>' + '<div class="mapboxgl-popup-close-button" type="button" aria-label="Close popup">×</div>' +
'<div class="html"></div>' + '<div class="html"></div>' +
'</div>', "</div>",
}); });
ui.popup.setMap(ui.map); ui.popup.setMap(ui.map);
ui.geocoder = new google.maps.Geocoder(); ui.geocoder = new google.maps.Geocoder();
ui.cluster = new MarkerClusterer(ui.map, null, { ui.cluster = new MarkerClusterer(ui.map, null, {
styles: [{ styles: [
width: 30, {
height: 30, width: 30,
className: 'mapboxgl-cluster', height: 30,
}], className: "mapboxgl-cluster",
},
],
}); });
$el.trigger(Events.MAPAPILOADED); $el.trigger(Events.MAPAPILOADED);
@ -102,11 +104,11 @@ const GoogleMapsDriver = (($) => {
const marker = new ui.MarkerUI({ const marker = new ui.MarkerUI({
position: pos, position: pos,
map: ui.map, map: ui.map,
align: ['center', 'top'], align: ["center", "top"],
html: `<div class="mapboxgl-marker"><div id="Marker${config['id']}" data-id="${config['id']}" class="marker">${config['icon']}</div></div>`, html: `<div class="mapboxgl-marker"><div id="Marker${config["id"]}" data-id="${config["id"]}" class="marker">${config["icon"]}</div></div>`,
onClick: () => { onClick: () => {
const $el = $(`#Marker${config['id']}`); const $el = $(`#Marker${config["id"]}`);
ui.showPopup(pos, config['content']); ui.showPopup(pos, config["content"]);
$el.trigger(Events.MAPMARKERCLICK); $el.trigger(Events.MAPMARKERCLICK);
}, },
@ -123,33 +125,33 @@ const GoogleMapsDriver = (($) => {
const ui = this; const ui = this;
const $popup = $(ui.popup.getDiv()); const $popup = $(ui.popup.getDiv());
if (ui.config['flyToMarker']) { if (ui.config["flyToMarker"]) {
ui.map.setCenter(pos); // panTo ui.map.setCenter(pos); // panTo
if (!ui.config['noZoom']) { if (!ui.config["noZoom"]) {
ui.map.setZoom(18); ui.map.setZoom(18);
} }
} }
// keep it hidden to render content // keep it hidden to render content
$popup.css({ $popup.css({
opacity: '0', opacity: "0",
}); });
$popup.removeClass('d-none'); $popup.removeClass("d-none");
$popup.find('.mapboxgl-popup-content .html').html(content); $popup.find(".mapboxgl-popup-content .html").html(content);
$popup.find('.mapboxgl-popup-close-button').on('click', (e) => { $popup.find(".mapboxgl-popup-close-button").on("click", (e) => {
e.preventDefault(); e.preventDefault();
ui.hidePopup(); ui.hidePopup();
}); });
// set position when content was rendered // set position when content was rendered
ui.popup.setPosition(pos, ['center', 'top']); ui.popup.setPosition(pos, ["center", "top"]);
// display popup // display popup
$popup.css({ $popup.css({
'margin-top': '-1rem', "margin-top": "-1rem",
opacity: '1', opacity: "1",
}); });
} }
@ -157,8 +159,8 @@ const GoogleMapsDriver = (($) => {
const ui = this; const ui = this;
const $popup = $(ui.popup.getDiv()); const $popup = $(ui.popup.getDiv());
$popup.addClass('d-none'); $popup.addClass("d-none");
if (!ui.config['noRestoreBounds'] || ui.config['flyToBounds']) { if (!ui.config["noRestoreBounds"] || ui.config["flyToBounds"]) {
ui.restoreBounds(); ui.restoreBounds();
} }
@ -173,20 +175,20 @@ const GoogleMapsDriver = (($) => {
address: addr, address: addr,
}, },
(results, status) => { (results, status) => {
if (status === 'OK') { if (status === "OK") {
//results[0].geometry.location; //results[0].geometry.location;
if (typeof callback === 'function') { if (typeof callback === "function") {
callback(results); callback(results);
} }
return results; return results;
} else { } else {
console.error( console.error(
`${ui.getName()}: Geocode was not successful for the following reason: ${status}`, `${ui.getName()}: Geocode was not successful for the following reason: ${status}`
); );
} }
}, }
); );
} }
@ -198,32 +200,32 @@ const GoogleMapsDriver = (($) => {
location: latlng, location: latlng,
}, },
(results, status) => { (results, status) => {
if (status === 'OK') { if (status === "OK") {
//results[0].formatted_address; //results[0].formatted_address;
if (typeof callback === 'function') { if (typeof callback === "function") {
callback(results); callback(results);
} }
return results; return results;
} else { } else {
console.error( console.error(
`${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`, `${ui.getName()}: Reverse Geocoding was not successful for the following reason: ${status}`
); );
} }
}, }
); );
} }
addGeoJson(config) { addGeoJson(config) {
const ui = this; const ui = this;
const firstMarker = config['geojson'].features[0].geometry.coordinates; const firstMarker = config["geojson"].features[0].geometry.coordinates;
//Map.setCenter(firstMarker); //Map.setCenter(firstMarker);
const bounds = new google.maps.LatLngBounds(); const bounds = new google.maps.LatLngBounds();
// add markers to map // add markers to map
config['geojson'].features.forEach((marker) => { config["geojson"].features.forEach((marker) => {
const id = marker.id; const id = marker.id;
const crds = marker.geometry.coordinates; const crds = marker.geometry.coordinates;
const content = marker.properties.content; const content = marker.properties.content;
@ -232,7 +234,7 @@ const GoogleMapsDriver = (($) => {
id, id,
content, content,
icon: marker.icon, icon: marker.icon,
flyToMarker: config['flyToMarker'], flyToMarker: config["flyToMarker"],
}); });
bounds.extend({ bounds.extend({

View File

@ -1,6 +1,6 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
const Obj = { const Obj = {
init: () => { init: () => {
@ -22,7 +22,7 @@ const Obj = {
ui.onMouseOver = options.onMouseOver; ui.onMouseOver = options.onMouseOver;
ui.isBoolean = (arg) => { ui.isBoolean = (arg) => {
if (typeof arg === 'boolean') { if (typeof arg === "boolean") {
return true; return true;
} else { } else {
return false; return false;
@ -30,7 +30,7 @@ const Obj = {
}; };
ui.isNotUndefined = (arg) => { ui.isNotUndefined = (arg) => {
if (typeof arg !== 'undefined') { if (typeof arg !== "undefined") {
return true; return true;
} else { } else {
return false; return false;
@ -46,7 +46,7 @@ const Obj = {
}; };
ui.isString = (arg) => { ui.isString = (arg) => {
if (typeof arg === 'string') { if (typeof arg === "string") {
return true; return true;
} else { } else {
return false; return false;
@ -54,7 +54,7 @@ const Obj = {
}; };
ui.isFunction = (arg) => { ui.isFunction = (arg) => {
if (typeof arg === 'function') { if (typeof arg === "function") {
return true; return true;
} else { } else {
return false; return false;
@ -65,8 +65,8 @@ const Obj = {
const ui = this; const ui = this;
// Create div element. // Create div element.
ui.div = document.createElement('div'); ui.div = document.createElement("div");
ui.div.style.position = 'absolute'; ui.div.style.position = "absolute";
// Validate and set custom div class // Validate and set custom div class
if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass)) if (ui.isNotUndefined(ui.divClass) && ui.hasContent(ui.divClass))
@ -82,19 +82,19 @@ const Obj = {
// If debug mode is enabled custom content will be replaced with debug content // If debug mode is enabled custom content will be replaced with debug content
if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) { if (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) {
ui.div.className = 'debug-mode'; ui.div.className = "debug-mode";
ui.div.innerHTML = ui.div.innerHTML =
'<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' + '<div style="height: 10px; width: 10px; background: red; border-radius: 100%;"></div>' +
'<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>'; '<div style="position: absolute; top: 5px; padding: 5px; width: 130px; text-align: center; font-size: 18px; text-transform: uppercase; font-weight: bolder; background: red; color: white; font-family: Arial;">Debug mode</div>';
ui.div.setAttribute( ui.div.setAttribute(
'style', "style",
'position: absolute;' + "position: absolute;" +
'border: 5px dashed red;' + "border: 5px dashed red;" +
'height: 150px;' + "height: 150px;" +
'width: 150px;' + "width: 150px;" +
'display: flex;' + "display: flex;" +
'justify-content: center;' + "justify-content: center;" +
'align-items: center;', "align-items: center;"
); );
} }
@ -102,14 +102,14 @@ const Obj = {
ui.getPanes().overlayMouseTarget.appendChild(ui.div); ui.getPanes().overlayMouseTarget.appendChild(ui.div);
// Add listeners to the element. // Add listeners to the element.
google.maps.event.addDomListener(ui.div, 'click', (event) => { google.maps.event.addDomListener(ui.div, "click", (event) => {
google.maps.event.trigger(ui, 'click'); google.maps.event.trigger(ui, "click");
if (ui.isFunction(ui.onClick)) ui.onClick(); if (ui.isFunction(ui.onClick)) ui.onClick();
event.stopPropagation(); event.stopPropagation();
}); });
google.maps.event.addDomListener(ui.div, 'mouseover', (event) => { google.maps.event.addDomListener(ui.div, "mouseover", (event) => {
google.maps.event.trigger(ui, 'mouseover'); google.maps.event.trigger(ui, "mouseover");
if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver(); if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver();
event.stopPropagation(); event.stopPropagation();
}); });
@ -119,7 +119,7 @@ const Obj = {
const ui = this; const ui = this;
let $div = $(ui.div).find( let $div = $(ui.div).find(
'.mapboxgl-marker,.marker-pin,.mapboxgl-popup,.popup', ".mapboxgl-marker,.marker-pin,.mapboxgl-popup,.popup"
); );
if (!$div.length) { if (!$div.length) {
$div = $(ui.div); $div = $(ui.div);
@ -128,12 +128,14 @@ const Obj = {
// Calculate position of div // Calculate position of div
const projection = ui.getProjection(); const projection = ui.getProjection();
if(!projection) { if (!projection) {
console.log('GoogleMapsHtmlOverlay: current map is missing'); console.log("GoogleMapsHtmlOverlay: current map is missing");
return null; return null;
} }
const positionInPixels = projection.fromLatLngToDivPixel(ui.getPosition()); const positionInPixels = projection.fromLatLngToDivPixel(
ui.getPosition()
);
// Align HTML overlay relative to original position // Align HTML overlay relative to original position
const offset = { const offset = {
@ -143,40 +145,40 @@ const Obj = {
const divWidth = $div.outerWidth(); const divWidth = $div.outerWidth();
const divHeight = $div.outerHeight(); const divHeight = $div.outerHeight();
switch (Array.isArray(ui.align) ? ui.align.join(' ') : '') { switch (Array.isArray(ui.align) ? ui.align.join(" ") : "") {
case 'left top': case "left top":
offset.y = divHeight; offset.y = divHeight;
offset.x = divWidth; offset.x = divWidth;
break; break;
case 'left center': case "left center":
offset.y = divHeight / 2; offset.y = divHeight / 2;
offset.x = divWidth; offset.x = divWidth;
break; break;
case 'left bottom': case "left bottom":
offset.y = 0; offset.y = 0;
offset.x = divWidth; offset.x = divWidth;
break; break;
case 'center top': case "center top":
offset.y = divHeight; offset.y = divHeight;
offset.x = divWidth / 2; offset.x = divWidth / 2;
break; break;
case 'center center': case "center center":
offset.y = divHeight / 2; offset.y = divHeight / 2;
offset.x = divWidth / 2; offset.x = divWidth / 2;
break; break;
case 'center bottom': case "center bottom":
offset.y = 0; offset.y = 0;
offset.x = divWidth / 2; offset.x = divWidth / 2;
break; break;
case 'right top': case "right top":
offset.y = divHeight; offset.y = divHeight;
offset.x = 0; offset.x = 0;
break; break;
case 'right center': case "right center":
offset.y = divHeight / 2; offset.y = divHeight / 2;
offset.x = 0; offset.x = 0;
break; break;
case 'right bottom': case "right bottom":
offset.y = 0; offset.y = 0;
offset.x = 0; offset.x = 0;
break; break;

View File

@ -1,40 +1,40 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import mapBoxGL from 'mapbox-gl'; import mapBoxGL from "mapbox-gl";
import Events from '../../_events'; import Events from "../../_events";
const MapBoxDriver = (($) => { const MapBoxDriver = (($) => {
class MapBoxDriver { class MapBoxDriver {
getName() { getName() {
return 'MapBoxDriver'; return "MapBoxDriver";
} }
init($el, config = []) { init($el, config = []) {
const ui = this; const ui = this;
mapBoxGL.accessToken = config['key']; mapBoxGL.accessToken = config["key"];
ui.map = new mapBoxGL.Map({ ui.map = new mapBoxGL.Map({
container: $el.find('.mapAPI-map')[0], container: $el.find(".mapAPI-map")[0],
center: config['center'] ? config['center'] : [0, 0], center: config["center"] ? config["center"] : [0, 0],
//hash: true, //hash: true,
style: config['style'] style: config["style"]
? config['style'] ? config["style"]
: 'mapbox://styles/mapbox/streets-v9', : "mapbox://styles/mapbox/streets-v9",
localIdeographFontFamily: config['font-family'], localIdeographFontFamily: config["font-family"],
zoom: config['mapZoom'] ? config['mapZoom'] : 10, zoom: config["mapZoom"] ? config["mapZoom"] : 10,
attributionControl: false, attributionControl: false,
antialias: true, antialias: true,
accessToken: config['key'], accessToken: config["key"],
}) })
.addControl( .addControl(
new mapBoxGL.AttributionControl({ new mapBoxGL.AttributionControl({
compact: true, compact: true,
}), })
) )
.addControl(new mapBoxGL.NavigationControl(), 'top-right') .addControl(new mapBoxGL.NavigationControl(), "top-right")
.addControl( .addControl(
new mapBoxGL.GeolocateControl({ new mapBoxGL.GeolocateControl({
positionOptions: { positionOptions: {
@ -42,24 +42,24 @@ const MapBoxDriver = (($) => {
}, },
trackUserLocation: true, trackUserLocation: true,
}), }),
'bottom-right', "bottom-right"
) )
.addControl( .addControl(
new mapBoxGL.ScaleControl({ new mapBoxGL.ScaleControl({
maxWidth: 80, maxWidth: 80,
unit: 'metric', unit: "metric",
}), }),
'top-left', "top-left"
) )
.addControl(new mapBoxGL.FullscreenControl()); .addControl(new mapBoxGL.FullscreenControl());
ui.map.on('load', (e) => { ui.map.on("load", (e) => {
$el.trigger(Events.MAPAPILOADED); $el.trigger(Events.MAPAPILOADED);
}); });
ui.popup = new mapBoxGL.Popup({ ui.popup = new mapBoxGL.Popup({
closeOnClick: false, closeOnClick: false,
className: 'popup', className: "popup",
}); });
} }
@ -68,16 +68,13 @@ const MapBoxDriver = (($) => {
// create a DOM el for the marker // create a DOM el for the marker
const $el = $( const $el = $(
`<div id="Marker${config['id']}" data-id="${config['id']}" class="marker">${config['icon']}</div>`, `<div id="Marker${config["id"]}" data-id="${config["id"]}" class="marker">${config["icon"]}</div>`
); );
$el.on('click', (e) => { $el.on("click", (e) => {
ui.popup ui.popup.setLngLat(crds).setHTML(config["content"]).addTo(ui.map);
.setLngLat(crds)
.setHTML(config['content'])
.addTo(ui.map);
if (config['flyToMarker']) { if (config["flyToMarker"]) {
ui.map.flyTo({ ui.map.flyTo({
center: crds, center: crds,
zoom: 17, zoom: 17,
@ -135,12 +132,12 @@ const MapBoxDriver = (($) => {
}, labelLayerId); }, labelLayerId);
}*/ }*/
const firstMarker = config['geojson'].features[0].geometry.coordinates; const firstMarker = config["geojson"].features[0].geometry.coordinates;
//Map.setCenter(firstMarker); //Map.setCenter(firstMarker);
const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker); const bounds = new mapBoxGL.LngLatBounds(firstMarker, firstMarker);
// add markers to map // add markers to map
config['geojson'].features.forEach((marker) => { config["geojson"].features.forEach((marker) => {
const id = marker.id; const id = marker.id;
const crds = marker.geometry.coordinates; const crds = marker.geometry.coordinates;
const content = marker.properties.content; const content = marker.properties.content;
@ -149,7 +146,7 @@ const MapBoxDriver = (($) => {
id, id,
content, content,
icon: marker.icon, icon: marker.icon,
flyToMarker: config['flyToMarker'], flyToMarker: config["flyToMarker"],
}); });
bounds.extend(crds); bounds.extend(crds);
@ -159,8 +156,8 @@ const MapBoxDriver = (($) => {
padding: 30, padding: 30,
}); });
ui.popup.on('close', (e) => { ui.popup.on("close", (e) => {
if (config['flyToBounds']) { if (config["flyToBounds"]) {
ui.map.fitBounds(bounds, { ui.map.fitBounds(bounds, {
padding: 30, padding: 30,
}); });

View File

@ -1,4 +1,4 @@
'use strict'; "use strict";
import mapbox from "mapbox-gl"; import mapbox from "mapbox-gl";
@ -8,7 +8,7 @@ window.offlineMaps.eventManager = {
_events: {}, _events: {},
on: function (event, action) { on: function (event, action) {
console.log(`event.on: ${ event}`); console.log(`event.on: ${event}`);
if (!(event in this._events)) { if (!(event in this._events)) {
this._events[event] = []; this._events[event] = [];
} }
@ -17,13 +17,13 @@ window.offlineMaps.eventManager = {
}, },
off: function (event) { off: function (event) {
console.log(`event.off: ${ event}`); console.log(`event.off: ${event}`);
delete this._events[event]; delete this._events[event];
return this; return this;
}, },
fire: function (event) { fire: function (event) {
console.log(`event.fire: ${ event}`); console.log(`event.fire: ${event}`);
var events = this._events; var events = this._events;
if (event in events) { if (event in events) {
var actions = events[event]; var actions = events[event];
@ -43,16 +43,20 @@ window.offlineMaps.eventManager = {
(function (window, emr, undefined) { (function (window, emr, undefined) {
var getIndexedDBStorage = function () { var getIndexedDBStorage = function () {
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; var indexedDB =
window.indexedDB ||
window.mozIndexedDB ||
window.webkitIndexedDB ||
window.msIndexedDB;
var IndexedDBImpl = function () { var IndexedDBImpl = function () {
var self = this; var self = this;
var db = null; var db = null;
var request = indexedDB.open('TileStorage'); var request = indexedDB.open("TileStorage");
request.onsuccess = function() { request.onsuccess = function () {
db = this.result; db = this.result;
emr.fire('storageLoaded', self); emr.fire("storageLoaded", self);
}; };
request.onerror = function (error) { request.onerror = function (error) {
@ -60,25 +64,25 @@ window.offlineMaps.eventManager = {
}; };
request.onupgradeneeded = function () { request.onupgradeneeded = function () {
var store = this.result.createObjectStore('tile', { keyPath: 'key' }); var store = this.result.createObjectStore("tile", { keyPath: "key" });
store.createIndex('key', 'key', { unique: true }); store.createIndex("key", "key", { unique: true });
}; };
this.add = function (key, value) { this.add = function (key, value) {
var transaction = db.transaction(['tile'], 'readwrite'); var transaction = db.transaction(["tile"], "readwrite");
var objectStore = transaction.objectStore('tile'); var objectStore = transaction.objectStore("tile");
objectStore.put({ key, value }); objectStore.put({ key, value });
}; };
this.delete = function (key) { this.delete = function (key) {
var transaction = db.transaction(['tile'], 'readwrite'); var transaction = db.transaction(["tile"], "readwrite");
var objectStore = transaction.objectStore('tile'); var objectStore = transaction.objectStore("tile");
objectStore.delete(key); objectStore.delete(key);
}; };
this.get = function (key, successCallback, errorCallback) { this.get = function (key, successCallback, errorCallback) {
var transaction = db.transaction(['tile'], 'readonly'); var transaction = db.transaction(["tile"], "readonly");
var objectStore = transaction.objectStore('tile'); var objectStore = transaction.objectStore("tile");
var result = objectStore.get(key); var result = objectStore.get(key);
result.onsuccess = function () { result.onsuccess = function () {
successCallback(this.result ? this.result.value : undefined); successCallback(this.result ? this.result.value : undefined);
@ -95,30 +99,49 @@ window.offlineMaps.eventManager = {
var WebSqlImpl = function () { var WebSqlImpl = function () {
var self = this; var self = this;
var db = openDatabase('TileStorage', '1.0', 'Tile Storage', 5 * 1024 * 1024); var db = openDatabase(
"TileStorage",
"1.0",
"Tile Storage",
5 * 1024 * 1024
);
db.transaction((tx) => { db.transaction((tx) => {
tx.executeSql('CREATE TABLE IF NOT EXISTS tile (key TEXT PRIMARY KEY, value TEXT)', [], () => { tx.executeSql(
emr.fire('storageLoaded', self); "CREATE TABLE IF NOT EXISTS tile (key TEXT PRIMARY KEY, value TEXT)",
}); [],
() => {
emr.fire("storageLoaded", self);
}
);
}); });
this.add = function (key, value) { this.add = function (key, value) {
db.transaction((tx) => { db.transaction((tx) => {
tx.executeSql('INSERT INTO tile (key, value) VALUES (?, ?)', [key, value]); tx.executeSql("INSERT INTO tile (key, value) VALUES (?, ?)", [
key,
value,
]);
}); });
}; };
this.delete = function (key) { this.delete = function (key) {
db.transaction((tx) => { db.transaction((tx) => {
tx.executeSql('DELETE FROM tile WHERE key = ?', [key]); tx.executeSql("DELETE FROM tile WHERE key = ?", [key]);
}); });
}; };
this.get = function (key, successCallback, errorCallback) { this.get = function (key, successCallback, errorCallback) {
db.transaction((tx) => { db.transaction((tx) => {
tx.executeSql('SELECT value FROM tile WHERE key = ?', [key], (tx, result) => { tx.executeSql(
successCallback(result.rows.length ? result.rows.item(0).value : undefined); "SELECT value FROM tile WHERE key = ?",
}, errorCallback); [key],
(tx, result) => {
successCallback(
result.rows.length ? result.rows.item(0).value : undefined
);
},
errorCallback
);
}); });
}; };
}; };
@ -126,10 +149,10 @@ window.offlineMaps.eventManager = {
return openDatabase ? new WebSqlImpl() : null; return openDatabase ? new WebSqlImpl() : null;
}; };
emr.on('storageLoad', () => { emr.on("storageLoad", () => {
var storage = getIndexedDBStorage() || getWebSqlStorage() || null; var storage = getIndexedDBStorage() || getWebSqlStorage() || null;
if (!storage) { if (!storage) {
emr.fire('storageLoaded', null); emr.fire("storageLoaded", null);
} }
}); });
})(window, window.offlineMaps.eventManager); })(window, window.offlineMaps.eventManager);
@ -141,25 +164,30 @@ window.offlineMaps.eventManager = {
}; };
StorageRequestManager.prototype._imageToDataUri = function (image) { StorageRequestManager.prototype._imageToDataUri = function (image) {
var canvas = window.document.createElement('canvas'); var canvas = window.document.createElement("canvas");
canvas.width = image.width; canvas.width = image.width;
canvas.height = image.height; canvas.height = image.height;
var context = canvas.getContext('2d'); var context = canvas.getContext("2d");
context.drawImage(image, 0, 0); context.drawImage(image, 0, 0);
return canvas.toDataURL('image/png'); return canvas.toDataURL("image/png");
}; };
StorageRequestManager.prototype._createTileImage = function (id, coord, value, cache) { StorageRequestManager.prototype._createTileImage = function (
var img = window.document.createElement('img'); id,
coord,
value,
cache
) {
var img = window.document.createElement("img");
img.id = id; img.id = id;
img.style.position = 'absolute'; img.style.position = "absolute";
img.coord = coord; img.coord = coord;
this.loadingBay.appendChild(img); this.loadingBay.appendChild(img);
if (cache) { if (cache) {
img.onload = this.getLoadCompleteWithCache(); img.onload = this.getLoadCompleteWithCache();
img.crossOrigin = 'Anonymous'; img.crossOrigin = "Anonymous";
} else { } else {
img.onload = this.getLoadComplete(); img.onload = this.getLoadComplete();
} }
@ -170,15 +198,19 @@ window.offlineMaps.eventManager = {
StorageRequestManager.prototype._loadTile = function (id, coord, url) { StorageRequestManager.prototype._loadTile = function (id, coord, url) {
var self = this; var self = this;
if (this._storage) { if (this._storage) {
this._storage.get(id, (value) => { this._storage.get(
if (value) { id,
self._createTileImage(id, coord, value, false); (value) => {
} else { if (value) {
self._createTileImage(id, coord, value, false);
} else {
self._createTileImage(id, coord, url, true);
}
},
() => {
self._createTileImage(id, coord, url, true); self._createTileImage(id, coord, url, true);
} }
}, () => { );
self._createTileImage(id, coord, url, true);
});
} else { } else {
self._createTileImage(id, coord, url, false); self._createTileImage(id, coord, url, false);
} }
@ -188,7 +220,10 @@ window.offlineMaps.eventManager = {
if (sortFunc && this.requestQueue.length > 8) { if (sortFunc && this.requestQueue.length > 8) {
this.requestQueue.sort(sortFunc); this.requestQueue.sort(sortFunc);
} }
while (this.openRequestCount < this.maxOpenRequests && this.requestQueue.length > 0) { while (
this.openRequestCount < this.maxOpenRequests &&
this.requestQueue.length > 0
) {
var request = this.requestQueue.pop(); var request = this.requestQueue.pop();
if (request) { if (request) {
this.openRequestCount++; this.openRequestCount++;
@ -201,7 +236,7 @@ window.offlineMaps.eventManager = {
StorageRequestManager.prototype.getLoadCompleteWithCache = function () { StorageRequestManager.prototype.getLoadCompleteWithCache = function () {
if (!this._loadComplete) { if (!this._loadComplete) {
var theManager = this; var theManager = this;
this._loadComplete = function(e) { this._loadComplete = function (e) {
//e = e || window.event; //e = e || window.event;
var img = e.srcElement || e.target; var img = e.srcElement || e.target;
@ -215,13 +250,15 @@ window.offlineMaps.eventManager = {
theManager.openRequestCount--; theManager.openRequestCount--;
delete theManager.requestsById[img.id]; delete theManager.requestsById[img.id];
if (e.type === 'load' && (img.complete || if (
(img.readyState && img.readyState === 'complete'))) { e.type === "load" &&
theManager.dispatchCallback('requestcomplete', img); (img.complete || (img.readyState && img.readyState === "complete"))
) {
theManager.dispatchCallback("requestcomplete", img);
} else { } else {
theManager.dispatchCallback('requesterror', { theManager.dispatchCallback("requesterror", {
element: img, element: img,
url: (`${ img.src}`), url: `${img.src}`,
}); });
img.src = null; img.src = null;
} }
@ -234,15 +271,16 @@ window.offlineMaps.eventManager = {
MM.extend(StorageRequestManager, MM.RequestManager); MM.extend(StorageRequestManager, MM.RequestManager);
var StorageLayer = function(provider, parent, name, storage) { var StorageLayer = function (provider, parent, name, storage) {
this.parent = parent || document.createElement('div'); this.parent = parent || document.createElement("div");
this.parent.style.cssText = 'position: absolute; top: 0px; left: 0px;' + this.parent.style.cssText =
'width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0'; "position: absolute; top: 0px; left: 0px;" +
"width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0";
this.name = name; this.name = name;
this.levels = {}; this.levels = {};
this.requestManager = new StorageRequestManager(storage); this.requestManager = new StorageRequestManager(storage);
this.requestManager.addCallback('requestcomplete', this.getTileComplete()); this.requestManager.addCallback("requestcomplete", this.getTileComplete());
this.requestManager.addCallback('requesterror', this.getTileError()); this.requestManager.addCallback("requesterror", this.getTileError());
if (provider) { if (provider) {
this.setProvider(provider); this.setProvider(provider);
} }
@ -250,21 +288,32 @@ window.offlineMaps.eventManager = {
MM.extend(StorageLayer, MM.Layer); MM.extend(StorageLayer, MM.Layer);
var StorageTemplatedLayer = function(template, subdomains, name, storage) { var StorageTemplatedLayer = function (template, subdomains, name, storage) {
return new StorageLayer(new MM.Template(template, subdomains), null, name, storage); return new StorageLayer(
new MM.Template(template, subdomains),
null,
name,
storage
);
}; };
emr.on('mapLoad', (storage) => { emr.on("mapLoad", (storage) => {
var map = mapbox.map('map'); var map = mapbox.map("map");
map.addLayer(new StorageTemplatedLayer('http://{S}.tile.osm.org/{Z}/{X}/{Y}.png', map.addLayer(
['a', 'b', 'c'], undefined, storage)); new StorageTemplatedLayer(
"http://{S}.tile.osm.org/{Z}/{X}/{Y}.png",
["a", "b", "c"],
undefined,
storage
)
);
map.ui.zoomer.add(); map.ui.zoomer.add();
map.ui.zoombox.add(); map.ui.zoombox.add();
map.centerzoom({ lat: 53.902254, lon: 27.561850 }, 13); map.centerzoom({ lat: 53.902254, lon: 27.56185 }, 13);
}); });
})(window, window.offlineMaps.eventManager, mapbox, MM); })(window, window.offlineMaps.eventManager, mapbox, MM);
(function (emr) { (function (emr) {
emr.on('storageLoaded', 'mapLoad'); emr.on("storageLoaded", "mapLoad");
emr.fire('storageLoad'); emr.fire("storageLoad");
})(window.offlineMaps.eventManager); })(window.offlineMaps.eventManager);

View File

@ -1,13 +1,13 @@
import Events from '../../_events'; import Events from "../../_events";
import Routie from "routie"; import Routie from "routie";
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => { $(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
Routie({ Routie({
'navigation': function() { navigation: function () {
$('#NavbarCollapse').addClass('in'); $("#NavbarCollapse").addClass("in");
}, },
'carousel:id:num': function(id, num) { "carousel:id:num": function (id, num) {
$(`#Carousel${ id}`).carousel(num); $(`#Carousel${id}`).carousel(num);
}, },
}); });
}); });

View File

@ -2,11 +2,11 @@
* Add your global events here * Add your global events here
*/ */
import MAP_DRIVER from './_components/drivers/_map.google'; import MAP_DRIVER from "./_components/drivers/_map.google";
//import MAP_DRIVER from './_components/drivers/_map.mapbox'; //import MAP_DRIVER from './_components/drivers/_map.mapbox';
const CONSTS = { const CONSTS = {
ENVS: ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'], ENVS: ["xs", "sm", "md", "lg", "xl", "xxl", "xxxl"],
MAP_DRIVER, MAP_DRIVER,
}; };

View File

@ -3,41 +3,41 @@
*/ */
export default { export default {
AJAX: 'ajax-load', AJAX: "ajax-load",
AJAXMAIN: 'ajax-main-load', AJAXMAIN: "ajax-main-load",
MAININIT: 'main-init', MAININIT: "main-init",
TABHIDDEN: 'tab-hidden', TABHIDDEN: "tab-hidden",
TABFOCUSED: 'tab-focused', TABFOCUSED: "tab-focused",
OFFLINE: 'offline', OFFLINE: "offline",
ONLINE: 'online', ONLINE: "online",
BACKONLINE: 'back-online', BACKONLINE: "back-online",
TOUCHENABLE: 'touch-enabled', TOUCHENABLE: "touch-enabled",
TOUCHDISABLED: 'touch-disabled', TOUCHDISABLED: "touch-disabled",
LOADED: 'load', LOADED: "load",
SWIPELEFT: 'swipeleft panleft', SWIPELEFT: "swipeleft panleft",
SWIPERIGHT: 'swiperight panright', SWIPERIGHT: "swiperight panright",
ALLERTAPPEARED: 'alert-appeared', ALLERTAPPEARED: "alert-appeared",
ALERTREMOVED: 'alert-removed', ALERTREMOVED: "alert-removed",
LODEDANDREADY: 'load-ready', LODEDANDREADY: "load-ready",
LAZYIMAGEREADY: 'image-lazy-bg-loaded', LAZYIMAGEREADY: "image-lazy-bg-loaded",
LAZYIMAGESREADY: 'images-lazy-loaded', LAZYIMAGESREADY: "images-lazy-loaded",
MAPLOADED: 'map-loaded', MAPLOADED: "map-loaded",
MAPAPILOADED: 'map-api-loaded', MAPAPILOADED: "map-api-loaded",
MAPMARKERCLICK: 'map-marker-click', MAPMARKERCLICK: "map-marker-click",
MAPPOPUPCLOSE: 'map-popup-close', MAPPOPUPCLOSE: "map-popup-close",
SCROLL: 'scroll', SCROLL: "scroll",
RESIZE: 'resize', RESIZE: "resize",
CAROUSEL_READY: 'bs.carousel.ready', CAROUSEL_READY: "bs.carousel.ready",
SET_TARGET_UPDATE: 'set-target-update', SET_TARGET_UPDATE: "set-target-update",
RESTORE_FIELD: 'restore-field', RESTORE_FIELD: "restore-field",
FORM_INIT_BASICS: 'form-basics', FORM_INIT_BASICS: "form-basics",
FORM_INIT_STEPPED: 'form-init-stepped', FORM_INIT_STEPPED: "form-init-stepped",
FORM_INIT_VALIDATE: 'form-init-validate', FORM_INIT_VALIDATE: "form-init-validate",
FORM_INIT_VALIDATE_FIELD: 'form-init-validate-field', FORM_INIT_VALIDATE_FIELD: "form-init-validate-field",
FORM_INIT_STORAGE: 'form-init-storage', FORM_INIT_STORAGE: "form-init-storage",
FORM_VALIDATION_FAILED: 'form-validation-failed', FORM_VALIDATION_FAILED: "form-validation-failed",
FORM_STEPPED_NEW_STEP: 'form-new-step', FORM_STEPPED_NEW_STEP: "form-new-step",
FORM_STEPPED_FIRST_STEP: 'form-first-step', FORM_STEPPED_FIRST_STEP: "form-first-step",
FORM_STEPPED_LAST_STEP: 'form-last-step', FORM_STEPPED_LAST_STEP: "form-last-step",
FORM_FIELDS: 'input,textarea,select', FORM_FIELDS: "input,textarea,select",
}; };

View File

@ -1,6 +1,6 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
/** /**
* Route side-wide events * Route side-wide events
@ -14,19 +14,19 @@ const EventsUI = (($) => {
const W = window; const W = window;
const $W = $(W); const $W = $(W);
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'EventsUI'; const NAME = "EventsUI";
class EventsUI { class EventsUI {
static process(el, args) { static process(el, args) {
let modEl = el; let modEl = el;
const eventName = args[0]; const eventName = args[0];
const tagName = typeof el !== undefined ? $(el).prop('tagName') : null; const tagName = typeof el !== undefined ? $(el).prop("tagName") : null;
switch (tagName) { switch (tagName) {
case 'HTML': case "HTML":
case 'BODY': case "BODY":
modEl = $W; modEl = $W;
break; break;
} }
@ -52,11 +52,11 @@ const EventsUI = (($) => {
let el = this; let el = this;
const args = arguments; const args = arguments;
const tagName = typeof el !== undefined ? $(el).prop('tagName') : null; const tagName = typeof el !== undefined ? $(el).prop("tagName") : null;
switch (tagName) { switch (tagName) {
case 'HTML': case "HTML":
case 'BODY': case "BODY":
el = $W; el = $W;
break; break;
} }

View File

@ -1,16 +1,16 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from './_events'; import Events from "./_events";
const LayoutUI = (($) => { const LayoutUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'LayoutUI'; const NAME = "LayoutUI";
const datepickerOptions = { const datepickerOptions = {
autoclose: true, autoclose: true,
@ -30,7 +30,7 @@ const LayoutUI = (($) => {
// Custom fonts // Custom fonts
$Body.append( $Body.append(
'<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,400i,700,700i&display=swap" rel="stylesheet">', '<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,400i,700,700i&display=swap" rel="stylesheet">'
); );
/*google analytics */ /*google analytics */
@ -40,7 +40,6 @@ const LayoutUI = (($) => {
ga('send', 'pageview'); ga('send', 'pageview');
});*/ });*/
// Fire further js when layout is ready // Fire further js when layout is ready
$(W).trigger(Events.LODEDANDREADY); $(W).trigger(Events.LODEDANDREADY);
} }

View File

@ -1,20 +1,20 @@
'use strict'; "use strict";
import $ from 'jquery'; import $ from "jquery";
import Events from './_events'; import Events from "./_events";
import Consts from './_consts'; import Consts from "./_consts";
import EventsRouter from './_events.router'; import EventsRouter from "./_events.router";
import Spinner from './_components/_ui.spinner'; import Spinner from "./_components/_ui.spinner";
// AJAX functionality // AJAX functionality
import AjaxUI from './_components/_ui.ajax'; import AjaxUI from "./_components/_ui.ajax";
import FormBasics from './_components/_ui.form.basics'; import FormBasics from "./_components/_ui.form.basics";
import HeaderUI from './_components/_ui.header-footer'; import HeaderUI from "./_components/_ui.header-footer";
import SmoothScroll from 'smooth-scroll'; import SmoothScroll from "smooth-scroll";
const smoothScroll = SmoothScroll(); const smoothScroll = SmoothScroll();
const MainUI = (($) => { const MainUI = (($) => {
@ -22,68 +22,68 @@ const MainUI = (($) => {
const W = window; const W = window;
const $W = $(W); const $W = $(W);
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'MainUI'; const NAME = "MainUI";
console.clear(); console.clear();
console.info( console.info(
`%cUI Kit ${UINAME} ${UIVERSION}`, `%cUI Kit ${UINAME} ${UIVERSION}`,
'color:yellow;font-size:14px', "color:yellow;font-size:14px"
); );
console.info( console.info(
`%c${UIMetaNAME} ${UIMetaVersion}`, `%c${UIMetaNAME} ${UIMetaVersion}`,
'color:yellow;font-size:12px', "color:yellow;font-size:12px"
); );
console.info( console.info(
`%chttps://github.com/a2nt/webpack-bootstrap-ui-kit by ${UIAUTHOR}`, `%chttps://github.com/a2nt/webpack-bootstrap-ui-kit by ${UIAUTHOR}`,
'color:yellow;font-size:10px', "color:yellow;font-size:10px"
); );
console.groupCollapsed('Events'); console.groupCollapsed("Events");
Object.keys(Events).forEach((k) => { Object.keys(Events).forEach((k) => {
console.info(`${k}: ${Events[k]}`); console.info(`${k}: ${Events[k]}`);
}); });
console.groupEnd('Events'); console.groupEnd("Events");
console.groupCollapsed('Consts'); console.groupCollapsed("Consts");
Object.keys(Consts).forEach((k) => { Object.keys(Consts).forEach((k) => {
console.info(`${k}: ${Consts[k]}`); console.info(`${k}: ${Consts[k]}`);
}); });
console.groupEnd('Events'); console.groupEnd("Events");
console.groupCollapsed('Init'); console.groupCollapsed("Init");
console.time('init'); console.time("init");
$W.on(`${Events.LODEDANDREADY}`, () => { $W.on(`${Events.LODEDANDREADY}`, () => {
console.groupEnd('Init'); console.groupEnd("Init");
console.timeEnd('init'); console.timeEnd("init");
console.time('Post-init'); console.time("Post-init");
console.groupCollapsed('Post-init'); console.groupCollapsed("Post-init");
}); });
// get browser locale // get browser locale
//const Locale = $('html').attr('lang').substring(0, 2); //const Locale = $('html').attr('lang').substring(0, 2);
const $AlertNotify = $('#AlertNotify'); const $AlertNotify = $("#AlertNotify");
const $SiteWideMessage = $('#SiteWideMessage'); const $SiteWideMessage = $("#SiteWideMessage");
// get browser window visibility preferences // get browser window visibility preferences
// Opera 12.10, Firefox >=18, Chrome >=31, IE11 // Opera 12.10, Firefox >=18, Chrome >=31, IE11
const HiddenName = 'hidden'; const HiddenName = "hidden";
const VisibilityChangeEvent = 'visibilitychange'; const VisibilityChangeEvent = "visibilitychange";
// update visibility state // update visibility state
D.addEventListener(VisibilityChangeEvent, () => { D.addEventListener(VisibilityChangeEvent, () => {
if (D.visibilityState === HiddenName) { if (D.visibilityState === HiddenName) {
console.log(`${NAME}: Tab: hidden`); console.log(`${NAME}: Tab: hidden`);
$Body.addClass('is-hidden'); $Body.addClass("is-hidden");
$Body.trigger(Events.TABHIDDEN); $Body.trigger(Events.TABHIDDEN);
$W.trigger(Events.TABHIDDEN); $W.trigger(Events.TABHIDDEN);
} else { } else {
console.log(`${NAME}: Tab: focused`); console.log(`${NAME}: Tab: focused`);
$Body.removeClass('is-hidden'); $Body.removeClass("is-hidden");
$Body.trigger(Events.TABFOCUSED); $Body.trigger(Events.TABFOCUSED);
$W.trigger(Events.TABFOCUSED); $W.trigger(Events.TABFOCUSED);
} }
@ -93,7 +93,7 @@ const MainUI = (($) => {
let pingInterval; let pingInterval;
let pingLock = false; let pingLock = false;
const sessionPing = () => { const sessionPing = () => {
if (pingLock || $Body.hasClass('is-offline')) { if (pingLock || $Body.hasClass("is-offline")) {
return; return;
} }
@ -103,12 +103,12 @@ const MainUI = (($) => {
sync: false, sync: false,
async: true, async: true,
cache: false, cache: false,
url: '/Security/ping', url: "/Security/ping",
global: false, global: false,
type: 'POST', type: "POST",
complete: (data, datastatus) => { complete: (data, datastatus) => {
updateOnlineStatus(); updateOnlineStatus();
if (datastatus !== 'success') { if (datastatus !== "success") {
console.warn(`${NAME}: ping failed`); console.warn(`${NAME}: ping failed`);
clearInterval(pingInterval); clearInterval(pingInterval);
@ -128,7 +128,7 @@ const MainUI = (($) => {
} }
statusLock = true; statusLock = true;
if (typeof navigator.onLine === 'undefined') { if (typeof navigator.onLine === "undefined") {
return false; return false;
} }
@ -138,8 +138,8 @@ const MainUI = (($) => {
clearInterval(pingInterval); clearInterval(pingInterval);
pingInterval = null; pingInterval = null;
$Body.addClass('is-offline'); $Body.addClass("is-offline");
$Body.removeClass('is-online'); $Body.removeClass("is-online");
$Body.trigger(Events.OFFLINE); $Body.trigger(Events.OFFLINE);
$W.trigger(Events.OFFLINE); $W.trigger(Events.OFFLINE);
@ -152,7 +152,7 @@ const MainUI = (($) => {
pingInterval = setInterval(sessionPing, 300000); // 5 min in ms pingInterval = setInterval(sessionPing, 300000); // 5 min in ms
} }
if ($Body.hasClass('is-offline')) { if ($Body.hasClass("is-offline")) {
sessionPing(); sessionPing();
console.log(`${NAME}: is back online`); console.log(`${NAME}: is back online`);
@ -161,8 +161,8 @@ const MainUI = (($) => {
console.log(`${NAME}: Online`); console.log(`${NAME}: Online`);
} }
$Body.addClass('is-online'); $Body.addClass("is-online");
$Body.removeClass('is-offline'); $Body.removeClass("is-offline");
$Body.trigger(Events.ONLINE); $Body.trigger(Events.ONLINE);
$W.trigger(Events.ONLINE); $W.trigger(Events.ONLINE);
@ -176,7 +176,7 @@ const MainUI = (($) => {
() => { () => {
updateOnlineStatus(); updateOnlineStatus();
}, },
false, false
); );
W.addEventListener( W.addEventListener(
@ -184,7 +184,7 @@ const MainUI = (($) => {
() => { () => {
updateOnlineStatus(); updateOnlineStatus();
}, },
false, false
); );
$W.on(`${Events.LOADED} ${Events.AJAX}`, () => { $W.on(`${Events.LOADED} ${Events.AJAX}`, () => {
@ -204,9 +204,9 @@ const MainUI = (($) => {
}; };
W.URLDetails = { W.URLDetails = {
base: $('base').attr('href'), base: $("base").attr("href"),
relative: '/', relative: "/",
hash: '', hash: "",
}; };
let eventFired = false; let eventFired = false;
@ -236,7 +236,7 @@ const MainUI = (($) => {
}, 200); }, 200);
}; };
setTouchScreen('ontouchstart' in window || navigator.msMaxTouchPoints > 0); setTouchScreen("ontouchstart" in window || navigator.msMaxTouchPoints > 0);
// disable touch on mouse events // disable touch on mouse events
/*D.addEventListener('mousemove', () => { /*D.addEventListener('mousemove', () => {
@ -248,10 +248,10 @@ const MainUI = (($) => {
});*/ });*/
// enable touch screen on touch events // enable touch screen on touch events
D.addEventListener('touchmove', () => { D.addEventListener("touchmove", () => {
setTouchScreen(true); setTouchScreen(true);
}); });
D.addEventListener('touchstart', () => { D.addEventListener("touchstart", () => {
setTouchScreen(true); setTouchScreen(true);
}); });
@ -268,8 +268,8 @@ const MainUI = (($) => {
ui.updateLocation(); ui.updateLocation();
// mark available offline areas // mark available offline areas
if ('caches' in W) { if ("caches" in W) {
$('a.offline').addClass('offline-available'); $("a.offline").addClass("offline-available");
} }
ui.loadImages(); ui.loadImages();
@ -278,7 +278,7 @@ const MainUI = (($) => {
ui.detectBootstrapScreenSize(); ui.detectBootstrapScreenSize();
// mark external links // mark external links
$('a.external,a[rel="external"]').attr('target', '_blank'); $('a.external,a[rel="external"]').attr("target", "_blank");
// show encoded emails // show encoded emails
/*$(D).find('.obm').each(() => { /*$(D).find('.obm').each(() => {
@ -304,26 +304,26 @@ const MainUI = (($) => {
// //
// scroll links // scroll links
$('.js-scrollTo').on('click', (e) => { $(".js-scrollTo").on("click", (e) => {
console.log(`${NAME}: .js-scrollTo`); console.log(`${NAME}: .js-scrollTo`);
e.preventDefault(); e.preventDefault();
const el = e.currentTarget; const el = e.currentTarget;
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
ScrollTo(el, $el.attr('data-target')); ScrollTo(el, $el.attr("data-target"));
}); });
// load external fonts // load external fonts
if ($('[data-extfont]').length) { if ($("[data-extfont]").length) {
console.log(`${NAME}: loading external fonts [data-extfont]`); console.log(`${NAME}: loading external fonts [data-extfont]`);
$.getScript( $.getScript(
'//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js', "//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js",
() => { () => {
const fonts = []; const fonts = [];
$('[data-extfont]').each((i, el) => { $("[data-extfont]").each((i, el) => {
fonts[i] = $(el).attr('data-extfont'); fonts[i] = $(el).attr("data-extfont");
}); });
W.WebFont.load({ W.WebFont.load({
@ -331,16 +331,16 @@ const MainUI = (($) => {
families: fonts, families: fonts,
}, },
}); });
}, }
); );
} }
// data-set links // data-set links
$('[data-set-target]').on('click', (e) => { $("[data-set-target]").on("click", (e) => {
console.log(`${NAME}: [data-set-target]`); console.log(`${NAME}: [data-set-target]`);
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const $target = $($el.data('set-target')); const $target = $($el.data("set-target"));
if (!$target.length) { if (!$target.length) {
return; return;
@ -348,25 +348,25 @@ const MainUI = (($) => {
$target.each((i, targetEl) => { $target.each((i, targetEl) => {
const $targetEl = $(targetEl); const $targetEl = $(targetEl);
const tag = $targetEl.prop('tagName').toLowerCase(); const tag = $targetEl.prop("tagName").toLowerCase();
if (tag === 'input' || tag === 'select') { if (tag === "input" || tag === "select") {
$targetEl.val($el.data('set-val')); $targetEl.val($el.data("set-val"));
} else if (!$targetEl.hasClass('field')) { } else if (!$targetEl.hasClass("field")) {
$targetEl.text($el.data('set-val')); $targetEl.text($el.data("set-val"));
} }
}); });
$el.trigger(Events.SET_TARGET_UPDATE); $el.trigger(Events.SET_TARGET_UPDATE);
$target.closest('form').trigger(Events.SET_TARGET_UPDATE); $target.closest("form").trigger(Events.SET_TARGET_UPDATE);
}); });
// emulate links // emulate links
$('.a[data-href]').on('click', (e) => { $(".a[data-href]").on("click", (e) => {
console.log(`${NAME}: js link processing .a[data-href]`); console.log(`${NAME}: js link processing .a[data-href]`);
const $el = $(e.currentTarget); const $el = $(e.currentTarget);
const href = $el.data('href'); const href = $el.data("href");
if (!href.length) { if (!href.length) {
console.warn(`${NAME}: .a[data-href] | Missing data-href`); console.warn(`${NAME}: .a[data-href] | Missing data-href`);
console.warn($el); console.warn($el);
@ -376,24 +376,24 @@ const MainUI = (($) => {
}); });
// set attributes for mobile friendly tables // set attributes for mobile friendly tables
$('.typography table').each((i, el) => { $(".typography table").each((i, el) => {
const $table = $(el); const $table = $(el);
let $header = $table.find('thead tr:first-child'); let $header = $table.find("thead tr:first-child");
if (!$header.length) { if (!$header.length) {
$header = $(el).find('tr:first-child'); $header = $(el).find("tr:first-child");
} }
$header.addClass('d-typography-breakpoint-none'); $header.addClass("d-typography-breakpoint-none");
$header.find('td').each((i, h) => { $header.find("td").each((i, h) => {
const $h = $(h); const $h = $(h);
$table $table
.find('tr') .find("tr")
.find(`td:eq(${i})`) .find(`td:eq(${i})`)
.each((i, el) => { .each((i, el) => {
const $el = $(el); const $el = $(el);
if (!$el.attr('data-label')) { if (!$el.attr("data-label")) {
$el.attr('data-label', $h.text()); $el.attr("data-label", $h.text());
} }
}); });
}); });
@ -402,16 +402,16 @@ const MainUI = (($) => {
// hide spinner // hide spinner
Spinner.hide(() => { Spinner.hide(() => {
$Body.addClass('loaded'); $Body.addClass("loaded");
}); });
// fire page printing // fire page printing
if (W.URLDetails['hash'].indexOf('printpage') > -1) { if (W.URLDetails["hash"].indexOf("printpage") > -1) {
W.print(); W.print();
} }
$Body.data(NAME, ui); $Body.data(NAME, ui);
$W.removeClass('lock-main-init'); $W.removeClass("lock-main-init");
} }
static detectBootstrapScreenSize() { static detectBootstrapScreenSize() {
@ -425,7 +425,7 @@ const MainUI = (($) => {
for (let i = 0; i < envs.length; ++i) { for (let i = 0; i < envs.length; ++i) {
const env = envs[i]; const env = envs[i];
$el.addClass(`d-${env}-none`); $el.addClass(`d-${env}-none`);
if ($el.is(':hidden')) { if ($el.is(":hidden")) {
curEnv = env; curEnv = env;
break; break;
} }
@ -437,17 +437,17 @@ const MainUI = (($) => {
let landscape = true; let landscape = true;
if ($W.width() > $W.height()) { if ($W.width() > $W.height()) {
$Body.removeClass('portrait'); $Body.removeClass("portrait");
$Body.addClass('landscape'); $Body.addClass("landscape");
} else { } else {
landscape = false; landscape = false;
$Body.removeClass('landscape'); $Body.removeClass("landscape");
$Body.addClass('portrait'); $Body.addClass("portrait");
} }
console.log( console.log(
`${NAME}: screen size detected ${curEnv} | landscape ${landscape}`, `${NAME}: screen size detected ${curEnv} | landscape ${landscape}`
); );
return curEnv; return curEnv;
@ -455,30 +455,30 @@ const MainUI = (($) => {
static updateLocation(url) { static updateLocation(url) {
let location = url || W.location.href; let location = url || W.location.href;
location = location.replace(W.URLDetails['base'], '/'); location = location.replace(W.URLDetails["base"], "/");
const hash = location.indexOf('#'); const hash = location.indexOf("#");
W.URLDetails.relative = location.split('#')[0]; W.URLDetails.relative = location.split("#")[0];
W.URLDetails.hash = W.URLDetails.hash =
hash >= 0 ? location.substr(location.indexOf('#')) : ''; hash >= 0 ? location.substr(location.indexOf("#")) : "";
} }
// show site-wide alert // show site-wide alert
static alert(msg, cls) { static alert(msg, cls) {
$SiteWideMessage.fadeOut('fast'); $SiteWideMessage.fadeOut("fast");
$SiteWideMessage.html( $SiteWideMessage.html(
`<div class="page-alert"><div class="alert alert-${cls}"><i class="close" data-dismiss="alert">&times;</i>${msg}</div></div>`, `<div class="page-alert"><div class="alert alert-${cls}"><i class="close" data-dismiss="alert">&times;</i>${msg}</div></div>`
); );
$SiteWideMessage.find('.page-alert').alert(); $SiteWideMessage.find(".page-alert").alert();
$SiteWideMessage.find('.close[data-dismiss="alert"]').click(() => { $SiteWideMessage.find('.close[data-dismiss="alert"]').click(() => {
$SiteWideMessage.fadeOut('slow', () => { $SiteWideMessage.fadeOut("slow", () => {
$SiteWideMessage.find('.page-alert').alert('close'); $SiteWideMessage.find(".page-alert").alert("close");
}); });
}); });
$SiteWideMessage.fadeIn('slow'); $SiteWideMessage.fadeIn("slow");
if ($AlertNotify.length) { if ($AlertNotify.length) {
$AlertNotify[0].play(); $AlertNotify[0].play();
@ -490,12 +490,12 @@ const MainUI = (($) => {
// hide site-wide alert // hide site-wide alert
static alertHide() { static alertHide() {
if ($SiteWideMessage.length !== 0) { if ($SiteWideMessage.length !== 0) {
$SiteWideMessage.fadeOut('slow', () => { $SiteWideMessage.fadeOut("slow", () => {
$SiteWideMessage.find('.alert').alert('close'); $SiteWideMessage.find(".alert").alert("close");
}); });
} }
if ($AlertNotify.length && typeof $AlertNotify[0].stop !== 'undefined') { if ($AlertNotify.length && typeof $AlertNotify[0].stop !== "undefined") {
$AlertNotify[0].stop(); $AlertNotify[0].stop();
} }
@ -504,17 +504,17 @@ const MainUI = (($) => {
// load all images // load all images
static loadImages() { static loadImages() {
const $imgs = $Body.find('img').not('.loaded'); const $imgs = $Body.find("img").not(".loaded");
const $imgUrls = []; const $imgUrls = [];
const $imgLazyUrls = []; const $imgLazyUrls = [];
// collect image details // collect image details
$imgs.each((i, el) => { $imgs.each((i, el) => {
const $el = $(el); const $el = $(el);
const src = $el.attr('src'); const src = $el.attr("src");
const lazySrc = $el.data('lazy-src'); const lazySrc = $el.data("lazy-src");
if ($el.hasClass('loaded')) { if ($el.hasClass("loaded")) {
return; return;
} }
@ -523,14 +523,14 @@ const MainUI = (($) => {
} }
if (lazySrc && lazySrc.length) { if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc); $imgLazyUrls.push(lazySrc);
$el.addClass('loading'); $el.addClass("loading");
AjaxUI.preload([lazySrc]).then(() => { AjaxUI.preload([lazySrc]).then(() => {
$el.attr('src', lazySrc); $el.attr("src", lazySrc);
$el.on(`${Events.LOADED}`, () => { $el.on(`${Events.LOADED}`, () => {
$el.addClass('loaded'); $el.addClass("loaded");
$el.removeClass('loading'); $el.removeClass("loading");
$el.trigger(`${Events.LAZYIMAGEREADY}`); $el.trigger(`${Events.LAZYIMAGEREADY}`);
}); });
@ -540,25 +540,25 @@ const MainUI = (($) => {
// load lazy backgrounds // load lazy backgrounds
$Body $Body
.find('[data-lazy-bg]') .find("[data-lazy-bg]")
.not('.loaded') .not(".loaded")
.each((i, el) => { .each((i, el) => {
const $el = $(el); const $el = $(el);
const lazySrc = $el.data('lazy-bg'); const lazySrc = $el.data("lazy-bg");
if ($el.hasClass('loaded')) { if ($el.hasClass("loaded")) {
return; return;
} }
if (lazySrc && lazySrc.length) { if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc); $imgLazyUrls.push(lazySrc);
$el.addClass('loading'); $el.addClass("loading");
AjaxUI.preload([lazySrc]).then(() => { AjaxUI.preload([lazySrc]).then(() => {
$el.css({ 'background-image': `url(${lazySrc})` }); $el.css({ "background-image": `url(${lazySrc})` });
$el.addClass('loaded'); $el.addClass("loaded");
$el.removeClass('loading'); $el.removeClass("loading");
$el.trigger(`${Events.LAZYIMAGEREADY}`); $el.trigger(`${Events.LAZYIMAGEREADY}`);
}); });
@ -567,25 +567,25 @@ const MainUI = (($) => {
// replace img src // replace img src
$Body $Body
.find('[data-src-replace]') .find("[data-src-replace]")
.not('.loaded') .not(".loaded")
.each((i, el) => { .each((i, el) => {
const $el = $(el); const $el = $(el);
const lazySrc = $el.data('src-replace'); const lazySrc = $el.data("src-replace");
if ($el.hasClass('loaded')) { if ($el.hasClass("loaded")) {
return; return;
} }
if (lazySrc && lazySrc.length) { if (lazySrc && lazySrc.length) {
$el.addClass('loaded'); $el.addClass("loaded");
$el.attr('src', lazySrc); $el.attr("src", lazySrc);
} }
}); });
// load defined images // load defined images
AjaxUI.preload($imgUrls).then(() => { AjaxUI.preload($imgUrls).then(() => {
$W.trigger('images-loaded'); $W.trigger("images-loaded");
// load lazy images // load lazy images
AjaxUI.preload($imgLazyUrls).then(() => { AjaxUI.preload($imgLazyUrls).then(() => {
@ -594,8 +594,8 @@ const MainUI = (($) => {
setTimeout(() => { setTimeout(() => {
$W.trigger(`${Events.LAZYIMAGESREADY}`); $W.trigger(`${Events.LAZYIMAGESREADY}`);
console.groupEnd('Post-init'); console.groupEnd("Post-init");
console.timeEnd('Post-init'); console.timeEnd("Post-init");
}, 100); }, 100);
}); });
}); });
@ -609,35 +609,35 @@ const MainUI = (($) => {
$W.on( $W.on(
`${Events.MAININIT} ${Events.AJAX} ${Events.AJAXMAIN} ${Events.LOADED}`, `${Events.MAININIT} ${Events.AJAX} ${Events.AJAXMAIN} ${Events.LOADED}`,
() => { () => {
if ($W.hasClass('lock-main-init')) { if ($W.hasClass("lock-main-init")) {
console.warn(`${NAME}: locked`); console.warn(`${NAME}: locked`);
return; return;
} }
$W.addClass('lock-main-init'); $W.addClass("lock-main-init");
MainUI.init(); MainUI.init();
}, }
); );
$W.on(`${Events.RESIZE}`, () => { $W.on(`${Events.RESIZE}`, () => {
MainUI.detectBootstrapScreenSize(); MainUI.detectBootstrapScreenSize();
}); });
$W.on('beforeunload unload', () => { $W.on("beforeunload unload", () => {
Spinner.show(() => { Spinner.show(() => {
$Body.removeClass('loaded'); $Body.removeClass("loaded");
}); });
}); });
// hide spinner on target _blank // hide spinner on target _blank
$('[target="_blank"],.external') $('[target="_blank"],.external')
.not('[data-toggle="lightbox"],[data-lightbox-gallery]') .not('[data-toggle="lightbox"],[data-lightbox-gallery]')
.on('click submit touch', (e) => { .on("click submit touch", (e) => {
console.log(`${NAME}: External link`); console.log(`${NAME}: External link`);
setTimeout(() => { setTimeout(() => {
Spinner.hide(() => { Spinner.hide(() => {
$Body.addClass('loaded'); $Body.addClass("loaded");
}); });
}, 1000); }, 1000);
}); });

View File

@ -1,10 +1,10 @@
'use strict'; "use strict";
//import $ from 'jquery'; //import $ from 'jquery';
import '../scss/app.scss'; import "../scss/app.scss";
import { Dropdown } from 'bootstrap'; import { Dropdown } from "bootstrap";
import Page from './_components/_page.jsx'; import Page from "./_components/_page.jsx";
//import 'hammerjs/hammer'; //import 'hammerjs/hammer';
//import 'jquery-hammerjs/jquery.hammer'; //import 'jquery-hammerjs/jquery.hammer';
@ -64,11 +64,11 @@ import 'bootstrap/js/dist/tab';*/
//import './_components/_ui.video.preview'; //import './_components/_ui.video.preview';
// Meta Lightbox // Meta Lightbox
import '@a2nt/meta-lightbox-react/src/js/app'; import "@a2nt/meta-lightbox-react/src/js/app";
const GraphPage = ReactDOM.render( const GraphPage = ReactDOM.render(
<Page />, <Page />,
document.getElementById('MainContent'), document.getElementById("MainContent")
); );
//import Confirmation from 'bootstrap-confirmation2/dist/bootstrap-confirmation'; //import Confirmation from 'bootstrap-confirmation2/dist/bootstrap-confirmation';
@ -90,8 +90,8 @@ function importAll(r) {
} }
const images = importAll( const images = importAll(
require.context('../img/', false, /\.(png|jpe?g|svg)$/), require.context("../img/", false, /\.(png|jpe?g|svg)$/)
); );
const fontAwesome = importAll( const fontAwesome = importAll(
require.context('font-awesome', false, /\.(otf|eot|svg|ttf|woff|woff2)$/), require.context("font-awesome", false, /\.(otf|eot|svg|ttf|woff|woff2)$/)
); );

View File

@ -5,11 +5,13 @@
export default { export default {
en: { en: {
jsSteppedForm: { jsSteppedForm: {
STEPCOUNTER: '<div class="steps-counter">Step <b class="current-step"></b> of <b class="total-steps"></b></div>', STEPCOUNTER:
STEPBUTTONS: '<div class="steps-buttons">' + '<div class="steps-counter">Step <b class="current-step"></b> of <b class="total-steps"></b></div>',
'<a href="#" class="step-ctrl step-prev"><i class="fas fa-chevron-left"></i> Prev</a>' + STEPBUTTONS:
' <a href="#" class="step-ctrl step-next">Next <i class="fas fa-chevron-right"></i></a>' + '<div class="steps-buttons">' +
'</div>', '<a href="#" class="step-ctrl step-prev"><i class="fas fa-chevron-left"></i> Prev</a>' +
' <a href="#" class="step-ctrl step-next">Next <i class="fas fa-chevron-right"></i></a>' +
"</div>",
}, },
}, },
}; };

View File

@ -16,21 +16,21 @@
"use strict"; "use strict";
// your page specific css // your page specific css
import '../scss/_types/PageTypeClassName.scss'; import "../scss/_types/PageTypeClassName.scss";
import $ from 'jquery'; import $ from "jquery";
import Events from '../_events'; import Events from "../_events";
// Mapbox API // Mapbox API
import '../_components/_ui.map.api'; import "../_components/_ui.map.api";
const PageTypeUI = (($) => { const PageTypeUI = (($) => {
// Constants // Constants
const W = window; const W = window;
const D = document; const D = document;
const $Body = $('body'); const $Body = $("body");
const NAME = 'PageTypeUI'; const NAME = "PageTypeUI";
class PageTypeUI { class PageTypeUI {
// Static methods // Static methods
@ -58,7 +58,6 @@ const PageTypeUI = (($) => {
}); });
return PageTypeUI; return PageTypeUI;
})($); })($);
export default PageTypeUI; export default PageTypeUI;

View File

@ -1,4 +1,4 @@
'use strict'; "use strict";
/*import $ from 'jquery'; /*import $ from 'jquery';
import '../_components/_ui.map.api'; import '../_components/_ui.map.api';

View File

@ -1,4 +1,4 @@
'use strict'; "use strict";
/*import $ from 'jquery'; /*import $ from 'jquery';
import Events from '../_events'; import Events from '../_events';

View File

@ -1,5 +1,5 @@
// src/mocks/browser.js // src/mocks/browser.js
import { setupWorker } from 'msw'; import { setupWorker } from "msw";
import { handlers } from './handlers'; import { handlers } from "./handlers";
// This configures a Service Worker with the given request handlers. // This configures a Service Worker with the given request handlers.
export const worker = setupWorker(...handlers); export const worker = setupWorker(...handlers);

View File

@ -1,5 +1,5 @@
// src/mocks/handlers.js // src/mocks/handlers.js
import { graphql } from 'msw'; import { graphql } from "msw";
export const handlers = [ export const handlers = [
// Handles a "Login" mutation // Handles a "Login" mutation
@ -15,7 +15,7 @@ export const handlers = [
); );
}),*/ }),*/
// Handles a "Pages" query // Handles a "Pages" query
graphql.query('Pages11', (req, res, ctx) => { graphql.query("Pages11", (req, res, ctx) => {
const apiKey = req.headers.map.apikey; const apiKey = req.headers.map.apikey;
if ( if (
!req.headers.map.apikey || !req.headers.map.apikey ||
@ -25,10 +25,10 @@ export const handlers = [
return res( return res(
ctx.errors([ ctx.errors([
{ {
message: 'Not authenticated', message: "Not authenticated",
errorType: 'AuthenticationError', errorType: "AuthenticationError",
}, },
]), ])
); );
} }
// When authenticated, respond with a query payload // When authenticated, respond with a query payload
@ -38,38 +38,38 @@ export const handlers = [
edges: [ edges: [
{ {
node: { node: {
ID: '1', ID: "1",
Title: 'Home-Mocked', Title: "Home-Mocked",
ClassName: 'Site\\Pages\\HomePage', ClassName: "Site\\Pages\\HomePage",
CSSClass: 'Site-Pages-HomePage', CSSClass: "Site-Pages-HomePage",
Summary: Summary:
"That's my personal website, I'm full-stack developer mostly specializing on SilverStipe backend projects and share some of my hobbies at this website.", "That's my personal website, I'm full-stack developer mostly specializing on SilverStipe backend projects and share some of my hobbies at this website.",
Link: '/en/', Link: "/en/",
URLSegment: 'home', URLSegment: "home",
Elements: { Elements: {
edges: [ edges: [
{ {
node: { node: {
ID: '3', ID: "3",
Title: 'Slider', Title: "Slider",
Render: Render:
'&lt;div\nid=&quot;e3&quot;\nclass=&quot;element site__elements__sliderelement\n\t\n\t&quot;\n&gt;\n\t&lt;div class=&quot;element-container container&quot;&gt;\n\t\t\n\n\n &lt;div id=&quot;Carousel3&quot; class=&quot;carousel slide js-carousel&quot;&gt;\n &lt;div class=&quot;carousel-inner&quot;&gt;\n \n &lt;div class=&quot;carousel-item carousel-item-Video carousel-item-nocontrols active&quot;&gt;\n &lt;div class=&quot;carousel-slide&quot;&gt;\n \n \n &lt;div class=&quot;video&quot;&gt;\n &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/IF1F_es1SaU?feature=oembed&amp;wmode=transparent&amp;enablejsapi=1&amp;disablekb=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;autoplay=1&amp;mute=1&amp;loop=1&amp;playlist=IF1F_es1SaU&quot; allow=&quot;autoplay&quot; allow=&quot;autoplay&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;\n &lt;/div&gt;\n \n\n\n\n\n &lt;/div&gt;\n &lt;/div&gt;\n \n &lt;/div&gt;\n &lt;/div&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n', "&lt;div\nid=&quot;e3&quot;\nclass=&quot;element site__elements__sliderelement\n\t\n\t&quot;\n&gt;\n\t&lt;div class=&quot;element-container container&quot;&gt;\n\t\t\n\n\n &lt;div id=&quot;Carousel3&quot; class=&quot;carousel slide js-carousel&quot;&gt;\n &lt;div class=&quot;carousel-inner&quot;&gt;\n \n &lt;div class=&quot;carousel-item carousel-item-Video carousel-item-nocontrols active&quot;&gt;\n &lt;div class=&quot;carousel-slide&quot;&gt;\n \n \n &lt;div class=&quot;video&quot;&gt;\n &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/IF1F_es1SaU?feature=oembed&amp;wmode=transparent&amp;enablejsapi=1&amp;disablekb=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;autoplay=1&amp;mute=1&amp;loop=1&amp;playlist=IF1F_es1SaU&quot; allow=&quot;autoplay&quot; allow=&quot;autoplay&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;\n &lt;/div&gt;\n \n\n\n\n\n &lt;/div&gt;\n &lt;/div&gt;\n \n &lt;/div&gt;\n &lt;/div&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n",
}, },
}, },
{ {
node: { node: {
ID: '7', ID: "7",
Title: 'Categories List', Title: "Categories List",
Render: Render:
'&lt;div\nid=&quot;e7&quot;\nclass=&quot;element dnadesign__elementallist__model__elementlist\n\t\n\t&quot;\n&gt;\n\t&lt;div class=&quot;element-container container&quot;&gt;\n\t\t\n&lt;div class=&quot;list-element__container row&quot; data-listelement-count=&quot;3&quot;&gt;\n \n \n\t &lt;div\nid=&quot;e9&quot;\nclass=&quot;element dynamic__elements__image__elements__elementimage\n\t\n\t col-block col-md&quot;\n&gt;\n\t&lt;div class=&quot;element-container&quot;&gt;\n\t\t\n &lt;div class=&quot;image-element__image height400 width400&quot;&gt;\n &lt;img\n src=&quot;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&quot;\n data-lazy-src=&quot;/assets/Uploads/ElementImage/1609765749853__FillWzQwMCw0MDBd.jpg&quot; class=&quot;img-responsive&quot; alt=&quot;Aquascaping&quot;\n /&gt;\n &lt;/div&gt;\n\n\n\n&lt;div class=&quot;image-element__caption img-content&quot;&gt;\n &lt;h3 class=&quot;image-element__title title&quot;&gt;Aquascaping&lt;/h3&gt;\n\n \n&lt;/div&gt;\n\n\n\n &lt;a href=&quot;/en/aquascaping/&quot; class=&quot;stretched-link&quot;&gt;\n &lt;b class=&quot;sr-only&quot;&gt;Aquascaping&lt;/b&gt;\n &lt;/a&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n\n \n\t &lt;div\nid=&quot;e10&quot;\nclass=&quot;element dynamic__elements__image__elements__elementimage\n\t\n\t col-block col-md&quot;\n&gt;\n\t&lt;div class=&quot;element-container&quot;&gt;\n\t\t\n &lt;div class=&quot;image-element__image height400 width400&quot;&gt;\n &lt;img\n src=&quot;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&quot;\n data-lazy-src=&quot;/assets/Uploads/ElementImage/1609766816754__FillWzQwMCw0MDBd.jpg&quot; class=&quot;img-responsive&quot; alt=&quot;Car Projects&quot;\n /&gt;\n &lt;/div&gt;\n\n\n\n&lt;div class=&quot;image-element__caption img-content&quot;&gt;\n &lt;h3 class=&quot;image-element__title title&quot;&gt;Car Projects&lt;/h3&gt;\n\n \n&lt;/div&gt;\n\n\n\n &lt;a href=&quot;/en/car/&quot; class=&quot;stretched-link&quot;&gt;\n &lt;b class=&quot;sr-only&quot;&gt;Car Projects&lt;/b&gt;\n &lt;/a&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n\n \n\t &lt;div\nid=&quot;e12&quot;\nclass=&quot;element dynamic__elements__image__elements__elementimage\n\t\n\t col-block col-md&quot;\n&gt;\n\t&lt;div class=&quot;element-container&quot;&gt;\n\t\t\n &lt;div class=&quot;image-element__image height400 width400&quot;&gt;\n &lt;img\n src=&quot;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&quot;\n data-lazy-src=&quot;/assets/Uploads/ElementImage/Screenshot-from-2021-01-04-20-30-19__FillWzQwMCw0MDBd.png&quot; class=&quot;img-responsive&quot; alt=&quot;Programming&quot;\n /&gt;\n &lt;/div&gt;\n\n\n\n&lt;div class=&quot;image-element__caption img-content&quot;&gt;\n &lt;h3 class=&quot;image-element__title title&quot;&gt;Programming&lt;/h3&gt;\n\n \n&lt;/div&gt;\n\n\n\n &lt;a href=&quot;/en/development/&quot; class=&quot;stretched-link&quot;&gt;\n &lt;b class=&quot;sr-only&quot;&gt;Programming&lt;/b&gt;\n &lt;/a&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n\n \n\n\n&lt;/div&gt;\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n', "&lt;div\nid=&quot;e7&quot;\nclass=&quot;element dnadesign__elementallist__model__elementlist\n\t\n\t&quot;\n&gt;\n\t&lt;div class=&quot;element-container container&quot;&gt;\n\t\t\n&lt;div class=&quot;list-element__container row&quot; data-listelement-count=&quot;3&quot;&gt;\n \n \n\t &lt;div\nid=&quot;e9&quot;\nclass=&quot;element dynamic__elements__image__elements__elementimage\n\t\n\t col-block col-md&quot;\n&gt;\n\t&lt;div class=&quot;element-container&quot;&gt;\n\t\t\n &lt;div class=&quot;image-element__image height400 width400&quot;&gt;\n &lt;img\n src=&quot;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&quot;\n data-lazy-src=&quot;/assets/Uploads/ElementImage/1609765749853__FillWzQwMCw0MDBd.jpg&quot; class=&quot;img-responsive&quot; alt=&quot;Aquascaping&quot;\n /&gt;\n &lt;/div&gt;\n\n\n\n&lt;div class=&quot;image-element__caption img-content&quot;&gt;\n &lt;h3 class=&quot;image-element__title title&quot;&gt;Aquascaping&lt;/h3&gt;\n\n \n&lt;/div&gt;\n\n\n\n &lt;a href=&quot;/en/aquascaping/&quot; class=&quot;stretched-link&quot;&gt;\n &lt;b class=&quot;sr-only&quot;&gt;Aquascaping&lt;/b&gt;\n &lt;/a&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n\n \n\t &lt;div\nid=&quot;e10&quot;\nclass=&quot;element dynamic__elements__image__elements__elementimage\n\t\n\t col-block col-md&quot;\n&gt;\n\t&lt;div class=&quot;element-container&quot;&gt;\n\t\t\n &lt;div class=&quot;image-element__image height400 width400&quot;&gt;\n &lt;img\n src=&quot;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&quot;\n data-lazy-src=&quot;/assets/Uploads/ElementImage/1609766816754__FillWzQwMCw0MDBd.jpg&quot; class=&quot;img-responsive&quot; alt=&quot;Car Projects&quot;\n /&gt;\n &lt;/div&gt;\n\n\n\n&lt;div class=&quot;image-element__caption img-content&quot;&gt;\n &lt;h3 class=&quot;image-element__title title&quot;&gt;Car Projects&lt;/h3&gt;\n\n \n&lt;/div&gt;\n\n\n\n &lt;a href=&quot;/en/car/&quot; class=&quot;stretched-link&quot;&gt;\n &lt;b class=&quot;sr-only&quot;&gt;Car Projects&lt;/b&gt;\n &lt;/a&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n\n \n\t &lt;div\nid=&quot;e12&quot;\nclass=&quot;element dynamic__elements__image__elements__elementimage\n\t\n\t col-block col-md&quot;\n&gt;\n\t&lt;div class=&quot;element-container&quot;&gt;\n\t\t\n &lt;div class=&quot;image-element__image height400 width400&quot;&gt;\n &lt;img\n src=&quot;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7&quot;\n data-lazy-src=&quot;/assets/Uploads/ElementImage/Screenshot-from-2021-01-04-20-30-19__FillWzQwMCw0MDBd.png&quot; class=&quot;img-responsive&quot; alt=&quot;Programming&quot;\n /&gt;\n &lt;/div&gt;\n\n\n\n&lt;div class=&quot;image-element__caption img-content&quot;&gt;\n &lt;h3 class=&quot;image-element__title title&quot;&gt;Programming&lt;/h3&gt;\n\n \n&lt;/div&gt;\n\n\n\n &lt;a href=&quot;/en/development/&quot; class=&quot;stretched-link&quot;&gt;\n &lt;b class=&quot;sr-only&quot;&gt;Programming&lt;/b&gt;\n &lt;/a&gt;\n\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n\n \n\n\n&lt;/div&gt;\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n",
}, },
}, },
{ {
node: { node: {
ID: '4', ID: "4",
Title: "Hello, I'm Tony Air", Title: "Hello, I'm Tony Air",
Render: Render:
'&lt;div\nid=&quot;e4&quot;\nclass=&quot;element dnadesign__elemental__models__elementcontent\n\t\n\t&quot;\n&gt;\n\t&lt;div class=&quot;element-container container&quot;&gt;\n\t\t&lt;div\nclass=&quot;content-element__content&quot;\n&gt;\n \n\t\n &lt;h2 class=&quot;content-element__title&quot;&gt;Hello, I&amp;#039;m Tony Air&lt;/h2&gt;\n \n\n &lt;div class=&quot;typography&quot;&gt;\n &lt;p&gt;That&#039;s my personal website, I&#039;m full-stack developer mostly specializing on SilverStipe backend projects and share some of my hobbies at this website.&lt;br&gt;&lt;br&gt;As for the things I do for work:&lt;br&gt;&lt;br&gt;Here&#039;s front-end UI kit:&amp;nbsp;&lt;a rel=&quot;noopener&quot; href=&quot;https://github.com/a2nt/webpack-bootstrap-ui-kit&quot; target=&quot;_blank&quot;&gt;https://github.com/a2nt/webpack-bootstrap-ui-kit&lt;/a&gt;&lt;br&gt;Here&#039;s SilverStipe quick start template:&amp;nbsp;&lt;a rel=&quot;noopener&quot; href=&quot;https://github.com/a2nt/silverstripe-webpack&quot; target=&quot;_blank&quot;&gt;https://github.com/a2nt/silverstripe-webpack&lt;/a&gt;&lt;br&gt;&lt;br&gt;More at my github:&amp;nbsp;&lt;a rel=&quot;noopener&quot; href=&quot;https://github.com/a2nt&quot; target=&quot;_blank&quot;&gt;https://github.com/a2nt&lt;/a&gt;&lt;/p&gt;\n &lt;/div&gt;\n\n \n&lt;/div&gt;\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n', "&lt;div\nid=&quot;e4&quot;\nclass=&quot;element dnadesign__elemental__models__elementcontent\n\t\n\t&quot;\n&gt;\n\t&lt;div class=&quot;element-container container&quot;&gt;\n\t\t&lt;div\nclass=&quot;content-element__content&quot;\n&gt;\n \n\t\n &lt;h2 class=&quot;content-element__title&quot;&gt;Hello, I&amp;#039;m Tony Air&lt;/h2&gt;\n \n\n &lt;div class=&quot;typography&quot;&gt;\n &lt;p&gt;That&#039;s my personal website, I&#039;m full-stack developer mostly specializing on SilverStipe backend projects and share some of my hobbies at this website.&lt;br&gt;&lt;br&gt;As for the things I do for work:&lt;br&gt;&lt;br&gt;Here&#039;s front-end UI kit:&amp;nbsp;&lt;a rel=&quot;noopener&quot; href=&quot;https://github.com/a2nt/webpack-bootstrap-ui-kit&quot; target=&quot;_blank&quot;&gt;https://github.com/a2nt/webpack-bootstrap-ui-kit&lt;/a&gt;&lt;br&gt;Here&#039;s SilverStipe quick start template:&amp;nbsp;&lt;a rel=&quot;noopener&quot; href=&quot;https://github.com/a2nt/silverstripe-webpack&quot; target=&quot;_blank&quot;&gt;https://github.com/a2nt/silverstripe-webpack&lt;/a&gt;&lt;br&gt;&lt;br&gt;More at my github:&amp;nbsp;&lt;a rel=&quot;noopener&quot; href=&quot;https://github.com/a2nt&quot; target=&quot;_blank&quot;&gt;https://github.com/a2nt&lt;/a&gt;&lt;/p&gt;\n &lt;/div&gt;\n\n \n&lt;/div&gt;\n\n\t&lt;/div&gt;\n&lt;/div&gt;\n",
}, },
}, },
], ],
@ -88,7 +88,7 @@ export const handlers = [
totalCount: 1, totalCount: 1,
}, },
}, },
}), })
); );
}), }),
]; ];

View File

@ -1,5 +1,5 @@
// src/mocks/server.js // src/mocks/server.js
import { setupServer } from 'msw/node'; import { setupServer } from "msw/node";
import { handlers } from './handlers'; import { handlers } from "./handlers";
// This configures a request mocking server with the given request handlers. // This configures a request mocking server with the given request handlers.
export const server = setupServer(...handlers); export const server = setupServer(...handlers);

View File

@ -29,8 +29,7 @@ $grays: map-merge(
"700": $gray-700, "700": $gray-700,
"800": $gray-800, "800": $gray-800,
"900": $gray-900, "900": $gray-900,
), ), $grays
$grays
) !default; ) !default;
$blue: $clr-blue !default; $blue: $clr-blue !default;
@ -62,8 +61,7 @@ $colors: map-merge(
"white": $white, "white": $white,
"gray": $gray-600, "gray": $gray-600,
"gray-dark": $gray-800, "gray-dark": $gray-800,
), ), $colors
$colors
) !default; ) !default;
$primary: $blue !default; $primary: $blue !default;
@ -88,8 +86,7 @@ $theme-colors: map-merge(
"danger": $danger, "danger": $danger,
"light": $light, "light": $light,
"dark": $dark, "dark": $dark,
), ), $theme-colors
$theme-colors
) !default; ) !default;
// UI color variables // UI color variables

View File

@ -1,84 +1,84 @@
<h2>Test <b>HTML</b>-content with PAJAX response</h2> <h2>Test <b>HTML</b>-content with PAJAX response</h2>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
https://twitter.com/reactjs/status/964689022747475968 https://twitter.com/reactjs/status/964689022747475968
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>
<p> <p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
1500s, when an unknown printer took a galley of type and scrambled it to when an unknown printer took a galley of type and scrambled it to make a type
make a type specimen book. It has survived not only five centuries, but also specimen book. It has survived not only five centuries, but also the leap into
the leap into electronic typesetting, remaining essentially unchanged. It electronic typesetting, remaining essentially unchanged. It was popularised in
was popularised in the 1960s with the release of Letraset sheets containing the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
Lorem Ipsum passages, and more recently with desktop publishing software and more recently with desktop publishing software like Aldus PageMaker
like Aldus PageMaker including versions of Lorem Ipsum. including versions of Lorem Ipsum.
</p> </p>

View File

@ -1,4 +1,4 @@
{ {
"Title": "Test Title!", "Title": "Test Title!",
"Content": "Test <b>HTML</b>-content with JSON response" "Content": "Test <b>HTML</b>-content with JSON response"
} }