mercury-rails 0.2.3 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/app/controllers/{images_controller.rb → mercury/images_controller.rb} +3 -3
  2. data/app/controllers/mercury_controller.rb +13 -3
  3. data/app/models/{image.rb → mercury/image.rb} +3 -1
  4. data/app/views/layouts/mercury.html.erb +14 -6
  5. data/app/views/mercury/lightviews/about.html +7 -3
  6. data/app/views/mercury/modals/character.html +2 -2
  7. data/app/views/mercury/modals/htmleditor.html +2 -2
  8. data/app/views/mercury/modals/link.html +3 -3
  9. data/app/views/mercury/modals/media.html +3 -3
  10. data/app/views/mercury/modals/table.html +3 -3
  11. data/app/views/mercury/panels/snippets.html +1 -1
  12. data/app/views/mercury/selects/formatblock.html +9 -9
  13. data/app/views/mercury/snippets/example/options.html.erb +27 -16
  14. data/config/engine.rb +35 -0
  15. data/db/migrate/{20110526035601_create_images.rb → 20110526035601_create_mercury_images.rb} +2 -2
  16. data/features/loading/loading.feature +1 -1
  17. data/features/loading/navigating.feature +1 -1
  18. data/features/loading/user_interface.feature +2 -2
  19. data/features/regions/editable/basic_editing.feature +8 -8
  20. data/features/regions/editable/inserting_snippets.feature +4 -5
  21. data/features/regions/editable/inserting_tables.feature +9 -9
  22. data/features/step_definitions/mercury_steps.rb +20 -23
  23. data/features/step_definitions/web_steps.rb +5 -5
  24. data/features/support/mercury_selectors.rb +1 -0
  25. data/lib/generators/mercury/install/install_generator.rb +24 -3
  26. data/lib/generators/mercury/install/templates/mongoid_paperclip_image.rb +17 -0
  27. data/lib/mercury-rails.rb +0 -1
  28. data/lib/mercury/authentication.rb +8 -0
  29. data/spec/javascripts/mercury/dialog_spec.js.coffee +28 -21
  30. data/spec/javascripts/mercury/dialogs/backcolor_spec.js.coffee +0 -2
  31. data/spec/javascripts/mercury/dialogs/forecolor_spec.js.coffee +0 -2
  32. data/spec/javascripts/mercury/dialogs/formatblock_spec.js.coffee +0 -2
  33. data/spec/javascripts/mercury/dialogs/snippetpanel_spec.js.coffee +0 -2
  34. data/spec/javascripts/mercury/dialogs/style_spec.js.coffee +0 -2
  35. data/spec/javascripts/mercury/history_buffer_spec.js.coffee +0 -2
  36. data/spec/javascripts/mercury/lightview_spec.js.coffee +42 -21
  37. data/spec/javascripts/mercury/mercury_spec.js.coffee +87 -7
  38. data/spec/javascripts/mercury/modal_spec.js.coffee +53 -23
  39. data/spec/javascripts/mercury/modals/htmleditor_spec.js.coffee +0 -2
  40. data/spec/javascripts/mercury/modals/insertcharacter_spec.js.coffee +2 -3
  41. data/spec/javascripts/mercury/modals/insertlink_spec.js.coffee +0 -2
  42. data/spec/javascripts/mercury/modals/insertmedia_spec.js.coffee +2 -2
  43. data/spec/javascripts/mercury/modals/insertsnippet_spec.js.coffee +0 -2
  44. data/spec/javascripts/mercury/modals/inserttable_spec.js.coffee +2 -4
  45. data/spec/javascripts/mercury/native_extensions_spec.js.coffee +20 -2
  46. data/spec/javascripts/mercury/page_editor_spec.js.coffee +130 -35
  47. data/spec/javascripts/mercury/palette_spec.js.coffee +4 -6
  48. data/spec/javascripts/mercury/panel_spec.js.coffee +44 -6
  49. data/spec/javascripts/mercury/region_spec.js.coffee +42 -8
  50. data/spec/javascripts/mercury/regions/editable_spec.js.coffee +0 -2
  51. data/spec/javascripts/mercury/regions/markupable_spec.js.coffee +0 -2
  52. data/spec/javascripts/mercury/regions/snippetable_spec.js.coffee +3 -5
  53. data/spec/javascripts/mercury/select_spec.js.coffee +4 -6
  54. data/spec/javascripts/mercury/snippet_spec.js.coffee +3 -4
  55. data/spec/javascripts/mercury/snippet_toolbar_spec.js.coffee +2 -4
  56. data/spec/javascripts/mercury/statusbar_spec.js.coffee +0 -2
  57. data/spec/javascripts/mercury/table_editor_spec.js.coffee +2 -4
  58. data/spec/javascripts/mercury/toolbar.button_group_spec.js.coffee +0 -2
  59. data/spec/javascripts/mercury/toolbar.button_spec.js.coffee +34 -15
  60. data/spec/javascripts/mercury/toolbar.expander_spec.js.coffee +0 -2
  61. data/spec/javascripts/mercury/toolbar_spec.js.coffee +41 -26
  62. data/spec/javascripts/mercury/tooltip_spec.js.coffee +3 -5
  63. data/spec/javascripts/mercury/uploader_spec.js.coffee +8 -14
  64. data/spec/javascripts/spec_helper.js +1 -0
  65. data/spec/javascripts/templates/mercury/page_editor.html +1 -0
  66. data/spec/javascripts/templates/mercury/region.html +2 -2
  67. data/vendor/assets/images/mercury/missing-image.png +0 -0
  68. data/vendor/assets/javascripts/mercury.js +218 -112
  69. data/vendor/assets/javascripts/mercury/dependencies/{jquery-1.6.js → jquery-1.7.js} +2030 -1595
  70. data/vendor/assets/javascripts/mercury/dependencies/jquery.additions.js +55 -0
  71. data/vendor/assets/javascripts/mercury/dialog.js.coffee +7 -5
  72. data/vendor/assets/javascripts/mercury/dialogs/backcolor.js.coffee +1 -1
  73. data/vendor/assets/javascripts/mercury/dialogs/forecolor.js.coffee +1 -1
  74. data/vendor/assets/javascripts/mercury/dialogs/formatblock.js.coffee +1 -1
  75. data/vendor/assets/javascripts/mercury/dialogs/{objectspanel.js.coffee → snippetpanel.js.coffee} +2 -2
  76. data/vendor/assets/javascripts/mercury/dialogs/style.js.coffee +1 -1
  77. data/vendor/assets/javascripts/mercury/finalize.js.coffee +3 -0
  78. data/vendor/assets/javascripts/mercury/lightview.js.coffee +76 -30
  79. data/vendor/assets/javascripts/mercury/locales/da.locale.js.coffee +211 -0
  80. data/vendor/assets/javascripts/mercury/locales/de.locale.js.coffee +206 -0
  81. data/vendor/assets/javascripts/mercury/locales/es.locale.js.coffee +211 -0
  82. data/vendor/assets/javascripts/mercury/locales/example.local.js.coffee +211 -0
  83. data/vendor/assets/javascripts/mercury/locales/fr.locale.js.coffee +211 -0
  84. data/vendor/assets/javascripts/mercury/locales/it.locale.js.coffee +208 -0
  85. data/vendor/assets/javascripts/mercury/locales/ko.local.js.coffee +206 -0
  86. data/vendor/assets/javascripts/mercury/locales/nl.locale.js.coffee +206 -0
  87. data/vendor/assets/javascripts/mercury/locales/pt.locale.js.coffee +211 -0
  88. data/vendor/assets/javascripts/mercury/locales/sv.local.js.coffee +209 -0
  89. data/vendor/assets/javascripts/mercury/locales/swedish_chef.locale.js.coffee +213 -0
  90. data/vendor/assets/javascripts/mercury/mercury.js.coffee +62 -17
  91. data/vendor/assets/javascripts/mercury/modal.js.coffee +34 -21
  92. data/vendor/assets/javascripts/mercury/modals/htmleditor.js.coffee +1 -2
  93. data/vendor/assets/javascripts/mercury/modals/insertcharacter.js.coffee +3 -3
  94. data/vendor/assets/javascripts/mercury/modals/insertlink.js.coffee +4 -4
  95. data/vendor/assets/javascripts/mercury/modals/insertmedia.js.coffee +10 -9
  96. data/vendor/assets/javascripts/mercury/modals/insertsnippet.js.coffee +1 -1
  97. data/vendor/assets/javascripts/mercury/modals/inserttable.js.coffee +8 -9
  98. data/vendor/assets/javascripts/mercury/native_extensions.js.coffee +26 -8
  99. data/vendor/assets/javascripts/mercury/page_editor.js.coffee +68 -46
  100. data/vendor/assets/javascripts/mercury/palette.js.coffee +1 -1
  101. data/vendor/assets/javascripts/mercury/panel.js.coffee +25 -7
  102. data/vendor/assets/javascripts/mercury/plugins/save_as_xml/mercury/page_editor.js.coffee +1 -0
  103. data/vendor/assets/javascripts/mercury/region.js.coffee +21 -17
  104. data/vendor/assets/javascripts/mercury/regions/editable.js.coffee +47 -35
  105. data/vendor/assets/javascripts/mercury/regions/markupable.js.coffee +43 -36
  106. data/vendor/assets/javascripts/mercury/regions/snippetable.js.coffee +22 -24
  107. data/vendor/assets/javascripts/mercury/select.js.coffee +3 -2
  108. data/vendor/assets/javascripts/mercury/snippet.js.coffee +2 -1
  109. data/vendor/assets/javascripts/mercury/snippet_toolbar.js.coffee +10 -7
  110. data/vendor/assets/javascripts/mercury/statusbar.js.coffee +4 -4
  111. data/vendor/assets/javascripts/mercury/table_editor.js.coffee +1 -3
  112. data/vendor/assets/javascripts/mercury/toolbar.button.js.coffee +42 -20
  113. data/vendor/assets/javascripts/mercury/toolbar.button_group.js.coffee +3 -3
  114. data/vendor/assets/javascripts/mercury/toolbar.expander.js.coffee +2 -2
  115. data/vendor/assets/javascripts/mercury/toolbar.js.coffee +8 -6
  116. data/vendor/assets/javascripts/mercury/tooltip.js.coffee +13 -9
  117. data/vendor/assets/javascripts/mercury/uploader.js.coffee +22 -16
  118. data/vendor/assets/javascripts/mercury_loader.js +2 -0
  119. data/vendor/assets/javascripts/mercury_overrides.js +6 -0
  120. data/vendor/assets/stylesheets/mercury/all_images.css.erb +89 -0
  121. data/vendor/assets/stylesheets/mercury/dialog.css +13 -4
  122. data/vendor/assets/stylesheets/mercury/lightview.css +66 -15
  123. data/vendor/assets/stylesheets/mercury/mercury.css +12 -7
  124. data/vendor/assets/stylesheets/mercury/modal.css +9 -5
  125. data/vendor/assets/stylesheets/mercury/toolbar.css +3 -29
  126. metadata +266 -144
  127. data/POST_INSTALL +0 -15
  128. data/README.md +0 -299
  129. data/VERSION +0 -1
  130. data/annotated_source.template +0 -57
  131. data/config/routes.rb +0 -15
  132. data/mercury-rails.gemspec +0 -288
  133. data/spec/javascripts/responses/blank.html +0 -1
  134. data/vendor/assets/javascripts/mercury/lightviews/imageprocessor.js.coffee +0 -2
@@ -1,7 +1,8 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury", ->
4
2
 
3
+ afterEach: ->
4
+ Mercury.config.localization.enabled = false
5
+
5
6
  describe "supported:", ->
6
7
 
7
8
  # this is here for documentation -- unable to test, because this is evaluated on script load
@@ -10,27 +11,60 @@ describe "Mercury", ->
10
11
  it "disallows konqueror and msie", ->
11
12
 
12
13
 
13
- describe "#bind", ->
14
+ describe ".on", ->
14
15
 
15
16
  it "binds an event prefixed with 'mercury:' to the top window", ->
16
17
  callCount = 0
17
- Mercury.bind('test', -> callCount += 1)
18
+ Mercury.on('test', -> callCount += 1)
18
19
  $(top).trigger("mercury:test")
19
20
  expect(callCount).toEqual(1)
20
21
 
21
22
 
22
- describe "#trigger", ->
23
+ describe ".trigger", ->
23
24
 
24
25
  it "triggers an event prefixed with 'mercury:' on the top window", ->
25
26
  argsForCall = []
26
27
  callCount = 0
27
- Mercury.bind('test', -> argsForCall[callCount] = arguments; callCount += 1)
28
+ Mercury.on('test', -> argsForCall[callCount] = arguments; callCount += 1)
28
29
  Mercury.trigger("test", {foo: 'bar'})
29
30
  expect(callCount).toEqual(1)
30
31
  expect(argsForCall[0][1]).toEqual({foo: 'bar'})
31
32
 
32
33
 
33
- describe "#log", ->
34
+ describe ".notify", ->
35
+
36
+ beforeEach ->
37
+ @alertSpy = spyOn(window, 'alert').andCallFake(=>)
38
+ @i18nSpy = spyOn(Mercury, 'I18n').andCallFake(=>)
39
+ Mercury.notify('hello world!')
40
+
41
+ it "translates the text first by calling Mercury.I18n", ->
42
+ expect(@i18nSpy.callCount).toEqual(1)
43
+ expect(@i18nSpy.argsForCall[0]).toEqual(['hello world!'])
44
+
45
+ it "alerts the message", ->
46
+ expect(@alertSpy.callCount).toEqual(1)
47
+ expect(@i18nSpy.argsForCall[0]).toEqual(['hello world!'])
48
+
49
+
50
+ describe ".warn", ->
51
+
52
+ beforeEach ->
53
+ window.console = {warn: (-> ''), trace: (-> '')}
54
+ @warnSpy = spyOn(window.console, 'warn').andCallFake(=>)
55
+ @notifySpy = spyOn(Mercury, 'notify').andCallFake(=>)
56
+
57
+ it "calls console.warn", ->
58
+ Mercury.warn('message', 2)
59
+ expect(@warnSpy.callCount).toEqual(1)
60
+
61
+ it "calls Mercury.notify if there's no console", ->
62
+ window.console = null
63
+ Mercury.warn('message', 2)
64
+ expect(@notifySpy.callCount).toEqual(1)
65
+
66
+
67
+ describe ".log", ->
34
68
 
35
69
  beforeEach ->
36
70
  window.console = {debug: -> ''}
@@ -50,3 +84,49 @@ describe "Mercury", ->
50
84
  window.console = null
51
85
  Mercury.log(1, 2)
52
86
  expect(@debugSpy.callCount).toEqual(0)
87
+
88
+
89
+ describe ".locale", ->
90
+
91
+ beforeEach ->
92
+ @translationSource = Mercury.I18n['en'] = {
93
+ 'original-top': 'translated-top'
94
+ _US_: {'original-sub': 'translated-sub'}
95
+ }
96
+
97
+ it "memoizes array for what the browsers language is set to (breaks with a different language set)", ->
98
+ Mercury.config.localization.enabled = true
99
+ expect(Mercury.determinedLocale).toEqual(undefined)
100
+ expect(Mercury.locale()).toEqual({top: @translationSource, sub: @translationSource['_US_']})
101
+ expect(Mercury.determinedLocale).toEqual({top: @translationSource, sub: @translationSource['_US_']})
102
+
103
+
104
+ describe ".I18n", ->
105
+
106
+ beforeEach ->
107
+ Mercury.I18n['foo'] =
108
+ 'originaL': 'translated -- top level'
109
+ 'uniquE': 'translated unique'
110
+ 'complex %s with %d, and %f': 'translated %s with %d, and %f'
111
+ BAR:
112
+ 'originaL': 'translated -- sub level'
113
+ 'unique': 'undesired unique'
114
+ Mercury.determinedLocale = {top: Mercury.I18n['foo'], sub: Mercury.I18n['foo']['BAR']}
115
+
116
+
117
+ it "translates from a top level locale", ->
118
+ Mercury.determinedLocale.sub = {}
119
+ expect(Mercury.I18n('originaL')).toEqual('translated -- top level')
120
+
121
+ it "translates from a sub level locale", ->
122
+ expect(Mercury.I18n('originaL')).toEqual('translated -- sub level')
123
+
124
+ it "falls back from a sub level locale", ->
125
+ expect(Mercury.I18n('uniquE')).toEqual('translated unique')
126
+
127
+ it "falls back to no translation", ->
128
+ Mercury.determinedLocale = {top: {}, sub: {}}
129
+ expect(Mercury.I18n('original')).toEqual('original')
130
+
131
+ it "uses printf to get any number of variables into the translation", ->
132
+ expect(Mercury.I18n('complex %s with %d, and %f', 'string', 1, 2.4)).toEqual('translated string with 1, and 2.4')
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modal", ->
4
2
 
5
3
  template 'mercury/modal.html'
@@ -7,8 +5,12 @@ describe "Mercury.modal", ->
7
5
  beforeEach ->
8
6
  $.fx.off = true
9
7
  Mercury.displayRect = {fullHeight: 200}
8
+ Mercury.determinedLocale =
9
+ top: {'hello world!': 'bork! bork!'}
10
+ sub: {'foo': 'Bork!'}
10
11
 
11
12
  afterEach ->
13
+ Mercury.config.localization.enabled = false
12
14
  Mercury.modal.initialized = false
13
15
  Mercury.modal.visible = false
14
16
  $(window).unbind('mercury:refresh')
@@ -119,11 +121,6 @@ describe "Mercury.modal", ->
119
121
  expect($('#modal_container .mercury-modal').length).toEqual(1)
120
122
  expect($('#modal_container .mercury-modal-overlay').length).toEqual(1)
121
123
 
122
- it "updates the title to reflect what was passed in the options", ->
123
- Mercury.modal.options.title = 'title'
124
- Mercury.modal.build()
125
- expect($('#test .mercury-modal-title span').html()).toEqual('title')
126
-
127
124
 
128
125
  describe "observed events", ->
129
126
 
@@ -146,13 +143,21 @@ describe "Mercury.modal", ->
146
143
  Mercury.trigger('resize')
147
144
  expect(spy.callCount).toEqual(1)
148
145
 
149
- describe "clicking on the overlay", ->
146
+ describe "clicking on the overlay (options.allowHideUsingOverlay = true)", ->
150
147
 
151
148
  it "calls hide", ->
149
+ Mercury.modal.options.allowHideUsingOverlay = true
152
150
  spy = spyOn(Mercury.modal, 'hide').andCallFake(=>)
153
151
  jasmine.simulate.click($('.mercury-modal-overlay').get(0))
154
152
  expect(spy.callCount).toEqual(1)
155
153
 
154
+ describe "clicking on the overlay (options.allowHideUsingOverlay = false)", ->
155
+
156
+ it "doesn't call hide", ->
157
+ spy = spyOn(Mercury.modal, 'hide').andCallFake(=>)
158
+ jasmine.simulate.click($('.mercury-modal-overlay').get(0))
159
+ expect(spy.callCount).toEqual(0)
160
+
156
161
  describe "clicking on the close button", ->
157
162
 
158
163
  it "calls hide", ->
@@ -170,6 +175,17 @@ describe "Mercury.modal", ->
170
175
  jasmine.simulate.keydown(document, {keyCode: 27})
171
176
  expect(spy.callCount).toEqual(1)
172
177
 
178
+ describe "ajax:beforeSend", ->
179
+
180
+ it "sets a success that will load the contents of the response", ->
181
+ options = {}
182
+ spy = spyOn(Mercury.modal, 'loadContent').andCallFake(=>)
183
+ Mercury.modal.element.trigger('ajax:beforeSend', [null, options])
184
+ expect(options.success).toBeDefined()
185
+ options.success('new content')
186
+ expect(spy.callCount).toEqual(1)
187
+ expect(spy.argsForCall[0]).toEqual(['new content'])
188
+
173
189
 
174
190
  describe "#appear", ->
175
191
 
@@ -178,7 +194,7 @@ describe "Mercury.modal", ->
178
194
  spyOn(Mercury.modal, 'update').andCallFake(=>)
179
195
  @loadSpy = spyOn(Mercury.modal, 'load').andCallFake(=>)
180
196
  @positionSpy = spyOn(Mercury.modal, 'position').andCallFake(=>)
181
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test')})
197
+ Mercury.modal('/blank.html', {appendTo: $('#test')})
182
198
 
183
199
  it "calls position", ->
184
200
  Mercury.modal.appear()
@@ -223,7 +239,7 @@ describe "Mercury.modal", ->
223
239
 
224
240
  beforeEach ->
225
241
  spyOn(Mercury.modal, 'appear').andCallFake(=>)
226
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test')})
242
+ Mercury.modal('/blank.html', {appendTo: $('#test')})
227
243
  Mercury.modal.contentPane = $()
228
244
 
229
245
  it "will keep the content element visible if asked to do so", ->
@@ -277,7 +293,7 @@ describe "Mercury.modal", ->
277
293
  beforeEach ->
278
294
  spyOn(Mercury.modal, 'appear').andCallFake(=>)
279
295
  @ajaxSpy = spyOn($, 'ajax')
280
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test')})
296
+ Mercury.modal('/blank.html', {appendTo: $('#test')})
281
297
 
282
298
  it "does nothing if there's no url", ->
283
299
  Mercury.modal.url = null
@@ -297,8 +313,8 @@ describe "Mercury.modal", ->
297
313
  describe "on a preloaded view", ->
298
314
 
299
315
  beforeEach ->
300
- @setTimeoutSpy = spyOn(window, 'setTimeout').andCallFake((callback) => callback())
301
- Mercury.preloadedViews = {'/evergreen/responses/blank.html': 'this is the preloaded content'}
316
+ @setTimeoutSpy = spyOn(window, 'setTimeout').andCallFake((timeout, callback) => callback())
317
+ Mercury.preloadedViews = {'/blank.html': 'this is the preloaded content'}
302
318
 
303
319
  afterEach ->
304
320
  Mercury.preloadedViews = {}
@@ -313,8 +329,10 @@ describe "Mercury.modal", ->
313
329
 
314
330
  it "makes an ajax request", ->
315
331
  @ajaxSpy.andCallFake(=>)
332
+ spyOn(Mercury, 'ajaxHeaders').andCallFake(=> {'X-CSRFToken': 'f00'})
316
333
  Mercury.modal.load()
317
334
  expect(@ajaxSpy.callCount).toEqual(1)
335
+ expect(@ajaxSpy.argsForCall[0][1]['headers']).toEqual({'X-CSRFToken': 'f00'})
318
336
 
319
337
  describe "on success", ->
320
338
 
@@ -343,7 +361,7 @@ describe "Mercury.modal", ->
343
361
  spy = spyOn(window, 'alert').andCallFake(=>)
344
362
  Mercury.modal.load()
345
363
  expect(spy.callCount).toEqual(1)
346
- expect(spy.argsForCall[0]).toEqual(['Mercury was unable to load /evergreen/responses/blank.html for the modal.'])
364
+ expect(spy.argsForCall[0]).toEqual(['Mercury was unable to load /blank.html for the modal.'])
347
365
 
348
366
 
349
367
  describe "#loadContent", ->
@@ -351,7 +369,7 @@ describe "Mercury.modal", ->
351
369
  beforeEach ->
352
370
  spyOn(Mercury.modal, 'appear').andCallFake(=>)
353
371
  @resizeSpy = spyOn(Mercury.modal, 'resize').andCallFake(=>)
354
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test'), title: 'title'})
372
+ Mercury.modal('/blank.html', {appendTo: $('#test'), title: 'title'})
355
373
 
356
374
  it "accepts options and sets them to the instance options", ->
357
375
  Mercury.modal.loadContent('content', {title: 'title'})
@@ -378,8 +396,8 @@ describe "Mercury.modal", ->
378
396
  expect($('.mercury-modal').hasClass('loading')).toEqual(false)
379
397
 
380
398
  it "sets the content elements html to whatever was passed", ->
381
- Mercury.modal.loadContent('content')
382
- expect($('.mercury-modal-content').html()).toEqual('content')
399
+ Mercury.modal.loadContent('<span>content</span>')
400
+ expect($('.mercury-modal-content').html()).toEqual('<span>content</span>')
383
401
 
384
402
  it "hides the contentElement", ->
385
403
  $('.mercury-modal-content').css('display', 'block')
@@ -388,9 +406,9 @@ describe "Mercury.modal", ->
388
406
  expect($('.mercury-modal-content').css('visibility')).toEqual('hidden')
389
407
 
390
408
  it "finds the content panes and control elements in case they were added with the content", ->
391
- Mercury.modal.loadContent('<div class="mercury-modal-pane-container"></div><div class="mercury-modal-controls"></div>')
392
- expect(Mercury.modal.contentPane.get(0)).toEqual($('#test .mercury-modal-pane-container').get(0))
393
- expect(Mercury.modal.contentControl.get(0)).toEqual($('#test .mercury-modal-controls').get(0))
409
+ Mercury.modal.loadContent('<div class="mercury-display-pane-container"></div><div class="mercury-display-controls"></div>')
410
+ expect(Mercury.modal.contentPane.get(0)).toEqual($('#test .mercury-display-pane-container').get(0))
411
+ expect(Mercury.modal.contentControl.get(0)).toEqual($('#test .mercury-display-controls').get(0))
394
412
 
395
413
  it "calls an afterLoad callback (if provided in options)", ->
396
414
  callCount = 0
@@ -403,6 +421,11 @@ describe "Mercury.modal", ->
403
421
  Mercury.modal.loadContent('content', {handler: 'foo'})
404
422
  expect(callCount).toEqual(1)
405
423
 
424
+ it "translates the content if configured", ->
425
+ Mercury.config.localization.enabled = true
426
+ Mercury.modal.loadContent('<span>foo</span>')
427
+ expect($('.mercury-modal-content').html()).toEqual('<span>Bork!</span>')
428
+
406
429
  it "calls resize", ->
407
430
  Mercury.modal.loadContent('content')
408
431
  expect(@resizeSpy.callCount).toEqual(1)
@@ -412,19 +435,26 @@ describe "Mercury.modal", ->
412
435
 
413
436
  beforeEach ->
414
437
  spyOn(Mercury.modal, 'appear').andCallFake(=>)
415
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test'), title: 'title'})
438
+ Mercury.modal('/blank.html', {appendTo: $('#test'), title: 'title'})
416
439
 
417
440
  it "sets the the title contents to what was provided in the options", ->
418
441
  Mercury.modal.options = {title: 'new title'}
419
442
  Mercury.modal.setTitle()
420
443
  expect($('.mercury-modal-title span').html()).toEqual('new title')
444
+ expect($('.mercury-modal-title a').css('display')).toEqual('inline')
445
+
446
+ it "hides the close button if the options.closeButton is false", ->
447
+ Mercury.modal.options = {title: 'new title', closeButton: false}
448
+ Mercury.modal.setTitle()
449
+ expect($('.mercury-modal-title a').css('display')).toEqual('none')
450
+
421
451
 
422
452
 
423
453
  describe "#reset", ->
424
454
 
425
455
  beforeEach ->
426
456
  spyOn(Mercury.modal, 'appear').andCallFake(=>)
427
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test'), title: 'title'})
457
+ Mercury.modal('/blank.html', {appendTo: $('#test'), title: 'title'})
428
458
 
429
459
  it "clears the title and content elements", ->
430
460
  $('.mercury-modal-content').html('content')
@@ -437,7 +467,7 @@ describe "Mercury.modal", ->
437
467
 
438
468
  beforeEach ->
439
469
  spyOn(Mercury.modal, 'appear').andCallFake(=>)
440
- Mercury.modal('/evergreen/responses/blank.html', {appendTo: $('#test')})
470
+ Mercury.modal('/blank.html', {appendTo: $('#test')})
441
471
 
442
472
  it "triggers the focus:frame event", ->
443
473
  spy = spyOn(Mercury, 'trigger').andCallFake(=>)
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modalHandlers.htmlEditor", ->
4
2
 
5
3
  template 'mercury/modals/htmleditor.html'
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modalHandlers.insertCharacter", ->
4
2
 
5
3
  template 'mercury/modals/insertcharacter.html'
@@ -7,7 +5,8 @@ describe "Mercury.modalHandlers.insertCharacter", ->
7
5
  beforeEach ->
8
6
  @modal =
9
7
  element: $('#test')
10
- @modalHideSpy = spyOn(Mercury.modal, 'hide').andCallFake(=>)
8
+ hide: ->
9
+ @modalHideSpy = spyOn(@modal, 'hide').andCallFake(=>)
11
10
  Mercury.modalHandlers.insertCharacter.call(@modal)
12
11
 
13
12
  describe "clicking on a character", ->
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modalHandlers.insertLink", ->
4
2
 
5
3
  template 'mercury/modals/insertlink.html'
@@ -1,11 +1,10 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modalHandlers.insertMedia", ->
4
2
 
5
3
  template 'mercury/modals/insertmedia.html'
6
4
 
7
5
  beforeEach ->
8
6
  Mercury.region = null
7
+ spyOn(window, 'setTimeout').andCallFake((timeout, callback) => callback())
9
8
  @modal =
10
9
  element: $('#test')
11
10
  hide: ->
@@ -21,6 +20,7 @@ describe "Mercury.modalHandlers.insertMedia", ->
21
20
  jasmine.simulate.click($('#checkbox1').get(0))
22
21
  expect(spy.callCount).toEqual(1)
23
22
 
23
+
24
24
  describe "focusing an input", ->
25
25
 
26
26
  beforeEach ->
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modalHandlers.insertSnippet", ->
4
2
 
5
3
  template 'mercury/modals/insertsnippet.html'
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.modalHandlers.insertTable", ->
4
2
 
5
3
  template 'mercury/modals/inserttable.html'
@@ -148,11 +146,11 @@ describe "Mercury.modalHandlers.insertTable", ->
148
146
  jasmine.simulate.click($('#submit').get(0))
149
147
  expect(spy.callCount).toEqual(1)
150
148
  expect(spy.argsForCall[0][0]).toEqual('action')
151
- expect(spy.argsForCall[0][1]['action']).toEqual('insertHTML')
149
+ expect(spy.argsForCall[0][1]['action']).toEqual('insertTable')
152
150
  value = spy.argsForCall[0][1]['value']
153
151
  expect(value).toContain('border="1"')
154
152
  expect(value).toContain('cellspacing="0"')
155
- expect(value).toContain('<td id="cell2">&nbsp;</td>')
153
+ expect(value).toContain('<td id="cell2"><br></td>')
156
154
 
157
155
  it "hides the modal", ->
158
156
  spy = spyOn(@modal, 'hide').andCallFake(=>)
@@ -1,5 +1,3 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "String", ->
4
2
 
5
3
  describe "#titleize", ->
@@ -15,6 +13,26 @@ describe "String", ->
15
13
  expect('rgb(255, 255, 0)'.toHex()).toEqual('#FFFF00')
16
14
 
17
15
 
16
+ describe "#regExpEscape", ->
17
+
18
+ it "escapes characters used in regular expressions", ->
19
+ expect('/.*+?|()[]{}\\'.regExpEscape()).toEqual('\\/\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}\\\\')
20
+
21
+
22
+ describe "#printf", ->
23
+
24
+ it "works something like a basic implementation of the standard sprintf", ->
25
+ expect('int %d'.printf(2.1)).toEqual('int 2')
26
+ expect('int%d'.printf(2.1)).toEqual('int2')
27
+ expect('%d-int'.printf(2.1)).toEqual('2-int')
28
+ expect('%f float'.printf(2.1)).toEqual('2.1 float')
29
+ expect('%s string'.printf(2.1)).toEqual('2.1 string')
30
+ expect('%% a'.printf(2.1)).toEqual('% a')
31
+ expect('a %% b'.printf()).toEqual('a % b')
32
+ expect('a %% %d'.printf(2.1)).toEqual('a % 2')
33
+ expect('%d\n%s'.printf(2.1, 'string')).toEqual('2\nstring')
34
+
35
+
18
36
  describe "Number", ->
19
37
 
20
38
  describe "#toHex", ->
@@ -1,11 +1,9 @@
1
- require '/assets/mercury.js'
2
-
3
1
  describe "Mercury.PageEditor", ->
4
2
 
5
3
  template 'mercury/page_editor.html'
6
4
 
7
5
  beforeEach ->
8
- Mercury.config.regionClass = 'custom-region-class'
6
+ Mercury.config.regions.className = 'custom-region-class'
9
7
 
10
8
  afterEach ->
11
9
  @pageEditor = null
@@ -15,6 +13,8 @@ describe "Mercury.PageEditor", ->
15
13
  $(window).unbind('mercury:focus:frame')
16
14
  $(window).unbind('mercury:focus:window')
17
15
  $(window).unbind('mercury:toggle:interface')
16
+ $(window).unbind('mercury:reinitialize')
17
+ $(window).unbind('mercury:mode')
18
18
  $(window).unbind('mercury:action')
19
19
  $(window).unbind('resize')
20
20
  $(document).unbind('mousedown')
@@ -24,13 +24,6 @@ describe "Mercury.PageEditor", ->
24
24
  beforeEach ->
25
25
  @initializeInterfaceSpy = spyOn(Mercury.PageEditor.prototype, 'initializeInterface').andCallFake(=>)
26
26
 
27
- it "throws an error if it's not supported", ->
28
- Mercury.supported = false
29
- expect(=>
30
- new Mercury.PageEditor()
31
- ).toThrow('Mercury.PageEditor is unsupported in this client. Supported browsers are chrome 10+, firefix 4+, and safari 5+.')
32
- Mercury.supported = true
33
-
34
27
  it "throws an error if it's already instantiated", ->
35
28
  window.mercuryInstance = true
36
29
  expect(=>
@@ -73,6 +66,7 @@ describe "Mercury.PageEditor", ->
73
66
  describe "#initializeInterface", ->
74
67
 
75
68
  beforeEach ->
69
+ @resizeSpy = spyOn(Mercury.PageEditor.prototype, 'resize').andCallFake(=>)
76
70
  Mercury.Toolbar = -> {toolbar: true}
77
71
  Mercury.Statusbar = -> {statusbar: true}
78
72
  @iframeSrcSpy = spyOn(Mercury.PageEditor.prototype, 'iframeSrc').andCallFake(=> '/foo')
@@ -98,6 +92,10 @@ describe "Mercury.PageEditor", ->
98
92
  @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test')})
99
93
  expect(@pageEditor.statusbar).toEqual({statusbar: true})
100
94
 
95
+ it "calls resize", ->
96
+ @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test')})
97
+ expect(@resizeSpy.callCount).toEqual(1)
98
+
101
99
 
102
100
  describe "#initializeFrame", ->
103
101
 
@@ -149,7 +147,7 @@ describe "Mercury.PageEditor", ->
149
147
  it "calls resize", ->
150
148
  @finalizeInterfaceSpy.andCallFake(=>)
151
149
  @pageEditor.initializeFrame()
152
- expect(@resizeSpy.callCount).toEqual(1)
150
+ expect(@resizeSpy.callCount).toEqual(2)
153
151
 
154
152
  it "calls initializeRegions", ->
155
153
  @finalizeInterfaceSpy.andCallFake(=>)
@@ -209,22 +207,30 @@ describe "Mercury.PageEditor", ->
209
207
  describe "#initializeRegions", ->
210
208
 
211
209
  beforeEach ->
210
+ @resizeSpy = spyOn(Mercury.PageEditor.prototype, 'resize').andCallFake(=>)
212
211
  Mercury.PageEditor.prototype.initializeFrame = ->
213
212
  @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test')})
214
213
  @pageEditor.document = $(document)
215
- @buildRegionSpy = spyOn(Mercury.PageEditor.prototype, 'buildRegion').andCallFake(=>)
216
214
 
217
215
  it "it calls buildRegion for all the regions found in a document", ->
216
+ spy = spyOn(Mercury.PageEditor.prototype, 'buildRegion').andCallFake(=>)
218
217
  @pageEditor.initializeRegions()
219
- expect(@buildRegionSpy.callCount).toEqual(3)
218
+ expect(spy.callCount).toEqual(4)
220
219
 
221
220
  it "focuses the first region", ->
222
- firstFocusCalled = false
223
- @pageEditor.regions = [{focus: => firstFocusCalled = true}, {}, {}]
221
+ regionIndex = 0
222
+ regionFocusCall = null;
223
+ spy = spyOn(Mercury.PageEditor.prototype, 'buildRegion').andCallFake ->
224
+ @regions.push({focus: ->
225
+ regionIndex += 1
226
+ regionFocusCall = regionIndex
227
+ })
224
228
  @pageEditor.initializeRegions()
225
- expect(firstFocusCalled).toEqual(true)
229
+ expect(spy.callCount).toEqual(4)
230
+ expect(regionFocusCall).toEqual(1)
226
231
 
227
232
  it "doesn't focus the first region if it's not supposed to be visible", ->
233
+ spy = spyOn(Mercury.PageEditor.prototype, 'buildRegion').andCallFake(=>)
228
234
  firstFocusCalled = false
229
235
  @pageEditor.regions = [{focus: => firstFocusCalled = true}, {}, {}]
230
236
  @pageEditor.options.visible = false
@@ -233,10 +239,19 @@ describe "Mercury.PageEditor", ->
233
239
 
234
240
 
235
241
  describe "#buildRegion", ->
242
+ # it "throws an error if it's not supported", ->
243
+ # Mercury.supported = false
244
+ # expect(=>
245
+ # new Mercury.PageEditor()
246
+ # ).toThrow('Mercury.PageEditor is unsupported in this client. Supported browsers are chrome 10+, firefix 4+, and safari 5+.')
247
+ # Mercury.supported = true
248
+ #
236
249
 
237
250
  beforeEach ->
251
+ @resizeSpy = spyOn(Mercury.PageEditor.prototype, 'resize').andCallFake(=>)
238
252
  Mercury.PageEditor.prototype.initializeFrame = ->
239
253
  Mercury.Regions.Editable = -> {region: true}
254
+ Mercury.Regions.Editable.supported = true
240
255
  @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test')})
241
256
 
242
257
  it "instantiates the region and pushes it into the regions array", ->
@@ -244,18 +259,41 @@ describe "Mercury.PageEditor", ->
244
259
  expect(@pageEditor.regions.length).toEqual(1)
245
260
  expect(@pageEditor.regions[0]).toEqual({region: true})
246
261
 
247
- it "alerts on errors", ->
248
- Mercury.debug = false
249
- Mercury.Regions.Editable = -> throw('error!')
250
- spy = spyOn(window, 'alert').andCallFake(=>)
262
+ it "throws an exception when there's no data-type attribute", ->
263
+ expect(=> @pageEditor.buildRegion($('#region4'))).toThrow('Region type is malformed, no data-type provided, or "Unknown" is unknown for the "region4" region.')
264
+ expect(=> @pageEditor.buildRegion($('#region4'))).toThrow('Region type is malformed, no data-type provided, or "Unknown" is unknown for the "region4" region.')
265
+
266
+ it "throws an exception when the data-type isn't known", ->
267
+ expect(=> @pageEditor.buildRegion($('#region4'))).toThrow('Region type is malformed, no data-type provided, or "Unknown" is unknown for the "region4" region.')
268
+ $('#region4').attr('data-type', 'foo')
269
+ expect(=> @pageEditor.buildRegion($('#region4'))).toThrow('Region type is malformed, no data-type provided, or "Foo" is unknown for the "region4" region.')
270
+
271
+ it "doesn't re-instantiate the region if the element's already initialized", ->
272
+ $('#region2').data('region', {foo: 'bar'})
251
273
  @pageEditor.buildRegion($('#region2'))
252
- expect(spy.callCount).toEqual(1)
253
- expect(spy.argsForCall[0]).toEqual(['Region type is malformed, no data-type provided, or "Editable" is unknown.'])
274
+ expect(@pageEditor.regions.length).toEqual(1)
275
+ expect(@pageEditor.regions[0]).toEqual({foo: 'bar'})
276
+
277
+ it "calls togglePreview on the region if in preview mode", ->
278
+ callCount = 0
279
+ Mercury.Regions.Editable = -> {region: true, togglePreview: -> callCount += 1 }
280
+ Mercury.Regions.Editable.supported = true
281
+ @pageEditor.previewing = true
282
+ @pageEditor.buildRegion($('#region2'))
283
+ expect(callCount).toEqual(1)
284
+
285
+ it "doesn't call togglePreview if not in preview mode", ->
286
+ callCount = 0
287
+ Mercury.Regions.Editable = -> {region: true, togglePreview: -> callCount += 1 }
288
+ Mercury.Regions.Editable.supported = true
289
+ @pageEditor.buildRegion($('#region2'))
290
+ expect(callCount).toEqual(0)
254
291
 
255
292
 
256
293
  describe "#finalizeInterface", ->
257
294
 
258
295
  beforeEach ->
296
+ @resizeSpy = spyOn(Mercury.PageEditor.prototype, 'resize').andCallFake(=>)
259
297
  Mercury.PageEditor.prototype.initializeFrame = ->
260
298
  Mercury.SnippetToolbar = -> {snippetToolbar: true}
261
299
  @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test')})
@@ -292,7 +330,7 @@ describe "Mercury.PageEditor", ->
292
330
 
293
331
  it "calls initializeFrame", ->
294
332
  @initializeFrameSpy = spyOn(Mercury.PageEditor.prototype, 'initializeFrame').andCallFake(=>)
295
- @setTimeoutSpy = spyOn(window, 'setTimeout').andCallFake((callback) -> callback())
333
+ @setTimeoutSpy = spyOn(window, 'setTimeout').andCallFake((timeout, callback) -> callback())
296
334
  Mercury.trigger('initialize:frame')
297
335
  expect(@initializeFrameSpy.callCount).toEqual(1)
298
336
  expect(@setTimeoutSpy.callCount).toEqual(1)
@@ -310,7 +348,7 @@ describe "Mercury.PageEditor", ->
310
348
  it "calls focus on a focusable element", ->
311
349
  callCount = 0
312
350
  @pageEditor.focusableElement = {focus: -> callCount += 1}
313
- @setTimeoutSpy = spyOn(window, 'setTimeout').andCallFake((callback) -> callback())
351
+ @setTimeoutSpy = spyOn(window, 'setTimeout').andCallFake((timeout, callback) -> callback())
314
352
  Mercury.trigger('focus:window')
315
353
  expect(callCount).toEqual(1)
316
354
 
@@ -321,6 +359,23 @@ describe "Mercury.PageEditor", ->
321
359
  Mercury.trigger('toggle:interface')
322
360
  expect(spy.callCount).toEqual(1)
323
361
 
362
+ describe "custom event: mode", ->
363
+
364
+ it "toggles preview mode if needed", ->
365
+ Mercury.trigger('mode', {mode: 'preview'})
366
+ expect(@pageEditor.previewing).toEqual(true)
367
+ Mercury.trigger('mode', {mode: 'preview'})
368
+ expect(@pageEditor.previewing).toEqual(false)
369
+ Mercury.trigger('mode', {mode: 'foo'})
370
+ expect(@pageEditor.previewing).toEqual(false)
371
+
372
+ describe "custom event: reinitialize", ->
373
+
374
+ it "calls initializeRegions", ->
375
+ spy = spyOn(Mercury.PageEditor.prototype, 'initializeRegions').andCallFake(=>)
376
+ Mercury.trigger('reinitialize')
377
+ expect(spy.callCount).toEqual(1)
378
+
324
379
  describe "custom event: action", ->
325
380
 
326
381
  it "calls save if the action was save", ->
@@ -350,16 +405,16 @@ describe "Mercury.PageEditor", ->
350
405
 
351
406
  describe "window resize", ->
352
407
 
408
+ # untestable
353
409
  it "calls resize", ->
354
- # untestable
355
410
  #spy = spyOn(Mercury.PageEditor.prototype, 'resize').andCallFake(=>)
356
411
  #resizeTo($(window).width() - 1, $(window).height() - 1)
357
412
  #expect(spy.callCount).toEqual(1)
358
413
 
359
414
  describe "onbeforeunload", ->
360
415
 
416
+ # untestable
361
417
  it "calls Mercury.beforeUnload", ->
362
- # untestable
363
418
  #spy = spyOn(Mercury, 'beforeUnload').andCallFake(=>)
364
419
  #window.onbeforeunload()
365
420
  #expect(spy.callCount).toEqual(1)
@@ -373,8 +428,18 @@ describe "Mercury.PageEditor", ->
373
428
  spec.toolbarHideCallCount = 0
374
429
  spec.statusbarShowCallCount = 0
375
430
  spec.statusbarHideCallCount = 0
376
- Mercury.Toolbar = -> {toolbar: true, height: (-> 100), show: (=> spec.toolbarShowCallCount += 1), hide: (=> spec.toolbarHideCallCount += 1)}
377
- Mercury.Statusbar = -> {statusbar: true, top: (-> 500), show: (=> spec.statusbarShowCallCount += 1), hide: (=> spec.statusbarHideCallCount += 1)}
431
+ Mercury.Toolbar = -> {
432
+ toolbar: true,
433
+ height: (-> 100),
434
+ show: (=> spec.toolbarShowCallCount += 1),
435
+ hide: (=> spec.toolbarHideCallCount += 1)
436
+ }
437
+ Mercury.Statusbar = -> {
438
+ statusbar: true,
439
+ top: (-> 500),
440
+ show: (=> spec.statusbarShowCallCount += 1),
441
+ hide: (=> spec.statusbarHideCallCount += 1)
442
+ }
378
443
  Mercury.PageEditor.prototype.initializeFrame = ->
379
444
  @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test')})
380
445
 
@@ -395,6 +460,14 @@ describe "Mercury.PageEditor", ->
395
460
  beforeEach ->
396
461
  @pageEditor.visible = true
397
462
 
463
+ it "triggers an extra preview mode event if currently previewing", ->
464
+ @pageEditor.previewing = true
465
+ spy = spyOn(Mercury, 'trigger').andCallFake(=>)
466
+ @pageEditor.toggleInterface()
467
+ expect(spy.callCount).toEqual(3)
468
+ expect(spy.argsForCall[0]).toEqual(['mode', {mode: 'preview'}])
469
+ expect(spy.argsForCall[1]).toEqual(['mode', {mode: 'preview'}])
470
+
398
471
  it "sets visible to false", ->
399
472
  @pageEditor.toggleInterface()
400
473
  expect(@pageEditor.visible).toEqual(false)
@@ -457,6 +530,16 @@ describe "Mercury.PageEditor", ->
457
530
  it "takes the location and removes the /editor", ->
458
531
  expect(@pageEditor.iframeSrc('http://foo.com/editor/path')).toEqual('http://foo.com/path')
459
532
 
533
+ it "uses the configured url regex to remove the editor", ->
534
+ original = Mercury.config.editorUrlRegEx
535
+ Mercury.config.editorUrlRegEx = /([http|https]:\/\/[^\/]*)\/(.*)\/edit\/?/i
536
+ expect(@pageEditor.iframeSrc('http://foo.com/path/edit')).toEqual('http://foo.com/path')
537
+ Mercury.config.editorUrlRegEx = original
538
+
539
+ it "adds query params", ->
540
+ expect(@pageEditor.iframeSrc('http://foo.com/editor/path', true)).toEqual('http://foo.com/path?mercury_frame=true')
541
+ expect(@pageEditor.iframeSrc('http://foo.com/editor/path?something=true', true)).toEqual('http://foo.com/path?something=true&mercury_frame=true')
542
+
460
543
 
461
544
  describe "#hijackLinksAndForms", ->
462
545
 
@@ -474,12 +557,12 @@ describe "Mercury.PageEditor", ->
474
557
  @pageEditor.hijackLinksAndForms()
475
558
  expect($('#anchor1').attr('target')).toEqual('_top')
476
559
  expect($('#anchor2').attr('target')).toEqual('_blank')
477
- expect($('#anchor3').attr('target')).toEqual('_top')
478
- expect($('#anchor4').attr('target')).toEqual('_top')
560
+ expect($('#anchor3').attr('target')).toEqual('_parent')
561
+ expect($('#anchor4').attr('target')).toEqual('_parent')
479
562
  expect($('#form1').attr('target')).toEqual('_top')
480
563
  expect($('#form2').attr('target')).toEqual('_blank')
481
- expect($('#form3').attr('target')).toEqual('_top')
482
- expect($('#form4').attr('target')).toEqual('_top')
564
+ expect($('#form3').attr('target')).toEqual('_parent')
565
+ expect($('#form4').attr('target')).toEqual('_parent')
483
566
 
484
567
  it "ignores links in regions", ->
485
568
  @pageEditor.hijackLinksAndForms()
@@ -590,10 +673,10 @@ describe "Mercury.PageEditor", ->
590
673
  @pageEditor.save()
591
674
  expect(@ajaxSpy.argsForCall[0][1]['data']).toEqual({content: {region1: 'region1'}})
592
675
 
593
- it "sets headers by calling #saveHeaders", ->
676
+ it "sets headers by calling Mercury.ajaxHeaders", ->
594
677
  @ajaxSpy.andCallFake(=>)
595
678
  spyOn(Mercury.PageEditor.prototype, 'serialize').andCallFake(=> {region1: 'region1'})
596
- spy = spyOn(Mercury.PageEditor.prototype, 'saveHeaders').andCallFake(=> {'X-CSRFToken': 'f00'})
679
+ spyOn(Mercury, 'ajaxHeaders').andCallFake(=> {'X-CSRFToken': 'f00'})
597
680
  @pageEditor.save()
598
681
  expect(@ajaxSpy.argsForCall[0][1]['headers']).toEqual({'X-CSRFToken': 'f00'})
599
682
 
@@ -613,6 +696,18 @@ describe "Mercury.PageEditor", ->
613
696
  @pageEditor.save()
614
697
  expect(Mercury.changes).toEqual(false)
615
698
 
699
+ it "calls a callback if one was provided", ->
700
+ callback = -> callback.callCount += 1
701
+ callback.callCount = 0;
702
+ @pageEditor.save(callback)
703
+ expect(callback.callCount).toEqual(1)
704
+
705
+ it "fires an event", ->
706
+ spy = spyOn(Mercury, 'trigger').andCallFake(=>)
707
+ @pageEditor.save()
708
+ expect(spy.callCount).toEqual(1)
709
+ expect(spy.argsForCall[0]).toEqual(['saved'])
710
+
616
711
  describe "on failed ajax request", ->
617
712
 
618
713
  beforeEach ->
@@ -652,4 +747,4 @@ describe "Mercury.PageEditor", ->
652
747
 
653
748
  it "returns an object with the region name, and it's serialized value", ->
654
749
  ret = @pageEditor.serialize()
655
- expect(ret).toEqual({region1: 'region1', region2: 'region2'})
750
+ expect(ret).toEqual({region1: 'region1', region2: 'region2'})