switch_access-rails 1.1.4

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/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Copyright (c) 2012, Leif Ringstad
2
+ All rights reserved.
3
+
4
+ Please not that Switch-Access from version 1.1 is dual licensed under GPL or a commercial license.
5
+
6
+ You can either
7
+ a) License it under GPL (See LICENSE.GPL for details)
8
+ b) Obtain a commercial license (Contact leifcr@gmail.com for details)
9
+
10
+ Switch Access library version 1.0 was licensed under the BSD 2-clause license.
data/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # Rails 3.2 Integration for switch_access
2
+
3
+ The `switch_access-rails` gem integrates the [Switch Access](http://leifcr.github.com/switch_access) library with the Rails 3.2 asset pipeline.
4
+
5
+
6
+ ## Usage
7
+
8
+ ### Installation
9
+
10
+ **1. Add `switch_access-rails` to your Gemfile**
11
+
12
+ gem 'switch_access-rails'
13
+
14
+ **2. Run `bundle install`.**
15
+
16
+ **3. Using**
17
+
18
+ Add to your application.js:
19
+ _jQuery_ is only needed if you haven't included them already
20
+
21
+ ```js
22
+ //= require jquery
23
+ //= require switch_access
24
+ ```
25
+ ### Helper methods
26
+ Four helper methods that should be used when creating switch-elements, and initializing the library
27
+
28
+ ```ruby
29
+ # Reset counters to 0, this is done before rendering
30
+ sw_element_reset_counters()
31
+
32
+ # get the next "group" classname with an id appended (increments automatically)
33
+ sw_element_begin_group()
34
+
35
+ # get the next "element" classname with an id appended (increments automatically)
36
+ sw_element_next_class()
37
+
38
+ # ends the group that was started.
39
+ sw_element_end_group()
40
+
41
+ # Get javascript initializer with given options.
42
+ # (Recommended to have as late as possible on the page)
43
+ sw_element_js_initializer(options = {})
44
+
45
+ # finalizes the switch access. Note: Must be done on the end of each page for now...
46
+ sw_element_fini()
47
+
48
+ ```
49
+
50
+ ## Example
51
+
52
+ Example in a ERB view
53
+
54
+ ```erb
55
+ <%=
56
+ content_tag :div, :class => sw_element_begin_group() do
57
+ content_tag(:div, "Switch element 1 in group 1", :class => sw_element_next_class()) +
58
+ content_tag(:div, "Switch element 2 in group 1", :class => sw_element_next_class()) +
59
+ content_tag(:div, "Switch element 3 in group 1", :class => sw_element_next_class())
60
+ end
61
+
62
+ %>
63
+ <% sw_element_end_group() %>
64
+
65
+ <%=
66
+ content_tag :div, :class => sw_element_begin_group() do
67
+ content_tag(:div, "Switch element 1 in group 2", :class => sw_element_next_class()) +
68
+ content_tag(:div, "Switch element 2 in group 2", :class => sw_element_next_class())
69
+ end
70
+ %>
71
+ <% sw_element_end_group() %>
72
+
73
+ <%= content_tag :div, "Switch element 3 outside groups", :class => sw_element_next_class() %>
74
+ <%= sw_element_js_initializer({
75
+ :debug => false, # can be removed if value is false
76
+ :switches => {
77
+ :number_of_switches => 2,
78
+ :groups => true,
79
+ :delay_for_allowed_keypress => 0
80
+ }
81
+ }) %>
82
+ <%= sw_element_fini() %>
83
+ ```
84
+
85
+ See [leifcr.github.com/switch_access](http://leifcr.github.com/switch_access) for examples, unit tests of the library and documentation.
86
+
87
+ ### Example CSS
88
+
89
+ You can include sample CSS stylesheets to see how highlighters/classes work
90
+ ```css
91
+ /* Complete example
92
+ *= require switch_access/example
93
+ *
94
+ * Only highlighters
95
+ *= require switch_access/example_highlighter
96
+ *
97
+ * Only switch element
98
+ *= require switch_access/example_switch_element
99
+ */
100
+ ```
101
+
102
+ ### Debugging
103
+
104
+ If you need to debug, log4javascript is included in the gem To avoid issues with log4javascript in other gems, it's namespaced under switch_access
105
+
106
+ First, add log4javascript to your application.js or other .js
107
+ ```js
108
+ //= require switch_access/log4javascript
109
+ ```
110
+
111
+ Second, set debug to true, and a log4javascript Appender/console should show up.
112
+
113
+ If you have a div with id set to "logger" the appender/console will be created inside that div.
114
+
115
+ ## License
116
+ This GEM is dual licensed under the GPL license and a commercial license. See LICENSE and LICENSE.GPL for details. For commercial usage, please contact leifcr@gmail.com
117
+
118
+ ## Contact
119
+ Feel free to contact me at @leifcr (twitter).
120
+
121
+ Copyright (c) 2012 Leif Ringstad
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rubygems/package_task'
4
+
5
+ $:.push File.expand_path('../lib', __FILE__)
6
+ require 'switch_access/rails/version'
7
+
8
+ gemspec = eval(File.read('switch_access-rails.gemspec'))
9
+ Gem::PackageTask.new(gemspec) do |pkg|
10
+ pkg.gem_spec = gemspec
11
+ end
12
+
13
+ desc 'build the gem and release it to rubygems.org'
14
+ task :release => :gem do
15
+ sh "gem push pkg/switch_access-rails-#{SwitchAccess::Rails::VERSION}.gem"
16
+ end
@@ -0,0 +1 @@
1
+ require 'switch_access/rails'
@@ -0,0 +1,3 @@
1
+ require 'switch_access/rails/version'
2
+ require 'switch_access/rails/engine'
3
+ require 'switch_access/rails/railtie'
@@ -0,0 +1,6 @@
1
+ module SwitchAccess
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ require 'switch_access/rails/view_helpers'
2
+
3
+ module SwitchAccess
4
+ module Rails
5
+ class Railtie < ::Rails::Railtie
6
+ ActiveSupport.on_load(:action_view) do
7
+ include SwitchAccess::Rails::ViewHelpers
8
+ end
9
+ # initializer "switch_access.rails.view_helpers" do |app|
10
+ # ActionView::Base.send :include, ViewHelpers
11
+ # end
12
+ end # class Railtie < Rails::Railtie
13
+ end # module Rails
14
+ end # module SwitchAccess
@@ -0,0 +1,5 @@
1
+ module SwitchAccess
2
+ module Rails
3
+ VERSION = '1.1.4'
4
+ end
5
+ end
@@ -0,0 +1,109 @@
1
+ module SwitchAccess
2
+ module Rails
3
+ module ViewHelpers
4
+
5
+ @@_sw_element_sci_class = nil
6
+
7
+ def sw_element_init(options = {})
8
+ sw_element_fini()
9
+ sw_element_sci(options)
10
+ end
11
+
12
+ def sw_element_sci(options = {})
13
+ @@_sw_element_sci_class = SwitchElements.new(options) if @@_sw_element_sci_class == nil
14
+ @@_sw_element_sci_class
15
+ end
16
+
17
+ #
18
+ # Reset counters
19
+ #
20
+ def sw_element_reset_counters
21
+ sw_element_sci().reset_counters()
22
+ end
23
+
24
+ #
25
+ # Begin a switch element group
26
+ #
27
+ def sw_element_begin_group
28
+ sw_element_sci().begin_group()
29
+ end
30
+
31
+ def sw_element_fini
32
+ @@_sw_element_sci_class = nil
33
+ end
34
+
35
+ #
36
+ # End a switch element group
37
+ #
38
+ def sw_element_end_group
39
+ ret = sw_element_sci().end_group()
40
+ if (ret < 0)
41
+ sw_element_fini()
42
+ end
43
+ ret
44
+ end
45
+
46
+ #
47
+ # Get the next switch element class
48
+ #
49
+ def sw_element_next_class
50
+ sw_element_sci().next_element_class()
51
+ end
52
+
53
+ #
54
+ # Get javascript initializer for switch access
55
+ #
56
+ def sw_element_js_initializer(options = {})
57
+ str =
58
+ <<-js
59
+ $(document).ready(function() {
60
+ if (typeof window._railsaccess == 'undefined') {
61
+ window._rails_sw_access = new SwitchAccess(#{options.to_json});
62
+ }
63
+ });
64
+ js
65
+ javascript_tag str.html_safe
66
+ end
67
+
68
+ class SwitchElements
69
+ def initialize(options = {})
70
+ @options = options
71
+ @options[:element_class_name] = "switch-element-" if !options.has_key?(:element_class_name)
72
+ reset_counters()
73
+ end
74
+
75
+ def reset_counters()
76
+ @parent_next_element_id = 0
77
+ @next_element_id = 0
78
+ @level = 0
79
+ end
80
+
81
+ def begin_group
82
+ @parent_next_element_id = @next_element_id + 1
83
+ @next_element_id = 1
84
+ @level += 1
85
+ "#{@options[:element_class_name]}#{@parent_next_element_id}"
86
+ end
87
+
88
+ def end_group
89
+ @level -= 1
90
+ @next_element_id = @parent_next_element_id
91
+ end
92
+
93
+ #
94
+ # Get the next switch element class
95
+ #
96
+ def next_element_class
97
+ "#{@options[:element_class_name]}#{increase_next_id()}"
98
+ end
99
+ #
100
+ # Increase the switch element id and return it
101
+ #
102
+ def increase_next_id
103
+ @next_element_id += 1
104
+ end
105
+ end # class SwitchElements
106
+
107
+ end # module ViewHelpers
108
+ end # module Rails
109
+ end # module SwitchAccess
@@ -0,0 +1,3 @@
1
+ //= require switch_access/execute_method
2
+ //= require switch_access/jquery.csswatch
3
+ //= require switch_access/switch_access
@@ -0,0 +1,107 @@
1
+ ###
2
+ # Execute Method
3
+ # (c) 2012 Leif Ringstad
4
+ # Licensed under the freeBSD license (see LICENSE.txt for details)
5
+ #
6
+ # Source: http://github.com/leifcr/execute_method
7
+ # v 1.0.0
8
+ ###
9
+
10
+ ExecuteMethod =
11
+ getFunctionsAndProperties: (str) ->
12
+ # console.log"getFunctionsAndProperties"
13
+ arr = str.split(".")
14
+ i = 0
15
+ ret = []
16
+ while i < arr.length
17
+ ret.push ExecuteMethod.getFunctionAndParameters(arr[i])
18
+ i++
19
+ # console.log ret
20
+ ret
21
+
22
+ getFunctionAndParameters: (str) ->
23
+ # console.log "getFunctionAndParameters"
24
+ if ExecuteMethod.isFunction(str)
25
+ params = str.substring(str.indexOf("(")+1, str.indexOf(")"))
26
+ if params.length > 0
27
+ params = ExecuteMethod.splitAndTypeCastParameters(params)
28
+ else
29
+ params = []
30
+ func = str.substring(0, str.indexOf ("\(") )
31
+ isfunc = true
32
+ else
33
+ func = str
34
+ params = null
35
+ isfunc = false
36
+
37
+ {func: func, params: params, isfunc: isfunc}
38
+
39
+ splitAndTypeCastParameters: (params) ->
40
+ # console.log"splitAndTypeCastParameters"
41
+ arr = params.split(",")
42
+ ret = []
43
+ i = 0
44
+ ret = []
45
+ while i < arr.length
46
+ ret.push ExecuteMethod.typecastParameter(arr[i])
47
+ i++
48
+ ret
49
+
50
+ isFunction: (str) ->
51
+ # console.log "isFunction"
52
+ if ExecuteMethod.regexIndexOf(str, /(\([\d|\D]+\))|(\(\))/, 0) != -1
53
+ return true
54
+ false
55
+
56
+ regexIndexOf: (string, regex, startpos) ->
57
+ # console.log "regexIndexOf"
58
+ indexOf = string.substring(startpos || 0).search(regex);
59
+ if (indexOf >= 0) then (indexOf + (startpos || 0)) else indexOf;
60
+
61
+ typecastParameter: (param) ->
62
+ param = param.trim()
63
+ param = param.replace(/^"/, "")
64
+ param = param.replace(/"$/m, "")
65
+ if param.search(/^\d+$/) == 0
66
+ # only numbers, parse to integer
67
+ return parseInt(param)
68
+ else if param.search(/^\d+\.\d+$/) == 0
69
+ return parseFloat(param)
70
+ else if param == "false"
71
+ return false
72
+ else if param == "true"
73
+ return true
74
+
75
+ param # just return the param as a string otherwise
76
+
77
+ executeSingleFunction: (func, params, context, _that) ->
78
+ context[func].apply(_that, params)
79
+
80
+ getSingleProperty: (property, context) ->
81
+ context[property]
82
+
83
+ ###
84
+ # @param {String} Provide a string on what to execute (e.g. this.is.something(true).to_run() or myFunction().property or myFunction())
85
+ # @param {Object} Provide a object to run the string provided on
86
+ # @param {Object} Provide an object that points to the "this" pointer which
87
+ ###
88
+ executeMethodByFunctionName: (str, context) ->
89
+ func_data = ExecuteMethod.getFunctionsAndProperties(str)
90
+ # since it's possible to chain functions and/or properties, and it's not possible to chain properly do a loop
91
+ i = 0
92
+ current_context = context
93
+ current_val = null
94
+ while i < func_data.length
95
+ if (func_data[i]["isfunc"] == true)
96
+ current_context = ExecuteMethod.executeSingleFunction(func_data[i]["func"], func_data[i]["params"], current_context, context)
97
+ else
98
+ current_context = ExecuteMethod.getSingleProperty(func_data[i]["func"], current_context)
99
+ i++
100
+ current_context
101
+
102
+ if (!String.prototype.trim)
103
+ String.prototype.trim = ->
104
+ this.replace(/^\s+|\s+$/g,'');
105
+
106
+ if (window.ExecuteMethod == "undefined" || window.ExecuteMethod == null || window.ExecuteMethod == undefined)
107
+ window.ExecuteMethod = ExecuteMethod
@@ -0,0 +1,264 @@
1
+ ###
2
+ jQuery css-watch event Coffeescript v1.2 - 11/20/2012
3
+ http://github.com/leifcr/jquery-csswatch/
4
+ (c) 2012 Leif Ringstad
5
+
6
+ @author Leif Ringstad
7
+ @version 1.0
8
+
9
+ Licensed under the freeBSD license
10
+ ###
11
+
12
+ # Note that with this pattern, as per Alex Sexton's, the plugin logic
13
+ # hasn't been nested in a jQuery plugin. Instead, we just use
14
+ # jQuery for its instantiation.
15
+
16
+ (($, window, document) ->
17
+
18
+ ###
19
+ Plugin constructor
20
+ ###
21
+ CssWatch = (elem, options) ->
22
+ @elem = elem
23
+ @$elem = $(elem)
24
+ @options = options
25
+ @cb_timer_id = null
26
+ @cached_function_name = ""
27
+ @stop_requested = false
28
+ return
29
+
30
+ ###
31
+ Plugin prototype
32
+ ###
33
+ CssWatch:: =
34
+ defaults:
35
+ event_name: "css-change"
36
+ data_attr_name: "css-watch-data"
37
+ use_event: true
38
+ callback: null
39
+ props: ""
40
+ props_functions: {}
41
+
42
+
43
+ ###
44
+ Initializer
45
+ ###
46
+ init: ->
47
+ @config = $.extend({}, @defaults, @options, @metadata)
48
+ @config.props = @splitAndTrimProps(@config.props)
49
+ if @config.props.length > 0
50
+ @setInitialData()
51
+ @start()
52
+
53
+ @
54
+
55
+ ###
56
+ split and trim properties
57
+ ###
58
+ splitAndTrimProps: (props) ->
59
+ arr = props.split(",")
60
+ ret = []
61
+ i = 0
62
+ while i < arr.length
63
+ ret.push arr[i].trim()
64
+ i++
65
+ ret
66
+
67
+ ###
68
+ set initial data
69
+ ###
70
+ setInitialData: ->
71
+ i = 0
72
+ while i < @config.props.length
73
+ @setData @config.props[i], @getPropertyValue(@config.props[i])
74
+ i++
75
+ return
76
+
77
+ ###
78
+ set a data element for a css property on the current element
79
+ ###
80
+ setData: (property, value) ->
81
+ @$elem.data("#{@config.data_attr_name}-#{property}", value)
82
+
83
+ ###
84
+ update data attributes from changes
85
+ ###
86
+ updateDataFromChanges: (changes) ->
87
+ @setData property, changes[property] for property, value in Object.keys(changes)
88
+ return
89
+
90
+ ###
91
+ get the datavalue stored for a property
92
+ ###
93
+ getDataValue: (property) ->
94
+ @$elem.data("#{@config.data_attr_name}-#{property}")
95
+
96
+ ###
97
+ get css property value (from jquery css or from custom function if needed)
98
+ ###
99
+ getPropertyValue: (property) ->
100
+ return @$elem.css(property) if (@cached_function_name == null) || (Object.keys(@config.props_functions).length == 0)
101
+
102
+ if @cached_function_name == ""
103
+ keys = Object.keys(@config.props_functions)
104
+ if property in keys
105
+ @cached_function_name = @config.props_functions[property]
106
+ else
107
+ @cached_function_name == null
108
+
109
+ if (@cached_function_name != "") && (@cached_function_name != null)
110
+ if (window.ExecuteMethod)
111
+ return ExecuteMethod.executeMethodByFunctionName(@cached_function_name, @$elem)
112
+ else
113
+ console.log "You are missing the ExecuteMethod library."
114
+ else
115
+ return @$elem.css(property)
116
+
117
+ ###
118
+ get object of changes
119
+ ###
120
+ changedProperties: ->
121
+ i = 0
122
+ ret = {}
123
+ while i < @config.props.length
124
+ if (@getPropertyValue(@config.props[i]) != @getDataValue(@config.props[i]))
125
+ ret[@config.props[i]] = @getPropertyValue(@config.props[i])
126
+ i++
127
+ ret
128
+
129
+ ###
130
+ stop csswatch / checking of css attributes
131
+ ###
132
+ stop: ->
133
+ return if (typeof @config == "undefined" || @config == null)
134
+ stop_requested = true
135
+ # stop the timer/windowanimate cb for this object
136
+ window.cssWatchCancelAnimationFrame(@cb_timer_id)
137
+
138
+
139
+ ###
140
+ start csswatch / checking of css attributes
141
+ ###
142
+ start: ->
143
+ return if (typeof @config == "undefined" || @config == null)
144
+ @stop_requested = false
145
+ # start the timer/windowanimate cb for this object if it isn't running
146
+ @cb_timer_id = window.cssWatchRequestAnimationFrame(=> @check(); return)
147
+ return
148
+
149
+ ###
150
+ the actual checking of changes
151
+ ###
152
+ check: ->
153
+ return false if (typeof @config == "undefined" || @config == null)
154
+ return false if @stop_requested == true
155
+ changes = @changedProperties()
156
+
157
+ if (Object.keys(changes).length > 0)
158
+ if @config.use_event
159
+ @$elem.trigger(@config.event_name, changes)
160
+
161
+ if @config.callback != null
162
+ @config.callback.apply(null, [changes])
163
+ # @config.callback.call({changes})
164
+ # set new data for each changed property
165
+ @updateDataFromChanges(changes)
166
+
167
+ @cb_timer_id = window.cssWatchRequestAnimationFrame(=> @check(); return)
168
+ false
169
+
170
+ ###
171
+ destroy plugin (stop/remove data)
172
+ ###
173
+ destroy: ->
174
+ @stop()
175
+ @$elem.removeData("css-watch-object")
176
+ @$elem.removeData(@config.data_attr_name)
177
+ return null
178
+
179
+ ###
180
+ Set defaults
181
+ ###
182
+ CssWatch.defaults = CssWatch::defaults
183
+
184
+ ###
185
+ Jquery extension for plugin
186
+ Plugin funcitonality is in the class above
187
+ ###
188
+ $.fn.csswatch = (options) ->
189
+ @each ->
190
+ if typeof options is "object" or not options
191
+ # check if there is an object existing, if so, delete it!
192
+ data = $(@).data("css-watch-object")
193
+ unless data
194
+ obj = new CssWatch(@, options)
195
+ $(@).data("css-watch-object", obj)
196
+ obj.init()
197
+ return
198
+ else if typeof options is "string"
199
+ obj = $(@).data("css-watch-object")
200
+ if obj && obj[options]
201
+ obj[options].apply this
202
+
203
+ return
204
+
205
+ #optional: window.Plugin = Plugin;
206
+
207
+ ) jQuery, window, document
208
+
209
+ ###
210
+ #
211
+ # Cross browser Object.keys implementation
212
+ #
213
+ # This is suggested implementation from Mozilla for supporting browser that do not implement Object.keys
214
+ # if object doesn't have .keys function
215
+ # if(!Object.keys) Object.keys = function(o){
216
+ # if (o !== Object(o))
217
+ # throw new TypeError('Object.keys called on non-object');
218
+ # var ret=[],p;
219
+ # for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
220
+ # return ret;
221
+ # }
222
+ ###
223
+
224
+ unless Object.keys
225
+ Object.keys = (o) ->
226
+ throw new TypeError("Object.keys called on non-object") if o isnt Object(o)
227
+ ret = []
228
+ p = undefined
229
+ for p of o
230
+ ret.push p if Object::hasOwnProperty.call(o, p)
231
+ ret
232
+
233
+ ###
234
+ Cross browser requestAnimationFrame
235
+ Not including settimeout as it will have a static value for timeout
236
+ ###
237
+
238
+ unless window.cssWatchRequestAnimationFrame
239
+ window.cssWatchRequestAnimationFrame = (->
240
+ window.webkitAnimationFrame or
241
+ window.webkitRequestAnimationFrame or
242
+ window.mozRequestAnimationFrame or
243
+ window.oRequestAnimationFrame or
244
+ window.msRequestAnimationFrame or
245
+ window.requestAnimationFrame or
246
+ (callback, element) ->
247
+ window.setTimeout(callback, 1000/60)
248
+ )()
249
+
250
+ ###
251
+ Cross browser cancelAnimationFrame
252
+ ###
253
+ unless window.cssWatchCancelAnimationFrame
254
+ window.cssWatchCancelAnimationFrame = (->
255
+ window.cancelAnimationFrame or
256
+ window.webkitCancelAnimationFrame or
257
+ window.webkitCancelRequestAnimationFrame or
258
+ window.mozCancelAnimationFrame or
259
+ window.mozCancelRequestAnimationFrame or
260
+ window.oCancelRequestAnimationFrame or
261
+ window.msCancelRequestAnimationFrame or
262
+ (timeout_id) -> # function FrameRequestCallback
263
+ window.clearTimeout timeout_id
264
+ )()