midas 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|