kiteditor 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +25 -0
- data/app/controllers/mercury/images_controller.rb +5 -0
- data/app/controllers/mercury_controller.rb +34 -0
- data/app/models/mercury/image.rb +17 -0
- data/app/views/layouts/mercury.html.erb +33 -0
- data/app/views/layouts/popup.html.haml +9 -0
- data/app/views/mercury/images/_list.html.haml +22 -0
- data/app/views/mercury/images/index.html.haml +4 -0
- data/app/views/mercury/images/index.js.erb +2 -0
- data/app/views/mercury/lightviews/about.html +11 -0
- data/app/views/mercury/modals/character.html +255 -0
- data/app/views/mercury/modals/htmleditor.html +13 -0
- data/app/views/mercury/modals/link.html +94 -0
- data/app/views/mercury/modals/media.html +1 -0
- data/app/views/mercury/modals/table.html +84 -0
- data/app/views/mercury/palettes/backcolor.html +73 -0
- data/app/views/mercury/palettes/forecolor.html +73 -0
- data/app/views/mercury/panels/history.html +3 -0
- data/app/views/mercury/panels/notes.html +3 -0
- data/app/views/mercury/panels/snippets.html +12 -0
- data/app/views/mercury/selects/formatblock.html +11 -0
- data/app/views/mercury/selects/style.html +5 -0
- data/app/views/mercury/snippets/example/options.html.erb +34 -0
- data/app/views/mercury/snippets/example/preview.html.erb +1 -0
- data/config/engine.rb +44 -0
- data/db/migrate/20110526035601_create_mercury_images.rb +11 -0
- data/features/loading/loading.feature +22 -0
- data/features/loading/navigating.feature +77 -0
- data/features/loading/user_interface.feature +67 -0
- data/features/regions/editable/advanced_editing.feature +0 -0
- data/features/regions/editable/basic_editing.feature +195 -0
- data/features/regions/editable/inserting_links.feature +98 -0
- data/features/regions/editable/inserting_media.feature +110 -0
- data/features/regions/editable/inserting_snippets.feature +102 -0
- data/features/regions/editable/inserting_special_characters.feature +24 -0
- data/features/regions/editable/inserting_tables.feature +109 -0
- data/features/regions/editable/pasting.feature +0 -0
- data/features/regions/editable/uploading_images.feature +0 -0
- data/features/regions/markupable/advanced_editing.feature +0 -0
- data/features/regions/markupable/basic_editing.feature +0 -0
- data/features/regions/markupable/inserting_links.feature +0 -0
- data/features/regions/markupable/inserting_media.feature +0 -0
- data/features/regions/markupable/inserting_snippets.feature +0 -0
- data/features/regions/markupable/inserting_special_characters.feature +0 -0
- data/features/regions/markupable/inserting_tables.feature +0 -0
- data/features/regions/markupable/uploading_images.feature +0 -0
- data/features/regions/snippetable/advanced_editing.feature +0 -0
- data/features/regions/snippetable/basic_editing.feature +0 -0
- data/features/regions/snippetable/inserting_snippets.feature +0 -0
- data/features/saving/saving.feature +33 -0
- data/features/step_definitions/debug_steps.rb +14 -0
- data/features/step_definitions/mercury_steps.rb +438 -0
- data/features/step_definitions/web_steps.rb +211 -0
- data/features/support/env.rb +46 -0
- data/features/support/mercury_contents.rb +25 -0
- data/features/support/mercury_selectors.rb +148 -0
- data/features/support/paths.rb +38 -0
- data/features/support/selectors.rb +44 -0
- data/lib/generators/mercury/install/install_generator.rb +49 -0
- data/lib/generators/mercury/install/templates/mongoid_paperclip_image.rb +17 -0
- data/lib/mercury/authentication.rb +8 -0
- data/lib/mercury-rails.rb +3 -0
- data/spec/javascripts/mercury/dialog_spec.js.coffee +281 -0
- data/spec/javascripts/mercury/dialogs/backcolor_spec.js.coffee +37 -0
- data/spec/javascripts/mercury/dialogs/forecolor_spec.js.coffee +37 -0
- data/spec/javascripts/mercury/dialogs/formatblock_spec.js.coffee +25 -0
- data/spec/javascripts/mercury/dialogs/snippetpanel_spec.js.coffee +30 -0
- data/spec/javascripts/mercury/dialogs/style_spec.js.coffee +25 -0
- data/spec/javascripts/mercury/history_buffer_spec.js.coffee +76 -0
- data/spec/javascripts/mercury/lightview_spec.js.coffee +497 -0
- data/spec/javascripts/mercury/mercury_spec.js.coffee +132 -0
- data/spec/javascripts/mercury/modal_spec.js.coffee +504 -0
- data/spec/javascripts/mercury/modals/htmleditor_spec.js.coffee +30 -0
- data/spec/javascripts/mercury/modals/insertcharacter_spec.js.coffee +29 -0
- data/spec/javascripts/mercury/modals/insertlink_spec.js.coffee +220 -0
- data/spec/javascripts/mercury/modals/insertmedia_spec.js.coffee +167 -0
- data/spec/javascripts/mercury/modals/insertsnippet_spec.js.coffee +52 -0
- data/spec/javascripts/mercury/modals/inserttable_spec.js.coffee +160 -0
- data/spec/javascripts/mercury/native_extensions_spec.js.coffee +60 -0
- data/spec/javascripts/mercury/page_editor_spec.js.coffee +750 -0
- data/spec/javascripts/mercury/palette_spec.js.coffee +49 -0
- data/spec/javascripts/mercury/panel_spec.js.coffee +185 -0
- data/spec/javascripts/mercury/region_spec.js.coffee +298 -0
- data/spec/javascripts/mercury/regions/editable_spec.js.coffee +561 -0
- data/spec/javascripts/mercury/regions/markupable_spec.js.coffee +367 -0
- data/spec/javascripts/mercury/regions/snippetable_spec.js.coffee +370 -0
- data/spec/javascripts/mercury/select_spec.js.coffee +49 -0
- data/spec/javascripts/mercury/snippet_spec.js.coffee +245 -0
- data/spec/javascripts/mercury/snippet_toolbar_spec.js.coffee +184 -0
- data/spec/javascripts/mercury/statusbar_spec.js.coffee +150 -0
- data/spec/javascripts/mercury/table_editor_spec.js.coffee +194 -0
- data/spec/javascripts/mercury/toolbar.button_group_spec.js.coffee +90 -0
- data/spec/javascripts/mercury/toolbar.button_spec.js.coffee +360 -0
- data/spec/javascripts/mercury/toolbar.expander_spec.js.coffee +118 -0
- data/spec/javascripts/mercury/toolbar_spec.js.coffee +222 -0
- data/spec/javascripts/mercury/tooltip_spec.js.coffee +186 -0
- data/spec/javascripts/mercury/uploader_spec.js.coffee +514 -0
- data/spec/javascripts/spec_helper.js +513 -0
- data/spec/javascripts/templates/mercury/dialog.html +2 -0
- data/spec/javascripts/templates/mercury/dialogs/backcolor.html +5 -0
- data/spec/javascripts/templates/mercury/dialogs/forecolor.html +5 -0
- data/spec/javascripts/templates/mercury/dialogs/formatblock.html +3 -0
- data/spec/javascripts/templates/mercury/dialogs/snippetpanel.html +16 -0
- data/spec/javascripts/templates/mercury/dialogs/style.html +3 -0
- data/spec/javascripts/templates/mercury/lightview.html +13 -0
- data/spec/javascripts/templates/mercury/modal.html +13 -0
- data/spec/javascripts/templates/mercury/modals/htmleditor.html +5 -0
- data/spec/javascripts/templates/mercury/modals/insertcharacter.html +5 -0
- data/spec/javascripts/templates/mercury/modals/insertlink.html +30 -0
- data/spec/javascripts/templates/mercury/modals/insertmedia.html +35 -0
- data/spec/javascripts/templates/mercury/modals/insertsnippet.html +6 -0
- data/spec/javascripts/templates/mercury/modals/inserttable.html +27 -0
- data/spec/javascripts/templates/mercury/page_editor.html +35 -0
- data/spec/javascripts/templates/mercury/palette.html +16 -0
- data/spec/javascripts/templates/mercury/panel.html +16 -0
- data/spec/javascripts/templates/mercury/region.html +2 -0
- data/spec/javascripts/templates/mercury/regions/editable.html +3 -0
- data/spec/javascripts/templates/mercury/regions/snippetable.html +4 -0
- data/spec/javascripts/templates/mercury/select.html +16 -0
- data/spec/javascripts/templates/mercury/snippet.html +1 -0
- data/spec/javascripts/templates/mercury/snippet_toolbar.html +16 -0
- data/spec/javascripts/templates/mercury/statusbar.html +8 -0
- data/spec/javascripts/templates/mercury/table_editor.html +65 -0
- data/spec/javascripts/templates/mercury/toolbar.button.html +64 -0
- data/spec/javascripts/templates/mercury/toolbar.button_group.html +9 -0
- data/spec/javascripts/templates/mercury/toolbar.expander.html +18 -0
- data/spec/javascripts/templates/mercury/toolbar.html +11 -0
- data/spec/javascripts/templates/mercury/tooltip.html +12 -0
- data/spec/javascripts/templates/mercury/uploader.html +11 -0
- data/vendor/assets/images/mercury/button.png +0 -0
- data/vendor/assets/images/mercury/close.png +0 -0
- data/vendor/assets/images/mercury/default-snippet.png +0 -0
- data/vendor/assets/images/mercury/loading-dark.gif +0 -0
- data/vendor/assets/images/mercury/loading-light.gif +0 -0
- data/vendor/assets/images/mercury/missing-image.png +0 -0
- data/vendor/assets/images/mercury/search-icon.png +0 -0
- data/vendor/assets/images/mercury/temp-logo.png +0 -0
- data/vendor/assets/images/mercury/toolbar/editable/buttons.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/_expander.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/_pressed.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/historypanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/insertcharacter.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/insertlink.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/insertmedia.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/inserttable.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/inspectorpanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/notespanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/preview.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/redo.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/save.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/snippetpanel.png +0 -0
- data/vendor/assets/images/mercury/toolbar/primary/undo.png +0 -0
- data/vendor/assets/images/mercury/toolbar/snippetable/buttons.png +0 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery-1.7.js +9300 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery-ui-1.8.13.custom.js +1328 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery-ui-1.8.18.custom.min.js +356 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery-ui.1.8.13.custom.min.js +356 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery.additions.js +206 -0
- data/vendor/assets/javascripts/mercury/dependencies/jquery.htmlClean.js +527 -0
- data/vendor/assets/javascripts/mercury/dependencies/liquidmetal.js +88 -0
- data/vendor/assets/javascripts/mercury/dependencies/showdown.js +1340 -0
- data/vendor/assets/javascripts/mercury/dialog.js.coffee +159 -0
- data/vendor/assets/javascripts/mercury/dialogs/backcolor.js.coffee +6 -0
- data/vendor/assets/javascripts/mercury/dialogs/forecolor.js.coffee +6 -0
- data/vendor/assets/javascripts/mercury/dialogs/formatblock.js.coffee +4 -0
- data/vendor/assets/javascripts/mercury/dialogs/snippetpanel.js.coffee +10 -0
- data/vendor/assets/javascripts/mercury/dialogs/style.js.coffee +4 -0
- data/vendor/assets/javascripts/mercury/finalize.js.coffee +3 -0
- data/vendor/assets/javascripts/mercury/history_buffer.js.coffee +30 -0
- data/vendor/assets/javascripts/mercury/lightview.js.coffee +205 -0
- data/vendor/assets/javascripts/mercury/locales/da.locale.js.coffee +0 -0
- data/vendor/assets/javascripts/mercury/locales/de.locale.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/es.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/example.local.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/fr.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/it.locale.js.coffee +208 -0
- data/vendor/assets/javascripts/mercury/locales/ko.local.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/nl.locale.js.coffee +206 -0
- data/vendor/assets/javascripts/mercury/locales/pt.locale.js.coffee +211 -0
- data/vendor/assets/javascripts/mercury/locales/sv.local.js.coffee +209 -0
- data/vendor/assets/javascripts/mercury/locales/swedish_chef.locale.js.coffee +213 -0
- data/vendor/assets/javascripts/mercury/mercury.js.coffee +109 -0
- data/vendor/assets/javascripts/mercury/modal.js.coffee +204 -0
- data/vendor/assets/javascripts/mercury/modals/htmleditor.js.coffee +11 -0
- data/vendor/assets/javascripts/mercury/modals/insertcharacter.js.coffee +4 -0
- data/vendor/assets/javascripts/mercury/modals/insertlink.js.coffee +95 -0
- data/vendor/assets/javascripts/mercury/modals/insertmedia.js.coffee +107 -0
- data/vendor/assets/javascripts/mercury/modals/insertsnippet.js.coffee +12 -0
- data/vendor/assets/javascripts/mercury/modals/inserttable.js.coffee +54 -0
- data/vendor/assets/javascripts/mercury/native_extensions.js.coffee +55 -0
- data/vendor/assets/javascripts/mercury/page_editor.js.coffee +241 -0
- data/vendor/assets/javascripts/mercury/palette.js.coffee +29 -0
- data/vendor/assets/javascripts/mercury/panel.js.coffee +115 -0
- data/vendor/assets/javascripts/mercury/plugins/save_as_xml/mercury/page_editor.js.coffee +28 -0
- data/vendor/assets/javascripts/mercury/plugins/save_as_xml/plugin.js +9 -0
- data/vendor/assets/javascripts/mercury/region.js.coffee +107 -0
- data/vendor/assets/javascripts/mercury/regions/editable.js.coffee +600 -0
- data/vendor/assets/javascripts/mercury/regions/markupable.js.coffee +398 -0
- data/vendor/assets/javascripts/mercury/regions/simple.js.coffee +339 -0
- data/vendor/assets/javascripts/mercury/regions/snippetable.js.coffee +124 -0
- data/vendor/assets/javascripts/mercury/select.js.coffee +44 -0
- data/vendor/assets/javascripts/mercury/snippet.js.coffee +104 -0
- data/vendor/assets/javascripts/mercury/snippet_toolbar.js.coffee +72 -0
- data/vendor/assets/javascripts/mercury/statusbar.js.coffee +51 -0
- data/vendor/assets/javascripts/mercury/support/history.js +1 -0
- data/vendor/assets/javascripts/mercury/table_editor.js.coffee +265 -0
- data/vendor/assets/javascripts/mercury/toolbar.button.js.coffee +173 -0
- data/vendor/assets/javascripts/mercury/toolbar.button_group.js.coffee +42 -0
- data/vendor/assets/javascripts/mercury/toolbar.expander.js.coffee +56 -0
- data/vendor/assets/javascripts/mercury/toolbar.js.coffee +86 -0
- data/vendor/assets/javascripts/mercury/tooltip.js.coffee +74 -0
- data/vendor/assets/javascripts/mercury/uploader.js.coffee +227 -0
- data/vendor/assets/javascripts/mercury.js +479 -0
- data/vendor/assets/javascripts/mercury_loader.js +193 -0
- data/vendor/assets/javascripts/mercury_overrides.js +6 -0
- data/vendor/assets/javascripts/popup.js +8 -0
- data/vendor/assets/stylesheets/mercury/all_images.css.erb +89 -0
- data/vendor/assets/stylesheets/mercury/dialog.css +208 -0
- data/vendor/assets/stylesheets/mercury/lightview.css +151 -0
- data/vendor/assets/stylesheets/mercury/mercury.css +151 -0
- data/vendor/assets/stylesheets/mercury/modal.css +183 -0
- data/vendor/assets/stylesheets/mercury/statusbar.css +32 -0
- data/vendor/assets/stylesheets/mercury/toolbar.css +304 -0
- data/vendor/assets/stylesheets/mercury/tooltip.css +26 -0
- data/vendor/assets/stylesheets/mercury/uploader.css +111 -0
- data/vendor/assets/stylesheets/mercury.css +28 -0
- data/vendor/assets/stylesheets/mercury_overrides.css +17 -0
- data/vendor/assets/stylesheets/popup.css.erb +37 -0
- metadata +634 -0
@@ -0,0 +1,241 @@
|
|
1
|
+
class @Mercury.PageEditor
|
2
|
+
|
3
|
+
# options
|
4
|
+
# saveStyle: 'form', or 'json' (defaults to json)
|
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)
|
7
|
+
# visible: boolean, if the interface should start visible or not (defaults to true)
|
8
|
+
constructor: (@saveUrl = null, @options = {}) ->
|
9
|
+
throw Mercury.I18n('Mercury.PageEditor can only be instantiated once.') if window.mercuryInstance
|
10
|
+
|
11
|
+
@options.visible = true unless (@options.visible == false || @options.visible == 'no')
|
12
|
+
@visible = @options.visible
|
13
|
+
|
14
|
+
window.mercuryInstance = @
|
15
|
+
@regions = []
|
16
|
+
@initializeInterface()
|
17
|
+
Mercury.csrfToken = token if token = jQuery(Mercury.config.csrfSelector).attr('content')
|
18
|
+
|
19
|
+
|
20
|
+
initializeInterface: ->
|
21
|
+
@focusableElement = jQuery('<input>', {class: 'mercury-focusable', type: 'text'}).appendTo(@options.appendTo ? 'body')
|
22
|
+
|
23
|
+
@iframe = jQuery('<iframe>', {id: 'mercury_iframe', class: 'mercury-iframe', seamless: 'true', frameborder: '0', src: 'about:blank'})
|
24
|
+
@iframe.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
25
|
+
|
26
|
+
@toolbar = new Mercury.Toolbar(@options)
|
27
|
+
@statusbar = new Mercury.Statusbar(@options)
|
28
|
+
@resize()
|
29
|
+
|
30
|
+
@iframe.on 'load', => @initializeFrame()
|
31
|
+
@iframe.get(0).contentWindow.document.location.href = @iframeSrc(null, true)
|
32
|
+
|
33
|
+
|
34
|
+
initializeFrame: ->
|
35
|
+
try
|
36
|
+
return if @iframe.data('loaded')
|
37
|
+
@iframe.data('loaded', true)
|
38
|
+
Mercury.notify("Opera isn't a fully supported browser, your results may not be optimal.") if jQuery.browser.opera
|
39
|
+
@document = jQuery(@iframe.get(0).contentWindow.document)
|
40
|
+
stylesToInject = Mercury.config.injectedStyles.replace(/{{regionClass}}/g, Mercury.config.regions.className)
|
41
|
+
jQuery("<style mercury-styles=\"true\">").html(stylesToInject).appendTo(@document.find('head'))
|
42
|
+
|
43
|
+
# jquery: make jQuery evaluate scripts within the context of the iframe window
|
44
|
+
iframeWindow = @iframe.get(0).contentWindow
|
45
|
+
jQuery.globalEval = (data) -> (iframeWindow.execScript || (data) -> iframeWindow["eval"].call(iframeWindow, data))(data) if (data && /\S/.test(data))
|
46
|
+
|
47
|
+
iframeWindow.Mercury = Mercury
|
48
|
+
iframeWindow.History = History if window.History && History.Adapter
|
49
|
+
|
50
|
+
@bindEvents()
|
51
|
+
@resize()
|
52
|
+
@initializeRegions()
|
53
|
+
@finalizeInterface()
|
54
|
+
Mercury.trigger('ready')
|
55
|
+
jQuery(iframeWindow).trigger('mercury:ready')
|
56
|
+
iframeWindow.Event.fire(iframeWindow, 'mercury:ready') if iframeWindow.Event && iframeWindow.Event.fire
|
57
|
+
iframeWindow.onMercuryReady() if iframeWindow.onMercuryReady
|
58
|
+
|
59
|
+
@iframe.css({visibility: 'visible'})
|
60
|
+
catch error
|
61
|
+
Mercury.notify('Mercury.PageEditor failed to load: %s\n\nPlease try refreshing.', error)
|
62
|
+
|
63
|
+
|
64
|
+
initializeRegions: ->
|
65
|
+
@regions = []
|
66
|
+
@buildRegion(jQuery(region)) for region in jQuery(".#{Mercury.config.regions.className}", @document)
|
67
|
+
return unless @options.visible
|
68
|
+
for region in @regions
|
69
|
+
if region.focus
|
70
|
+
region.focus()
|
71
|
+
break
|
72
|
+
|
73
|
+
|
74
|
+
buildRegion: (region) ->
|
75
|
+
if region.data('region')
|
76
|
+
region = region.data('region')
|
77
|
+
else
|
78
|
+
type = (
|
79
|
+
region.data('type') ||
|
80
|
+
( jQuery.type(Mercury.config.regions.determineType) == 'function' && Mercury.config.regions.determineType(region) ) ||
|
81
|
+
'unknown'
|
82
|
+
).titleize()
|
83
|
+
throw Mercury.I18n('Region type is malformed, no data-type provided, or "%s" is unknown for the "%s" region.', type, region.attr('id') || 'unknown') if type == 'Unknown' || !Mercury.Regions[type]
|
84
|
+
if !Mercury.Regions[type].supported
|
85
|
+
Mercury.notify('Mercury.Regions.%s is unsupported in this client. Supported browsers are %s.', type, Mercury.Regions[type].supportedText)
|
86
|
+
return false
|
87
|
+
region = new Mercury.Regions[type](region, @iframe.get(0).contentWindow)
|
88
|
+
region.togglePreview() if @previewing
|
89
|
+
@regions.push(region)
|
90
|
+
|
91
|
+
|
92
|
+
finalizeInterface: ->
|
93
|
+
@santizerElement = jQuery('<div>', {id: 'mercury_sanitizer', contenteditable: 'true', style: 'position:fixed;width:100px;height:100px;top:0;left:-100px;opacity:0;overflow:hidden'})
|
94
|
+
@santizerElement.appendTo(@options.appendTo ? @document.find('body'))
|
95
|
+
|
96
|
+
@snippetToolbar = new Mercury.SnippetToolbar(@document)
|
97
|
+
|
98
|
+
@hijackLinksAndForms()
|
99
|
+
Mercury.trigger('mode', {mode: 'preview'}) unless @options.visible
|
100
|
+
|
101
|
+
|
102
|
+
bindEvents: ->
|
103
|
+
Mercury.on 'autosave', => @autosave()
|
104
|
+
Mercury.on 'initialize:frame', => setTimeout(100, @initializeFrame)
|
105
|
+
Mercury.on 'focus:frame', => @iframe.focus()
|
106
|
+
Mercury.on 'focus:window', => setTimeout(10, => @focusableElement.focus())
|
107
|
+
Mercury.on 'toggle:interface', => @toggleInterface()
|
108
|
+
Mercury.on 'reinitialize', => @initializeRegions()
|
109
|
+
Mercury.on 'mode', (event, options) => @previewing = !@previewing if options.mode == 'preview'
|
110
|
+
Mercury.on 'action', (event, options) =>
|
111
|
+
action = Mercury.config.globalBehaviors[options.action] || @[options.action]
|
112
|
+
return unless typeof(action) == 'function'
|
113
|
+
options.already_handled = true
|
114
|
+
action.call(@, options)
|
115
|
+
|
116
|
+
@document.on 'mousedown', (event) ->
|
117
|
+
Mercury.trigger('hide:dialogs')
|
118
|
+
if Mercury.region
|
119
|
+
Mercury.trigger('unfocus:regions') unless jQuery(event.target).closest(".#{Mercury.config.regions.className}").get(0) == Mercury.region.element.get(0)
|
120
|
+
|
121
|
+
jQuery(window).on 'resize', =>
|
122
|
+
@resize()
|
123
|
+
|
124
|
+
jQuery(@document).bind 'keydown', (event) =>
|
125
|
+
return unless event.ctrlKey || event.metaKey
|
126
|
+
if (event.keyCode == 83) # meta+S
|
127
|
+
Mercury.trigger('action', {action: 'save'})
|
128
|
+
event.preventDefault()
|
129
|
+
|
130
|
+
jQuery(window).bind 'keydown', (event) =>
|
131
|
+
return unless event.ctrlKey || event.metaKey
|
132
|
+
if (event.keyCode == 83) # meta+S
|
133
|
+
Mercury.trigger('action', {action: 'save'})
|
134
|
+
event.preventDefault()
|
135
|
+
|
136
|
+
window.onbeforeunload = @beforeUnload
|
137
|
+
|
138
|
+
|
139
|
+
toggleInterface: ->
|
140
|
+
if @visible
|
141
|
+
Mercury.trigger('mode', {mode: 'preview'}) if @previewing
|
142
|
+
@visible = false
|
143
|
+
@toolbar.hide()
|
144
|
+
@statusbar.hide()
|
145
|
+
else
|
146
|
+
@visible = true
|
147
|
+
@toolbar.show()
|
148
|
+
@statusbar.show()
|
149
|
+
Mercury.trigger('mode', {mode: 'preview'})
|
150
|
+
@resize()
|
151
|
+
|
152
|
+
|
153
|
+
resize: ->
|
154
|
+
width = jQuery(window).width()
|
155
|
+
height = @statusbar.top()
|
156
|
+
toolbarHeight = @toolbar.height()
|
157
|
+
|
158
|
+
Mercury.displayRect = {top: toolbarHeight, left: 0, width: width, height: height - toolbarHeight, fullHeight: height}
|
159
|
+
|
160
|
+
@iframe.css {
|
161
|
+
top: toolbarHeight
|
162
|
+
left: 0
|
163
|
+
height: height - toolbarHeight
|
164
|
+
}
|
165
|
+
|
166
|
+
Mercury.trigger('resize')
|
167
|
+
|
168
|
+
|
169
|
+
iframeSrc: (url = null, params = false) ->
|
170
|
+
url = (url ? window.location.href).replace(Mercury.config.editorUrlRegEx ?= /([http|https]:\/\/.[^\/]*)\/editor\/?(.*)/i, "$1/$2")
|
171
|
+
url = url.replace(/[\?|\&]mercury_frame=true/gi, '')
|
172
|
+
if params
|
173
|
+
return "#{url}#{if url.indexOf('?') > -1 then '&' else '?'}mercury_frame=true"
|
174
|
+
else
|
175
|
+
return url
|
176
|
+
|
177
|
+
|
178
|
+
hijackLinksAndForms: ->
|
179
|
+
for element in jQuery('a, form', @document)
|
180
|
+
ignored = false
|
181
|
+
for classname in Mercury.config.nonHijackableClasses || []
|
182
|
+
if jQuery(element).hasClass(classname)
|
183
|
+
ignored = true
|
184
|
+
continue
|
185
|
+
if !ignored && (element.target == '' || element.target == '_self') && !jQuery(element).closest(".#{Mercury.config.regions.className}").length
|
186
|
+
jQuery(element).attr('target', '_parent')
|
187
|
+
|
188
|
+
|
189
|
+
beforeUnload: ->
|
190
|
+
if Mercury.changes && !Mercury.silent
|
191
|
+
return Mercury.I18n('You might have unsaved changes. Are you sure you want to leave without saving them first?')
|
192
|
+
Mercury.trigger('unload')
|
193
|
+
return null
|
194
|
+
|
195
|
+
|
196
|
+
getRegionByName: (id) ->
|
197
|
+
for region in @regions
|
198
|
+
return region if region.name == id
|
199
|
+
return null
|
200
|
+
|
201
|
+
autosave: ->
|
202
|
+
Mercury.log("Autosave")
|
203
|
+
url = @saveUrl ? Mercury.saveURL ? @iframeSrc()
|
204
|
+
data = @serialize()
|
205
|
+
data = jQuery.toJSON(data) unless @options.saveStyle == 'form'
|
206
|
+
method = 'PUT' if @options.saveMethod == 'PUT'
|
207
|
+
jQuery.ajax url+"&auto=1", {
|
208
|
+
headers: Mercury.ajaxHeaders()
|
209
|
+
type: method || 'POST'
|
210
|
+
dataType: @options.saveDataType || 'json'
|
211
|
+
data: {content: data, _method: method}
|
212
|
+
success: =>
|
213
|
+
Mercury.trigger('autosaved')
|
214
|
+
}
|
215
|
+
|
216
|
+
save: (callback) ->
|
217
|
+
url = @saveUrl ? Mercury.saveURL ? @iframeSrc()
|
218
|
+
data = @serialize()
|
219
|
+
Mercury.log('saving', data)
|
220
|
+
data = jQuery.toJSON(data) unless @options.saveStyle == 'form'
|
221
|
+
method = 'PUT' if @options.saveMethod == 'PUT'
|
222
|
+
jQuery.ajax url, {
|
223
|
+
headers: Mercury.ajaxHeaders()
|
224
|
+
type: method || 'POST'
|
225
|
+
dataType: @options.saveDataType || 'json'
|
226
|
+
data: {content: data, _method: method}
|
227
|
+
success: =>
|
228
|
+
Mercury.changes = false
|
229
|
+
Mercury.trigger('saved')
|
230
|
+
callback() if typeof(callback) == 'function'
|
231
|
+
error: =>
|
232
|
+
Mercury.notify('Mercury was unable to save to the url: %s', url)
|
233
|
+
}
|
234
|
+
|
235
|
+
|
236
|
+
serialize: ->
|
237
|
+
serialized = {}
|
238
|
+
for region in @regions
|
239
|
+
Mercury.log("region", region)
|
240
|
+
serialized[region.name] = region.serialize()
|
241
|
+
return serialized
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class @Mercury.Palette extends Mercury.Dialog
|
2
|
+
|
3
|
+
constructor: (@url, @name, @options = {}) ->
|
4
|
+
super
|
5
|
+
|
6
|
+
|
7
|
+
build: ->
|
8
|
+
@element = jQuery('<div>', {class: "mercury-palette mercury-#{@name}-palette loading", style: 'display:none'})
|
9
|
+
@element.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
10
|
+
|
11
|
+
|
12
|
+
bindEvents: ->
|
13
|
+
Mercury.on 'hide:dialogs', (event, dialog) => @hide() unless dialog == @
|
14
|
+
super
|
15
|
+
|
16
|
+
|
17
|
+
position: (keepVisible) ->
|
18
|
+
@element.css({top: 0, left: 0, display: 'block', visibility: 'hidden'})
|
19
|
+
position = @button.offset()
|
20
|
+
width = @element.width()
|
21
|
+
|
22
|
+
position.left = position.left - width + @button.width() if position.left + width > jQuery(window).width()
|
23
|
+
|
24
|
+
@element.css {
|
25
|
+
top: position.top + @button.height()
|
26
|
+
left: position.left
|
27
|
+
display: if keepVisible then 'block' else 'none'
|
28
|
+
visibility: 'visible'
|
29
|
+
}
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class @Mercury.Panel extends Mercury.Dialog
|
2
|
+
|
3
|
+
constructor: (@url, @name, @options = {}) ->
|
4
|
+
super
|
5
|
+
|
6
|
+
|
7
|
+
build: ->
|
8
|
+
@element = jQuery('<div>', {class: 'mercury-panel loading', style: 'display:none;'})
|
9
|
+
@titleElement = jQuery("<h1>#{Mercury.I18n(@options.title)}</h1>").appendTo(@element)
|
10
|
+
@paneElement = jQuery('<div>', {class: 'mercury-panel-pane'}).appendTo(@element)
|
11
|
+
|
12
|
+
if @options.closeButton
|
13
|
+
jQuery('<a/>', {class: 'mercury-panel-close'}).appendTo(@titleElement).css({opacity: 0})
|
14
|
+
|
15
|
+
@element.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
16
|
+
|
17
|
+
|
18
|
+
bindEvents: ->
|
19
|
+
Mercury.on 'resize', => @position(@visible)
|
20
|
+
|
21
|
+
Mercury.on 'hide:panels', (event, panel) =>
|
22
|
+
return if panel == @
|
23
|
+
@button.removeClass('pressed')
|
24
|
+
@hide()
|
25
|
+
|
26
|
+
@titleElement.find('.mercury-panel-close').on 'click', (event) ->
|
27
|
+
event.preventDefault()
|
28
|
+
Mercury.trigger('hide:panels')
|
29
|
+
|
30
|
+
@element.on 'mousedown', (event) ->
|
31
|
+
event.stopPropagation()
|
32
|
+
|
33
|
+
@element.on 'ajax:beforeSend', (event, xhr, options) =>
|
34
|
+
options.success = (content) =>
|
35
|
+
@loadContent(content)
|
36
|
+
@resize()
|
37
|
+
|
38
|
+
super
|
39
|
+
|
40
|
+
|
41
|
+
show: ->
|
42
|
+
Mercury.trigger('hide:panels', @)
|
43
|
+
super
|
44
|
+
|
45
|
+
|
46
|
+
resize: ->
|
47
|
+
@titleElement.find('.mercury-panel-close').css({opacity: 0})
|
48
|
+
@paneElement.css({display: 'none'})
|
49
|
+
preWidth = @element.width()
|
50
|
+
|
51
|
+
@paneElement.css({visibility: 'hidden', width: 'auto', display: 'block'})
|
52
|
+
postWidth = @element.width()
|
53
|
+
|
54
|
+
@paneElement.css({visibility: 'visible', display: 'none'})
|
55
|
+
position = @element.offset()
|
56
|
+
@element.animate {left: position.left - (postWidth - preWidth), width: postWidth}, 200, 'easeInOutSine', =>
|
57
|
+
@titleElement.find('.mercury-panel-close').animate({opacity: 1}, 100)
|
58
|
+
|
59
|
+
@paneElement.css({display: 'block', width: postWidth})
|
60
|
+
@makeDraggable()
|
61
|
+
|
62
|
+
@hide() unless @visible
|
63
|
+
|
64
|
+
|
65
|
+
position: (keepVisible) ->
|
66
|
+
@element.css({display: 'block', visibility: 'hidden'})
|
67
|
+
offset = @element.offset()
|
68
|
+
elementWidth = @element.width()
|
69
|
+
height = Mercury.displayRect.height - 16
|
70
|
+
|
71
|
+
paneHeight = height - @titleElement.outerHeight()
|
72
|
+
@paneElement.css({height: paneHeight, overflowY: if paneHeight < 30 then 'hidden' else 'auto'})
|
73
|
+
|
74
|
+
left = Mercury.displayRect.width - elementWidth - 20 unless @moved
|
75
|
+
left = 8 if left <= 8
|
76
|
+
|
77
|
+
if @pinned || elementWidth + offset.left > Mercury.displayRect.width - 20
|
78
|
+
left = Mercury.displayRect.width - elementWidth - 20
|
79
|
+
|
80
|
+
@element.css {
|
81
|
+
top: Mercury.displayRect.top + 8,
|
82
|
+
left: left,
|
83
|
+
height: height,
|
84
|
+
display: if keepVisible then 'block' else 'none',
|
85
|
+
visibility: 'visible'
|
86
|
+
}
|
87
|
+
|
88
|
+
@makeDraggable()
|
89
|
+
@element.hide() unless keepVisible
|
90
|
+
|
91
|
+
|
92
|
+
loadContent: (data) ->
|
93
|
+
@loaded = true
|
94
|
+
@element.removeClass('loading')
|
95
|
+
@paneElement.css({visibility: 'hidden'})
|
96
|
+
@paneElement.html(data)
|
97
|
+
@paneElement.localize(Mercury.locale()) if Mercury.config.localization.enabled
|
98
|
+
|
99
|
+
|
100
|
+
makeDraggable: ->
|
101
|
+
elementWidth = @element.width()
|
102
|
+
@element.draggable {
|
103
|
+
handle: 'h1',
|
104
|
+
axis: 'x',
|
105
|
+
opacity: 0.70
|
106
|
+
scroll: false,
|
107
|
+
addClasses: false,
|
108
|
+
iframeFix: true,
|
109
|
+
containment: [8, 0, Mercury.displayRect.width - elementWidth - 20, 0] #[x1, y1, x2, y2]
|
110
|
+
stop: =>
|
111
|
+
left = @element.offset().left
|
112
|
+
@moved = true
|
113
|
+
@pinned = if left > Mercury.displayRect.width - elementWidth - 30 then true else false
|
114
|
+
return true
|
115
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class Mercury.PageEditor extends Mercury.PageEditor
|
2
|
+
|
3
|
+
save: ->
|
4
|
+
url = @saveUrl ? Mercury.saveURL ? @iframeSrc()
|
5
|
+
data = @serializeAsXml()
|
6
|
+
console.log('saving', data)
|
7
|
+
return
|
8
|
+
method = 'PUT' if @options.saveMethod == 'PUT'
|
9
|
+
jQuery.ajax url, {
|
10
|
+
headers: Mercury.ajaxHeaders()
|
11
|
+
type: method || 'POST'
|
12
|
+
dataType: 'xml'
|
13
|
+
data: data
|
14
|
+
success: =>
|
15
|
+
Mercury.changes = false
|
16
|
+
error: =>
|
17
|
+
alert("Mercury was unable to save to the url: #{url}")
|
18
|
+
}
|
19
|
+
|
20
|
+
serializeAsXml: ->
|
21
|
+
data = @serialize()
|
22
|
+
regionNodes = []
|
23
|
+
for regionName, regionProperties of data
|
24
|
+
snippetNodes = []
|
25
|
+
for snippetName, snippetProperties of regionProperties['snippets']
|
26
|
+
snippetNodes.push("<#{snippetName} name=\"#{snippetProperties['name']}\"><![CDATA[#{jQuery.toJSON(snippetProperties['options'])}]]></#{snippetName}>")
|
27
|
+
regionNodes.push("<region name=\"#{regionName}\" type=\"#{regionProperties['type']}\"><value>\n<![CDATA[#{regionProperties['value']}]]>\n</value><snippets>#{snippetNodes.join('')}</snippets></region>")
|
28
|
+
return "<regions>#{regionNodes.join('')}</regions>"
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/*!
|
2
|
+
* This is an example plugin that will serialize to XML instead of JSON before saving. This could be useful to someone,
|
3
|
+
* but is mostly provided as an example of how to write a simple plugin.
|
4
|
+
*
|
5
|
+
* This file is could be a nice place to provide configuration options for your plugin.
|
6
|
+
*
|
7
|
+
*= require_self
|
8
|
+
*= require_tree ./mercury
|
9
|
+
*/
|
@@ -0,0 +1,107 @@
|
|
1
|
+
class @Mercury.Region
|
2
|
+
type = 'region'
|
3
|
+
|
4
|
+
constructor: (@element, @window, @options = {}) ->
|
5
|
+
@type = 'region' unless @type
|
6
|
+
Mercury.log("building #{@type}", @element, @options)
|
7
|
+
|
8
|
+
@document = @window.document
|
9
|
+
@name = @element.attr(Mercury.config.regions.identifier)
|
10
|
+
@history = new Mercury.HistoryBuffer()
|
11
|
+
@build()
|
12
|
+
@bindEvents()
|
13
|
+
@pushHistory()
|
14
|
+
@element.data('region', @)
|
15
|
+
|
16
|
+
|
17
|
+
build: ->
|
18
|
+
|
19
|
+
|
20
|
+
focus: ->
|
21
|
+
|
22
|
+
|
23
|
+
bindEvents: ->
|
24
|
+
Mercury.on 'mode', (event, options) => @togglePreview() if options.mode == 'preview'
|
25
|
+
|
26
|
+
Mercury.on 'focus:frame', =>
|
27
|
+
return if @previewing || Mercury.region != @
|
28
|
+
@focus()
|
29
|
+
|
30
|
+
Mercury.on 'action', (event, options) =>
|
31
|
+
return if @previewing || Mercury.region != @
|
32
|
+
@execCommand(options.action, options) if options.action
|
33
|
+
|
34
|
+
@element.on 'mousemove', (event) =>
|
35
|
+
return if @previewing || Mercury.region != @
|
36
|
+
snippet = jQuery(event.target).closest('.mercury-snippet')
|
37
|
+
if snippet.length
|
38
|
+
@snippet = snippet
|
39
|
+
Mercury.trigger('show:toolbar', {type: 'snippet', snippet: @snippet})
|
40
|
+
|
41
|
+
@element.on 'mouseout', =>
|
42
|
+
return if @previewing
|
43
|
+
Mercury.trigger('hide:toolbar', {type: 'snippet', immediately: false})
|
44
|
+
|
45
|
+
|
46
|
+
content: (value = null, filterSnippets = false) ->
|
47
|
+
if value != null
|
48
|
+
@element.html(value)
|
49
|
+
else
|
50
|
+
# sanitize the html before we return it
|
51
|
+
container = jQuery('<div>').appendTo(@document.createDocumentFragment())
|
52
|
+
container.html(@element.html().replace(/^\s+|\s+$/g, ''))
|
53
|
+
|
54
|
+
# replace snippet contents to be an identifier
|
55
|
+
if filterSnippets then for snippet in container.find('.mercury-snippet')
|
56
|
+
snippet = jQuery(snippet)
|
57
|
+
snippet.attr({contenteditable: null, 'data-version': null})
|
58
|
+
snippet.html("[#{snippet.data('snippet')}]")
|
59
|
+
|
60
|
+
return container.html()
|
61
|
+
|
62
|
+
|
63
|
+
togglePreview: ->
|
64
|
+
if @previewing
|
65
|
+
@previewing = false
|
66
|
+
@element.addClass(Mercury.config.regions.className).removeClass("#{Mercury.config.regions.className}-preview")
|
67
|
+
@focus() if Mercury.region == @
|
68
|
+
else
|
69
|
+
@previewing = true
|
70
|
+
@element.addClass("#{Mercury.config.regions.className}-preview").removeClass(Mercury.config.regions.className)
|
71
|
+
Mercury.trigger('region:blurred', {region: @})
|
72
|
+
|
73
|
+
|
74
|
+
execCommand: (action, options = {}) ->
|
75
|
+
@focus()
|
76
|
+
@pushHistory() unless action == 'redo'
|
77
|
+
|
78
|
+
Mercury.log('execCommand', action, options.value)
|
79
|
+
Mercury.changes = true unless options.already_handled
|
80
|
+
|
81
|
+
|
82
|
+
pushHistory: ->
|
83
|
+
@history.push(@content())
|
84
|
+
|
85
|
+
|
86
|
+
snippets: ->
|
87
|
+
snippets = {}
|
88
|
+
for element in @element.find('[data-snippet]')
|
89
|
+
snippet = Mercury.Snippet.find(jQuery(element).data('snippet'))
|
90
|
+
snippet.setVersion(jQuery(element).data('version'))
|
91
|
+
snippets[snippet.identity] = snippet.serialize()
|
92
|
+
return snippets
|
93
|
+
|
94
|
+
|
95
|
+
dataAttributes: ->
|
96
|
+
data = {}
|
97
|
+
o = if @type=='simple' then jQuery(this.container[0]) else @element
|
98
|
+
data[attr] = o.attr('data-' + attr) for attr in Mercury.config.regions.dataAttributes
|
99
|
+
return data
|
100
|
+
|
101
|
+
serialize: ->
|
102
|
+
return {
|
103
|
+
type: @type
|
104
|
+
data: @dataAttributes()
|
105
|
+
value: @content(null, true)
|
106
|
+
snippets: @snippets()
|
107
|
+
}
|