Skip to content

Commit

Permalink
Added a more complex project structure based on current best practices
Browse files Browse the repository at this point in the history
- juicy and ready to eat
  • Loading branch information
enzy committed Jul 26, 2015
1 parent 5fcdf53 commit 2c95271
Show file tree
Hide file tree
Showing 26 changed files with 514 additions and 105 deletions.
8 changes: 7 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# EditorConfig is awesome: http://EditorConfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
trim_trailing_whitespace = true

[*.{json,yml}]
indent_style = space
22 changes: 17 additions & 5 deletions mango.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@
"src_folder": "src",
"dist_folder": "dist",
"styles": [
"src/styles/screen.styl"
"src/styles/index.styl",
"src/styles/oldie.styl",
"src/styles/print.styl"
],
"scripts": [
"src/scripts/index.js"
"src/scripts/index.es6"
],
"images": [
"src/images/**/*.{jpg,png,svg}"
],
"static": null,
"static": [
"src/fonts/**",
"node_modules/lt-ie-9/lt-ie-9.min.js"
],
"templates": [
"src/**/*.{html,jade}"
"src/templates/*.jade"
],
"dependencies": [
"lt-ie-9",
"stylus-normalize",
"jquery"
],
"watch": null
"data": {
"global": "src/data/global.json"
},
"hooks": {
"init": "mango install"
}
}
4 changes: 4 additions & 0 deletions src/data/global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"title": "mango-cli example project",
"url": "http://mangoweb.github.io/mango"
}
Empty file added src/fonts/.gitignore
Empty file.
Empty file added src/images/.gitignore
Empty file.
28 changes: 0 additions & 28 deletions src/images/the-shape.svg

This file was deleted.

12 changes: 0 additions & 12 deletions src/index.html

This file was deleted.

62 changes: 62 additions & 0 deletions src/scripts/components/component.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
var $ = jQuery

/**
* Abstract component class
*
* - use for creating own components with standartized API
* - dependes on jQuery.on() for attaching listeners (can be replaced with Zepto, Gator, etc.)
*
* @abstract
*
* @author Matěj Šimek <[email protected]> (http://www.matejsimek.com)
*/
class Component {

/**
* @param {HTMLElement} element
* @param {Object} data
*/
constructor(element, data = {}) {
this.el = element
this.data = data

this.attachListeners()
}

/**
* Assign event handlers from this.listeners property
*
* Format:
* - "type": "handlerName"
* - "type<space>.selector": "handlerName"
*/
attachListeners() {
let self = this
let eventSplitter = /^(\S+)\s*(.*)$/

for(let event in this.listeners) {
let type = event.trim()
let selector = false
let callback = this[this.listeners[event]]

let split = event.match(eventSplitter)
if(split) {
type = split[1]
selector = split[2]
}

let listener = (e) => {
callback(e, self)
}

if(selector){
$(this.el).on(type, selector, listener)
} else {
$(this.el).on(type, listener)
}
}
}

}

module.exports = Component
26 changes: 26 additions & 0 deletions src/scripts/components/example.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var Component = require('./component')

/**
* Example component class
*
* - all DOM operations must be executed after creating an instance (in constructor)
* - when defining own constructor, don't forget to call super(element, data)
* - DOM event listeners are in Backbone style
*
*/
class Example extends Component {

get listeners() {
return {
'click .example-child': 'handleClick'
}
}

handleClick(e, self) {
e.preventDefault()
alert(self.data)
}

}

module.exports = Example
32 changes: 32 additions & 0 deletions src/scripts/index.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// Main project bundle
//

// Dependencies
//
require('./plugins')


//
// Lazy components initialization from initComponents queue
//
// Components declarations
var components = {
'example': require('./components/example')
}
// Init function
var init = (component) => {
if(component.name in components){
var Component = components[component.name] // class
var placement = (typeof component.place == 'string') ? document.querySelector(component.place) : component.place // DOM element
var instance = new Component(placement, component.data || {}) // new instance
} else {
console.warn('Component with name ' + component.name + ' was not found!')
}
}
// Instance only required components
initComponents.map(init)
// Allow lazy init of components after page load
initComponents = {
push: init
}
16 changes: 0 additions & 16 deletions src/scripts/index.js

This file was deleted.

27 changes: 27 additions & 0 deletions src/scripts/plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Tiny project dependencies like polyfills and environment setup
//


// Avoid `console` errors in browsers that lack a console.
//
;(function() {
var method
var noop = function () {}
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeStamp', 'trace', 'warn'
]
var length = methods.length
var console = (window.console = window.console || {})

while (length--) {
method = methods[length]
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop
}
}
})();
41 changes: 41 additions & 0 deletions src/scripts/utils/inject.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
var head = document.head || document.getElementsByTagName('head')[0]

/**
* Injects script into the current page
*
* @param {string|Object} scripts src or Object script attributes with optional 'content' as inline javascript
* @param {Function} load callback
*
* @author Matěj Šimek <[email protected]> (http://www.matejsimek.com)
*/
module.exports = function inject(options, callback) {
var script = document.createElement('script')

script.addEventListener('load', callback)
script.type = 'text/javascript'

// options is an URL string
if(typeof options == 'string') {
script.src = options
script.async = true
}

// options is an object with script attributes
// key 'content' is alias for inline script content
else if(typeof options == 'object') {

for(key in options) {
if(!options.hasOwnProperty(key)) continue
var value = options[key]

if(key == 'content') {
script.appendChild(document.createTextNode(value))
} else {
script[key] = value
}
})

}

head.appendChild(script)
}
4 changes: 4 additions & 0 deletions src/styles/comps/layout.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.layout
display block
max-width 45em
margin $spacing auto
Loading

0 comments on commit 2c95271

Please sign in to comment.