mirror of
https://github.com/locomotivemtl/locomotive-boilerplate.git
synced 2026-01-15 00:55:08 +08:00
Start adding modularjs & modularload, start updating readme, update html files, change jquery cdn, remove IE from babelrc
This commit is contained in:
12
.babelrc
12
.babelrc
@@ -1,13 +1,3 @@
|
|||||||
{
|
{
|
||||||
"presets": [
|
"presets": ["@babel/preset-env"]
|
||||||
[
|
|
||||||
"@babel/preset-env",
|
|
||||||
{
|
|
||||||
"targets": {
|
|
||||||
"ie": "11"
|
|
||||||
},
|
|
||||||
"useBuiltIns": "usage"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
README.md
18
README.md
@@ -1,12 +1,14 @@
|
|||||||
Locomotive's Front-end Boilerplate
|
<p align="center">
|
||||||
==================================
|
<a href="https://github.com/locomotivemtl/locomotive-boilerplate">
|
||||||
|
<img src="https://user-images.githubusercontent.com/4596862/54868065-c2aea200-4d5e-11e9-9ce3-e0013c15f48c.png" height="140">
|
||||||
Front-end boilerplate for projects by [Locomotive][locomtl].
|
</a>
|
||||||
|
</p>
|
||||||
|
<h1 align="center">Locomotive Boilerplate</h1>
|
||||||
|
<p align="center">Front-end boilerplate for projects by Locomotive.</p>
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
```sh
|
```sh
|
||||||
# install mbp and gulp
|
npm install mbp gulp -g
|
||||||
npm install mbp gulp@next -g
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -19,9 +21,7 @@ gulp
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
Change the mentions of `boilerplate` for your project's name in
|
Change the mentions of `boilerplate` for your project's name in `mconfig.json`.
|
||||||
- `mconfig.json`
|
|
||||||
- `assets/scripts/utils/environment.js`
|
|
||||||
|
|
||||||
## CSS
|
## CSS
|
||||||
|
|
||||||
|
|||||||
@@ -1,161 +1,10 @@
|
|||||||
import { APP_NAME, $document, $pjaxWrapper } from './utils/environment';
|
import modular from 'modujs';
|
||||||
|
import * as modules from './modules';
|
||||||
import globals from './globals';
|
import globals from './globals';
|
||||||
|
|
||||||
import { arrayContains, removeFromArray } from './utils/array';
|
const app = new modular({
|
||||||
import { getNodeData } from './utils/html';
|
modules: modules
|
||||||
import { isFunction } from './utils/is';
|
});
|
||||||
|
|
||||||
// Basic modules
|
app.init(app);
|
||||||
import * as modules from './modules';
|
globals();
|
||||||
|
|
||||||
const MODULE_NAME = 'App';
|
|
||||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
|
||||||
|
|
||||||
export const EVENT = {
|
|
||||||
INIT_MODULES: `initModules.${EVENT_NAMESPACE}`,
|
|
||||||
INIT_SCOPED_MODULES: `initScopedModules.${EVENT_NAMESPACE}`,
|
|
||||||
DELETE_SCOPED_MODULES: `deleteScopedModules.${EVENT_NAMESPACE}`
|
|
||||||
};
|
|
||||||
|
|
||||||
class App {
|
|
||||||
constructor() {
|
|
||||||
this.modules = modules;
|
|
||||||
this.currentModules = [];
|
|
||||||
|
|
||||||
$document.on(EVENT.INIT_MODULES, (event) => {
|
|
||||||
this.initGlobals(event.firstBlood)
|
|
||||||
.deleteModules(event)
|
|
||||||
.initModules(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
$document.on(EVENT.INIT_SCOPED_MODULES, (event) => {
|
|
||||||
this.initModules(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
$document.on(EVENT.DELETE_SCOPED_MODULES, (event) => {
|
|
||||||
this.deleteModules(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy all existing modules or a specific scope of modules
|
|
||||||
* @param {Object} event The event being triggered.
|
|
||||||
* @return {Object} Self (allows chaining)
|
|
||||||
*/
|
|
||||||
deleteModules(event) {
|
|
||||||
let destroyAll = true;
|
|
||||||
let moduleIds = [];
|
|
||||||
|
|
||||||
// Check for scope first
|
|
||||||
if (event.$scope instanceof jQuery && event.$scope.length > 0) {
|
|
||||||
// Modules within scope
|
|
||||||
const $modules = event.$scope.find('[data-module]');
|
|
||||||
|
|
||||||
// Determine their uids
|
|
||||||
moduleIds = $.makeArray($modules.map(function(index) {
|
|
||||||
return $modules.eq(index).data('uid');
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (moduleIds.length > 0) {
|
|
||||||
destroyAll = false;
|
|
||||||
} else {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop modules and destroying all of them, or specific ones
|
|
||||||
let i = this.currentModules.length;
|
|
||||||
|
|
||||||
while (i--) {
|
|
||||||
if (destroyAll || arrayContains(moduleIds, this.currentModules[i].uid)) {
|
|
||||||
removeFromArray(moduleIds, this.currentModules[i].uid);
|
|
||||||
this.currentModules[i].destroy();
|
|
||||||
this.currentModules.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute global functions and settings
|
|
||||||
* Allows you to initialize global modules only once if you need
|
|
||||||
* (ex.: when using Barba.js or SmoothState.js)
|
|
||||||
* @return {Object} Self (allows chaining)
|
|
||||||
*/
|
|
||||||
initGlobals(firstBlood) {
|
|
||||||
globals(firstBlood);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find modules and initialize them
|
|
||||||
* @param {Object} event The event being triggered.
|
|
||||||
* @return {Object} Self (allows chaining)
|
|
||||||
*/
|
|
||||||
initModules(event) {
|
|
||||||
// Elements with module
|
|
||||||
let $moduleEls = [];
|
|
||||||
|
|
||||||
// If first blood, load all modules in the DOM
|
|
||||||
// If scoped, render elements with modules
|
|
||||||
// If Barba, load modules contained in Barba container
|
|
||||||
if (event.firstBlood) {
|
|
||||||
$moduleEls = $document.find('[data-module]');
|
|
||||||
} else if (event.$scope instanceof jQuery && event.$scope.length > 0) {
|
|
||||||
$moduleEls = event.$scope.find('[data-module]');
|
|
||||||
} else if (event.isPjax) {
|
|
||||||
$moduleEls = $pjaxWrapper.find('[data-module]');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through elements
|
|
||||||
let i = 0;
|
|
||||||
const elsLen = $moduleEls.length;
|
|
||||||
|
|
||||||
for (; i < elsLen; i++) {
|
|
||||||
|
|
||||||
// Current element
|
|
||||||
let el = $moduleEls[i];
|
|
||||||
|
|
||||||
// All data- attributes considered as options
|
|
||||||
let options = getNodeData(el);
|
|
||||||
|
|
||||||
// Add current DOM element and jQuery element
|
|
||||||
options.el = el;
|
|
||||||
options.$el = $moduleEls.eq(i);
|
|
||||||
|
|
||||||
// Module does exist at this point
|
|
||||||
let attr = options.module;
|
|
||||||
|
|
||||||
// Splitting modules found in the data-attribute
|
|
||||||
let moduleIdents = attr.split(/[,\s]+/g);
|
|
||||||
|
|
||||||
// Loop modules
|
|
||||||
let j = 0;
|
|
||||||
let modulesLen = moduleIdents.length;
|
|
||||||
|
|
||||||
for (; j < modulesLen; j++) {
|
|
||||||
let moduleAttr = moduleIdents[j];
|
|
||||||
|
|
||||||
if (typeof this.modules[moduleAttr] === 'function') {
|
|
||||||
let module = new this.modules[moduleAttr](options);
|
|
||||||
this.currentModules.push(module);
|
|
||||||
module.init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IIFE for loading the application
|
|
||||||
// ==========================================================================
|
|
||||||
(function() {
|
|
||||||
new App();
|
|
||||||
$document.triggerHandler({
|
|
||||||
type: EVENT.INIT_MODULES,
|
|
||||||
firstBlood: true
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
import TransitionManager from './transitions/TransitionManager';
|
|
||||||
import svg4everybody from 'svg4everybody';
|
import svg4everybody from 'svg4everybody';
|
||||||
|
|
||||||
export default function(firstBlood) {
|
export default function() {
|
||||||
svg4everybody();
|
svg4everybody();
|
||||||
|
|
||||||
if (firstBlood) {
|
|
||||||
const transitionManager = new TransitionManager();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
export {default as Example} from './modules/Example';
|
export {default as load} from './modules/load';
|
||||||
export {default as Scroll} from './modules/Scroll';
|
export {default as scroll} from './modules/scroll';
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
let uid = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract Module
|
|
||||||
*/
|
|
||||||
export default class {
|
|
||||||
constructor(options) {
|
|
||||||
this.$el = options.$el || null;
|
|
||||||
this.el = options.el || null;
|
|
||||||
|
|
||||||
// Generate a unique module identifier
|
|
||||||
this.uid = 'm-' + uid++;
|
|
||||||
// Use jQuery's data API to "store it in the DOM"
|
|
||||||
this.$el.data('uid', this.uid);
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
if (this.$el) {
|
|
||||||
this.$el.removeData('uid')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +1,11 @@
|
|||||||
import { APP_NAME } from '../utils/environment';
|
import { module } from 'modujs';
|
||||||
import AbstractModule from './AbstractModule';
|
|
||||||
|
|
||||||
const MODULE_NAME = 'Example';
|
|
||||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
|
||||||
|
|
||||||
const EVENT = {
|
|
||||||
CLICK: `click.${EVENT_NAMESPACE}`
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class extends AbstractModule {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
|
|
||||||
// Declaration of properties
|
|
||||||
console.log('🔨 [module]:constructor - Example');
|
|
||||||
|
|
||||||
|
export default class extends module {
|
||||||
|
constructor(m) {
|
||||||
|
super(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// Set events and such
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
|
||||||
console.log('❌ [module]:destroy - Example');
|
|
||||||
super.destroy();
|
|
||||||
this.$el.off(`.${EVENT_NAMESPACE}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,25 @@
|
|||||||
import { APP_NAME, $document } from '../utils/environment';
|
import { module } from 'modujs';
|
||||||
import AbstractModule from './AbstractModule';
|
import { $document } from '../utils/environment'
|
||||||
import ScrollManager from '../scroll/vendors/ScrollManager';
|
import ScrollManager from '../scroll/vendors/ScrollManager';
|
||||||
|
|
||||||
const MODULE_NAME = 'Scroll';
|
export default class extends module {
|
||||||
const EVENT_NAMESPACE = `${APP_NAME}.${MODULE_NAME}`;
|
constructor(m) {
|
||||||
|
super(m);
|
||||||
export default class extends AbstractModule {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
setTimeout(() => {
|
this.scrollManager = new ScrollManager({
|
||||||
this.scrollManager = new ScrollManager({
|
container: this.$el,
|
||||||
container: this.$el,
|
selector: '.js-animate',
|
||||||
selector: '.js-animate',
|
smooth: false,
|
||||||
smooth: false,
|
smoothMobile: false,
|
||||||
smoothMobile: false,
|
mobileContainer: $document,
|
||||||
mobileContainer: $document,
|
getWay: false,
|
||||||
getWay: false,
|
getSpeed: false
|
||||||
getSpeed: false
|
});
|
||||||
});
|
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
super.destroy();
|
|
||||||
this.scrollManager.destroy();
|
this.scrollManager.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
assets/scripts/modules/load.js
Normal file
22
assets/scripts/modules/load.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { module } from 'modujs';
|
||||||
|
import modularLoad from 'modularload';
|
||||||
|
|
||||||
|
export default class extends module {
|
||||||
|
constructor(m) {
|
||||||
|
super(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
const load = new modularLoad({
|
||||||
|
enterDelay: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
load.on('loaded', (transition, oldContainer, newContainer) => {
|
||||||
|
this.call('destroy', oldContainer, 'app');
|
||||||
|
})
|
||||||
|
|
||||||
|
load.on('ready', (transition, newContainer) => {
|
||||||
|
this.call('update', newContainer, 'app');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,8 +6,9 @@
|
|||||||
"author": "Locomotive <info@locomotive.ca>",
|
"author": "Locomotive <info@locomotive.ca>",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"locomotive-scroll": "git+https://git@github.com/locomotivemtl/locomotive-scroll.git",
|
"locomotive-scroll": "git+https://git@github.com/locomotivemtl/locomotive-scroll.git",
|
||||||
|
"modujs": "*",
|
||||||
|
"modularload": "*",
|
||||||
"normalize.css": "*",
|
"normalize.css": "*",
|
||||||
"pjax": "*",
|
|
||||||
"smooth-scrollbar": "git+https://git@github.com/locomotivemtl/smooth-scrollbar.git#develop",
|
"smooth-scrollbar": "git+https://git@github.com/locomotivemtl/smooth-scrollbar.git#develop",
|
||||||
"svg4everybody": "*"
|
"svg4everybody": "*"
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
1
www/assets/scripts/app.js.map
Normal file
1
www/assets/scripts/app.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html class="has-no-js" lang="en" data-debug="true">
|
<html class="has-no-js" lang="en" data-page="home">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Boilerplate</title>
|
<title>Boilerplate</title>
|
||||||
@@ -16,31 +16,33 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" href="assets/styles/main.css">
|
<link rel="stylesheet" href="assets/styles/main.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-module-load>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<ul>
|
<h1>Boilerplate</h1>
|
||||||
<li>
|
<nav>
|
||||||
<a href="/">Home</a>
|
<ul>
|
||||||
</li>
|
<li><a href="page.html">Page</a></li>
|
||||||
<li>
|
<li><a href="page.html" data-load="customTransition">Custom page</a></li>
|
||||||
<a href="page.html" data-transition="CustomTransition">Page</a>
|
</ul>
|
||||||
</li>
|
</nav>
|
||||||
<li>
|
|
||||||
<a href="page.html" class="no-transition">No transition link</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div id="js-pjax-wrapper">
|
<main>
|
||||||
<div class="js-pjax-container" data-template="home">
|
<div data-load-container>
|
||||||
<div class="o-scroll" data-module="Scroll">
|
<div data-module-scroll>
|
||||||
<div data-module="Example">Home page with Example module</div>
|
|
||||||
|
<p>Home</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
<footer>
|
||||||
|
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank">🚂</a></p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
<script>window.jQuery || document.write('<script src="assets/scripts/jquery-3.3.1.min.js"><\/script>')</script>
|
<script>window.jQuery || document.write('<script src="assets/scripts/jquery-3.3.1.min.js"><\/script>')</script>
|
||||||
<script src="assets/scripts/vendors.js"></script>
|
<script src="assets/scripts/vendors.js"></script>
|
||||||
<script src="assets/scripts/app.js"></script>
|
<script src="assets/scripts/app.js"></script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html class="has-no-js" lang="en" data-debug="true">
|
<html class="has-no-js" lang="en" data-page="page">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Page | Boilerplate</title>
|
<title>Page | Boilerplate</title>
|
||||||
@@ -16,31 +16,34 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" href="assets/styles/main.css">
|
<link rel="stylesheet" href="assets/styles/main.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body data-module-load>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<ul>
|
<h1>Boilerplate</h1>
|
||||||
<li>
|
<nav>
|
||||||
<a href="/">Home</a>
|
<ul>
|
||||||
</li>
|
<li><a href="page.html">Page</a></li>
|
||||||
<li>
|
<li><a href="page.html" data-load="customTransition">Custom page</a></li>
|
||||||
<a href="page.html" data-transition="CustomTransition">Page</a>
|
</ul>
|
||||||
</li>
|
</nav>
|
||||||
<li>
|
|
||||||
<a href="page.html" class="no-transition">No transition link</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div id="js-pjax-wrapper">
|
<main>
|
||||||
<div class="js-pjax-container" data-template="page" data-transition="pageTransition">
|
<div data-load-container>
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus tempore officia temporibus error rem id, vel perspiciatis eveniet placeat, ducimus fugit vitae sequi, quas deserunt ab eius expedita quia nulla.
|
<div data-module-scroll>
|
||||||
|
|
||||||
|
<p>Page</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
|
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
<footer>
|
||||||
<script>window.jQuery || document.write('<script src="assets/scripts/jquery-3.2.1.min.js"><\/script>')</script>
|
<p>Made with <a href="https://github.com/locomotivemtl/locomotive-boilerplate" title="Locomotive Boilerplate" target="_blank">🚂</a></p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<script>window.jQuery || document.write('<script src="assets/scripts/jquery-3.3.1.min.js"><\/script>')</script>
|
||||||
<script src="assets/scripts/vendors.js"></script>
|
<script src="assets/scripts/vendors.js"></script>
|
||||||
<script src="assets/scripts/app.js"></script>
|
<script src="assets/scripts/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user