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",
"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": {

View File

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

6
dist/index.html vendored
View File

@ -1,4 +1,4 @@
<!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">
<a
href="https://www.google.com/chrome/browser/desktop/"
@ -8,8 +8,8 @@
experience, upgrade for free today.
</a>
</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>
cd ./webpack-bootstrap-ui-kit-quick-start.git
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
]
},
"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": [
{
"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.
*/
const INTEGRITY_CHECKSUM = 'f0a916b13c8acc2b526a03a6d26df85f'
const bypassHeaderName = 'x-msw-bypass'
const activeClientIds = new Set()
const INTEGRITY_CHECKSUM = "f0a916b13c8acc2b526a03a6d26df85f";
const bypassHeaderName = "x-msw-bypass";
const activeClientIds = new Set();
self.addEventListener('install', function () {
return self.skipWaiting()
})
self.addEventListener("install", function () {
return self.skipWaiting();
});
self.addEventListener('activate', async function (event) {
return self.clients.claim()
})
self.addEventListener("activate", async function (event) {
return self.clients.claim();
});
self.addEventListener('message', async function (event) {
const clientId = event.source.id
self.addEventListener("message", async function (event) {
const clientId = event.source.id;
if (!clientId || !self.clients) {
return
return;
}
const client = await self.clients.get(clientId)
const client = await self.clients.get(clientId);
if (!client) {
return
return;
}
const allClients = await self.clients.matchAll()
const allClients = await self.clients.matchAll();
switch (event.data) {
case 'KEEPALIVE_REQUEST': {
case "KEEPALIVE_REQUEST": {
sendToClient(client, {
type: 'KEEPALIVE_RESPONSE',
})
break
type: "KEEPALIVE_RESPONSE",
});
break;
}
case 'INTEGRITY_CHECK_REQUEST': {
case "INTEGRITY_CHECK_REQUEST": {
sendToClient(client, {
type: 'INTEGRITY_CHECK_RESPONSE',
type: "INTEGRITY_CHECK_RESPONSE",
payload: INTEGRITY_CHECKSUM,
})
break
});
break;
}
case 'MOCK_ACTIVATE': {
activeClientIds.add(clientId)
case "MOCK_ACTIVATE": {
activeClientIds.add(clientId);
sendToClient(client, {
type: 'MOCKING_ENABLED',
type: "MOCKING_ENABLED",
payload: true,
})
break
});
break;
}
case 'MOCK_DEACTIVATE': {
activeClientIds.delete(clientId)
break
case "MOCK_DEACTIVATE": {
activeClientIds.delete(clientId);
break;
}
case 'CLIENT_CLOSED': {
activeClientIds.delete(clientId)
case "CLIENT_CLOSED": {
activeClientIds.delete(clientId);
const remainingClients = allClients.filter((client) => {
return client.id !== clientId
})
return client.id !== clientId;
});
// Unregister itself when there are no more clients
if (remainingClients.length === 0) {
self.registration.unregister()
self.registration.unregister();
}
break
break;
}
}
})
});
// Resolve the "master" client for the given event.
// Client that issues a request doesn't necessarily equal the client
// that registered the worker. It's with the latter the worker should
// communicate with during the response resolving phase.
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') {
return client
if (client.frameType === "top-level") {
return client;
}
const allClients = await self.clients.matchAll()
const allClients = await self.clients.matchAll();
return allClients
.filter((client) => {
// Get only those clients that are currently visible.
return client.visibilityState === 'visible'
return client.visibilityState === "visible";
})
.find((client) => {
// Find the client ID that's recorded in the
// set of clients that have registered the worker.
return activeClientIds.has(client.id)
})
return activeClientIds.has(client.id);
});
}
async function handleRequest(event, requestId) {
const client = await resolveMasterClient(event)
const response = await getResponse(event, client, requestId)
const client = await resolveMasterClient(event);
const response = await getResponse(event, client, requestId);
// Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) {
;(async function () {
const clonedResponse = response.clone()
(async function () {
const clonedResponse = response.clone();
sendToClient(client, {
type: 'RESPONSE',
type: "RESPONSE",
payload: {
requestId,
type: clonedResponse.type,
@ -131,21 +131,21 @@ async function handleRequest(event, requestId) {
headers: serializeHeaders(clonedResponse.headers),
redirected: clonedResponse.redirected,
},
})
})()
});
})();
}
return response
return response;
}
async function getResponse(event, client, requestId) {
const { request } = event
const requestClone = request.clone()
const getOriginalResponse = () => fetch(requestClone)
const { request } = event;
const requestClone = request.clone();
const getOriginalResponse = () => fetch(requestClone);
// Bypass mocking when the request client is not active.
if (!client) {
return getOriginalResponse()
return getOriginalResponse();
}
// 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
// and is not ready to handle requests.
if (!activeClientIds.has(client.id)) {
return await getOriginalResponse()
return await getOriginalResponse();
}
// Bypass requests with the explicit bypass header
if (requestClone.headers.get(bypassHeaderName) === 'true') {
const cleanRequestHeaders = serializeHeaders(requestClone.headers)
if (requestClone.headers.get(bypassHeaderName) === "true") {
const cleanRequestHeaders = serializeHeaders(requestClone.headers);
// Remove the bypass header to comply with the CORS preflight check.
delete cleanRequestHeaders[bypassHeaderName]
delete cleanRequestHeaders[bypassHeaderName];
const originalRequest = new Request(requestClone, {
headers: new Headers(cleanRequestHeaders),
})
});
return fetch(originalRequest)
return fetch(originalRequest);
}
// Send the request to the client-side MSW.
const reqHeaders = serializeHeaders(request.headers)
const body = await request.text()
const reqHeaders = serializeHeaders(request.headers);
const body = await request.text();
const clientMessage = await sendToClient(client, {
type: 'REQUEST',
type: "REQUEST",
payload: {
id: requestId,
url: request.url,
@ -193,31 +193,31 @@ async function getResponse(event, client, requestId) {
bodyUsed: request.bodyUsed,
keepalive: request.keepalive,
},
})
});
switch (clientMessage.type) {
case 'MOCK_SUCCESS': {
case "MOCK_SUCCESS": {
return delayPromise(
() => respondWithMock(clientMessage),
clientMessage.payload.delay,
)
clientMessage.payload.delay
);
}
case 'MOCK_NOT_FOUND': {
return getOriginalResponse()
case "MOCK_NOT_FOUND": {
return getOriginalResponse();
}
case 'NETWORK_ERROR': {
const { name, message } = clientMessage.payload
const networkError = new Error(message)
networkError.name = name
case "NETWORK_ERROR": {
const { name, message } = clientMessage.payload;
const networkError = new Error(message);
networkError.name = name;
// Rejecting a request Promise emulates a network error.
throw networkError
throw networkError;
}
case 'INTERNAL_ERROR': {
const parsedBody = JSON.parse(clientMessage.payload.body)
case "INTERNAL_ERROR": {
const parsedBody = JSON.parse(clientMessage.payload.body);
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\
`,
request.method,
request.url,
)
request.url
);
return respondWithMock(clientMessage)
return respondWithMock(clientMessage);
}
}
return getOriginalResponse()
return getOriginalResponse();
}
self.addEventListener('fetch', function (event) {
const { request } = event
const accept = request.headers.get('accept') || ''
self.addEventListener("fetch", function (event) {
const { request } = event;
const accept = request.headers.get("accept") || "";
// Bypass server-sent events.
if (accept.includes('text/event-stream')) {
return
if (accept.includes("text/event-stream")) {
return;
}
// Bypass navigation requests.
if (request.mode === 'navigate') {
return
if (request.mode === "navigate") {
return;
}
// Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests.
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
return
if (request.cache === "only-if-cached" && request.mode !== "same-origin") {
return;
}
// Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests
// after it's been deleted (still remains active until the next reload).
if (activeClientIds.size === 0) {
return
return;
}
const requestId = uuidv4()
const requestId = uuidv4();
return event.respondWith(
handleRequest(event, requestId).catch((error) => {
if (error.name === 'NetworkError') {
if (error.name === "NetworkError") {
console.warn(
'[MSW] Successfully emulated a network error for the "%s %s" request.',
request.method,
request.url,
)
return
request.url
);
return;
}
// 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.`,
request.method,
request.url,
`${error.name}: ${error.message}`,
)
}),
)
})
`${error.name}: ${error.message}`
);
})
);
});
function serializeHeaders(headers) {
const reqHeaders = {}
const reqHeaders = {};
headers.forEach((value, name) => {
reqHeaders[name] = reqHeaders[name]
? [].concat(reqHeaders[name]).concat(value)
: value
})
return reqHeaders
: value;
});
return reqHeaders;
}
function sendToClient(client, message) {
return new Promise((resolve, reject) => {
const channel = new MessageChannel()
const channel = new MessageChannel();
channel.port1.onmessage = (event) => {
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) {
return new Promise((resolve) => {
setTimeout(() => resolve(cb()), duration)
})
setTimeout(() => resolve(cb()), duration);
});
}
function respondWithMock(clientMessage) {
return new Response(clientMessage.payload.body, {
...clientMessage.payload,
headers: clientMessage.payload.headers,
})
});
}
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0
const v = c == 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0;
const v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}

View File

@ -1,64 +1,99 @@
<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="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">
<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
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
<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">
<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
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
<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">
<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
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
<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>

View File

@ -6,14 +6,16 @@
<li>
<p>Clone quick start repository</p>
<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>
<p>Install npm packages</p>
<pre>
cd ./webpack-bootstrap-ui-kit-quick-start.git
npm install
</pre>
</pre
>
</li>
<li>
<p>Edit ./src files</p>
@ -30,15 +32,19 @@ git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre>
<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.
<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>
@ -60,18 +66,16 @@ git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre>
</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.
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>
@ -82,17 +86,15 @@ git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre>
</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.
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>
@ -125,14 +127,14 @@ git clone https://github.com/a2nt/webpack-bootstrap-ui-kit-quick-start.git</pre>
</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.
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">

View File

@ -1,40 +1,62 @@
<h2 class="list-element__title">Content Header</h2>
<div class="typography">
Some content ...
</div>
<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 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" />
<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 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" />
<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 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" />
<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 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" />
<img
src="https://via.placeholder.com/300x300"
alt="Some kind image"
class="w-100"
/>
</div>
</div>
</div>

View File

@ -7,10 +7,10 @@
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-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">
@ -19,9 +19,13 @@
<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="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>
<a
href="https://www.google.com/maps/dir/Current+Location/40.8827743,-74.4276612"
target="_blank"
>Get Directions &raquo;</a
>
</div>
</div>
</div>
@ -29,9 +33,13 @@
<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="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>
<a
href="https://www.google.com/maps/dir/Current+Location/40.7884708,-74.0249253"
target="_blank"
>Get Directions &raquo;</a
>
</div>
</div>
</div>
@ -39,9 +47,13 @@
<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="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>
<a
href="https://www.google.com/maps/dir/Current+Location/40.8527479,-78.2475576"
target="_blank"
>Get Directions &raquo;</a
>
</div>
</div>
</div>
@ -49,9 +61,13 @@
<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="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>
<a
href="https://www.google.com/maps/dir/Current+Location/42.3297023,-72.5552186"
target="_blank"
>Get Directions &raquo;</a
>
</div>
</div>
</div>

View File

@ -1,18 +1,10 @@
<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 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>
@ -21,8 +13,7 @@
<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
Copyright &copy; 2019 - Tony Air (A2nt) Webpack Bootstrap 4 UI Kit
</div>
<nav class="footer-nav">
<ul class="list-inline d-flex">
@ -37,10 +28,7 @@
</div>
<div class="col-sm-4">
<div class="text-end credits footer__credits">
<a
href="https://github.com/a2nt"
target="_blank"
rel="nofollow"
<a href="https://github.com/a2nt" target="_blank" rel="nofollow"
><span>Developed by</span> Tony Air</a
>
</div>

View File

@ -17,18 +17,12 @@
<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"
<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"
<a class="nav-link js-scrollTo" href="#Slider" data-text="Slider"
>Slider</a
>
</li>
@ -43,7 +37,10 @@
</a>
<button
class="nav-link dropdown-toggle dropdown-toggle-sm dropdown-toggle-touch"
class="
nav-link
dropdown-toggle dropdown-toggle-sm dropdown-toggle-touch
"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
@ -54,9 +51,7 @@
<div class="dropdown-menu" aria-labelledby="NavbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a
class="dropdown-item js-scrollTo"
href="#AccordionList"
<a class="dropdown-item js-scrollTo" href="#AccordionList"
>Scroll to AccordionList</a
>
<div class="dropdown-divider"></div>
@ -74,10 +69,7 @@
</div>
</li>
<li class="nav-item">
<a
id="LoadGraphQL"
class="nav-link graphql-page"
href="/home"
<a id="LoadGraphQL" class="nav-link graphql-page" href="/home"
>Load GraphQL</a
>
</li>
@ -99,10 +91,7 @@
placeholder="Search"
aria-label="Search"
/>
<button
class="btn btn-outline-success my-2 my-sm-0"
type="submit"
>
<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>

View File

@ -1,18 +1,35 @@
<!-- if $SlideShow -->
<div id="Carousel{$ID}" class="carousel slide js-carousel d-none d-sm-block" data-indicators="true" data-arrows="true">
<div
id="Carousel{$ID}"
class="carousel slide js-carousel d-none d-sm-block"
data-indicators="true"
data-arrows="true"
>
<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
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">
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn btn-default btn-lg"
>
<i class="fas fa-bars"></i>
Learn More
</a>
@ -23,15 +40,27 @@
<!-- /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
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">
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn btn-default btn-lg"
>
<i class="fas fa-bars"></i>
Learn More
</a>
@ -42,15 +71,27 @@
<!-- /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
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">
<a
href="$PageLink.Link"
title="$PageLink.MenuTitle.XML"
class="btn btn-default btn-lg"
>
<i class="fas fa-bars"></i>
Learn More
</a>

View File

@ -4,8 +4,8 @@
role="alert"
>
<div class="typography">
The Internet connection is missing right now, but you're able to
browse previously opened pages offline.
The Internet connection is missing right now, but you're able to browse
previously opened pages offline.
</div>
<button
type="button"

View File

@ -183,12 +183,7 @@
<div id="PageLoading">
<div class="loading-spinner">
<img
class="logo"
src="../../img/logo.svg"
width="200"
alt="UI Kit"
/><br />
<img class="logo" src="../../img/logo.svg" width="200" alt="UI Kit" /><br />
<div class="lds-ellipsis">
<div></div>
<div></div>

View File

@ -1,7 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<head>
<title>Webpack Bootstrap 4 UI Demo</title>
<%= require('html-loader!./html/Head.html').default %>
<meta name="ping" content="/Security/ping" />
@ -9,15 +8,13 @@
<meta name="api_static_domain" content="<%= STATIC_URL %>" />
<meta name="swversion" content="<%= SWVERSION %>" />
<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">
<%= require('html-loader!./html/_components/LoadingSpinner.html').default %>
<%= require('html-loader!./html/_components/Alerts.html').default %>
<%=
require('html-loader!./html/First.html').default %>
<%=
<%= require('html-loader!./html/_components/LoadingSpinner.html').default
%> <%= require('html-loader!./html/_components/Alerts.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/Navigation.html').default %>
@ -26,9 +23,7 @@
<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>
<h1 class="page-header">Webpack Bootstrap 4 UI Demo</h1>
</div>
</div>
<!-- Slider -->
@ -39,12 +34,13 @@
</section>
<!-- /Slider -->
<!-- Lightbox -->
<section id="Lightbox" class="element dnadesign__elemental__models__elementcontent">
<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>
<h2 class="content-element__title">Lightbox Demo</h2>
<%=
require('html-loader!../node_modules/@a2nt/meta-lightbox-js/src/html/meta-lightbox.html').default
%>
@ -53,16 +49,20 @@
</section>
<!-- /Lightbox -->
<!-- Content -->
<section id="Content" class="element dnadesign__elemental__models__elementcontent">
<section
id="Content"
class="element dnadesign__elemental__models__elementcontent"
>
<div class="element-container container">
<%=
require('html-loader!./html/Elements/Content.html').default
%>
<%= require('html-loader!./html/Elements/Content.html').default %>
</div>
</section>
<!-- /Content -->
<!-- List -->
<section id="List" class="element dnadesign__elementallist__model__elementlist bg-dark">
<section
id="List"
class="element dnadesign__elementallist__model__elementlist bg-dark"
>
<div class="element-container container">
<%=
require('html-loader!./html/Elements/ElementsList.html').default
@ -73,8 +73,7 @@
<!-- Accordion List -->
<section id="AccordionList" class="element site__elements__accordion">
<div class="element-container container">
<%=
require('html-loader!./html/Elements/Accordion.html').default
<%= require('html-loader!./html/Elements/Accordion.html').default
%>
</div>
</section>
@ -82,8 +81,7 @@
<!-- Map Element -->
<section id="MapElement" class="element site__elements__mapelement">
<div class="element-container container">
<%= require('html-loader!./html/Elements/Map.html').default
%>
<%= require('html-loader!./html/Elements/Map.html').default %>
</div>
</section>
<!-- /Map Element -->
@ -94,8 +92,6 @@
<%= require('html-loader!./html/Footer.html').default %>
</footer>
<!-- React is required -->
<%= REACT_SCRIPTS %>
<%= require('html-loader!./html/Last.html').default %>
</body>
<%= REACT_SCRIPTS %> <%= require('html-loader!./html/Last.html').default %>
</body>
</html>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,26 +1,22 @@
// browser tab visibility state detection
import Events from '../_events';
import Consts from '../_consts';
import Page from './models/page.jsx';
import Events from "../_events";
import Consts from "../_consts";
import Page from "./models/page.jsx";
import {
getParents,
} from '../main/funcs';
import { getParents } from "../main/funcs";
import {
Collapse,
} from 'bootstrap';
import { Collapse } from "bootstrap";
import SpinnerUI from '../main/loading-spinner';
import SpinnerUI from "../main/loading-spinner";
const MainUILinks = ((W) => {
const NAME = 'main.links';
const NAME = "main.links";
const D = document;
const BODY = D.body;
class MainUILinks {
window
window;
static init() {
const ui = this;
ui.GraphPage = null;
@ -30,7 +26,7 @@ const MainUILinks = ((W) => {
ui.loaded();
// history state switch
W.addEventListener('popstate', (e) => {
W.addEventListener("popstate", (e) => {
ui.popState(e);
});
}
@ -38,21 +34,19 @@ const MainUILinks = ((W) => {
static loaded() {
const ui = this;
D.querySelectorAll('.graphql-page').forEach((el, i) => {
const el_id = el.getAttribute('href');
D.querySelectorAll(".graphql-page").forEach((el, i) => {
const el_id = el.getAttribute("href");
el.setAttribute(`data-${ui.name}-id`, el_id);
el.addEventListener('click', ui.loadClick);
el.addEventListener("click", ui.loadClick);
});
}
static setActiveLinks(link) {
const ui = this;
D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach(
(el) => {
el.classList.add('active');
},
);
D.querySelectorAll(`[data-${ui.name}-id="${link}"]`).forEach((el) => {
el.classList.add("active");
});
}
static reset() {
@ -60,8 +54,8 @@ const MainUILinks = ((W) => {
D.activeElement.blur();
// remove active and loading classes
D.querySelectorAll('.graphql-page,.nav-item').forEach((el2) => {
el2.classList.remove('active', 'loading');
D.querySelectorAll(".graphql-page,.nav-item").forEach((el2) => {
el2.classList.remove("active", "loading");
});
}
@ -82,12 +76,12 @@ const MainUILinks = ((W) => {
if (!ui.GraphPage) {
console.log(
`${NAME}: [popstate] GraphPage is missing. Have to render it first`,
`${NAME}: [popstate] GraphPage is missing. Have to render it first`
);
ui.GraphPage = ReactDOM.render(
<Page />,
document.getElementById('MainContent'),
document.getElementById("MainContent")
);
}
@ -116,12 +110,12 @@ const MainUILinks = ((W) => {
SpinnerUI.show();
ui.reset();
el.classList.add('loading');
el.classList.remove('response-404', 'response-500', 'response-523');
BODY.classList.add('ajax-loading');
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');
const navs = getParents(el, ".collapse");
if (navs.length) {
navs.forEach((nav) => {
const collapseInst = Collapse.getInstance(nav);
@ -141,33 +135,33 @@ const MainUILinks = ((W) => {
if (!ui.GraphPage) {
ui.GraphPage = ReactDOM.render(
<Page />,
document.getElementById('MainContent'),
document.getElementById("MainContent")
);
}
const link = el.getAttribute('href') || el.getAttribute('data-href');
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');
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({
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.GraphPage.state.Link
);
ui.setActiveLinks(ui.GraphPage.state.Link)
ui.setActiveLinks(ui.GraphPage.state.Link);
}
SpinnerUI.hide();
@ -181,7 +175,7 @@ const MainUILinks = ((W) => {
/*BODY.classList.remove('ajax-loading');
el.classList.remove('loading');*/
el.classList.add('error', `response-${e.status}`);
el.classList.add("error", `response-${e.status}`);
/*switch (e.status) {
case 500:
break;

View File

@ -1,17 +1,11 @@
/*
* Lightbox window
*/
import {
Component
} from 'react';
import Events from '../../events';
import { Component } from "react";
import Events from "../../events";
import {
client
} from '../apollo/init';
import {
gql
} from '@apollo/client';
import { client } from "../apollo/init";
import { gql } from "@apollo/client";
class Page extends Component {
state = {
@ -22,7 +16,7 @@ class Page extends Component {
current: null,
ID: null,
URLSegment: null,
ClassName: 'Page',
ClassName: "Page",
CSSClass: null,
Title: null,
Summary: null,
@ -41,10 +35,10 @@ class Page extends Component {
if (ui.state.URL) {
window.history.pushState(
{
page: JSON.stringify(ui.state)
page: JSON.stringify(ui.state),
},
ui.state.Title,
ui.state.URL,
ui.state.URL
);
}
}
@ -122,12 +116,14 @@ class Page extends Component {
ui.reset();
ui.setState({
Title: 'Loading ...',
Title: "Loading ...",
loading: true,
});
console.log(client.readQuery({
query
}));
console.log(
client.readQuery({
query,
})
);
client
.query({
query: query,
@ -139,12 +135,14 @@ class Page extends Component {
client.writeQuery({
query,
data: {
resp
}
resp,
},
});
console.log(client.readQuery({
query
}));
console.log(
client.readQuery({
query,
})
);
ui.setState({
ID: page.ID,
@ -162,40 +160,40 @@ class Page extends Component {
.catch((error) => {
console.error(error);
let msg = '';
let msg = "";
if (error.response) {
switch (error.response.status) {
case 404:
msg = 'Not Found.';
msg = "Not Found.";
break;
case 500:
msg = 'Server issue, please try again latter.';
msg = "Server issue, please try again latter.";
break;
default:
msg = 'Something went wrong.';
msg = "Something went wrong.";
break;
}
} else if (error.request) {
msg = 'No response received';
msg = "No response received";
} else {
console.warn('Error', error.message);
console.warn("Error", error.message);
}
ui.setState({
error: msg
error: msg,
});
});
};
getHtml = (html) => {
const decodeHtmlEntity = (input) => {
var doc = new DOMParser().parseFromString(input, 'text/html');
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
};
return {
__html: decodeHtmlEntity(html)
__html: decodeHtmlEntity(html),
};
};
@ -208,7 +206,7 @@ class Page extends Component {
<div dangerouslySetInnerHTML={props.html}></div>
);
let html = '';
let html = "";
if (ui.state.Elements.length) {
ui.state.Elements.map((el) => {
html += el.node.Render;

View File

@ -1,20 +1,11 @@
/*
* page #MainContent area
*/
import {
Component
} from 'react';
import { Component } from "react";
import {
useQuery,
gql
} from '@apollo/client';
import {
client
} from '../apollo/init';
import {
cache
} from '../apollo/cache';
import { useQuery, gql } from "@apollo/client";
import { client } from "../apollo/init";
import { cache } from "../apollo/cache";
const D = document;
const BODY = document.body;
@ -23,13 +14,13 @@ class Page extends Component {
state = {
type: [],
shown: false,
Title: 'Loading ...',
Title: "Loading ...",
loading: true,
error: false,
current: null,
ID: null,
URLSegment: null,
ClassName: 'Page',
ClassName: "Page",
CSSClass: null,
Summary: null,
Link: null,
@ -59,7 +50,7 @@ class Page extends Component {
}
isOnline = () => {
return BODY.classList.contains('is-online');
return BODY.classList.contains("is-online");
};
load = (link) => {
@ -87,7 +78,7 @@ class Page extends Component {
if (!ui.isOnline()) {
const data = client.readQuery({
query
query,
});
if (data && ui.processResponse(data)) {
@ -98,15 +89,15 @@ class Page extends Component {
ui.setState(
Object.assign(ui.empty_state, {
Title: 'Offline',
CSSClass: 'graphql__status-523',
Title: "Offline",
CSSClass: "graphql__status-523",
Summary: "You're Offline. The page is not available now.",
loading: false,
}),
})
);
reject({
status: 523
status: 523,
});
}
} else {
@ -117,14 +108,14 @@ class Page extends Component {
client
.query({
query: query,
fetchPolicy: ui.isOnline() ? 'no-cache' : 'cache-first',
fetchPolicy: ui.isOnline() ? "no-cache" : "cache-first",
})
.then((resp) => {
// write to cache
const data = resp.data;
client.writeQuery({
query,
data: data
data: data,
});
if (ui.processResponse(data)) {
@ -133,14 +124,14 @@ class Page extends Component {
} else {
console.log(`${ui.name}: not found`);
reject({
status: 404
status: 404,
});
}
})
.catch((error) => {
reject({
status: 500,
error: error
error: error,
});
});
}
@ -155,11 +146,11 @@ class Page extends Component {
ui.setState(
Object.assign(ui.empty_state, {
Title: 'Not Found',
CSSClass: 'graphql__status-404',
Summary: 'The page is not found.',
Title: "Not Found",
CSSClass: "graphql__status-404",
Summary: "The page is not found.",
loading: false,
}),
})
);
return false;
@ -184,12 +175,12 @@ class Page extends Component {
getHtml = (html) => {
const decodeHtmlEntity = (input) => {
var doc = new DOMParser().parseFromString(input, 'text/html');
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
};
return {
__html: decodeHtmlEntity(html)
__html: decodeHtmlEntity(html),
};
};
@ -202,7 +193,7 @@ class Page extends Component {
<div dangerouslySetInnerHTML={props.html}></div>
);
let html = '';
let html = "";
if (ui.state.HTML) {
console.log(`${ui.name}: HTML only`);
html = ui.state.HTML;
@ -217,7 +208,7 @@ class Page extends Component {
}
if (ui.state.loading) {
const spinner = D.getElementById('PageLoading');
const spinner = D.getElementById("PageLoading");
html = `<div class="loading">Loading ...</div>`;
}

View File

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

View File

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

View File

@ -1,5 +1,5 @@
function _gaLt(event) {
if (typeof ga !== 'function') {
if (typeof ga !== "function") {
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) */
while (
el &&
(typeof el.tagName == 'undefined' ||
el.tagName.toLowerCase() != 'a' ||
(typeof el.tagName == "undefined" ||
el.tagName.toLowerCase() != "a" ||
!el.href)
) {
el = el.parentNode;
@ -21,7 +21,7 @@ function _gaLt(event) {
if (link.indexOf(location.host) == -1 && !link.match(/^javascript:/i)) {
/* external link */
/* 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);
};
/* Is target set and not _(self|parent|top)? */
@ -31,12 +31,12 @@ function _gaLt(event) {
: false;
/* send event with callback */
ga(
'send',
'event',
'Outgoing Links',
"send",
"event",
"Outgoing Links",
link,
document.location.pathname + document.location.search,
{ hitCallback: hitBack(link, target) },
{ hitCallback: hitBack(link, target) }
);
/* Prevent standard click */
@ -49,13 +49,13 @@ function _gaLt(event) {
var w = window;
w.addEventListener
? w.addEventListener(
'load',
"load",
() => {
document.body.addEventListener('click', _gaLt, !1);
document.body.addEventListener("click", _gaLt, !1);
},
!1,
!1
)
: w.attachEvent &&
w.attachEvent('onload', () => {
document.body.attachEvent('onclick', _gaLt);
w.attachEvent("onload", () => {
document.body.attachEvent("onclick", _gaLt);
});

View File

@ -1,4 +1,4 @@
'use strict';
"use strict";
const Obj = {
init: () => {
@ -9,11 +9,9 @@ const Obj = {
ui.setMap(options.map);
ui.position = options.position;
ui.html =
(options.html ?
options.html :
'<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>'
);
ui.html = options.html
? options.html
: '<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>';
ui.divClass = options.divClass;
ui.align = options.align;
ui.isDebugMode = options.debug;
@ -21,7 +19,7 @@ const Obj = {
ui.onMouseOver = options.onMouseOver;
ui.isBoolean = (arg) => {
if (typeof arg === 'boolean') {
if (typeof arg === "boolean") {
return true;
} else {
return false;
@ -29,7 +27,7 @@ const Obj = {
};
ui.isNotUndefined = (arg) => {
if (typeof arg !== 'undefined') {
if (typeof arg !== "undefined") {
return true;
} else {
return false;
@ -45,7 +43,7 @@ const Obj = {
};
ui.isString = (arg) => {
if (typeof arg === 'string') {
if (typeof arg === "string") {
return true;
} else {
return false;
@ -53,7 +51,7 @@ const Obj = {
};
ui.isFunction = (arg) => {
if (typeof arg === 'function') {
if (typeof arg === "function") {
return true;
} else {
return false;
@ -64,8 +62,8 @@ const Obj = {
const ui = this;
// Create div element.
ui.div = document.createElement('div');
ui.div.style.position = 'absolute';
ui.div = document.createElement("div");
ui.div.style.position = "absolute";
// Validate and set custom div class
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 (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) {
ui.div.className = 'debug-mode';
ui.div.className = "debug-mode";
ui.div.innerHTML =
'<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>';
ui.div.setAttribute(
'style',
'position: absolute;' +
'border: 5px dashed red;' +
'height: 150px;' +
'width: 150px;' +
'display: flex;' +
'justify-content: center;' +
'align-items: center;'
"style",
"position: absolute;" +
"border: 5px dashed red;" +
"height: 150px;" +
"width: 150px;" +
"display: flex;" +
"justify-content: center;" +
"align-items: center;"
);
}
@ -101,14 +99,14 @@ const Obj = {
ui.getPanes().overlayMouseTarget.appendChild(ui.div);
// Add listeners to the element.
google.maps.event.addDomListener(ui.div, 'click', (event) => {
google.maps.event.trigger(ui, 'click');
google.maps.event.addDomListener(ui.div, "click", (event) => {
google.maps.event.trigger(ui, "click");
if (ui.isFunction(ui.onClick)) ui.onClick();
event.stopPropagation();
});
google.maps.event.addDomListener(ui.div, 'mouseover', (event) => {
google.maps.event.trigger(ui, 'mouseover');
google.maps.event.addDomListener(ui.div, "mouseover", (event) => {
google.maps.event.trigger(ui, "mouseover");
if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver();
event.stopPropagation();
});
@ -118,9 +116,9 @@ const Obj = {
const ui = this;
// Calculate position of div
var positionInPixels = ui.getProjection().fromLatLngToDivPixel(
new google.maps.LatLng(ui.position)
);
var positionInPixels = ui
.getProjection()
.fromLatLngToDivPixel(new google.maps.LatLng(ui.position));
// Align HTML overlay relative to original position
var divOffset = {
@ -128,40 +126,40 @@ const Obj = {
x: undefined,
};
switch (Array.isArray(ui.align) ? ui.align.join(' ') : '') {
case 'left top':
switch (Array.isArray(ui.align) ? ui.align.join(" ") : "") {
case "left top":
divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth;
break;
case 'left center':
case "left center":
divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth;
break;
case 'left bottom':
case "left bottom":
divOffset.y = 0;
divOffset.x = ui.div.offsetWidth;
break;
case 'center top':
case "center top":
divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth / 2;
break;
case 'center center':
case "center center":
divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth / 2;
break;
case 'center bottom':
case "center bottom":
divOffset.y = 0;
divOffset.x = ui.div.offsetWidth / 2;
break;
case 'right top':
case "right top":
divOffset.y = ui.div.offsetHeight;
divOffset.x = 0;
break;
case 'right center':
case "right center":
divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = 0;
break;
case 'right bottom':
case "right bottom":
divOffset.y = 0;
divOffset.x = 0;
break;
@ -171,8 +169,8 @@ const Obj = {
}
// Set position
ui.div.style.top = `${positionInPixels.y - divOffset.y }px`;
ui.div.style.left = `${positionInPixels.x - divOffset.x }px`;
ui.div.style.top = `${positionInPixels.y - divOffset.y}px`;
ui.div.style.left = `${positionInPixels.x - divOffset.x}px`;
}
getPosition() {
@ -194,6 +192,6 @@ const Obj = {
}
return GoogleMapsHtmlOverlay;
},
}
};
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 MarkerUI from './map.google.marker';
import Events from "../_events";
import MarkerUI from "./map.google.marker";
const GoogleMapsDriver = ((window) => {
class GoogleMapsDriver {
getName() {
return 'GoogleMapsDriver';
return "GoogleMapsDriver";
}
init(el, config = []) {
@ -22,8 +22,10 @@ const GoogleMapsDriver = ((window) => {
ui.googleApiLoaded();
};
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${config['key']}&callback=init${ui.getName()}`;
const script = document.createElement("script");
script.src = `https://maps.googleapis.com/maps/api/js?key=${
config["key"]
}&callback=init${ui.getName()}`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
@ -34,18 +36,22 @@ const GoogleMapsDriver = ((window) => {
const el = ui.el;
const config = ui.config;
const mapDiv = el.querySelector('.mapAPI-map');
const zoom = config['mapZoom'] && config['mapZoom'] !== '0' ? parseInt(config['mapZoom']) : 10;
const center = config['center'] && config['center'] !== ',' ?
{
lat: config['center'][1],
lng: config['center'][0],
} :
{
const mapDiv = el.querySelector(".mapAPI-map");
const zoom =
config["mapZoom"] && config["mapZoom"] !== "0"
? parseInt(config["mapZoom"])
: 10;
const center =
config["center"] && config["center"] !== ","
? {
lat: config["center"][1],
lng: config["center"][0],
}
: {
lat: 0,
lng: 0,
};
const style = config['style'] ? config['style'] : null;
const style = config["style"] ? config["style"] : null;
console.log(`${ui.getName()}: API is loaded`);
// init fontawesome icons
@ -60,27 +66,30 @@ const GoogleMapsDriver = ((window) => {
ui.default_zoom = zoom;
mapDiv.classList.add('mapboxgl-map');
mapDiv.classList.add("mapboxgl-map");
ui.popup = new ui.MarkerUI({
map: ui.map,
align: ['center', 'top'],
divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none',
html: '<div class="mapboxgl-popup-tip"></div><div class="mapboxgl-popup-content">' +
align: ["center", "top"],
divClass: "mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none",
html:
'<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="html"></div>' +
'</div>',
"</div>",
});
ui.popup.setMap(ui.map);
ui.geocoder = new google.maps.Geocoder();
ui.cluster = new MarkerClusterer(ui.map, null, {
styles: [{
styles: [
{
width: 30,
height: 30,
className: 'mapboxgl-cluster',
}],
className: "mapboxgl-cluster",
},
],
});
el.dispatchEvent(new Event(Events.MAPAPILOADED));
@ -97,11 +106,11 @@ const GoogleMapsDriver = ((window) => {
const marker = new ui.MarkerUI({
position: pos,
map: ui.map,
align: ['center', 'top'],
html: `<div class="mapboxgl-marker"><div id="Marker${config['id']}" data-id="${config['id']}" class="marker">${config['icon']}</div></div>`,
align: ["center", "top"],
html: `<div class="mapboxgl-marker"><div id="Marker${config["id"]}" data-id="${config["id"]}" class="marker">${config["icon"]}</div></div>`,
onClick: () => {
const el = document.querySelector(`#Marker${config['id']}`);
ui.showPopup(pos, config['content']);
const el = document.querySelector(`#Marker${config["id"]}`);
ui.showPopup(pos, config["content"]);
el.dispatchEvent(new Event(Events.MAPMARKERCLICK));
},
@ -118,38 +127,40 @@ const GoogleMapsDriver = ((window) => {
const ui = this;
const popup = ui.popup.getDiv();
if (ui.config['flyToMarker']) {
if (ui.config["flyToMarker"]) {
ui.map.setCenter(pos); // panTo
if (!ui.config['noZoom']) {
if (!ui.config["noZoom"]) {
ui.map.setZoom(18);
}
}
// keep it hidden to render content
popup.style.opacity = '0';
popup.classList.remove('d-none');
popup.style.opacity = "0";
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
.querySelector(".mapboxgl-popup-close-button")
.addEventListener("click", (e) => {
e.preventDefault();
ui.hidePopup();
});
// set position when content was rendered
ui.popup.setPosition(pos, ['center', 'top']);
ui.popup.setPosition(pos, ["center", "top"]);
// display popup
popup.style.opacity = '1';
popup.style['margin-top'] = '-1rem';
popup.style.opacity = "1";
popup.style["margin-top"] = "-1rem";
}
hidePopup() {
const ui = this;
const popup = ui.popup.getDiv();
popup.classList.add('d-none');
if (!ui.config['noRestoreBounds'] || ui.config['flyToBounds']) {
popup.classList.add("d-none");
if (!ui.config["noRestoreBounds"] || ui.config["flyToBounds"]) {
ui.restoreBounds();
}
@ -164,20 +175,20 @@ const GoogleMapsDriver = ((window) => {
address: addr,
},
(results, status) => {
if (status === 'OK') {
if (status === "OK") {
//results[0].geometry.location;
if (typeof callback === 'function') {
if (typeof callback === "function") {
callback(results);
}
return results;
} else {
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,
},
(results, status) => {
if (status === 'OK') {
if (status === "OK") {
//results[0].formatted_address;
if (typeof callback === 'function') {
if (typeof callback === "function") {
callback(results);
}
return results;
} else {
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) {
const ui = this;
const geojson = JSON.parse(config['geojson']);
const geojson = JSON.parse(config["geojson"]);
const firstMarker = geojson.features[0].geometry.coordinates;
//Map.setCenter(firstMarker);
const bounds = new google.maps.LatLngBounds();
@ -223,7 +234,7 @@ const GoogleMapsDriver = ((window) => {
id,
content,
icon: marker.icon,
flyToMarker: config['flyToMarker'],
flyToMarker: config["flyToMarker"],
});
bounds.extend({

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,20 +1,20 @@
// 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 BODY = D.body;
const SPINNER = D.getElementById('PageLoading');
const SPINNER = D.getElementById("PageLoading");
class SpinnerUI {
static show() {
console.log(`${NAME}: show`);
SPINNER.classList.remove('d-none');
SPINNER.classList.remove("d-none");
}
static 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 Consts from '../_consts';
import SpinnerUI from './loading-spinner';
import Events from "../_events";
import Consts from "../_consts";
import SpinnerUI from "./loading-spinner";
const MainUI = ((W) => {
const NAME = '_main';
const NAME = "_main";
const D = document;
const BODY = D.body;
console.info(
`%cUI Kit ${UINAME} ${UIVERSION}`,
'color:yellow;font-size:14px',
"color:yellow;font-size:14px"
);
console.info(
`%c${UIMetaNAME} ${UIMetaVersion}`,
'color:yellow;font-size:12px',
"color:yellow;font-size:12px"
);
console.info(
`%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.groupCollapsed('Events');
console.info(`%cENV: ${process.env.NODE_ENV}`, "color:green;font-size:10px");
console.groupCollapsed("Events");
Object.keys(Events).forEach((k) => {
console.info(`${k}: ${Events[k]}`);
});
console.groupEnd('Events');
console.groupEnd("Events");
console.groupCollapsed('Consts');
console.groupCollapsed("Consts");
Object.keys(Consts).forEach((k) => {
console.info(`${k}: ${Consts[k]}`);
});
console.groupEnd('Events');
console.groupEnd("Events");
console.groupCollapsed('Init');
console.time('init');
console.groupCollapsed("Init");
console.time("init");
class MainUI {
// first time the website initialization
@ -47,7 +47,7 @@ const MainUI = ((W) => {
landing: W.location.href,
},
D.title,
W.location.href,
W.location.href
);
//
@ -64,11 +64,11 @@ const MainUI = ((W) => {
W.addEventListener(`${Events.LOADED}`, () => {
MainUI.init();
BODY.classList.add('loaded');
BODY.classList.add("loaded");
SpinnerUI.hide();
console.groupEnd('init');
console.timeEnd('init');
console.groupEnd("init");
console.timeEnd("init");
W.dispatchEvent(new Event(Events.LODEDANDREADY));
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,3 @@
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();
/*import {
@ -9,11 +9,11 @@ const store = configure();
store.subscribe(() => console.log(store.getState()));
store.dispatch({
type: 'counter/incremented',
})
type: "counter/incremented",
});
store.dispatch({
type: 'counter/incremented',
})
type: "counter/incremented",
});
store.dispatch({
type: 'counter/decremented',
})
type: "counter/decremented",
});

View File

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

View File

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

View File

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

View File

@ -1,25 +1,25 @@
// caches polyfill because it is not added to native yet!
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 log = require('../libs/log');
var caches = require('../../../thirdparty/serviceworker-caches');
var log = require("../libs/log");
var caches = require("../../../thirdparty/serviceworker-caches");
if (debug) {
log('SW: debug is on');
log("SW: debug is on");
log(`SW: CACHE_NAME: ${CACHE_NAME}`);
//log(`SW: appDomain: ${appDomain}`);
//log(`SW: lang: ${lang}`);
}
if (typeof CACHE_NAME !== 'string') {
throw new Error('Cache Name cannot be empty');
if (typeof CACHE_NAME !== "string") {
throw new Error("Cache Name cannot be empty");
}
self.addEventListener('fetch', (event) => {
self.addEventListener("fetch", (event) => {
// skip non-get
if (event.request.method !== 'GET') {
if (event.request.method !== "GET") {
return;
}
@ -34,9 +34,9 @@ self.addEventListener('fetch', (event) => {
//Skip admin url's
if (
requestURL.pathname.indexOf('admin') >= 0 ||
requestURL.pathname.indexOf('Security') >= 0 ||
requestURL.pathname.indexOf('/dev') >= 0
requestURL.pathname.indexOf("admin") >= 0 ||
requestURL.pathname.indexOf("Security") >= 0 ||
requestURL.pathname.indexOf("/dev") >= 0
) {
log(`SW: skip admin ${event.request.url}`);
return;
@ -80,23 +80,23 @@ self.addEventListener('fetch', (event) => {
// when fetch times out or fails
.catch((err) => {
log('SW: fetch failed');
log("SW: fetch failed");
// Return the promise which
// resolves on a match in cache for the current request
// or rejects if no matches are found
return caches.match(cacheRequest);
}),
})
);
});
// Now we need to clean up resources in the previous versions
// of Service Worker scripts
self.addEventListener('activate', (event) => {
self.addEventListener("activate", (event) => {
log(`SW: activated: ${version}`);
// Destroy the cache
event.waitUntil(caches.delete(CACHE_NAME));
});
self.addEventListener('install', (e) => {
self.addEventListener("install", (e) => {
log(`SW: installing version: ${version}`);
});

View File

@ -1,8 +1,8 @@
import Events from '../_events';
import Carousel from 'bootstrap/js/src/carousel';
import Events from "../_events";
import Carousel from "bootstrap/js/src/carousel";
const CarouselUI = ((window) => {
const NAME = 'js-carousel';
const NAME = "js-carousel";
const init = () => {
console.log(`${NAME}: init`);
@ -11,53 +11,55 @@ const CarouselUI = ((window) => {
const carousel = new Carousel(el);
// create next/prev arrows
if (el.dataset.bsArrows) {
const next = document.createElement('button');
next.classList.add('carousel-control-next');
next.setAttribute('type', 'button');
next.setAttribute('aria-label', 'Next Slide');
next.setAttribute('data-bs-target', el.getAttribute('id'));
next.setAttribute('data-bs-slide', 'next');
next.addEventListener('click', (e) => {
const next = document.createElement("button");
next.classList.add("carousel-control-next");
next.setAttribute("type", "button");
next.setAttribute("aria-label", "Next Slide");
next.setAttribute("data-bs-target", el.getAttribute("id"));
next.setAttribute("data-bs-slide", "next");
next.addEventListener("click", (e) => {
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);
const prev = document.createElement('button');
prev.setAttribute('type', 'button');
prev.setAttribute('aria-label', 'Previous Slide');
prev.classList.add('carousel-control-prev');
prev.setAttribute('data-bs-target', el.getAttribute('id'));
prev.setAttribute('data-bs-slide', 'prev');
prev.addEventListener('click', (e) => {
const prev = document.createElement("button");
prev.setAttribute("type", "button");
prev.setAttribute("aria-label", "Previous Slide");
prev.classList.add("carousel-control-prev");
prev.setAttribute("data-bs-target", el.getAttribute("id"));
prev.setAttribute("data-bs-slide", "prev");
prev.addEventListener("click", (e) => {
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);
}
if (el.dataset.bsIndicators) {
const indicators = document.createElement('div');
indicators.classList.add('carousel-indicators');
const items = el.querySelectorAll('.carousel-item');
const indicators = document.createElement("div");
indicators.classList.add("carousel-indicators");
const items = el.querySelectorAll(".carousel-item");
let i = 0;
while (i < items.length) {
const ind = document.createElement('button');
ind.setAttribute('type', 'button');
ind.setAttribute('aria-label', `Slide to #${ i + 1}`);
const ind = document.createElement("button");
ind.setAttribute("type", "button");
ind.setAttribute("aria-label", `Slide to #${i + 1}`);
if (i == 0) {
ind.classList.add('active');
ind.classList.add("active");
}
ind.setAttribute('data-bs-target', el.getAttribute('id'));
ind.setAttribute('data-bs-slide-to', i);
ind.setAttribute("data-bs-target", el.getAttribute("id"));
ind.setAttribute("data-bs-slide-to", i);
ind.addEventListener('click', (e) => {
ind.addEventListener("click", (e) => {
const target = e.target;
carousel.to(target.getAttribute('data-bs-slide-to'));
indicators.querySelectorAll('.active').forEach((ind2) => {
ind2.classList.remove('active');
carousel.to(target.getAttribute("data-bs-slide-to"));
indicators.querySelectorAll(".active").forEach((ind2) => {
ind2.classList.remove("active");
});
target.classList.add('active');
target.classList.add("active");
});
indicators.appendChild(ind);
@ -65,15 +67,18 @@ const CarouselUI = ((window) => {
}
el.appendChild(indicators);
el.addEventListener('slide.bs.carousel', (e) => {
el.querySelectorAll('.carousel-indicators .active').forEach((ind2) => {
ind2.classList.remove('active');
});
el.querySelectorAll(`.carousel-indicators [data-bs-slide-to="${ e.to }"]`).forEach((ind2) => {
ind2.classList.add('active');
el.addEventListener("slide.bs.carousel", (e) => {
el.querySelectorAll(".carousel-indicators .active").forEach(
(ind2) => {
ind2.classList.remove("active");
}
);
el.querySelectorAll(
`.carousel-indicators [data-bs-slide-to="${e.to}"]`
).forEach((ind2) => {
ind2.classList.add("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
// so it isn't very stable implementation. You should have something for the fall-back.
import Events from '../_events';
import Consts from '../_consts';
import InstagramFeed from '@jsanahuja/instagramfeed/src/InstagramFeed';
import Events from "../_events";
import Consts from "../_consts";
import InstagramFeed from "@jsanahuja/instagramfeed/src/InstagramFeed";
export default ((window) => {
const NAME = 'js-instagramfeed';
const NAME = "js-instagramfeed";
const BODY = document.body;
const ig_media_preview = (base64data) => {
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),
p = t.slice(3).split(''),
p = t.slice(3).split(""),
o = t
.substring(0, 3)
.split('')
.split("")
.map((e) => {
return e.charCodeAt(0);
}),
c = atob(jpegtpl).split('');
c = atob(jpegtpl).split("");
c[162] = String.fromCharCode(o[1]);
c[160] = String.fromCharCode(o[2]);
return base64data ?
`data:image/jpeg;base64,${btoa(c.concat(p).join(''))}` :
null;
return base64data
? `data:image/jpeg;base64,${btoa(c.concat(p).join(""))}`
: null;
};
const loadFeed = () => {
@ -41,41 +41,39 @@ export default ((window) => {
el.classList.remove(`${NAME}-loaded`, `${NAME}-error`);
new InstagramFeed({
username: dataset['username'],
tag: dataset['tag'] || null,
display_profile: dataset['display-profile'],
display_biography: dataset['display-biography'],
display_gallery: dataset['display-gallery'],
display_captions: dataset['display-captions'],
cache_time: dataset['cache_time'] || 360,
items: dataset['items'] || 12,
username: dataset["username"],
tag: dataset["tag"] || null,
display_profile: dataset["display-profile"],
display_biography: dataset["display-biography"],
display_gallery: dataset["display-gallery"],
display_captions: dataset["display-captions"],
cache_time: dataset["cache_time"] || 360,
items: dataset["items"] || 12,
styling: false,
lazy_load: true,
callback: (data) => {
console.log(`${NAME}: data response received`);
const list = document.createElement('div');
list.classList.add(`${NAME}-list`, 'row');
const list = document.createElement("div");
list.classList.add(`${NAME}-list`, "row");
el.appendChild(list);
data['edge_owner_to_timeline_media']['edges'].forEach(
(el, i) => {
const item = el['node'];
const preview = ig_media_preview(item['media_preview']);
data["edge_owner_to_timeline_media"]["edges"].forEach((el, i) => {
const item = el["node"];
const preview = ig_media_preview(item["media_preview"]);
list.innerHTML +=
`<div class="a col ${NAME}-item"` +
` 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']}"` +
` 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"]}"` +
`style="background:url(${preview})" />` +
'</div>';
},
);
"</div>";
});
el.classList.remove(`${NAME}-loading`);
el.classList.add(`${NAME}-loaded`);
window.dispatchEvent(new Event('MetaWindowindow.initLinks'));
window.dispatchEvent(new Event("MetaWindowindow.initLinks"));
window.dispatchEvent(new Event(`${NAME}.loaded`));
},
on_error: (e) => {

View File

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

View File

@ -1,17 +1,17 @@
'use strict';
"use strict";
import $ from 'jquery';
import Events from '../_events';
import Spinner from './_ui.spinner';
import $ from "jquery";
import Events from "../_events";
import Spinner from "./_ui.spinner";
const AjaxUI = (($) => {
// Constants
const G = window;
const D = document;
const $Html = $('html');
const $Body = $('body');
const $Html = $("html");
const $Body = $("body");
const NAME = 'jsAjaxUI';
const NAME = "jsAjaxUI";
const DATA_KEY = NAME;
class AjaxUI {
@ -21,23 +21,23 @@ const AjaxUI = (($) => {
const $element = $(this._element);
$element.addClass(`${NAME}-active`);
$element.bind('click', function (e) {
$element.bind("click", function (e) {
e.preventDefault();
const $this = $(this);
$('.ajax').each(function () {
$(".ajax").each(function () {
const $this = $(this);
$this.removeClass('active');
$this.parents('.nav-item').removeClass('active');
$this.removeClass("active");
$this.parents(".nav-item").removeClass("active");
});
$this.addClass('loading');
$this.addClass("loading");
AjaxUI.load($this.attr('href'), () => {
$this.removeClass('loading');
$this.parents('.nav-item').addClass('active');
$this.addClass('active');
AjaxUI.load($this.attr("href"), () => {
$this.removeClass("loading");
$this.parents(".nav-item").addClass("active");
$this.addClass("active");
});
});
}
@ -46,14 +46,14 @@ const AjaxUI = (($) => {
static load(url, callback) {
// show spinner
Spinner.show(() => {
$Body.removeClass('loaded');
$Body.removeClass("loaded");
});
// update document location
G.MainUI.updateLocation(url);
const absoluteLocation =
G.URLDetails['base'] + G.URLDetails['relative'].substring(1);
G.URLDetails["base"] + G.URLDetails["relative"].substring(1);
if (absoluteLocation !== G.location.href) {
G.history.pushState(
{
@ -61,7 +61,7 @@ const AjaxUI = (($) => {
page: absoluteLocation,
},
document.title,
absoluteLocation,
absoluteLocation
);
}
@ -69,41 +69,41 @@ const AjaxUI = (($) => {
sync: false,
async: true,
url,
dataType: 'json',
method: 'GET',
dataType: "json",
method: "GET",
cache: false,
error(jqXHR) {
console.warn(`${NAME}: AJAX request failure: ${jqXHR.statusText}`);
G.location.href = url;
// google analytics
if (typeof G.ga === 'function') {
G.ga('send', 'event', 'error', 'AJAX ERROR', jqXHR.statusText);
if (typeof G.ga === "function") {
G.ga("send", "event", "error", "AJAX ERROR", jqXHR.statusText);
}
},
success(data, status, jqXHR) {
AjaxUI.process(data, jqXHR, callback);
// google analytics
if (typeof G.ga === 'function') {
G.ga('set', {
page: G.URLDetails['relative'] + G.URLDetails['hash'],
title: jqXHR.getResponseHeader('X-Title'),
if (typeof G.ga === "function") {
G.ga("set", {
page: G.URLDetails["relative"] + G.URLDetails["hash"],
title: jqXHR.getResponseHeader("X-Title"),
});
G.ga('send', 'pageview');
G.ga("send", "pageview");
}
},
});
}
static process(data, jqXHR, callback) {
const css = jqXHR.getResponseHeader('X-Include-CSS').split(',') || [];
const js = jqXHR.getResponseHeader('X-Include-JS').split(',') || [];
const css = jqXHR.getResponseHeader("X-Include-CSS").split(",") || [];
const js = jqXHR.getResponseHeader("X-Include-JS").split(",") || [];
// Replace HTML regions
if (typeof data.regions === 'object') {
if (typeof data.regions === "object") {
for (const key in data.regions) {
if (typeof data.regions[key] === 'string') {
if (typeof data.regions[key] === "string") {
AjaxUI.replaceRegion(data.regions[key], key);
}
}
@ -111,52 +111,52 @@ const AjaxUI = (($) => {
// remove already loaded scripts
$('link[type="text/css"]').each(function () {
const i = css.indexOf($(this).attr('href'));
const i = css.indexOf($(this).attr("href"));
if (i > -1) {
css.splice(i, 1);
} else if (!$Body.data('unload-blocked')) {
console.log(`${NAME}: Unloading | ${$(this).attr('href')}`);
} else if (!$Body.data("unload-blocked")) {
console.log(`${NAME}: Unloading | ${$(this).attr("href")}`);
$(this).remove();
}
});
$('script[type="text/javascript"]').each(function () {
const i = js.indexOf($(this).attr('src'));
const i = js.indexOf($(this).attr("src"));
if (i > -1) {
js.splice(i, 1);
} else if (!$Body.data('unload-blocked')) {
console.log(`${NAME}: Unloading | ${$(this).attr('src')}`);
} else if (!$Body.data("unload-blocked")) {
console.log(`${NAME}: Unloading | ${$(this).attr("src")}`);
$(this).remove();
}
});
// preload CSS
this.preload(css).then(() => {
const $head = $('head');
const $head = $("head");
css.forEach((el) => {
$head.append(
`<link rel="stylesheet" type="text/css" href="${el}" />`,
`<link rel="stylesheet" type="text/css" href="${el}" />`
);
});
// preload JS
this.preload(js, 'script').then(() => {
this.preload(js, "script").then(() => {
js.forEach((el) => {
$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!`);
// trigger events
if (typeof data.events === 'object') {
if (typeof data.events === "object") {
for (const eventName in data.events) {
$(D).trigger(eventName, [data.events[eventName]]);
}
}
if (typeof callback !== 'undefined') {
if (typeof callback !== "undefined") {
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) {
return $.Deferred().resolve().promise();
}
@ -233,15 +233,15 @@ const AjaxUI = (($) => {
};
// auto-apply
$('.ajax').ready(() => {
$('.ajax').jsAjaxUI();
$(".ajax").ready(() => {
$(".ajax").jsAjaxUI();
});
// AJAX update browser title
$(D).on('layoutRefresh', (e, data) => {
$(D).on("layoutRefresh", (e, data) => {
D.title = data.Title;
$Html.attr('class', '');
$Html.attr("class", "");
if (data.ClassName) {
$Html.addClass(data.ClassName);
}
@ -255,9 +255,9 @@ const AjaxUI = (($) => {
if (event.state !== null && event.state.ajax) {
console.log(`${NAME}: GOBACK (AJAX state)`);
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)`);
$existingLink.trigger('click');
$existingLink.trigger("click");
} else if (D.location.href !== G.location.href) {
console.log(`${NAME}: GOBACK (HTTP)`);
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 'jquery-hammerjs/jquery.hammer';
import "hammerjs/hammer";
import "jquery-hammerjs/jquery.hammer";
import Events from '../_events';
import Events from "../_events";
const CarouselUI = (($) => {
// Constants
const NAME = 'CarouselUI';
const NAME = "CarouselUI";
class CarouselUI {
// Static methods
@ -28,36 +28,36 @@ const CarouselUI = (($) => {
const $e = $(e),
id = `Carousel${i}`;
$e.attr('id', id);
$e.data('id', i);
$e.attr("id", id);
$e.data("id", i);
const $items = $(e).find('.carousel-item'),
const $items = $(e).find(".carousel-item"),
count = $items.length;
if (!count) {
return;
}
// create carousel-controls
if ($e.data('indicators')) {
if ($e.data("indicators")) {
const $indicators = $('<ol class="carousel-indicators"></ol>');
$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++) {
$indicators.append(
`<li data-target="#${id}" data-slide-to="${i}"></li>`,
`<li data-target="#${id}" data-slide-to="${i}"></li>`
);
}
$e.prepend($indicators);
}
// create arrows
if ($e.data('arrows')) {
if ($e.data("arrows")) {
$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(
`<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();
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) {
$youtubeSlides.each((i, e) => {
const $e = $(e);
try {
$e.data(
'player',
"player",
new YT.Player(e, {
events: {
onReady: () => {
$e.data('player').pauseVideo();
$e.data("player").pauseVideo();
},
},
}),
})
);
$e.data('player').pauseVideo();
$e.data("player").pauseVideo();
} catch (e) {}
});
}
});
$e.find('.carousel-control-prev').on('click', (e) => {
$e.find(".carousel-control-prev").on("click", (e) => {
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.carousel('next');
$e.carousel("next");
});
// init touch swipes
$e.hammer().bind(Events.SWIPELEFT, (e) => {
$(event.target).carousel('next');
$(event.target).carousel("next");
});
$e.hammer().bind(Events.SWIPERIGHT, (e) => {
$(event.target).carousel('prev');
$(event.target).carousel("prev");
});
/*$e.find('.carousel-item').hammer().bind('tap', (event) => {
@ -120,7 +120,7 @@ const CarouselUI = (($) => {
static dispose() {
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 D = document;
@ -8,16 +8,16 @@ const CookieUI = (($) => {
class CookieUI {
static get(name) {
return D.cookie.split('; ').reduce((r, v) => {
const parts = v.split('=');
return D.cookie.split("; ").reduce((r, v) => {
const parts = v.split("=");
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();
D.cookie = `${name}=${encodeURIComponent(
value,
value
)}; 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 CookieUI from './_ui.cookie';
import Events from "../_events";
import CookieUI from "./_ui.cookie";
const FlyoutUI = (($) => {
const W = window;
const D = document;
const $Body = $('body');
const $Body = $("body");
const NAME = 'FlyoutUI';
const NAME = "FlyoutUI";
const COOKIE = `${NAME}-hide`;
const TIMEOUT = 2000;
@ -29,14 +29,14 @@ const FlyoutUI = (($) => {
ui.$modal.data(NAME, ui);
if ($close.length) {
$close.on('click', () => {
$close.on("click", () => {
ui.hide();
});
}
const hide = CookieUI.get(COOKIE);
if (!$close.length || !hide || hide !== 'true') {
if (!$close.length || !hide || hide !== "true") {
setTimeout(() => {
ui.show();
}, TIMEOUT);
@ -52,7 +52,7 @@ const FlyoutUI = (($) => {
static hide(callback) {
const ui = this;
CookieUI.set(COOKIE, 'true', 1);
CookieUI.set(COOKIE, "true", 1);
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 SpinnerUI from './_ui.spinner';
import FormFieldUI from './_ui.form.fields';
import Events from "../_events";
import SpinnerUI from "./_ui.spinner";
import FormFieldUI from "./_ui.form.fields";
const FormBasics = (($) => {
// Constants
const NAME = 'jsFormBasics';
const NAME = "jsFormBasics";
const DATA_KEY = NAME;
const $Html = $('html, body');
const $Html = $("html, body");
const W = window;
const D = document;
@ -37,8 +37,8 @@ const FormBasics = (($) => {
$fields.each((e, el) => {
const $el = $(el);
if ($el.hasClass('required') || $el.attr('aria-required')) {
$el.closest('.field').addClass('required');
if ($el.hasClass("required") || $el.attr("aria-required")) {
$el.closest(".field").addClass("required");
}
});
@ -46,50 +46,50 @@ const FormBasics = (($) => {
$radioOptions.each((e, el) => {
const $el = $(el);
if ($el.is(':checked')) {
$el.parents('.radio').addClass('checked');
if ($el.is(":checked")) {
$el.parents(".radio").addClass("checked");
}
});
$radioOptions.on('change', (e) => {
$radioOptions.on("change", (e) => {
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);
if (!$el.find('input').is(':checked')) {
$el.removeClass('checked');
if (!$el.find("input").is(":checked")) {
$el.removeClass("checked");
}
});
if ($el.is(':checked')) {
$parent.addClass('checked');
if ($el.is(":checked")) {
$parent.addClass("checked");
}
});
$el.on('submit', (e) => {
$el.on("submit", (e) => {
setTimeout(() => {
if (!$el.find('.error').length) {
if (!$el.find(".error").length) {
SpinnerUI.show();
}
}, 100);
});
$('.field.password .show-password').on('click', (e) => {
$(".field.password .show-password").on("click", (e) => {
console.log(`${NAME}: .field.password .show-password (click)`);
const $el = $(e.currentTarget);
const $field = $el.siblings('input');
const $icon = $el.find('.fas');
const attr = $field.attr('type');
const $field = $el.siblings("input");
const $icon = $el.find(".fas");
const attr = $field.attr("type");
if (attr === 'password') {
$field.attr('type', 'text');
$icon.removeClass('fa-eye').addClass('fa-eye-slash');
if (attr === "password") {
$field.attr("type", "text");
$icon.removeClass("fa-eye").addClass("fa-eye-slash");
} else {
$field.attr('type', 'password');
$icon.removeClass('fa-eye-slash').addClass('fa-eye');
$field.attr("type", "password");
$icon.removeClass("fa-eye-slash").addClass("fa-eye");
}
});
@ -131,7 +131,7 @@ const FormBasics = (($) => {
};
const init = () => {
$('form').jsFormBasics();
$("form").jsFormBasics();
};
// auto-apply

View File

@ -1,15 +1,15 @@
'use strict';
"use strict";
import $ from 'jquery';
import $ from "jquery";
import Events from '../_events';
import SpinnerUI from './_ui.spinner';
import Events from "../_events";
import SpinnerUI from "./_ui.spinner";
import 'croppie/croppie.js';
import 'exif-js/exif.js';
import "croppie/croppie.js";
import "exif-js/exif.js";
const CroppieUI = (($) => {
const NAME = 'jsCroppieUI';
const NAME = "jsCroppieUI";
const DATA_KEY = NAME;
const G = window;
@ -18,7 +18,7 @@ const CroppieUI = (($) => {
const jqteOptions = {
color: false,
fsize: false,
funit: 'em',
funit: "em",
format: false,
rule: false,
source: false,
@ -39,17 +39,17 @@ const CroppieUI = (($) => {
ui.input = $el.find('input[type="file"]');
//ui.inputData = $('<input type="hidden" class="base64enc" name="' + ui.input.attr('name') + 'base64" />');
ui.width = ui.input.data('width');
ui.height = ui.input.data('height');
ui.width = ui.input.data("width");
ui.height = ui.input.data("height");
$el.append(
'<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);
ui.uploadCropWrap = $el.find('.cropper-wrap');
ui.uploadCrop = ui.uploadCropWrap.find('.cropper-container');
ui.uploadCropWrap = $el.find(".cropper-wrap");
ui.uploadCrop = ui.uploadCropWrap.find(".cropper-container");
const ratio = ui.width / (ui.uploadCrop.width() - 32);
ui.uploadCrop.croppie({
@ -63,24 +63,24 @@ const CroppieUI = (($) => {
ui.uploadCrop.hide();
ui.input.on('change', (e) => {
ui.input.on("change", (e) => {
this.readFile(e.currentTarget);
});
ui.$btnRemove = $el.find('.btn-remove');
ui.$btnRemove.on('click', (e) => {
ui.$btnRemove = $el.find(".btn-remove");
ui.$btnRemove.on("click", (e) => {
e.preventDefault();
ui.uploadCrop.removeClass('ready');
$el.find('.croppie-image').remove();
ui.uploadCrop.removeClass("ready");
$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.uploadCropWrap.hide();
});
if (ui.$el.find('img.croppie-image').length) {
if (ui.$el.find("img.croppie-image").length) {
ui.$btnRemove.show();
}
}
@ -88,14 +88,14 @@ const CroppieUI = (($) => {
readFile(input) {
const ui = this;
const $el = ui.$el;
const $form = $el.closest('form');
const $form = $el.closest("form");
if (input.files && input.files[0]) {
const reader = new FileReader();
reader.onload = (e) => {
ui.uploadCrop.addClass('ready');
ui.uploadCrop.croppie('bind', {
ui.uploadCrop.addClass("ready");
ui.uploadCrop.croppie("bind", {
url: e.target.result,
});
@ -106,56 +106,56 @@ const CroppieUI = (($) => {
reader.readAsDataURL(input.files[0]);
$form.off('submit');
$form.on('submit', (e) => {
$form.off("submit");
$form.on("submit", (e) => {
console.log(`${NAME}: Processing submission ...`);
e.preventDefault();
if ($form.data('locked')) {
console.warn(`${NAME}: Form#${$form.attr('id')} is locked.`);
if ($form.data("locked")) {
console.warn(`${NAME}: Form#${$form.attr("id")} is locked.`);
return false;
}
$form.data('locked', true);
$form.data("locked", true);
SpinnerUI.show();
if (!ui.uploadCrop.hasClass('ready')) {
if (!ui.uploadCrop.hasClass("ready")) {
return true;
}
ui.uploadCrop
.croppie('result', {
type: 'blob',
.croppie("result", {
type: "blob",
size: {
width: ui.width,
height: ui.height,
},
format: 'png',
format: "png",
})
.then((blob) => {
const form = e.currentTarget;
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.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;
}
$.ajax({
url: $(form).attr('action'),
url: $(form).attr("action"),
data,
processData: false,
contentType: false,
type: $(form).attr('method'),
type: $(form).attr("method"),
success: function (data) {
$form.data('locked', false);
$form.data("locked", false);
let IS_JSON = false;
let json = {};
@ -167,39 +167,39 @@ const CroppieUI = (($) => {
}
if (IS_JSON) {
if (typeof json['status'] !== 'undefined') {
if (json['status'] === 'success') {
MainUI.alert(json['message'], json['status']);
if (typeof json["status"] !== "undefined") {
if (json["status"] === "success") {
MainUI.alert(json["message"], json["status"]);
if (typeof json['link'] !== 'undefined') {
if (typeof json["link"] !== "undefined") {
console.log(
`${NAME}: Finished submission > JSON ... Redirecting to ${json['link']}.`,
`${NAME}: Finished submission > JSON ... Redirecting to ${json["link"]}.`
);
setTimeout(() => {
G.location = json['link'];
G.location = json["link"];
}, 2000);
} else {
console.warn(
`${NAME}: Finished submission > JSON no redirect link.`,
`${NAME}: Finished submission > JSON no redirect link.`
);
}
} else if (json['status'] === 'error') {
MainUI.alert(json['message'], json['status']);
} else if (json["status"] === "error") {
MainUI.alert(json["message"], json["status"]);
}
}
if (typeof json['form'] !== 'undefined') {
if (typeof json["form"] !== "undefined") {
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);
}
} else {
console.log(
`${NAME}: Finished submission > DATA response.`,
`${NAME}: Finished submission > DATA response.`
);
$(form).replaceWith(data);
@ -216,7 +216,7 @@ const CroppieUI = (($) => {
});
} else {
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
$(window).on(`${NAME}.init ${Events.AJAX} ${Events.LOADED}`, () => {
$('.field.croppie').jsCroppieUI();
$(".field.croppie").jsCroppieUI();
});
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-timepicker/js/bootstrap-timepicker.js';
import "bootstrap-datepicker/dist/js/bootstrap-datepicker.js";
import "bootstrap-timepicker/js/bootstrap-timepicker.js";
const DatetimeUI = (($) => {
// Constants
const W = window;
const D = document;
const $Body = $('body');
const $Body = $("body");
const NAME = 'jsDatetimeUI';
const NAME = "jsDatetimeUI";
const DATA_KEY = NAME;
const datepickerOptions = {
@ -34,56 +34,56 @@ const DatetimeUI = (($) => {
ui._el = el;
// datepicker
if ($el.hasClass('date') || $el.attr('type') === 'date') {
if ($el.hasClass("date") || $el.attr("type") === "date") {
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(
$.extend(
datepickerOptions,
{
defaultViewDate: defaultDate,
multidate: $el.data('multidate'),
multidate: $el.data("multidate"),
},
$el.data(),
),
$el.data()
)
);
}
// timepicker
else if ($el.hasClass('time') || $el.attr('type') === 'time') {
$el.attr('readonly', 'true');
else if ($el.hasClass("time") || $el.attr("type") === "time") {
$el.attr("readonly", "true");
$el
.timepicker(
$.extend(
{
snapToStep: true,
icons: {
up: 'fas fa-chevron-up',
down: 'fas fa-chevron-down',
up: "fas fa-chevron-up",
down: "fas fa-chevron-down",
},
},
$el.data(),
),
$el.data()
)
.on('show.timepicker', (e) => {
)
.on("show.timepicker", (e) => {
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) {
$dropdown
.find('tbody')
.find("tbody")
.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"]');
$clearBtn.on('click', (e) => {
$clearBtn.on("click", (e) => {
e.preventDefault();
$el.timepicker('clear');
$el.timepicker('hideWidget');
$el.timepicker("clear");
$el.timepicker("hideWidget");
});
});
}
@ -118,7 +118,7 @@ const DatetimeUI = (($) => {
// auto-apply
$(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();
});

View File

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

View File

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

View File

@ -1,22 +1,22 @@
'use strict';
"use strict";
import $ from 'jquery';
import $ from "jquery";
import Events from '../_events';
import Spinner from '../_components/_ui.spinner';
import FormValidateField from './_ui.form.validate.field';
import Events from "../_events";
import Spinner from "../_components/_ui.spinner";
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/uncompressed/jquery-te-1.4.0.js';
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";
const JqteUI = (($) => {
const NAME = 'jsJqteUI';
const NAME = "jsJqteUI";
const DATA_KEY = NAME;
const jqteOptions = {
color: false,
fsize: false,
funit: 'em',
funit: "em",
format: false,
rule: false,
source: false,
@ -30,7 +30,7 @@ const JqteUI = (($) => {
const ui = this;
const $element = $(element);
const validationUI = $element.data('jsFormValidateField');
const validationUI = $element.data("jsFormValidateField");
ui._element = element;
$element.data(DATA_KEY, this);
@ -39,9 +39,9 @@ const JqteUI = (($) => {
// dynamic error control
if (validationUI) {
$element
.parents('.jqte')
.find('.jqte_editor')
.on('change', (e) => {
.parents(".jqte")
.find(".jqte_editor")
.on("change", (e) => {
validationUI.validate();
});
}
@ -75,7 +75,7 @@ const JqteUI = (($) => {
// auto-apply
$(window).on(`${Events.AJAX} ${Events.LOADED}`, () => {
$('textarea.jqte-field').jsJqteUI();
$("textarea.jqte-field").jsJqteUI();
});
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 Events from '../_events';
import select2 from "select2/dist/js/select2.js";
import Events from "../_events";
const FormSelect2 = (($) => {
// Constants
const NAME = 'jsFormSelect2';
const NAME = "jsFormSelect2";
const DATA_KEY = NAME;
const $Html = $('html, body');
const $Html = $("html, body");
const W = window;
const D = document;
@ -27,8 +27,8 @@ const FormSelect2 = (($) => {
const $fields = $el.find(Events.FORM_FIELDS);
const $selectFields = $el
.find('select:not([readonly])')
.not('.no-select2');
.find("select:not([readonly])")
.not(".no-select2");
$selectFields.each((i, el) => {
$(el).select2();
@ -46,12 +46,12 @@ const FormSelect2 = (($) => {
const $el = $(ui._el);
const $selectFields = $el
.find('select:not([readonly])')
.not('.no-select2');
.find("select:not([readonly])")
.not(".no-select2");
$selectFields.each((i, el) => {
const $el = $(el);
if ($el.hasClass('select2-hidden-accessible')) {
$el.select2('destroy');
if ($el.hasClass("select2-hidden-accessible")) {
$el.select2("destroy");
}
});
@ -83,7 +83,7 @@ const FormSelect2 = (($) => {
};
const init = () => {
$('form').jsFormSelect2();
$("form").jsFormSelect2();
};
// auto-apply

View File

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

View File

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

View File

@ -1,15 +1,15 @@
'use strict';
"use strict";
import $ from 'jquery';
import Events from '../_events';
import $ from "jquery";
import Events from "../_events";
const FormValidateField = (($) => {
// Constants
const NAME = 'jsFormValidateField';
const NAME = "jsFormValidateField";
const DATA_KEY = NAME;
const $Body = $('body');
const $Body = $("body");
const FieldUI = 'jsFormFieldUI';
const FieldUI = "jsFormFieldUI";
class FormValidateField {
constructor(el) {
@ -18,13 +18,13 @@ const FormValidateField = (($) => {
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);
// 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);
});
@ -45,7 +45,7 @@ const FormValidateField = (($) => {
const ui = this;
const $el = ui.$el;
const $field = $el.closest('.field');
const $field = $el.closest(".field");
const extraChecks = $el.data(`${NAME}-extra`);
let valid = true;
let msg = null;
@ -56,58 +56,58 @@ const FormValidateField = (($) => {
if (!ui.$el[0].checkValidity()) {
valid = false;
console.warn(
`${NAME}: Browser check validity is failed #${$el.attr('id')}`,
`${NAME}: Browser check validity is failed #${$el.attr("id")}`
);
}
let unmaskedVal = val;
if (typeof $el.inputmask === 'function') {
unmaskedVal = $el.inputmask('unmaskedvalue');
if (typeof $el.inputmask === "function") {
unmaskedVal = $el.inputmask("unmaskedvalue");
}
// required
if (
$el.hasClass('required') &&
$el.hasClass("required") &&
(!unmaskedVal.length ||
!unmaskedVal.trim().length ||
(ui.isHtml(val) && !$(unmaskedVal).text().length))
) {
valid = false;
console.warn(`${NAME}: Required field is missing #${$el.attr('id')}`);
console.warn(`${NAME}: Required field is missing #${$el.attr("id")}`);
}
// validate URL
if (
$el.hasClass('url') &&
$el.hasClass("url") &&
unmaskedVal.length &&
!ui.valideURL(unmaskedVal)
) {
valid = false;
msg =
'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')}`);
"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")}`);
}
// maxlength
const maxLength = $el.attr('maxlength');
const maxLength = $el.attr("maxlength");
if (unmaskedVal.length && maxLength && maxLength.length) {
if (unmaskedVal.length > maxLength) {
valid = false;
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
const minLength = $el.attr('minlength');
const minLength = $el.attr("minlength");
if (unmaskedVal.length && minLength && minLength.length) {
if (unmaskedVal.length < minLength) {
valid = false;
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;
if (!result) {
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) {
const doc = new DOMParser().parseFromString(str, 'text/html');
const doc = new DOMParser().parseFromString(str, "text/html");
return Array.from(doc.body.childNodes).some(
(node) => node.nodeType === 1,
(node) => node.nodeType === 1
);
}
@ -150,24 +150,24 @@ const FormValidateField = (($) => {
return false;
}
return url.protocol === 'http:' || url.protocol === 'https:';
return url.protocol === "http:" || url.protocol === "https:";
}
setError(scrollTo = true, msg = null) {
const ui = this;
const fieldUI = ui.$el.data(FieldUI);
const $field = ui.$el.closest('.field');
const $field = ui.$el.closest(".field");
const bodyScroll = $Body.scrollTop();
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();
$field.addClass('error');
$field.addClass("error");
if (msg) {
fieldUI.addMessage(msg, 'alert-error alert-danger', scrollTo);
fieldUI.addMessage(msg, "alert-error alert-danger", scrollTo);
} else if (pos && scrollTo) {
$field.focus();
$Body.scrollTop(bodyScroll + pos - rowCorrection);
@ -178,13 +178,13 @@ const FormValidateField = (($) => {
const ui = this;
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-validation');
$field.find('.alert-error').remove();
$field.removeClass("holder-error");
$field.removeClass("holder-validation");
$field.find(".alert-error").remove();
}
static _jQueryInterface() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,15 +1,15 @@
'use strict';
"use strict";
import $ from 'jquery';
import Events from '../lib/_events';
import $ from "jquery";
import Events from "../lib/_events";
const NoCaptcha = (($) => {
// Constants
const $window = $(window);
const D = document;
const $Body = $('body');
const $Body = $("body");
const NAME = 'jsNoCaptcha';
const NAME = "jsNoCaptcha";
class NoCaptcha {
static init() {
@ -18,14 +18,17 @@ const NoCaptcha = (($) => {
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`);
$.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();
},
}
);
} else {
this.renderCaptcha();
@ -38,41 +41,44 @@ const NoCaptcha = (($) => {
static renderCaptcha() {
const grecaptcha = $window[0].grecaptcha;
if (typeof grecaptcha === 'undefined' || typeof grecaptcha.render === 'undefined') {
if (
typeof grecaptcha === "undefined" ||
typeof grecaptcha.render === "undefined"
) {
return;
}
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`);
return;
}
const submitListener = (e) => {
const $field = $(e.currentTarget).find('.g-recaptcha');
grecaptcha.execute($field.data('widgetid'));
const $field = $(e.currentTarget).find(".g-recaptcha");
grecaptcha.execute($field.data("widgetid"));
};
$_noCaptchaFields.each((i, field) => {
const $field = $(field);
if ($field.data('widgetid') || $field.html().length) {
if ($field.data("widgetid") || $field.html().length) {
return;
}
const $form = $field.data('form') ?
$(`#${$field.data('form')}`) :
$field.parents('form');
const $form = $field.data("form")
? $(`#${$field.data("form")}`)
: $field.parents("form");
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
if ($field.data('size') === 'invisible' && !$field.data('callback')) {
if ($field.data("size") === "invisible" && !$field.data("callback")) {
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 = (($) => {
// Constants
const NAME = 'OpeningHoursUI';
const NAME = "OpeningHoursUI";
class OpeningHoursUI {
// Static methods
static each(callback) {
$('.js-opening-hours').each((i, e) => {
$(".js-opening-hours").each((i, e) => {
callback(i, $(e));
});
}
@ -22,50 +22,50 @@ const OpeningHoursUI = (($) => {
console.log(`${NAME}: init ...`);
const hours = $.parseJSON($('.oppening-hours-json').html());
const hours = $.parseJSON($(".oppening-hours-json").html());
const date = new Date();
const dateYMD = this.Date_toYMD(date);
const weekday = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const today = weekday[date.getDay()];
let html =
'<b class="opening-hours-status opening-hours-status-closed">Closed today</b>';
if (
typeof hours['days'] !== 'undefined' &&
typeof hours['days'][today] !== 'undefined' &&
hours['days'][today].length
typeof hours["days"] !== "undefined" &&
typeof hours["days"][today] !== "undefined" &&
hours["days"][today].length
) {
html = 'Open today ';
$.each(hours['days'][today], (i, v) => {
if (v['DisplayStart'] || v['DisplayEnd']) {
html = "Open today ";
$.each(hours["days"][today], (i, v) => {
if (v["DisplayStart"] || v["DisplayEnd"]) {
if (
(v['DisplayStart'] &&
v['DisplayStart'] <= dateYMD &&
v['DisplayEnd'] &&
v['DisplayEnd'] >= dateYMD) ||
(v['DisplayStart'] &&
v['DisplayStart'] <= dateYMD &&
!v['DisplayEnd']) ||
(v['DisplayEnd'] &&
v['DisplayEnd'] >= dateYMD &&
!v['DisplayStart'])
(v["DisplayStart"] &&
v["DisplayStart"] <= dateYMD &&
v["DisplayEnd"] &&
v["DisplayEnd"] >= dateYMD) ||
(v["DisplayStart"] &&
v["DisplayStart"] <= dateYMD &&
!v["DisplayEnd"]) ||
(v["DisplayEnd"] &&
v["DisplayEnd"] >= dateYMD &&
!v["DisplayStart"])
) {
html = `Open today from ${v['From']} to ${v['Till']}`;
html = `Open today from ${v["From"]} to ${v["Till"]}`;
return false;
}
} else {
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 (
typeof hours['holidays'] !== 'undefined' &&
typeof hours['holidays'][dateYMD] !== 'undefined'
typeof hours["holidays"] !== "undefined" &&
typeof hours["holidays"][dateYMD] !== "undefined"
) {
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>`;
}
@ -104,7 +104,7 @@ const OpeningHoursUI = (($) => {
static dispose() {
console.log(`${NAME}: dispose`);
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 $searchLng = $('[name="search-lng"]');
const $nearbyLat = $('#nearby-lat');
const $nearbyLng = $('#nearby-lng');
const $radius = $('#distance-radius');
const $category = $('#distance-category');
const $nearbyLat = $("#nearby-lat");
const $nearbyLng = $("#nearby-lng");
const $radius = $("#distance-radius");
const $category = $("#distance-category");
const $newLocation = $('[name="newlocation"]');
const $setnewlocation = $('#setnewlocation');
const $newlocationholder = $('.set-newlocation-holder');
const $setnewlocation = $("#setnewlocation");
const $newlocationholder = $(".set-newlocation-holder");
const updatePosition = (lat, lng) => {
$searchLat.val(lat);
@ -29,14 +29,14 @@ $(() => {
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`;
$.getJSON(geoUrl).done((data) => {
if (data.status === 'OK') {
if (data.status === "OK") {
updatePosition(
data.results[0].geometry.location.lat,
data.results[0].geometry.location.lng,
data.results[0].geometry.location.lng
);
//getCategories();
}
@ -44,7 +44,7 @@ $(() => {
};
const getCurrentPosition = () => {
$('.search-location .current-val').text('Current Location');
$(".search-location .current-val").text("Current Location");
navigator.geolocation.getCurrentPosition(
(position) => {
@ -52,9 +52,9 @@ $(() => {
//hideDistancesThatDontMatter();
},
() => {
$('.search-location .current-val').text('Unable to get your location');
updatePosition('', '');
},
$(".search-location .current-val").text("Unable to get your location");
updatePosition("", "");
}
);
};
@ -64,7 +64,7 @@ $(() => {
getCurrentPosition();
}
$('#Form_SearchForm').on('keyup keypress', (e) => {
$("#Form_SearchForm").on("keyup keypress", (e) => {
var keyCode = e.keyCode || e.which;
if (keyCode === 13) {
e.preventDefault();
@ -72,15 +72,15 @@ $(() => {
}
});
$('.get-current-location').on('click', (e) => {
$(".get-current-location").on("click", (e) => {
e.preventDefault();
getCurrentPosition();
$newlocationholder.toggle();
$newLocation.val('');
$newLocation.val("");
});
$setnewlocation.on('click', (e) => {
$setnewlocation.on("click", (e) => {
e.preventDefault();
$newlocationholder.toggle();
@ -90,14 +90,14 @@ $(() => {
getGeoPosition();
});
$('.new-search').on('click', (e) => {
$(".new-search").on("click", (e) => {
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');
if (typeof google !== 'undefined' && $map.length) {
const $directions = $('#DirectionsPanel'),
$fromAddress = $('#FromAddress'),
$getDirections = $('#GetDirections'),
$directionContainer = $('#DirectionContainer'),
const $map = $("#Map");
if (typeof google !== "undefined" && $map.length) {
const $directions = $("#DirectionsPanel"),
$fromAddress = $("#FromAddress"),
$getDirections = $("#GetDirections"),
$directionContainer = $("#DirectionContainer"),
directionsDisplay = new google.maps.DirectionsRenderer(),
directionsService = new google.maps.DirectionsService(),
currentPosition = {
lat: $map.data('lat'),
lng: $map.data('lng'),
lat: $map.data("lat"),
lng: $map.data("lng"),
},
map = new google.maps.Map($map[0], {
zoom: 15,
@ -172,7 +172,7 @@ $(() => {
if (status === google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
},
}
);
$directionContainer.slideDown();

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
function _gaLt(event) {
if (typeof ga !== 'function') {
if (typeof ga !== "function") {
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) */
while (
el &&
(typeof el.tagName == 'undefined' ||
el.tagName.toLowerCase() != 'a' ||
(typeof el.tagName == "undefined" ||
el.tagName.toLowerCase() != "a" ||
!el.href)
) {
el = el.parentNode;
@ -21,7 +21,7 @@ function _gaLt(event) {
if (link.indexOf(location.host) == -1 && !link.match(/^javascript:/i)) {
/* external link */
/* 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);
};
/* Is target set and not _(self|parent|top)? */
@ -31,12 +31,12 @@ function _gaLt(event) {
: false;
/* send event with callback */
ga(
'send',
'event',
'Outgoing Links',
"send",
"event",
"Outgoing Links",
link,
document.location.pathname + document.location.search,
{ hitCallback: hitBack(link, target) },
{ hitCallback: hitBack(link, target) }
);
/* Prevent standard click */
@ -49,13 +49,13 @@ function _gaLt(event) {
var w = window;
w.addEventListener
? w.addEventListener(
'load',
"load",
() => {
document.body.addEventListener('click', _gaLt, !1);
document.body.addEventListener("click", _gaLt, !1);
},
!1,
!1
)
: w.attachEvent &&
w.attachEvent('onload', () => {
document.body.attachEvent('onclick', _gaLt);
w.attachEvent("onload", () => {
document.body.attachEvent("onclick", _gaLt);
});

View File

@ -1,4 +1,4 @@
'use strict';
"use strict";
const Obj = {
init: () => {
@ -9,11 +9,9 @@ const Obj = {
ui.setMap(options.map);
ui.position = options.position;
ui.html =
(options.html ?
options.html :
'<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>'
);
ui.html = options.html
? options.html
: '<div class="mapboxgl-marker"><i class="marker-icon fas fa-map-marker-alt"></i></div>';
ui.divClass = options.divClass;
ui.align = options.align;
ui.isDebugMode = options.debug;
@ -21,7 +19,7 @@ const Obj = {
ui.onMouseOver = options.onMouseOver;
ui.isBoolean = (arg) => {
if (typeof arg === 'boolean') {
if (typeof arg === "boolean") {
return true;
} else {
return false;
@ -29,7 +27,7 @@ const Obj = {
};
ui.isNotUndefined = (arg) => {
if (typeof arg !== 'undefined') {
if (typeof arg !== "undefined") {
return true;
} else {
return false;
@ -45,7 +43,7 @@ const Obj = {
};
ui.isString = (arg) => {
if (typeof arg === 'string') {
if (typeof arg === "string") {
return true;
} else {
return false;
@ -53,7 +51,7 @@ const Obj = {
};
ui.isFunction = (arg) => {
if (typeof arg === 'function') {
if (typeof arg === "function") {
return true;
} else {
return false;
@ -64,8 +62,8 @@ const Obj = {
const ui = this;
// Create div element.
ui.div = document.createElement('div');
ui.div.style.position = 'absolute';
ui.div = document.createElement("div");
ui.div.style.position = "absolute";
// Validate and set custom div class
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 (ui.isBoolean(ui.isDebugMode) && ui.isDebugMode) {
ui.div.className = 'debug-mode';
ui.div.className = "debug-mode";
ui.div.innerHTML =
'<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>';
ui.div.setAttribute(
'style',
'position: absolute;' +
'border: 5px dashed red;' +
'height: 150px;' +
'width: 150px;' +
'display: flex;' +
'justify-content: center;' +
'align-items: center;'
"style",
"position: absolute;" +
"border: 5px dashed red;" +
"height: 150px;" +
"width: 150px;" +
"display: flex;" +
"justify-content: center;" +
"align-items: center;"
);
}
@ -101,14 +99,14 @@ const Obj = {
ui.getPanes().overlayMouseTarget.appendChild(ui.div);
// Add listeners to the element.
google.maps.event.addDomListener(ui.div, 'click', (event) => {
google.maps.event.trigger(ui, 'click');
google.maps.event.addDomListener(ui.div, "click", (event) => {
google.maps.event.trigger(ui, "click");
if (ui.isFunction(ui.onClick)) ui.onClick();
event.stopPropagation();
});
google.maps.event.addDomListener(ui.div, 'mouseover', (event) => {
google.maps.event.trigger(ui, 'mouseover');
google.maps.event.addDomListener(ui.div, "mouseover", (event) => {
google.maps.event.trigger(ui, "mouseover");
if (ui.isFunction(ui.onMouseOver)) ui.onMouseOver();
event.stopPropagation();
});
@ -118,9 +116,9 @@ const Obj = {
const ui = this;
// Calculate position of div
var positionInPixels = ui.getProjection().fromLatLngToDivPixel(
new google.maps.LatLng(ui.position)
);
var positionInPixels = ui
.getProjection()
.fromLatLngToDivPixel(new google.maps.LatLng(ui.position));
// Align HTML overlay relative to original position
var divOffset = {
@ -128,40 +126,40 @@ const Obj = {
x: undefined,
};
switch (Array.isArray(ui.align) ? ui.align.join(' ') : '') {
case 'left top':
switch (Array.isArray(ui.align) ? ui.align.join(" ") : "") {
case "left top":
divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth;
break;
case 'left center':
case "left center":
divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth;
break;
case 'left bottom':
case "left bottom":
divOffset.y = 0;
divOffset.x = ui.div.offsetWidth;
break;
case 'center top':
case "center top":
divOffset.y = ui.div.offsetHeight;
divOffset.x = ui.div.offsetWidth / 2;
break;
case 'center center':
case "center center":
divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = ui.div.offsetWidth / 2;
break;
case 'center bottom':
case "center bottom":
divOffset.y = 0;
divOffset.x = ui.div.offsetWidth / 2;
break;
case 'right top':
case "right top":
divOffset.y = ui.div.offsetHeight;
divOffset.x = 0;
break;
case 'right center':
case "right center":
divOffset.y = ui.div.offsetHeight / 2;
divOffset.x = 0;
break;
case 'right bottom':
case "right bottom":
divOffset.y = 0;
divOffset.x = 0;
break;
@ -171,8 +169,8 @@ const Obj = {
}
// Set position
ui.div.style.top = `${positionInPixels.y - divOffset.y }px`;
ui.div.style.left = `${positionInPixels.x - divOffset.x }px`;
ui.div.style.top = `${positionInPixels.y - divOffset.y}px`;
ui.div.style.left = `${positionInPixels.x - divOffset.x}px`;
}
getPosition() {
@ -194,6 +192,6 @@ const Obj = {
}
return GoogleMapsHtmlOverlay;
},
}
};
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 MarkerUI from './_map.google.marker';
import Events from "../../_events";
import MarkerUI from "./_map.google.marker";
const GoogleMapsDriver = (($) => {
class GoogleMapsDriver {
getName() {
return 'GoogleMapsDriver';
return "GoogleMapsDriver";
}
init($el, config = []) {
@ -25,10 +25,10 @@ const GoogleMapsDriver = (($) => {
ui.googleApiLoaded();
};
$('body').append(
$("body").append(
`<script async defer src="https://maps.googleapis.com/maps/api/js?key=${
config['key']
}&callback=init${ui.getName()}"></script>`,
config["key"]
}&callback=init${ui.getName()}"></script>`
);
}
@ -37,19 +37,19 @@ const GoogleMapsDriver = (($) => {
const $el = ui.$el;
const config = ui.config;
const $mapDiv = $el.find('.mapAPI-map');
const $mapDiv = $el.find(".mapAPI-map");
const zoom = config['mapZoom'] ? config['mapZoom'] : 10;
const center = config['center']
const zoom = config["mapZoom"] ? config["mapZoom"] : 10;
const center = config["center"]
? {
lat: config['center'][1],
lng: config['center'][0],
lat: config["center"][1],
lng: config["center"][0],
}
: {
lat: 0,
lng: 0,
};
const style = config['style'] ? config['style'] : null;
const style = config["style"] ? config["style"] : null;
console.log(`${ui.getName()}: API is loaded`);
// init fontawesome icons
@ -64,28 +64,30 @@ const GoogleMapsDriver = (($) => {
ui.default_zoom = zoom;
$mapDiv.addClass('mapboxgl-map');
$mapDiv.addClass("mapboxgl-map");
ui.popup = new ui.MarkerUI({
map: ui.map,
align: ['center', 'top'],
divClass: 'mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none',
align: ["center", "top"],
divClass: "mapboxgl-popup popup mapboxgl-popup-anchor-bottom d-none",
html:
'<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="html"></div>' +
'</div>',
"</div>",
});
ui.popup.setMap(ui.map);
ui.geocoder = new google.maps.Geocoder();
ui.cluster = new MarkerClusterer(ui.map, null, {
styles: [{
styles: [
{
width: 30,
height: 30,
className: 'mapboxgl-cluster',
}],
className: "mapboxgl-cluster",
},
],
});
$el.trigger(Events.MAPAPILOADED);
@ -102,11 +104,11 @@ const GoogleMapsDriver = (($) => {
const marker = new ui.MarkerUI({
position: pos,
map: ui.map,
align: ['center', 'top'],
html: `<div class="mapboxgl-marker"><div id="Marker${config['id']}" data-id="${config['id']}" class="marker">${config['icon']}</div></div>`,
align: ["center", "top"],
html: `<div class="mapboxgl-marker"><div id="Marker${config["id"]}" data-id="${config["id"]}" class="marker">${config["icon"]}</div></div>`,
onClick: () => {
const $el = $(`#Marker${config['id']}`);
ui.showPopup(pos, config['content']);
const $el = $(`#Marker${config["id"]}`);
ui.showPopup(pos, config["content"]);
$el.trigger(Events.MAPMARKERCLICK);
},
@ -123,33 +125,33 @@ const GoogleMapsDriver = (($) => {
const ui = this;
const $popup = $(ui.popup.getDiv());
if (ui.config['flyToMarker']) {
if (ui.config["flyToMarker"]) {
ui.map.setCenter(pos); // panTo
if (!ui.config['noZoom']) {
if (!ui.config["noZoom"]) {
ui.map.setZoom(18);
}
}
// keep it hidden to render content
$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();
ui.hidePopup();
});
// set position when content was rendered
ui.popup.setPosition(pos, ['center', 'top']);
ui.popup.setPosition(pos, ["center", "top"]);
// display popup
$popup.css({
'margin-top': '-1rem',
opacity: '1',
"margin-top": "-1rem",
opacity: "1",
});
}
@ -157,8 +159,8 @@ const GoogleMapsDriver = (($) => {
const ui = this;
const $popup = $(ui.popup.getDiv());
$popup.addClass('d-none');
if (!ui.config['noRestoreBounds'] || ui.config['flyToBounds']) {
$popup.addClass("d-none");
if (!ui.config["noRestoreBounds"] || ui.config["flyToBounds"]) {
ui.restoreBounds();
}
@ -173,20 +175,20 @@ const GoogleMapsDriver = (($) => {
address: addr,
},
(results, status) => {
if (status === 'OK') {
if (status === "OK") {
//results[0].geometry.location;
if (typeof callback === 'function') {
if (typeof callback === "function") {
callback(results);
}
return results;
} else {
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,
},
(results, status) => {
if (status === 'OK') {
if (status === "OK") {
//results[0].formatted_address;
if (typeof callback === 'function') {
if (typeof callback === "function") {
callback(results);
}
return results;
} else {
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) {
const ui = this;
const firstMarker = config['geojson'].features[0].geometry.coordinates;
const firstMarker = config["geojson"].features[0].geometry.coordinates;
//Map.setCenter(firstMarker);
const bounds = new google.maps.LatLngBounds();
// add markers to map
config['geojson'].features.forEach((marker) => {
config["geojson"].features.forEach((marker) => {
const id = marker.id;
const crds = marker.geometry.coordinates;
const content = marker.properties.content;
@ -232,7 +234,7 @@ const GoogleMapsDriver = (($) => {
id,
content,
icon: marker.icon,
flyToMarker: config['flyToMarker'],
flyToMarker: config["flyToMarker"],
});
bounds.extend({

View File

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

View File

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

View File

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

View File

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

View File

@ -2,11 +2,11 @@
* 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';
const CONSTS = {
ENVS: ['xs', 'sm', 'md', 'lg', 'xl', 'xxl', 'xxxl'],
ENVS: ["xs", "sm", "md", "lg", "xl", "xxl", "xxxl"],
MAP_DRIVER,
};

View File

@ -3,41 +3,41 @@
*/
export default {
AJAX: 'ajax-load',
AJAXMAIN: 'ajax-main-load',
MAININIT: 'main-init',
TABHIDDEN: 'tab-hidden',
TABFOCUSED: 'tab-focused',
OFFLINE: 'offline',
ONLINE: 'online',
BACKONLINE: 'back-online',
TOUCHENABLE: 'touch-enabled',
TOUCHDISABLED: 'touch-disabled',
LOADED: 'load',
SWIPELEFT: 'swipeleft panleft',
SWIPERIGHT: 'swiperight panright',
ALLERTAPPEARED: 'alert-appeared',
ALERTREMOVED: 'alert-removed',
LODEDANDREADY: 'load-ready',
LAZYIMAGEREADY: 'image-lazy-bg-loaded',
LAZYIMAGESREADY: 'images-lazy-loaded',
MAPLOADED: 'map-loaded',
MAPAPILOADED: 'map-api-loaded',
MAPMARKERCLICK: 'map-marker-click',
MAPPOPUPCLOSE: 'map-popup-close',
SCROLL: 'scroll',
RESIZE: 'resize',
CAROUSEL_READY: 'bs.carousel.ready',
SET_TARGET_UPDATE: 'set-target-update',
RESTORE_FIELD: 'restore-field',
FORM_INIT_BASICS: 'form-basics',
FORM_INIT_STEPPED: 'form-init-stepped',
FORM_INIT_VALIDATE: 'form-init-validate',
FORM_INIT_VALIDATE_FIELD: 'form-init-validate-field',
FORM_INIT_STORAGE: 'form-init-storage',
FORM_VALIDATION_FAILED: 'form-validation-failed',
FORM_STEPPED_NEW_STEP: 'form-new-step',
FORM_STEPPED_FIRST_STEP: 'form-first-step',
FORM_STEPPED_LAST_STEP: 'form-last-step',
FORM_FIELDS: 'input,textarea,select',
AJAX: "ajax-load",
AJAXMAIN: "ajax-main-load",
MAININIT: "main-init",
TABHIDDEN: "tab-hidden",
TABFOCUSED: "tab-focused",
OFFLINE: "offline",
ONLINE: "online",
BACKONLINE: "back-online",
TOUCHENABLE: "touch-enabled",
TOUCHDISABLED: "touch-disabled",
LOADED: "load",
SWIPELEFT: "swipeleft panleft",
SWIPERIGHT: "swiperight panright",
ALLERTAPPEARED: "alert-appeared",
ALERTREMOVED: "alert-removed",
LODEDANDREADY: "load-ready",
LAZYIMAGEREADY: "image-lazy-bg-loaded",
LAZYIMAGESREADY: "images-lazy-loaded",
MAPLOADED: "map-loaded",
MAPAPILOADED: "map-api-loaded",
MAPMARKERCLICK: "map-marker-click",
MAPPOPUPCLOSE: "map-popup-close",
SCROLL: "scroll",
RESIZE: "resize",
CAROUSEL_READY: "bs.carousel.ready",
SET_TARGET_UPDATE: "set-target-update",
RESTORE_FIELD: "restore-field",
FORM_INIT_BASICS: "form-basics",
FORM_INIT_STEPPED: "form-init-stepped",
FORM_INIT_VALIDATE: "form-init-validate",
FORM_INIT_VALIDATE_FIELD: "form-init-validate-field",
FORM_INIT_STORAGE: "form-init-storage",
FORM_VALIDATION_FAILED: "form-validation-failed",
FORM_STEPPED_NEW_STEP: "form-new-step",
FORM_STEPPED_FIRST_STEP: "form-first-step",
FORM_STEPPED_LAST_STEP: "form-last-step",
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
@ -14,19 +14,19 @@ const EventsUI = (($) => {
const W = window;
const $W = $(W);
const D = document;
const $Body = $('body');
const $Body = $("body");
const NAME = 'EventsUI';
const NAME = "EventsUI";
class EventsUI {
static process(el, args) {
let modEl = el;
const eventName = args[0];
const tagName = typeof el !== undefined ? $(el).prop('tagName') : null;
const tagName = typeof el !== undefined ? $(el).prop("tagName") : null;
switch (tagName) {
case 'HTML':
case 'BODY':
case "HTML":
case "BODY":
modEl = $W;
break;
}
@ -52,11 +52,11 @@ const EventsUI = (($) => {
let el = this;
const args = arguments;
const tagName = typeof el !== undefined ? $(el).prop('tagName') : null;
const tagName = typeof el !== undefined ? $(el).prop("tagName") : null;
switch (tagName) {
case 'HTML':
case 'BODY':
case "HTML":
case "BODY":
el = $W;
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 = (($) => {
// Constants
const W = window;
const D = document;
const $Body = $('body');
const $Body = $("body");
const NAME = 'LayoutUI';
const NAME = "LayoutUI";
const datepickerOptions = {
autoclose: true,
@ -30,7 +30,7 @@ const LayoutUI = (($) => {
// Custom fonts
$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 */
@ -40,7 +40,6 @@ const LayoutUI = (($) => {
ga('send', 'pageview');
});*/
// Fire further js when layout is ready
$(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 Consts from './_consts';
import Events from "./_events";
import Consts from "./_consts";
import EventsRouter from './_events.router';
import Spinner from './_components/_ui.spinner';
import EventsRouter from "./_events.router";
import Spinner from "./_components/_ui.spinner";
// AJAX functionality
import AjaxUI from './_components/_ui.ajax';
import AjaxUI from "./_components/_ui.ajax";
import FormBasics from './_components/_ui.form.basics';
import HeaderUI from './_components/_ui.header-footer';
import FormBasics from "./_components/_ui.form.basics";
import HeaderUI from "./_components/_ui.header-footer";
import SmoothScroll from 'smooth-scroll';
import SmoothScroll from "smooth-scroll";
const smoothScroll = SmoothScroll();
const MainUI = (($) => {
@ -22,68 +22,68 @@ const MainUI = (($) => {
const W = window;
const $W = $(W);
const D = document;
const $Body = $('body');
const $Body = $("body");
const NAME = 'MainUI';
const NAME = "MainUI";
console.clear();
console.info(
`%cUI Kit ${UINAME} ${UIVERSION}`,
'color:yellow;font-size:14px',
"color:yellow;font-size:14px"
);
console.info(
`%c${UIMetaNAME} ${UIMetaVersion}`,
'color:yellow;font-size:12px',
"color:yellow;font-size:12px"
);
console.info(
`%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) => {
console.info(`${k}: ${Events[k]}`);
});
console.groupEnd('Events');
console.groupEnd("Events");
console.groupCollapsed('Consts');
console.groupCollapsed("Consts");
Object.keys(Consts).forEach((k) => {
console.info(`${k}: ${Consts[k]}`);
});
console.groupEnd('Events');
console.groupEnd("Events");
console.groupCollapsed('Init');
console.time('init');
console.groupCollapsed("Init");
console.time("init");
$W.on(`${Events.LODEDANDREADY}`, () => {
console.groupEnd('Init');
console.timeEnd('init');
console.groupEnd("Init");
console.timeEnd("init");
console.time('Post-init');
console.groupCollapsed('Post-init');
console.time("Post-init");
console.groupCollapsed("Post-init");
});
// get browser locale
//const Locale = $('html').attr('lang').substring(0, 2);
const $AlertNotify = $('#AlertNotify');
const $SiteWideMessage = $('#SiteWideMessage');
const $AlertNotify = $("#AlertNotify");
const $SiteWideMessage = $("#SiteWideMessage");
// get browser window visibility preferences
// Opera 12.10, Firefox >=18, Chrome >=31, IE11
const HiddenName = 'hidden';
const VisibilityChangeEvent = 'visibilitychange';
const HiddenName = "hidden";
const VisibilityChangeEvent = "visibilitychange";
// update visibility state
D.addEventListener(VisibilityChangeEvent, () => {
if (D.visibilityState === HiddenName) {
console.log(`${NAME}: Tab: hidden`);
$Body.addClass('is-hidden');
$Body.addClass("is-hidden");
$Body.trigger(Events.TABHIDDEN);
$W.trigger(Events.TABHIDDEN);
} else {
console.log(`${NAME}: Tab: focused`);
$Body.removeClass('is-hidden');
$Body.removeClass("is-hidden");
$Body.trigger(Events.TABFOCUSED);
$W.trigger(Events.TABFOCUSED);
}
@ -93,7 +93,7 @@ const MainUI = (($) => {
let pingInterval;
let pingLock = false;
const sessionPing = () => {
if (pingLock || $Body.hasClass('is-offline')) {
if (pingLock || $Body.hasClass("is-offline")) {
return;
}
@ -103,12 +103,12 @@ const MainUI = (($) => {
sync: false,
async: true,
cache: false,
url: '/Security/ping',
url: "/Security/ping",
global: false,
type: 'POST',
type: "POST",
complete: (data, datastatus) => {
updateOnlineStatus();
if (datastatus !== 'success') {
if (datastatus !== "success") {
console.warn(`${NAME}: ping failed`);
clearInterval(pingInterval);
@ -128,7 +128,7 @@ const MainUI = (($) => {
}
statusLock = true;
if (typeof navigator.onLine === 'undefined') {
if (typeof navigator.onLine === "undefined") {
return false;
}
@ -138,8 +138,8 @@ const MainUI = (($) => {
clearInterval(pingInterval);
pingInterval = null;
$Body.addClass('is-offline');
$Body.removeClass('is-online');
$Body.addClass("is-offline");
$Body.removeClass("is-online");
$Body.trigger(Events.OFFLINE);
$W.trigger(Events.OFFLINE);
@ -152,7 +152,7 @@ const MainUI = (($) => {
pingInterval = setInterval(sessionPing, 300000); // 5 min in ms
}
if ($Body.hasClass('is-offline')) {
if ($Body.hasClass("is-offline")) {
sessionPing();
console.log(`${NAME}: is back online`);
@ -161,8 +161,8 @@ const MainUI = (($) => {
console.log(`${NAME}: Online`);
}
$Body.addClass('is-online');
$Body.removeClass('is-offline');
$Body.addClass("is-online");
$Body.removeClass("is-offline");
$Body.trigger(Events.ONLINE);
$W.trigger(Events.ONLINE);
@ -176,7 +176,7 @@ const MainUI = (($) => {
() => {
updateOnlineStatus();
},
false,
false
);
W.addEventListener(
@ -184,7 +184,7 @@ const MainUI = (($) => {
() => {
updateOnlineStatus();
},
false,
false
);
$W.on(`${Events.LOADED} ${Events.AJAX}`, () => {
@ -204,9 +204,9 @@ const MainUI = (($) => {
};
W.URLDetails = {
base: $('base').attr('href'),
relative: '/',
hash: '',
base: $("base").attr("href"),
relative: "/",
hash: "",
};
let eventFired = false;
@ -236,7 +236,7 @@ const MainUI = (($) => {
}, 200);
};
setTouchScreen('ontouchstart' in window || navigator.msMaxTouchPoints > 0);
setTouchScreen("ontouchstart" in window || navigator.msMaxTouchPoints > 0);
// disable touch on mouse events
/*D.addEventListener('mousemove', () => {
@ -248,10 +248,10 @@ const MainUI = (($) => {
});*/
// enable touch screen on touch events
D.addEventListener('touchmove', () => {
D.addEventListener("touchmove", () => {
setTouchScreen(true);
});
D.addEventListener('touchstart', () => {
D.addEventListener("touchstart", () => {
setTouchScreen(true);
});
@ -268,8 +268,8 @@ const MainUI = (($) => {
ui.updateLocation();
// mark available offline areas
if ('caches' in W) {
$('a.offline').addClass('offline-available');
if ("caches" in W) {
$("a.offline").addClass("offline-available");
}
ui.loadImages();
@ -278,7 +278,7 @@ const MainUI = (($) => {
ui.detectBootstrapScreenSize();
// mark external links
$('a.external,a[rel="external"]').attr('target', '_blank');
$('a.external,a[rel="external"]').attr("target", "_blank");
// show encoded emails
/*$(D).find('.obm').each(() => {
@ -304,26 +304,26 @@ const MainUI = (($) => {
//
// scroll links
$('.js-scrollTo').on('click', (e) => {
$(".js-scrollTo").on("click", (e) => {
console.log(`${NAME}: .js-scrollTo`);
e.preventDefault();
const el = e.currentTarget;
const $el = $(e.currentTarget);
ScrollTo(el, $el.attr('data-target'));
ScrollTo(el, $el.attr("data-target"));
});
// load external fonts
if ($('[data-extfont]').length) {
if ($("[data-extfont]").length) {
console.log(`${NAME}: loading external fonts [data-extfont]`);
$.getScript(
'//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js',
"//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js",
() => {
const fonts = [];
$('[data-extfont]').each((i, el) => {
fonts[i] = $(el).attr('data-extfont');
$("[data-extfont]").each((i, el) => {
fonts[i] = $(el).attr("data-extfont");
});
W.WebFont.load({
@ -331,16 +331,16 @@ const MainUI = (($) => {
families: fonts,
},
});
},
}
);
}
// data-set links
$('[data-set-target]').on('click', (e) => {
$("[data-set-target]").on("click", (e) => {
console.log(`${NAME}: [data-set-target]`);
const $el = $(e.currentTarget);
const $target = $($el.data('set-target'));
const $target = $($el.data("set-target"));
if (!$target.length) {
return;
@ -348,25 +348,25 @@ const MainUI = (($) => {
$target.each((i, targetEl) => {
const $targetEl = $(targetEl);
const tag = $targetEl.prop('tagName').toLowerCase();
const tag = $targetEl.prop("tagName").toLowerCase();
if (tag === 'input' || tag === 'select') {
$targetEl.val($el.data('set-val'));
} else if (!$targetEl.hasClass('field')) {
$targetEl.text($el.data('set-val'));
if (tag === "input" || tag === "select") {
$targetEl.val($el.data("set-val"));
} else if (!$targetEl.hasClass("field")) {
$targetEl.text($el.data("set-val"));
}
});
$el.trigger(Events.SET_TARGET_UPDATE);
$target.closest('form').trigger(Events.SET_TARGET_UPDATE);
$target.closest("form").trigger(Events.SET_TARGET_UPDATE);
});
// emulate links
$('.a[data-href]').on('click', (e) => {
$(".a[data-href]").on("click", (e) => {
console.log(`${NAME}: js link processing .a[data-href]`);
const $el = $(e.currentTarget);
const href = $el.data('href');
const href = $el.data("href");
if (!href.length) {
console.warn(`${NAME}: .a[data-href] | Missing data-href`);
console.warn($el);
@ -376,24 +376,24 @@ const MainUI = (($) => {
});
// set attributes for mobile friendly tables
$('.typography table').each((i, el) => {
$(".typography table").each((i, el) => {
const $table = $(el);
let $header = $table.find('thead tr:first-child');
let $header = $table.find("thead tr:first-child");
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);
$table
.find('tr')
.find("tr")
.find(`td:eq(${i})`)
.each((i, el) => {
const $el = $(el);
if (!$el.attr('data-label')) {
$el.attr('data-label', $h.text());
if (!$el.attr("data-label")) {
$el.attr("data-label", $h.text());
}
});
});
@ -402,16 +402,16 @@ const MainUI = (($) => {
// hide spinner
Spinner.hide(() => {
$Body.addClass('loaded');
$Body.addClass("loaded");
});
// fire page printing
if (W.URLDetails['hash'].indexOf('printpage') > -1) {
if (W.URLDetails["hash"].indexOf("printpage") > -1) {
W.print();
}
$Body.data(NAME, ui);
$W.removeClass('lock-main-init');
$W.removeClass("lock-main-init");
}
static detectBootstrapScreenSize() {
@ -425,7 +425,7 @@ const MainUI = (($) => {
for (let i = 0; i < envs.length; ++i) {
const env = envs[i];
$el.addClass(`d-${env}-none`);
if ($el.is(':hidden')) {
if ($el.is(":hidden")) {
curEnv = env;
break;
}
@ -437,17 +437,17 @@ const MainUI = (($) => {
let landscape = true;
if ($W.width() > $W.height()) {
$Body.removeClass('portrait');
$Body.addClass('landscape');
$Body.removeClass("portrait");
$Body.addClass("landscape");
} else {
landscape = false;
$Body.removeClass('landscape');
$Body.addClass('portrait');
$Body.removeClass("landscape");
$Body.addClass("portrait");
}
console.log(
`${NAME}: screen size detected ${curEnv} | landscape ${landscape}`,
`${NAME}: screen size detected ${curEnv} | landscape ${landscape}`
);
return curEnv;
@ -455,30 +455,30 @@ const MainUI = (($) => {
static updateLocation(url) {
let location = url || W.location.href;
location = location.replace(W.URLDetails['base'], '/');
const hash = location.indexOf('#');
location = location.replace(W.URLDetails["base"], "/");
const hash = location.indexOf("#");
W.URLDetails.relative = location.split('#')[0];
W.URLDetails.relative = location.split("#")[0];
W.URLDetails.hash =
hash >= 0 ? location.substr(location.indexOf('#')) : '';
hash >= 0 ? location.substr(location.indexOf("#")) : "";
}
// show site-wide alert
static alert(msg, cls) {
$SiteWideMessage.fadeOut('fast');
$SiteWideMessage.fadeOut("fast");
$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.fadeOut('slow', () => {
$SiteWideMessage.find('.page-alert').alert('close');
$SiteWideMessage.fadeOut("slow", () => {
$SiteWideMessage.find(".page-alert").alert("close");
});
});
$SiteWideMessage.fadeIn('slow');
$SiteWideMessage.fadeIn("slow");
if ($AlertNotify.length) {
$AlertNotify[0].play();
@ -490,12 +490,12 @@ const MainUI = (($) => {
// hide site-wide alert
static alertHide() {
if ($SiteWideMessage.length !== 0) {
$SiteWideMessage.fadeOut('slow', () => {
$SiteWideMessage.find('.alert').alert('close');
$SiteWideMessage.fadeOut("slow", () => {
$SiteWideMessage.find(".alert").alert("close");
});
}
if ($AlertNotify.length && typeof $AlertNotify[0].stop !== 'undefined') {
if ($AlertNotify.length && typeof $AlertNotify[0].stop !== "undefined") {
$AlertNotify[0].stop();
}
@ -504,17 +504,17 @@ const MainUI = (($) => {
// load all images
static loadImages() {
const $imgs = $Body.find('img').not('.loaded');
const $imgs = $Body.find("img").not(".loaded");
const $imgUrls = [];
const $imgLazyUrls = [];
// collect image details
$imgs.each((i, el) => {
const $el = $(el);
const src = $el.attr('src');
const lazySrc = $el.data('lazy-src');
const src = $el.attr("src");
const lazySrc = $el.data("lazy-src");
if ($el.hasClass('loaded')) {
if ($el.hasClass("loaded")) {
return;
}
@ -523,14 +523,14 @@ const MainUI = (($) => {
}
if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc);
$el.addClass('loading');
$el.addClass("loading");
AjaxUI.preload([lazySrc]).then(() => {
$el.attr('src', lazySrc);
$el.attr("src", lazySrc);
$el.on(`${Events.LOADED}`, () => {
$el.addClass('loaded');
$el.removeClass('loading');
$el.addClass("loaded");
$el.removeClass("loading");
$el.trigger(`${Events.LAZYIMAGEREADY}`);
});
@ -540,25 +540,25 @@ const MainUI = (($) => {
// load lazy backgrounds
$Body
.find('[data-lazy-bg]')
.not('.loaded')
.find("[data-lazy-bg]")
.not(".loaded")
.each((i, 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;
}
if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc);
$el.addClass('loading');
$el.addClass("loading");
AjaxUI.preload([lazySrc]).then(() => {
$el.css({ 'background-image': `url(${lazySrc})` });
$el.css({ "background-image": `url(${lazySrc})` });
$el.addClass('loaded');
$el.removeClass('loading');
$el.addClass("loaded");
$el.removeClass("loading");
$el.trigger(`${Events.LAZYIMAGEREADY}`);
});
@ -567,25 +567,25 @@ const MainUI = (($) => {
// replace img src
$Body
.find('[data-src-replace]')
.not('.loaded')
.find("[data-src-replace]")
.not(".loaded")
.each((i, 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;
}
if (lazySrc && lazySrc.length) {
$el.addClass('loaded');
$el.attr('src', lazySrc);
$el.addClass("loaded");
$el.attr("src", lazySrc);
}
});
// load defined images
AjaxUI.preload($imgUrls).then(() => {
$W.trigger('images-loaded');
$W.trigger("images-loaded");
// load lazy images
AjaxUI.preload($imgLazyUrls).then(() => {
@ -594,8 +594,8 @@ const MainUI = (($) => {
setTimeout(() => {
$W.trigger(`${Events.LAZYIMAGESREADY}`);
console.groupEnd('Post-init');
console.timeEnd('Post-init');
console.groupEnd("Post-init");
console.timeEnd("Post-init");
}, 100);
});
});
@ -609,35 +609,35 @@ const MainUI = (($) => {
$W.on(
`${Events.MAININIT} ${Events.AJAX} ${Events.AJAXMAIN} ${Events.LOADED}`,
() => {
if ($W.hasClass('lock-main-init')) {
if ($W.hasClass("lock-main-init")) {
console.warn(`${NAME}: locked`);
return;
}
$W.addClass('lock-main-init');
$W.addClass("lock-main-init");
MainUI.init();
},
}
);
$W.on(`${Events.RESIZE}`, () => {
MainUI.detectBootstrapScreenSize();
});
$W.on('beforeunload unload', () => {
$W.on("beforeunload unload", () => {
Spinner.show(() => {
$Body.removeClass('loaded');
$Body.removeClass("loaded");
});
});
// hide spinner on target _blank
$('[target="_blank"],.external')
.not('[data-toggle="lightbox"],[data-lightbox-gallery]')
.on('click submit touch', (e) => {
.on("click submit touch", (e) => {
console.log(`${NAME}: External link`);
setTimeout(() => {
Spinner.hide(() => {
$Body.addClass('loaded');
$Body.addClass("loaded");
});
}, 1000);
});

View File

@ -1,10 +1,10 @@
'use strict';
"use strict";
//import $ from 'jquery';
import '../scss/app.scss';
import "../scss/app.scss";
import { Dropdown } from 'bootstrap';
import Page from './_components/_page.jsx';
import { Dropdown } from "bootstrap";
import Page from "./_components/_page.jsx";
//import 'hammerjs/hammer';
//import 'jquery-hammerjs/jquery.hammer';
@ -64,11 +64,11 @@ import 'bootstrap/js/dist/tab';*/
//import './_components/_ui.video.preview';
// Meta Lightbox
import '@a2nt/meta-lightbox-react/src/js/app';
import "@a2nt/meta-lightbox-react/src/js/app";
const GraphPage = ReactDOM.render(
<Page />,
document.getElementById('MainContent'),
document.getElementById("MainContent")
);
//import Confirmation from 'bootstrap-confirmation2/dist/bootstrap-confirmation';
@ -90,8 +90,8 @@ function importAll(r) {
}
const images = importAll(
require.context('../img/', false, /\.(png|jpe?g|svg)$/),
require.context("../img/", false, /\.(png|jpe?g|svg)$/)
);
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 {
en: {
jsSteppedForm: {
STEPCOUNTER: '<div class="steps-counter">Step <b class="current-step"></b> of <b class="total-steps"></b></div>',
STEPBUTTONS: '<div class="steps-buttons">' +
STEPCOUNTER:
'<div class="steps-counter">Step <b class="current-step"></b> of <b class="total-steps"></b></div>',
STEPBUTTONS:
'<div class="steps-buttons">' +
'<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>',
"</div>",
},
},
};

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
// src/mocks/handlers.js
import { graphql } from 'msw';
import { graphql } from "msw";
export const handlers = [
// Handles a "Login" mutation
@ -15,7 +15,7 @@ export const handlers = [
);
}),*/
// Handles a "Pages" query
graphql.query('Pages11', (req, res, ctx) => {
graphql.query("Pages11", (req, res, ctx) => {
const apiKey = req.headers.map.apikey;
if (
!req.headers.map.apikey ||
@ -25,10 +25,10 @@ export const handlers = [
return res(
ctx.errors([
{
message: 'Not authenticated',
errorType: 'AuthenticationError',
message: "Not authenticated",
errorType: "AuthenticationError",
},
]),
])
);
}
// When authenticated, respond with a query payload
@ -38,38 +38,38 @@ export const handlers = [
edges: [
{
node: {
ID: '1',
Title: 'Home-Mocked',
ClassName: 'Site\\Pages\\HomePage',
CSSClass: 'Site-Pages-HomePage',
ID: "1",
Title: "Home-Mocked",
ClassName: "Site\\Pages\\HomePage",
CSSClass: "Site-Pages-HomePage",
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.",
Link: '/en/',
URLSegment: 'home',
Link: "/en/",
URLSegment: "home",
Elements: {
edges: [
{
node: {
ID: '3',
Title: 'Slider',
ID: "3",
Title: "Slider",
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: {
ID: '7',
Title: 'Categories List',
ID: "7",
Title: "Categories List",
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: {
ID: '4',
ID: "4",
Title: "Hello, I'm Tony Air",
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,
},
},
}),
})
);
}),
];

View File

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

View File

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

View File

@ -1,84 +1,84 @@
<h2>Test <b>HTML</b>-content with PAJAX response</h2>
<p>
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.
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>
https://twitter.com/reactjs/status/964689022747475968
<p>
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.
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>
<p>
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.
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>
<p>
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.
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>
<p>
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.
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>
<p>
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.
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>
<p>
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.
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>
<p>
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.
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>