pinball_wizard 0.0.1.pre → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bower.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "pinball_wizard",
3
+ "version": "0.3.0",
4
+ "main": "dist/pinball_wizard.js",
5
+ "dependencies": {
6
+ },
7
+ "devDependencies": {},
8
+ "ignore": [
9
+ "spec/**.*",
10
+ "package.json",
11
+ "README.md",
12
+ "lib"
13
+ ]
14
+ }
@@ -0,0 +1,42 @@
1
+ (function() {
2
+ define(function() {
3
+ return function(ele, pinballQueue, searchQuery) {
4
+ var add, classNames, entry, feature, featureNames, matches, state, _i, _j, _len, _len1, _ref;
5
+ classNames = [];
6
+ add = function(name) {
7
+ return classNames.push('use-' + name.split('_').join('-'));
8
+ };
9
+ for (_i = 0, _len = pinballQueue.length; _i < _len; _i++) {
10
+ entry = pinballQueue[_i];
11
+ if (!entry.length) {
12
+ continue;
13
+ }
14
+ switch (entry[0]) {
15
+ case 'activate':
16
+ add(entry[1]);
17
+ break;
18
+ case 'add':
19
+ _ref = entry[1];
20
+ for (feature in _ref) {
21
+ state = _ref[feature];
22
+ if (state === 'active') {
23
+ add(feature);
24
+ }
25
+ }
26
+ }
27
+ }
28
+ matches = searchQuery.match(/pinball=([a-z-_,]+)/i);
29
+ if (matches && matches.length > 1) {
30
+ featureNames = (matches[1] + '').split(',');
31
+ for (_j = 0, _len1 = featureNames.length; _j < _len1; _j++) {
32
+ feature = featureNames[_j];
33
+ add(feature);
34
+ }
35
+ }
36
+ if (ele) {
37
+ ele.className += ' ' + classNames.join(' ');
38
+ }
39
+ };
40
+ });
41
+
42
+ }).call(this);
@@ -0,0 +1,3 @@
1
+ // Minified on http://closure-compiler.appspot.com/ using Advanced settings
2
+
3
+ (function(g,d,e){var f,h,b,a,c,l,k;h=[];f=function(a){h.push("use-"+a.split("_").join("-"))};c=0;for(l=d.length;c<l;c++)if(b=d[c],b.length)switch(b[0]){case "activate":f(b[1]);break;case "add":for(a in k=b[1],k)b=k[a],"active"===b&&f(a)}if((a=e.match(/pinball=([a-z-_,]+)/i))&&1<a.length)for(d=(a[1]+"").split(","),e=0,c=d.length;e<c;e++)a=d[e],f(a);g&&(g.className+=" "+h.join(" "))})(document.documentElement,window.pinball,window.location.search);
@@ -0,0 +1,227 @@
1
+ (function() {
2
+ 'use strict';
3
+ var __slice = [].slice;
4
+
5
+ define(function() {
6
+ var activate, add, addCSSClassName, cssClassName, deactivate, debug, exports, features, get, isActive, logPrefix, push, removeCSSClassName, reset, showLog, state, subscribe, subscribers, update, urlValues, _buildSubscriber, _log, _notifySubscriberOnActivate, _notifySubscribersOnActivate, _notifySubscribersOnDeactivate, _urlValueMatches, _urlValues;
7
+ features = {};
8
+ subscribers = {};
9
+ showLog = false;
10
+ logPrefix = '[PinballWizard]';
11
+ _log = function() {
12
+ var args, message;
13
+ message = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
14
+ if (showLog && window.console && window.console.log) {
15
+ console.log.apply(console, ["" + logPrefix + " " + message].concat(__slice.call(args)));
16
+ }
17
+ };
18
+ _notifySubscribersOnActivate = function(name) {
19
+ var subscriber, _i, _len, _ref, _results;
20
+ if (subscribers[name] == null) {
21
+ subscribers[name] = [];
22
+ }
23
+ _ref = subscribers[name];
24
+ _results = [];
25
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
26
+ subscriber = _ref[_i];
27
+ _results.push(_notifySubscriberOnActivate(subscriber, name));
28
+ }
29
+ return _results;
30
+ };
31
+ _notifySubscriberOnActivate = function(subscriber, name) {
32
+ _log('Notify subscriber that %s is active', name);
33
+ return subscriber.onActivate();
34
+ };
35
+ _notifySubscribersOnDeactivate = function(name) {
36
+ var subscriber, _i, _len, _ref, _results;
37
+ if (subscribers[name] == null) {
38
+ subscribers[name] = [];
39
+ }
40
+ _ref = subscribers[name];
41
+ _results = [];
42
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
43
+ subscriber = _ref[_i];
44
+ _results.push(subscriber.onDeactivate());
45
+ }
46
+ return _results;
47
+ };
48
+ _urlValueMatches = function(value) {
49
+ var v, _i, _len, _ref;
50
+ _ref = _urlValues();
51
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
52
+ v = _ref[_i];
53
+ if (value === v) {
54
+ return true;
55
+ }
56
+ }
57
+ return false;
58
+ };
59
+ _urlValues = function(search) {
60
+ var key, pair, pairs, value, _i, _len, _ref;
61
+ if (search == null) {
62
+ search = window.location.search;
63
+ }
64
+ pairs = search.substr(1).split('&');
65
+ for (_i = 0, _len = pairs.length; _i < _len; _i++) {
66
+ pair = pairs[_i];
67
+ _ref = pair.split('='), key = _ref[0], value = _ref[1];
68
+ if (key === 'pinball' && (value != null)) {
69
+ return value.split(',');
70
+ }
71
+ }
72
+ return [];
73
+ };
74
+ urlValues = _urlValues();
75
+ cssClassName = function(name, prefix) {
76
+ if (prefix == null) {
77
+ prefix = 'use-';
78
+ }
79
+ return prefix + name.split('_').join('-');
80
+ };
81
+ addCSSClassName = function(name, ele) {
82
+ var cN;
83
+ if (ele == null) {
84
+ ele = document.documentElement;
85
+ }
86
+ cN = cssClassName(name);
87
+ if (ele.className.indexOf(cN) < 0) {
88
+ return ele.className += ' ' + cN;
89
+ }
90
+ };
91
+ removeCSSClassName = function(name, ele) {
92
+ var cN;
93
+ if (ele == null) {
94
+ ele = document.documentElement;
95
+ }
96
+ cN = cssClassName(name);
97
+ if (ele.className.indexOf(cN) >= 0) {
98
+ return ele.className = ele.className.replace(cN, '');
99
+ }
100
+ };
101
+ add = function(list) {
102
+ var name, state, _results;
103
+ _results = [];
104
+ for (name in list) {
105
+ state = list[name];
106
+ features[name] = state;
107
+ _log("Added %s: %s.", name, state);
108
+ if (isActive(name)) {
109
+ _results.push(activate(name, "automatic. added as '" + state + "'"));
110
+ } else if (_urlValueMatches(name, urlValues)) {
111
+ _results.push(activate(name, 'URL'));
112
+ } else {
113
+ _results.push(void 0);
114
+ }
115
+ }
116
+ return _results;
117
+ };
118
+ get = function(name) {
119
+ return features[name];
120
+ };
121
+ update = function(name, state) {
122
+ return features[name] = state;
123
+ };
124
+ activate = function(name, sourceName) {
125
+ var source, state;
126
+ if (sourceName == null) {
127
+ sourceName = null;
128
+ }
129
+ state = get(name);
130
+ source = sourceName != null ? " (source: " + sourceName + ")" : '';
131
+ switch (state) {
132
+ case void 0:
133
+ return _log("Attempted to activate %s, but it was not found%s.", name, source);
134
+ case 'inactive':
135
+ _log("Activate %s%s.", name, source);
136
+ update(name, 'active');
137
+ addCSSClassName(name);
138
+ return _notifySubscribersOnActivate(name);
139
+ case 'active':
140
+ return _log("Attempted to activate %s, but it is already active%s.", name, source);
141
+ default:
142
+ return _log("Attempted to activate %s, but it is %s%s.", name, state, source);
143
+ }
144
+ };
145
+ deactivate = function(name, source) {
146
+ var state;
147
+ if (source == null) {
148
+ source = null;
149
+ }
150
+ state = get(name);
151
+ source = typeof sourceName !== "undefined" && sourceName !== null ? " (source: " + sourceName + ")" : '';
152
+ switch (state) {
153
+ case void 0:
154
+ return _log("Attempted to deactivate %s, but it was not found%s.", name, source);
155
+ case 'active':
156
+ _log("Dectivate %s%s.", name, source);
157
+ update(name, 'inactive');
158
+ removeCSSClassName(name);
159
+ return _notifySubscribersOnDeactivate(name);
160
+ default:
161
+ return _log("Attempted to deactivate %s, but it is %s%s.", name, state, source);
162
+ }
163
+ };
164
+ isActive = function(name) {
165
+ return get(name) === 'active';
166
+ };
167
+ _buildSubscriber = function(onActivate, onDeactivate) {
168
+ return {
169
+ onActivate: onActivate != null ? onActivate : function() {},
170
+ onDeactivate: onDeactivate != null ? onDeactivate : function() {}
171
+ };
172
+ };
173
+ subscribe = function(name, onActivate, onDeactivate) {
174
+ var subscriber;
175
+ _log('Added subscriber to %s', name);
176
+ subscriber = _buildSubscriber(onActivate, onDeactivate);
177
+ if (subscribers[name] == null) {
178
+ subscribers[name] = [];
179
+ }
180
+ subscribers[name].push(subscriber);
181
+ if (isActive(name)) {
182
+ return _notifySubscriberOnActivate(subscriber, name);
183
+ }
184
+ };
185
+ push = function(params) {
186
+ var method;
187
+ method = params.shift();
188
+ return this[method].apply(this, params);
189
+ };
190
+ state = function() {
191
+ return features;
192
+ };
193
+ reset = function() {
194
+ return features = {};
195
+ };
196
+ debug = function() {
197
+ return showLog = true;
198
+ };
199
+ exports = {
200
+ add: add,
201
+ get: get,
202
+ activate: activate,
203
+ deactivate: deactivate,
204
+ isActive: isActive,
205
+ subscribe: subscribe,
206
+ push: push,
207
+ state: state,
208
+ reset: reset,
209
+ debug: debug,
210
+ cssClassName: cssClassName,
211
+ addCSSClassName: addCSSClassName,
212
+ removeCSSClassName: removeCSSClassName,
213
+ _urlValues: _urlValues
214
+ };
215
+ if (typeof window !== "undefined" && window !== null ? window.pinball : void 0) {
216
+ if (_urlValueMatches('debug')) {
217
+ debug();
218
+ }
219
+ while (window.pinball.length) {
220
+ exports.push(window.pinball.shift());
221
+ }
222
+ window.pinball = exports;
223
+ }
224
+ return exports;
225
+ });
226
+
227
+ }).call(this);
data/gulpfile.js ADDED
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ var gulp = require('gulp');
4
+ var coffee = require('gulp-coffee')
5
+ var gutil = require('gulp-util')
6
+ var sourcemaps = require('gulp-sourcemaps')
7
+ var del = require('del');
8
+
9
+ gulp.task('clean-dist', function (cb) {
10
+ del('dist/', cb);
11
+ });
12
+
13
+ gulp.task('dist', ['clean-dist'], function() {
14
+ gulp.src('src/**/*.coffee')
15
+ .pipe(coffee().on('error', gutil.log))
16
+ .pipe(gulp.dest('dist/'));
17
+ });
18
+
19
+ gulp.task('coffee', function() {
20
+ gulp.src('src/**/*.coffee')
21
+ .pipe(sourcemaps.init())
22
+ .pipe(coffee().on('error', gutil.log))
23
+ .pipe(sourcemaps.write())
24
+ .pipe(gulp.dest('.tmp/dist/'));
25
+ });
26
+
27
+ gulp.task('coffee-spec', function() {
28
+ gulp.src('test/**/*.coffee')
29
+ .pipe(sourcemaps.init())
30
+ .pipe(coffee().on('error', gutil.log))
31
+ .pipe(sourcemaps.write())
32
+ .pipe(gulp.dest('.tmp/test/'));
33
+ });
34
+
35
+ gulp.task('build', ['coffee','coffee-spec','dist']);
36
+
37
+ gulp.task('default', ['build'], function () {
38
+ gulp.watch('src/**/*.coffee', ['coffee','dist']);
39
+ gulp.watch('test/**/*.coffee', ['coffee-spec']);
40
+ });
data/karma.conf.js ADDED
@@ -0,0 +1,66 @@
1
+ // Karma configuration
2
+ // Generated on Tue Jan 13 2015 13:14:05 GMT-0500 (EST)
3
+
4
+ module.exports = function(config) {
5
+ config.set({
6
+
7
+ // base path that will be used to resolve all patterns (eg. files, exclude)
8
+ basePath: '.tmp/',
9
+
10
+ // frameworks to use
11
+ // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
12
+ frameworks: ['jasmine','requirejs'],
13
+
14
+
15
+ // list of files / patterns to load in the browser
16
+ files: [
17
+ {pattern: 'dist/**/*.js', included: false},
18
+ {pattern: 'test/spec/**/*_spec.js', included: false},
19
+
20
+ 'test/test-main.js'
21
+ ],
22
+
23
+ // list of files to exclude
24
+ exclude: [
25
+ ],
26
+
27
+
28
+ // preprocess matching files before serving them to the browser
29
+ // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
30
+ preprocessors: {
31
+ },
32
+
33
+
34
+ // test results reporter to use
35
+ // possible values: 'dots', 'progress'
36
+ // available reporters: https://npmjs.org/browse/keyword/karma-reporter
37
+ reporters: ['progress'],
38
+
39
+
40
+ // web server port
41
+ port: 9876,
42
+
43
+
44
+ // enable / disable colors in the output (reporters and logs)
45
+ colors: true,
46
+
47
+
48
+ // level of logging
49
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
50
+ logLevel: config.LOG_INFO,
51
+
52
+
53
+ // enable / disable watching file and executing tests whenever any file changes
54
+ autoWatch: true,
55
+
56
+
57
+ // start these browsers
58
+ // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
59
+ browsers: ['Chrome'],
60
+
61
+
62
+ // Continuous Integration mode
63
+ // if true, Karma captures browsers, runs the tests and exits
64
+ singleRun: false
65
+ });
66
+ };
@@ -0,0 +1,5 @@
1
+ require 'pinball_wizard/configuration'
2
+ require 'pinball_wizard/feature'
3
+ require 'pinball_wizard/registry'
4
+ require 'pinball_wizard/dsl'
5
+ require 'pinball_wizard/railtie' if defined?(Rails)
@@ -0,0 +1,17 @@
1
+ module PinballWizard
2
+ def self.configuration
3
+ @configuration ||= Configuration.new
4
+ end
5
+
6
+ def self.configure
7
+ yield(configuration)
8
+ end
9
+
10
+ class Configuration
11
+ attr_accessor :class_patterns
12
+
13
+ def initialize(class_patterns = {})
14
+ @class_patterns = class_patterns
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ require 'pinball_wizard/helpers/hash'
2
+
3
+ module PinballWizard
4
+ module DSL
5
+ def self.build(config = PinballWizard.configuration, &block)
6
+ builder = Builder.new(config)
7
+ builder.instance_eval(&block)
8
+ builder
9
+ end
10
+
11
+ class Builder
12
+ attr_reader :config
13
+
14
+ def initialize(config)
15
+ @config = config
16
+ end
17
+
18
+ def feature(name, *options)
19
+ options = Helpers::Hash.normalize_options(options)
20
+ feature = build_feature(name, options)
21
+ Registry.add(feature)
22
+ end
23
+
24
+ private
25
+
26
+ def build_feature(name, options)
27
+ build_from_class_pattern(name, options) || Feature.new(name, options)
28
+ end
29
+
30
+ def build_from_class_pattern(name, options)
31
+ config.class_patterns.each_pair do |key, klass|
32
+ return klass.new(name, options) if options.keys.include?(key)
33
+ end
34
+ false
35
+ end
36
+ end
37
+ end
38
+ end