unpoly-rails 0.57.0 → 0.60.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +393 -1
- data/Gemfile.lock +5 -2
- data/README.md +1 -1
- data/README_RAILS.md +1 -1
- data/Rakefile +10 -1
- data/design/es6.js +32 -0
- data/design/ie11.txt +9 -0
- data/design/measure_jquery/element_list.js +41 -0
- data/design/measure_jquery/up.on_vs_addEventListener.js +56 -0
- data/design/todo_jquery.txt +13 -0
- data/dist/unpoly-bootstrap3.js +8 -8
- data/dist/unpoly-bootstrap3.min.js +1 -1
- data/dist/unpoly.css +22 -20
- data/dist/unpoly.js +6990 -5336
- data/dist/unpoly.min.css +1 -1
- data/dist/unpoly.min.js +4 -4
- data/lib/assets/javascripts/unpoly-bootstrap3/viewport-ext.coffee +5 -0
- data/lib/assets/javascripts/unpoly.coffee +8 -6
- data/lib/assets/javascripts/unpoly/browser.coffee.erb +23 -118
- data/lib/assets/javascripts/unpoly/classes/body_shifter.coffee +36 -0
- data/lib/assets/javascripts/unpoly/classes/cache.coffee +4 -4
- data/lib/assets/javascripts/unpoly/classes/compile_pass.coffee +45 -39
- data/lib/assets/javascripts/unpoly/classes/config.coffee +9 -0
- data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +18 -27
- data/lib/assets/javascripts/unpoly/classes/divertible_chain.coffee +39 -0
- data/lib/assets/javascripts/unpoly/classes/event_listener.coffee +116 -0
- data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +8 -8
- data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +19 -19
- data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +54 -31
- data/lib/assets/javascripts/unpoly/classes/{focus_tracker.coffee → focus_follower.coffee} +2 -2
- data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +25 -25
- data/lib/assets/javascripts/unpoly/classes/html_parser.coffee +4 -11
- data/lib/assets/javascripts/unpoly/classes/motion_controller.coffee +157 -0
- data/lib/assets/javascripts/unpoly/classes/params.coffee.erb +525 -0
- data/lib/assets/javascripts/unpoly/classes/record.coffee +8 -2
- data/lib/assets/javascripts/unpoly/classes/rect.js +21 -0
- data/lib/assets/javascripts/unpoly/classes/request.coffee +41 -35
- data/lib/assets/javascripts/unpoly/classes/response.coffee +7 -3
- data/lib/assets/javascripts/unpoly/classes/reveal_motion.coffee +102 -0
- data/lib/assets/javascripts/unpoly/classes/scroll_motion.coffee +67 -0
- data/lib/assets/javascripts/unpoly/classes/selector.coffee +60 -0
- data/lib/assets/javascripts/unpoly/classes/tether.coffee +105 -0
- data/lib/assets/javascripts/unpoly/classes/url_set.coffee +12 -7
- data/lib/assets/javascripts/unpoly/element.coffee.erb +1126 -0
- data/lib/assets/javascripts/unpoly/event.coffee.erb +437 -0
- data/lib/assets/javascripts/unpoly/feedback.coffee +73 -94
- data/lib/assets/javascripts/unpoly/form.coffee.erb +188 -181
- data/lib/assets/javascripts/unpoly/{dom.coffee.erb → fragment.coffee.erb} +250 -283
- data/lib/assets/javascripts/unpoly/framework.coffee +67 -0
- data/lib/assets/javascripts/unpoly/history.coffee +29 -28
- data/lib/assets/javascripts/unpoly/legacy.coffee +60 -0
- data/lib/assets/javascripts/unpoly/link.coffee.erb +127 -119
- data/lib/assets/javascripts/unpoly/log.coffee +99 -19
- data/lib/assets/javascripts/unpoly/modal.coffee.erb +95 -118
- data/lib/assets/javascripts/unpoly/motion.coffee.erb +158 -138
- data/lib/assets/javascripts/unpoly/namespace.coffee.erb +0 -5
- data/lib/assets/javascripts/unpoly/popup.coffee.erb +119 -102
- data/lib/assets/javascripts/unpoly/protocol.coffee +11 -15
- data/lib/assets/javascripts/unpoly/proxy.coffee +62 -65
- data/lib/assets/javascripts/unpoly/radio.coffee +3 -5
- data/lib/assets/javascripts/unpoly/rails.coffee +8 -9
- data/lib/assets/javascripts/unpoly/syntax.coffee.erb +173 -125
- data/lib/assets/javascripts/unpoly/toast.coffee +25 -24
- data/lib/assets/javascripts/unpoly/tooltip.coffee +89 -79
- data/lib/assets/javascripts/unpoly/util.coffee.erb +579 -1074
- data/lib/assets/javascripts/unpoly/{layout.coffee.erb → viewport.coffee.erb} +334 -264
- data/lib/assets/stylesheets/unpoly/dom.sass +1 -1
- data/lib/assets/stylesheets/unpoly/layout.sass +2 -0
- data/lib/assets/stylesheets/unpoly/popup.sass +0 -1
- data/lib/assets/stylesheets/unpoly/tooltip.sass +17 -12
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -2
- data/spec_app/Gemfile +2 -1
- data/spec_app/Gemfile.lock +38 -27
- data/spec_app/app/assets/javascripts/integration_test.coffee +1 -0
- data/spec_app/app/assets/javascripts/jasmine_specs.coffee +1 -2
- data/spec_app/app/assets/stylesheets/integration_test.sass +14 -1
- data/spec_app/app/controllers/scroll_test_controller.rb +5 -0
- data/spec_app/app/views/css_test/modal.erb +6 -6
- data/spec_app/app/views/css_test/popup.erb +44 -18
- data/spec_app/app/views/css_test/tooltip.erb +23 -4
- data/spec_app/app/views/error_test/trigger.erb +1 -1
- data/spec_app/app/views/form_test/basics/new.erb +1 -3
- data/spec_app/app/views/pages/start.erb +9 -2
- data/spec_app/app/views/reveal_test/long1.erb +1 -1
- data/spec_app/app/views/reveal_test/long2.erb +1 -1
- data/spec_app/app/views/reveal_test/within_document_viewport.erb +24 -0
- data/spec_app/app/views/reveal_test/within_overflowing_div_viewport.erb +28 -0
- data/spec_app/app/views/scroll_test/long1.erb +30 -0
- data/spec_app/config/routes.rb +1 -0
- data/spec_app/spec/javascripts/helpers/agent_detector.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +1 -0
- data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +17 -5
- data/spec_app/spec/javascripts/helpers/enable_logging.js.coffee +1 -1
- data/spec_app/spec/javascripts/helpers/fixture.js.coffee +25 -0
- data/spec_app/spec/javascripts/helpers/jquery_no_conflict.js +1 -0
- data/spec_app/spec/javascripts/helpers/last_request.js.coffee +1 -0
- data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +1 -1
- data/spec_app/spec/javascripts/helpers/parse_form_data.js.coffee +2 -2
- data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +4 -1
- data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +2 -1
- data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +2 -2
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +18 -11
- data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/spec_util.coffee +47 -0
- data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_array.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +6 -2
- data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +6 -2
- data/spec_app/spec/javascripts/helpers/to_be_element.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/to_be_error.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_hidden.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_scrolled_to.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_visible.js.coffee +9 -0
- data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +1 -2
- data/spec_app/spec/javascripts/helpers/to_equal_node_list.coffee +7 -0
- data/spec_app/spec/javascripts/helpers/to_equal_via_is_equal.js.coffee +7 -0
- data/spec_app/spec/javascripts/helpers/to_have_class.js.coffee +10 -0
- data/spec_app/spec/javascripts/helpers/to_have_descendant.js.coffee +10 -0
- data/spec_app/spec/javascripts/helpers/to_have_length.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +7 -3
- data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +1 -0
- data/spec_app/spec/javascripts/helpers/to_have_text.js.coffee +9 -0
- data/spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee +0 -21
- data/spec_app/spec/javascripts/helpers/to_match_list.coffee +14 -0
- data/spec_app/spec/javascripts/helpers/to_match_selector.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_match_text.js.coffee +4 -1
- data/spec_app/spec/javascripts/helpers/to_match_url.coffee +1 -0
- data/spec_app/spec/javascripts/helpers/trigger.js.coffee +91 -7
- data/spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee +3 -0
- data/spec_app/spec/javascripts/up/browser_spec.js.coffee +23 -90
- data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +3 -0
- data/spec_app/spec/javascripts/up/classes/config_spec.coffee +24 -0
- data/spec_app/spec/javascripts/up/classes/divertible_chain_spec.coffee +45 -0
- data/spec_app/spec/javascripts/up/classes/focus_tracker_spec.coffee +5 -2
- data/spec_app/spec/javascripts/up/classes/params_spec.coffee +557 -0
- data/spec_app/spec/javascripts/up/classes/request_spec.coffee +7 -4
- data/spec_app/spec/javascripts/up/classes/scroll_motion_spec.js.coffee +51 -0
- data/spec_app/spec/javascripts/up/classes/store/memory_spec.js.coffee +3 -0
- data/spec_app/spec/javascripts/up/classes/store/session_spec.js.coffee +3 -2
- data/spec_app/spec/javascripts/up/element_spec.coffee +897 -0
- data/spec_app/spec/javascripts/up/event_spec.js.coffee +496 -0
- data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +69 -48
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +252 -194
- data/spec_app/spec/javascripts/up/{dom_spec.js.coffee → fragment_spec.js.coffee} +381 -388
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +21 -19
- data/spec_app/spec/javascripts/up/jquery_spec.js.coffee +4 -0
- data/spec_app/spec/javascripts/up/legacy_spec.js.coffee +27 -0
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +163 -160
- data/spec_app/spec/javascripts/up/log_spec.js.coffee +85 -12
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +141 -123
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +117 -113
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +60 -77
- data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +1 -0
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +85 -78
- data/spec_app/spec/javascripts/up/radio_spec.js.coffee +29 -22
- data/spec_app/spec/javascripts/up/rails_spec.js.coffee +14 -13
- data/spec_app/spec/javascripts/up/spec_spec.js.coffee +9 -0
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +96 -66
- data/spec_app/spec/javascripts/up/toast_spec.js.coffee +37 -0
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +31 -47
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +725 -562
- data/spec_app/spec/javascripts/up/{layout_spec.js.coffee → viewport_spec.js.coffee} +175 -149
- metadata +57 -19
- data/lib/assets/javascripts/unpoly-bootstrap3/layout-ext.coffee +0 -5
- data/lib/assets/javascripts/unpoly/bus.coffee.erb +0 -518
- data/lib/assets/javascripts/unpoly/classes/extract_step.coffee +0 -4
- data/lib/assets/javascripts/unpoly/classes/motion_tracker.coffee +0 -125
- data/lib/assets/javascripts/unpoly/params.coffee.erb +0 -522
- data/spec_app/spec/javascripts/helpers/append_fixture.js.coffee +0 -8
- data/spec_app/spec/javascripts/up/bus_spec.js.coffee +0 -210
- data/spec_app/spec/javascripts/up/namespace_spec.js.coffee +0 -9
- data/spec_app/spec/javascripts/up/params_spec.coffee +0 -768
- data/spec_app/vendor/asset-libs/jasmine-fixture-1.3.4/jasmine-fixture.js +0 -433
- data/spec_app/vendor/asset-libs/jasmine-jquery-2.1.1/.bower.json +0 -26
- data/spec_app/vendor/asset-libs/jasmine-jquery-2.1.1/jasmine-jquery.js +0 -838
@@ -4,16 +4,16 @@ Logging
|
|
4
4
|
|
5
5
|
Unpoly can print debugging information to the developer console, e.g.:
|
6
6
|
|
7
|
-
- Which [events](/up.
|
7
|
+
- Which [events](/up.event) are called
|
8
8
|
- When we're [making requests to the network](/up.proxy)
|
9
9
|
- Which [compilers](/up.syntax) are applied to which elements
|
10
10
|
|
11
11
|
You can activate logging by calling [`up.log.enable()`](/up.log.enable).
|
12
12
|
The output can be configured using the [`up.log.config`](/up.log.config) property.
|
13
13
|
|
14
|
-
@
|
14
|
+
@module up.log
|
15
15
|
###
|
16
|
-
up.log =
|
16
|
+
up.log = do ->
|
17
17
|
|
18
18
|
u = up.util
|
19
19
|
b = up.browser
|
@@ -28,7 +28,7 @@ up.log = (($) ->
|
|
28
28
|
Whether Unpoly will print debugging information to the developer console.
|
29
29
|
|
30
30
|
Debugging information includes which elements are being [compiled](/up.syntax)
|
31
|
-
and which [events](/up.
|
31
|
+
and which [events](/up.event) are being emitted.
|
32
32
|
Note that errors will always be printed, regardless of this setting.
|
33
33
|
@param {boolean} [options.collapse=false]
|
34
34
|
Whether debugging information is printed as a collapsed tree.
|
@@ -39,7 +39,7 @@ up.log = (($) ->
|
|
39
39
|
A string to prepend to Unpoly's logging messages so you can distinguish it from your own messages.
|
40
40
|
@stable
|
41
41
|
###
|
42
|
-
config =
|
42
|
+
config = new up.Config
|
43
43
|
prefix: '[UP] '
|
44
44
|
enabled: sessionStore.get('enabled')
|
45
45
|
collapse: false
|
@@ -50,29 +50,107 @@ up.log = (($) ->
|
|
50
50
|
prefix = (message) ->
|
51
51
|
"#{config.prefix}#{message}"
|
52
52
|
|
53
|
+
###**
|
54
|
+
A cross-browser way to interact with `console.log`, `console.error`, etc.
|
55
|
+
|
56
|
+
This function falls back to `console.log` if the output stream is not implemented.
|
57
|
+
It also prints substitution strings (e.g. `console.log("From %o to %o", "a", "b")`)
|
58
|
+
as a single string if the browser console does not support substitution strings.
|
59
|
+
|
60
|
+
\#\#\# Example
|
61
|
+
|
62
|
+
up.browser.puts('log', 'Hi world')
|
63
|
+
up.browser.puts('error', 'There was an error in %o', obj)
|
64
|
+
|
65
|
+
@function up.browser.puts
|
66
|
+
@internal
|
67
|
+
###
|
68
|
+
callConsole = (stream, args...) ->
|
69
|
+
console[stream](args...)
|
70
|
+
|
71
|
+
CONSOLE_PLACEHOLDERS = /\%[odisf]/g
|
72
|
+
|
73
|
+
stringifyArg = (arg) ->
|
74
|
+
maxLength = 200
|
75
|
+
closer = ''
|
76
|
+
|
77
|
+
if u.isString(arg)
|
78
|
+
string = arg.replace(/[\n\r\t ]+/g, ' ')
|
79
|
+
string = string.replace(/^[\n\r\t ]+/, '')
|
80
|
+
string = string.replace(/[\n\r\t ]$/, '')
|
81
|
+
string = "\"#{string}\""
|
82
|
+
closer = '"'
|
83
|
+
else if u.isUndefined(arg)
|
84
|
+
# JSON.stringify(undefined) is actually undefined
|
85
|
+
string = 'undefined'
|
86
|
+
else if u.isNumber(arg) || u.isFunction(arg)
|
87
|
+
string = arg.toString()
|
88
|
+
else if u.isArray(arg)
|
89
|
+
string = "[#{u.map(arg, stringifyArg).join(', ')}]"
|
90
|
+
closer = ']'
|
91
|
+
else if u.isJQuery(arg)
|
92
|
+
string = "$(#{u.map(arg, stringifyArg).join(', ')})"
|
93
|
+
closer = ')'
|
94
|
+
else if u.isElement(arg)
|
95
|
+
string = "<#{arg.tagName.toLowerCase()}"
|
96
|
+
for attr in ['id', 'name', 'class']
|
97
|
+
if value = arg.getAttribute(attr)
|
98
|
+
string += " #{attr}=\"#{value}\""
|
99
|
+
string += ">"
|
100
|
+
closer = '>'
|
101
|
+
else # object
|
102
|
+
string = JSON.stringify(arg)
|
103
|
+
if string.length > maxLength
|
104
|
+
string = "#{string.substr(0, maxLength)} …"
|
105
|
+
string += closer
|
106
|
+
string
|
107
|
+
|
108
|
+
###**
|
109
|
+
See https://developer.mozilla.org/en-US/docs/Web/API/Console#Using_string_substitutions
|
110
|
+
|
111
|
+
@function up.browser.sprintf
|
112
|
+
@internal
|
113
|
+
###
|
114
|
+
sprintf = (message, args...) ->
|
115
|
+
sprintfWithFormattedArgs(u.identity, message, args...)
|
116
|
+
|
117
|
+
###**
|
118
|
+
@function up.browser.sprintfWithFormattedArgs
|
119
|
+
@internal
|
120
|
+
###
|
121
|
+
sprintfWithFormattedArgs = (formatter, message, args...) ->
|
122
|
+
return '' if u.isBlank(message)
|
123
|
+
|
124
|
+
i = 0
|
125
|
+
message.replace CONSOLE_PLACEHOLDERS, ->
|
126
|
+
arg = args[i]
|
127
|
+
arg = formatter(stringifyArg(arg))
|
128
|
+
i += 1
|
129
|
+
arg
|
130
|
+
|
53
131
|
###**
|
54
132
|
Prints a debugging message to the browser console.
|
55
133
|
|
56
134
|
@function up.log.debug
|
57
135
|
@param {string} message
|
58
|
-
@param {Array} args
|
136
|
+
@param {Array} ...args
|
59
137
|
@internal
|
60
138
|
###
|
61
139
|
debug = (message, args...) ->
|
62
140
|
if config.enabled && message
|
63
|
-
|
141
|
+
console.debug(prefix(message), args...)
|
64
142
|
|
65
143
|
###**
|
66
144
|
Prints a logging message to the browser console.
|
67
145
|
|
68
146
|
@function up.puts
|
69
147
|
@param {string} message
|
70
|
-
@param {Array} args
|
148
|
+
@param {Array} ...args
|
71
149
|
@internal
|
72
150
|
###
|
73
151
|
puts = (message, args...) ->
|
74
152
|
if config.enabled && message
|
75
|
-
|
153
|
+
console.log(prefix(message), args...)
|
76
154
|
|
77
155
|
###**
|
78
156
|
@function up.warn
|
@@ -80,7 +158,7 @@ up.log = (($) ->
|
|
80
158
|
###
|
81
159
|
warn = (message, args...) ->
|
82
160
|
if message
|
83
|
-
|
161
|
+
console.warn(prefix(message), args...)
|
84
162
|
|
85
163
|
###**
|
86
164
|
- Makes sure the group always closes
|
@@ -92,12 +170,12 @@ up.log = (($) ->
|
|
92
170
|
group = (message, args...) ->
|
93
171
|
block = args.pop() # Coffeescript copies the arguments array
|
94
172
|
if config.enabled && message
|
95
|
-
|
96
|
-
|
173
|
+
fn = if config.collapse then 'groupCollapsed' else 'group'
|
174
|
+
console[fn](prefix(message), args...)
|
97
175
|
try
|
98
176
|
block()
|
99
177
|
finally
|
100
|
-
|
178
|
+
console.groupEnd() if message
|
101
179
|
else
|
102
180
|
block()
|
103
181
|
|
@@ -107,7 +185,7 @@ up.log = (($) ->
|
|
107
185
|
###
|
108
186
|
error = (message, args...) ->
|
109
187
|
if message
|
110
|
-
|
188
|
+
console.error(prefix(message), args...)
|
111
189
|
|
112
190
|
printBanner = ->
|
113
191
|
# The ASCII art looks broken in code since we need to escape backslashes
|
@@ -120,9 +198,9 @@ up.log = (($) ->
|
|
120
198
|
banner += "Call `up.log.disable()` to disable logging for this session."
|
121
199
|
else
|
122
200
|
banner += "Call `up.log.enable()` to enable logging for this session."
|
123
|
-
|
201
|
+
console.log(banner)
|
124
202
|
|
125
|
-
up.on 'up:framework:
|
203
|
+
up.on 'up:framework:booted', printBanner
|
126
204
|
up.on 'up:framework:reset', reset
|
127
205
|
|
128
206
|
setEnabled = (value) ->
|
@@ -133,7 +211,7 @@ up.log = (($) ->
|
|
133
211
|
Makes future Unpoly events print vast amounts of debugging information to the developer console.
|
134
212
|
|
135
213
|
Debugging information includes which elements are being [compiled](/up.syntax)
|
136
|
-
and which [events](/up.
|
214
|
+
and which [events](/up.event) are being emitted.
|
137
215
|
|
138
216
|
@function up.log.enable
|
139
217
|
@stable
|
@@ -152,6 +230,9 @@ up.log = (($) ->
|
|
152
230
|
disable = ->
|
153
231
|
setEnabled(false)
|
154
232
|
|
233
|
+
puts: puts
|
234
|
+
sprintf: sprintf
|
235
|
+
sprintfWithFormattedArgs: sprintfWithFormattedArgs
|
155
236
|
puts: puts
|
156
237
|
debug: debug
|
157
238
|
error: error
|
@@ -160,8 +241,7 @@ up.log = (($) ->
|
|
160
241
|
config: config
|
161
242
|
enable: enable
|
162
243
|
disable: disable
|
163
|
-
|
164
|
-
)(jQuery)
|
244
|
+
isEnabled: -> config.enabled
|
165
245
|
|
166
246
|
up.puts = up.log.puts
|
167
247
|
up.warn = up.log.warn
|
@@ -5,7 +5,7 @@ Modal dialogs
|
|
5
5
|
Instead of [linking to a page fragment](/up.link), you can choose to show a fragment
|
6
6
|
in a modal dialog. The existing page will remain open in the background.
|
7
7
|
|
8
|
-
To open a modal, add an [`up-modal`](/a-up-modal) attribute to a link:
|
8
|
+
To open a modal, add an [`[up-modal]`](/a-up-modal) attribute to a link:
|
9
9
|
|
10
10
|
<a href="/blogs" up-modal=".blog-list">Switch blog</a>
|
11
11
|
|
@@ -54,11 +54,12 @@ You can change this structure by setting [`up.modal.config.template`](/up.modal.
|
|
54
54
|
or function.
|
55
55
|
|
56
56
|
|
57
|
-
@
|
57
|
+
@module up.modal
|
58
58
|
###
|
59
|
-
up.modal =
|
59
|
+
up.modal = do ->
|
60
60
|
|
61
61
|
u = up.util
|
62
|
+
e = up.element
|
62
63
|
|
63
64
|
###**
|
64
65
|
Sets default options for future modals.
|
@@ -81,7 +82,7 @@ up.modal = (($) ->
|
|
81
82
|
@param {number} [config.height='auto']
|
82
83
|
The height of the dialog in pixels.
|
83
84
|
Defaults to `undefined`, meaning that the dialog will grow to fit its contents.
|
84
|
-
@param {string|Function(config)} [config.template]
|
85
|
+
@param {string|Function(config): string} [config.template]
|
85
86
|
A string containing the HTML structure of the modal.
|
86
87
|
You can supply an alternative template string, but make sure that it
|
87
88
|
defines tag with the classes `up-modal`, `up-modal-dialog` and `up-modal-content`.
|
@@ -120,7 +121,7 @@ up.modal = (($) ->
|
|
120
121
|
The default [flavor](/up.modal.flavors).
|
121
122
|
@stable
|
122
123
|
###
|
123
|
-
config =
|
124
|
+
config = new up.Config
|
124
125
|
maxWidth: null
|
125
126
|
width: null
|
126
127
|
height: null
|
@@ -189,7 +190,7 @@ up.modal = (($) ->
|
|
189
190
|
the values are the respective default configurations.
|
190
191
|
@experimental
|
191
192
|
###
|
192
|
-
flavors =
|
193
|
+
flavors = new up.Config
|
193
194
|
default: {}
|
194
195
|
|
195
196
|
###**
|
@@ -210,10 +211,10 @@ up.modal = (($) ->
|
|
210
211
|
@experimental
|
211
212
|
###
|
212
213
|
|
213
|
-
state =
|
214
|
+
state = new up.Config
|
214
215
|
phase: 'closed' # can be 'opening', 'opened', 'closing' and 'closed'
|
215
|
-
|
216
|
-
|
216
|
+
anchorElement: null # the element to which the tooltip is anchored
|
217
|
+
modalElement: null # the modal container
|
217
218
|
sticky: null
|
218
219
|
closable: null
|
219
220
|
flavor: null
|
@@ -221,13 +222,14 @@ up.modal = (($) ->
|
|
221
222
|
coveredUrl: null
|
222
223
|
coveredTitle: null
|
223
224
|
position: null
|
224
|
-
unshifters: []
|
225
225
|
|
226
|
-
|
226
|
+
bodyShifter = new up.BodyShifter()
|
227
|
+
|
228
|
+
chain = new up.DivertibleChain()
|
227
229
|
|
228
230
|
reset = ->
|
229
|
-
|
230
|
-
|
231
|
+
e.remove(state.modalElement) if state.modalElement
|
232
|
+
bodyShifter.unshift()
|
231
233
|
state.reset()
|
232
234
|
chain.reset()
|
233
235
|
config.reset()
|
@@ -241,56 +243,32 @@ up.modal = (($) ->
|
|
241
243
|
state.coveredTitle = null
|
242
244
|
state.coveredUrl = null
|
243
245
|
|
246
|
+
part = (name) ->
|
247
|
+
selector = ".up-modal-#{name}"
|
248
|
+
state.modalElement.querySelector(selector)
|
249
|
+
|
244
250
|
createHiddenFrame = (target, options) ->
|
245
|
-
|
246
|
-
|
247
|
-
|
251
|
+
html = templateHtml()
|
252
|
+
state.modalElement = modalElement = e.createFromHtml(html)
|
253
|
+
modalElement.setAttribute('up-flavor', state.flavor)
|
254
|
+
modalElement.setAttribute('up-position', state.position) if u.isPresent(state.position)
|
248
255
|
|
249
|
-
$dialog = $modal.find('.up-modal-dialog')
|
250
256
|
dialogStyles = u.only(options, 'width', 'maxWidth', 'height')
|
251
|
-
|
257
|
+
e.setStyle(part('dialog'), dialogStyles)
|
252
258
|
|
253
|
-
|
254
|
-
|
259
|
+
unless state.closable
|
260
|
+
closeElement = part('close')
|
261
|
+
e.remove(closeElement)
|
262
|
+
|
263
|
+
contentElement = part('content')
|
255
264
|
# Create an empty element that will match the
|
256
265
|
# selector that is being replaced.
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
state.$modal = $modal
|
266
|
+
up.fragment.createPlaceholder(target, contentElement)
|
267
|
+
e.hide(modalElement)
|
268
|
+
document.body.appendChild(modalElement)
|
261
269
|
|
262
270
|
unveilFrame = ->
|
263
|
-
|
264
|
-
|
265
|
-
# Gives `<body>` a right padding in the width of a scrollbar.
|
266
|
-
# Also gives elements anchored to the right side of the screen
|
267
|
-
# an increased `right`.
|
268
|
-
#
|
269
|
-
# This is to prevent the body and elements from jumping when we add the
|
270
|
-
# modal overlay, which has its own scroll bar.
|
271
|
-
# This is screwed up, but Bootstrap does the same.
|
272
|
-
shiftElements = ->
|
273
|
-
if u.documentHasVerticalScrollbar()
|
274
|
-
$body = $('body')
|
275
|
-
scrollbarWidth = u.scrollbarWidth()
|
276
|
-
bodyRightPadding = u.readComputedStyleNumber($body, 'paddingRight')
|
277
|
-
bodyRightShift = scrollbarWidth + bodyRightPadding
|
278
|
-
unshiftBody = u.writeTemporaryStyle($body,
|
279
|
-
paddingRight: bodyRightShift
|
280
|
-
overflowY: 'hidden'
|
281
|
-
)
|
282
|
-
state.unshifters.push(unshiftBody)
|
283
|
-
up.layout.anchoredRight().each ->
|
284
|
-
$element = $(this)
|
285
|
-
elementRight = u.readComputedStyleNumber($element, 'right')
|
286
|
-
elementRightShift = scrollbarWidth + elementRight
|
287
|
-
unshifter = u.writeTemporaryStyle($element, right: elementRightShift)
|
288
|
-
state.unshifters.push(unshifter)
|
289
|
-
|
290
|
-
|
291
|
-
# Reverts the effects of `shiftElements`.
|
292
|
-
unshiftElements = ->
|
293
|
-
unshifter() while unshifter = state.unshifters.pop()
|
271
|
+
e.show(state.modalElement)
|
294
272
|
|
295
273
|
###**
|
296
274
|
Returns whether a modal is currently open.
|
@@ -307,8 +285,8 @@ up.modal = (($) ->
|
|
307
285
|
###**
|
308
286
|
Opens the given link's destination in a modal overlay:
|
309
287
|
|
310
|
-
var
|
311
|
-
up.modal.follow(
|
288
|
+
var link = document.querySelector('a')
|
289
|
+
up.modal.follow(link)
|
312
290
|
|
313
291
|
Any option attributes for [`a[up-modal]`](/a.up-modal) will be honored.
|
314
292
|
|
@@ -356,12 +334,12 @@ up.modal = (($) ->
|
|
356
334
|
###
|
357
335
|
followAsap = (linkOrSelector, options) ->
|
358
336
|
options = u.options(options)
|
359
|
-
options
|
337
|
+
options.link = e.get(linkOrSelector)
|
360
338
|
openAsap(options)
|
361
339
|
|
362
|
-
preloadNow = (
|
340
|
+
preloadNow = (link, options) ->
|
363
341
|
options = u.options(options)
|
364
|
-
options
|
342
|
+
options.link = link
|
365
343
|
options.preload = true
|
366
344
|
# Use openNow() and not openAsap() so (1) we don't close a currently open modal
|
367
345
|
# and (2) our pending AJAX request does not prevent other modals from opening
|
@@ -372,7 +350,7 @@ up.modal = (($) ->
|
|
372
350
|
|
373
351
|
\#\#\# Example
|
374
352
|
|
375
|
-
up.modal.visit('/foo', { target: '.list' })
|
353
|
+
up.modal.visit('/foo', { target: '.list' })
|
376
354
|
|
377
355
|
This will request `/foo`, extract the `.list` selector from the response
|
378
356
|
and open the selected container in a modal dialog.
|
@@ -404,7 +382,7 @@ up.modal = (($) ->
|
|
404
382
|
\#\#\# Example
|
405
383
|
|
406
384
|
var html = 'before <div class="content">inner</div> after';
|
407
|
-
up.modal.extract('.content', html)
|
385
|
+
up.modal.extract('.content', html)
|
408
386
|
|
409
387
|
The would open a modal with the following contents:
|
410
388
|
|
@@ -427,7 +405,7 @@ up.modal = (($) ->
|
|
427
405
|
extractAsap = (selector, html, options) ->
|
428
406
|
options = u.options(options)
|
429
407
|
options.html = html
|
430
|
-
options.history
|
408
|
+
options.history ?= false
|
431
409
|
options.target = selector
|
432
410
|
openAsap(options)
|
433
411
|
|
@@ -436,35 +414,35 @@ up.modal = (($) ->
|
|
436
414
|
|
437
415
|
openNow = (options) ->
|
438
416
|
options = u.options(options)
|
439
|
-
|
440
|
-
url = u.
|
441
|
-
html = u.
|
442
|
-
target = u.
|
417
|
+
link = u.pluckKey(options, 'link') || e.none()
|
418
|
+
url = u.pluckKey(options, 'url') ? link.getAttribute('up-href') ? link.getAttribute('href')
|
419
|
+
html = u.pluckKey(options, 'html')
|
420
|
+
target = u.pluckKey(options, 'target') ? link.getAttribute('up-modal')
|
443
421
|
validateTarget(target)
|
444
|
-
options.flavor
|
445
|
-
options.position
|
446
|
-
options.position = u.evalOption(options.position,
|
447
|
-
options.width
|
448
|
-
options.maxWidth
|
449
|
-
options.height
|
450
|
-
options.animation
|
422
|
+
options.flavor ?= link.getAttribute('up-flavor') ? config.flavor
|
423
|
+
options.position ?= link.getAttribute('up-position') ? flavorDefault('position', options.flavor)
|
424
|
+
options.position = u.evalOption(options.position, { link })
|
425
|
+
options.width ?= link.getAttribute('up-width') ? flavorDefault('width', options.flavor)
|
426
|
+
options.maxWidth ?= link.getAttribute('up-max-width') ? flavorDefault('maxWidth', options.flavor)
|
427
|
+
options.height ?= link.getAttribute('up-height') ? flavorDefault('height')
|
428
|
+
options.animation ?= link.getAttribute('up-animation') ? flavorDefault('openAnimation', options.flavor)
|
451
429
|
options.animation = u.evalOption(options.animation, position: options.position)
|
452
|
-
options.backdropAnimation
|
430
|
+
options.backdropAnimation ?= link.getAttribute('up-backdrop-animation') ? flavorDefault('backdropOpenAnimation', options.flavor)
|
453
431
|
options.backdropAnimation = u.evalOption(options.backdropAnimation, position: options.position)
|
454
|
-
options.sticky
|
455
|
-
options.closable
|
456
|
-
options.confirm
|
457
|
-
options.method = up.link.followMethod(
|
432
|
+
options.sticky ?= e.booleanAttr(link, 'up-sticky') ? flavorDefault('sticky', options.flavor)
|
433
|
+
options.closable ?= e.booleanAttr(link, 'up-closable') ? flavorDefault('closable', options.flavor)
|
434
|
+
options.confirm ?= link.getAttribute('up-confirm')
|
435
|
+
options.method = up.link.followMethod(link, options)
|
458
436
|
options.layer = 'modal'
|
459
|
-
options.failTarget
|
460
|
-
options.failLayer
|
437
|
+
options.failTarget ?= link.getAttribute('up-fail-target')
|
438
|
+
options.failLayer ?= link.getAttribute('up-fail-layer') ? 'auto'
|
461
439
|
|
462
|
-
animateOptions = up.motion.animateOptions(options,
|
440
|
+
animateOptions = up.motion.animateOptions(options, link, duration: flavorDefault('openDuration', options.flavor), easing: flavorDefault('openEasing', options.flavor))
|
463
441
|
|
464
442
|
# Although we usually fall back to full page loads if a browser doesn't support pushState,
|
465
443
|
# in the case of modals we assume that the developer would rather see a dialog
|
466
444
|
# without an URL update.
|
467
|
-
options.history
|
445
|
+
options.history ?= e.booleanOrStringAttr(link, 'up-history') ? flavorDefault('history', options.flavor)
|
468
446
|
options.history = false unless up.browser.canPushState()
|
469
447
|
|
470
448
|
# This will prevent up.replace() from looking for fallbacks, since
|
@@ -475,7 +453,7 @@ up.modal = (($) ->
|
|
475
453
|
return up.replace(target, url, options)
|
476
454
|
|
477
455
|
up.browser.whenConfirmed(options).then ->
|
478
|
-
up.
|
456
|
+
up.event.whenEmitted('up:modal:open', url: url, log: 'Opening modal').then ->
|
479
457
|
state.phase = 'opening'
|
480
458
|
state.flavor = options.flavor
|
481
459
|
state.sticky = options.sticky
|
@@ -490,12 +468,12 @@ up.modal = (($) ->
|
|
490
468
|
else
|
491
469
|
promise = up.replace(target, url, extractOptions)
|
492
470
|
promise = promise.then ->
|
493
|
-
|
471
|
+
bodyShifter.shift()
|
494
472
|
unveilFrame()
|
495
473
|
animate(options.animation, options.backdropAnimation, animateOptions)
|
496
474
|
promise = promise.then ->
|
497
475
|
state.phase = 'opened'
|
498
|
-
up.emit('up:modal:opened',
|
476
|
+
up.emit('up:modal:opened', log: 'Modal opened')
|
499
477
|
promise
|
500
478
|
|
501
479
|
validateTarget = (target) ->
|
@@ -544,9 +522,9 @@ up.modal = (($) ->
|
|
544
522
|
unless isOpen()
|
545
523
|
return Promise.resolve()
|
546
524
|
|
547
|
-
viewportCloseAnimation =
|
525
|
+
viewportCloseAnimation = options.animation ? flavorDefault('closeAnimation')
|
548
526
|
viewportCloseAnimation = u.evalOption(viewportCloseAnimation, position: state.position)
|
549
|
-
backdropCloseAnimation =
|
527
|
+
backdropCloseAnimation = options.backdropAnimation ? flavorDefault('backdropCloseAnimation')
|
550
528
|
backdropCloseAnimation = u.evalOption(backdropCloseAnimation, position: state.position)
|
551
529
|
animateOptions = up.motion.animateOptions(options, duration: flavorDefault('closeDuration'), easing: flavorDefault('closeEasing'))
|
552
530
|
|
@@ -556,7 +534,7 @@ up.modal = (($) ->
|
|
556
534
|
title: state.coveredTitle
|
557
535
|
)
|
558
536
|
|
559
|
-
up.
|
537
|
+
up.event.whenEmitted(state.modalElement, 'up:modal:close', log: 'Closing modal').then ->
|
560
538
|
state.phase = 'closing'
|
561
539
|
# the current URL must be deleted *before* calling up.destroy,
|
562
540
|
# since up.feedback listens to up:fragment:destroyed and then
|
@@ -568,22 +546,22 @@ up.modal = (($) ->
|
|
568
546
|
promise = animate(viewportCloseAnimation, backdropCloseAnimation, animateOptions)
|
569
547
|
|
570
548
|
promise = promise.then ->
|
571
|
-
up.destroy(state
|
549
|
+
up.destroy(state.modalElement, destroyOptions)
|
572
550
|
|
573
551
|
promise = promise.then ->
|
574
|
-
|
552
|
+
bodyShifter.unshift()
|
575
553
|
state.phase = 'closed'
|
576
|
-
state
|
554
|
+
state.modalElement = null
|
577
555
|
state.flavor = null
|
578
556
|
state.sticky = null
|
579
557
|
state.closable = null
|
580
558
|
state.position = null
|
581
|
-
up.emit('up:modal:closed',
|
559
|
+
up.emit('up:modal:closed', log: 'Modal closed')
|
582
560
|
|
583
561
|
promise
|
584
562
|
|
585
563
|
markAsAnimating = (isAnimating = true) ->
|
586
|
-
|
564
|
+
e.toggleClass(state.modalElement, 'up-modal-animating', isAnimating)
|
587
565
|
|
588
566
|
animate = (viewportAnimation, backdropAnimation, animateOptions) ->
|
589
567
|
# If we're not animating the dialog, don't animate the backdrop either
|
@@ -591,9 +569,10 @@ up.modal = (($) ->
|
|
591
569
|
Promise.resolve()
|
592
570
|
else
|
593
571
|
markAsAnimating()
|
572
|
+
|
594
573
|
promise = Promise.all([
|
595
|
-
up.animate(
|
596
|
-
up.animate(
|
574
|
+
up.animate(part('viewport'), viewportAnimation, animateOptions),
|
575
|
+
up.animate(part('backdrop'), backdropAnimation, animateOptions)
|
597
576
|
])
|
598
577
|
promise = promise.then -> markAsAnimating(false)
|
599
578
|
promise
|
@@ -632,11 +611,11 @@ up.modal = (($) ->
|
|
632
611
|
@stable
|
633
612
|
###
|
634
613
|
contains = (elementOrSelector) ->
|
635
|
-
|
636
|
-
|
614
|
+
element = e.get(elementOrSelector)
|
615
|
+
!!e.closest(element, '.up-modal')
|
637
616
|
|
638
617
|
flavor = (name, overrideConfig = {}) ->
|
639
|
-
up.warn
|
618
|
+
up.legacy.warn('up.modal.flavor() is deprecated. Use the up.modal.flavors property instead.')
|
640
619
|
u.assign(flavorOverrides(name), overrideConfig)
|
641
620
|
|
642
621
|
###**
|
@@ -711,8 +690,8 @@ up.modal = (($) ->
|
|
711
690
|
###
|
712
691
|
up.link.addFollowVariant '[up-modal]',
|
713
692
|
# Don't just pass the `follow` function reference so we can stub it in tests
|
714
|
-
follow: (
|
715
|
-
preload: (
|
693
|
+
follow: (link, options) -> followAsap(link, options)
|
694
|
+
preload: (link, options) -> preloadNow(link, options)
|
716
695
|
|
717
696
|
# Close the modal when someone clicks outside the dialog (but not on a modal opener).
|
718
697
|
# We register the event on .up-modal, which covers the *entire* viewport, not just
|
@@ -724,22 +703,22 @@ up.modal = (($) ->
|
|
724
703
|
up.on('click', '.up-modal', (event) ->
|
725
704
|
return unless state.closable
|
726
705
|
|
727
|
-
|
728
|
-
unless
|
729
|
-
up.
|
706
|
+
target = event.target
|
707
|
+
unless e.closest(target, '.up-modal-dialog') || e.closest(target, '[up-modal]')
|
708
|
+
up.event.consumeAction(event)
|
730
709
|
u.muteRejection closeAsap()
|
731
710
|
)
|
732
711
|
|
733
|
-
up.on('up:fragment:inserted', (event,
|
734
|
-
if contains(
|
735
|
-
if newSource =
|
712
|
+
up.on('up:fragment:inserted', (event, fragment) ->
|
713
|
+
if contains(fragment)
|
714
|
+
if newSource = fragment.getAttribute('up-source')
|
736
715
|
state.url = newSource
|
737
|
-
else if event.origin && contains(event.origin) && !up.popup.contains(
|
716
|
+
else if event.origin && contains(event.origin) && !up.popup.contains(fragment)
|
738
717
|
u.muteRejection autoclose()
|
739
718
|
)
|
740
719
|
|
741
720
|
# Close the pop-up overlay when the user presses ESC.
|
742
|
-
up.
|
721
|
+
up.event.onEscape ->
|
743
722
|
if state.closable
|
744
723
|
u.muteRejection closeAsap()
|
745
724
|
|
@@ -756,13 +735,13 @@ up.modal = (($) ->
|
|
756
735
|
@selector .up-modal [up-close]
|
757
736
|
@stable
|
758
737
|
###
|
759
|
-
up.on('click', '.up-modal [up-close]', (event
|
738
|
+
up.on('click', '.up-modal [up-close]', (event) ->
|
760
739
|
u.muteRejection closeAsap()
|
761
740
|
# If the user closes the modal by clicking on the background, we want to halt the event chain here.
|
762
741
|
# The event should not trigger anything else. The user needs to click again for another interaction.
|
763
742
|
# Also only prevent the default when we actually closed a modal.
|
764
743
|
# This way we can have buttons that close a modal when within a modal, but link to a destination if not.
|
765
|
-
up.
|
744
|
+
up.event.consumeAction(event)
|
766
745
|
)
|
767
746
|
|
768
747
|
###**
|
@@ -791,9 +770,9 @@ up.modal = (($) ->
|
|
791
770
|
Otherwise it will slide in from the right.
|
792
771
|
@stable
|
793
772
|
###
|
794
|
-
up.macro 'a[up-drawer], [up-href][up-drawer]', (
|
795
|
-
target =
|
796
|
-
|
773
|
+
up.macro 'a[up-drawer], [up-href][up-drawer]', (link) ->
|
774
|
+
target = link.getAttribute('up-drawer')
|
775
|
+
e.setAttrs link,
|
797
776
|
'up-modal': target
|
798
777
|
'up-flavor': 'drawer'
|
799
778
|
|
@@ -817,8 +796,8 @@ up.modal = (($) ->
|
|
817
796
|
when 'left' then 'move-to-left'
|
818
797
|
when 'right' then 'move-to-right'
|
819
798
|
position: (options) ->
|
820
|
-
if u.isPresent(options
|
821
|
-
u.horizontalScreenHalf(options
|
799
|
+
if u.isPresent(options.link)
|
800
|
+
u.horizontalScreenHalf(options.link)
|
822
801
|
else
|
823
802
|
# In case the drawer was opened programmatically through Javascript,
|
824
803
|
# we might now know the link that was clicked on.
|
@@ -844,5 +823,3 @@ up.modal = (($) ->
|
|
844
823
|
contains: contains
|
845
824
|
isOpen: isOpen
|
846
825
|
flavor: flavor # deprecated
|
847
|
-
|
848
|
-
)(jQuery)
|