mercury-rails 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/POST_INSTALL +12 -6
  2. data/app/assets/javascripts/{mercury/dependencies/jquery-1.7.js → jquery-1.7.js} +0 -0
  3. data/app/assets/javascripts/mercury.js +1 -3
  4. data/app/assets/javascripts/mercury/dependencies/jquery.additions.js +103 -13
  5. data/app/assets/javascripts/mercury/dialogs/forecolor.js.coffee +1 -1
  6. data/app/assets/javascripts/mercury/mercury.js.coffee +1 -1
  7. data/app/assets/javascripts/mercury/modals/insertlink.js.coffee +13 -4
  8. data/app/assets/javascripts/mercury/page_editor.js.coffee +19 -8
  9. data/app/assets/javascripts/mercury/region.js.coffee +0 -1
  10. data/app/assets/javascripts/mercury/regions/full.coffee +11 -2
  11. data/app/assets/javascripts/mercury/snippet.js.coffee +2 -2
  12. data/app/assets/stylesheets/mercury/bootstrap-overrides.css +1 -0
  13. data/app/assets/stylesheets/mercury/dialog.css +1 -0
  14. data/app/helpers/mercury_helper.rb +7 -0
  15. data/app/views/layouts/mercury.html.erb +10 -20
  16. data/app/views/mercury/snippets/example/options.html.erb +23 -8
  17. data/config/routes.rb +9 -0
  18. data/features/loading/loading.feature +1 -1
  19. data/features/regions/full/basic_editing.feature +21 -19
  20. data/features/regions/full/inserting_snippets.feature +2 -3
  21. data/lib/generators/mercury/install/images/images_generator.rb +2 -2
  22. data/lib/mercury/engine.rb +2 -0
  23. data/lib/mercury/version.rb +1 -1
  24. data/spec/dummy/app/views/layouts/mercury.html.erb +28 -0
  25. data/spec/javascripts/mercury/dialogs/forecolor_spec.js.coffee +1 -1
  26. data/spec/javascripts/mercury/page_editor_spec.js.coffee +4 -4
  27. data/spec/javascripts/mercury/snippet_spec.js.coffee +2 -2
  28. data/spec/javascripts/spec_helper.js +1 -0
  29. metadata +8 -8
  30. data/spec/dummy/public/distro.html +0 -349
  31. data/spec/dummy/public/frame.html +0 -15
data/POST_INSTALL CHANGED
@@ -4,12 +4,18 @@ and other useful info can be found at: https://github.com/jejacks0n/mercury
4
4
 
5
5
  Here's a post install checklist:
6
6
 
7
- * Setup the database for image processing (ActiveRecord only) by running:
7
+ * Adjust your application.js & css files to not `require_tree .`
8
8
 
9
- rake mercury_engine:install:migrations
10
- rake db:migrate
9
+ * Learn about, and change configurations in app/assets/javascripts/mercury.js.
11
10
 
12
- * Learn about, and make configuration adjustments in the mercury.js file.
11
+ * If installed, you can make changes to the provided layout and css files too.
13
12
 
14
- * If installed, check out mercury.html.erb and mercury_overrides.css for more
15
- customization info.
13
+ * If you want image processing and uploading (using paperclip by default):
14
+
15
+ rails g mercury:install:images (use --orm=mongoid for MongoDB)
16
+ bundle
17
+ rake db:migrate (if using ActiveRecord)
18
+
19
+ * For a basic example of authentication for Mercury, install the example:
20
+
21
+ rails g mercury:install:authentication
@@ -2,10 +2,8 @@
2
2
  * Mercury Editor is a CoffeeScript and jQuery based WYSIWYG editor. Documentation and other useful information can be
3
3
  * found at https://github.com/jejacks0n/mercury
4
4
  *
5
- *= require_self
6
- *
7
5
  * Minimum jQuery requirements are 1.7
8
- *= require mercury/dependencies/jquery-1.7
6
+ *= require_self
9
7
  *
10
8
  * You can include the Rails jQuery ujs script here to get some nicer behaviors in modals, panels and lightviews when
11
9
  * using :remote => true within the contents rendered in them.
@@ -1,23 +1,113 @@
1
1
  /*
2
- * jQuery serializeObject Plugin
2
+ * jQuery serializeObject Plugin: https://github.com/fojas/jQuery-serializeObject
3
3
  *
4
4
  */
5
- (function($) {
6
- $.fn.serializeObject = function() {
7
- var o = {};
8
- var a = this.serializeArray();
9
- jQuery.each(a, function() {
10
- if (o[this.name] !== undefined) {
11
- if (!o[this.name].push) o[this.name] = [o[this.name]];
12
- o[this.name].push(this.value || '');
13
- } else {
14
- o[this.name] = this.value || '';
5
+ !function($){
6
+ $.serializeObject = function(obj){
7
+ var o={},lookup=o,a = obj;
8
+ $.each(a,function(){
9
+ var named = this.name.replace(/\[([^\]]+)?\]/g,',$1').split(','),
10
+ cap = named.length - 1,
11
+ i = 0;
12
+ for(;i<cap;i++) {
13
+ // move down the tree - create objects or array if necessary
14
+ if(lookup.push){ // this is an array, add values instead of setting them
15
+ // push an object if this is an empty array or we are about to overwrite a value
16
+ if( !lookup[lookup.length -1] // this is an empty array
17
+ || lookup[lookup.length -1].constructor !== Object //current value is not a hash
18
+ || lookup[lookup.length -1][named[i+1]] !== undefined //current item is already set
19
+ ){
20
+ lookup.push({});
21
+ }
22
+ lookup = lookup[lookup.length -1];
23
+ } else {
24
+ lookup = lookup[named[i]] = lookup[named[i]] || (named[i+1]==""?[]:{});
25
+ }
15
26
  }
27
+ if(lookup.push){
28
+ lookup.push(this.value);
29
+ }else{
30
+ lookup[named[cap]]=this.value;
31
+ }
32
+ lookup = o;
16
33
  });
17
34
  return o;
18
35
  };
19
- })(jQuery);
20
36
 
37
+ $.deserializeObject = function deserializeObject(json,arr,prefix){
38
+ var i,j,thisPrefix,objType;
39
+ arr = arr || [];
40
+ if(Object.prototype.toString.call(json) ==='[object Object]'){
41
+ for(i in json){
42
+ thisPrefix = prefix ? [prefix,'[',i,']'].join('') : i;
43
+ if(json.hasOwnProperty(i)){
44
+ objType = Object.prototype.toString.call(json[i])
45
+ if(objType === '[object Array]'){
46
+ for(j = 0,jsonLen = json[i].length;j<jsonLen;j++){
47
+ deserializeObject(json[i][j],arr,thisPrefix+'[]');
48
+ }
49
+ }else if(objType === '[object Object]'){
50
+ deserializeObject(json[i],arr,thisPrefix);
51
+ }else {
52
+ arr.push({
53
+ name : thisPrefix,
54
+ value : json[i]
55
+ });
56
+ }
57
+ }
58
+ }
59
+ } else {
60
+ arr.push({
61
+ name : prefix,
62
+ value : json
63
+ });
64
+ }
65
+ return arr;
66
+ }
67
+
68
+ var check = function(){
69
+ // older versions of jQuery do not have prop
70
+ var propExists = !!$.fn.prop;
71
+ return function(obj,checked){
72
+ if(propExists) obj.prop('checked',checked);
73
+ else obj.attr('checked', (checked ? 'checked' : null ));
74
+ };
75
+ }();
76
+
77
+ $.applySerializedArray = function(form,obj){
78
+ var $form = $(form).find('input,select,textarea'), el;
79
+ check($form.filter(':checked'),false)
80
+ for(var i = obj.length;i--;){
81
+ el = $form.filter("[name='"+obj[i].name+"']");
82
+ if(el.filter(':checkbox').length){
83
+ if(el.val() == obj[i].value) check(el.filter(':checkbox'),true);
84
+ }else if(el.filter(':radio').length){
85
+ check(el.filter("[value='"+obj[i].value+"']"),true)
86
+ } else {
87
+ el.val(obj[i].value);
88
+ }
89
+ }
90
+ };
91
+
92
+ $.applySerializedObject = function(form, obj){
93
+ $.applySerializedArray(form,$.deserializeObject(obj));
94
+ };
95
+
96
+ $.fn.serializeObject = $.fn.serializeObject || function(){
97
+ return $.serializeObject(this.serializeArray());
98
+ };
99
+
100
+ $.fn.applySerializedObject = function(obj){
101
+ $.applySerializedObject(this,obj);
102
+ return this;
103
+ };
104
+
105
+ $.fn.applySerializedArray = function(obj){
106
+ $.applySerializedArray(this,obj);
107
+ return this;
108
+ };
109
+
110
+ }(jQuery);
21
111
  /*
22
112
  * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
23
113
  *
@@ -203,4 +293,4 @@ jQuery.extend(jQuery.easing, {
203
293
  return this;
204
294
  });
205
295
  };
206
- })(jQuery);
296
+ })(jQuery);
@@ -1,6 +1,6 @@
1
1
  @Mercury.dialogHandlers.foreColor = ->
2
2
  @element.find('.picker, .last-picked').on 'click', (event) =>
3
- color = jQuery(event.target).css('background-color')
3
+ color = jQuery(event.target).css('background-color').toHex()
4
4
  @element.find('.last-picked').css({background: color})
5
5
  @button.css({backgroundColor: color})
6
6
  Mercury.trigger('action', {action: 'foreColor', value: color})
@@ -34,7 +34,7 @@
34
34
  #
35
35
  @Mercury ||= {}
36
36
  jQuery.extend @Mercury,
37
- version: '0.7.1'
37
+ version: '0.8.0'
38
38
 
39
39
  # Mercury object namespaces
40
40
  Regions: Mercury.Regions || {}
@@ -1,6 +1,9 @@
1
1
  @Mercury.modalHandlers.insertLink = {
2
2
 
3
3
  initialize: ->
4
+ @editing = false
5
+ @content = null
6
+
4
7
  # make the inputs work with the radio buttons
5
8
  @element.find('.control-label input').on('click', @onLabelChecked)
6
9
  @element.find('.controls .optional, .controls .required').on('focus', @onInputFocused)
@@ -32,13 +35,19 @@
32
35
  @element.find('#link_text').val(selection.textContent()) if selection.textContent
33
36
 
34
37
  # if we're editing a link prefill the information
38
+
35
39
  a = selection.commonAncestor(true).closest('a') if selection && selection.commonAncestor
36
- return false unless a && a.length
37
- @editing = a
40
+ img = /<img/.test(selection.htmlContent()) if selection.htmlContent
41
+ return false unless img || a && a.length
38
42
 
39
43
  # don't allow changing the content on edit
40
44
  @element.find('#link_text_container').hide()
41
45
 
46
+ @content = selection.htmlContent() if img
47
+
48
+ return false unless a && a.length
49
+ @editing = a
50
+
42
51
  # fill in the external url or bookmark select based on what it looks like
43
52
  if a.attr('href') && a.attr('href').indexOf('#') == 0
44
53
  bookmarkSelect = @element.find('#link_existing_bookmark')
@@ -106,7 +115,7 @@
106
115
  el = @element.find("#link_#{type}")
107
116
  @addInputError(el, "can't be blank") unless el.val()
108
117
 
109
- unless @editing
118
+ if !@editing && !@content
110
119
  el = @element.find('#link_text')
111
120
  @addInputError(el, "can't be blank") unless el.val()
112
121
 
@@ -133,7 +142,7 @@
133
142
  else
134
143
  attrs['target'] = target if target
135
144
 
136
- value = {tagName: 'a', attrs: attrs, content: content}
145
+ value = {tagName: 'a', attrs: attrs, content: @content || content}
137
146
 
138
147
  if @editing
139
148
  Mercury.trigger('action', {action: 'replaceLink', value: value, node: @editing.get(0)})
@@ -3,7 +3,7 @@ class @Mercury.PageEditor
3
3
  # options
4
4
  # saveStyle: 'form', or 'json' (defaults to json)
5
5
  # saveDataType: 'xml', 'json', 'jsonp', 'script', 'text', 'html' (defaults to json)
6
- # saveMethod: 'POST', or 'PUT', create or update actions on save (defaults to POST)
6
+ # saveMethod: 'POST', or 'PUT', create or update actions on save (defaults to PUT)
7
7
  # visible: boolean, if the interface should start visible or not (defaults to true)
8
8
  constructor: (@saveUrl = null, @options = {}) ->
9
9
  throw Mercury.I18n('Mercury.PageEditor can only be instantiated once.') if window.mercuryInstance
@@ -21,7 +21,7 @@ class @Mercury.PageEditor
21
21
  initializeInterface: ->
22
22
  @focusableElement = jQuery('<input>', {class: 'mercury-focusable', type: 'text'}).appendTo(@options.appendTo ? 'body')
23
23
 
24
- @iframe = jQuery('<iframe>', {id: 'mercury_iframe', class: 'mercury-iframe', seamless: 'true', frameborder: '0', src: 'about:blank'})
24
+ @iframe = jQuery('<iframe>', {id: 'mercury_iframe', class: 'mercury-iframe', frameborder: '0', src: 'about:blank'})
25
25
  @iframe.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
26
26
 
27
27
  @toolbar = new Mercury.Toolbar(@options)
@@ -221,14 +221,21 @@ class @Mercury.PageEditor
221
221
  save: (callback) ->
222
222
  url = @saveUrl ? Mercury.saveUrl ? @iframeSrc()
223
223
  data = @serialize()
224
+ data = {content: data}
225
+
226
+ if @options.saveMethod == 'POST'
227
+ method = 'POST'
228
+ else
229
+ method = 'PUT'
230
+ data['_method'] = method
231
+
224
232
  Mercury.log('saving', data)
225
- data = jQuery.toJSON(data) unless @options.saveStyle == 'form'
226
- method = 'PUT' if @options.saveMethod == 'PUT'
227
- jQuery.ajax url, {
233
+
234
+ options = {
228
235
  headers: Mercury.ajaxHeaders()
229
- type: method || 'POST'
230
- dataType: @options.saveDataType,
231
- data: {content: data, _method: method}
236
+ type: method
237
+ dataType: @options.saveDataType
238
+ data: data
232
239
  success: =>
233
240
  Mercury.changes = false
234
241
  Mercury.trigger('saved')
@@ -237,6 +244,10 @@ class @Mercury.PageEditor
237
244
  Mercury.trigger('save_failed', response)
238
245
  Mercury.notify('Mercury was unable to save to the url: %s', url)
239
246
  }
247
+ if @options.saveStyle != 'form'
248
+ options['data'] = jQuery.toJSON(data)
249
+ options['contentType'] = 'application/json'
250
+ jQuery.ajax url, options
240
251
 
241
252
 
242
253
  serialize: ->
@@ -88,7 +88,6 @@ class @Mercury.Region
88
88
  for element in @element.find('[data-snippet]')
89
89
  snippet = Mercury.Snippet.find(jQuery(element).data('snippet'))
90
90
  continue unless snippet
91
- snippet.setVersion(jQuery(element).data('version'))
92
91
  snippets[snippet.identity] = snippet.serialize()
93
92
  return snippets
94
93
 
@@ -216,7 +216,9 @@ class @Mercury.Regions.Full extends Mercury.Region
216
216
  element.contentEditable = false
217
217
  element = jQuery(element)
218
218
  if snippet = Mercury.Snippet.find(element.data('snippet'))
219
- unless element.data('version')
219
+ if element.data('version')
220
+ snippet.setVersion(element.data('version'))
221
+ else
220
222
  try
221
223
  version = parseInt(element.html().match(/\/(\d+)\]/)[1])
222
224
  if version
@@ -365,6 +367,7 @@ class @Mercury.Regions.Full extends Mercury.Region
365
367
  sanitize: (sanitizer) ->
366
368
  # always remove nested regions
367
369
  sanitizer.find("[#{Mercury.config.regions.attribute}]").remove()
370
+ sanitizer.find('[src*="webkit-fake-url://"]').remove()
368
371
 
369
372
  if Mercury.config.pasting.sanitize
370
373
  switch Mercury.config.pasting.sanitize
@@ -490,7 +493,13 @@ class Mercury.Regions.Full.Selection
490
493
 
491
494
 
492
495
  textContent: ->
493
- return @range.cloneContents().textContent
496
+ return @content().textContent
497
+
498
+
499
+ htmlContent: ->
500
+ content = @content()
501
+ return jQuery('<div>').html(content).html()
502
+ return null
494
503
 
495
504
 
496
505
  content: ->
@@ -100,8 +100,8 @@ class @Mercury.Snippet
100
100
  setVersion: (version = null) ->
101
101
  version = parseInt(version)
102
102
  if version && @history.stack[version - 1]
103
- @version = version - 1
104
- @options = @history.stack[@version]
103
+ @version = version
104
+ @options = @history.stack[version - 1]
105
105
  return true
106
106
  return false
107
107
 
@@ -18,6 +18,7 @@ legend {
18
18
  display: block;
19
19
  position: relative;
20
20
  margin-left: 10px;
21
+ margin-bottom: 0;
21
22
  font-weight: bold;
22
23
  width: auto;
23
24
  padding: 0;
@@ -201,6 +201,7 @@
201
201
  }
202
202
  .mercury-snippet-panel ul li img {
203
203
  float: left;
204
+ cursor: move;
204
205
  }
205
206
  .mercury-snippet-panel ul li h4,
206
207
  .mercury-snippet-panel ul li .description {
@@ -0,0 +1,7 @@
1
+ module MercuryHelper
2
+
3
+ def mercury_edit_path(path = nil)
4
+ mercury_engine.mercury_editor_path(path.nil? ? request.path.gsub(/^\/\/?(editor)?/, '') : path)
5
+ end
6
+
7
+ end
@@ -4,30 +4,20 @@
4
4
  <meta name="viewport" content="width=device-width, maximum-scale=1.0, initial-scale=1.0">
5
5
  <%= csrf_meta_tags %>
6
6
  <title>Mercury Editor</title>
7
- <%= stylesheet_link_tag 'mercury', 'mercury_overrides' %>
8
- <%= javascript_include_tag 'mercury', 'mercury_overrides' %>
7
+ <%= stylesheet_link_tag 'mercury' %>
8
+ <%= javascript_include_tag 'jquery-1.7', 'mercury' %>
9
9
  </head>
10
10
  <body>
11
11
  <script type="text/javascript">
12
- var saveUrl = null; // Set to the url that you want to save any given page to.
13
- var options = {
14
- saveStyle: null, // 'form', or 'json' (default json)
15
- saveMethod: null, // 'POST', or 'PUT', (create, vs. update -- default POST)
16
- visible: null // if the interface should start visible or not (default true)
17
- };
12
+ // Set to the url that you want to save any given page to, leave null for default handling.
13
+ var saveUrl = null;
18
14
 
19
- <!-- Mix in any configurations provided through Rails.application.config.mercury_config -->
20
- <% if Rails.application.config.respond_to?(:mercury_config) %>
21
- jQuery.extend(Mercury.config, <%= Rails.application.config.mercury_config.to_json.html_safe %>);
22
- <% end -%>
23
-
24
- <!-- Mix in any options for PageEditor provided through Rails.application.config.mercury_page_editor_config -->
25
- <% if Rails.application.config.respond_to?(:mercury_page_editor_config) %>
26
- jQuery.extend(options, <%= Rails.application.config.mercury_page_editor_config.to_json.html_safe %>);
27
- <% end -%>
28
-
29
- <!-- Instantiate the PageEditor -->
30
- new Mercury.PageEditor(saveUrl, options);
15
+ // Instantiate the PageEditor
16
+ new Mercury.PageEditor(saveUrl, {
17
+ saveStyle: null, // 'form', or 'json' (default json)
18
+ saveMethod: null, // 'PUT', or 'POST', (create, vs. update -- default PUT)
19
+ visible: true // boolean - if the interface should start visible or not
20
+ });
31
21
  </script>
32
22
  </body>
33
23
  </html>
@@ -1,15 +1,30 @@
1
- <%= form_for 'options', {html: {class: 'form-horizontal', style: 'width:600px'}} do |f| %>
2
- <div class="form-inputs">
3
- <label for="options_first_name">First Name</label>
4
- <input id="options_first_name" name="options[first_name]" type="text" value="<%= @options[:first_name] %>"/>
1
+ <%= form_for 'options', {html: {class: 'form-horizontal', style: 'width:615px'}} do |f| %>
2
+
3
+ <div class="form-inputs mercury-display-pane-container">
4
+
5
+ <fieldset>
6
+ <div class="control-group string optional">
7
+ <label class="string optional control-label" for="options_first_name">First Name</label>
8
+ <div class="controls">
9
+ <input class="span6 string optional" id="options_first_name" name="options[first_name]" size="50" type="text" value="<%= @options[:first_name] %>">
10
+ </div>
11
+ </div>
12
+ </fieldset>
13
+
5
14
  <fieldset>
6
15
  <legend>Options</legend>
7
- <label class="label" for="options_favorite_beer">Favorite Beer</label>
8
- <input id="options_favorite_beer" name="options[favorite_beer]" type="text" value="<%= @options[:favorite_beer] %>"/>
16
+ <div class="control-group string optional">
17
+ <label class="string optional control-label" for="options_favorite_beer">Favorite Beer</label>
18
+ <div class="controls">
19
+ <input class="span6 string optional" id="options_favorite_beer" name="options[favorite_beer]" size="50" type="text" value="<%= @options[:favorite_beer] %>">
20
+ </div>
21
+ </div>
9
22
  </fieldset>
23
+
10
24
  </div>
11
25
 
12
- <div class="form-actions">
13
- <input name="commit" type="submit" value="Insert Snippet"/>
26
+ <div class="form-actions mercury-display-controls">
27
+ <input class="btn btn-primary" name="commit" type="submit" value="Insert Snippet"/>
14
28
  </div>
29
+
15
30
  <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ Mercury::Engine.routes.draw do
2
+ match '/editor(/*requested_uri)' => "mercury#edit", :as => :mercury_editor
3
+
4
+ scope '/mercury' do
5
+ match ':type/:resource' => "mercury#resource"
6
+ match 'snippets/:name/options' => "mercury#snippet_options"
7
+ match 'snippets/:name/preview' => "mercury#snippet_preview"
8
+ end
9
+ end
@@ -21,5 +21,5 @@ Feature:
21
21
  # Latest selenium webdriver seems to consider the lightview hidden
22
22
  @use_hidden_elements
23
23
  Scenario: A user can expect to see the status bar
24
- Then I should see "Mercury Editor v0.7.1" within the statusbar
24
+ Then I should see "Mercury Editor v0.8.0" within the statusbar
25
25
 
@@ -8,10 +8,10 @@ Feature:
8
8
  Given I am on an editable page
9
9
  And the editor won't prompt when leaving the page
10
10
 
11
- # Scenario: A user can expect all this!
11
+ Scenario: A user can expect all this!
12
12
 
13
13
 
14
- Scenario: A user can set and unset bold content
14
+ Scenario: A user can set and unset bold content
15
15
  Given the content of the full region is simple content
16
16
  And I make a selection
17
17
 
@@ -22,7 +22,7 @@ Feature:
22
22
  Then the contents of the full region should be "this is <span>simple</span> <b>content</b>"
23
23
 
24
24
 
25
- Scenario: A user can italicize content
25
+ Scenario: A user can italicize content
26
26
  Given the content of the full region is simple content
27
27
  And I make a selection
28
28
 
@@ -33,7 +33,7 @@ Feature:
33
33
  Then the contents of the full region should be "this is <span>simple</span> <b>content</b>"
34
34
 
35
35
 
36
- Scenario: A user can overline content
36
+ Scenario: A user can overline content
37
37
  Given the content of the full region is simple content
38
38
  And I make a selection
39
39
 
@@ -42,7 +42,7 @@ Feature:
42
42
  # doesn't remove overlines
43
43
 
44
44
 
45
- Scenario: A user can strikeout content
45
+ Scenario: A user can strikeout content
46
46
  Given the content of the full region is simple content
47
47
  And I make a selection
48
48
 
@@ -52,7 +52,8 @@ Feature:
52
52
  When I click on the strikethrough editor button
53
53
  Then the contents of the full region should be "this is <span>simple</span> <b>content</b>"
54
54
 
55
- Scenario: A user can underline content
55
+
56
+ Scenario: A user can underline content
56
57
  Given the content of the full region is simple content
57
58
  And I make a selection
58
59
 
@@ -63,7 +64,7 @@ Feature:
63
64
  Then the contents of the full region should be "this is <span>simple</span> <b>content</b>"
64
65
 
65
66
 
66
- Scenario: A user can make content superscript
67
+ Scenario: A user can make content superscript
67
68
  Given the content of the full region is simple content
68
69
  And I make a selection
69
70
 
@@ -74,7 +75,7 @@ Feature:
74
75
  Then the contents of the full region should be "this is <span>simple</span> <b>content</b>"
75
76
 
76
77
 
77
- Scenario: A user can make content subscript
78
+ Scenario: A user can make content subscript
78
79
  Given the content of the full region is simple content
79
80
  And I make a selection
80
81
 
@@ -85,7 +86,7 @@ Feature:
85
86
  Then the contents of the full region should be "this is <span>simple</span> <b>content</b>"
86
87
 
87
88
 
88
- Scenario: A user can justify content to the left, center, right, or fully justified
89
+ Scenario: A user can justify content to the left, center, right, or fully justified
89
90
  # firefox: this isn't possible on the first line due to a bug in gecko, so we have special content for it
90
91
  Given the content of the full region has justifiable content
91
92
  And I make a selection
@@ -103,7 +104,7 @@ Feature:
103
104
  Then the contents of the full region should be "<div>first line</div><br><div align='justify'>this is <span>justifiable</span><b>content</b></div>"
104
105
 
105
106
 
106
- Scenario: A user can make an unordered list
107
+ Scenario: A user can make an unordered list
107
108
  Given the content of the full region is simple content
108
109
  And I make a selection
109
110
 
@@ -112,7 +113,8 @@ Feature:
112
113
 
113
114
  # todo: we should test enter and tab, and shift+tab in advanced editing
114
115
 
115
- Scenario: A user can make an ordered list
116
+
117
+ Scenario: A user can make an ordered list
116
118
  Given the content of the full region is simple content
117
119
  And I make a selection
118
120
 
@@ -122,7 +124,7 @@ Feature:
122
124
  # todo: we should test enter and tab, and shift+tab in advanced editing
123
125
 
124
126
 
125
- Scenario: A user can indent and outdent content
127
+ Scenario: A user can indent and outdent content
126
128
  # firefox: this isn't possible on the first line due to a bug in gecko, so we have special content for it
127
129
  Given the content of the full region has justifiable content
128
130
  And I make a selection
@@ -140,7 +142,7 @@ Feature:
140
142
  Then the contents of the full region should be "<div>first line</div><br>this is <span>justifiable</span><b>content</b>"
141
143
 
142
144
 
143
- Scenario: A user can insert horizontal rules
145
+ Scenario: A user can insert horizontal rules
144
146
  Given the content of the full region is simple content
145
147
  And I make a selection
146
148
 
@@ -151,7 +153,7 @@ Feature:
151
153
  Then the contents of the full region should be "this is&nbsp;<hr size='2' width='100%'><hr size='2' width='100%'> <b>content</b>"
152
154
 
153
155
 
154
- Scenario: A user can clean/remove formatting on their selection
156
+ Scenario: A user can clean/remove formatting on their selection
155
157
  Given the content of the full region has wrapped content
156
158
  And I make a selection
157
159
 
@@ -159,7 +161,7 @@ Feature:
159
161
  Then the contents of the full region should be "this is wrapped content"
160
162
 
161
163
 
162
- Scenario: A user can wrap content within predefined styles
164
+ Scenario: A user can wrap content within predefined styles
163
165
  Given the content of the full region is simple content
164
166
  And I make a selection
165
167
 
@@ -168,7 +170,7 @@ Feature:
168
170
  Then the contents of the full region should be "this is <span class='red'><span>simple</span></span> <b>content</b>"
169
171
 
170
172
 
171
- Scenario: A user can wrap content in formatted block tags
173
+ Scenario: A user can wrap content in formatted block tags
172
174
  Given the content of the full region is simple content
173
175
  And I make a selection
174
176
 
@@ -177,7 +179,7 @@ Feature:
177
179
  Then the contents of the full region should be "<h2>this is <span>simple</span> <b>content</b></h2>"
178
180
 
179
181
 
180
- Scenario: A user can set the background color of a selection
182
+ Scenario: A user can set the background color of a selection
181
183
  Given the content of the full region is simple content
182
184
  And I make a selection
183
185
 
@@ -186,11 +188,11 @@ Feature:
186
188
  Then the contents of the full region should be "this is <span style='background-color:#FF0000'><span>simple</span></span> <b>content</b>"
187
189
 
188
190
 
189
- Scenario: A user can set the foreground color
191
+ Scenario: A user can set the foreground color
190
192
  Given the content of the full region is simple content
191
193
  And I make a selection
192
194
 
193
195
  When I click on the foreground color editor palette
194
196
  And click on the color red
195
- Then the contents of the full region should be "this is <font color='rgb(255, 0, 0)'><span>simple</span></font> <b>content</b>"
197
+ Then the contents of the full region should be "this is <font color='#FF0000'><span>simple</span></font> <b>content</b>"
196
198
 
@@ -78,9 +78,8 @@ Feature:
78
78
  Then the contents of the full region should be "<div data-version='2' data-snippet='snippet_42' class='example-snippet' contenteditable='false'><strong>Jeremy</strong> likes Stella</div> <b>content</b>"
79
79
 
80
80
  When I edit the snippet
81
- # todo: this is a bug
82
- # Then the "First Name" field should contain "Jeremy"
83
- # And the "Favorite Beer" field should contain "Stella"
81
+ Then the "First Name" field should contain "Jeremy"
82
+ And the "Favorite Beer" field should contain "Stella"
84
83
 
85
84
  When I close the modal
86
85
  When I click on the "Redo" button
@@ -31,9 +31,9 @@ module Mercury
31
31
  end
32
32
 
33
33
  def add_gemfile_dependencies
34
- prepend_to_file "Gemfile", %Q{gem 'paperclip'}
34
+ append_to_file "Gemfile", %Q{gem 'paperclip'}
35
35
  if options[:orm] == 'mongoid'
36
- prepend_to_file "Gemfile", %Q{gem 'mongoid-paperclip', :require => 'mongoid_paperclip'}
36
+ append_to_file "Gemfile", %Q{gem 'mongoid-paperclip', :require => 'mongoid_paperclip'}
37
37
  end
38
38
  end
39
39
 
@@ -3,6 +3,8 @@ require 'rails'
3
3
  module Mercury
4
4
  class Engine < ::Rails::Engine
5
5
 
6
+ paths['app/helpers']
7
+
6
8
  # Additional application configuration to include precompiled assets.
7
9
  initializer :assets, :group => :all do |app|
8
10
  app.config.assets.precompile += %w( mercury.js mercury.css mercury_overrides.css mercury_overrides.js )
@@ -1,3 +1,3 @@
1
1
  module Mercury
2
- VERSION = '0.7.1'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, maximum-scale=1.0, initial-scale=1.0">
5
+ <%= csrf_meta_tags %>
6
+ <title>Mercury Editor</title>
7
+ <%= stylesheet_link_tag 'mercury' %>
8
+ <%= javascript_include_tag 'jquery-1.7', 'mercury' %>
9
+ </head>
10
+ <body>
11
+ <script type="text/javascript">
12
+ // Mix in configurations provided through Rails.application.config.mercury_config (for cucumber testing)
13
+ <% if Rails.application.config.respond_to?(:mercury_config) %>
14
+ jQuery.extend(Mercury.config, <%= Rails.application.config.mercury_config.to_json.html_safe %>);
15
+ <% end -%>
16
+
17
+ // Set to the url that you want to save any given page to, leave null for default handling.
18
+ var saveUrl = null;
19
+
20
+ // Instantiate the PageEditor
21
+ new Mercury.PageEditor(saveUrl, {
22
+ saveStyle: null, // 'form', or 'json' (default json)
23
+ saveMethod: null, // 'PUT', or 'POST', (create, vs. update -- default PUT)
24
+ visible: true // boolean - if the interface should start visible or not
25
+ });
26
+ </script>
27
+ </body>
28
+ </html>
@@ -26,7 +26,7 @@ describe "Mercury.dialogHandlers.foreColor", ->
26
26
  spy = spyOn(Mercury, 'trigger').andCallFake(=>)
27
27
  jasmine.simulate.click($('#white').get(0))
28
28
  expect(spy.callCount).toEqual(1)
29
- expect(spy.argsForCall[0]).toEqual(['action', {action: 'foreColor', value: 'rgb(255, 255, 255)'}])
29
+ expect(spy.argsForCall[0]).toEqual(['action', {action: 'foreColor', value: '#FFFFFF'}])
30
30
 
31
31
 
32
32
  describe "when any other element is clicked", ->
@@ -661,7 +661,7 @@ describe "Mercury.PageEditor", ->
661
661
  describe "POST", ->
662
662
  beforeEach ->
663
663
  Mercury.PageEditor.prototype.initializeInterface = ->
664
- @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test'), saveDataType: 'text'})
664
+ @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test'), saveDataType: 'text', saveMethod: 'POST'})
665
665
  @iframeSrcSpy = spyOn(Mercury.PageEditor.prototype, 'iframeSrc').andCallFake(=> '/foo/baz')
666
666
  @ajaxSpy = spyOn($, 'ajax')
667
667
 
@@ -697,7 +697,7 @@ describe "Mercury.PageEditor", ->
697
697
  Mercury.config.saveStyle = 'json'
698
698
  spyOn(Mercury.PageEditor.prototype, 'serialize').andCallFake(=> {region1: 'region1'})
699
699
  @pageEditor.save()
700
- expect(@ajaxSpy.argsForCall[0][1]['data']).toEqual({content: '{"region1":"region1"}' })
700
+ expect(@ajaxSpy.argsForCall[0][1]['data']).toEqual('{"content":{"region1":"region1"}}')
701
701
 
702
702
  it "can serialize as form values", ->
703
703
  @ajaxSpy.andCallFake(=>)
@@ -764,7 +764,7 @@ describe "Mercury.PageEditor", ->
764
764
 
765
765
  beforeEach ->
766
766
  Mercury.PageEditor.prototype.initializeInterface = ->
767
- @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test'), saveMethod: 'PUT'})
767
+ @pageEditor = new Mercury.PageEditor('', {appendTo: $('#test'), saveMethod: 'FOO'})
768
768
  @iframeSrcSpy = spyOn(Mercury.PageEditor.prototype, 'iframeSrc').andCallFake(=> '/foo/baz')
769
769
  @ajaxSpy = spyOn($, 'ajax')
770
770
 
@@ -772,7 +772,7 @@ describe "Mercury.PageEditor", ->
772
772
  @ajaxSpy.andCallFake(=>)
773
773
  spyOn(Mercury.PageEditor.prototype, 'serialize').andCallFake(=> {region1: 'region1'})
774
774
  @pageEditor.save()
775
- expect(@ajaxSpy.argsForCall[0][1]['data']['_method']).toEqual('PUT')
775
+ expect(test=@ajaxSpy.argsForCall[0][1]['data']).toContain('"_method":"PUT"')
776
776
 
777
777
 
778
778
  describe "#serialize", ->
@@ -163,11 +163,11 @@ describe "Mercury.Snippet", ->
163
163
 
164
164
  it "sets the version", ->
165
165
  @snippet.setVersion(5)
166
- expect(@snippet.version).toEqual(4)
166
+ expect(@snippet.version).toEqual(5)
167
167
 
168
168
  it "accepts a version (can be a string)", ->
169
169
  @snippet.setVersion('2')
170
- expect(@snippet.version).toEqual(1)
170
+ expect(@snippet.version).toEqual(2)
171
171
 
172
172
  it "pulls the version out of the history buffer", ->
173
173
  @snippet.setVersion(3)
@@ -1,3 +1,4 @@
1
+ require('/assets/jquery-1.7.js');
1
2
  require('/assets/mercury.js');
2
3
 
3
4
  jasmine.simulate = {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mercury-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -266,7 +266,7 @@ files:
266
266
  - app/assets/images/mercury/toolbar/primary/snippetpanel.png
267
267
  - app/assets/images/mercury/toolbar/primary/undo.png
268
268
  - app/assets/images/mercury/toolbar/snippets/buttons.png
269
- - app/assets/javascripts/mercury/dependencies/jquery-1.7.js
269
+ - app/assets/javascripts/jquery-1.7.js
270
270
  - app/assets/javascripts/mercury/dependencies/jquery-ui-1.8.13.custom.js
271
271
  - app/assets/javascripts/mercury/dependencies/jquery.additions.js
272
272
  - app/assets/javascripts/mercury/dependencies/jquery.htmlClean.js
@@ -340,6 +340,7 @@ files:
340
340
  - app/assets/stylesheets/mercury/uploader.css
341
341
  - app/assets/stylesheets/mercury.css
342
342
  - app/controllers/mercury_controller.rb
343
+ - app/helpers/mercury_helper.rb
343
344
  - app/views/layouts/mercury.html.erb
344
345
  - app/views/mercury/lightviews/about.html
345
346
  - app/views/mercury/modals/character.html
@@ -356,6 +357,7 @@ files:
356
357
  - app/views/mercury/selects/style.html
357
358
  - app/views/mercury/snippets/example/options.html.erb
358
359
  - app/views/mercury/snippets/example/preview.html.erb
360
+ - config/routes.rb
359
361
  - LICENSE
360
362
  - POST_INSTALL
361
363
  - features/generators/authentication.feature
@@ -403,6 +405,7 @@ files:
403
405
  - spec/dummy/app/assets/stylesheets/application.css.scss
404
406
  - spec/dummy/app/controllers/application_controller.rb
405
407
  - spec/dummy/app/views/layouts/application.html.erb
408
+ - spec/dummy/app/views/layouts/mercury.html.erb
406
409
  - spec/dummy/config.ru
407
410
  - spec/dummy/config/application.rb
408
411
  - spec/dummy/config/boot.rb
@@ -423,9 +426,7 @@ files:
423
426
  - spec/dummy/config/routes.rb
424
427
  - spec/dummy/public/500.html
425
428
  - spec/dummy/public/blank.html
426
- - spec/dummy/public/distro.html
427
429
  - spec/dummy/public/favicon.ico
428
- - spec/dummy/public/frame.html
429
430
  - spec/dummy/public/images/bunny.gif
430
431
  - spec/dummy/public/images/bunny2.jpg
431
432
  - spec/dummy/public/index.html
@@ -517,7 +518,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
517
518
  version: '0'
518
519
  segments:
519
520
  - 0
520
- hash: -1857149294402445734
521
+ hash: -2908225509589390282
521
522
  required_rubygems_version: !ruby/object:Gem::Requirement
522
523
  none: false
523
524
  requirements:
@@ -526,7 +527,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
526
527
  version: '0'
527
528
  segments:
528
529
  - 0
529
- hash: -1857149294402445734
530
+ hash: -2908225509589390282
530
531
  requirements: []
531
532
  rubyforge_project:
532
533
  rubygems_version: 1.8.21
@@ -579,6 +580,7 @@ test_files:
579
580
  - spec/dummy/app/assets/stylesheets/application.css.scss
580
581
  - spec/dummy/app/controllers/application_controller.rb
581
582
  - spec/dummy/app/views/layouts/application.html.erb
583
+ - spec/dummy/app/views/layouts/mercury.html.erb
582
584
  - spec/dummy/config.ru
583
585
  - spec/dummy/config/application.rb
584
586
  - spec/dummy/config/boot.rb
@@ -599,9 +601,7 @@ test_files:
599
601
  - spec/dummy/config/routes.rb
600
602
  - spec/dummy/public/500.html
601
603
  - spec/dummy/public/blank.html
602
- - spec/dummy/public/distro.html
603
604
  - spec/dummy/public/favicon.ico
604
- - spec/dummy/public/frame.html
605
605
  - spec/dummy/public/images/bunny.gif
606
606
  - spec/dummy/public/images/bunny2.jpg
607
607
  - spec/dummy/public/index.html
@@ -1,349 +0,0 @@
1
- <html>
2
- <head>
3
- <!-- add prototype and styles to ensure that libraries don't collide and css doesn't conflict -->
4
- <title>Mercury Editor Regression Testing</title>
5
- <script src="/prototype.js" type="text/javascript"></script>
6
- <style type="text/css">
7
- body { border: 1px dotted #000; padding: 10px; }
8
- input { padding: 20px !important }
9
- .mercury-toolbar-container { display: none !important }
10
- </style>
11
-
12
- <meta name="viewport" content="width=device-width, maximum-scale=1.0, initial-scale=1.0">
13
-
14
- <!-- include the loader -->
15
- <script src="/assets/mercury/support/history.js" type="text/javascript"></script>
16
- <script src="/mercury/javascripts/mercury_loader.js?pack=bundled&src=/mercury" type="text/javascript"></script>
17
-
18
- <!-- preload snippets -->
19
- <script type="text/javascript">
20
- // it's worth mentioning that mercury is not loaded in the first request, but should be loaded in the second.
21
- History.Adapter.bind(window, 'statechange', function() {
22
- var state = History.getState();
23
- console.debug(state.data, state.title, state.url);
24
- });
25
-
26
- Event.observe(window, "mercury:ready", function() {
27
- Mercury.saveURL = '/contents';
28
- Mercury.Snippet.load({
29
- snippet_0: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "00"}},
30
- snippet_1: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "01"}},
31
- snippet_2: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "02"}},
32
- snippet_3: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "03"}},
33
- snippet_4: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "04"}},
34
- snippet_5: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "05"}},
35
- snippet_6: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "06"}},
36
- snippet_7: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "07"}},
37
- snippet_8: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "08"}},
38
- snippet_9: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "09"}},
39
- snippet_10: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "10"}},
40
- snippet_11: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "11"}},
41
- snippet_12: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "12"}},
42
- snippet_13: {name: 'example', options: {'options[favorite_beer]': "Bells Hopslam", 'options[first_name]': "13"}}
43
- });
44
- })
45
- </script>
46
-
47
- <!-- styles for the content layout -->
48
- <style type="text/css">
49
- body, td {
50
- font: normal normal normal 100%/normal 'Helvetica Neue', Helvetica, Arial, sans-serif;
51
- }
52
- h1 {
53
- color: #09F;
54
- margin: 20px 0 0 0;
55
- font-weight: 200;
56
- }
57
- h2 {
58
- font-weight: 200;
59
- margin: 15px 0 0 0;
60
- border-bottom: 1px solid #CCC;
61
- }
62
- #forms form {
63
- display: inline;
64
- }
65
- #content {
66
- min-width: 500px;
67
- width: 70%;
68
- margin: 20px auto;
69
- }
70
- #controls {
71
- position: absolute;
72
- top: 20px;
73
- left: 20px;
74
- padding: 10px;
75
- margin: 0;
76
- border: 1px solid #999;
77
- background: rgba(255, 255, 255, 0.8);
78
- border-radius: 3px;
79
- -moz-border-radius: 3px;
80
- -webkit-border-radius: 3px;
81
- list-style-type: none;
82
- }
83
- #controls div {
84
- color: #333;
85
- text-transform: lowercase;
86
- text-decoration: none;
87
- cursor: pointer;
88
- }
89
- .mercury-snippet {
90
- background: rgba(0, 0, 0, 0.5);
91
- color: #FFF;
92
- width: 300px;
93
- height: 100px;
94
- margin: 1px 0;
95
- border-radius: 3px;
96
- -moz-border-radius: 3px;
97
- -webkit-border-radius: 3px;
98
- }
99
- #snippetable1 {
100
- float: left;
101
- width: 100%;
102
- margin-bottom: 20px;
103
- }
104
- #snippetable1 .mercury-snippet {
105
- float: left;
106
- width: 33%;
107
- border: 1px solid #000;
108
- }
109
- </style>
110
- </head>
111
- <body>
112
-
113
- <div id="content">
114
-
115
- <ul id="controls">
116
- <li><div onclick="alert(Mercury.version)">Mercury Version</div></li>
117
- <li><div onclick="Mercury.trigger('toggle:interface')">Toggle Interface</div></li>
118
- <li><div onclick="var num = 1; History.pushState({state: num}, 'Mercury Editor -- With history.pushState!', '?pushstate=' + num);">history.pushState</div></li>
119
- <li><div onclick="History.go(-1);">History.go(-1)</div></li>
120
- <li><div onclick="History.back();">History.back()</div></li>
121
- <li><div onclick="History.forward();">History.forward()</div></li>
122
- </ul>
123
-
124
- <h1>Forms (with various methods and targets)</h1>
125
- <div id="forms">
126
- <form id="form1" action="/mercury/test_page" method="post" target="_top">
127
- <input type="submit" name="commit" value="post _top">
128
- </form>
129
- <form id="form2" action="/mercury/test_page" method="get" target="_blank">
130
- <input type="submit" name="commit" value="post _blank">
131
- </form>
132
- <form id="form3" action="/mercury/test_page" method="post" target="_self">
133
- <input type="submit" name="commit" value="post _self">
134
- </form>
135
- <form id="form4" action="/mercury/test_page" method="get">
136
- <input type="submit" name="commit" value="get [none]">
137
- </form>
138
- <form id="form5" action="/mercury/test_page" method="post" class="lightview" target="_self">
139
- <input type="submit" name="commit" value="post _self .lightview">
140
- </form>
141
- <form id="form6" action="/mercury/test_page" method="get" target="foo">
142
- <input type="submit" name="commit" value="get foo">
143
- </form>
144
- </div>
145
-
146
- <h1>Links (With various targets)</h1>
147
- <div id="links">
148
- <a id="anchor1" href="/mercury/test_page" target="_top">_top</a>
149
- <a id="anchor2" href="/mercury/test_page" target="_blank">_blank</a>
150
- <a id="anchor3" href="/mercury/test_page" target="_self">_self</a>
151
- <a id="anchor4" href="/mercury/test_page">[none]</a>
152
- <a id="anchor5" href="/mercury/test_page" class="lightview" target="_self">_self .lightview</a>
153
- <a id="anchor6" href="/mercury/test_page" target="foo">foo</a>
154
- </div>
155
-
156
- <h1>Editable region</h1>
157
- <div id="editable1" class="mercury-region" data-type="editable">
158
- If the first line of content isn't wrapped in an element you can't set justification (mozilla only bug).
159
-
160
- <h2>text with a meta tag (that will be removed)</h2>
161
- 123<meta>editable content
162
-
163
- <h2>anchor with a div inside</h2>
164
- <a href="/foo1">l<div>ink with a div in</div> it</a>
165
-
166
- <h2>image wrapped in an anchor</h2>
167
- <a href="/foo2"><img alt="logo" src="/assets/mercury/temp-logo.png"></a>123
168
-
169
- <h2>table with header and definition cells</h2>
170
- <table border="1">
171
- <tbody>
172
- <tr>
173
- <th>R1C1</th>
174
- <th colspan="5">R1C2</th>
175
- </tr>
176
- <tr>
177
- <th colspan="2">R2C1</th>
178
- <th rowspan="2">R2C2</th>
179
- <th>R2C3</th>
180
- <th rowspan="5">R2C4</th>
181
- <th>R2C5</th>
182
- </tr>
183
- <tr>
184
- <td colspan="2">R3C1</td>
185
- <td>R3C2</td>
186
- <td>R3C3</td>
187
- </tr>
188
- <tr>
189
- <td>R4C1</td>
190
- <td>R4C2</td>
191
- <td rowspan="4">R4C3</td>
192
- <td>R4C4</td>
193
- <td>R4C5</td>
194
- </tr>
195
- <tr>
196
- <td>R5C1</td>
197
- <td>R5C2</td>
198
- <td>R5C3</td>
199
- <td>R5C4</td>
200
- </tr>
201
- <tr>
202
- <th rowspan="2">R6C1</th>
203
- <th rowspan="2">R6C2</th>
204
- <th>R6C3</th>
205
- <th>R6C4</th>
206
- </tr>
207
- <tr>
208
- <td>R7C1</td>
209
- <td>R7C2</td>
210
- <td>R7C3</td>
211
- </tr>
212
- <tr>
213
- <td colspan="2">R8C1</td>
214
- <td colspan="4">R7C2</td>
215
- </tr>
216
- </tbody>
217
- </table>
218
-
219
- <h2>table without tbody or border</h2>
220
- <table>
221
- <tr>
222
- <th>R1C1</th>
223
- <th colspan="2">R1C2</th>
224
- </tr>
225
- <tr>
226
- <td rowspan="2">R2C1</td>
227
- <td>R2C2</td>
228
- <td>R2C3</td>
229
- </tr>
230
- <tr>
231
- <td>R3C1</td>
232
- <td>R3C2</td>
233
- </tr>
234
- </table>
235
-
236
- <h2>fixed width table (column where all colspans > 1, row where all rowspans > 1)</h2>
237
- <table border="1" width="200">
238
- <tbody>
239
- <tr>
240
- <td rowspan="2">R1C1</td>
241
- <td colspan="2" rowspan="2">R1C2</td>
242
- </tr>
243
- <tr></tr>
244
- <tr>
245
- <td>R3C1</td>
246
- <td colspan="2">R3C2</td>
247
- </tr>
248
- <tr>
249
- <td>R4C1</td>
250
- <td colspan="2">R4C3</td>
251
- </tr>
252
- </tbody>
253
- </table>
254
-
255
- <h2>paragraph with an overline wrapped in an underline</h2>
256
- <p>123 <u>under <span style="text-decoration:overline">overline</span> line</u> 123</p>
257
-
258
- <h2>paragraph with an underline wrapped in an overline</h2>
259
- <p>123 <span style="text-decoration:overline">over <u>underline</u> line</span> 123</p>
260
-
261
- <h2>style tag that styles images with a border</h2>
262
- <style type="text/css">img { border: 2px solid red}</style>
263
-
264
- <h2>image next to content wrapped in an anchor</h2>
265
- <img alt="logo" src="/assets/mercury/temp-logo.png"><a href="#bookmark1">link for #bookmark1</a>
266
-
267
- <h2>snippet that's pre-loaded</h2>
268
- <div class="mercury-snippet" data-snippet="snippet_0">snippet0</div>
269
-
270
- <h2>bookmark links</h2>
271
- <a name="bookmark1">Bookmark1</a><br/><a name="bookmark2">Bookmark2</a>
272
-
273
- <br/><br/>
274
- Additional content not wrapped in anything
275
-
276
- <h2>youtube and vimeo iframes with content surrounding it</h2>
277
- <!--123<iframe style="width: 560px; height: 349px; " src="http://www.youtube.com/embed/0pXYp72dwl0?wmode=transparent" frameborder="0" allowfullscreen="true"></iframe>123321-->
278
- <!--<iframe style="width: 400px; height: 225px; " src="http://player.vimeo.com/video/615344?title=1&amp;byline=1&amp;portrait=0&amp;color=ffffff" frameborder="0"></iframe>123-->
279
- </div>
280
-
281
- <h1>Markupable region (with markdown)</h1>
282
- <div id="markupable1" class="mercury-region" data-type="markupable">
283
- ## notes ##
284
- **whitespace** in markupable regions is _important_.
285
-
286
- ## ordered list ##
287
- 1. list item 1
288
- 2. list item 2
289
-
290
- ## unordered list ##
291
- - list item 1
292
- - list item 2
293
-
294
- ## horizontal rule ##
295
- - - -
296
-
297
- ## anchor ##
298
- [this is a link](foo 'optional title')
299
-
300
- ## image ##
301
- ![add alt text](/assets/mercury/temp-logo.png)
302
-
303
- ## snippet that's pre-loaded ##
304
- [--snippet_1--]
305
-
306
- ## code ##
307
- <a href="/foo">this html will not be escaped</a>
308
- and whitespace will be retained
309
-
310
- ## blockquote ##
311
- > this is indented one level
312
-
313
- ## paragraph with bold, italics, etc. ##
314
- Turkey corned beef ham, chuck ham hock **venison _drumstick_ ** tongue ribeye. Beef tongue pancetta, short ribs meatball headcheese jowl bacon swine t-bone shoulder venison. Hamburger short loin turkey flank short ribs tail. Chicken tri-tip sausage, bresaola sirloin turkey hamburger <sub>headcheese</sub> shank rump. Pork ground round t-bone, ham hock sirloin biltong chicken fatback pork belly pastrami pancetta jowl tail. Cow ribeye pork chop, flank sirloin tail short loin pork loin chicken boudin pastrami. Boudin chuck shankle, spare ribs pancetta <sup>fatback</sup> bresaola.
315
- </div>
316
-
317
- <h1>Snippetable region</h1>
318
- <div id="snippetable1" class="mercury-region" data-type="snippetable">
319
- <div class="mercury-snippet" data-snippet="snippet_2">snippet2</div>
320
- <div class="mercury-snippet" data-snippet="snippet_3">snippet3</div>
321
- <div class="mercury-snippet" data-snippet="snippet_4">snippet4</div>
322
- <div class="mercury-snippet" data-snippet="snippet_5">snippet5</div>
323
- <div class="mercury-snippet" data-snippet="snippet_6">snippet6</div>
324
- <div class="mercury-snippet" data-snippet="snippet_7">snippet7</div>
325
- <div class="mercury-snippet" data-snippet="snippet_8">snippet8</div>
326
- <div class="mercury-snippet" data-snippet="snippet_9">snippet9</div>
327
- </div>
328
-
329
- <h1>Editable region (single snippet and no content)</h1>
330
- <div id="editable2" class="mercury-region" data-type="editable">
331
- <div class="mercury-snippet" data-snippet="snippet_10">snippet10</div>
332
- </div>
333
-
334
- <h1>Editable region (fixed width/height and overflow)</h1>
335
- <div id="editable3" class="mercury-region" data-type="editable" style="width:200px;height:90px;">
336
- wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
337
- <br/>1<br/>2<br/>3<br/>4<br/>5<br/>6<br/>7<br/><a href="#offset_test">8</a><br/>9<br/>10<br/>11<br/>12<br/>13<br/>14<br/>15
338
- </div>
339
-
340
- <h1>Snippetable region (iframe snippet that contains flash)</h1>
341
- <div id="snippetable2" class="mercury-region" data-type="snippetable">
342
- <div class="mercury-snippet" data-snippet="snippet_11">snippet11</div>
343
- <div class="mercury-snippet" data-snippet="snippet_12">snippet12</div>
344
- <iframe class="mercury-snippet" data-snippet="snippet_13" width="560" height="349" src="http://www.youtube.com/embed/0pXYp72dwl0?wmode=transparent" frameborder="0" allowfullscreen="true"></iframe>
345
- </div>
346
- </div>
347
-
348
- </body>
349
- </html>
@@ -1,15 +0,0 @@
1
- <html>
2
- <head>
3
- <!-- add prototype and styles to ensure that libraries don't collide and css doesn't conflict -->
4
- <title>Mercury Editor Regression Testing</title>
5
- <style type="text/css">
6
- html, body {
7
- padding: 0;
8
- margin: 0;
9
- }
10
- </style>
11
- </head>
12
- <body>
13
- <iframe src="/" width="100%" height="300"></iframe>
14
- </body>
15
- </html>