punchbox 1.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 663d8f696f1b9b5f4c317b27e15325efd2e7be6b
4
+ data.tar.gz: c79a9152bb2c34821b3be762a1c40c798d0d6a3c
5
+ SHA512:
6
+ metadata.gz: 1f23c149e2b9996bdbd215de7a6094dc9487fc87be5ffb3ff9c69b39d3a9cdfbf628cf2f8c1bae66adbe58a6b8eb6c75ab99b35cca7d5e8c6bbde66d9281d335
7
+ data.tar.gz: 2cc7537e9b24cc05864f62b43afb0364ab80764281416ffc84d8ad39e29ec309cc3267fc4b3f1041acc9dd2f6dbd34b862a9cca2fc09d4865ae27299ccfbace4
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Kieran Eglin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # Punchbox 👊
2
+
3
+ Punchbox is a dead-simple way to add page-specific JavaScript to your Rails project.
4
+
5
+ The goal for this project is to have a focused scope (page-specific JS and nothing else), be as lightweight as possible, have no dependencies, and to run on <sup><sup>almost</sup></sup> any browser that runs JS.
6
+
7
+ Punchbox's syntax is a spiritual successor to [Paloma](https://github.com/kbparagua/paloma) and is otherwise inspired by a project I've contributed to in the past, [seed_tray](https://github.com/LoamStudios/seed_tray).
8
+
9
+ ## Compatibility
10
+
11
+ Punchbox should work on Rails 4+ and really any Ruby version that's supported by your version of Rails. There's really nothing fancy happening Ruby-side.
12
+
13
+ The JavaScript is pure without any dependencies (no jQuery! 🎉). It should work down to IE9, thereby working on 98% of browsers.
14
+
15
+ Punchbox works with or without Turbolinks.
16
+
17
+ The JavaScript is only ~840 *bytes* minified and gzipped.
18
+
19
+ ## Installation
20
+
21
+ You know the drill. Add this line to your application's Gemfile:
22
+
23
+ ```ruby
24
+ gem 'punchbox'
25
+ ```
26
+
27
+ And then execute:
28
+ ```bash
29
+ $ bundle
30
+ ```
31
+
32
+ Or install it yourself as:
33
+ ```bash
34
+ $ gem install punchbox
35
+ ```
36
+
37
+ Once you've done that, require Punchbox before tree in your main JavaScript file.
38
+
39
+ ```javascript
40
+ // ...
41
+ //= require punchbox
42
+ //= require_tree .
43
+ ```
44
+
45
+ Finally, include the `punchbox_attributes` hooks in your main `<body>` tag.
46
+
47
+ ```html
48
+ <body <%= punchbox_attributes %>>
49
+ <%= yield %>
50
+ </body>
51
+ ```
52
+ ## Usage
53
+
54
+ Punchbox's syntax is very similar to that of Paloma's. To run JS on a certain page, you call Punchbox like so:
55
+
56
+ ```javascript
57
+ Punchbox.on(<controller: string>, <callable>);
58
+ ```
59
+
60
+ **Important**
61
+
62
+ Punchbox automatically runs your code after your document is ready, negating the need for `$(document).ready` and the like. If this is a problem, please make an issue and I'll consider changing this behaviour.
63
+
64
+ ### Controller
65
+
66
+ `controller` should be a string or a function that returns a string. It should be the exact name of the controller (plus namespace) that you want your code to run on. It should be ClassCase (PascalCase) only.
67
+
68
+ For example, if your controller is `PostsController`, you'd enter 'Posts'. If your controller is `AdminPanelsController`, you'd enter `AdminPanels`.
69
+
70
+ #### Namespacing
71
+
72
+ Namespacing is accomplished via forward slashes.
73
+
74
+ If your controller is `AdminPanel::Settings::UserManagersController`, you'd enter `AdminPanel/Settings/UserManagers`.
75
+
76
+ ### Callable (read this part)
77
+
78
+ `callable` can be a function, class, or object. Classes are the preferred convention, but of course you can use whatever is compatible with your current workflow.
79
+
80
+ #### Function names
81
+
82
+ Functions should be named after the actions on which they should run. A function `index` would run when the `index` action is invoked.
83
+
84
+ The exception is `controller`. Punchbox treats functions named `controller` in a special way and runs them on every action in a given Rails controller.
85
+
86
+ #### Examples
87
+
88
+ In all examples I'll be targeting the `Posts` controller. *Remember that the name of your `callable` or your JS filepath don't have anything to do with Punchbox's functionality. However, I'll be naming the callables after the controllers to keep up with the preferred convention.*
89
+
90
+ **ES2015+ (class syntax)**
91
+
92
+ ```javascript
93
+ class Posts {
94
+ controller() {
95
+ console.log('Hello from every action on a controller!');
96
+ }
97
+
98
+ index() {
99
+ console.log('Hello from just the index action!');
100
+ }
101
+
102
+ // ...
103
+ }
104
+
105
+ Punchbox.on('Posts', Posts); // Notice that you don't instantiate the class
106
+ ```
107
+
108
+ **Function syntax**
109
+
110
+ ```javascript
111
+ function Posts() {
112
+ // ...
113
+ };
114
+
115
+ Posts.prototype.controller = function() {
116
+ console.log('Hello from every action on a controller!');
117
+ };
118
+
119
+ Posts.prototype.index = function() {
120
+ console.log('Hello from just the index action!');
121
+ };
122
+
123
+ Punchbox.on('Posts', Posts); // Notice that you don't instantiate the function
124
+ ```
125
+
126
+ **Object syntax**
127
+
128
+ ```javascript
129
+ var Posts = {
130
+ controller: function() {
131
+ console.log('Hello from every action on a controller!');
132
+ },
133
+
134
+ index: function() {
135
+ console.log('Hello from just the index action!');
136
+ }
137
+ }
138
+
139
+ Punchbox.on('Posts', Posts);
140
+ ```
141
+
142
+ **CoffeeScript**
143
+
144
+ ```coffeescript
145
+ class Posts
146
+ controller: ->
147
+ console.log 'Hello from every action on a controller!'
148
+
149
+ index: ->
150
+ console.log 'Hello from just the index action!'
151
+
152
+ Punchbox.on('Posts', Posts) # Notice that you don't instantiate the class
153
+ ```
154
+
155
+ ## Contributing
156
+
157
+ If you want to contribute, don't hesitate to create an issue or PR! Since this project is in it's infancy, your input could help shape the project as a whole!
158
+
159
+ Please note that the magic happens inside `app/assets/javascripts/punchbox.es6`. `punchbox.js` is then created via Babel before deployment. If you make a PR, please only edit `punchbox.es6`.
160
+
161
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kieraneglin/punchbox/. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
162
+
163
+ ## License
164
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Punchbox'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+
33
+ task default: :test
@@ -0,0 +1,78 @@
1
+ class Punchbox {
2
+ static on(controller, classOrObject) {
3
+ let punchbox = new Punchbox();
4
+ punchbox.instantiatable = classOrObject;
5
+
6
+ punchbox._onPageLoad(() => {
7
+ punchbox._assignAttributes();
8
+ if (controller === punchbox._snakeToPascal(punchbox.controller)) {
9
+ punchbox._run();
10
+ }
11
+ });
12
+ }
13
+
14
+ _assignAttributes() {
15
+ let bodyTag = document.body;
16
+
17
+ this.controller = bodyTag.getAttribute('data-punchbox-controller');
18
+ this.action = bodyTag.getAttribute('data-punchbox-action');
19
+ }
20
+
21
+ _callIfExists(functionName) {
22
+ let instance = this.instantiatable;
23
+
24
+ if (typeof instance[functionName] === 'function') {
25
+ instance[functionName]();
26
+
27
+ if(functionName === 'controller') {
28
+ document.dispatchEvent(new Event(`punchbox:${this.controller}:run`));
29
+ } else {
30
+ document.dispatchEvent(new Event(`punchbox:${this.controller}:${this.action}:run`));
31
+ }
32
+ }
33
+ }
34
+
35
+ _instantiate() {
36
+ let classOrObject = this.instantiatable;
37
+
38
+ if (typeof classOrObject === 'function') {
39
+ return new classOrObject();
40
+ } else if (typeof classOrObject === 'object') {
41
+ return classOrObject;
42
+ }
43
+ }
44
+
45
+ _onPageLoad(callback) {
46
+ if (window.Turbolinks) {
47
+ let loadEvent = Turbolinks.EVENTS ? 'page:change' : 'turbolinks:load';
48
+
49
+ document.addEventListener(loadEvent, () => {
50
+ callback();
51
+ });
52
+ } else {
53
+ window.onload = () => {
54
+ callback();
55
+ };
56
+ }
57
+ }
58
+
59
+ _run() {
60
+ // It's like 4am. Please excuse my naming
61
+ this.instantiatable = this._instantiate();
62
+ this._callIfExists('controller');
63
+ this._callIfExists(this.action);
64
+ }
65
+
66
+ _snakeToPascal(string) {
67
+ return string.split('_').map((str) => {
68
+ return this._upperFirst(
69
+ str.split('/')
70
+ .map(this._upperFirst)
71
+ .join('/'));
72
+ }).join('');
73
+ }
74
+
75
+ _upperFirst(string) {
76
+ return string.slice(0, 1).toUpperCase() + string.slice(1, string.length);
77
+ }
78
+ }
@@ -0,0 +1,101 @@
1
+ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2
+
3
+ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4
+
5
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
+
7
+ var Punchbox = function () {
8
+ function Punchbox() {
9
+ _classCallCheck(this, Punchbox);
10
+ }
11
+
12
+ _createClass(Punchbox, [{
13
+ key: '_assignAttributes',
14
+ value: function _assignAttributes() {
15
+ var bodyTag = document.body;
16
+
17
+ this.controller = bodyTag.getAttribute('data-punchbox-controller');
18
+ this.action = bodyTag.getAttribute('data-punchbox-action');
19
+ }
20
+ }, {
21
+ key: '_callIfExists',
22
+ value: function _callIfExists(functionName) {
23
+ var instance = this.instantiatable;
24
+
25
+ if (typeof instance[functionName] === 'function') {
26
+ instance[functionName]();
27
+
28
+ if (functionName === 'controller') {
29
+ document.dispatchEvent(new Event('punchbox:' + this.controller + ':run'));
30
+ } else {
31
+ document.dispatchEvent(new Event('punchbox:' + this.controller + ':' + this.action + ':run'));
32
+ }
33
+ }
34
+ }
35
+ }, {
36
+ key: '_instantiate',
37
+ value: function _instantiate() {
38
+ var classOrObject = this.instantiatable;
39
+
40
+ if (typeof classOrObject === 'function') {
41
+ return new classOrObject();
42
+ } else if ((typeof classOrObject === 'undefined' ? 'undefined' : _typeof(classOrObject)) === 'object') {
43
+ return classOrObject;
44
+ }
45
+ }
46
+ }, {
47
+ key: '_onPageLoad',
48
+ value: function _onPageLoad(callback) {
49
+ if (window.Turbolinks) {
50
+ var loadEvent = Turbolinks.EVENTS ? 'page:change' : 'turbolinks:load';
51
+
52
+ document.addEventListener(loadEvent, function () {
53
+ callback();
54
+ });
55
+ } else {
56
+ window.onload = function () {
57
+ callback();
58
+ };
59
+ }
60
+ }
61
+ }, {
62
+ key: '_run',
63
+ value: function _run() {
64
+ // It's like 4am. Please excuse my naming
65
+ this.instantiatable = this._instantiate();
66
+ this._callIfExists('controller');
67
+ this._callIfExists(this.action);
68
+ }
69
+ }, {
70
+ key: '_snakeToPascal',
71
+ value: function _snakeToPascal(string) {
72
+ var _this = this;
73
+
74
+ return string.split('_').map(function (str) {
75
+ return _this._upperFirst(str.split('/').map(_this._upperFirst).join('/'));
76
+ }).join('');
77
+ }
78
+ }, {
79
+ key: '_upperFirst',
80
+ value: function _upperFirst(string) {
81
+ return string.slice(0, 1).toUpperCase() + string.slice(1, string.length);
82
+ }
83
+ }], [{
84
+ key: 'on',
85
+ value: function on(controller, classOrObject) {
86
+ var _this2 = this;
87
+
88
+ var punchbox = new Punchbox();
89
+ punchbox.instantiatable = classOrObject;
90
+
91
+ punchbox._onPageLoad(function () {
92
+ punchbox._assignAttributes();
93
+ if (controller === punchbox._snakeToPascal(punchbox.controller)) {
94
+ punchbox._run();
95
+ }
96
+ });
97
+ }
98
+ }]);
99
+
100
+ return Punchbox;
101
+ }();
data/lib/punchbox.rb ADDED
@@ -0,0 +1,3 @@
1
+ module Punchbox
2
+ require 'punchbox/engine' if defined?(Rails)
3
+ end
@@ -0,0 +1,6 @@
1
+ module AttributeHelper
2
+ def punchbox_attributes
3
+ "data-punchbox-controller=#{controller_path} " \
4
+ "data-punchbox-action=#{action_name}"
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ require 'punchbox/attribute_helper'
2
+
3
+ module Punchbox
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ initializer 'attribute.helper' do
7
+ ActionView::Base.send :include, AttributeHelper
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Punchbox
2
+ VERSION = '1.0.1'.freeze
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :punchbox do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: punchbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kieran Eglin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Defining page-specific Javascript shouldn't be hard. That's what Punchbox
42
+ is looking to fix
43
+ email:
44
+ - kieran.eglin@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - MIT-LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - app/assets/javascripts/punchbox.es6
53
+ - app/assets/javascripts/punchbox.js
54
+ - lib/punchbox.rb
55
+ - lib/punchbox/attribute_helper.rb
56
+ - lib/punchbox/engine.rb
57
+ - lib/punchbox/version.rb
58
+ - lib/tasks/punchbox_tasks.rake
59
+ homepage: https://github.com/kieraneglin/punchbox
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 1.9.3
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.6.11
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Dead simple page-specific Javascript for Rails
83
+ test_files: []