hoarder-js 0.0.1 → 0.0.2
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/CHANGELOG +2 -0
- data/Gemfile.lock +2 -2
- data/Manifest +14 -3
- data/assets/scripts/coffee/hoarder/form/form.coffee +47 -44
- data/assets/scripts/coffee/hoarder/form/form_serializer.coffee +23 -0
- data/assets/scripts/coffee/hoarder/form_manager.coffee +35 -19
- data/assets/scripts/coffee/hoarder/submitter/form_submitter.coffee +10 -15
- data/assets/scripts/coffee/hoarder/submitter/submitters/base_submitter.coffee +11 -0
- data/assets/scripts/coffee/hoarder/submitter/submitters/polling_submitter.coffee +30 -27
- data/assets/scripts/coffee/hoarder/submitter/submitters/simple_submitter.coffee +11 -21
- data/assets/scripts/coffee/hoarder/validator/constraints/alpha_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/alphanumeric_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/base_constraint.coffee +10 -0
- data/assets/scripts/coffee/hoarder/validator/constraints/credit_card_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/email_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/max_length_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/min_length_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/numeric_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/phone_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/constraints/required_constraint.coffee +8 -14
- data/assets/scripts/coffee/hoarder/validator/form_validator.coffee +30 -25
- data/assets/scripts/coffee/hoarder/validator/rules/validation_rule.coffee +10 -0
- data/assets/scripts/js/lib/bonzo.js +1151 -0
- data/assets/scripts/js/lib/qwery.js +369 -0
- data/assets/scripts/js/lib/reqwest.js +565 -0
- data/assets/scripts/js/patches/event_listeners.js +73 -0
- data/bin/hoarder.js +2807 -369
- data/hoarder-js.gemspec +3 -3
- data/spec/jasmine.yml +3 -0
- data/spec/runner.html +44 -34
- data/spec/support/fixtures.coffee +19 -0
- data/spec/support/lib/jasmine-fixture.js +506 -0
- data/spec/support/lib/jquery-1.7.1.min.js +4 -0
- data/spec/support/mocks.coffee +12 -37
- data/spec/support/requirements.coffee +0 -1
- data/spec/tests/form/form_serializer_spec.coffee +78 -0
- data/spec/tests/form/form_spec.coffee +127 -0
- data/spec/tests/form_manager_spec.coffee +128 -40
- data/spec/tests/submitter/form_submitter_spec.coffee +59 -42
- data/spec/tests/submitter/submitters/polling_submitter_spec.coffee +102 -57
- data/spec/tests/submitter/submitters/simple_submitter_spec.coffee +42 -16
- data/spec/tests/validator/constraints_spec.coffee +65 -57
- data/spec/tests/validator/form_validator_spec.coffee +39 -23
- data/spec/tests/validator/validation_rule_spec.coffee +14 -0
- metadata +16 -5
- data/assets/scripts/coffee/hoarder/form/form_element.coffee +0 -22
- data/assets/scripts/coffee/hoarder/validator/error/validation_error.coffee +0 -9
- data/assets/scripts/js/lib/jquery.js +0 -5
data/CHANGELOG
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
GIT
|
2
2
|
remote: git://github.com/jpeace/keystone.git
|
3
|
-
revision:
|
3
|
+
revision: 54627ade405d8b3307e349f36bab6e87b75fae84
|
4
4
|
specs:
|
5
5
|
keystone (0.0.1)
|
6
6
|
closure-compiler
|
@@ -85,7 +85,7 @@ GEM
|
|
85
85
|
multi_json (~> 1.0)
|
86
86
|
rack (~> 1.0)
|
87
87
|
tilt (~> 1.1, != 1.3.0)
|
88
|
-
tilt (1.
|
88
|
+
tilt (1.4.0)
|
89
89
|
websocket (1.0.7)
|
90
90
|
|
91
91
|
PLATFORMS
|
data/Manifest
CHANGED
@@ -6,13 +6,15 @@ Manifest
|
|
6
6
|
README.rdoc
|
7
7
|
Rakefile
|
8
8
|
assets/scripts/coffee/hoarder/form/form.coffee
|
9
|
-
assets/scripts/coffee/hoarder/form/
|
9
|
+
assets/scripts/coffee/hoarder/form/form_serializer.coffee
|
10
10
|
assets/scripts/coffee/hoarder/form_manager.coffee
|
11
11
|
assets/scripts/coffee/hoarder/submitter/form_submitter.coffee
|
12
|
+
assets/scripts/coffee/hoarder/submitter/submitters/base_submitter.coffee
|
12
13
|
assets/scripts/coffee/hoarder/submitter/submitters/polling_submitter.coffee
|
13
14
|
assets/scripts/coffee/hoarder/submitter/submitters/simple_submitter.coffee
|
14
15
|
assets/scripts/coffee/hoarder/validator/constraints/alpha_constraint.coffee
|
15
16
|
assets/scripts/coffee/hoarder/validator/constraints/alphanumeric_constraint.coffee
|
17
|
+
assets/scripts/coffee/hoarder/validator/constraints/base_constraint.coffee
|
16
18
|
assets/scripts/coffee/hoarder/validator/constraints/credit_card_constraint.coffee
|
17
19
|
assets/scripts/coffee/hoarder/validator/constraints/email_constraint.coffee
|
18
20
|
assets/scripts/coffee/hoarder/validator/constraints/max_length_constraint.coffee
|
@@ -20,9 +22,12 @@ assets/scripts/coffee/hoarder/validator/constraints/min_length_constraint.coffee
|
|
20
22
|
assets/scripts/coffee/hoarder/validator/constraints/numeric_constraint.coffee
|
21
23
|
assets/scripts/coffee/hoarder/validator/constraints/phone_constraint.coffee
|
22
24
|
assets/scripts/coffee/hoarder/validator/constraints/required_constraint.coffee
|
23
|
-
assets/scripts/coffee/hoarder/validator/error/validation_error.coffee
|
24
25
|
assets/scripts/coffee/hoarder/validator/form_validator.coffee
|
25
|
-
assets/scripts/
|
26
|
+
assets/scripts/coffee/hoarder/validator/rules/validation_rule.coffee
|
27
|
+
assets/scripts/js/lib/bonzo.js
|
28
|
+
assets/scripts/js/lib/qwery.js
|
29
|
+
assets/scripts/js/lib/reqwest.js
|
30
|
+
assets/scripts/js/patches/event_listeners.js
|
26
31
|
bin/hoarder.js
|
27
32
|
config/assets.rb
|
28
33
|
lib/hoarder.rb
|
@@ -30,13 +35,19 @@ lib/hoarder/symbols.rb
|
|
30
35
|
spec/jasmine.yml
|
31
36
|
spec/runner.html
|
32
37
|
spec/support/classes.coffee
|
38
|
+
spec/support/fixtures.coffee
|
33
39
|
spec/support/helpers.coffee
|
40
|
+
spec/support/lib/jasmine-fixture.js
|
41
|
+
spec/support/lib/jquery-1.7.1.min.js
|
34
42
|
spec/support/mocks.coffee
|
35
43
|
spec/support/objects.coffee
|
36
44
|
spec/support/requirements.coffee
|
45
|
+
spec/tests/form/form_serializer_spec.coffee
|
46
|
+
spec/tests/form/form_spec.coffee
|
37
47
|
spec/tests/form_manager_spec.coffee
|
38
48
|
spec/tests/submitter/form_submitter_spec.coffee
|
39
49
|
spec/tests/submitter/submitters/polling_submitter_spec.coffee
|
40
50
|
spec/tests/submitter/submitters/simple_submitter_spec.coffee
|
41
51
|
spec/tests/validator/constraints_spec.coffee
|
42
52
|
spec/tests/validator/form_validator_spec.coffee
|
53
|
+
spec/tests/validator/validation_rule_spec.coffee
|
@@ -1,48 +1,51 @@
|
|
1
|
-
require
|
1
|
+
FormSerializer = require 'hoarder/form/form_serializer'
|
2
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
3
|
class Form
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
4
|
+
|
5
|
+
constructor: (@formElement)->
|
6
|
+
@addedElements = [ ]
|
7
|
+
|
8
|
+
elements: -> (@formElement[index] for index in [0..@formElement.length] when @formElement[index]?.nodeName in [ 'INPUT', 'SELECT', 'TEXTAREA' ])
|
9
|
+
|
10
|
+
action: -> @formElement.action
|
11
|
+
|
12
|
+
method: -> @formElement.method
|
13
|
+
|
14
|
+
addElement: (name, value)->
|
15
|
+
throw new Error "'#{name}' already exists as an element on the form." if @hasElement name
|
16
|
+
element = createElement name, value
|
17
|
+
@formElement.appendChild element
|
18
|
+
@addedElements.push element
|
19
|
+
element
|
20
|
+
|
21
|
+
addElements: (elements)->
|
22
|
+
errors = [ ]
|
23
|
+
for element in elements
|
24
|
+
try @addElement(element.name, element.value)
|
25
|
+
catch e
|
26
|
+
errors.push e
|
27
|
+
throw errors[0] if errors.length
|
28
|
+
|
29
|
+
hasElement: (name)-> @getElement(name)?
|
30
|
+
|
31
|
+
getElement: (name)-> @formElement[name] if @formElement[name] instanceof HTMLElement
|
32
|
+
|
33
|
+
updateAddedElement: (name, value)-> if @formElement[name]? then @formElement[name].value = value else @addElement name, value
|
34
|
+
|
35
|
+
clearAddedElements: ->
|
36
|
+
@formElement.removeChild element for element in @addedElements
|
37
|
+
@addedElements = []
|
38
|
+
|
39
|
+
serialize: -> FormSerializer.toString @
|
40
|
+
|
41
|
+
|
42
|
+
# private
|
43
|
+
|
44
|
+
createElement = (name, value)->
|
45
|
+
element = document.createElement("input")
|
46
|
+
element.type = "hidden"
|
47
|
+
element.name = name
|
48
|
+
element.value = value
|
49
|
+
element
|
47
50
|
|
48
51
|
return Form
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Serializer
|
2
|
+
|
3
|
+
@toString: (form)-> removeNulls((serializeElement element for element in form.elements())).join("&")
|
4
|
+
|
5
|
+
# private
|
6
|
+
|
7
|
+
serializeElement = (element)->
|
8
|
+
return "#{element.name}=#{encodeURIComponent element.value}" unless isComplicated element
|
9
|
+
return "#{element.name}=#{encodeURIComponent element.value}" if isCheckable(element) and element.checked
|
10
|
+
return ("#{element.name}=#{encodeURIComponent option.value}" for option in element.options when option.selected).join("&") if isMultiSelect(element)
|
11
|
+
null
|
12
|
+
|
13
|
+
isComplicated = (element)-> isCheckable(element) or isMultiSelect(element) or isFile(element)
|
14
|
+
|
15
|
+
isCheckable = (element)-> element.nodeName is "INPUT" and element.type in [ "checkbox", "radio" ]
|
16
|
+
|
17
|
+
isMultiSelect = (element)-> element.nodeName is "SELECT" and element.type is "select-multiple"
|
18
|
+
|
19
|
+
isFile = (element)-> element.nodeName is "INPUT" and element.type is "file"
|
20
|
+
|
21
|
+
removeNulls = (array)-> array.filter((e)-> return e)
|
22
|
+
|
23
|
+
return Serializer
|
@@ -1,32 +1,48 @@
|
|
1
|
+
require 'patches/event_listeners'
|
2
|
+
|
1
3
|
Signal = require "cronus/signal"
|
2
4
|
SignalRelay = require "cronus/signal_relay"
|
3
5
|
|
6
|
+
Form = require 'hoarder/form/form'
|
4
7
|
FormSubmitter = require 'hoarder/submitter/form_submitter'
|
5
8
|
FormValidator = require 'hoarder/validator/form_validator'
|
6
9
|
|
7
|
-
#
|
8
|
-
# @author - Tim Shelburne <tim@musiconelive.com>
|
9
|
-
#
|
10
|
-
# abstracts submitting and validating forms from the validator and submitter
|
11
|
-
#
|
12
10
|
class FormManager
|
13
|
-
constructor: (@formSubmitter, @formValidator)->
|
14
|
-
@validatedWithErrors = new Signal()
|
15
|
-
@submittedWithSuccess = new SignalRelay(@formSubmitter.submittedWithSuccess)
|
16
|
-
@submittedWithError = new SignalRelay(@formSubmitter.submittedWithError)
|
17
11
|
|
18
|
-
|
19
|
-
|
12
|
+
@create: (pollingUrl="", pollFrequency=1000)->
|
13
|
+
new @(FormSubmitter.create(pollingUrl, pollFrequency), FormValidator.create())
|
14
|
+
|
15
|
+
constructor: (@formSubmitter, @formValidator)->
|
16
|
+
@validatedWithErrors = new Signal()
|
17
|
+
@submittedWithSuccess = new SignalRelay(@formSubmitter.submittedWithSuccess)
|
18
|
+
@submittedWithError = new SignalRelay(@formSubmitter.submittedWithError)
|
19
|
+
@_forms = [ ]
|
20
|
+
@_listeners = { }
|
21
|
+
|
22
|
+
manage: (formId, type='simple')->
|
23
|
+
throw new Error "'#{formId}' is already a managed form." if getForm.call(@, formId)?
|
24
|
+
formElement = document.getElementById formId
|
25
|
+
form = new Form(formElement)
|
26
|
+
formElement.addEventListener 'submit', @_listeners[formId] = (event)=>
|
27
|
+
event.preventDefault()
|
28
|
+
submit.call @, form, type
|
29
|
+
@_forms.push form
|
30
|
+
form
|
20
31
|
|
21
|
-
|
22
|
-
|
32
|
+
release: (formId)->
|
33
|
+
form = getForm.call @, formId
|
34
|
+
form.formElement.removeEventListener 'submit', @_listeners[formId]
|
35
|
+
delete @_listeners[formId]
|
36
|
+
@_forms.splice @_forms.indexOf(form), 1
|
23
37
|
|
24
|
-
|
25
|
-
|
38
|
+
getForm = (formId)->
|
39
|
+
for form in @_forms
|
40
|
+
return form if form.formElement.id is formId
|
26
41
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
42
|
+
submit = (form, type)->
|
43
|
+
if @formValidator.validateForm form
|
44
|
+
@formSubmitter.submit form, type
|
45
|
+
else
|
46
|
+
@validatedWithErrors.dispatch form
|
31
47
|
|
32
48
|
return FormManager
|
@@ -3,27 +3,22 @@ MultiSignalRelay = require "cronus/multi_signal_relay"
|
|
3
3
|
SimpleSubmitter = require "hoarder/submitter/submitters/simple_submitter"
|
4
4
|
PollingSubmitter = require "hoarder/submitter/submitters/polling_submitter"
|
5
5
|
|
6
|
-
#
|
7
|
-
# @author - Tim Shelburne <tim@musiconelive.com>
|
8
|
-
#
|
9
|
-
# a class to handle submitting forms
|
10
|
-
#
|
11
6
|
class FormSubmitter
|
7
|
+
|
8
|
+
@create: (pollingUrl, pollFrequency=1000)->
|
9
|
+
new @([ new SimpleSubmitter(), new PollingSubmitter(pollingUrl, pollFrequency)])
|
10
|
+
|
12
11
|
constructor: (@submitters)->
|
13
|
-
successSignals =
|
14
|
-
errorSignals =
|
15
|
-
for submitter in @submitters
|
16
|
-
successSignals.push submitter.submittedWithSuccess
|
17
|
-
errorSignals.push submitter.submittedWithError
|
12
|
+
successSignals = (submitter.submittedWithSuccess for submitter in @submitters)
|
13
|
+
errorSignals = (submitter.submittedWithError for submitter in @submitters)
|
18
14
|
|
19
15
|
@submittedWithSuccess = new MultiSignalRelay(successSignals)
|
20
16
|
@submittedWithError = new MultiSignalRelay(errorSignals)
|
21
17
|
|
22
|
-
|
23
|
-
new @([ new SimpleSubmitter(), new PollingSubmitter(pollingUrl, 1000)])
|
24
|
-
|
25
|
-
submitForm: (form)->
|
18
|
+
submit: (form, type)->
|
26
19
|
for submitter in @submitters
|
27
|
-
|
20
|
+
if submitter.canSubmit(type)
|
21
|
+
submitter.submit form
|
22
|
+
break
|
28
23
|
|
29
24
|
return FormSubmitter
|
@@ -1,36 +1,39 @@
|
|
1
|
-
|
1
|
+
require 'lib/reqwest'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
class PollingSubmitter extends SimpleSubmitter
|
3
|
+
BaseSubmitter = require "hoarder/submitter/submitters/base_submitter"
|
4
|
+
|
5
|
+
class PollingSubmitter extends BaseSubmitter
|
6
|
+
|
9
7
|
constructor: (@pollUrl, @pollFrequency)->
|
10
8
|
super()
|
9
|
+
@type = 'polling'
|
11
10
|
|
12
|
-
|
11
|
+
submit: (form)->
|
12
|
+
reqwest(
|
13
|
+
url: form.action
|
14
|
+
type: form.method
|
15
|
+
data: form.serialize()
|
16
|
+
success: (data)=> @poll(form, data.processId)
|
17
|
+
error: (xhr, text)=> @submittedWithError.dispatch(form, text)
|
18
|
+
)
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
@
|
17
|
-
|
18
|
-
|
20
|
+
poll: (form, processId)=>
|
21
|
+
reqwest(
|
22
|
+
url: @pollUrl
|
23
|
+
type: "POST"
|
24
|
+
data: "processId=#{processId}"
|
25
|
+
success: (data)=> pollSuccess.call @, form, processId, data
|
26
|
+
error: (xhr, text)=> @submittedWithError.dispatch(form, text)
|
27
|
+
)
|
19
28
|
|
20
|
-
|
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
|
+
# private
|
29
30
|
|
30
|
-
pollSuccess
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
pollSuccess = (form, processId, data)->
|
32
|
+
if data.processCompleted
|
33
|
+
@submittedWithSuccess.dispatch(form, data.processData)
|
34
|
+
else
|
35
|
+
setTimeout( =>
|
36
|
+
@poll(form, data.processId)
|
37
|
+
, @pollFrequency)
|
35
38
|
|
36
39
|
return PollingSubmitter
|
@@ -1,30 +1,20 @@
|
|
1
|
-
require
|
1
|
+
require 'lib/reqwest'
|
2
2
|
|
3
|
-
|
3
|
+
BaseSubmitter = require 'hoarder/submitter/submitters/base_submitter'
|
4
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()
|
5
|
+
class SimpleSubmitter extends BaseSubmitter
|
14
6
|
|
15
|
-
|
7
|
+
constructor: ->
|
8
|
+
super()
|
9
|
+
@type = 'simple'
|
16
10
|
|
17
|
-
|
18
|
-
|
11
|
+
submit: (form)->
|
12
|
+
reqwest(
|
19
13
|
url: form.action
|
20
14
|
type: form.method
|
21
15
|
data: form.serialize()
|
22
|
-
success: (data)=>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
submitSuccess: (form, data)-> @submittedWithSuccess.dispatch(form, data)
|
27
|
-
|
28
|
-
submitError: (form, xhr, text)-> @submittedWithError.dispatch(form, text)
|
16
|
+
success: (data)=> @submittedWithSuccess.dispatch(form, data)
|
17
|
+
error: (xhr, text)=> @submittedWithError.dispatch(form, text)
|
18
|
+
)
|
29
19
|
|
30
20
|
return SimpleSubmitter
|
@@ -1,18 +1,12 @@
|
|
1
|
-
|
1
|
+
BaseConstraint = require 'hoarder/validator/constraints/base_constraint'
|
2
2
|
|
3
|
-
|
4
|
-
# @author - Tim Shelburne <tim@musiconelive.com>
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
class AlphaConstraint
|
9
|
-
canHandle: (type)->
|
10
|
-
type is "alpha"
|
3
|
+
class AlphaConstraint extends BaseConstraint
|
11
4
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
5
|
+
constructor: ->
|
6
|
+
@type = "alpha"
|
7
|
+
|
8
|
+
rulePasses: (element)-> element.value.match(/^[A-Za-z\s]*$/)
|
9
|
+
|
10
|
+
errorMessage: -> "This field only accepts numbers and characters (0-9, A-Z, a-z)."
|
17
11
|
|
18
12
|
return AlphaConstraint
|