midas 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.bundle/config +2 -0
- data/.document +5 -0
- data/.gitignore +32 -0
- data/Gemfile +12 -0
- data/LICENSE +20 -0
- data/README.textile +21 -0
- data/Rakefile +84 -0
- data/VERSION +1 -0
- data/features/step_definitions/editor_steps.rb +16 -0
- data/features/step_definitions/web_steps.rb +205 -0
- data/features/support/env.rb +39 -0
- data/features/support/paths.rb +29 -0
- data/features/view_editor.feature +8 -0
- data/generators/midas/midas_generator.rb +1 -0
- data/lib/midas.rb +1 -0
- data/midas.gemspec +131 -0
- data/public/images/midas/toolbars/actions/_background.png +0 -0
- data/public/images/midas/toolbars/actions/_background_radio.png +0 -0
- data/public/images/midas/toolbars/actions/_separator.png +0 -0
- data/public/images/midas/toolbars/actions/extra/prefspane.png +0 -0
- data/public/images/midas/toolbars/actions/extra/todospane.png +0 -0
- data/public/images/midas/toolbars/actions/historypanel.png +0 -0
- data/public/images/midas/toolbars/actions/insertcharacter.png +0 -0
- data/public/images/midas/toolbars/actions/insertlink.png +0 -0
- data/public/images/midas/toolbars/actions/insertmedia.png +0 -0
- data/public/images/midas/toolbars/actions/insertobject.png +0 -0
- data/public/images/midas/toolbars/actions/inserttable.png +0 -0
- data/public/images/midas/toolbars/actions/inspectorpanel.png +0 -0
- data/public/images/midas/toolbars/actions/notespanel.png +0 -0
- data/public/images/midas/toolbars/actions/preview.png +0 -0
- data/public/images/midas/toolbars/actions/redo.png +0 -0
- data/public/images/midas/toolbars/actions/save.png +0 -0
- data/public/images/midas/toolbars/actions/undo.png +0 -0
- data/public/images/midas/toolbars/htmleditor/_background.png +0 -0
- data/public/images/midas/toolbars/htmleditor/_line_separator.png +0 -0
- data/public/images/midas/toolbars/htmleditor/_separator.png +0 -0
- data/public/images/midas/toolbars/htmleditor/buttons.png +0 -0
- data/public/javascripts/midas/config.js +181 -0
- data/public/javascripts/midas/dialog.js +9 -0
- data/public/javascripts/midas/midas.js +307 -0
- data/public/javascripts/midas/native_extensions.js +43 -0
- data/public/javascripts/midas/palette.js +108 -0
- data/public/javascripts/midas/region.js +194 -0
- data/public/javascripts/midas/statusbar.js +84 -0
- data/public/javascripts/midas/toolbar.js +255 -0
- data/public/javascripts/prototype.js +6001 -0
- data/public/midas/backcolor.html +97 -0
- data/public/midas/examples/bundled.html +60 -0
- data/public/midas/examples/iframe.html +73 -0
- data/public/midas/examples/index.html +73 -0
- data/public/midas/examples/javascript_archive.js +111 -0
- data/public/midas/forecolor.html +97 -0
- data/public/stylesheets/midas/dialog.css +2 -0
- data/public/stylesheets/midas/midas.css +9 -0
- data/public/stylesheets/midas/palette.css +50 -0
- data/public/stylesheets/midas/region.css +16 -0
- data/public/stylesheets/midas/statusbar.css +17 -0
- data/public/stylesheets/midas/toolbar.css +262 -0
- data/rails/init.rb +1 -0
- data/spec/javascripts/dialog_spec.js +7 -0
- data/spec/javascripts/fixtures/midas_fixture.html +27 -0
- data/spec/javascripts/fixtures/midas_styles.css +14 -0
- data/spec/javascripts/fixtures/native_extensions_fixture.html +5 -0
- data/spec/javascripts/helpers/browser_detection.js +15 -0
- data/spec/javascripts/helpers/event_simulation.js +505 -0
- data/spec/javascripts/helpers/spec_helper.js +125 -0
- data/spec/javascripts/midas_spec.js +284 -0
- data/spec/javascripts/native_extensions_spec.js +39 -0
- data/spec/javascripts/palette_spec.js +59 -0
- data/spec/javascripts/region_spec.js +441 -0
- data/spec/javascripts/statusbar_spec.js +61 -0
- data/spec/javascripts/support/jasmine.yml +82 -0
- data/spec/javascripts/support/jasmine_config.rb +39 -0
- data/spec/javascripts/support/jasmine_runner.rb +19 -0
- data/spec/javascripts/toolbar_spec.js +149 -0
- data/spec/ruby/helpers/spec_helper.rb +9 -0
- data/spec/ruby/midas_spec.rb +9 -0
- data/spec/spec.opts +1 -0
- data/tasks/midas_tasks.rake +105 -0
- metadata +166 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module NavigationHelpers
|
2
|
+
# Maps a name to a path. Used by the
|
3
|
+
#
|
4
|
+
# When /^I go to (.+)$/ do |page_name|
|
5
|
+
#
|
6
|
+
# step definition in web_steps.rb
|
7
|
+
#
|
8
|
+
def path_to(page_name)
|
9
|
+
case page_name
|
10
|
+
|
11
|
+
when /the editor page/
|
12
|
+
'/integration/midas.html'
|
13
|
+
|
14
|
+
|
15
|
+
# Add more mappings here.
|
16
|
+
# Here is an example that pulls values out of the Regexp:
|
17
|
+
#
|
18
|
+
# when /^(.*)'s profile page$/i
|
19
|
+
# user_profile_path(User.find_by_login($1))
|
20
|
+
|
21
|
+
else
|
22
|
+
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
23
|
+
"Now, go and add a mapping in #{__FILE__}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
World(NavigationHelpers)
|
29
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
# generate tool views/controller -- put things in routes
|
data/lib/midas.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# basic rails hooks
|
data/midas.gemspec
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{midas}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jeremy Jackson"]
|
12
|
+
s.date = %q{2010-06-06}
|
13
|
+
s.description = %q{Provides a front end for editing content in a contextual way with WYSIWYG editing}
|
14
|
+
s.email = %q{jejacks0n@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.textile"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".bundle/config",
|
21
|
+
".document",
|
22
|
+
".gitignore",
|
23
|
+
"Gemfile",
|
24
|
+
"LICENSE",
|
25
|
+
"README.textile",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"features/step_definitions/editor_steps.rb",
|
29
|
+
"features/step_definitions/web_steps.rb",
|
30
|
+
"features/support/env.rb",
|
31
|
+
"features/support/paths.rb",
|
32
|
+
"features/view_editor.feature",
|
33
|
+
"generators/midas/midas_generator.rb",
|
34
|
+
"lib/midas.rb",
|
35
|
+
"midas.gemspec",
|
36
|
+
"public/images/midas/toolbars/actions/_background.png",
|
37
|
+
"public/images/midas/toolbars/actions/_background_radio.png",
|
38
|
+
"public/images/midas/toolbars/actions/_separator.png",
|
39
|
+
"public/images/midas/toolbars/actions/extra/prefspane.png",
|
40
|
+
"public/images/midas/toolbars/actions/extra/todospane.png",
|
41
|
+
"public/images/midas/toolbars/actions/historypanel.png",
|
42
|
+
"public/images/midas/toolbars/actions/insertcharacter.png",
|
43
|
+
"public/images/midas/toolbars/actions/insertlink.png",
|
44
|
+
"public/images/midas/toolbars/actions/insertmedia.png",
|
45
|
+
"public/images/midas/toolbars/actions/insertobject.png",
|
46
|
+
"public/images/midas/toolbars/actions/inserttable.png",
|
47
|
+
"public/images/midas/toolbars/actions/inspectorpanel.png",
|
48
|
+
"public/images/midas/toolbars/actions/notespanel.png",
|
49
|
+
"public/images/midas/toolbars/actions/preview.png",
|
50
|
+
"public/images/midas/toolbars/actions/redo.png",
|
51
|
+
"public/images/midas/toolbars/actions/save.png",
|
52
|
+
"public/images/midas/toolbars/actions/undo.png",
|
53
|
+
"public/images/midas/toolbars/htmleditor/_background.png",
|
54
|
+
"public/images/midas/toolbars/htmleditor/_line_separator.png",
|
55
|
+
"public/images/midas/toolbars/htmleditor/_separator.png",
|
56
|
+
"public/images/midas/toolbars/htmleditor/buttons.png",
|
57
|
+
"public/javascripts/midas/config.js",
|
58
|
+
"public/javascripts/midas/dialog.js",
|
59
|
+
"public/javascripts/midas/midas.js",
|
60
|
+
"public/javascripts/midas/native_extensions.js",
|
61
|
+
"public/javascripts/midas/palette.js",
|
62
|
+
"public/javascripts/midas/region.js",
|
63
|
+
"public/javascripts/midas/statusbar.js",
|
64
|
+
"public/javascripts/midas/toolbar.js",
|
65
|
+
"public/javascripts/prototype.js",
|
66
|
+
"public/midas/backcolor.html",
|
67
|
+
"public/midas/examples/bundled.html",
|
68
|
+
"public/midas/examples/iframe.html",
|
69
|
+
"public/midas/examples/index.html",
|
70
|
+
"public/midas/examples/javascript_archive.js",
|
71
|
+
"public/midas/forecolor.html",
|
72
|
+
"public/stylesheets/midas/dialog.css",
|
73
|
+
"public/stylesheets/midas/midas.css",
|
74
|
+
"public/stylesheets/midas/palette.css",
|
75
|
+
"public/stylesheets/midas/region.css",
|
76
|
+
"public/stylesheets/midas/statusbar.css",
|
77
|
+
"public/stylesheets/midas/toolbar.css",
|
78
|
+
"rails/init.rb",
|
79
|
+
"spec/javascripts/dialog_spec.js",
|
80
|
+
"spec/javascripts/fixtures/midas_fixture.html",
|
81
|
+
"spec/javascripts/fixtures/midas_styles.css",
|
82
|
+
"spec/javascripts/fixtures/native_extensions_fixture.html",
|
83
|
+
"spec/javascripts/helpers/browser_detection.js",
|
84
|
+
"spec/javascripts/helpers/event_simulation.js",
|
85
|
+
"spec/javascripts/helpers/spec_helper.js",
|
86
|
+
"spec/javascripts/midas_spec.js",
|
87
|
+
"spec/javascripts/native_extensions_spec.js",
|
88
|
+
"spec/javascripts/palette_spec.js",
|
89
|
+
"spec/javascripts/region_spec.js",
|
90
|
+
"spec/javascripts/statusbar_spec.js",
|
91
|
+
"spec/javascripts/support/jasmine.yml",
|
92
|
+
"spec/javascripts/support/jasmine_config.rb",
|
93
|
+
"spec/javascripts/support/jasmine_runner.rb",
|
94
|
+
"spec/javascripts/toolbar_spec.js",
|
95
|
+
"spec/ruby/helpers/spec_helper.rb",
|
96
|
+
"spec/ruby/midas_spec.rb",
|
97
|
+
"spec/spec.opts",
|
98
|
+
"tasks/midas_tasks.rake"
|
99
|
+
]
|
100
|
+
s.homepage = %q{http://github.com/jejacks0n/midas}
|
101
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
102
|
+
s.require_paths = ["lib"]
|
103
|
+
s.rubygems_version = %q{1.3.5}
|
104
|
+
s.summary = %q{A rich text editor gem for Rails}
|
105
|
+
s.test_files = [
|
106
|
+
"spec/javascripts/support/jasmine_config.rb",
|
107
|
+
"spec/javascripts/support/jasmine_runner.rb",
|
108
|
+
"spec/ruby/helpers/spec_helper.rb",
|
109
|
+
"spec/ruby/midas_spec.rb"
|
110
|
+
]
|
111
|
+
|
112
|
+
if s.respond_to? :specification_version then
|
113
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
114
|
+
s.specification_version = 3
|
115
|
+
|
116
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
117
|
+
s.add_runtime_dependency(%q<packr>, [">= 3.1.0"])
|
118
|
+
s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
|
119
|
+
s.add_development_dependency(%q<jasmine>, [">= 0.10.3.5"])
|
120
|
+
else
|
121
|
+
s.add_dependency(%q<packr>, [">= 3.1.0"])
|
122
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
123
|
+
s.add_dependency(%q<jasmine>, [">= 0.10.3.5"])
|
124
|
+
end
|
125
|
+
else
|
126
|
+
s.add_dependency(%q<packr>, [">= 3.1.0"])
|
127
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
128
|
+
s.add_dependency(%q<jasmine>, [">= 0.10.3.5"])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,181 @@
|
|
1
|
+
Midas.Config = {
|
2
|
+
|
3
|
+
/* The stylesheet to load for the skin of the toolbar/editable regions.
|
4
|
+
*/
|
5
|
+
stylesheet: '/stylesheets/midas.css',
|
6
|
+
|
7
|
+
/* Toolbars
|
8
|
+
*
|
9
|
+
* Any object you put in here will create a new toolbar.
|
10
|
+
*
|
11
|
+
* button format: [label, description, [type, action], [type, action], etc]
|
12
|
+
* type can be:
|
13
|
+
* 'button' (default) calls handleCommand and passes the key of the object (eg. save, preview, undo etc.)
|
14
|
+
* 'toggle' will toggle on or off when clicked (and otherwise behaves like a button)
|
15
|
+
* 'dialog' will open a dialog window, expects the action to be:
|
16
|
+
* a string url
|
17
|
+
* a function that returns a string url
|
18
|
+
* 'panel' will open a panel dialog, expects the action to be:
|
19
|
+
* a string url
|
20
|
+
* a function that returns a string url
|
21
|
+
* 'palette' will open a palette window, expects the action to be:
|
22
|
+
* a string url
|
23
|
+
* a function that returns a string url
|
24
|
+
* 'select' will open a select/pulldown style window, expects the action to be:
|
25
|
+
* an array
|
26
|
+
* a function that returns an array
|
27
|
+
* 'context' will call a callback function, expects the action to be:
|
28
|
+
* a function that returns a boolean to highlight the button or not
|
29
|
+
* note: if a function isn't provided, the key will be passed to the
|
30
|
+
* contextHandler (eg. backcolor, bold, etc.), in which case a
|
31
|
+
* default context will be used (there are several defined in
|
32
|
+
* Midas.Toolbar.contexts).
|
33
|
+
* 'mode' will toggle a given mode in the editor, expects the action to be:
|
34
|
+
* a string, denoting the name of the mode
|
35
|
+
* note: if a string isn't provided, the key will be passed to the
|
36
|
+
* modeHandler (eg. preview, html, etc.)
|
37
|
+
* note: it's assumed that when a specific "mode" is turned on, all other "modes" will be
|
38
|
+
* turned off (this happens automatically), thus putting the editor into a specific
|
39
|
+
* "state".
|
40
|
+
*
|
41
|
+
* If a button is an object (not an array, not a string), it's assumed that it's a button group,
|
42
|
+
* all of it's children will be expected to be buttons or button groups. A button group is
|
43
|
+
* wrapped within a div for styling. It's important to note that each of the keys, regardless of
|
44
|
+
* if it's in a group or not needs to be unique.
|
45
|
+
*
|
46
|
+
* The save action is special, in that it's handled by Midas directly, all other actions are
|
47
|
+
* handled by Midas.Region.
|
48
|
+
*
|
49
|
+
* Separators are any "button" that's not an array, and are expected to be a string. You can use
|
50
|
+
* three different separator styles: line, spacer, and flex spacer.
|
51
|
+
* '-' = line
|
52
|
+
* ' ' = spacer
|
53
|
+
* '*' = flex spacer
|
54
|
+
*/
|
55
|
+
toolbars: {
|
56
|
+
actions: {
|
57
|
+
save: ['Save', 'Save this page'],
|
58
|
+
preview: ['Preview', 'Preview this page', ['toggle'], ['mode']],
|
59
|
+
sep1: ' ',
|
60
|
+
undo: ['Undo', 'Undo your last action'],
|
61
|
+
redo: ['Redo', 'Redo your last action'],
|
62
|
+
sep2: ' ',
|
63
|
+
insertlink: ['Link', 'Insert a hyperlink', ['dialog', '/midas/link']],
|
64
|
+
insertmedia: ['Media', 'Insert media', ['dialog', '/midas/media']],
|
65
|
+
inserttable: ['Table', 'Insert a table', ['dialog', '/midas/table']],
|
66
|
+
insertobject: ['Object', 'Insert an object (form, widget, etc)', ['dialog', '/midas/object']],
|
67
|
+
insertcharacter: ['Character', 'Insert special characters', ['dialog', '/midas/character']],
|
68
|
+
inspectorpanel: ['Inspector', 'Open the element inspector panel', ['panel', '/midas/inspector']],
|
69
|
+
sep3: '*',
|
70
|
+
notespanel: ['Notes', 'Open the page notes panel', ['panel', '/midas/notes']],
|
71
|
+
historypanel: ['History', 'Open the page history panel', ['panel', '/midas/history']]
|
72
|
+
},
|
73
|
+
htmleditor: {
|
74
|
+
style: ['Style', '', ['select', function() { return Midas.Config.styles }]],
|
75
|
+
formatblock: ['Block Format', '', ['select', function() { return Midas.Config.blocks }]],
|
76
|
+
sep1: '-',
|
77
|
+
//backcolor: ['Background Color', '', ['palette', '/midas/backcolor.html'], ['context']],
|
78
|
+
forecolor: ['Text Color', '', ['palette', '/midas/forecolor.html'], ['context']],
|
79
|
+
sep2: '-',
|
80
|
+
decoration: {
|
81
|
+
bold: ['Bold', '', ['context']],
|
82
|
+
italic: ['Italicize', '', ['context']],
|
83
|
+
//overline: ['Overline', '', ['context']],
|
84
|
+
strikethrough: ['Strikethrough', '', ['context']],
|
85
|
+
underline: ['Underline', '', ['context']],
|
86
|
+
sep: '-'
|
87
|
+
},
|
88
|
+
script: {
|
89
|
+
subscript: ['Subscript', '', ['context']],
|
90
|
+
superscript: ['Superscript', '', ['context']],
|
91
|
+
sep: '-'
|
92
|
+
},
|
93
|
+
justify: {
|
94
|
+
justifyleft: ['Align Left', '', ['context']],
|
95
|
+
justifycenter: ['Center', '', ['context']],
|
96
|
+
justifyright: ['Align Right', '', ['context']],
|
97
|
+
justifyfull: ['Justify Full', '', ['context']],
|
98
|
+
sep: '-'
|
99
|
+
},
|
100
|
+
list: {
|
101
|
+
insertunorderedlist: ['Unordered List', '', ['context']],
|
102
|
+
insertorderedlist: ['Numbered List', '', ['context']],
|
103
|
+
sep: '-'
|
104
|
+
},
|
105
|
+
indent: {
|
106
|
+
outdent: ['Decrease Indentation', ''],
|
107
|
+
indent: ['Increase Indentation', ''],
|
108
|
+
sep: '-'
|
109
|
+
},
|
110
|
+
//table: {
|
111
|
+
// insertrowbefore: ['Insert Row', 'Insert a table row before'],
|
112
|
+
// insertrowafter: ['Insert Row', 'Insert a table row after'],
|
113
|
+
// deleterow: ['Delete Row', 'Delete this table row'],
|
114
|
+
// insertcolumnbefore: ['Insert Column', 'Insert a table column before'],
|
115
|
+
// insertcolumnafter: ['Insert Column', 'Insert a table column after'],
|
116
|
+
// deletecolumn: ['Delete Column', 'Delete this table column'],
|
117
|
+
// sep: '-'
|
118
|
+
// },
|
119
|
+
breaks: {
|
120
|
+
horizontalrule: ['Horizontal Rule', ''],
|
121
|
+
sep: '-'
|
122
|
+
},
|
123
|
+
removeformatting: ['Remove Formatting', ''],
|
124
|
+
html: ['Edit HTML', '', ['dialog', '/midas/html']]
|
125
|
+
}
|
126
|
+
},
|
127
|
+
|
128
|
+
/* Behaviors
|
129
|
+
*
|
130
|
+
* Behaviors are used to change the default behaviors of the editor when a given button is
|
131
|
+
* clicked. For example, we prefer to add HR tags using an HR wrapped within a div with a
|
132
|
+
* classname of hr, which allows for more flexible styling. To add your own complex
|
133
|
+
* behaviors just prototype them onto Midas.Region.handle.
|
134
|
+
*
|
135
|
+
* An example behavior would be to add a new button, called buynowbutton, and providing a
|
136
|
+
* behavior like:
|
137
|
+
*
|
138
|
+
* buynowbutton: {insertElement: function() {
|
139
|
+
* return new Element('a', {href: '/buy-now', class: 'buy-now'}).update('Buy Now!');
|
140
|
+
* }}
|
141
|
+
*
|
142
|
+
* It's important to note that the this keyword inside of the callback functions applies to an
|
143
|
+
* instance of Midas.Region.
|
144
|
+
*
|
145
|
+
* Behavior Methods, and expected arguments (arguments can be provided in an array when there
|
146
|
+
* is more than one expected):
|
147
|
+
* execCommand: a string of the action to take, or an array [action to take, argument]
|
148
|
+
* insertHTML: a callback function that returns a string
|
149
|
+
* ...
|
150
|
+
*/
|
151
|
+
behaviors: {
|
152
|
+
horizontalrule: {insertHTML: function() {
|
153
|
+
return '<div class="hr"><hr/></div>';
|
154
|
+
}}
|
155
|
+
},
|
156
|
+
|
157
|
+
/* CSS Classes that can be inserted using the toolbar
|
158
|
+
* -- will wrap selections in spans with a classname of whatever is selected
|
159
|
+
*/
|
160
|
+
styles: [
|
161
|
+
['red', 'Red text'],
|
162
|
+
['bold', 'Large bold text'],
|
163
|
+
['blue', 'Blue background']
|
164
|
+
],
|
165
|
+
|
166
|
+
/* Block elements that can be inserted using the toolbar
|
167
|
+
* -- will wrap selections in selected element
|
168
|
+
*/
|
169
|
+
blocks: [
|
170
|
+
['<h1>', 'Heading 1 <h1>'],
|
171
|
+
['<h2>', 'Heading 2 <h2>'],
|
172
|
+
['<h3>', 'Heading 3 <h3>'],
|
173
|
+
['<h4>', 'Heading 4 <h4>'],
|
174
|
+
['<h5>', 'Heading 5 <h5>'],
|
175
|
+
['<h6>', 'Heading 6 <h6>'],
|
176
|
+
['<p>', 'Paragraph'],
|
177
|
+
['<blockquote>', 'Blockquote <blockquote>']
|
178
|
+
['<pre>', 'Formatted <pre>']
|
179
|
+
]
|
180
|
+
|
181
|
+
};
|
@@ -0,0 +1,307 @@
|
|
1
|
+
var Midas = Class.create({
|
2
|
+
version: 0.2,
|
3
|
+
options: {
|
4
|
+
classname: 'editable',
|
5
|
+
saveUrl: window.location.href,
|
6
|
+
saveMethod: 'put',
|
7
|
+
configuration: null,
|
8
|
+
useIframe: false // boolean true, or a string of the document to load
|
9
|
+
},
|
10
|
+
contentWindow: window,
|
11
|
+
actionsToHandle: ['save'],
|
12
|
+
|
13
|
+
initialize: function(options, toolbarOptions, regionOptions, statusbarOptions) {
|
14
|
+
options = options || {};
|
15
|
+
if (!Midas.agentIsCapable()) throw('Midas requires a browser that has contentEditable features');
|
16
|
+
if (options['useIframe'] && !window.isTop()) {
|
17
|
+
Midas.trace('Midas will only instantiate in "top", when using an iframe');
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
|
21
|
+
Midas.registerInstance(this);
|
22
|
+
|
23
|
+
this.options = Object.extend(Object.clone(this.options), options);
|
24
|
+
this.options['configuration'] = this.options['configuration'] || Midas.Config;
|
25
|
+
this.config = this.options['configuration'];
|
26
|
+
|
27
|
+
this.toolbarOptions = toolbarOptions || {};
|
28
|
+
this.statusbarOptions = statusbarOptions || {};
|
29
|
+
this.regionOptions = regionOptions || {};
|
30
|
+
|
31
|
+
this.initializeInterface();
|
32
|
+
|
33
|
+
this.setupObservers();
|
34
|
+
},
|
35
|
+
|
36
|
+
initializeInterface: function() {
|
37
|
+
this.regions = [];
|
38
|
+
|
39
|
+
if (this.options['useIframe']) {
|
40
|
+
var src = (this.options['useIframe'] === true) ? window.location.href + '?midas_regions=true' : this.options['useIframe'];
|
41
|
+
|
42
|
+
this.iframe = new Element('iframe', {
|
43
|
+
seamless: 'true',
|
44
|
+
frameborder: '0',
|
45
|
+
className: 'midas-iframe-window',
|
46
|
+
src: 'about:blank'
|
47
|
+
});
|
48
|
+
|
49
|
+
Event.observe(this.iframe, 'load', function() {
|
50
|
+
this.initializeRegions(this.iframe.contentWindow);
|
51
|
+
this.finalizeInterface();
|
52
|
+
}.bind(this));
|
53
|
+
|
54
|
+
this.iframe.src = src;
|
55
|
+
this.iframeContainer = new Element('div', {'class': 'midas-iframe-container'});
|
56
|
+
this.iframeContainer.appendChild(this.iframe);
|
57
|
+
|
58
|
+
document.body.setStyle('overflow:hidden');
|
59
|
+
document.body.appendChild(this.iframeContainer);
|
60
|
+
} else {
|
61
|
+
this.initializeRegions(this.contentWindow);
|
62
|
+
this.finalizeInterface();
|
63
|
+
}
|
64
|
+
},
|
65
|
+
|
66
|
+
initializeRegions: function(contentWindow) {
|
67
|
+
this.contentWindow = contentWindow;
|
68
|
+
Object.extend(this.regionOptions, {contentWindow: this.contentWindow, configuration: this.options['configuration']});
|
69
|
+
|
70
|
+
var body = this.contentWindow.document.body;
|
71
|
+
if (typeof(body.select) == 'function') {
|
72
|
+
this.regionElements = body.select('div.' + this.options['classname']);
|
73
|
+
} else {
|
74
|
+
this.regionElements = body.getElementsByClassName(this.options['classname']);
|
75
|
+
}
|
76
|
+
|
77
|
+
for (var i = 0; i < this.regionElements.length; ++i) {
|
78
|
+
this.regions.push(new Midas.Region(this.regionElements[i], this.regionOptions, 'midas' + this._id + '_region_' + i));
|
79
|
+
}
|
80
|
+
},
|
81
|
+
|
82
|
+
finalizeInterface: function() {
|
83
|
+
if (this.regions[0]) this.setActiveRegion(this.regions[0]);
|
84
|
+
|
85
|
+
Object.extend(this.toolbarOptions, {contentWindow: this.contentWindow, configuration: this.options['configuration']});
|
86
|
+
Object.extend(this.statusbarOptions, {contentWindow: this.contentWindow, configuration: this.options['configuration']});
|
87
|
+
|
88
|
+
this.toolbar = new Midas.Toolbar(this.toolbarOptions);
|
89
|
+
this.statusbar = new Midas.Statusbar(this.statusbarOptions);
|
90
|
+
|
91
|
+
this.resize();
|
92
|
+
|
93
|
+
},
|
94
|
+
|
95
|
+
setupObservers: function() {
|
96
|
+
window.onbeforeunload = this.onBeforeUnload.bind(this);
|
97
|
+
Event.observe(window, 'resize', this.resize.bind(this));
|
98
|
+
|
99
|
+
Event.observe(document, 'mouseup', function(e) {
|
100
|
+
var element = Event.element(e);
|
101
|
+
if (this.toolbar && (element.descendantOf(this.toolbar.element) || element == this.toolbar.element)) return;
|
102
|
+
for (var i = 0; i < this.regions.length; ++i) {
|
103
|
+
if (element == this.regions[i].element || element.descendantOf(this.regions[i].element)) return;
|
104
|
+
}
|
105
|
+
|
106
|
+
this.setActiveRegion(null);
|
107
|
+
if (this.toolbar) this.toolbar.unsetActiveButtons();
|
108
|
+
}.bind(this));
|
109
|
+
|
110
|
+
//{action: action, event: event, toolbar: this}
|
111
|
+
Event.observe(document, 'midas:button', function(e) {
|
112
|
+
if (!this.activeRegion) return;
|
113
|
+
var a = e.memo;
|
114
|
+
|
115
|
+
if (this.toolbar != a['toolbar']) return;
|
116
|
+
this.changed = true;
|
117
|
+
|
118
|
+
var handled = this.handleAction(a['action'], a['event'], a['toolbar'], a['options']);
|
119
|
+
if (!handled) this.activeRegion.handleAction(a['action'], a['event'], a['toolbar'], a['options']);
|
120
|
+
if (this.statusbar) this.statusbar.update(this.activeRegion, e);
|
121
|
+
if (this.toolbar) this.toolbar.setActiveButtons(this.regions, this.activeRegion);
|
122
|
+
}.bindAsEventListener(this));
|
123
|
+
|
124
|
+
//{mode: mode, toolbar: this}
|
125
|
+
Event.observe(document, 'midas:mode', function(e) {
|
126
|
+
if (!this.activeRegion) return;
|
127
|
+
var a = e.memo;
|
128
|
+
|
129
|
+
if (this.toolbar != a['toolbar']) return;
|
130
|
+
|
131
|
+
this.handleMode(a['mode'], a['toolbar']);
|
132
|
+
}.bindAsEventListener(this));
|
133
|
+
|
134
|
+
//{region: this, name: this.name, event: event}
|
135
|
+
Event.observe(document, 'midas:region', function(e) {
|
136
|
+
var a = e.memo;
|
137
|
+
if (this.regions.indexOf(a['region']) < 0) return;
|
138
|
+
|
139
|
+
if (a['changed']) this.changed = true;
|
140
|
+
this.setActiveRegion(a['region']);
|
141
|
+
}.bindAsEventListener(this));
|
142
|
+
|
143
|
+
//{region: this, name: this.name, event: event}
|
144
|
+
Event.observe(document, 'midas:region:update', function(e) {
|
145
|
+
var a = e.memo;
|
146
|
+
|
147
|
+
Midas.fire('region', e.memo);
|
148
|
+
|
149
|
+
if (this.regions.indexOf(a['region']) < 0) return;
|
150
|
+
|
151
|
+
if (this.statusbar) this.statusbar.update(this.activeRegion, a['event']);
|
152
|
+
if (this.toolbar) this.toolbar.setActiveButtons(this.regions, this.activeRegion);
|
153
|
+
}.bind(this));
|
154
|
+
},
|
155
|
+
|
156
|
+
setActiveRegion: function(region) {
|
157
|
+
this.activeRegion = region;
|
158
|
+
},
|
159
|
+
|
160
|
+
handleAction: function(action, event, toolbar, options) {
|
161
|
+
options = options || {};
|
162
|
+
|
163
|
+
if (this.actionsToHandle.indexOf(action) < 0) return false;
|
164
|
+
if (Object.isFunction(this[action])) return this[action].apply(this, arguments);
|
165
|
+
|
166
|
+
throw('Unhandled action "' + action + '"');
|
167
|
+
},
|
168
|
+
|
169
|
+
handleMode: function(mode, toolbar) {
|
170
|
+
//!!
|
171
|
+
},
|
172
|
+
|
173
|
+
serialize: function() {
|
174
|
+
var serialized = {};
|
175
|
+
this.regions.each(function(region) {
|
176
|
+
var value = region.serialize();
|
177
|
+
serialized[value.name] = value.content;
|
178
|
+
});
|
179
|
+
return serialized;
|
180
|
+
},
|
181
|
+
|
182
|
+
save: function() {
|
183
|
+
var method = this.options.saveMethod;
|
184
|
+
var parameters = {};
|
185
|
+
if (method.toUpperCase() != 'POST' && method.toUpperCase() != 'GET') {
|
186
|
+
parameters['_method'] = method;
|
187
|
+
}
|
188
|
+
|
189
|
+
new Ajax.Request(this.options.saveUrl, {
|
190
|
+
method: method,
|
191
|
+
parameters: Object.extend(parameters, this.serialize()),
|
192
|
+
onSuccess: function() {
|
193
|
+
this.changed = false;
|
194
|
+
}.bind(this)
|
195
|
+
});
|
196
|
+
|
197
|
+
return true;
|
198
|
+
},
|
199
|
+
|
200
|
+
resize: function() {
|
201
|
+
var view = document.viewport.getDimensions();
|
202
|
+
|
203
|
+
if (this.iframe) {
|
204
|
+
var toolbarHeight = (this.toolbar) ? this.toolbar.getHeight() : 0;
|
205
|
+
var statusbarHeight = (this.statusbar) ? this.statusbar.getHeight() : 0;
|
206
|
+
this.iframeContainer.setStyle({
|
207
|
+
height: (view.height - statusbarHeight - toolbarHeight - 10) + 'px',
|
208
|
+
width: view.width + 'px',
|
209
|
+
top: this.toolbar.getHeight() + 'px',
|
210
|
+
left: 0
|
211
|
+
});
|
212
|
+
this.iframe.setStyle({
|
213
|
+
height: (view.height - statusbarHeight - toolbarHeight - 10) + 'px',
|
214
|
+
width: view.width + 'px'
|
215
|
+
});
|
216
|
+
}
|
217
|
+
},
|
218
|
+
|
219
|
+
onBeforeUnload: function() {
|
220
|
+
if (this.changed) return "You've made changes without saving them. Are you sure you'd like to navigate away without saving them first?";
|
221
|
+
},
|
222
|
+
|
223
|
+
destroy: function() {
|
224
|
+
if (this.toolbar) this.toolbar.destroy();
|
225
|
+
if (this.statusbar) this.statusbar.destroy();
|
226
|
+
this.regions.each(function(region) {
|
227
|
+
region.destroy();
|
228
|
+
});
|
229
|
+
if (this.iframe) {
|
230
|
+
this.iframe.remove();
|
231
|
+
this.iframe = null;
|
232
|
+
}
|
233
|
+
this.toolbar = null;
|
234
|
+
this.statusbar = null;
|
235
|
+
this.regions = [];
|
236
|
+
Midas.unregisterInstance(this);
|
237
|
+
}
|
238
|
+
});
|
239
|
+
|
240
|
+
// Midas static methods
|
241
|
+
Object.extend(Midas, {
|
242
|
+
version: 0.2,
|
243
|
+
instances: [],
|
244
|
+
agentId: null,
|
245
|
+
debugMode: false,
|
246
|
+
|
247
|
+
registerInstance: function(instance) {
|
248
|
+
this.instances.push(instance);
|
249
|
+
},
|
250
|
+
|
251
|
+
unregisterInstance: function(instance) {
|
252
|
+
this.instances = this.instances.without(instance);
|
253
|
+
},
|
254
|
+
|
255
|
+
agent: function() {
|
256
|
+
if (this.agentId) return this.agentId;
|
257
|
+
|
258
|
+
var agent = navigator.userAgent.toLowerCase();
|
259
|
+
|
260
|
+
var name = null;
|
261
|
+
if ((agent.indexOf("msie") != -1) && (agent.indexOf("opera") == -1) && (agent.indexOf("webtv") == -1)) {
|
262
|
+
name = 'msie';
|
263
|
+
} else if (agent.indexOf("opera") != -1) {
|
264
|
+
name = 'opera';
|
265
|
+
} else if (agent.indexOf("gecko") != -1) {
|
266
|
+
name = 'gecko';
|
267
|
+
} else if (agent.indexOf("safari") != -1) {
|
268
|
+
name = 'safari';
|
269
|
+
} else if (agent.indexOf("konqueror") != -1) {
|
270
|
+
name = 'konqueror';
|
271
|
+
}
|
272
|
+
|
273
|
+
this.agentId = name;
|
274
|
+
return name;
|
275
|
+
},
|
276
|
+
|
277
|
+
agentIsCapable: function() {
|
278
|
+
var agent = Midas.agent();
|
279
|
+
|
280
|
+
// TODO: IE is disabled at this point because it doesn't follow the w3c standards in regards to designMode.
|
281
|
+
return (agent && document.getElementById && document.designMode && agent != 'konqueror' && agent != 'msie') ? true : false;
|
282
|
+
},
|
283
|
+
|
284
|
+
fire: function(event, memo) {
|
285
|
+
event = 'midas:' + event;
|
286
|
+
Midas.trace('Midas.fire', event, memo);
|
287
|
+
|
288
|
+
Event.fire(document, event, memo);
|
289
|
+
},
|
290
|
+
|
291
|
+
trace: function() {
|
292
|
+
var args = [];
|
293
|
+
for (var i = 0; i < arguments.length; ++i) args.push(arguments[i]);
|
294
|
+
if (Midas.debugMode && typeof(console) != 'undefined') {
|
295
|
+
try {
|
296
|
+
console.debug(args);
|
297
|
+
} catch(e1) {
|
298
|
+
try {
|
299
|
+
console.info(args);
|
300
|
+
} catch(e2) {
|
301
|
+
try { console.log(args); } catch(e3) {}
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
});
|
307
|
+
|