hoarder-js 0.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.
Files changed (44) hide show
  1. data/CHANGELOG +1 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +100 -0
  4. data/LICENSE +21 -0
  5. data/Manifest +42 -0
  6. data/README.rdoc +0 -0
  7. data/Rakefile +38 -0
  8. data/assets/scripts/coffee/hoarder/form/form.coffee +48 -0
  9. data/assets/scripts/coffee/hoarder/form/form_element.coffee +22 -0
  10. data/assets/scripts/coffee/hoarder/form_manager.coffee +32 -0
  11. data/assets/scripts/coffee/hoarder/submitter/form_submitter.coffee +29 -0
  12. data/assets/scripts/coffee/hoarder/submitter/submitters/polling_submitter.coffee +36 -0
  13. data/assets/scripts/coffee/hoarder/submitter/submitters/simple_submitter.coffee +30 -0
  14. data/assets/scripts/coffee/hoarder/validator/constraints/alpha_constraint.coffee +18 -0
  15. data/assets/scripts/coffee/hoarder/validator/constraints/alphanumeric_constraint.coffee +18 -0
  16. data/assets/scripts/coffee/hoarder/validator/constraints/credit_card_constraint.coffee +18 -0
  17. data/assets/scripts/coffee/hoarder/validator/constraints/email_constraint.coffee +18 -0
  18. data/assets/scripts/coffee/hoarder/validator/constraints/max_length_constraint.coffee +18 -0
  19. data/assets/scripts/coffee/hoarder/validator/constraints/min_length_constraint.coffee +18 -0
  20. data/assets/scripts/coffee/hoarder/validator/constraints/numeric_constraint.coffee +18 -0
  21. data/assets/scripts/coffee/hoarder/validator/constraints/phone_constraint.coffee +18 -0
  22. data/assets/scripts/coffee/hoarder/validator/constraints/required_constraint.coffee +18 -0
  23. data/assets/scripts/coffee/hoarder/validator/error/validation_error.coffee +9 -0
  24. data/assets/scripts/coffee/hoarder/validator/form_validator.coffee +53 -0
  25. data/assets/scripts/js/lib/jquery.js +5 -0
  26. data/bin/hoarder.js +1197 -0
  27. data/config/assets.rb +8 -0
  28. data/hoarder-js.gemspec +36 -0
  29. data/lib/hoarder.rb +1 -0
  30. data/lib/hoarder/symbols.rb +17 -0
  31. data/spec/jasmine.yml +44 -0
  32. data/spec/runner.html +75 -0
  33. data/spec/support/classes.coffee +0 -0
  34. data/spec/support/helpers.coffee +22 -0
  35. data/spec/support/mocks.coffee +42 -0
  36. data/spec/support/objects.coffee +0 -0
  37. data/spec/support/requirements.coffee +1 -0
  38. data/spec/tests/form_manager_spec.coffee +43 -0
  39. data/spec/tests/submitter/form_submitter_spec.coffee +47 -0
  40. data/spec/tests/submitter/submitters/polling_submitter_spec.coffee +60 -0
  41. data/spec/tests/submitter/submitters/simple_submitter_spec.coffee +19 -0
  42. data/spec/tests/validator/constraints_spec.coffee +74 -0
  43. data/spec/tests/validator/form_validator_spec.coffee +29 -0
  44. metadata +132 -0
@@ -0,0 +1 @@
1
+ v0.0.1 new library
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ gem "echoe"
4
+ gem 'rake'
5
+ gem 'jasmine'
6
+ gem 'jasmine-headless-webkit'
7
+
8
+ gem 'keystone', git: "git://github.com/jpeace/keystone.git"
9
+ gem 'cronus', git: "git://github.com/tshelburne/cronus-js.git"
@@ -0,0 +1,100 @@
1
+ GIT
2
+ remote: git://github.com/jpeace/keystone.git
3
+ revision: 3680c30328bf3b93af7c7f1b1bad685cbaec35dd
4
+ specs:
5
+ keystone (0.0.1)
6
+ closure-compiler
7
+ coffee-script
8
+ sass
9
+ sinatra
10
+
11
+ GIT
12
+ remote: git://github.com/tshelburne/cronus-js.git
13
+ revision: c2cb5da182efb6c3742518dabda93f48b5281126
14
+ specs:
15
+ cronus (0.0.1)
16
+
17
+ GEM
18
+ remote: http://rubygems.org/
19
+ specs:
20
+ allison (2.0.3)
21
+ childprocess (0.3.9)
22
+ ffi (~> 1.0, >= 1.0.11)
23
+ closure-compiler (1.1.8)
24
+ coffee-script (2.2.0)
25
+ coffee-script-source
26
+ execjs
27
+ coffee-script-source (1.6.2)
28
+ diff-lcs (1.2.4)
29
+ echoe (4.6.3)
30
+ allison (>= 2.0.3)
31
+ gemcutter (>= 0.7.0)
32
+ rake (>= 0.9.2)
33
+ rdoc (>= 3.6.1)
34
+ rubyforge (>= 2.0.4)
35
+ execjs (1.4.0)
36
+ multi_json (~> 1.0)
37
+ ffi (1.8.1)
38
+ gemcutter (0.7.1)
39
+ hike (1.2.2)
40
+ jasmine (1.3.2)
41
+ jasmine-core (~> 1.3.1)
42
+ rack (~> 1.0)
43
+ rspec (>= 1.3.1)
44
+ selenium-webdriver (>= 0.1.3)
45
+ jasmine-core (1.3.1)
46
+ jasmine-headless-webkit (0.8.4)
47
+ coffee-script
48
+ jasmine-core (~> 1.1)
49
+ multi_json
50
+ rainbow
51
+ sprockets (~> 2)
52
+ json (1.7.7)
53
+ json_pure (1.7.7)
54
+ multi_json (1.7.2)
55
+ rack (1.5.2)
56
+ rack-protection (1.5.0)
57
+ rack
58
+ rainbow (1.1.4)
59
+ rake (10.0.4)
60
+ rdoc (4.0.1)
61
+ json (~> 1.4)
62
+ rspec (2.13.0)
63
+ rspec-core (~> 2.13.0)
64
+ rspec-expectations (~> 2.13.0)
65
+ rspec-mocks (~> 2.13.0)
66
+ rspec-core (2.13.1)
67
+ rspec-expectations (2.13.0)
68
+ diff-lcs (>= 1.1.3, < 2.0)
69
+ rspec-mocks (2.13.1)
70
+ rubyforge (2.0.4)
71
+ json_pure (>= 1.1.7)
72
+ rubyzip (0.9.9)
73
+ sass (3.2.8)
74
+ selenium-webdriver (2.32.1)
75
+ childprocess (>= 0.2.5)
76
+ multi_json (~> 1.0)
77
+ rubyzip
78
+ websocket (~> 1.0.4)
79
+ sinatra (1.4.2)
80
+ rack (~> 1.5, >= 1.5.2)
81
+ rack-protection (~> 1.4)
82
+ tilt (~> 1.3, >= 1.3.4)
83
+ sprockets (2.9.3)
84
+ hike (~> 1.2)
85
+ multi_json (~> 1.0)
86
+ rack (~> 1.0)
87
+ tilt (~> 1.1, != 1.3.0)
88
+ tilt (1.3.7)
89
+ websocket (1.0.7)
90
+
91
+ PLATFORMS
92
+ ruby
93
+
94
+ DEPENDENCIES
95
+ cronus!
96
+ echoe
97
+ jasmine
98
+ jasmine-headless-webkit
99
+ keystone!
100
+ rake
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Tim Shelburne
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,42 @@
1
+ CHANGELOG
2
+ Gemfile
3
+ Gemfile.lock
4
+ LICENSE
5
+ Manifest
6
+ README.rdoc
7
+ Rakefile
8
+ assets/scripts/coffee/hoarder/form/form.coffee
9
+ assets/scripts/coffee/hoarder/form/form_element.coffee
10
+ assets/scripts/coffee/hoarder/form_manager.coffee
11
+ assets/scripts/coffee/hoarder/submitter/form_submitter.coffee
12
+ assets/scripts/coffee/hoarder/submitter/submitters/polling_submitter.coffee
13
+ assets/scripts/coffee/hoarder/submitter/submitters/simple_submitter.coffee
14
+ assets/scripts/coffee/hoarder/validator/constraints/alpha_constraint.coffee
15
+ assets/scripts/coffee/hoarder/validator/constraints/alphanumeric_constraint.coffee
16
+ assets/scripts/coffee/hoarder/validator/constraints/credit_card_constraint.coffee
17
+ assets/scripts/coffee/hoarder/validator/constraints/email_constraint.coffee
18
+ assets/scripts/coffee/hoarder/validator/constraints/max_length_constraint.coffee
19
+ assets/scripts/coffee/hoarder/validator/constraints/min_length_constraint.coffee
20
+ assets/scripts/coffee/hoarder/validator/constraints/numeric_constraint.coffee
21
+ assets/scripts/coffee/hoarder/validator/constraints/phone_constraint.coffee
22
+ assets/scripts/coffee/hoarder/validator/constraints/required_constraint.coffee
23
+ assets/scripts/coffee/hoarder/validator/error/validation_error.coffee
24
+ assets/scripts/coffee/hoarder/validator/form_validator.coffee
25
+ assets/scripts/js/lib/jquery.js
26
+ bin/hoarder.js
27
+ config/assets.rb
28
+ lib/hoarder.rb
29
+ lib/hoarder/symbols.rb
30
+ spec/jasmine.yml
31
+ spec/runner.html
32
+ spec/support/classes.coffee
33
+ spec/support/helpers.coffee
34
+ spec/support/mocks.coffee
35
+ spec/support/objects.coffee
36
+ spec/support/requirements.coffee
37
+ spec/tests/form_manager_spec.coffee
38
+ spec/tests/submitter/form_submitter_spec.coffee
39
+ spec/tests/submitter/submitters/polling_submitter_spec.coffee
40
+ spec/tests/submitter/submitters/simple_submitter_spec.coffee
41
+ spec/tests/validator/constraints_spec.coffee
42
+ spec/tests/validator/form_validator_spec.coffee
File without changes
@@ -0,0 +1,38 @@
1
+ $: << File.expand_path("#{File.dirname(__FILE__)}/lib")
2
+
3
+ require 'hoarder'
4
+ require 'cronus'
5
+
6
+ require 'rake'
7
+ require 'jasmine-headless-webkit'
8
+ require 'keystone'
9
+ require 'echoe'
10
+
11
+ Echoe.new("hoarder-js") do |p|
12
+ p.author = "Tim Shelburne"
13
+ p.email = "shelburt02@gmail.com"
14
+ p.url = "https://github.com/tshelburne/hoarder-js"
15
+
16
+ p.ignore_pattern = FileList[".gitignore"]
17
+ p.development_dependencies = [ "jasmine", "jasmine-headless-webkit" ]
18
+ end
19
+
20
+ desc "Default"
21
+ task default: :'test:jasmine'
22
+
23
+ namespace :test do
24
+
25
+ desc "Run Jasmine tests"
26
+ Jasmine::Headless::Task.new(jasmine: :assets) do |t|
27
+ t.colors = true
28
+ t.keep_on_error = true
29
+ t.jasmine_config = './spec/jasmine.yml'
30
+ end
31
+
32
+ end
33
+
34
+ desc "Build assets"
35
+ Keystone::RakeTask.new :assets do |t|
36
+ t.config_file = "config/assets.rb"
37
+ t.output_path = 'bin'
38
+ end
@@ -0,0 +1,48 @@
1
+ require "lib/jquery"
2
+
3
+ FormElement = require "hoarder/form/form_element"
4
+
5
+ #
6
+ # @author - Tim Shelburne <tim@musiconelive.com>
7
+ #
8
+ # wraps an HTML form for easier form management
9
+ #
10
+ class Form
11
+ constructor: (formId, @type = "simple")->
12
+ @form = $("##{formId}")
13
+ @form.submit (e)-> e.preventDefault()
14
+ @action = @form.attr("action")
15
+ @method = @form.attr("method")
16
+ @addedElements = []
17
+
18
+ elements: ->
19
+ elements = []
20
+ inputs = @form.find("input")
21
+ elements = elements.concat inputs.toArray() if inputs.length > 0
22
+ selects = @form.find("select")
23
+ elements = elements.concat selects.toArray() if selects.length > 0
24
+ textareas = @form.find("textarea")
25
+ elements = elements.concat textareas.toArray() if textareas.length > 0
26
+
27
+ formElements = []
28
+ for element in elements
29
+ validationRules = if element.getAttribute("data-validation")? then (rule.trim() for rule in element.getAttribute("data-validation").split(',')) else []
30
+ selector = "#{element.nodeName}[data-bind='#{element.getAttribute("data-bind")}']"
31
+ formElements.push new FormElement(element.name, element.value, selector, validationRules)
32
+ formElements
33
+
34
+ addElement: (name, value, isRemovable = true)->
35
+ @form.append "<input type='hidden' name='#{name}' value='#{value}'/>"
36
+ @addedElements.push $("input[name='#{name}']", @form) if isRemovable
37
+
38
+ addElements: (elements)-> @addElement(element.name, element.value) for element in elements
39
+
40
+ updateAddedElement: (name, value)-> @form.find("input[name='#{name}']").val(value)
41
+
42
+ clearAddedElements: ->
43
+ element.remove() for element in @addedElements
44
+ @addedElements = []
45
+
46
+ serialize: -> @form.serialize()
47
+
48
+ return Form
@@ -0,0 +1,22 @@
1
+ require "lib/jquery"
2
+
3
+ #
4
+ # @author - Tim Shelburne <tim@musiconelive.com>
5
+ #
6
+ # represents a single element in a form
7
+ #
8
+ class FormElement
9
+ constructor: (@name, @value, @selector, @validationRules = [])->
10
+
11
+ addError: (error)->
12
+ $(@selector).closest("li").addClass("invalid")
13
+ $(@selector).closest("li").find("aside.tooltip").html(error.message)
14
+ $(@selector).focus -> $(this).closest("li").addClass("focused")
15
+ $(@selector).blur -> $(this).closest("li").removeClass("focused")
16
+
17
+ clearError: ->
18
+ $(@selector).closest("li").removeClass("invalid")
19
+ $(@selector).closest("li").find("aside.tooltip").html("")
20
+ $(@selector).unbind("focus").unbind("blur")
21
+
22
+ return FormElement
@@ -0,0 +1,32 @@
1
+ Signal = require "cronus/signal"
2
+ SignalRelay = require "cronus/signal_relay"
3
+
4
+ FormSubmitter = require 'hoarder/submitter/form_submitter'
5
+ FormValidator = require 'hoarder/validator/form_validator'
6
+
7
+ #
8
+ # @author - Tim Shelburne <tim@musiconelive.com>
9
+ #
10
+ # abstracts submitting and validating forms from the validator and submitter
11
+ #
12
+ class FormManager
13
+ constructor: (@formSubmitter, @formValidator)->
14
+ @validatedWithErrors = new Signal()
15
+ @submittedWithSuccess = new SignalRelay(@formSubmitter.submittedWithSuccess)
16
+ @submittedWithError = new SignalRelay(@formSubmitter.submittedWithError)
17
+
18
+ @default: (pollingUrl="")->
19
+ new @(FormSubmitter.default(pollingUrl), FormValidator.default())
20
+
21
+ validateForm: (form)->
22
+ @formValidator.validateForm(form)
23
+
24
+ submitForm: (form)->
25
+ errors = @validateForm(form)
26
+
27
+ if (errors.length > 0)
28
+ @validatedWithErrors.dispatch(errors)
29
+ else
30
+ @formSubmitter.submitForm(form)
31
+
32
+ return FormManager
@@ -0,0 +1,29 @@
1
+ MultiSignalRelay = require "cronus/multi_signal_relay"
2
+
3
+ SimpleSubmitter = require "hoarder/submitter/submitters/simple_submitter"
4
+ PollingSubmitter = require "hoarder/submitter/submitters/polling_submitter"
5
+
6
+ #
7
+ # @author - Tim Shelburne <tim@musiconelive.com>
8
+ #
9
+ # a class to handle submitting forms
10
+ #
11
+ class FormSubmitter
12
+ constructor: (@submitters)->
13
+ successSignals = []
14
+ errorSignals = []
15
+ for submitter in @submitters
16
+ successSignals.push submitter.submittedWithSuccess
17
+ errorSignals.push submitter.submittedWithError
18
+
19
+ @submittedWithSuccess = new MultiSignalRelay(successSignals)
20
+ @submittedWithError = new MultiSignalRelay(errorSignals)
21
+
22
+ @default: (pollingUrl)->
23
+ new @([ new SimpleSubmitter(), new PollingSubmitter(pollingUrl, 1000)])
24
+
25
+ submitForm: (form)->
26
+ for submitter in @submitters
27
+ submitter.submitForm(form) if submitter.canSubmit(form)
28
+
29
+ return FormSubmitter
@@ -0,0 +1,36 @@
1
+ SimpleSubmitter = require "hoarder/submitter/submitters/simple_submitter"
2
+
3
+ #
4
+ # @author - Tim Shelburne <tim@musiconelive.com>
5
+ #
6
+ # handles executing a delayed
7
+ #
8
+ class PollingSubmitter extends SimpleSubmitter
9
+ constructor: (@pollUrl, @pollFrequency)->
10
+ super()
11
+
12
+ canSubmit: (form)-> form.type is "polling"
13
+
14
+ submitSuccess: (form, data)->
15
+ @interval = setInterval( =>
16
+ @queryPoll(form, data.pollId)
17
+ , @pollFrequency)
18
+ @queryPoll(form, data.pollId)
19
+
20
+ queryPoll: (form, pollId)=>
21
+ unless @executing
22
+ @executing = true
23
+ $.ajax
24
+ url: @pollUrl
25
+ type: "POST"
26
+ data: "pollId=#{pollId}"
27
+ success: (data)=> @pollSuccess(form, pollId, data)
28
+ error: (xhr, text)=> @submitError(form, xhr, text)
29
+
30
+ pollSuccess: (form, pollId, data)=>
31
+ @executing = false
32
+ if data.pollCompleted
33
+ clearInterval(@interval)
34
+ @submittedWithSuccess.dispatch(form, data.pollData)
35
+
36
+ return PollingSubmitter
@@ -0,0 +1,30 @@
1
+ require "lib/jquery"
2
+
3
+ Signal = require "cronus/signal"
4
+
5
+ #
6
+ # @author - Tim Shelburne <tim@musiconelive.com>
7
+ #
8
+ # handles submitting a form and waiting for a response
9
+ #
10
+ class SimpleSubmitter
11
+ constructor: ->
12
+ @submittedWithSuccess = new Signal()
13
+ @submittedWithError = new Signal()
14
+
15
+ canSubmit: (form)-> form.type is "simple"
16
+
17
+ submitForm: (form)->
18
+ $.ajax
19
+ url: form.action
20
+ type: form.method
21
+ data: form.serialize()
22
+ success: (data)=>
23
+ @submitSuccess(form, data)
24
+ error: (xhr, text)=> @submitError(form, xhr, text)
25
+
26
+ submitSuccess: (form, data)-> @submittedWithSuccess.dispatch(form, data)
27
+
28
+ submitError: (form, xhr, text)-> @submittedWithError.dispatch(form, text)
29
+
30
+ return SimpleSubmitter
@@ -0,0 +1,18 @@
1
+ ValidationError = require "hoarder/validator/error/validation_error"
2
+
3
+ #
4
+ # @author - Tim Shelburne <tim@musiconelive.com>
5
+ #
6
+ #
7
+ #
8
+ class AlphaConstraint
9
+ canHandle: (type)->
10
+ type is "alpha"
11
+
12
+ handle: (element)->
13
+ # if element.value.match(/^[A-Za-z0-9\s]*$/)
14
+ # return []
15
+ # else
16
+ # return [ new ValidationError "This field only accepts numbers and characters (0-9, A-Z, a-z)." ]
17
+
18
+ return AlphaConstraint