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,86 @@
|
|
1
|
+
class @Mercury.Toolbar
|
2
|
+
|
3
|
+
constructor: (@options = {}) ->
|
4
|
+
@visible = @options.visible
|
5
|
+
@build()
|
6
|
+
@bindEvents()
|
7
|
+
|
8
|
+
|
9
|
+
build: ->
|
10
|
+
@element = jQuery('<div>', {class: 'mercury-toolbar-container', style: 'width:10000px'})
|
11
|
+
@element.css({display: 'none'}) unless @visible
|
12
|
+
@element.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
13
|
+
|
14
|
+
for own toolbarName, buttons of Mercury.config.toolbars
|
15
|
+
continue if buttons._custom
|
16
|
+
toolbar = jQuery('<div>', {class: "mercury-toolbar mercury-#{toolbarName}-toolbar"}).appendTo(@element)
|
17
|
+
toolbar.attr('data-regions', buttons._regions) if buttons._regions
|
18
|
+
container = jQuery('<div>', {class: 'mercury-toolbar-button-container'}).appendTo(toolbar)
|
19
|
+
|
20
|
+
for own buttonName, options of buttons
|
21
|
+
continue if buttonName == '_regions'
|
22
|
+
button = @buildButton(buttonName, options)
|
23
|
+
button.appendTo(container) if button
|
24
|
+
|
25
|
+
if container.css('white-space') == 'nowrap'
|
26
|
+
expander = new Mercury.Toolbar.Expander(toolbarName, {appendTo: toolbar, for: container})
|
27
|
+
expander.appendTo(@element)
|
28
|
+
|
29
|
+
toolbar.addClass('disabled') if Mercury.config.toolbars['primary'] && toolbarName != 'primary'
|
30
|
+
|
31
|
+
@element.css({width: '100%'})
|
32
|
+
|
33
|
+
|
34
|
+
buildButton: (name, options) ->
|
35
|
+
return false if name[0] == '_'
|
36
|
+
switch jQuery.type(options)
|
37
|
+
when 'array' # button
|
38
|
+
[title, summary, handled] = options
|
39
|
+
new Mercury.Toolbar.Button(name, title, summary, handled, {appendDialogsTo: @element})
|
40
|
+
|
41
|
+
when 'object' # button group
|
42
|
+
group = new Mercury.Toolbar.ButtonGroup(name, options)
|
43
|
+
for own action, opts of options
|
44
|
+
button = @buildButton(action, opts)
|
45
|
+
button.appendTo(group) if button
|
46
|
+
group
|
47
|
+
|
48
|
+
when 'string' # separator
|
49
|
+
jQuery('<hr>', {class: "mercury-#{if options == '-' then 'line-separator' else 'separator'}"})
|
50
|
+
|
51
|
+
else throw Mercury.I18n('Unknown button structure -- please provide an array, object, or string for "%s".', name)
|
52
|
+
|
53
|
+
|
54
|
+
bindEvents: ->
|
55
|
+
Mercury.on 'region:focused', (event, options) =>
|
56
|
+
for toolbar in @element.find(".mercury-toolbar")
|
57
|
+
toolbar = jQuery(toolbar)
|
58
|
+
if regions = toolbar.data('regions')
|
59
|
+
toolbar.removeClass('disabled') if regions.split(',').indexOf(options.region.type) > -1
|
60
|
+
|
61
|
+
Mercury.on 'region:blurred', (event, options) =>
|
62
|
+
for toolbar in @element.find(".mercury-toolbar")
|
63
|
+
toolbar = jQuery(toolbar)
|
64
|
+
if regions = toolbar.data('regions')
|
65
|
+
toolbar.addClass('disabled') if regions.split(',').indexOf(options.region.type) > -1
|
66
|
+
|
67
|
+
@element.on 'click', ->
|
68
|
+
Mercury.trigger('hide:dialogs')
|
69
|
+
|
70
|
+
@element.on 'mousedown', (event) ->
|
71
|
+
event.preventDefault()
|
72
|
+
|
73
|
+
|
74
|
+
height: ->
|
75
|
+
if @visible then @element.outerHeight() else 0
|
76
|
+
|
77
|
+
|
78
|
+
show: ->
|
79
|
+
@visible = true
|
80
|
+
@element.css({top: -@element.outerHeight(), display: 'block'})
|
81
|
+
@element.animate({top: 0}, 200, 'easeInOutSine')
|
82
|
+
|
83
|
+
|
84
|
+
hide: ->
|
85
|
+
@visible = false
|
86
|
+
@element.hide()
|
@@ -0,0 +1,74 @@
|
|
1
|
+
@Mercury.tooltip = (forElement, content, options = {}) ->
|
2
|
+
Mercury.tooltip.show(forElement, content, options)
|
3
|
+
return Mercury.tooltip
|
4
|
+
|
5
|
+
jQuery.extend Mercury.tooltip,
|
6
|
+
|
7
|
+
show: (@forElement, @content, @options = {}) ->
|
8
|
+
@document = @forElement.get(0).ownerDocument
|
9
|
+
@initialize()
|
10
|
+
if @visible then @update() else @appear()
|
11
|
+
|
12
|
+
|
13
|
+
initialize: ->
|
14
|
+
return if @initialized
|
15
|
+
@build()
|
16
|
+
@bindEvents()
|
17
|
+
@initialized = true
|
18
|
+
|
19
|
+
|
20
|
+
build: ->
|
21
|
+
@element = jQuery('<div>', {class: 'mercury-tooltip'})
|
22
|
+
@element.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
23
|
+
|
24
|
+
|
25
|
+
bindEvents: ->
|
26
|
+
Mercury.on 'resize', => @position() if @visible
|
27
|
+
|
28
|
+
@element.on 'mousedown', (event) ->
|
29
|
+
event.preventDefault()
|
30
|
+
event.stopPropagation()
|
31
|
+
|
32
|
+
for parent in @forElement.parentsUntil(jQuery('body', @document))
|
33
|
+
continue unless parent.scrollHeight > parent.clientHeight
|
34
|
+
jQuery(parent).on 'scroll', =>
|
35
|
+
@position() if @visible
|
36
|
+
|
37
|
+
jQuery(@document).on 'scroll', =>
|
38
|
+
@position() if @visible
|
39
|
+
|
40
|
+
|
41
|
+
appear: ->
|
42
|
+
@update()
|
43
|
+
|
44
|
+
@element.show()
|
45
|
+
@element.animate {opacity: 1}, 200, 'easeInOutSine', =>
|
46
|
+
@visible = true
|
47
|
+
|
48
|
+
|
49
|
+
update: ->
|
50
|
+
@element.html(@content)
|
51
|
+
@position()
|
52
|
+
|
53
|
+
|
54
|
+
position: ->
|
55
|
+
offset = @forElement.offset()
|
56
|
+
width = @element.width()
|
57
|
+
|
58
|
+
top = offset.top + (Mercury.displayRect.top - jQuery(@document).scrollTop()) + @forElement.outerHeight()
|
59
|
+
left = offset.left - jQuery(@document).scrollLeft()
|
60
|
+
|
61
|
+
left = left - (left + width + 25) - Mercury.displayRect.width if (left + width + 25) > Mercury.displayRect.width
|
62
|
+
left = if left <= 0 then 0 else left
|
63
|
+
|
64
|
+
@element.css {
|
65
|
+
top: top
|
66
|
+
left: left
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
hide: ->
|
71
|
+
return unless @initialized
|
72
|
+
@element.hide()
|
73
|
+
@visible = false
|
74
|
+
|
@@ -0,0 +1,227 @@
|
|
1
|
+
@Mercury.uploader = (file, options) ->
|
2
|
+
Mercury.uploader.show(file, options) if Mercury.config.uploading.enabled
|
3
|
+
return Mercury.uploader
|
4
|
+
|
5
|
+
jQuery.extend Mercury.uploader,
|
6
|
+
|
7
|
+
show: (file, @options = {}) ->
|
8
|
+
@file = new Mercury.uploader.File(file)
|
9
|
+
if @file.errors
|
10
|
+
alert("Error: #{@file.errors}")
|
11
|
+
return
|
12
|
+
return unless @supported()
|
13
|
+
|
14
|
+
Mercury.trigger('focus:window')
|
15
|
+
@initialize()
|
16
|
+
@appear()
|
17
|
+
|
18
|
+
|
19
|
+
initialize: ->
|
20
|
+
return if @initialized
|
21
|
+
@build()
|
22
|
+
@bindEvents()
|
23
|
+
@initialized = true
|
24
|
+
|
25
|
+
|
26
|
+
supported: ->
|
27
|
+
xhr = new XMLHttpRequest
|
28
|
+
fileReader = window.FileReader
|
29
|
+
|
30
|
+
if window.Uint8Array && window.ArrayBuffer && !XMLHttpRequest.prototype.sendAsBinary
|
31
|
+
XMLHttpRequest::sendAsBinary = (datastr) ->
|
32
|
+
ui8a = new Uint8Array(datastr.length)
|
33
|
+
ui8a[index] = (datastr.charCodeAt(index) & 0xff) for data, index in datastr
|
34
|
+
@send(ui8a.buffer)
|
35
|
+
|
36
|
+
return !!(xhr.upload && xhr.sendAsBinary && fileReader)
|
37
|
+
|
38
|
+
|
39
|
+
build: ->
|
40
|
+
@element = jQuery('<div>', {class: 'mercury-uploader', style: 'display:none'})
|
41
|
+
@element.append('<div class="mercury-uploader-preview"><b><img/></b></div>')
|
42
|
+
@element.append('<div class="mercury-uploader-details"></div>')
|
43
|
+
@element.append('<div class="mercury-uploader-progress"><span></span><div class="mercury-uploader-indicator"><div><b>0%</b></div></div></div>')
|
44
|
+
|
45
|
+
@updateStatus('Processing...')
|
46
|
+
|
47
|
+
@overlay = jQuery('<div>', {class: 'mercury-uploader-overlay', style: 'display:none'})
|
48
|
+
|
49
|
+
@element.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
50
|
+
@overlay.appendTo(jQuery(@options.appendTo).get(0) ? 'body')
|
51
|
+
|
52
|
+
|
53
|
+
bindEvents: ->
|
54
|
+
Mercury.on 'resize', => @position()
|
55
|
+
|
56
|
+
|
57
|
+
appear: ->
|
58
|
+
@fillDisplay()
|
59
|
+
@position()
|
60
|
+
|
61
|
+
@overlay.show()
|
62
|
+
@overlay.animate {opacity: 1}, 200, 'easeInOutSine', =>
|
63
|
+
@element.show()
|
64
|
+
@element.animate {opacity: 1}, 200, 'easeInOutSine', =>
|
65
|
+
@visible = true
|
66
|
+
@loadImage()
|
67
|
+
|
68
|
+
|
69
|
+
position: ->
|
70
|
+
width = @element.outerWidth()
|
71
|
+
height = @element.outerHeight()
|
72
|
+
|
73
|
+
@element.css {
|
74
|
+
top: (Mercury.displayRect.height - height) / 2
|
75
|
+
left: (Mercury.displayRect.width - width) / 2
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
fillDisplay: ->
|
80
|
+
details = [
|
81
|
+
Mercury.I18n('Name: %s', @file.name),
|
82
|
+
Mercury.I18n('Size: %s', @file.readableSize),
|
83
|
+
Mercury.I18n('Type: %s', @file.type)
|
84
|
+
]
|
85
|
+
@element.find('.mercury-uploader-details').html(details.join('<br/>'))
|
86
|
+
|
87
|
+
|
88
|
+
loadImage: ->
|
89
|
+
@file.readAsDataURL (result) =>
|
90
|
+
@element.find('.mercury-uploader-preview b').html(jQuery('<img>', {src: result}))
|
91
|
+
@upload()
|
92
|
+
|
93
|
+
|
94
|
+
upload: ->
|
95
|
+
xhr = new XMLHttpRequest
|
96
|
+
jQuery.each ['onloadstart', 'onprogress', 'onload', 'onabort', 'onerror'], (index, eventName) =>
|
97
|
+
xhr.upload[eventName] = (event) => @uploaderEvents[eventName].call(@, event)
|
98
|
+
xhr.onload = (event) =>
|
99
|
+
if (event.currentTarget.status >= 400)
|
100
|
+
@updateStatus('Error: Unable to upload the file')
|
101
|
+
Mercury.notify('Unable to process response: %s', event.currentTarget.status)
|
102
|
+
@hide()
|
103
|
+
else
|
104
|
+
try
|
105
|
+
response =
|
106
|
+
if Mercury.config.uploading.handler
|
107
|
+
Mercury.config.uploading.handler(event.target.responseText)
|
108
|
+
else
|
109
|
+
jQuery.parseJSON(event.target.responseText)
|
110
|
+
src = response.url || response.image.url
|
111
|
+
throw 'Malformed response from server.' unless src
|
112
|
+
Mercury.trigger('action', {action: 'insertImage', value: {src: src}})
|
113
|
+
@hide()
|
114
|
+
catch error
|
115
|
+
@updateStatus('Error: Unable to upload the file')
|
116
|
+
Mercury.notify('Unable to process response: %s', error)
|
117
|
+
@hide()
|
118
|
+
|
119
|
+
xhr.open('post', Mercury.config.uploading.url, true)
|
120
|
+
xhr.setRequestHeader('Accept', 'application/json, text/javascript, text/html, application/xml, text/xml, */*')
|
121
|
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
|
122
|
+
xhr.setRequestHeader(Mercury.config.csrfHeader, Mercury.csrfToken)
|
123
|
+
|
124
|
+
@file.readAsBinaryString (result) =>
|
125
|
+
# build the multipart post string
|
126
|
+
multipart = new Mercury.uploader.MultiPartPost(Mercury.config.uploading.inputName, @file, result)
|
127
|
+
|
128
|
+
# update the content size so we can calculate
|
129
|
+
@file.updateSize(multipart.delta)
|
130
|
+
|
131
|
+
# set the content type and send
|
132
|
+
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + multipart.boundary)
|
133
|
+
xhr.sendAsBinary(multipart.body)
|
134
|
+
|
135
|
+
|
136
|
+
updateStatus: (message, loaded) ->
|
137
|
+
@element.find('.mercury-uploader-progress span').html(Mercury.I18n(message).toString())
|
138
|
+
if loaded
|
139
|
+
percent = Math.floor(loaded * 100 / @file.size) + '%'
|
140
|
+
@element.find('.mercury-uploader-indicator div').css({width: percent})
|
141
|
+
@element.find('.mercury-uploader-indicator b').html(percent).show()
|
142
|
+
|
143
|
+
|
144
|
+
hide: (delay = 0) ->
|
145
|
+
setTimeout delay * 1000, =>
|
146
|
+
@element.animate {opacity: 0}, 200, 'easeInOutSine', =>
|
147
|
+
@overlay.animate {opacity: 0}, 200, 'easeInOutSine', =>
|
148
|
+
@overlay.hide()
|
149
|
+
@element.hide()
|
150
|
+
@reset()
|
151
|
+
@visible = false
|
152
|
+
Mercury.trigger('focus:frame')
|
153
|
+
|
154
|
+
|
155
|
+
reset: ->
|
156
|
+
@element.find('.mercury-uploader-preview b').html('')
|
157
|
+
@element.find('.mercury-uploader-indicator div').css({width: 0})
|
158
|
+
@element.find('.mercury-uploader-indicator b').html('0%').hide()
|
159
|
+
@updateStatus('Processing...')
|
160
|
+
|
161
|
+
|
162
|
+
uploaderEvents:
|
163
|
+
onloadstart: -> @updateStatus('Uploading...')
|
164
|
+
|
165
|
+
onprogress: (event) -> @updateStatus('Uploading...', event.loaded)
|
166
|
+
|
167
|
+
onabort: ->
|
168
|
+
@updateStatus('Aborted')
|
169
|
+
@hide(1)
|
170
|
+
|
171
|
+
onload: ->
|
172
|
+
@updateStatus('Successfully uploaded...', @file.size)
|
173
|
+
|
174
|
+
onerror: ->
|
175
|
+
@updateStatus('Error: Unable to upload the file')
|
176
|
+
@hide(3)
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
class Mercury.uploader.File
|
181
|
+
|
182
|
+
constructor: (@file) ->
|
183
|
+
@size = @file.size
|
184
|
+
@fullSize = @file.size
|
185
|
+
@readableSize = @file.size.toBytes()
|
186
|
+
@name = @file.fileName
|
187
|
+
@name ||= @file.name
|
188
|
+
@type = @file.type
|
189
|
+
|
190
|
+
# add any errors if we need to
|
191
|
+
errors = []
|
192
|
+
errors.push(Mercury.I18n('Too large')) if @size >= Mercury.config.uploading.maxFileSize
|
193
|
+
errors.push(Mercury.I18n('Unsupported format')) unless Mercury.config.uploading.allowedMimeTypes.indexOf(@type) > -1
|
194
|
+
@errors = errors.join(' / ') if errors.length
|
195
|
+
|
196
|
+
|
197
|
+
readAsDataURL: (callback = null) ->
|
198
|
+
reader = new FileReader()
|
199
|
+
reader.readAsDataURL(@file)
|
200
|
+
reader.onload = => callback(reader.result) if callback
|
201
|
+
|
202
|
+
|
203
|
+
readAsBinaryString: (callback = null) ->
|
204
|
+
reader = new FileReader()
|
205
|
+
reader.readAsBinaryString(@file)
|
206
|
+
reader.onload = => callback(reader.result) if callback
|
207
|
+
|
208
|
+
|
209
|
+
updateSize: (delta) ->
|
210
|
+
@fullSize = @size + delta
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
class Mercury.uploader.MultiPartPost
|
215
|
+
|
216
|
+
constructor: (@inputName, @file, @contents, @formInputs = {}) ->
|
217
|
+
@boundary = 'Boundaryx20072377098235644401115438165x'
|
218
|
+
@body = ''
|
219
|
+
@buildBody()
|
220
|
+
@delta = @body.length - @file.size
|
221
|
+
|
222
|
+
|
223
|
+
buildBody: ->
|
224
|
+
boundary = '--' + @boundary
|
225
|
+
for own name, value of @formInputs
|
226
|
+
@body += "#{boundary}\r\nContent-Disposition: form-data; name=\"#{name}\"\r\n\r\n#{unescape(encodeURIComponent(value))}\r\n"
|
227
|
+
@body += "#{boundary}\r\nContent-Disposition: form-data; name=\"#{@inputName}\"; filename=\"#{@file.name}\"\r\nContent-Type: #{@file.type}\r\nContent-Transfer-Encoding: binary\r\n\r\n#{@contents}\r\n#{boundary}--"
|