mercury-rails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +152 -0
  3. data/VERSION +1 -0
  4. data/app/assets/images/mercury/button.png +0 -0
  5. data/app/assets/images/mercury/clippy.png +0 -0
  6. data/app/assets/images/mercury/default-snippet.png +0 -0
  7. data/app/assets/images/mercury/loading-dark.gif +0 -0
  8. data/app/assets/images/mercury/loading-light.gif +0 -0
  9. data/app/assets/images/mercury/search-icon.png +0 -0
  10. data/app/assets/images/mercury/toolbar/editable/buttons.png +0 -0
  11. data/app/assets/images/mercury/toolbar/markupable/buttons.png +0 -0
  12. data/app/assets/images/mercury/toolbar/primary/_expander.png +0 -0
  13. data/app/assets/images/mercury/toolbar/primary/_pressed.png +0 -0
  14. data/app/assets/images/mercury/toolbar/primary/historypanel.png +0 -0
  15. data/app/assets/images/mercury/toolbar/primary/insertcharacter.png +0 -0
  16. data/app/assets/images/mercury/toolbar/primary/insertlink.png +0 -0
  17. data/app/assets/images/mercury/toolbar/primary/insertmedia.png +0 -0
  18. data/app/assets/images/mercury/toolbar/primary/inserttable.png +0 -0
  19. data/app/assets/images/mercury/toolbar/primary/inspectorpanel.png +0 -0
  20. data/app/assets/images/mercury/toolbar/primary/notespanel.png +0 -0
  21. data/app/assets/images/mercury/toolbar/primary/objectspanel.png +0 -0
  22. data/app/assets/images/mercury/toolbar/primary/preview.png +0 -0
  23. data/app/assets/images/mercury/toolbar/primary/redo.png +0 -0
  24. data/app/assets/images/mercury/toolbar/primary/save.png +0 -0
  25. data/app/assets/images/mercury/toolbar/primary/todospanel.png +0 -0
  26. data/app/assets/images/mercury/toolbar/primary/undo.png +0 -0
  27. data/app/assets/images/mercury/toolbar/snippetable/buttons.png +0 -0
  28. data/app/assets/javascripts/mercury.js +30 -0
  29. data/app/assets/javascripts/mercury/dialog.js.coffee +75 -0
  30. data/app/assets/javascripts/mercury/dialogs/backcolor.js.coffee +6 -0
  31. data/app/assets/javascripts/mercury/dialogs/forecolor.js.coffee +6 -0
  32. data/app/assets/javascripts/mercury/dialogs/formatblock.js.coffee +4 -0
  33. data/app/assets/javascripts/mercury/dialogs/objectspanel.js.coffee +10 -0
  34. data/app/assets/javascripts/mercury/dialogs/style.js.coffee +4 -0
  35. data/app/assets/javascripts/mercury/history_buffer.js.coffee +30 -0
  36. data/app/assets/javascripts/mercury/mercury.js.coffee +293 -0
  37. data/app/assets/javascripts/mercury/modal.js.coffee +177 -0
  38. data/app/assets/javascripts/mercury/modals/htmleditor.js.coffee +10 -0
  39. data/app/assets/javascripts/mercury/modals/insertcharacter.js.coffee +4 -0
  40. data/app/assets/javascripts/mercury/modals/insertlink.js.coffee +92 -0
  41. data/app/assets/javascripts/mercury/modals/insertmedia.js.coffee +72 -0
  42. data/app/assets/javascripts/mercury/modals/insertsnippet.js.coffee +11 -0
  43. data/app/assets/javascripts/mercury/modals/inserttable.js.coffee +56 -0
  44. data/app/assets/javascripts/mercury/native_extensions.js.coffee +47 -0
  45. data/app/assets/javascripts/mercury/page_editor.js.coffee +139 -0
  46. data/app/assets/javascripts/mercury/palette.js.coffee +29 -0
  47. data/app/assets/javascripts/mercury/panel.js.coffee +97 -0
  48. data/app/assets/javascripts/mercury/region.js.coffee +103 -0
  49. data/app/assets/javascripts/mercury/regions/editable.js.coffee +546 -0
  50. data/app/assets/javascripts/mercury/regions/markupable.js.coffee +380 -0
  51. data/app/assets/javascripts/mercury/regions/snippetable.js.coffee +127 -0
  52. data/app/assets/javascripts/mercury/select.js.coffee +40 -0
  53. data/app/assets/javascripts/mercury/snippet.js.coffee +92 -0
  54. data/app/assets/javascripts/mercury/snippet_toolbar.js.coffee +69 -0
  55. data/app/assets/javascripts/mercury/statusbar.js.coffee +25 -0
  56. data/app/assets/javascripts/mercury/table_editor.js.coffee +266 -0
  57. data/app/assets/javascripts/mercury/toolbar.button.js.coffee +152 -0
  58. data/app/assets/javascripts/mercury/toolbar.button_group.js.coffee +42 -0
  59. data/app/assets/javascripts/mercury/toolbar.expander.js.coffee +56 -0
  60. data/app/assets/javascripts/mercury/toolbar.js.coffee +72 -0
  61. data/app/assets/javascripts/mercury/tooltip.js.coffee +67 -0
  62. data/app/assets/javascripts/mercury/uploader.js.coffee +213 -0
  63. data/app/assets/javascripts/mercury/websocket.js.coffee +34 -0
  64. data/app/assets/stylesheets/mercury.css +31 -0
  65. data/app/assets/stylesheets/mercury/dialog.scss +178 -0
  66. data/app/assets/stylesheets/mercury/mercury.scss +119 -0
  67. data/app/assets/stylesheets/mercury/modal.scss +192 -0
  68. data/app/assets/stylesheets/mercury/statusbar.scss +23 -0
  69. data/app/assets/stylesheets/mercury/toolbar.scss +417 -0
  70. data/app/assets/stylesheets/mercury/tooltip.scss +26 -0
  71. data/app/assets/stylesheets/mercury/uploader.scss +109 -0
  72. data/app/controllers/images_controller.rb +19 -0
  73. data/app/controllers/mercury_controller.rb +20 -0
  74. data/app/models/image.rb +14 -0
  75. data/app/views/layouts/mercury.html.haml +12 -0
  76. data/app/views/mercury/modals/character.html.haml +252 -0
  77. data/app/views/mercury/modals/htmleditor.html.haml +8 -0
  78. data/app/views/mercury/modals/link.html.haml +31 -0
  79. data/app/views/mercury/modals/media.html.haml +33 -0
  80. data/app/views/mercury/modals/sanitizer.html.haml +4 -0
  81. data/app/views/mercury/modals/table.html.haml +49 -0
  82. data/app/views/mercury/palettes/backcolor.html.haml +79 -0
  83. data/app/views/mercury/palettes/forecolor.html.haml +79 -0
  84. data/app/views/mercury/panels/history.html.haml +0 -0
  85. data/app/views/mercury/panels/notes.html.haml +0 -0
  86. data/app/views/mercury/panels/snippets.html.haml +10 -0
  87. data/app/views/mercury/selects/formatblock.html.haml +10 -0
  88. data/app/views/mercury/selects/style.html.haml +4 -0
  89. data/app/views/mercury/snippets/example.html.haml +2 -0
  90. data/app/views/mercury/snippets/example_options.html.haml +16 -0
  91. data/config/engine.rb +6 -0
  92. data/config/routes.rb +15 -0
  93. data/db/migrate/20110526035601_create_images.rb +11 -0
  94. data/features/editing/basic.feature +11 -0
  95. data/features/step_definitions/debug_steps.rb +14 -0
  96. data/features/step_definitions/web_steps.rb +211 -0
  97. data/features/support/env.rb +46 -0
  98. data/features/support/paths.rb +35 -0
  99. data/features/support/selectors.rb +42 -0
  100. data/lib/mercury-rails.rb +4 -0
  101. data/log/.gitkeep +0 -0
  102. data/mercury-rails.gemspec +230 -0
  103. data/spec/javascripts/mercury/dialog_spec.js.coffee +258 -0
  104. data/spec/javascripts/mercury/history_buffer_spec.js.coffee +79 -0
  105. data/spec/javascripts/mercury/mercury_spec.js.coffee +52 -0
  106. data/spec/javascripts/mercury/native_extensions_spec.js.coffee +66 -0
  107. data/spec/javascripts/mercury/page_editor_spec.js.coffee +435 -0
  108. data/spec/javascripts/mercury/palette_spec.js.coffee +51 -0
  109. data/spec/javascripts/mercury/panel_spec.js.coffee +147 -0
  110. data/spec/javascripts/mercury/region_spec.js.coffee +261 -0
  111. data/spec/javascripts/mercury/regions/_editable_.js.coffee +0 -0
  112. data/spec/javascripts/mercury/regions/_markupable_.js.coffee +0 -0
  113. data/spec/javascripts/mercury/regions/snippetable_spec.js.coffee +368 -0
  114. data/spec/javascripts/mercury/select_spec.js.coffee +51 -0
  115. data/spec/javascripts/mercury/snippet_spec.js.coffee +246 -0
  116. data/spec/javascripts/mercury/snippet_toolbar_spec.js.coffee +186 -0
  117. data/spec/javascripts/mercury/statusbar_spec.js.coffee +78 -0
  118. data/spec/javascripts/mercury/table_editor_spec.js.coffee +192 -0
  119. data/spec/javascripts/mercury/toolbar.button_group_spec.js.coffee +92 -0
  120. data/spec/javascripts/mercury/toolbar.button_spec.js.coffee +341 -0
  121. data/spec/javascripts/mercury/toolbar.expander_spec.js.coffee +120 -0
  122. data/spec/javascripts/mercury/toolbar_spec.js.coffee +152 -0
  123. data/spec/javascripts/mercury/tooltip_spec.js.coffee +188 -0
  124. data/spec/javascripts/mercury/uploader_spec.js.coffee +512 -0
  125. data/spec/javascripts/responses/blank.html +1 -0
  126. data/spec/javascripts/spec_helper.js +513 -0
  127. data/spec/javascripts/templates/mercury/dialog.html +2 -0
  128. data/spec/javascripts/templates/mercury/page_editor.html +24 -0
  129. data/spec/javascripts/templates/mercury/palette.html +16 -0
  130. data/spec/javascripts/templates/mercury/panel.html +16 -0
  131. data/spec/javascripts/templates/mercury/region.html +2 -0
  132. data/spec/javascripts/templates/mercury/regions/snippetable.html +4 -0
  133. data/spec/javascripts/templates/mercury/select.html +16 -0
  134. data/spec/javascripts/templates/mercury/snippet.html +1 -0
  135. data/spec/javascripts/templates/mercury/snippet_toolbar.html +16 -0
  136. data/spec/javascripts/templates/mercury/statusbar.html +7 -0
  137. data/spec/javascripts/templates/mercury/table_editor.html +65 -0
  138. data/spec/javascripts/templates/mercury/toolbar.button.html +64 -0
  139. data/spec/javascripts/templates/mercury/toolbar.button_group.html +9 -0
  140. data/spec/javascripts/templates/mercury/toolbar.expander.html +18 -0
  141. data/spec/javascripts/templates/mercury/toolbar.html +10 -0
  142. data/spec/javascripts/templates/mercury/tooltip.html +12 -0
  143. data/spec/javascripts/templates/mercury/uploader.html +11 -0
  144. data/vendor/assets/javascripts/jquery-1.6.js +8865 -0
  145. data/vendor/assets/javascripts/jquery-ui-1.8.13.custom.min.js +249 -0
  146. data/vendor/assets/javascripts/jquery-ui-1.8.13.sortable.custom.js +1078 -0
  147. data/vendor/assets/javascripts/jquery.easing.js +173 -0
  148. data/vendor/assets/javascripts/jquery.json2.js +178 -0
  149. data/vendor/assets/javascripts/jquery.serialize_object.js +16 -0
  150. data/vendor/assets/javascripts/jquery.ujs.js +289 -0
  151. data/vendor/assets/javascripts/liquidmetal.js +88 -0
  152. data/vendor/assets/javascripts/showdown.js +1362 -0
  153. metadata +364 -0
@@ -0,0 +1,51 @@
1
+ require '/assets/mercury/mercury.js'
2
+
3
+ describe "Mercury.Palette", ->
4
+
5
+ template 'mercury/palette.html'
6
+
7
+ beforeEach ->
8
+ $.fx.off = true
9
+
10
+ afterEach ->
11
+ @palette = null
12
+ delete(@palette)
13
+
14
+ describe "#build", ->
15
+
16
+ it "builds an element", ->
17
+ @palette = new Mercury.Palette('/evergreen/responses/blank.html', 'foo', {appendTo: '#test', for: $('#button')})
18
+ html = $('<div>').html(@palette.element).html()
19
+ expect(html).toContain('class="mercury-palette mercury-foo-palette loading"')
20
+ expect(html).toContain('style="display:none"')
21
+
22
+ it "appends to any element", ->
23
+ @palette = new Mercury.Palette('/evergreen/responses/blank.html', 'foo', {appendTo: '#palette_container', for: $('#button')})
24
+ expect($('#palette_container .mercury-palette').length).toEqual(1)
25
+
26
+
27
+ describe "observed events", ->
28
+
29
+ beforeEach ->
30
+ @palette = new Mercury.Palette('/evergreen/responses/blank.html', 'foo', {appendTo: '#test', for: $('#button')})
31
+
32
+ it "hides", ->
33
+ @palette.element.css({display: 'block'})
34
+ Mercury.trigger('hide:dialogs')
35
+ expect(@palette.element.css('display')).toEqual('none')
36
+
37
+ it "doesn't hide if it's the same dialog", ->
38
+ @palette.element.css({display: 'block'})
39
+ Mercury.trigger('hide:dialogs', @palette)
40
+ expect(@palette.element.css('display')).toEqual('block')
41
+
42
+
43
+ describe "#position", ->
44
+
45
+ beforeEach ->
46
+ @palette = new Mercury.Palette('/evergreen/responses/blank.html', 'foo', {appendTo: '#test', for: $('#button')})
47
+
48
+ it "positions based on it's button", ->
49
+ @palette.element.css({display: 'block'})
50
+ @palette.position(true)
51
+ expect(@palette.element.offset()).toEqual({top: 62, left: 42})
@@ -0,0 +1,147 @@
1
+ require '/assets/mercury/mercury.js'
2
+
3
+ describe "Mercury.Panel", ->
4
+
5
+ template 'mercury/panel.html'
6
+
7
+ beforeEach ->
8
+ Mercury.displayRect = {top: 20, left: 20, width: 200, height: 200}
9
+ $.fx.off = true
10
+
11
+ afterEach ->
12
+ @panel = null
13
+ delete(@panel)
14
+ $(document).unbind('mercury:resize')
15
+ $(document).unbind('mercury:hide:panels')
16
+
17
+ describe "#build", ->
18
+
19
+ it "builds an element", ->
20
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#test', title: 'foo panel'})
21
+ html = $('<div>').html(@panel.element).html()
22
+ expect(html).toContain('class="mercury-panel loading"')
23
+ expect(html).toContain('style="display:none;"')
24
+ expect(html).toContain('<h1>foo panel</h1><div class="mercury-panel-pane"></div>')
25
+
26
+ it "appends to any element", ->
27
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#panel_container', title: 'foo panel'})
28
+ expect($('#panel_container .mercury-panel').length).toEqual(1)
29
+
30
+
31
+ describe "observed events", ->
32
+
33
+ beforeEach ->
34
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#test', title: 'foo panel', for: $('#button')})
35
+
36
+ describe "custom event: resize", ->
37
+
38
+ it "calls position", ->
39
+ spy = spyOn(Mercury.Panel.prototype, 'position').andCallFake(=>)
40
+ Mercury.trigger('resize')
41
+ expect(spy.callCount).toEqual(1)
42
+
43
+ describe "custom event: hide:panels", ->
44
+
45
+ it "hides", ->
46
+ @panel.element.css({display: 'block'})
47
+ Mercury.trigger('hide:panels')
48
+ expect(@panel.element.css('display')).toEqual('none')
49
+
50
+ it "doesn't hide if it's the same dialog", ->
51
+ @panel.element.css({display: 'block'})
52
+ Mercury.trigger('hide:panels', @panel)
53
+ expect(@panel.element.css('display')).toEqual('block')
54
+
55
+
56
+ describe "#show", ->
57
+
58
+ beforeEach ->
59
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#test', title: 'foo panel'})
60
+
61
+ it "hides other panels and dialogs", ->
62
+ spyOn(Mercury.Panel.prototype, 'position')
63
+ spyOn(Mercury.Panel.prototype, 'appear')
64
+ spy = spyOn(Mercury, 'trigger').andCallFake(=>)
65
+ @panel.show()
66
+ expect(spy.callCount).toEqual(2)
67
+ expect(spy.argsForCall[0]).toEqual(['hide:panels', @panel])
68
+ expect(spy.argsForCall[1]).toEqual(['hide:dialogs', @panel])
69
+
70
+
71
+ describe "#resize", ->
72
+
73
+ beforeEach ->
74
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#panel_container', title: 'foo panel'})
75
+ @panel.element.css({display: 'block'})
76
+ @panel.visible = true
77
+
78
+ it "figures out what size it should be and resizes", ->
79
+ @panel.resize()
80
+ expect(@panel.element.offset()).toEqual({top: 42, left: 84})
81
+ expect(@panel.element.css('display')).toEqual('block')
82
+
83
+ it "calls makeDraggable", ->
84
+ spy = spyOn(Mercury.Panel.prototype, 'makeDraggable').andCallFake(=>)
85
+ @panel.resize()
86
+ expect(spy.callCount).toEqual(1)
87
+
88
+ it "keeps it hidden if it's not supposed to be visible", ->
89
+ @panel.visible = false
90
+ @panel.resize()
91
+ expect(@panel.element.css('display')).toEqual('none')
92
+
93
+
94
+ describe "#position", ->
95
+
96
+ beforeEach ->
97
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#panel_container', title: 'foo panel'})
98
+ @panel.element.css({display: 'block'})
99
+ @panel.visible = true
100
+
101
+ it "positions based on the display rectangle", ->
102
+ @panel.position(true)
103
+ expect(@panel.element.offset()).toEqual({top: 70, left: 122})
104
+ expect(@panel.element.css('display')).toEqual('block')
105
+
106
+ it "calls makeDraggable", ->
107
+ spy = spyOn(Mercury.Panel.prototype, 'makeDraggable').andCallFake(=>)
108
+ @panel.position()
109
+ expect(spy.callCount).toEqual(1)
110
+
111
+ it "keeps it hidden if it's not supposed to be visible", ->
112
+ @panel.visible = false
113
+ @panel.position()
114
+ expect(@panel.element.css('display')).toEqual('none')
115
+
116
+
117
+ describe "#loadContent", ->
118
+
119
+ beforeEach ->
120
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#test', title: 'foo panel'})
121
+
122
+ it "sets loaded to be true", ->
123
+ @panel.loadContent()
124
+ expect(@panel.loaded).toEqual(true)
125
+
126
+ it "removes the loading class from the element", ->
127
+ @panel.loadContent()
128
+ expect(@panel.element.hasClass('loading')).toEqual(false)
129
+
130
+ it "sets the element html to be the data passed to it", ->
131
+ @panel.loadContent('hello world!')
132
+ html = @panel.element.html()
133
+ expect(html).toContain('<h1>foo panel</h1>')
134
+ expect(html).toContain('class="mercury-panel-pane"')
135
+ expect(html).toContain('style="visibility: hidden;"')
136
+ expect(html).toContain('hello world')
137
+
138
+
139
+ describe "#makesDraggable", ->
140
+
141
+ beforeEach ->
142
+ @panel = new Mercury.Panel('/evergreen/resources/panel.html', 'foo', {appendTo: '#test', title: 'foo panel'})
143
+
144
+ it "makes the element draggable", ->
145
+ spy = spyOn($.fn, 'draggable').andCallFake(=>)
146
+ @panel.makeDraggable()
147
+ expect(spy.callCount).toEqual(1)
@@ -0,0 +1,261 @@
1
+ require '/assets/mercury/mercury.js'
2
+
3
+ describe "Mercury.Region", ->
4
+
5
+ template 'mercury/region.html'
6
+
7
+ afterEach ->
8
+ @region = null
9
+ delete(@region)
10
+ $(document).unbind('mercury:mode')
11
+ $(document).unbind('mercury:focus:frame')
12
+ $(document).unbind('mercury:action')
13
+
14
+ describe "constructor", ->
15
+
16
+ beforeEach ->
17
+ @buildSpy = spyOn(Mercury.Region.prototype, 'build').andCallFake(=>)
18
+ @bindEventsSpy = spyOn(Mercury.Region.prototype, 'bindEvents').andCallFake(=>)
19
+ @pushHistorySpy = spyOn(Mercury.Region.prototype, 'pushHistory').andCallFake(=>)
20
+
21
+ it "expects an element and window (for context)", ->
22
+ @region = new Mercury.Region($('#region'), window)
23
+ expect(@region.element.get(0)).toEqual($('#region').get(0))
24
+
25
+ it "accepts options", ->
26
+ @region = new Mercury.Region($('#region'), window, {foo: 'bar'})
27
+ expect(@region.options).toEqual({foo: 'bar'})
28
+
29
+ it "sets variables we need", ->
30
+ @region = new Mercury.Region($('#region'), window, {foo: 'bar'})
31
+ expect(@region.name).toEqual('region')
32
+ expect(@region.history).toBeDefined()
33
+
34
+ it "calls build", ->
35
+ @region = new Mercury.Region($('#region'), window, {foo: 'bar'})
36
+ expect(@buildSpy.callCount).toEqual(1)
37
+
38
+ it "calls bindEvents", ->
39
+ @region = new Mercury.Region($('#region'), window, {foo: 'bar'})
40
+ expect(@bindEventsSpy.callCount).toEqual(1)
41
+
42
+ it "pushes the initial state to the history buffer", ->
43
+ @region = new Mercury.Region($('#region'), window, {foo: 'bar'})
44
+ expect(@pushHistorySpy.callCount).toEqual(1)
45
+
46
+
47
+ describe "#build", ->
48
+
49
+ it "does nothing and is there as an interface"
50
+
51
+
52
+ describe "#focus", ->
53
+
54
+ it "does nothing and is there as an interface"
55
+
56
+
57
+ describe "observed events", ->
58
+
59
+ beforeEach ->
60
+ @region = new Mercury.Region($('#region_with_snippet'), window)
61
+
62
+ describe "custom event: mode", ->
63
+
64
+ it "calls togglePreview if the mode is preview", ->
65
+ spy = spyOn(Mercury.Region.prototype, 'togglePreview').andCallFake(=>)
66
+ Mercury.trigger('mode', {mode: 'foo'})
67
+ expect(spy.callCount).toEqual(0)
68
+ Mercury.trigger('mode', {mode: 'preview'})
69
+ expect(spy.callCount).toEqual(1)
70
+
71
+ describe "custom event: focus:frame", ->
72
+
73
+ beforeEach ->
74
+ @focusSpy = spyOn(Mercury.Region.prototype, 'focus').andCallFake(=>)
75
+
76
+ it "does nothing if in preview mode", ->
77
+ @region.previewing = true
78
+ Mercury.trigger('focus:frame', {region: @region})
79
+ expect(@focusSpy.callCount).toEqual(0)
80
+
81
+ it "does nothing if it's not active region", ->
82
+ Mercury.region = {}
83
+ Mercury.trigger('focus:frame', {region: @region})
84
+ expect(@focusSpy.callCount).toEqual(0)
85
+
86
+ it "calls focus", ->
87
+ Mercury.region = @region
88
+ Mercury.trigger('focus:frame', {region: @region})
89
+ expect(@focusSpy.callCount).toEqual(1)
90
+
91
+ describe "custom event: action", ->
92
+
93
+ beforeEach ->
94
+ @execCommandSpy = spyOn(Mercury.Region.prototype, 'execCommand').andCallFake(=>)
95
+
96
+ it "does nothing if in preview mode", ->
97
+ @region.previewing = true
98
+ Mercury.trigger('action', {action: 'foo', value: 'bar'})
99
+ expect(@execCommandSpy.callCount).toEqual(0)
100
+
101
+ it "does nothing if it's not active region", ->
102
+ Mercury.region = {}
103
+ Mercury.trigger('action', {action: 'foo', value: 'bar'})
104
+ expect(@execCommandSpy.callCount).toEqual(0)
105
+
106
+ it "calls execCommand with the action and options", ->
107
+ Mercury.region = @region
108
+ Mercury.trigger('action', {action: 'foo', value: 'bar'})
109
+ expect(@execCommandSpy.callCount).toEqual(1)
110
+ expect(@execCommandSpy.argsForCall[0]).toEqual(['foo', {action: 'foo', value: 'bar'}])
111
+
112
+ describe "mouseover", ->
113
+
114
+ beforeEach ->
115
+ @triggerSpy = spyOn(Mercury, 'trigger').andCallFake(=>)
116
+
117
+ it "does nothing if in preview mode", ->
118
+ @region.previewing = true
119
+ jasmine.simulate.mousemove($('#region_with_snippet .mercury-snippet').get(0))
120
+ expect(@triggerSpy.callCount).toEqual(0)
121
+
122
+ it "does nothing if it's not the active region", ->
123
+ Mercury.region = {}
124
+ jasmine.simulate.mousemove($('#region_with_snippet .mercury-snippet').get(0))
125
+ expect(@triggerSpy.callCount).toEqual(0)
126
+
127
+ it "shows the snippet toolbar if a snippet was moused over", ->
128
+ Mercury.region = @region
129
+ jasmine.simulate.mousemove($('#region_with_snippet .mercury-snippet').get(0))
130
+ expect(@triggerSpy.callCount).toEqual(1)
131
+ expect(@triggerSpy.argsForCall[0][0]).toEqual('show:toolbar')
132
+
133
+ describe "mouseout", ->
134
+
135
+ beforeEach ->
136
+ @triggerSpy = spyOn(Mercury, 'trigger').andCallFake(=>)
137
+
138
+ it "does nothing if previewing", ->
139
+ @region.previewing = true
140
+ jasmine.simulate.mouseout(@region.element.get(0))
141
+ expect(@triggerSpy.callCount).toEqual(0)
142
+
143
+ it "hides the snippet toolbar", ->
144
+ jasmine.simulate.mouseout(@region.element.get(0))
145
+ expect(@triggerSpy.callCount).toEqual(1)
146
+ expect(@triggerSpy.argsForCall[0]).toEqual(['hide:toolbar', {type: 'snippet', immediately: false}])
147
+
148
+
149
+ describe "#html", ->
150
+
151
+ beforeEach ->
152
+ @region = new Mercury.Region($('#region_with_snippet'), window)
153
+
154
+ describe "getting html", ->
155
+
156
+ it "returns the html of the element", ->
157
+ html = @region.html()
158
+ expect(html).toEqual('contents<div class="mercury-snippet" data-snippet="snippet_1" data-version="1">snippet</div>')
159
+
160
+ it "replaces snippet content with an indentifier if asked", ->
161
+ html = @region.html(null, true)
162
+ expect(html).toEqual('contents<div class="mercury-snippet" data-snippet="snippet_1">[snippet_1]</div>')
163
+
164
+ describe "setting html", ->
165
+
166
+ it "sets the value of the html", ->
167
+ @region.html('new html')
168
+ expect($('#region_with_snippet').html()).toEqual('new html')
169
+
170
+
171
+ describe "#togglePreview", ->
172
+
173
+ beforeEach ->
174
+ @region = new Mercury.Region($('#region'), window)
175
+ Mercury.region = @region
176
+ @focusSpy = spyOn(Mercury.Region.prototype, 'focus').andCallFake(=>)
177
+ @triggerSpy = spyOn(Mercury, 'trigger').andCallFake(=>)
178
+
179
+ describe "when not previewing", ->
180
+
181
+ beforeEach ->
182
+ @region.togglePreview()
183
+
184
+ it "sets previewing to true", ->
185
+ expect(@region.previewing).toEqual(true)
186
+
187
+ it "swaps classes on the element", ->
188
+ expect(@region.element.hasClass('mercury-region')).toEqual(false)
189
+ expect(@region.element.hasClass('mercury-region-preview')).toEqual(true)
190
+
191
+ it "triggers a blur event", ->
192
+ expect(@triggerSpy.callCount).toEqual(1)
193
+ expect(@triggerSpy.argsForCall[0]).toEqual(['region:blurred', {region: @region}])
194
+
195
+ describe "when previewing", ->
196
+
197
+ beforeEach ->
198
+ @region.previewing = true
199
+ @region.togglePreview()
200
+
201
+ it "sets previewing to false", ->
202
+ expect(@region.previewing).toEqual(false)
203
+
204
+ it "swaps classes on the element", ->
205
+ expect(@region.element.hasClass('mercury-region-preview')).toEqual(false)
206
+ expect(@region.element.hasClass('mercury-region')).toEqual(true)
207
+
208
+ it "calls focus if it's the active region", ->
209
+ expect(@focusSpy.callCount).toEqual(1)
210
+
211
+
212
+ describe "#execCommand", ->
213
+
214
+ beforeEach ->
215
+ Mercury.changes = false
216
+ @region = new Mercury.Region($('#region'), window)
217
+
218
+ it "calls focus", ->
219
+ spy = spyOn(Mercury.Region.prototype, 'focus').andCallFake(=>)
220
+ @region.execCommand('foo')
221
+ expect(spy.callCount).toEqual(1)
222
+
223
+ it "pushes to the history (unless the action is redo)", ->
224
+ spy = spyOn(Mercury.Region.prototype, 'pushHistory').andCallFake(=>)
225
+ @region.execCommand('redo')
226
+ expect(spy.callCount).toEqual(0)
227
+ @region.execCommand('foo')
228
+ expect(spy.callCount).toEqual(1)
229
+
230
+ it "tells Mercury that changes have been made", ->
231
+ @region.execCommand('foo')
232
+ expect(Mercury.changes).toEqual(true)
233
+
234
+
235
+ describe "#pushHistory", ->
236
+
237
+ beforeEach ->
238
+ Mercury.changes = false
239
+ @region = new Mercury.Region($('#region'), window)
240
+
241
+ it "pushes the current content (html) of the region to the history buffer", ->
242
+ spy = spyOn(@region.history, 'push').andCallFake(=>)
243
+ @region.pushHistory('foo')
244
+ expect(spy.callCount).toEqual(1)
245
+
246
+
247
+ describe "#snippets", ->
248
+
249
+ it "does nothing and is there as an interface", ->
250
+
251
+
252
+ describe "#serialize", ->
253
+
254
+ beforeEach ->
255
+ @region = new Mercury.Region($('#region'), window)
256
+
257
+ it "returns an object with it's type, value, and snippets", ->
258
+ serialized = @region.serialize()
259
+ expect(serialized.type).toEqual('region')
260
+ expect(serialized.value).toEqual('contents')
261
+ expect(serialized.snippets).toEqual({})