ratchet_design 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/app/assets/images/ratchet/favicon.ico +0 -0
- data/app/assets/javascripts/ratchet/_svg.js +55 -0
- data/app/assets/javascripts/ratchet/base/form.js +220 -0
- data/app/assets/javascripts/ratchet/base/mobilemenu.js +62 -0
- data/app/assets/javascripts/ratchet/base/validation.js +230 -0
- data/app/assets/javascripts/ratchet/core.js +92 -0
- data/app/assets/javascripts/ratchet/enhancement/_collapse.js +96 -0
- data/app/assets/javascripts/ratchet/enhancement/_lightbox.js +93 -0
- data/app/assets/javascripts/ratchet/enhancement/_swap.js +120 -0
- data/app/assets/javascripts/ratchet/enhancement/_switcheroo.js +28 -0
- data/app/assets/javascripts/ratchet/enhancement/_textcounter.js +92 -0
- data/app/assets/javascripts/ratchet/enhancement/loader.js +77 -0
- data/app/assets/javascripts/ratchet/enhancement/notice.js +70 -0
- data/app/assets/javascripts/ratchet/enhancement/sticky.js +128 -0
- data/app/assets/javascripts/ratchet/enhancement/waypoints.js +328 -0
- data/app/assets/javascripts/ratchet/shim/classlist.js +234 -0
- data/app/assets/javascripts/ratchet/shim/object.assign.js +30 -0
- data/app/assets/javascripts/ratchet/utility/compile_data.js +32 -0
- data/app/assets/javascripts/ratchet/utility/from_top.js +14 -0
- data/app/assets/javascripts/ratchet/utility/full_stop.js +55 -0
- data/app/assets/javascripts/ratchet/utility/get_closest.js +20 -0
- data/app/assets/javascripts/ratchet/utility/get_next.js +17 -0
- data/app/assets/javascripts/ratchet/utility/load_font.js +72 -0
- data/app/assets/javascripts/ratchet/utility/load_script.js +34 -0
- data/app/assets/javascripts/ratchet/utility/matches.js +15 -0
- data/app/assets/javascripts/ratchet/utility/scroll_to.js +74 -0
- data/app/assets/javascripts/ratchet/utility/throttle.js +25 -0
- data/app/assets/javascripts/ratchet/utility/timeout.js +45 -0
- data/app/assets/javascripts/ratchet/utility/unhover.js +56 -0
- data/app/assets/javascripts/ratchet/utility/word_count.js +15 -0
- data/app/assets/stylesheets/ratchet/_core.scss +20 -0
- data/app/assets/stylesheets/ratchet/base/_button.scss +101 -0
- data/app/assets/stylesheets/ratchet/base/_document.scss +306 -0
- data/app/assets/stylesheets/ratchet/base/_form.scss +614 -0
- data/app/assets/stylesheets/ratchet/base/_list.scss +114 -0
- data/app/assets/stylesheets/ratchet/base/_media.scss +41 -0
- data/app/assets/stylesheets/ratchet/base/_table.scss +81 -0
- data/app/assets/stylesheets/ratchet/base/_text.scss +411 -0
- data/app/assets/stylesheets/ratchet/enhancement/_contrast-section.scss +22 -0
- data/app/assets/stylesheets/ratchet/enhancement/_feature.scss +49 -0
- data/app/assets/stylesheets/ratchet/enhancement/_hero.scss +44 -0
- data/app/assets/stylesheets/ratchet/enhancement/_loader.scss +109 -0
- data/app/assets/stylesheets/ratchet/enhancement/_notice.scss +74 -0
- data/app/assets/stylesheets/ratchet/enhancement/_signup.scss +206 -0
- data/app/assets/stylesheets/ratchet/enhancement/_sticky-sidebar.scss +36 -0
- data/app/assets/stylesheets/ratchet/fonts-woff.css +55 -0
- data/app/assets/stylesheets/ratchet/fonts-woff2.css +55 -0
- data/app/assets/stylesheets/ratchet/utility/_global.scss +255 -0
- data/app/assets/stylesheets/ratchet/utility/_grid.scss +102 -0
- data/app/assets/svgs/ratchet/facebook.svg +1 -0
- data/app/assets/svgs/ratchet/github.svg +1 -0
- data/app/assets/svgs/ratchet/google-plus.svg +1 -0
- data/app/assets/svgs/ratchet/ibm.svg +1 -0
- data/app/assets/svgs/ratchet/inbox.svg +1 -0
- data/app/assets/svgs/ratchet/linkedin.svg +1 -0
- data/app/assets/svgs/ratchet/ratchet.svg +1 -0
- data/app/assets/svgs/ratchet/search.svg +1 -0
- data/app/assets/svgs/ratchet/subscribe.svg +1 -0
- data/app/assets/svgs/ratchet/twitter.svg +1 -0
- data/app/assets/svgs/ratchet/y-combinator.svg +1 -0
- data/app/helpers/ratchet/application_helper.rb +51 -0
- data/app/views/layouts/ratchet/default.html.slim +61 -0
- data/app/views/shared/ratchet/_footer.html.slim +2 -0
- data/app/views/shared/ratchet/_header.html.slim +17 -0
- data/app/views/shared/ratchet/_icons.html.slim +89 -0
- data/lib/ratchet_design.rb +12 -0
- data/lib/ratchet_design/version.rb +3 -0
- data/public/assets/ratchet/core-0.1.0.js +103 -0
- data/public/assets/ratchet/core-0.1.0.js.gz +0 -0
- data/public/assets/ratchet/core-0.1.0.map.json +1 -0
- data/public/assets/ratchet/fonts-woff-0.1.0.css +55 -0
- data/public/assets/ratchet/fonts-woff-0.1.0.css.gz +0 -0
- data/public/assets/ratchet/fonts-woff2-0.1.0.css +55 -0
- data/public/assets/ratchet/fonts-woff2-0.1.0.css.gz +0 -0
- metadata +177 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
// Shim modules
|
2
|
+
require( './shim/classlist' );
|
3
|
+
require( './shim/object.assign' );
|
4
|
+
|
5
|
+
// Utility modules
|
6
|
+
var loadFont = require( './utility/load_font' );
|
7
|
+
var fullStop = require( './utility/full_stop' );
|
8
|
+
var unhover = require( './utility/unhover' );
|
9
|
+
var throttle = require( './utility/throttle' );
|
10
|
+
var loadScript = require( './utility/load_script' );
|
11
|
+
var fromTop = require( './utility/from_top' );
|
12
|
+
var scrollTo = require( './utility/scroll_to' );
|
13
|
+
var matches = require( './utility/matches' );
|
14
|
+
var getClosest = require( './utility/get_closest' );
|
15
|
+
var getNext = require( './utility/get_next' );
|
16
|
+
var wordCount = require( './utility/word_count' );
|
17
|
+
var compileData = require( './utility/compile_data' );
|
18
|
+
var timeout = require( './utility/timeout' );
|
19
|
+
|
20
|
+
// Base modules
|
21
|
+
var mobileMenu = require( './base/mobilemenu' );
|
22
|
+
var form = require( './base/form' );
|
23
|
+
var validation = require( './base/validation' );
|
24
|
+
|
25
|
+
// Enhancement modules
|
26
|
+
var loader = require( './enhancement/loader' );
|
27
|
+
var waypoints = require( './enhancement/waypoints' );
|
28
|
+
var notice = require( './enhancement/notice' );
|
29
|
+
var sticky = require( './enhancement/sticky' );
|
30
|
+
var esvg = require( './_svg' );
|
31
|
+
// var swap = require( './enhancement/swap' );
|
32
|
+
|
33
|
+
// Vendor modules
|
34
|
+
var event = require( 'compose-event' );
|
35
|
+
var highlighter = require( 'compose-code-highlighter' );
|
36
|
+
require( 'codemirror/mode/htmlmixed/htmlmixed' );
|
37
|
+
require( 'codemirror/mode/slim/slim' );
|
38
|
+
require( 'codemirror/mode/javascript/javascript' );
|
39
|
+
require( 'codemirror/mode/css/css' );
|
40
|
+
require( 'codemirror/mode/sql/sql' );
|
41
|
+
require( 'codemirror/mode/php/php' );
|
42
|
+
require( 'codemirror/mode/ruby/ruby' );
|
43
|
+
require( 'codemirror/mode/shell/shell' );
|
44
|
+
require( 'codemirror/mode/go/go' );
|
45
|
+
require( 'codemirror/mode/python/python' );
|
46
|
+
require( 'codemirror/mode/yaml/yaml' );
|
47
|
+
require( 'codemirror/mode/clike/clike' );
|
48
|
+
require( 'codemirror/addon/runmode/runmode' );
|
49
|
+
require( 'codemirror/addon/edit/matchbrackets' );
|
50
|
+
|
51
|
+
// Public API object
|
52
|
+
window.ratchet = module.exports = {
|
53
|
+
esvg : esvg,
|
54
|
+
event : event,
|
55
|
+
loadFont : loadFont,
|
56
|
+
throttle : throttle,
|
57
|
+
loadScript : loadScript,
|
58
|
+
scrollTo : scrollTo,
|
59
|
+
wordCount : wordCount,
|
60
|
+
getNext : getNext,
|
61
|
+
getClosest : getClosest,
|
62
|
+
compileData : compileData,
|
63
|
+
timeout : timeout,
|
64
|
+
mobileMenu : mobileMenu,
|
65
|
+
form : form,
|
66
|
+
validation : validation,
|
67
|
+
loader : loader,
|
68
|
+
// swap : swap,
|
69
|
+
waypoints : waypoints,
|
70
|
+
notice : notice,
|
71
|
+
sticky : sticky
|
72
|
+
}
|
73
|
+
|
74
|
+
// Default events instantiation
|
75
|
+
event.change( function() {
|
76
|
+
|
77
|
+
// Unhover module
|
78
|
+
unhover();
|
79
|
+
|
80
|
+
// FullStop module
|
81
|
+
fullStop();
|
82
|
+
|
83
|
+
// Form module
|
84
|
+
form();
|
85
|
+
|
86
|
+
// Validation module
|
87
|
+
validation();
|
88
|
+
|
89
|
+
// Syntax highlighting
|
90
|
+
highlighter.highlight();
|
91
|
+
|
92
|
+
}, false );
|
@@ -0,0 +1,96 @@
|
|
1
|
+
/**
|
2
|
+
* Collapse 0.0.1
|
3
|
+
* Easily create expandable excerpts
|
4
|
+
* @author Kyle Foster (@hkfoster)
|
5
|
+
* @license MIT
|
6
|
+
**/
|
7
|
+
|
8
|
+
// Dependencies
|
9
|
+
var getClosest = require('../utility/get_closest')
|
10
|
+
|
11
|
+
;( function( root, factory ) {
|
12
|
+
if ( typeof define === 'function' && define.amd ) {
|
13
|
+
define( factory );
|
14
|
+
} else if ( typeof exports === 'object' ) {
|
15
|
+
module.exports = factory;
|
16
|
+
} else {
|
17
|
+
root.collapse = factory( root );
|
18
|
+
}
|
19
|
+
})( this, function( root ) {
|
20
|
+
|
21
|
+
'use strict';
|
22
|
+
|
23
|
+
// Public API function
|
24
|
+
var exports = function( element, settings ) {
|
25
|
+
|
26
|
+
// Parameter variables
|
27
|
+
var
|
28
|
+
selectors = document.querySelectorAll( element ),
|
29
|
+
defaults = {
|
30
|
+
expandText : 'Show more ∨',
|
31
|
+
collapseText : 'Show less ∧',
|
32
|
+
triggerText : ' '
|
33
|
+
};
|
34
|
+
|
35
|
+
// Only run if selector exists
|
36
|
+
if ( !selectors ) return false;
|
37
|
+
|
38
|
+
// Scoped variables
|
39
|
+
var
|
40
|
+
options = compose.extend( defaults, settings ),
|
41
|
+
state = {};
|
42
|
+
|
43
|
+
// Loop over expandable elements
|
44
|
+
for ( var i = 0; i < selectors.length; i++ ) {
|
45
|
+
|
46
|
+
// Scoped variables
|
47
|
+
var
|
48
|
+
selector = selectors[ i ],
|
49
|
+
original = selector.innerHTML,
|
50
|
+
expanded = original + '<a class="expand" href="#">' + options.collapseText + '</a>',
|
51
|
+
collapsed = original.split( options.triggerText )[ 0 ] + '… <a class="expand" href="#">' + options.expandText + '</a>';
|
52
|
+
|
53
|
+
// Set excerpt text
|
54
|
+
selector.innerHTML = collapsed;
|
55
|
+
|
56
|
+
// Set index data attribute
|
57
|
+
selector.dataset.idx = i;
|
58
|
+
|
59
|
+
// Populate state reference object
|
60
|
+
state[ i ] = {
|
61
|
+
'expanded' : expanded,
|
62
|
+
'collapsed' : collapsed
|
63
|
+
};
|
64
|
+
|
65
|
+
}
|
66
|
+
|
67
|
+
// Attach click listener
|
68
|
+
document.body.addEventListener( 'click', clickHandler, false );
|
69
|
+
|
70
|
+
// Click handler function
|
71
|
+
function clickHandler( event ) {
|
72
|
+
|
73
|
+
// Only run on `rel=expand` links
|
74
|
+
if ( event.target.className !== 'expand' ) return false;
|
75
|
+
|
76
|
+
// Prevent default behavior
|
77
|
+
event.preventDefault();
|
78
|
+
|
79
|
+
// Scoped variables
|
80
|
+
var expandable = getClosest( event.target, element ),
|
81
|
+
stateObject = state[ expandable.dataset.idx ];
|
82
|
+
|
83
|
+
// Toggle between excerpt and full text
|
84
|
+
expandable.innerHTML = ( expandable.innerHTML === stateObject.expanded ) ? stateObject.collapsed : stateObject.expanded;
|
85
|
+
|
86
|
+
// Toggle between expand and collapse link text
|
87
|
+
event.target.textContent = ( event.target.textContent === options.expandText ) ? options.collapseText : options.expandText;
|
88
|
+
|
89
|
+
}
|
90
|
+
|
91
|
+
};
|
92
|
+
|
93
|
+
// Public API
|
94
|
+
return exports;
|
95
|
+
|
96
|
+
});
|
@@ -0,0 +1,93 @@
|
|
1
|
+
Event = require('compose-event')
|
2
|
+
/**
|
3
|
+
* Lightbox.js 0.0.2
|
4
|
+
* A lightbox plugin that makes sense
|
5
|
+
* @author Kyle Foster (@hkfoster)
|
6
|
+
* @license MIT
|
7
|
+
**/
|
8
|
+
|
9
|
+
// Transport
|
10
|
+
( function( root, factory ) {
|
11
|
+
if ( typeof define === 'function' && define.amd ) {
|
12
|
+
define( factory );
|
13
|
+
} else if ( typeof exports === 'object' ) {
|
14
|
+
module.exports = factory;
|
15
|
+
} else {
|
16
|
+
root.lightbox = factory( root );
|
17
|
+
}
|
18
|
+
})( this, function( root ) {
|
19
|
+
|
20
|
+
'use strict';
|
21
|
+
|
22
|
+
// Define global variable(s)
|
23
|
+
var lightboxTrigger = document.querySelectorAll( '[rel="lightbox"]' );
|
24
|
+
|
25
|
+
// Only run if lightbox trigger is present
|
26
|
+
if ( lightboxTrigger ) {
|
27
|
+
init();
|
28
|
+
}
|
29
|
+
|
30
|
+
// Where the magic happens
|
31
|
+
function init() {
|
32
|
+
|
33
|
+
// Preload lightbox images
|
34
|
+
for ( var imgIndex = 0; imgIndex < lightboxTrigger.length; imgIndex ++ ) {
|
35
|
+
|
36
|
+
// Create a temporary image element
|
37
|
+
var tempImg = new Image();
|
38
|
+
|
39
|
+
// And use it to load up image(s)
|
40
|
+
tempImg.src = lightboxTrigger[ imgIndex ].href;
|
41
|
+
|
42
|
+
}
|
43
|
+
|
44
|
+
// Attach our click listener
|
45
|
+
Event.on(document, 'click', '[rel="lightbox"]', openLightbox)
|
46
|
+
|
47
|
+
}
|
48
|
+
|
49
|
+
// Open lightbox function
|
50
|
+
function openLightbox( event ) {
|
51
|
+
|
52
|
+
// Prevent default behavior/bubbling
|
53
|
+
event.stopPropagation();
|
54
|
+
event.preventDefault();
|
55
|
+
|
56
|
+
// Define scoped variable(s)
|
57
|
+
var lightboxUrl = event.target.href,
|
58
|
+
lightboxCont = '<aside class="lightbox-overlay"><figure class="lightbox-content"><img src="' + lightboxUrl + '" alt=""><a class="close-btn" href="#?"></a></figure></aside>';
|
59
|
+
|
60
|
+
// Open the lightbox
|
61
|
+
document.body.insertAdjacentHTML('beforeend' lightboxCont );
|
62
|
+
|
63
|
+
// Prevent scrolling while lightbox is shown
|
64
|
+
document.body.style.overflow = 'hidden';
|
65
|
+
|
66
|
+
Event.one('.close-btn', 'click', closeLightbox)
|
67
|
+
|
68
|
+
}
|
69
|
+
|
70
|
+
// Close lightbox function
|
71
|
+
function closeLightbox( event ) {
|
72
|
+
|
73
|
+
// Prevent default behavior/bubbling
|
74
|
+
event.stopPropagation();
|
75
|
+
event.preventDefault();
|
76
|
+
|
77
|
+
// Define scoped variable(s)
|
78
|
+
var lightboxOverlay = document.querySelector( '.lightbox-overlay' ),
|
79
|
+
lightboxContent = lightboxOverlay.querySelector( '.lightbox-content' ),
|
80
|
+
|
81
|
+
// Kick off closing animation
|
82
|
+
lightboxContent.className += ' closing';
|
83
|
+
|
84
|
+
Event.one(lightboxContent, 'animationend', function() {
|
85
|
+
// Remove the lightbox from the DOM
|
86
|
+
document.body.removeChild( lightboxOverlay );
|
87
|
+
|
88
|
+
// And turn scrolling back on
|
89
|
+
document.body.style.overflow = '';
|
90
|
+
})
|
91
|
+
}
|
92
|
+
|
93
|
+
});
|
@@ -0,0 +1,120 @@
|
|
1
|
+
/**
|
2
|
+
* Swap 0.0.2
|
3
|
+
* Compose swappable element module
|
4
|
+
* @author Kyle Foster (@hkfoster)
|
5
|
+
* @license MIT
|
6
|
+
**/
|
7
|
+
|
8
|
+
// Dependencies
|
9
|
+
var ScrollTo = require('../utility/scroll_to')
|
10
|
+
|
11
|
+
// Transport
|
12
|
+
;( function( root, factory ) {
|
13
|
+
if ( typeof define === 'function' && define.amd ) {
|
14
|
+
define( factory );
|
15
|
+
} else if ( typeof exports === 'object' ) {
|
16
|
+
module.exports = factory;
|
17
|
+
} else {
|
18
|
+
root.swap = factory( root );
|
19
|
+
}
|
20
|
+
})( this, function( root ) {
|
21
|
+
|
22
|
+
'use strict';
|
23
|
+
|
24
|
+
var triggers = document.querySelectorAll( '.swap-trigger' );
|
25
|
+
|
26
|
+
if ( triggers.length ) {
|
27
|
+
|
28
|
+
// Assignment
|
29
|
+
var location = window.location.hash;
|
30
|
+
|
31
|
+
// Swap function
|
32
|
+
var swap = function( trigger, target ) {
|
33
|
+
|
34
|
+
// Find all current `selected` class elements
|
35
|
+
var currentSelection = document.querySelectorAll( '.selected' );
|
36
|
+
|
37
|
+
// And deselect them
|
38
|
+
for ( var i = 0; i < currentSelection.length; i++ ) {
|
39
|
+
currentSelection[ i ].classList.remove( 'selected' );
|
40
|
+
}
|
41
|
+
|
42
|
+
// Select our new elements
|
43
|
+
trigger.classList.add( 'selected' );
|
44
|
+
target.classList.add( 'selected' );
|
45
|
+
};
|
46
|
+
|
47
|
+
// Get current window hash
|
48
|
+
var getHash = function() {
|
49
|
+
return location.split( '#' )[ 1 ];
|
50
|
+
};
|
51
|
+
|
52
|
+
// Get link target hash
|
53
|
+
var getLinkTarget = function( link ) {
|
54
|
+
return link.href.split( '#' )[ 1 ];
|
55
|
+
};
|
56
|
+
|
57
|
+
// Hash check function
|
58
|
+
var hashCheck = function( event ) {
|
59
|
+
|
60
|
+
// If no hash
|
61
|
+
if ( !location ) {
|
62
|
+
|
63
|
+
// Assign first element(s) variables
|
64
|
+
var firstTrigger = document.querySelector( '.swap-trigger' ),
|
65
|
+
firstTarget = document.querySelector( '.swappable' );
|
66
|
+
|
67
|
+
// And select them
|
68
|
+
swap( firstTrigger, firstTarget );
|
69
|
+
|
70
|
+
// Otherwise
|
71
|
+
} else {
|
72
|
+
|
73
|
+
// Stop default anchor tag jump
|
74
|
+
ScrollTo(0, 0);
|
75
|
+
|
76
|
+
// Assign appropriate element(s) variables
|
77
|
+
var loadedTarget = document.querySelector( '#' + getHash() ),
|
78
|
+
loadedTrigger = document.querySelector('[href="#' + getHash() + '"]' );
|
79
|
+
|
80
|
+
// And select them
|
81
|
+
swap( loadedTrigger, loadedTarget );
|
82
|
+
|
83
|
+
}
|
84
|
+
|
85
|
+
};
|
86
|
+
|
87
|
+
// Click handler function
|
88
|
+
var clickHandler = function( event ) {
|
89
|
+
|
90
|
+
// Prevent default behavior
|
91
|
+
event.stopPropagation();
|
92
|
+
event.preventDefault();
|
93
|
+
|
94
|
+
// Local assignment
|
95
|
+
var triggerElem = this,
|
96
|
+
linkTarget = getLinkTarget( triggerElem ),
|
97
|
+
targetElem = document.querySelector( '#' + linkTarget );
|
98
|
+
|
99
|
+
// Select the appropriate elements
|
100
|
+
swap ( triggerElem, targetElem );
|
101
|
+
|
102
|
+
// Replace the hash
|
103
|
+
history.replaceState( null, '', '#' + linkTarget );
|
104
|
+
|
105
|
+
};
|
106
|
+
|
107
|
+
// Run hash check on window load
|
108
|
+
window.addEventListener( 'load', hashCheck, false );
|
109
|
+
|
110
|
+
// Iterate over each swap trigger
|
111
|
+
for ( var i = 0; i < triggers.length; i++ ) {
|
112
|
+
|
113
|
+
// And attach our click listener
|
114
|
+
triggers[ i ].addEventListener( 'click', clickHandler, false );
|
115
|
+
|
116
|
+
}
|
117
|
+
|
118
|
+
}
|
119
|
+
|
120
|
+
});
|
@@ -0,0 +1,28 @@
|
|
1
|
+
/**
|
2
|
+
* Switcheroo v0.0.1
|
3
|
+
* Move a given node from one place to another
|
4
|
+
* @author Kyle Foster @hkfoster
|
5
|
+
* @license MIT
|
6
|
+
**/
|
7
|
+
|
8
|
+
( function( window ) {
|
9
|
+
|
10
|
+
'use strict';
|
11
|
+
|
12
|
+
// Define nodeWrapper function
|
13
|
+
var switcheroo = function( node, location ) {
|
14
|
+
if ( node ) {
|
15
|
+
location.appendChild( node );
|
16
|
+
}
|
17
|
+
};
|
18
|
+
|
19
|
+
// Transport
|
20
|
+
if ( typeof define === 'function' && define.amd ) {
|
21
|
+
define( switcheroo );
|
22
|
+
} else if ( typeof exports === 'object' ) {
|
23
|
+
module.exports = switcheroo;
|
24
|
+
} else {
|
25
|
+
window.switcheroo = switcheroo;
|
26
|
+
}
|
27
|
+
|
28
|
+
})( window );
|
@@ -0,0 +1,92 @@
|
|
1
|
+
/**
|
2
|
+
* Text Counter 0.0.1
|
3
|
+
* Count & display number of chars/words in a textarea
|
4
|
+
* @author Matt Gillespie (@savethetweets) & Kyle Foster (@hkfoster)
|
5
|
+
* @license MIT
|
6
|
+
**/
|
7
|
+
|
8
|
+
;( function( root, factory ) {
|
9
|
+
if ( typeof define === 'function' && define.amd ) {
|
10
|
+
define( factory );
|
11
|
+
} else if ( typeof exports === 'object' ) {
|
12
|
+
module.exports = factory;
|
13
|
+
} else {
|
14
|
+
root.textCounter = factory( root );
|
15
|
+
}
|
16
|
+
})( this, function( root ) {
|
17
|
+
|
18
|
+
'use strict';
|
19
|
+
|
20
|
+
// Public API function
|
21
|
+
var exports = function( element, settings ) {
|
22
|
+
|
23
|
+
// Parameter variables
|
24
|
+
var
|
25
|
+
selector = document.querySelector( element ),
|
26
|
+
defaults = {
|
27
|
+
defaultMsg : 'characters available',
|
28
|
+
type : 'characters',
|
29
|
+
successMsg : null,
|
30
|
+
closeCount : 20,
|
31
|
+
value : 140
|
32
|
+
};
|
33
|
+
|
34
|
+
// Only run if selector exists
|
35
|
+
if ( !selector ) return false;
|
36
|
+
|
37
|
+
// Scoped variables
|
38
|
+
var
|
39
|
+
options = compose.extend( defaults, settings ),
|
40
|
+
progressElem = selector.querySelector( 'progress' ),
|
41
|
+
counterInput = selector.querySelector( 'textarea' ),
|
42
|
+
targetCount = progressElem.value || options.limit,
|
43
|
+
currentCount = 0,
|
44
|
+
counterLabel,
|
45
|
+
labelValue;
|
46
|
+
|
47
|
+
// Create and insert progress label span
|
48
|
+
compose.insertAfter( compose.makeNode( '<span>' + options.value + ' ' + options.defaultMsg + '</span>' ), progressElem );
|
49
|
+
|
50
|
+
// Cache progress span
|
51
|
+
counterLabel = progressElem.nextElementSibling;
|
52
|
+
|
53
|
+
// Attach input listener
|
54
|
+
counterInput.addEventListener( 'keyup', updateProgress, false );
|
55
|
+
|
56
|
+
// Update progress function
|
57
|
+
function updateProgress( event ) {
|
58
|
+
|
59
|
+
// Update current count based on words or characters
|
60
|
+
currentCount = ( options.type === 'words' ) ? currentCount = compose.wordCount( event.target.value ) : currentCount = event.target.value.length;
|
61
|
+
|
62
|
+
// Compare current count to target count and set label value
|
63
|
+
labelValue = targetCount - currentCount;
|
64
|
+
|
65
|
+
// Set progress element’s value accordingly
|
66
|
+
progressElem.value = labelValue;
|
67
|
+
|
68
|
+
// If close count value is set and label value falls below it
|
69
|
+
if ( options.closeCount && labelValue <= options.closeCount ) {
|
70
|
+
|
71
|
+
// Apply `.danger` class to label
|
72
|
+
counterLabel.classList.add( 'danger' );
|
73
|
+
|
74
|
+
// Otherwise
|
75
|
+
} else {
|
76
|
+
|
77
|
+
// Remove `.danger` class from label
|
78
|
+
counterLabel.classList.remove( 'danger' );
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
// If success message is set, trigger it … otherwise display negative text count
|
83
|
+
counterLabel.textContent = ( options.successMsg && labelValue <= 0 ) ? options.successMsg : labelValue + ' ' + options.defaultMsg;
|
84
|
+
|
85
|
+
}
|
86
|
+
|
87
|
+
};
|
88
|
+
|
89
|
+
// Public API
|
90
|
+
return exports;
|
91
|
+
|
92
|
+
});
|