zen 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gems +34 -0
- data/.travis.yml +7 -0
- data/AUTHORS +5 -0
- data/CHANGELOG +14 -0
- data/{license.txt → LICENSE} +0 -0
- data/MANIFEST +67 -51
- data/README.md +18 -25
- data/Rakefile +2 -3
- data/bin/zen +2 -2
- data/lib/zen.rb +93 -57
- data/lib/zen/asset.rb +7 -8
- data/lib/zen/bin/app.rb +0 -2
- data/lib/zen/controller/admin_controller.rb +4 -9
- data/lib/zen/controller/base_controller.rb +0 -25
- data/lib/zen/controller/main_controller.rb +5 -5
- data/lib/zen/controller/preview.rb +50 -0
- data/lib/zen/helper/common.rb +4 -68
- data/lib/zen/helper/message.rb +82 -0
- data/lib/zen/helper/theme.rb +2 -2
- data/lib/zen/language.rb +68 -38
- data/lib/zen/language/en/zen_general.yml +1 -4
- data/lib/zen/language/nl/zen_general.yml +28 -0
- data/lib/zen/language/nl/zen_models.yml +13 -0
- data/lib/zen/layout/admin.xhtml +1 -1
- data/lib/zen/layout/login.xhtml +1 -1
- data/lib/zen/model/settings.rb +2 -0
- data/lib/zen/package.rb +29 -25
- data/lib/zen/package/all.rb +1 -1
- data/lib/zen/package/categories/lib/categories/controller/categories.rb +51 -63
- data/lib/zen/package/categories/lib/categories/controller/category_groups.rb +45 -52
- data/lib/zen/package/categories/lib/categories/language/en/categories.yml +2 -2
- data/lib/zen/package/categories/lib/categories/language/nl/categories.yml +39 -0
- data/lib/zen/package/categories/lib/categories/language/nl/category_groups.yml +33 -0
- data/lib/zen/package/categories/lib/categories/plugin/categories.rb +2 -2
- data/lib/zen/package/comments/lib/comments.rb +31 -2
- data/lib/zen/package/comments/lib/comments/controller/comments.rb +42 -57
- data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +36 -51
- data/lib/zen/package/comments/lib/comments/language/en/comments.yml +7 -3
- data/lib/zen/package/comments/lib/comments/language/nl/comments.yml +48 -0
- data/lib/zen/package/comments/lib/comments/model/comment.rb +45 -4
- data/lib/zen/package/comments/lib/comments/plugin/anti_spam.rb +152 -0
- data/lib/zen/package/comments/lib/comments/plugin/comments.rb +5 -6
- data/lib/zen/package/comments/lib/comments/view/admin/comments/index.xhtml +2 -2
- data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_groups.rb +43 -52
- data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_fields.rb +68 -67
- data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_fields.yml +1 -1
- data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_field_groups.yml +32 -0
- data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_fields.yml +52 -0
- data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field.rb +3 -3
- data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_group.rb +4 -7
- data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +3 -3
- data/lib/zen/package/menus/lib/menus/controller/menu_items.rb +37 -44
- data/lib/zen/package/menus/lib/menus/controller/menus.rb +33 -43
- data/lib/zen/package/menus/lib/menus/helper/menu_item.rb +5 -10
- data/lib/zen/package/menus/lib/menus/language/nl/menu_items.yml +41 -0
- data/lib/zen/package/menus/lib/menus/language/nl/menus.yml +39 -0
- data/lib/zen/package/menus/lib/menus/model/menu.rb +3 -3
- data/lib/zen/package/menus/lib/menus/model/menu_item.rb +3 -3
- data/lib/zen/package/menus/lib/menus/plugin/menus.rb +5 -6
- data/lib/zen/package/menus/migrations/1297184342_create_schema.rb +1 -1
- data/lib/zen/package/sections/lib/sections.rb +20 -0
- data/lib/zen/package/sections/lib/sections/controller/section_entries.rb +85 -79
- data/lib/zen/package/sections/lib/sections/controller/sections.rb +58 -66
- data/lib/zen/package/sections/lib/sections/language/en/sections.yml +0 -1
- data/lib/zen/package/sections/lib/sections/language/nl/section_entries.yml +43 -0
- data/lib/zen/package/sections/lib/sections/language/nl/sections.yml +47 -0
- data/lib/zen/package/sections/lib/sections/model/section.rb +11 -15
- data/lib/zen/package/sections/lib/sections/model/section_entry.rb +9 -5
- data/lib/zen/package/sections/lib/sections/plugin/section_entries.rb +7 -8
- data/lib/zen/package/sections/lib/sections/plugin/sections.rb +3 -4
- data/lib/zen/package/sections/lib/sections/view/admin/section-entries/form.xhtml +0 -4
- data/lib/zen/package/sections/lib/sections/view/admin/section-entries/index.xhtml +8 -2
- data/lib/zen/package/sections/migrations/1306772479_remove_unique_slug.rb +28 -0
- data/lib/zen/package/settings/lib/settings.rb +21 -34
- data/lib/zen/package/settings/lib/settings/controller/settings.rb +29 -22
- data/lib/zen/package/settings/lib/settings/language/en/settings.yml +7 -5
- data/lib/zen/package/settings/lib/settings/language/nl/settings.yml +39 -0
- data/lib/zen/package/settings/lib/settings/model/setting.rb +3 -5
- data/lib/zen/package/settings/lib/settings/plugin/group_base.rb +3 -4
- data/lib/zen/package/settings/lib/settings/plugin/setting_base.rb +3 -5
- data/lib/zen/package/settings/lib/settings/plugin/settings.rb +11 -4
- data/lib/zen/package/settings/lib/settings/view/admin/settings/index.xhtml +5 -5
- data/lib/zen/package/settings/migrations/1299538742_add_language_key.rb +8 -8
- data/lib/zen/package/settings/migrations/1303196915_settings_plugin.rb +2 -5
- data/lib/zen/package/users/lib/users/controller/access_rules.rb +54 -61
- data/lib/zen/package/users/lib/users/controller/user_groups.rb +49 -57
- data/lib/zen/package/users/lib/users/controller/users.rb +58 -73
- data/lib/zen/package/users/lib/users/language/en/users.yml +6 -0
- data/lib/zen/package/users/lib/users/language/nl/access_rules.yml +37 -0
- data/lib/zen/package/users/lib/users/language/nl/user_groups.yml +31 -0
- data/lib/zen/package/users/lib/users/language/nl/users.yml +56 -0
- data/lib/zen/package/users/lib/users/model/user.rb +16 -1
- data/lib/zen/package/users/lib/users/view/admin/users/form.xhtml +27 -2
- data/lib/zen/package/users/lib/users/view/admin/users/index.xhtml +15 -3
- data/lib/zen/package/users/migrations/1304939855_user_settings.rb +15 -0
- data/lib/zen/plugin.rb +7 -9
- data/lib/zen/public/admin/css/{buttons.css → zen/buttons.css} +11 -7
- data/lib/zen/public/admin/css/{datepicker.css → zen/datepicker.css} +0 -0
- data/lib/zen/public/admin/css/{editor.css → zen/editor.css} +10 -5
- data/lib/zen/public/admin/css/{forms.css → zen/forms.css} +1 -1
- data/lib/zen/public/admin/css/{general.css → zen/general.css} +7 -7
- data/lib/zen/public/admin/css/{grid.css → zen/grid.css} +0 -0
- data/lib/zen/public/admin/css/{layout.css → zen/layout.css} +4 -5
- data/lib/zen/public/admin/css/zen/messages.css +61 -0
- data/lib/zen/public/admin/css/{notifications.css → zen/notifications.css} +4 -4
- data/lib/zen/public/admin/css/{reset.css → zen/reset.css} +0 -0
- data/lib/zen/public/admin/css/{tables.css → zen/tables.css} +3 -3
- data/lib/zen/public/admin/css/{tabs.css → zen/tabs.css} +5 -5
- data/lib/zen/public/admin/css/zen/window.css +79 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/accept.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/add.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/back.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/bold.png +0 -0
- data/lib/zen/public/admin/images/zen/icons/close.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/delete.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/edit.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/error.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/help.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/info.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/italic.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/large/error.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/large/notice.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/large/success.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/link.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/logout.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/ol.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/pdf.png +0 -0
- data/lib/zen/public/admin/images/zen/icons/preview.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/ul.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/user.png +0 -0
- data/lib/zen/public/admin/images/{icons → zen/icons}/view.png +0 -0
- data/lib/zen/public/admin/js/zen/core.js +73 -0
- data/lib/zen/public/admin/js/zen/editor.js +527 -0
- data/lib/zen/public/admin/js/zen/editor/markdown.js +84 -0
- data/lib/zen/public/admin/js/zen/editor/textile.js +84 -0
- data/lib/zen/public/admin/js/zen/init.js +12 -66
- data/lib/zen/public/admin/js/zen/tabs.js +5 -0
- data/lib/zen/public/admin/js/zen/window.js +206 -0
- data/lib/zen/task/build.rake +23 -6
- data/lib/zen/task/clean.rake +6 -7
- data/lib/zen/task/db.rake +7 -9
- data/lib/zen/task/package.rake +6 -6
- data/lib/zen/task/test.rake +6 -0
- data/lib/zen/task/theme.rake +3 -3
- data/lib/zen/theme.rb +3 -4
- data/lib/zen/validation.rb +7 -9
- data/lib/zen/version.rb +3 -4
- data/lib/zen/view/bottom.xhtml +0 -5
- data/lib/zen/view/main.xhtml +2 -0
- data/proto/app/app.rb +6 -4
- data/proto/app/config/config.rb +1 -7
- data/proto/app/config/database.rb +47 -43
- data/proto/app/config/middlewares.rb +0 -40
- data/proto/app/start.rb +1 -6
- data/proto/app/{vendor → theme}/.gitkeep +0 -0
- data/proto/migration.rb +3 -3
- data/proto/package/lib/package.rb +0 -1
- data/proto/package/lib/package/controller/controllers.rb +7 -40
- data/proto/package/lib/package/model/model.rb +3 -3
- metadata +106 -79
- data/CHANGELOG.md +0 -27
- data/ROADMAP.md +0 -53
- data/lib/zen/database.rb +0 -112
- data/lib/zen/logger.rb +0 -56
- data/lib/zen/public/admin/css/modals.css +0 -63
- data/lib/zen/public/admin/images/icons/close.png +0 -0
- data/lib/zen/public/admin/js/vendor/yepnope.js +0 -1
- data/lib/zen/public/admin/js/zen/editor/base.js +0 -262
- data/lib/zen/public/admin/js/zen/editor/drivers/html.js +0 -89
- data/lib/zen/public/admin/js/zen/editor/drivers/markdown.js +0 -87
- data/lib/zen/public/admin/js/zen/editor/drivers/textile.js +0 -87
- data/lib/zen/public/admin/js/zen/modal.js +0 -146
- data/lib/zen/public/admin/js/zen/notification.js +0 -211
- data/proto/app/config/requires.rb +0 -10
- data/proto/app/vendor/theme/.gitkeep +0 -0
- data/proto/package/lib/package/view/admin/package/edit.xhtml +0 -0
- data/proto/package/lib/package/view/admin/package/form.xhtml +0 -0
- data/proto/package/lib/package/view/admin/package/new.xhtml +0 -0
File without changes
|
File without changes
|
File without changes
|
File without changes
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
Binary file
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,73 @@
|
|
1
|
+
/**
|
2
|
+
* This file contains various extensions and core functions that are used by the
|
3
|
+
* Javascript API provided by Zen.
|
4
|
+
*
|
5
|
+
* @author Yorick Peterse
|
6
|
+
* @since 0.2.6
|
7
|
+
*/
|
8
|
+
Zen = {};
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Object containing all the assets that were loaded from a class using the Depends
|
12
|
+
* mutator.
|
13
|
+
*
|
14
|
+
* @author Yorick Peterse
|
15
|
+
* @since 0.2.6
|
16
|
+
*/
|
17
|
+
Zen.assets = {
|
18
|
+
javascript: [],
|
19
|
+
stylesheet: []
|
20
|
+
}
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Extends the Class class so that dependencies on Javascript and CSS files can be
|
24
|
+
* inserted into a class using the assets system that comes with Mootools.
|
25
|
+
*
|
26
|
+
* Note that you shouldn't specify the file extension, this will be added automatically.
|
27
|
+
*
|
28
|
+
* @example
|
29
|
+
* var my_class = new Class(
|
30
|
+
* {
|
31
|
+
* Depends:
|
32
|
+
* {
|
33
|
+
* stylesheet: ['zen/editor']
|
34
|
+
* }
|
35
|
+
* });
|
36
|
+
*
|
37
|
+
* @author Yorick Peterse
|
38
|
+
* @since 0.2.6
|
39
|
+
* @param [Object] deps Object containing the stylesheets and Javascript files required
|
40
|
+
* by a class.
|
41
|
+
*/
|
42
|
+
Class.Mutators.Depends = function(deps)
|
43
|
+
{
|
44
|
+
// Load all Javascript files
|
45
|
+
if ( deps.javascript )
|
46
|
+
{
|
47
|
+
deps.javascript.each(function(file)
|
48
|
+
{
|
49
|
+
file = '/admin/js/' + file + '.js';
|
50
|
+
|
51
|
+
if ( !Zen.assets.javascript.contains(file) )
|
52
|
+
{
|
53
|
+
Asset.javascript(file);
|
54
|
+
Zen.assets.javascript.push(file);
|
55
|
+
}
|
56
|
+
});
|
57
|
+
}
|
58
|
+
|
59
|
+
// Load all stylesheets
|
60
|
+
if ( deps.stylesheet )
|
61
|
+
{
|
62
|
+
deps.stylesheet.each(function(file)
|
63
|
+
{
|
64
|
+
file = '/admin/css/' + file + '.css';
|
65
|
+
|
66
|
+
if ( !Zen.assets.stylesheet.contains(file) )
|
67
|
+
{
|
68
|
+
Asset.css(file);
|
69
|
+
Zen.assets.stylesheet.push(file);
|
70
|
+
}
|
71
|
+
});
|
72
|
+
}
|
73
|
+
}
|
@@ -0,0 +1,527 @@
|
|
1
|
+
/**
|
2
|
+
* Base class for all drivers that provides several common methods and allows developers
|
3
|
+
* to use the same syntax for all editor drivers.
|
4
|
+
*
|
5
|
+
* ## Usage
|
6
|
+
*
|
7
|
+
* In order to create a new instance of Zen.Editor your textareas will need an attribute
|
8
|
+
* called "data-format". Without this attribute this class will assume you're using HTML
|
9
|
+
* as your markup. An example of the most basic textarea looks like the following:
|
10
|
+
*
|
11
|
+
* <textarea data-format="markdown"></textarea>
|
12
|
+
*
|
13
|
+
* To make it easier to retrieve an editor instance once it's created you should add an ID
|
14
|
+
* to the element. Instances of a textarea with an ID set can be retrieved from
|
15
|
+
* Zen.Editor.instances, this doesn't work for classes or other attributes.
|
16
|
+
*
|
17
|
+
* <textarea data-format="markdown" id="markdown_editor"></textarea>
|
18
|
+
*
|
19
|
+
* Once you have your element in place you can create a new instance by doing the
|
20
|
+
* following:
|
21
|
+
*
|
22
|
+
* var editor = new Zen.Editor($('markdown_editor'));
|
23
|
+
*
|
24
|
+
* This will create a new editor instance using HTML as the markup. Because we've set an
|
25
|
+
* ID we can retrieve this instance as following:
|
26
|
+
*
|
27
|
+
* Zen.Editor.instances.markdown_editor
|
28
|
+
*
|
29
|
+
* This means that it's not required to actually store the instance in a variable unless
|
30
|
+
* you're not using an ID.
|
31
|
+
*
|
32
|
+
* The first parameter of the Zen.Editor class can either be a string or an element. If
|
33
|
+
* it's a string it's assumed that it's a valid CSS selector and the first element found
|
34
|
+
* will be used. If it's an element it will be used directly without any further
|
35
|
+
* processing. A few examples can be seen below.
|
36
|
+
*
|
37
|
+
* new Zen.Editor('#markdown_editor'); // => markdown_editor will be used
|
38
|
+
* new Zen.Editor($$('textarea.some_editor')); // => First item will be used
|
39
|
+
*
|
40
|
+
* The second parameter is an object with custom options. Currently there are only two
|
41
|
+
* options available:
|
42
|
+
*
|
43
|
+
* * height: sets a fixed height for the textarea.
|
44
|
+
* * width: does the same as "height" but for the width.
|
45
|
+
*
|
46
|
+
* The third (and last) parameter is an array of custom buttons to add to the editor on
|
47
|
+
* top of the default buttons. This parameter should be an array of objects where each
|
48
|
+
* object has the following three keys:
|
49
|
+
*
|
50
|
+
* * name: a unique name for the button, also set as the class of the <li> element.
|
51
|
+
* * label: a label to display in the button, also used for the value of the title
|
52
|
+
* attribute.
|
53
|
+
* * onClick: function that's executed whenever the button is clicked. This function can
|
54
|
+
* take a single parameter which is set to the instance of the editor to which the button
|
55
|
+
* belongs.
|
56
|
+
*
|
57
|
+
* A full example looks like the following:
|
58
|
+
*
|
59
|
+
* new Zen.Editor(
|
60
|
+
* $('markdown_editor'),
|
61
|
+
* {
|
62
|
+
* height: 600
|
63
|
+
* },
|
64
|
+
* [
|
65
|
+
* {
|
66
|
+
* name: 'example',
|
67
|
+
* label: 'example',
|
68
|
+
* onClick: function(editor)
|
69
|
+
* {
|
70
|
+
* console.log(editor.get('value'));
|
71
|
+
* }
|
72
|
+
* }
|
73
|
+
* ]
|
74
|
+
* );
|
75
|
+
*
|
76
|
+
* ## Available Drivers
|
77
|
+
*
|
78
|
+
* Currently the following drivers are available:
|
79
|
+
*
|
80
|
+
* * HTML (default)
|
81
|
+
* * Markdown
|
82
|
+
* * Textile
|
83
|
+
*
|
84
|
+
* ## Creating Drivers
|
85
|
+
*
|
86
|
+
* Creating a new driver for your own favorite markup engine (e.g. restructuredText) is
|
87
|
+
* pretty simple. Each driver should be declared under the Zen.Editor namespace and should
|
88
|
+
* extend the base class, Zen.Editor. The latter makes it possible for the driver to use
|
89
|
+
* features of the parent class if it doesn't override or provides them itself.
|
90
|
+
*
|
91
|
+
* A basic skeleton for a driver looks like the following:
|
92
|
+
*
|
93
|
+
* Zen.Editor.RestructuredText = new Class(
|
94
|
+
* {
|
95
|
+
* Extends: Zen.Editor
|
96
|
+
* });
|
97
|
+
*
|
98
|
+
* Usually you don't want to redeclare the initialize() method as it's used to create most
|
99
|
+
* of the required data for an editor. Typically you'll only want to override the methods
|
100
|
+
* for the default buttons or add your own ones.
|
101
|
+
*
|
102
|
+
* Once a driver has been written it's class has to be registered, this can be done as
|
103
|
+
* following:
|
104
|
+
*
|
105
|
+
* Zen.Editor.drivers.restructured_text = 'RestructuredText';
|
106
|
+
*
|
107
|
+
* The key of Zen.Editor.drivers should match the value set in the data-format attribute,
|
108
|
+
* it's value should be the name of the driver's class.
|
109
|
+
*
|
110
|
+
* @author Yorick Peterse
|
111
|
+
* @since 0.2.6
|
112
|
+
* @implements Options
|
113
|
+
* @namespace Zen
|
114
|
+
*/
|
115
|
+
Zen.Editor = new Class(
|
116
|
+
{
|
117
|
+
Implements: Options,
|
118
|
+
|
119
|
+
Depends:
|
120
|
+
{
|
121
|
+
stylesheet: ['zen/editor'],
|
122
|
+
javascript: ['zen/editor/markdown', 'zen/editor/textile', 'zen/window']
|
123
|
+
},
|
124
|
+
|
125
|
+
/**
|
126
|
+
* Object containing all the default options merged with the custom ones.
|
127
|
+
*
|
128
|
+
* @author Yorick Peterse
|
129
|
+
* @since 0.2.6
|
130
|
+
* @var [Object]
|
131
|
+
*/
|
132
|
+
options:
|
133
|
+
{
|
134
|
+
// The default height in pixels
|
135
|
+
height: 400,
|
136
|
+
|
137
|
+
// The default width in pixels, set it to null to leave it unchanged (default)
|
138
|
+
width: null
|
139
|
+
},
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Array containing all the buttons to display in the toolbar and their onClick
|
143
|
+
* events. Note that if the onClick values are strings the class assumes they're
|
144
|
+
* methods available in the current instance.
|
145
|
+
*
|
146
|
+
* Each callback gets two parameters sent to it: the editor instance and the object of
|
147
|
+
* the button that was clicked.
|
148
|
+
*
|
149
|
+
* @author Yorick Peterse
|
150
|
+
* @since 0.2.6
|
151
|
+
* @var [Array]
|
152
|
+
*/
|
153
|
+
buttons:
|
154
|
+
[
|
155
|
+
{name: 'bold' , label: 'Bold' , onClick: 'bold'},
|
156
|
+
{name: 'italic' , label: 'Italic' , onClick: 'italic'},
|
157
|
+
{name: 'link' , label: 'Link' , onClick: 'link'},
|
158
|
+
{name: 'ul' , label: 'Unordered list', onClick: 'ul'},
|
159
|
+
{name: 'ol' , label: 'Ordered list' , onClick: 'ol'},
|
160
|
+
{name: 'preview', label: 'Preview' , onClick: 'preview'}
|
161
|
+
],
|
162
|
+
|
163
|
+
/**
|
164
|
+
* The DOM element to use for the editor.
|
165
|
+
*
|
166
|
+
* @author Yorick Peterse
|
167
|
+
* @since 0.2.6
|
168
|
+
* @var [Element]
|
169
|
+
*/
|
170
|
+
element: null,
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Creates a new instance of the class and saves and validates all the given data.
|
174
|
+
*
|
175
|
+
* @example
|
176
|
+
* var editor = new Zen.Editor($('editor'), {markup: 'markdown'});
|
177
|
+
*
|
178
|
+
* @author Yorick Peterse
|
179
|
+
* @since 0.2.6
|
180
|
+
* @param [Object|String] element Either a DOM element or a CSS selector. If a
|
181
|
+
* selector is specified only the first element will be used.
|
182
|
+
* @param [Object] options Object containing a custom set of options that will be
|
183
|
+
* merged with this.options.
|
184
|
+
* @param [Array] buttons An array with a custom set of buttons to add on top of the
|
185
|
+
* default ones.
|
186
|
+
*/
|
187
|
+
initialize: function(element, options, buttons)
|
188
|
+
{
|
189
|
+
// Merge the options
|
190
|
+
this.setOptions(options);
|
191
|
+
|
192
|
+
// The element variable is always required
|
193
|
+
if ( typeOf(element) === 'undefined' )
|
194
|
+
{
|
195
|
+
throw new SyntaxError("You need to specify an element for the editor.");
|
196
|
+
}
|
197
|
+
|
198
|
+
this.element = Zen.Editor.getElement(element);
|
199
|
+
|
200
|
+
// Create the HTML for the editor
|
201
|
+
var toolbar = new Element('div', {'class': 'editor_toolbar'});
|
202
|
+
var container = new Element('div', {'class': 'editor_container'});
|
203
|
+
var ul = new Element('ul');
|
204
|
+
var current_class = this;
|
205
|
+
|
206
|
+
// Push the custom buttons
|
207
|
+
if ( typeof buttons !== 'undefined' && buttons.length > 0 )
|
208
|
+
{
|
209
|
+
this.buttons.combine(buttons);
|
210
|
+
}
|
211
|
+
|
212
|
+
// Create the HTML for all the buttons
|
213
|
+
this.buttons.each(function(button)
|
214
|
+
{
|
215
|
+
var li = new Element(
|
216
|
+
'li',
|
217
|
+
{
|
218
|
+
'class': button.name,
|
219
|
+
html: button.label,
|
220
|
+
title: button.label
|
221
|
+
}
|
222
|
+
);
|
223
|
+
|
224
|
+
// Add the onClick event, when clicked the current editor's instance is passed
|
225
|
+
// to the event allowing developers to work with it's content.
|
226
|
+
li.addEvent('click', function()
|
227
|
+
{
|
228
|
+
var current_editor = this.getParent('.editor_container')
|
229
|
+
.getElement('textarea');
|
230
|
+
|
231
|
+
if ( typeOf(button.onClick) === 'string' )
|
232
|
+
{
|
233
|
+
current_class[button.onClick](current_editor, this);
|
234
|
+
}
|
235
|
+
else
|
236
|
+
{
|
237
|
+
button.onClick(current_editor, this);
|
238
|
+
}
|
239
|
+
});
|
240
|
+
|
241
|
+
li.inject(ul);
|
242
|
+
});
|
243
|
+
|
244
|
+
// Inject the HTML into the DOM
|
245
|
+
ul.inject(toolbar);
|
246
|
+
toolbar.inject(container);
|
247
|
+
container.inject(this.element, 'before');
|
248
|
+
|
249
|
+
// Set the options
|
250
|
+
['height', 'width'].each(function(attr)
|
251
|
+
{
|
252
|
+
if ( current_class.options[attr] !== null )
|
253
|
+
{
|
254
|
+
element.setStyle(attr, current_class.options[attr]);
|
255
|
+
}
|
256
|
+
});
|
257
|
+
|
258
|
+
// Inject the textarea back into the container
|
259
|
+
element.inject(container);
|
260
|
+
element.set('data-state', 'initialized');
|
261
|
+
},
|
262
|
+
|
263
|
+
/**
|
264
|
+
* Destroys the editor instance. This will remove all HTML and removes the textarea
|
265
|
+
* from Zen.Editor.instances if it has an ID.
|
266
|
+
*
|
267
|
+
* @author Yorick Peterse
|
268
|
+
* @since 0.2.6
|
269
|
+
*/
|
270
|
+
destroy: function()
|
271
|
+
{
|
272
|
+
// First we'll have to remove all HTML
|
273
|
+
var parent_container = this.element.getParent('.editor_container');
|
274
|
+
var id = this.element.id;
|
275
|
+
|
276
|
+
this.element.inject(parent_container, 'before');
|
277
|
+
this.element.removeAttribute('data-state');
|
278
|
+
|
279
|
+
parent_container.destroy();
|
280
|
+
|
281
|
+
if ( typeOf(id) !== 'undefined' )
|
282
|
+
{
|
283
|
+
Zen.Editor.instances[id] = null;
|
284
|
+
}
|
285
|
+
|
286
|
+
// Reset the dimensions
|
287
|
+
this.element.setStyle('height', null);
|
288
|
+
this.element.setStyle('width' , null);
|
289
|
+
},
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Inserts a set of <strong> tags around the cursor.
|
293
|
+
*
|
294
|
+
* @author Yorick Peterse
|
295
|
+
* @since 0.2.6
|
296
|
+
* @param [Element] editor The editor to insert the tags into.
|
297
|
+
*/
|
298
|
+
bold: function(editor)
|
299
|
+
{
|
300
|
+
editor.insertAroundCursor({before: '<strong>', after: '</strong>'});
|
301
|
+
},
|
302
|
+
|
303
|
+
/**
|
304
|
+
* Inserts a set of <em> tags around the cursor.
|
305
|
+
*
|
306
|
+
* @author Yorick Peterse
|
307
|
+
* @since 0.2.6
|
308
|
+
* @param [Element] editor The editor to insert the tags into.
|
309
|
+
*/
|
310
|
+
italic: function(editor)
|
311
|
+
{
|
312
|
+
editor.insertAroundCursor({before: '<em>', after: '</em>'});
|
313
|
+
},
|
314
|
+
|
315
|
+
/**
|
316
|
+
* Asks for a URL and inserts it into the textarea using an <a> tag.
|
317
|
+
*
|
318
|
+
* @author Yorick Peterse
|
319
|
+
* @since 0.2.6
|
320
|
+
* @param [Element] editor The editor to insert the tags into.
|
321
|
+
*/
|
322
|
+
link: function(editor)
|
323
|
+
{
|
324
|
+
var link = prompt('URL', 'http://');
|
325
|
+
|
326
|
+
editor.insertAroundCursor(
|
327
|
+
{
|
328
|
+
before: '<a href="' + link + '">',
|
329
|
+
after: '</a>'
|
330
|
+
});
|
331
|
+
},
|
332
|
+
|
333
|
+
/**
|
334
|
+
* Inserts a set of <ul> and <li> tags around the cursor.
|
335
|
+
*
|
336
|
+
* @author Yorick Peterse
|
337
|
+
* @since 0.2.6
|
338
|
+
* @param [Element] editor The editor to insert the tags into.
|
339
|
+
*/
|
340
|
+
ul: function(editor)
|
341
|
+
{
|
342
|
+
editor.insertAroundCursor(
|
343
|
+
{
|
344
|
+
before: "\n<ul>\n <li>",
|
345
|
+
after: "</li>\n</ul>\n"
|
346
|
+
});
|
347
|
+
},
|
348
|
+
|
349
|
+
/**
|
350
|
+
* Inserts a set of <ol> and <li> tags around the cursor.
|
351
|
+
*
|
352
|
+
* @author Yorick Peterse
|
353
|
+
* @since 0.2.6
|
354
|
+
* @param [Element] editor The editor to insert the tags into.
|
355
|
+
*/
|
356
|
+
ol: function(editor)
|
357
|
+
{
|
358
|
+
editor.insertAroundCursor(
|
359
|
+
{
|
360
|
+
before: "\n<ol>\n <li>",
|
361
|
+
after: "</li>\n</ol>\n"
|
362
|
+
});
|
363
|
+
},
|
364
|
+
|
365
|
+
/**
|
366
|
+
* Shows a preview of the content entered in the text area.
|
367
|
+
*
|
368
|
+
* @author Yorick Peterse
|
369
|
+
* @since 0.2.6
|
370
|
+
* @param [Element] editor The editor to render the preview for.
|
371
|
+
*/
|
372
|
+
preview: function(editor)
|
373
|
+
{
|
374
|
+
var markup = editor.get('value');
|
375
|
+
var engine = editor.get('data-format');
|
376
|
+
|
377
|
+
new Request(
|
378
|
+
{
|
379
|
+
method: 'POST',
|
380
|
+
url: '/admin/preview',
|
381
|
+
data: {engine: engine, markup: markup},
|
382
|
+
onSuccess: function(response)
|
383
|
+
{
|
384
|
+
new Zen.Window(
|
385
|
+
response,
|
386
|
+
{
|
387
|
+
title: 'Preview',
|
388
|
+
width: 600,
|
389
|
+
move: true,
|
390
|
+
buttons:
|
391
|
+
[
|
392
|
+
{
|
393
|
+
name: 'close',
|
394
|
+
label: 'Close',
|
395
|
+
onClick: function(instance)
|
396
|
+
{
|
397
|
+
instance.destroy();
|
398
|
+
}
|
399
|
+
}
|
400
|
+
]
|
401
|
+
}
|
402
|
+
);
|
403
|
+
}
|
404
|
+
}).send();
|
405
|
+
}
|
406
|
+
});
|
407
|
+
|
408
|
+
/**
|
409
|
+
* Object containing the names of all available drivers and their classes.
|
410
|
+
* Note that these drivers should be declared under the Zen.Editor namespace.
|
411
|
+
*
|
412
|
+
* @author Yorick Peterse
|
413
|
+
* @since 0.2.6
|
414
|
+
* @var [Object]
|
415
|
+
*/
|
416
|
+
Zen.Editor.drivers = {
|
417
|
+
markdown: 'Markdown',
|
418
|
+
textile: 'Textile'
|
419
|
+
};
|
420
|
+
|
421
|
+
/**
|
422
|
+
* Object that will contain a list of all instances of the Zen.Editor class. Note that the
|
423
|
+
* textareas will need an ID in order for them to be added to this list.
|
424
|
+
*
|
425
|
+
* @author Yorick Peterse
|
426
|
+
* @since 0.2.6
|
427
|
+
* @var [Object]
|
428
|
+
*/
|
429
|
+
Zen.Editor.instances = {};
|
430
|
+
|
431
|
+
/**
|
432
|
+
* Class method that can be used to create editor instances using different drivers while
|
433
|
+
* still using the same syntax.
|
434
|
+
*
|
435
|
+
* @example
|
436
|
+
* var editor = Zen.Editor.init('markdown', $('editor'), {height: 200});
|
437
|
+
*
|
438
|
+
* @author Yorick Peterse
|
439
|
+
* @since 0.2.6
|
440
|
+
* @param [String] driver The name of the driver to use.
|
441
|
+
* @param [Object|String] A DOM element or a CSS selector.
|
442
|
+
* @param [Object] options An object containing custom options to use.
|
443
|
+
* @param [Object[ buttons An array of buttons to add to the editor.
|
444
|
+
* @see Zen.Editor.initialize
|
445
|
+
* @return [Object] An instance of the correct driver or an error class in case something
|
446
|
+
* went wrong.
|
447
|
+
*/
|
448
|
+
Zen.Editor.init = function(driver, element, options, buttons)
|
449
|
+
{
|
450
|
+
if ( !driver )
|
451
|
+
{
|
452
|
+
throw new SyntaxError("You need to specify a driver.");
|
453
|
+
}
|
454
|
+
|
455
|
+
if ( !element )
|
456
|
+
{
|
457
|
+
throw new SyntaxError("You need to specify a DOM element or a CSS selector.");
|
458
|
+
}
|
459
|
+
|
460
|
+
// Get the element so we can determine if the textarea has already been processed
|
461
|
+
element = Zen.Editor.getElement(element);
|
462
|
+
|
463
|
+
if ( element.get('data-state') === 'initialized' )
|
464
|
+
{
|
465
|
+
return;
|
466
|
+
}
|
467
|
+
|
468
|
+
var driver_class = Zen.Editor.drivers[driver];
|
469
|
+
var instance = null;
|
470
|
+
|
471
|
+
// Try to see if a driver exists for the given name. If there isn't we'll use the
|
472
|
+
// HTML driver as a fallback.
|
473
|
+
if ( typeOf(driver_class) === 'undefined' || !Zen.Editor[driver_class] )
|
474
|
+
{
|
475
|
+
instance = new Zen.Editor(element, options, buttons);
|
476
|
+
}
|
477
|
+
else
|
478
|
+
{
|
479
|
+
instance = new Zen.Editor[driver_class](element, options, buttons);
|
480
|
+
}
|
481
|
+
|
482
|
+
// Store the instance if it has an ID
|
483
|
+
if ( typeOf(instance.element.id) !== 'undefined' )
|
484
|
+
{
|
485
|
+
Zen.Editor.instances[instance.element.id] = instance;
|
486
|
+
}
|
487
|
+
|
488
|
+
return instance;
|
489
|
+
};
|
490
|
+
|
491
|
+
/**
|
492
|
+
* Retrieves the correct element for the given CSS selector or element(s). If the
|
493
|
+
* parameter is a single DOM element it will be returned immediately, if it's an array of
|
494
|
+
* objects only the first one will be returned. If the parameter is a string this method
|
495
|
+
* will return the first element for the given selector.
|
496
|
+
*
|
497
|
+
* @example
|
498
|
+
* Zen.Editor.getElement($$('.some_class')); # => Element
|
499
|
+
*
|
500
|
+
* @author Yorick Peterse
|
501
|
+
* @since 0.2.6
|
502
|
+
* @param [String|Array|Element] The source data from which to extract the (first)
|
503
|
+
* element.
|
504
|
+
* @return [Element]
|
505
|
+
*/
|
506
|
+
Zen.Editor.getElement = function(element)
|
507
|
+
{
|
508
|
+
if ( typeOf(element) === 'element' )
|
509
|
+
{
|
510
|
+
return element;
|
511
|
+
}
|
512
|
+
|
513
|
+
if ( typeOf(element) === 'string' )
|
514
|
+
{
|
515
|
+
element = $$(element);
|
516
|
+
|
517
|
+
if ( element.length === 0 )
|
518
|
+
{
|
519
|
+
throw new Error("The CSS selector did not result in any elements.");
|
520
|
+
}
|
521
|
+
}
|
522
|
+
|
523
|
+
if ( element.length > 0 )
|
524
|
+
{
|
525
|
+
return element[0];
|
526
|
+
}
|
527
|
+
};
|