diff --git a/CHANGELOG.md b/CHANGELOG.md
index e609918af..17bc36b07 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
-* **Build 15x** (2014-09-xx)
- - Moved `ViewMaker` trait to live under system, it can be useful for Models too.
+* **Build 15x** (2014-10-xx)
+ - Plugins are now updated in order of their dependency definitions.
+ - Moved `ViewMaker` trait now lives under system, it can be useful for Models too.
* **Build 149** (2014-09-29)
- Added new `hint` form field type (see Backend > Forms docs).
diff --git a/modules/backend/behaviors/FormController.php b/modules/backend/behaviors/FormController.php
index 7f640857d..e87683a2c 100644
--- a/modules/backend/behaviors/FormController.php
+++ b/modules/backend/behaviors/FormController.php
@@ -572,6 +572,20 @@ class FormController extends ControllerBehavior
*/
public function formExtendQuery($query) {}
+ /**
+ * Static helper for extending form fields.
+ * @param callable $callback
+ * @return void
+ */
+ public static function extendFormFields($callback)
+ {
+ $calledClass = self::getCalledExtensionClass();
+ Event::listen('backend.form.extendFields', function($widget) use ($calledClass, $callback) {
+ if (!is_a($widget->getController(), $calledClass)) return;
+ $callback($widget, $widget->model, $widget->getContext());
+ });
+ }
+
//
// Internals
//
diff --git a/modules/backend/behaviors/ListController.php b/modules/backend/behaviors/ListController.php
index 5509127f5..f700ce21d 100644
--- a/modules/backend/behaviors/ListController.php
+++ b/modules/backend/behaviors/ListController.php
@@ -313,4 +313,18 @@ class ListController extends ControllerBehavior
*/
public function listOverrideHeaderValue($columnName, $definition = null) {}
+ /**
+ * Static helper for extending form fields.
+ * @param callable $callback
+ * @return void
+ */
+ public static function extendListColumns($callback)
+ {
+ $calledClass = self::getCalledExtensionClass();
+ Event::listen('backend.list.extendColumns', function($widget) use ($calledClass, $callback) {
+ if (!is_a($widget->getController(), $calledClass)) return;
+ $callback($widget, $widget->model, $widget->getContext());
+ });
+ }
+
}
\ No newline at end of file
diff --git a/modules/backend/controllers/Auth.php b/modules/backend/controllers/Auth.php
index 105f2a6cf..8015d892f 100644
--- a/modules/backend/controllers/Auth.php
+++ b/modules/backend/controllers/Auth.php
@@ -9,7 +9,7 @@ use BackendAuth;
use Backend\Models\User;
use Backend\Models\AccessLog;
use Backend\Classes\Controller;
-use System\Classes\VersionManager;
+use System\Classes\UpdateManager;
use System\Classes\ApplicationException;
use October\Rain\Support\ValidationException;
use Exception;
@@ -75,7 +75,7 @@ class Auth extends Controller
], true);
// Load version updates
- VersionManager::instance()->updateAll();
+ UpdateManager::instance()->update();
// Log the sign in event
AccessLog::add($user);
diff --git a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css
index c130bbe0d..fde1cb191 100644
--- a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css
+++ b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css
@@ -1,3 +1,6 @@
+/*
+ Icon font
+*/
@font-face {
font-family: 'RedactorFont';
src: url('../vendor/redactor/redactor-font.eot');
@@ -8,247 +11,126 @@
font-weight: normal;
font-style: normal;
}
-.redactor_box::selection {
- background: #ffff9e;
-}
-.redactor_box::-moz-selection {
- background: #ffff9e;
-}
-.redactor_box img::selection {
- background: transparent;
-}
-.redactor_box img::-moz-selection {
- background: transparent;
-}
-.redactor_box {
+/*
+ Box
+*/
+.redactor-box {
position: relative;
overflow: visible;
background: #fff;
+ margin-bottom: 24px;
}
-.redactor_box iframe {
+.redactor-box iframe,
+.redactor-box textarea {
display: block;
- margin: 0;
- padding: 0;
- border: none;
-}
-.redactor_box textarea {
position: relative;
- display: block;
- overflow: auto;
margin: 0;
padding: 0;
width: 100%;
+}
+.redactor-box iframe {
+ border: 1px solid #eee;
+}
+.redactor-box textarea {
+ overflow: auto;
outline: none;
border: none;
- background-color: #222;
+ background-color: #111;
box-shadow: none;
color: #ccc;
font-size: 13px;
font-family: Menlo, Monaco, monospace, sans-serif;
resize: none;
}
-.redactor_box textarea:focus {
+.redactor-box textarea:focus {
outline: none;
}
-.redactor_box,
-.redactor_box textarea {
+/*
+ Z-index setup
+*/
+.redactor-editor,
+.redactor-box,
+.redactor-box textarea {
z-index: auto !important;
}
-.redactor_box_fullscreen {
- z-index: 300 !important;
- width: 100%!important;
+.redactor-box-fullscreen {
+ z-index: 99 !important;
}
-#redactor_modal_overlay,
-#redactor_modal,
-.redactor_dropdown {
- z-index: 302 !important;
+.redactor-toolbar,
+.redactor-dropdown {
+ z-index: 1050 !important;
}
-body .redactor_air {
- position: absolute;
- z-index: 502;
+#redactor-modal-overlay,
+#redactor-modal-box,
+#redactor-modal {
+ z-index: 1051 !important;
}
-body .redactor_box_fullscreen {
+/*
+ Resize
+*/
+.redactor-resize {
+ background: #f4f4f4;
+ padding: 4px 0 3px 0;
+ cursor: move;
+ border: 1px solid #e3e3e3;
+ border-top: none;
+}
+.redactor-resize div {
+ width: 30px;
+ margin: auto;
+ border-top: 1px solid #bbb;
+ border-bottom: 1px solid #fff;
+}
+/*
+ Fullscreen
+*/
+body .redactor-box-fullscreen {
position: fixed;
top: 0;
left: 0;
width: 100%;
- background: #f9f9f9;
- overflow-y: scroll !important;
}
-body .redactor_box_fullscreen .redactor_editor {
- max-width: 960px;
- margin: 20px auto !important;
- padding: 20px;
-}
-.redactor-link-tooltip {
- position: absolute;
- z-index: 49999;
- padding: 10px;
- line-height: 1;
- display: inline-block;
- background-color: #000;
- color: #555 !important;
-}
-.redactor-link-tooltip,
-.redactor-link-tooltip a {
- font-size: 12px;
- font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
-}
-.redactor-link-tooltip a {
- color: #ccc;
- margin: 0 5px;
- text-decoration: none;
-}
-.redactor-link-tooltip a:hover {
- color: #fff;
-}
-#redactor-image-box img {
- width: 100%;
-}
-.redactor_editor {
+/*
+ Editor
+*/
+.redactor-editor {
position: relative;
overflow: auto;
margin: 0 !important;
- padding: 10px 20px;
- padding-bottom: 5px;
+ padding: 20px;
outline: none;
- background: none;
- background: #fff;
- box-shadow: none !important;
white-space: normal;
- border: none;
+ border: 1px solid #eee;
+ font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
+ font-size: 14px;
+ line-height: 1.6em;
}
-.redactor_editor:focus {
+.redactor-editor:focus {
outline: none;
}
-.redactor_editor a {
- color: #15c !important;
- text-decoration: underline !important;
+/*
+ Placeholder
+*/
+.redactor-placeholder {
+ position: relative;
}
-.redactor_editor .redactor_placeholder {
+.redactor-placeholder:after {
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ content: attr(placeholder);
color: #999 !important;
- display: block !important;
+ font-weight: normal !important;
}
-.redactor_editor {
- font-family: Helvetica, Arial, sans-serif;
- line-height: 170%;
+/* Placeholder in linebreaks mode */
+.redactor-linebreaks.redactor-placeholder:after {
+ top: 10px;
+ left: 10px;
}
-.redactor_editor object,
-.redactor_editor embed,
-.redactor_editor video,
-.redactor_editor img {
- max-width: 100%;
- width: auto;
-}
-.redactor_editor video,
-.redactor_editor img {
- height: auto;
-}
-.redactor_editor div,
-.redactor_editor p,
-.redactor_editor ul,
-.redactor_editor ol,
-.redactor_editor dl,
-.redactor_editor blockquote,
-.redactor_editor pre {
- margin: 0;
- margin-bottom: 10px !important;
- border: none;
- background: none !important;
- box-shadow: none !important;
-}
-.redactor_editor iframe,
-.redactor_editor object,
-.redactor_editor hr {
- margin-bottom: 15px !important;
-}
-.redactor_editor blockquote {
- margin-left: 1.5em !important;
- padding-left: 0 !important;
- color: #777;
- font-style: italic !important;
-}
-.redactor_editor ul,
-.redactor_editor ol {
- padding-left: 2em !important;
-}
-.redactor_editor ul ul,
-.redactor_editor ol ol,
-.redactor_editor ul ol,
-.redactor_editor ol ul {
- margin: 2px !important;
- padding: 0 !important;
- padding-left: 2em !important;
- border: none;
-}
-.redactor_editor dl dt {
- font-weight: bold;
-}
-.redactor_editor dd {
- margin-left: 1em;
-}
-.redactor_editor code {
- background-color: #d8d7d7 !important;
-}
-.redactor_editor pre {
- overflow: auto;
- padding: 1em !important;
- border: 1px solid #ddd !important;
- border-radius: 3px !important;
- background: #f8f8f8 !important;
- white-space: pre;
- font-size: 90% !important;
-}
-.redactor_editor hr {
- display: block;
- height: 1px;
- border: 0;
- border-top: 1px solid #ccc;
-}
-.redactor_editor h1,
-.redactor_editor h2,
-.redactor_editor h3,
-.redactor_editor h4,
-.redactor_editor h5,
-.redactor_editor h6 {
- margin-top: 0 !important;
- padding: 0 !important;
- background: none;
- color: #000;
- font-weight: bold;
-}
-.redactor_editor h1 {
- font-size: 36px !important;
- line-height: 1.111em !important;
- margin-bottom: .15em !important;
-}
-.redactor_editor h2 {
- font-size: 30px !important;
- line-height: 1.111em !important;
- margin-bottom: .25em !important;
-}
-.redactor_editor h3 {
- font-size: 24px !important;
- line-height: 1.333em !important;
- margin-bottom: .2em !important;
-}
-.redactor_editor h4 {
- font-size: 18px !important;
- line-height: 1.5em !important;
- margin-bottom: .2em !important;
-}
-.redactor_editor h5 {
- font-size: 1em !important;
- line-height: 1.6em !important;
- margin-bottom: .25em !important;
-}
-.redactor_editor h6 {
- font-size: .8em !important;
- line-height: 1.6em !important;
- text-transform: uppercase;
- margin-bottom: .3em !important;
-}
-.redactor_toolbar {
+/*
+ Toolbar
+*/
+.redactor-toolbar {
position: relative;
top: 0;
left: 0;
@@ -256,32 +138,35 @@ body .redactor_box_fullscreen .redactor_editor {
padding: 0 !important;
list-style: none !important;
font-size: 14px !important;
- font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
line-height: 1 !important;
+ background: #fff;
border: none;
- background: #dddddd;
- z-index: 301;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
-.redactor_toolbar:after {
+.redactor-toolbar:before,
+.redactor-toolbar:after {
+ content: " ";
+ display: table;
+}
+.redactor-toolbar:after {
+ clear: both;
+}
+.redactor-toolbar:after {
content: "";
display: table;
clear: both;
}
-.redactor_toolbar.redactor-toolbar-overflow {
+.redactor-toolbar.redactor-toolbar-overflow {
overflow-y: auto;
height: 29px;
white-space: nowrap;
}
-.redactor_toolbar.redactor-toolbar-external {
+.redactor-toolbar.redactor-toolbar-external {
z-index: 999;
box-shadow: none;
border: 1px solid rgba(0, 0, 0, 0.1);
}
-.redactor_toolbar li.redactor_btn_right {
- float: right;
- margin-right: 2px;
-}
-.redactor_toolbar li {
+.redactor-toolbar li {
vertical-align: top;
display: inline-block;
margin: 0 !important;
@@ -292,12 +177,9 @@ body .redactor_box_fullscreen .redactor_editor {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
-.redactor_toolbar li a {
+.redactor-toolbar li a {
display: block;
- color: #404040;
- font-size: 14px;
- width: 20px;
- line-height: 20px;
+ color: #333;
text-align: center;
padding: 9px 10px;
outline: none;
@@ -309,59 +191,47 @@ body .redactor_box_fullscreen .redactor_editor {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
-.redactor_toolbar li a:hover {
+.redactor-toolbar li a:hover {
outline: none;
- background-color: #999999;
- color: #ffffff;
-}
-.redactor_toolbar li a:hover i:before {
+ background-color: #1f78d8;
color: #fff;
}
-.redactor_toolbar li a:active,
-.redactor_toolbar li a.redactor_act {
- outline: none;
- background-color: #404040;
- color: #ffffff;
+.redactor-toolbar li a:hover i:before {
+ color: #fff;
}
-.redactor_toolbar li a.redactor-btn-image {
+.redactor-toolbar li a:active,
+.redactor-toolbar li a.redactor-act {
+ outline: none;
+ background-color: #ccc;
+ color: #444;
+}
+.redactor-toolbar li a.redactor-btn-image {
width: 14px;
height: 14px;
background-position: center center;
background-repeat: no-repeat;
}
-.redactor_toolbar li a.fa-redactor-btn {
+.redactor-toolbar li a.fa-redactor-btn {
display: inline-block;
padding: 9px 10px 8px 10px;
line-height: 1;
}
-.redactor_toolbar.redactor-toolbar-typewriter {
- box-shadow: none;
- background: rgba(240, 240, 240, 0.9);
-}
-.redactor_toolbar.redactor-toolbar-typewriter li a:hover {
- outline: none;
- background-color: #1f78d8;
- color: #fff;
-}
-.redactor_toolbar.redactor-toolbar-typewriter li a:active,
-.redactor_toolbar.redactor-toolbar-typewriter li a.redactor_act {
- outline: none;
- background-color: #ccc;
- color: #444;
-}
-body .redactor_air .redactor_toolbar {
- padding-right: 2px !important;
-}
-.redactor_button_disabled {
+.redactor-toolbar li a.redactor-button-disabled {
+ opacity: 30;
+ filter: alpha(opacity=3000);
filter: alpha(opacity=30);
-moz-opacity: 0.3;
opacity: 0.3;
}
-.redactor_button_disabled:hover {
+.redactor-toolbar li a.redactor-button-disabled:hover {
+ color: #333;
outline: none;
background-color: transparent !important;
cursor: default;
}
+/*
+ Icons
+*/
.re-icon {
font-family: 'RedactorFont';
speak: none;
@@ -474,392 +344,103 @@ body .redactor_air .redactor_toolbar {
.re-gallery:before {
content: "\e61f";
}
-.redactor_format_blockquote {
- padding-left: 10px;
- color: #666 !important;
- font-style: italic;
+/*
+ Toolbar tooltip
+*/
+.redactor-toolbar-tooltip {
+ position: absolute;
+ z-index: 100;
+ text-align: center;
+ top: 0;
+ left: 0;
+ background: #000;
+ color: #fff;
+ padding: 5px 8px;
+ line-height: 1;
+ font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
+ font-size: 12px;
+ border-radius: 2px;
}
-.redactor_format_pre {
- font-family: monospace, sans-serif;
-}
-.redactor_format_h1,
-.redactor_format_h2,
-.redactor_format_h3,
-.redactor_format_h4,
-.redactor_format_h5 {
- font-weight: bold;
-}
-.redactor_format_h1 {
- font-size: 30px;
- line-height: 36px;
-}
-.redactor_format_h2 {
- font-size: 24px;
- line-height: 36px;
-}
-.redactor_format_h3 {
- font-size: 20px;
- line-height: 30px;
-}
-.redactor_format_h4 {
- font-size: 16px;
- line-height: 26px;
-}
-.redactor_format_h5 {
- font-size: 14px;
- line-height: 23px;
-}
-.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h1,
-.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h2,
-.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h3,
-.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h4,
-.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h5 {
- font-size: 1em;
- line-height: 1.6em;
- text-transform: uppercase;
-}
-.redactor-toolbar-typewriter .redactor_dropdown .redactor_format_h2 {
- font-size: .85em;
-}
-.redactor_editor.redactor-editor-typewriter {
- background: #f5f5f5 !important;
- padding: 25px 50px !important;
-}
-.redactor_editor.redactor-editor-typewriter div,
-.redactor_editor.redactor-editor-typewriter p,
-.redactor_editor.redactor-editor-typewriter ul,
-.redactor_editor.redactor-editor-typewriter ol,
-.redactor_editor.redactor-editor-typewriter table,
-.redactor_editor.redactor-editor-typewriter dl,
-.redactor_editor.redactor-editor-typewriter blockquote,
-.redactor_editor.redactor-editor-typewriter pre,
-.redactor_editor.redactor-editor-typewriter h1,
-.redactor_editor.redactor-editor-typewriter h2,
-.redactor_editor.redactor-editor-typewriter h3,
-.redactor_editor.redactor-editor-typewriter h4,
-.redactor_editor.redactor-editor-typewriter h5,
-.redactor_editor.redactor-editor-typewriter h6 {
- font-family: 'Courier New', 'Lucida Console', Consolas, Monaco, monospace, sans-serif;
- font-size: 18px !important;
- line-height: 1.5em !important;
- margin-bottom: 1.5em !important;
-}
-.redactor_editor.redactor-editor-typewriter h2 {
- font-size: 14px !important;
-}
-.redactor_editor.redactor-editor-typewriter h1,
-.redactor_editor.redactor-editor-typewriter h2,
-.redactor_editor.redactor-editor-typewriter h3,
-.redactor_editor.redactor-editor-typewriter h4,
-.redactor_editor.redactor-editor-typewriter h5,
-.redactor_editor.redactor-editor-typewriter h6 {
- text-transform: uppercase;
-}
-.redactor_editor.redactor-editor-typewriter a {
- color: #000 !important;
- text-decoration: underline !important;
-}
-.redactor_editor.redactor_editor_wym {
- padding: 10px 7px 0 7px !important;
- background: #f6f6f6 !important;
-}
-.redactor_editor.redactor_editor_wym div,
-.redactor_editor.redactor_editor_wym p,
-.redactor_editor.redactor_editor_wym ul,
-.redactor_editor.redactor_editor_wym ol,
-.redactor_editor.redactor_editor_wym table,
-.redactor_editor.redactor_editor_wym dl,
-.redactor_editor.redactor_editor_wym pre,
-.redactor_editor.redactor_editor_wym h1,
-.redactor_editor.redactor_editor_wym h2,
-.redactor_editor.redactor_editor_wym h3,
-.redactor_editor.redactor_editor_wym h4,
-.redactor_editor.redactor_editor_wym h5,
-.redactor_editor.redactor_editor_wym h6,
-.redactor_editor.redactor_editor_wym blockquote {
- margin-top: 0;
- margin-bottom: 5px !important;
- padding: 10px !important;
- border: 1px solid #e4e4e4 !important;
- background-color: #fff !important;
- z-index: 0;
-}
-.redactor_editor.redactor_editor_wym blockquote:before {
- content: '';
-}
-.redactor_editor.redactor_editor_wym img {
- position: relative;
- z-index: 1;
-}
-.redactor_editor.redactor_editor_wym div {
- border: 1px dotted #aaa !important;
-}
-.redactor_editor.redactor_editor_wym pre {
- border: 2px dashed #e4e4e4 !important;
- background-color: #f8f8f8 !important;
-}
-.redactor_editor.redactor_editor_wym ul,
-.redactor_editor.redactor_editor_wym ol {
- padding-left: 2em !important;
-}
-.redactor_editor.redactor_editor_wym ul li ul,
-.redactor_editor.redactor_editor_wym ol li ul,
-.redactor_editor.redactor_editor_wym ul li ol,
-.redactor_editor.redactor_editor_wym ol li ol {
- border: none !important;
-}
-.redactor_dropdown {
+/*
+ Dropdown
+*/
+.redactor-dropdown {
position: absolute;
top: 28px;
left: 0;
- padding: 10px;
- width: 200px;
- background-color: #fff;
- box-shadow: 0 1px 5px #bbb;
- font-size: 13px;
- font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif;
- line-height: 21px;
-}
-.redactor-toolbar-typewriter .redactor_dropdown {
- font-family: 'Courier New', 'Lucida Console', Consolas, Monaco, monospace, sans-serif;
- background-color: #f5f5f5;
-}
-.redactor_separator_drop {
- padding: 0 !important;
- border-top: 1px solid #ddd;
- font-size: 0;
- line-height: 0;
-}
-.redactor_dropdown a {
- display: block;
- padding: 3px 5px;
- color: #000;
- text-decoration: none;
-}
-.redactor_dropdown a:hover {
- background-color: #dde4ef;
- color: #444 !important;
- text-decoration: none;
-}
-#redactor_modal_overlay {
- position: fixed;
- top: 0;
- left: 0;
- margin: auto;
- width: 100%;
- height: 100%;
- background-color: #000 !important;
- filter: alpha(opacity=30);
- -moz-opacity: 0.3;
- opacity: 0.3;
-}
-#redactor_modal {
- position: fixed;
- top: 50%;
- left: 50%;
padding: 0;
- background: #fff;
- color: #000;
- font-size: 12px !important;
- font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
- box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
-}
-#redactor_modal header {
- padding: 20px 30px 5px 30px;
- font-size: 16px;
-}
-#redactor_modal section {
- padding: 20px 30px;
-}
-#redactor_modal label {
- display: block !important;
- float: none !important;
- margin: 10px 0 3px 0 !important;
- padding: 0 !important;
- font-size: 12px !important;
-}
-#redactor_modal footer:after {
- content: "";
- display: table;
- clear: both;
-}
-#redactor_modal footer div {
- float: left;
-}
-#redactor_modal input[type="radio"],
-#redactor_modal input[type="checkbox"] {
- position: relative;
- top: -1px;
-}
-#redactor_modal input[type="text"],
-#redactor_modal input[type="password"],
-#redactor_modal input[type="email"],
-#redactor_modal textarea {
- position: relative;
- z-index: 2;
- margin: 0;
- padding: 1px 2px;
- height: 23px;
- border: 1px solid #ccc;
- border-radius: 1px;
- background-color: white;
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
- color: #333;
- font-size: 13px;
- font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
- line-height: 1;
- -moz-transition: border 0.3s ease-in;
- transition: border 0.3s ease-in;
-}
-#redactor_modal textarea {
- display: block;
- margin-top: 4px;
- line-height: 1.4em;
-}
-#redactor_modal input:focus,
-#redactor_modal textarea:focus {
- outline: none;
- border-color: #5ca9e4;
- box-shadow: 0 0 0 2px rgba(70, 161, 231, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2) inset;
-}
-#redactor_modal_close {
- position: absolute;
- top: 5px;
- right: 3px;
- width: 20px;
- height: 20px;
- color: #999;
- font-size: 26px;
- cursor: pointer;
-}
-#redactor_modal_close:hover {
- color: #000;
-}
-.redactor_input {
- width: 99%;
+ min-width: 220px;
+ max-height: 254px;
+ overflow: auto;
+ background-color: #fff;
+ box-shadow: 0 1px 7px rgba(0, 0, 0, 0.25);
font-size: 14px;
+ font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
+ line-height: 1.6em;
}
-.redactor_modal_box {
- overflow: auto;
- margin-bottom: 10px;
- height: 350px;
-}
-#redactor_image_box {
- overflow: auto;
- margin-bottom: 10px;
- height: 270px;
-}
-#redactor_image_box_select {
+.redactor-dropdown a {
display: block;
- margin-bottom: 15px !important;
- width: 200px;
-}
-#redactor_image_box img {
- margin-right: 10px;
- margin-bottom: 10px;
- max-width: 100px;
- cursor: pointer;
-}
-#redactor_tabs {
- margin-bottom: 18px;
-}
-#redactor_tabs a {
- display: inline-block;
- margin-right: 2px;
- padding: 4px 14px;
- border: 1px solid #d2d2d2;
- border-radius: 3px;
- background: #fff;
+ padding: 10px 15px;
color: #000;
text-decoration: none;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.07);
+}
+.redactor-dropdown a:last-child {
+ border-bottom: none;
+}
+.redactor-dropdown a:hover {
+ background-color: #1f78d8;
+ color: #fff !important;
+ text-decoration: none;
+}
+/*
+ LINK TOOLTIP
+*/
+.redactor-link-tooltip {
+ position: absolute;
+ z-index: 49999;
+ padding: 10px;
line-height: 1;
+ display: inline-block;
+ background-color: #000;
+ color: #555 !important;
}
-#redactor_tabs a:hover,
-#redactor_tabs a.redactor_tabs_act {
- border-color: #eee;
- color: #999 !important;
- text-decoration: none !important;
-}
-.redactor_modal_btn_hidden {
- display: none;
-}
-#redactor_modal footer button {
- position: relative;
- width: 100%;
- padding: 10px 16px;
- margin: 0;
- outline: none;
- border: none;
- background-color: #ddd;
- color: #000;
- text-align: center;
- text-decoration: none;
- font-weight: normal;
+.redactor-link-tooltip,
+.redactor-link-tooltip a {
font-size: 12px;
font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
- line-height: 1;
- cursor: pointer;
}
-#redactor_modal footer button:hover {
- color: #777;
- background: none;
- background: #bbb;
+.redactor-link-tooltip a {
+ color: #ccc;
+ margin: 0 5px;
text-decoration: none;
}
-#redactor_modal footer button.redactor_modal_delete_btn {
- background: none;
+.redactor-link-tooltip a:hover {
color: #fff;
- background-color: #b52525;
}
-#redactor_modal footer button.redactor_modal_delete_btn:hover {
- color: rgba(255, 255, 255, 0.6);
- background-color: #881b1b;
-}
-#redactor_modal footer button.redactor_modal_action_btn {
- background: none;
- color: #fff;
- background-color: #2461b5;
-}
-#redactor_modal footer button.redactor_modal_action_btn:hover {
- color: rgba(255, 255, 255, 0.6);
- background-color: #1a4580;
-}
-/* Drag and Drop Area */
-.redactor_droparea {
+/*
+ DROPAREA
+*/
+#redactor-droparea {
position: relative;
- margin: auto;
- margin-bottom: 5px;
- width: 100%;
+ overflow: hidden;
+ padding: 140px 20px;
+ border: 3px dashed rgba(0, 0, 0, 0.1);
}
-.redactor_droparea .redactor_dropareabox {
- position: relative;
- z-index: 1;
- padding: 60px 0;
- width: 99%;
- border: 1px dashed #ddd;
- background: #fff;
+#redactor-droparea.drag-hover {
+ background: rgba(200, 222, 250, 0.75);
+}
+#redactor-droparea.drag-drop {
+ background: rgba(250, 248, 200, 0.5);
+}
+#redactor-droparea-placeholder {
text-align: center;
-}
-.redactor_droparea .redactor_dropareabox,
-.redactor_dropalternative {
- color: #555;
font-size: 12px;
+ color: rgba(0, 0, 0, 0.7);
}
-.redactor_dropalternative {
- margin: 4px 0 2px 0;
-}
-.redactor_dropareabox.hover {
- border-color: #aaa;
- background: #efe3b8;
-}
-.redactor_dropareabox.error {
- border-color: #dcc3c3;
- background: #f7e5e5;
-}
-.redactor_dropareabox.drop {
- border-color: #e0e5d6;
- background: #f4f4ee;
-}
+/*
+ PROGRESS
+*/
#redactor-progress {
position: fixed;
top: 0;
@@ -905,27 +486,406 @@ body .redactor_air .redactor_toolbar {
background-position: 0 0;
}
}
-.redactor_editor figure {
+/*
+ MODAL
+*/
+#redactor-modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ margin: auto;
+ overflow: auto;
+ width: 100%;
+ height: 100%;
+ background-color: #000 !important;
+ opacity: 30;
+ filter: alpha(opacity=3000);
+ filter: alpha(opacity=30);
+ -moz-opacity: 0.3;
+ opacity: 0.3;
+}
+#redactor-modal-box {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+#redactor-modal {
+ position: relative;
+ margin: auto;
+ margin-bottom: 20px;
+ padding: 0;
+ background: #fff;
+ color: #000;
+ font-size: 14px !important;
+ font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
+ box-shadow: 0 1px 70px rgba(0, 0, 0, 0.5);
+}
+#redactor-modal header {
+ padding: 30px 40px 5px 40px;
+ font-size: 18px;
+ font-weight: bold;
+}
+#redactor-modal section {
+ padding: 30px 40px 50px 40px;
+}
+#redactor-modal label {
+ display: block;
+ float: none !important;
+ margin: 15px 0 3px 0 !important;
+ padding: 0;
+}
+#redactor-modal input[type="radio"],
+#redactor-modal input[type="checkbox"] {
+ position: relative;
+ top: -1px;
+}
+#redactor-modal select {
+ width: 100%;
+}
+#redactor-modal input[type="text"],
+#redactor-modal input[type="password"],
+#redactor-modal input[type="email"],
+#redactor-modal input[type="url"],
+#redactor-modal textarea {
+ position: relative;
+ z-index: 2;
+ margin: 0;
+ padding: 5px 4px;
+ height: 28px;
+ border: 1px solid #ccc;
+ border-radius: 1px;
+ background-color: white;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
+ color: #333;
+ width: 100%;
+ font-size: 14px;
+ font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
+ -webkit-transition: border 0.3s ease-in;
+ -moz-transition: border 0.3s ease-in;
+ transition: border 0.3s ease-in;
+}
+#redactor-modal input[type="text"]:focus,
+#redactor-modal input[type="password"]:focus,
+#redactor-modal input[type="email"]:focus,
+#redactor-modal input[type="url"]:focus,
+#redactor-modal textarea:focus {
+ outline: none;
+ border-color: #5ca9e4;
+ box-shadow: 0 0 0 2px rgba(70, 161, 231, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2) inset;
+}
+#redactor-modal input[type="text"].redactor-input-error,
+#redactor-modal input[type="password"].redactor-input-error,
+#redactor-modal input[type="email"].redactor-input-error,
+#redactor-modal input[type="url"].redactor-input-error,
+#redactor-modal textarea.redactor-input-error {
+ border-color: #e82f2f;
+ box-shadow: 0 0 0 2px rgba(232, 47, 47, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2) inset;
+}
+#redactor-modal textarea {
+ display: block;
+ margin-top: 4px;
+ line-height: 1.4em;
+}
+/*
+ Tabs in Modal
+*/
+#redactor-modal-tabber {
+ margin-bottom: 15px;
+ font-size: 12px;
+}
+#redactor-modal-tabber a {
+ border: 1px solid #ddd;
+ line-height: 1;
+ padding: 8px 15px;
+ margin-right: -1px;
+ text-decoration: none;
+ color: #000;
+}
+#redactor-modal-tabber a:hover {
+ background-color: #1f78d8;
+ border-color: #1f78d8;
+ color: #fff;
+}
+#redactor-modal-tabber a.active {
+ cursor: default;
+ background-color: #ddd;
+ border-color: #ddd;
+ color: rgba(0, 0, 0, 0.6);
+}
+/*
+ List in Modal
+*/
+#redactor-modal #redactor-modal-list {
+ margin-left: 0;
+ padding-left: 0;
+ list-style: none;
+ max-height: 250px;
+ overflow-x: scroll;
+}
+#redactor-modal #redactor-modal-list li {
+ border-bottom: 1px solid #ddd;
+}
+#redactor-modal #redactor-modal-list li:last-child {
+ border-bottom: none;
+}
+#redactor-modal #redactor-modal-list a {
+ padding: 10px 5px;
+ color: #000;
+ text-decoration: none;
+ font-size: 13px;
+ display: block;
position: relative;
}
-.redactor_editor figcaption {
+#redactor-modal #redactor-modal-list a:hover {
+ background-color: #eee;
+}
+#redactor-modal-close {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ width: 30px;
+ height: 30px;
+ text-align: right;
+ color: #bbb;
+ font-size: 30px;
+ font-weight: 300;
+ cursor: pointer;
+}
+#redactor-modal-close:hover {
+ color: #000;
+}
+#redactor-modal footer button {
+ position: relative;
+ width: 100%;
+ padding: 14px 16px;
+ margin: 0;
+ outline: none;
+ border: none;
+ background-color: #ddd;
+ color: #000;
+ text-align: center;
+ text-decoration: none;
+ font-weight: normal;
+ font-size: 12px;
+ font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
+ line-height: 1;
+ cursor: pointer;
+}
+#redactor-modal footer button:hover {
+ color: #777;
+ background: none;
+ background: #bbb;
+ text-decoration: none;
+}
+#redactor-modal footer button.redactor-modal-delete-btn {
+ background: none;
+ color: #fff;
+ background-color: #b52525;
+}
+#redactor-modal footer button.redactor-modal-delete-btn:hover {
+ color: rgba(255, 255, 255, 0.6);
+ background-color: #881b1b;
+}
+#redactor-modal footer button.redactor-modal-action-btn {
+ background: none;
+ color: #fff;
+ background-color: #2461b5;
+}
+#redactor-modal footer button.redactor-modal-action-btn:hover {
+ color: rgba(255, 255, 255, 0.6);
+ background-color: #1a4580;
+}
+/*
+ ##############################################
+
+ DROPDOWN FORMATTING
+
+ ##############################################
+*/
+.redactor-dropdown .redactor-formatting-blockquote {
+ color: rgba(0, 0, 0, 0.4);
+ font-style: italic;
+}
+.redactor-dropdown .redactor-formatting-pre {
+ font-family: monospace, sans-serif;
+}
+.redactor-dropdown .redactor-formatting-h1 {
+ font-size: 36px;
+ line-height: 36px;
+ font-weight: bold;
+}
+.redactor-dropdown .redactor-formatting-h2 {
+ font-size: 24px;
+ line-height: 36px;
+ font-weight: bold;
+}
+.redactor-dropdown .redactor-formatting-h3 {
+ font-size: 21px;
+ line-height: 30px;
+ font-weight: bold;
+}
+.redactor-dropdown .redactor-formatting-h4 {
+ font-size: 18px;
+ line-height: 26px;
+ font-weight: bold;
+}
+.redactor-dropdown .redactor-formatting-h5 {
+ font-size: 16px;
+ line-height: 23px;
+ font-weight: bold;
+}
+/*
+ ##############################################
+
+ CONTENT STYLES
+
+ ##############################################
+*/
+.redactor-editor a {
+ color: #15c;
+ text-decoration: underline;
+}
+.redactor-editor object,
+.redactor-editor embed,
+.redactor-editor video,
+.redactor-editor img {
+ max-width: 100%;
+ width: auto;
+}
+.redactor-editor video,
+.redactor-editor img {
+ height: auto;
+}
+.redactor-editor div,
+.redactor-editor p,
+.redactor-editor ul,
+.redactor-editor ol,
+.redactor-editor table,
+.redactor-editor dl,
+.redactor-editor figure,
+.redactor-editor blockquote,
+.redactor-editor pre {
+ margin: 0;
+ margin-bottom: 15px;
+ border: none;
+ background: none;
+ box-shadow: none;
+}
+.redactor-editor iframe,
+.redactor-editor object,
+.redactor-editor hr {
+ margin-bottom: 15px;
+}
+.redactor-editor iframe {
+ width: auto;
+}
+.redactor-editor blockquote {
+ margin-left: 1.6em !important;
+ padding-left: 0;
+ color: #777;
+ font-style: italic;
+}
+.redactor-editor ul,
+.redactor-editor ol {
+ padding-left: 2em;
+}
+.redactor-editor ul ul,
+.redactor-editor ol ol,
+.redactor-editor ul ol,
+.redactor-editor ol ul {
+ margin: 2px;
+ padding: 0;
+ padding-left: 2em;
+ border: none;
+}
+.redactor-editor dl dt {
+ font-weight: bold;
+}
+.redactor-editor dd {
+ margin-left: 1em;
+}
+.redactor-editor code {
+ background-color: #d8d7d7;
+}
+.redactor-editor pre {
+ overflow: auto;
+ padding: 1em;
+ border: 1px solid #ddd;
+ border-radius: 3px;
+ background: #f8f8f8;
+ white-space: pre;
+ font-size: 90%;
+}
+.redactor-editor hr {
+ display: block;
+ height: 1px;
+ border: 0;
+ border-top: 1px solid #ccc;
+}
+.redactor-editor h1,
+.redactor-editor h2,
+.redactor-editor h3,
+.redactor-editor h4,
+.redactor-editor h5,
+.redactor-editor h6 {
+ font-weight: bold;
+ color: #0000;
+ padding: 0;
+ background: none;
+ text-rendering: optimizeLegibility;
+ margin: 0 0 .5em 0;
+}
+.redactor-editor h1,
+.redactor-editor h2,
+.redactor-editor h3,
+.redactor-editor h4 {
+ line-height: 1.3;
+}
+.redactor-editor h1 {
+ font-size: 36px;
+}
+.redactor-editor h2 {
+ font-size: 24px;
+ margin-bottom: .7em;
+}
+.redactor-editor h3 {
+ font-size: 21px;
+}
+.redactor-editor h4 {
+ font-size: 18px;
+}
+.redactor-editor h5 {
+ font-size: 16px;
+}
+.redactor-editor h6 {
+ font-size: 12px;
+ text-transform: uppercase;
+}
+.redactor-editor figure {
+ position: relative;
+}
+.redactor-editor figcaption {
text-align: center;
line-height: 20px;
font-size: 14px;
}
-.redactor_editor figure[data-type=table] {
+.redactor-editor figure[data-type=table] {
clear: both;
}
-.redactor_editor figure[data-type=video] {
+.redactor-editor figure[data-type=video] {
position: relative;
margin-bottom: 20px;
text-align: center;
clear: both;
}
-.redactor_editor figure[data-type=video] p {
+.redactor-editor figure[data-type=video] p {
margin: 0;
}
-.redactor_editor figure[data-type=video].oc-figure-full:before {
+.redactor-editor figure[data-type=video].oc-figure-full:before {
position: relative;
padding-bottom: 51%;
width: 100%;
@@ -933,34 +893,34 @@ body .redactor_air .redactor_toolbar {
content: "";
display: block;
}
-.redactor_editor figure[data-type=video].oc-figure-full iframe {
+.redactor-editor figure[data-type=video].oc-figure-full iframe {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
-.redactor_editor figure[data-type=image] {
+.redactor-editor figure[data-type=image] {
position: relative;
margin-bottom: 20px;
}
-.redactor_editor figure[data-type=image] .oc-figure-controls {
+.redactor-editor figure[data-type=image] .oc-figure-controls {
top: 0px;
}
-.redactor_editor figure[data-type=image] img {
+.redactor-editor figure[data-type=image] img {
width: 100%;
}
-.redactor_editor figure[data-type=image].oc-figure-large {
+.redactor-editor figure[data-type=image].oc-figure-large {
width: 100%;
clear: both;
}
-.redactor_editor figure[data-type=image].oc-figure-medium {
+.redactor-editor figure[data-type=image].oc-figure-medium {
width: 50%;
}
-.redactor_editor figure[data-type=image].oc-figure-small {
+.redactor-editor figure[data-type=image].oc-figure-small {
width: 33%;
}
-.redactor_editor figure[data-type=quote] {
+.redactor-editor figure[data-type=quote] {
font-family: Georgia, serif;
margin-bottom: 20px;
margin-left: 20px;
@@ -969,25 +929,25 @@ body .redactor_air .redactor_toolbar {
border-left: solid 4px #cccccc;
padding-left: 20px;
}
-.redactor_editor figure[data-type=quote] figcaption {
+.redactor-editor figure[data-type=quote] figcaption {
font-weight: bold;
text-align: left;
}
-.redactor_editor figure[data-type=quote] .oc-figure-controls {
+.redactor-editor figure[data-type=quote] .oc-figure-controls {
margin-left: -5px;
}
-.redactor_editor figure[data-type=quote].oc-figure-medium,
-.redactor_editor figure[data-type=quote].oc-figure-medium blockquote {
+.redactor-editor figure[data-type=quote].oc-figure-medium,
+.redactor-editor figure[data-type=quote].oc-figure-medium blockquote {
font-size: 20px;
}
-.redactor_editor figure[data-type=quote].oc-figure-large,
-.redactor_editor figure[data-type=quote].oc-figure-large blockquote {
+.redactor-editor figure[data-type=quote].oc-figure-large,
+.redactor-editor figure[data-type=quote].oc-figure-large blockquote {
font-size: 24px;
}
-.redactor_editor figure[data-type=quote].oc-figure-right {
+.redactor-editor figure[data-type=quote].oc-figure-right {
width: 33%;
}
-.redactor_editor figure[data-type=quote].oc-figure-left {
+.redactor-editor figure[data-type=quote].oc-figure-left {
width: 33%;
border-left: none;
border-right: solid 4px #cccccc;
@@ -996,30 +956,27 @@ body .redactor_air .redactor_toolbar {
margin-left: 0;
margin-right: 20px;
}
-.redactor_editor figure[data-type=quote].oc-figure-left .oc-figure-controls {
+.redactor-editor figure[data-type=quote].oc-figure-left .oc-figure-controls {
margin-left: 0;
margin-right: -5px;
}
-.redactor_editor figure[data-type=quote] cite {
+.redactor-editor figure[data-type=quote] cite {
display: block;
text-align: left;
font-weight: bold;
}
-.redactor_editor figure[data-type=quote] cite:before {
+.redactor-editor figure[data-type=quote] cite:before {
content: "\2014\00a0";
}
-.redactor_editor figure[data-type=quote] cite:empty:before {
+.redactor-editor figure[data-type=quote] cite:empty:before {
opacity: 0.4;
content: "\2014 Type to add citation (optional)";
}
-.redactor_box figure:hover .oc-figure-controls {
- display: block;
-}
-.redactor_box figcaption:empty:before {
+.redactor-box figcaption:empty:before {
opacity: .4;
content: "Type to add caption (optional)";
}
-.redactor_box .oc-figure-controls {
+.redactor-box .oc-figure-controls {
background: #dddddd !important;
padding: 0;
position: absolute;
@@ -1036,7 +993,10 @@ body .redactor_air .redactor_toolbar {
z-index: 800;
text-align: center;
}
-.redactor_box .oc-figure-controls span {
+.redactor-box figure:hover .oc-figure-controls {
+ display: block;
+}
+.redactor-box .oc-figure-controls span {
display: inline-block;
border: none;
background: none;
@@ -1049,35 +1009,35 @@ body .redactor_air .redactor_toolbar {
text-align: center;
cursor: pointer;
}
-.redactor_box .oc-figure-controls span:before {
+.redactor-box .oc-figure-controls span:before {
line-height: 24px;
}
-.redactor_box .oc-figure-controls span:hover {
+.redactor-box .oc-figure-controls span:hover {
background: rgba(255, 255, 255, 0.3);
color: #fff;
background: #999999;
color: #ffffff;
}
-.redactor_box .oc-figure-controls span.on {
+.redactor-box .oc-figure-controls span.on {
background: #fff;
color: #555555;
background-color: #404040;
color: #ffffff;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-divider {
+.redactor-box .oc-figure-controls span.oc-figure-controls-divider {
width: 1px;
background: #cccccc;
padding: 0;
margin: 0 4px;
cursor: normal;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-small {
+.redactor-box .oc-figure-controls span.oc-figure-controls-small {
font-size: 7px;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-medium {
+.redactor-box .oc-figure-controls span.oc-figure-controls-medium {
font-size: 10px;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-arrow-left:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-arrow-left:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1086,7 +1046,7 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f060";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-arrow-right:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-arrow-right:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1095,7 +1055,7 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f061";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-arrow-up:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-arrow-up:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1104,7 +1064,7 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f062";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-arrow-down:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-arrow-down:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1113,7 +1073,7 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f063";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-resize-full:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-resize-full:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1122,7 +1082,7 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f065";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-resize-small:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-resize-small:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1131,10 +1091,10 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f066";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-delete {
+.redactor-box .oc-figure-controls span.oc-figure-controls-delete {
margin-left: 20px;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-delete:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-delete:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1143,16 +1103,16 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f014";
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-delete:hover {
+.redactor-box .oc-figure-controls span.oc-figure-controls-delete:hover {
background: #c63e26;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-table {
+.redactor-box .oc-figure-controls span.oc-figure-controls-table {
width: auto;
padding-left: 10px;
padding-right: 10px;
text-align: left;
}
-.redactor_box .oc-figure-controls span.oc-figure-controls-table:before {
+.redactor-box .oc-figure-controls span.oc-figure-controls-table:before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -1161,42 +1121,42 @@ body .redactor_air .redactor_toolbar {
*margin-right: .3em;
content: "\f0ce";
}
-.redactor_box .oc-figure-right {
+.redactor-box .oc-figure-right {
float: right;
margin-left: 20px;
}
-.redactor_box .oc-figure-right .oc-figure-controls {
+.redactor-box .oc-figure-right .oc-figure-controls {
right: 0;
}
-.redactor_box .oc-figure-left {
+.redactor-box .oc-figure-left {
float: left;
margin-right: 20px;
}
-.redactor_box .oc-dropdown-menu,
-.redactor_box .oc-dropdown-menu ul {
+.redactor-box .oc-dropdown-menu,
+.redactor-box .oc-dropdown-menu ul {
padding: 0 !important;
}
-.redactor_box .oc-dropdown-menu ul {
+.redactor-box .oc-dropdown-menu ul {
background-color: #ffffff !important;
}
-.redactor_box .oc-dropdown-menu a {
+.redactor-box .oc-dropdown-menu a {
text-decoration: none;
padding: 0 15px !important;
color: #39454a !important;
text-decoration: none !important;
}
-.redactor_box .oc-dropdown-menu a:hover,
-.redactor_box .oc-dropdown-menu a:focus {
+.redactor-box .oc-dropdown-menu a:hover,
+.redactor-box .oc-dropdown-menu a:focus {
color: #ffffff !important;
}
@media (max-width: 769px) {
- .redactor_box figure[data-type=image] {
+ .redactor-box figure[data-type=image] {
width: 100% !important;
float: none !important;
margin-left: 0;
margin-right: 0;
}
- .redactor_box figure[data-type=video] iframe {
+ .redactor-box figure[data-type=video] iframe {
width: 100% !important;
height: auto !important;
}
@@ -1305,61 +1265,120 @@ body .redactor_air .redactor_toolbar {
border: 1px solid #e0e0e0;
}
.field-richeditor,
-.field-richeditor .redactor_box {
+.field-richeditor .redactor-box {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
-.field-richeditor .redactor_toolbar {
+.field-richeditor .redactor-toolbar {
border-top-right-radius: 3px;
border-top-left-radius: 3px;
}
.field-richeditor.editor-focus {
border-color: #808c8d;
}
-.field-richeditor.size-tiny .redactor_editor {
+.field-richeditor.size-tiny .redactor-editor {
height: 20px !important;
}
-.field-richeditor.size-small .redactor_editor {
+.field-richeditor.size-small .redactor-editor {
height: 70px !important;
}
-.field-richeditor.size-large .redactor_editor {
+.field-richeditor.size-large .redactor-editor {
height: 170px !important;
}
-.field-richeditor.size-huge .redactor_editor {
+.field-richeditor.size-huge .redactor-editor {
height: 220px !important;
}
-.field-richeditor.size-giant .redactor_editor {
+.field-richeditor.size-giant .redactor-editor {
height: 320px !important;
}
-.field-richeditor.stretch .redactor_box {
+.redactor-box {
+ margin-bottom: 0;
+}
+.redactor-box iframe {
+ border: none;
+}
+.redactor-box-fullscreen {
+ z-index: 399 !important;
+}
+.redactor-toolbar,
+.redactor-dropdown {
+ z-index: 1350 !important;
+}
+#redactor-modal-overlay,
+#redactor-modal-box,
+#redactor-modal {
+ z-index: 1351 !important;
+}
+.redactor-toolbar {
+ background: #dddddd;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.redactor-toolbar li.redactor-btn-right {
+ float: right;
+ margin-right: 2px;
+}
+.redactor-toolbar li a {
+ color: #404040;
+ font-size: 14px;
+ width: 20px;
+ line-height: 20px;
+}
+.redactor-toolbar li a:hover {
+ background-color: #999999;
+ color: #ffffff;
+}
+.redactor-toolbar li a:active,
+.redactor-toolbar li a.redactor-act {
+ background-color: #404040;
+ color: #ffffff;
+}
+.redactor-editor {
+ border: none;
+}
+body .redactor-box-fullscreen {
+ background: #f9f9f9;
+ overflow-y: scroll !important;
+ width: 100%!important;
+}
+body .redactor-box-fullscreen .redactor-editor {
+ background: #fff;
+ max-width: 960px;
+ margin: 20px auto !important;
+ padding: 20px;
+}
+.field-richeditor.stretch .redactor-box {
display: block;
position: relative;
- height: 100%!important;
- width: 100%!important;
+ height: 100% !important;
+ width: 100% !important;
+ -webkit-border-radius: 0 !important;
+ -moz-border-radius: 0 !important;
+ border-radius: 0 !important;
overflow: hidden;
}
-.field-richeditor.stretch .redactor_box .redactor_toolbar {
+.field-richeditor.stretch .redactor-box .redactor-toolbar {
+ -webkit-border-radius: 0 !important;
+ -moz-border-radius: 0 !important;
+ border-radius: 0 !important;
display: block;
border-bottom: none;
position: absolute;
top: 0;
width: 100%;
}
-.field-richeditor.stretch .redactor_box .redactor_editor,
-.field-richeditor.stretch .redactor_box textarea {
- height: auto !important;
- width: 100%!important;
+.field-richeditor.stretch .redactor-box .redactor-editor,
+.field-richeditor.stretch .redactor-box textarea {
+ width: 100% !important;
left: 0;
top: 0;
bottom: 0;
position: absolute;
}
-.field-richeditor.stretch .redactor_box textarea {
+.field-richeditor.stretch .redactor-box .redactor-editor {
+ height: auto !important;
+}
+.field-richeditor.stretch .redactor-box textarea {
padding: 10px;
}
-.field-richeditor.stretch .redactor_box iframe {
- display: block;
- position: absolute;
- height: 100% !important;
-}
diff --git a/modules/backend/formwidgets/richeditor/assets/js/plugin.cleanup.js b/modules/backend/formwidgets/richeditor/assets/js/plugin.cleanup.js
index 8f473bfac..dbd6525d9 100644
--- a/modules/backend/formwidgets/richeditor/assets/js/plugin.cleanup.js
+++ b/modules/backend/formwidgets/richeditor/assets/js/plugin.cleanup.js
@@ -26,9 +26,11 @@
}
- window.RedactorPlugins.cleanup = {
- init: function () {
- this.cleanup = new Cleanup(this)
+ window.RedactorPlugins.cleanup = function() {
+ return {
+ init: function () {
+ this.cleanup = new Cleanup(this)
+ }
}
}
diff --git a/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js b/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js
index 41fc60864..20b70dce2 100644
--- a/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js
+++ b/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js
@@ -32,7 +32,7 @@
*/
this.redactor.$editor.on('click', 'figcaption:empty, cite:empty', $.proxy(function (event) {
$(event.target).prepend('
')
- this.redactor.selectionEnd(event.target)
+ this.redactor.caret.setEnd(event.target)
event.stopPropagation()
}, this))
@@ -47,7 +47,7 @@
* Prevent user from removing captions or citations with delete/backspace keys
*/
this.redactor.$editor.on('keydown', $.proxy(function (event) {
- var current = this.redactor.getCurrent(),
+ var current = this.redactor.selection.getCurrent(),
isEmpty = !current.length,
isCaptionNode = !!$(current).closest('figcaption, cite').length,
isDeleteKey = $.inArray(event.keyCode, [this.redactor.keyCode.BACKSPACE, this.redactor.keyCode.DELETE]) >= 0
@@ -71,14 +71,14 @@
}).remove()
if (this.redactor.opts.visual) {
- this.redactor.sync()
+ this.redactor.code.sync()
}
},
showToolbar: function (event) {
var $figure = $(event.currentTarget),
type = $figure.data('type') || 'default',
- $toolbar = this.getToolbar(type).data('figure', $figure).prependTo($figure)
+ $toolbar = this.getToolbar(type).data('figure', $figure).prependTo($figure).show()
if (this.redactor[type] && this.redactor[type].onShow) {
this.redactor[type].onShow($figure, $toolbar)
@@ -86,7 +86,7 @@
},
hideToolbar: function (event) {
- $(event.currentTarget).find('.oc-figure-controls').appendTo(this.redactor.$box)
+ $(event.currentTarget).find('.oc-figure-controls').appendTo(this.redactor.$box).hide()
},
observeToolbars: function () {
@@ -94,9 +94,9 @@
/*
* Before clicking a command, make sure we save the current node within the editor
*/
- this.redactor.$editor.on('mousedown', '.oc-figure-controls', $.proxy(function () {
+ this.redactor.$editor.on('mousedown', '.oc-figure-controls', $.proxy(function (event) {
event.preventDefault()
- this.current = this.redactor.getCurrent()
+ this.current = this.redactor.selection.getCurrent()
}, this))
this.redactor.$editor.on('click', '.oc-figure-controls span, .oc-figure-controls a', $.proxy(function (event) {
@@ -116,7 +116,7 @@
/*
* Mobile
*/
- if (this.redactor.isMobile()) {
+ if (this.redactor.utils.isMobile()) {
/*
* If $editor is focused, click doesn't seem to fire
@@ -244,7 +244,7 @@
/*
* Maintain undo history
*/
- this.redactor.bufferSet(this.redactor.$editor.html())
+ this.redactor.buffer.set(this.redactor.$editor.html())
/*
* Shared functions
@@ -269,7 +269,7 @@
break
}
- this.redactor.sync()
+ this.redactor.code.sync()
},
@@ -279,21 +279,28 @@
/*
* Node at cursor
*/
- var currentNode = redactor.getBlock()
+ var currentNode = redactor.selection.getBlock()
/*
* Delete key
*/
- if (event.keyCode === 8 && !redactor.getCaretOffset(currentNode) && currentNode.previousSibling && currentNode.previousSibling.nodeName === 'FIGURE') {
+ if (
+ event.keyCode === 8
+ && !redactor.caret.getOffset(currentNode)
+ && currentNode.previousSibling
+ && currentNode.previousSibling.nodeName === 'FIGURE'
+ ) {
event.preventDefault()
}
})
}
}
- window.RedactorPlugins.figure = {
- init: function () {
- this.figure = new Figure(this)
+ window.RedactorPlugins.figure = function() {
+ return {
+ init: function () {
+ this.figure = new Figure(this)
+ }
}
}
diff --git a/modules/backend/formwidgets/richeditor/assets/js/plugin.fullscreen.js b/modules/backend/formwidgets/richeditor/assets/js/plugin.fullscreen.js
index 7d6991620..8e0392850 100644
--- a/modules/backend/formwidgets/richeditor/assets/js/plugin.fullscreen.js
+++ b/modules/backend/formwidgets/richeditor/assets/js/plugin.fullscreen.js
@@ -3,182 +3,127 @@
window.RedactorPlugins = window.RedactorPlugins || {};
- window.RedactorPlugins.fullscreen = {
+ window.RedactorPlugins.fullscreen = function() {
+ return {
- init: function() {
+ init: function() {
+ this.fullscreen.isOpen = false
- this.fullscreen = false
+ var button = this.button.add('fullscreen', 'FullScreen')
+ this.button.addCallback(button, $.proxy(this.fullscreen.toggle, this))
+ button.addClass('redactor_btn_fullscreen').removeClass('redactor-btn-image')
+ button.parent().addClass('redactor-btn-right')
- this.buttonAdd('fullscreen', 'Fullscreen', $.proxy(this.toggleFullscreen, this))
- this.buttonGet('fullscreen').addClass('redactor_btn_fullscreen').removeClass('redactor-btn-image')
- this.buttonGet('fullscreen').parent().addClass('redactor_btn_right')
+ if (this.opts.fullscreen)
+ this.fullscreen.toggle()
+ },
- if (this.opts.fullscreen)
- this.toggleFullscreen()
+ toggle: function() {
+ if (!this.fullscreen.isOpen)
+ this.fullscreen.enable()
+ else
+ this.fullscreen.disable()
+ },
- },
+ enable: function() {
+ this.button.changeIcon('fullscreen', 'normalscreen')
+ this.button.setActive('fullscreen')
+ this.fullscreen.isOpen = true
- toggleFullscreen: function() {
- if (!this.fullscreen)
- this.enableFullScreen()
- else
- this.disableFullScreen()
- },
+ if (this.opts.toolbarExternal) {
+ this.fullscreen.toolcss = {}
+ this.fullscreen.boxcss = {}
+ this.fullscreen.toolcss.width = this.$toolbar.css('width')
+ this.fullscreen.toolcss.top = this.$toolbar.css('top')
+ this.fullscreen.toolcss.position = this.$toolbar.css('position')
+ this.fullscreen.boxcss.top = this.$box.css('top')
+ }
- enableFullScreen: function() {
- var html
+ this.fullscreen.height = this.$editor.height()
- this.buttonChangeIcon('fullscreen', 'normalscreen')
- this.buttonActive('fullscreen')
- this.fullscreen = true
+ if (this.opts.maxHeight) this.$editor.css('max-height', '')
+ if (this.opts.minHeight) this.$editor.css('min-height', '')
- if (this.opts.toolbarExternal) {
- this.toolcss = {}
- this.boxcss = {}
- this.toolcss.width = this.$toolbar.css('width')
- this.toolcss.top = this.$toolbar.css('top')
- this.toolcss.position = this.$toolbar.css('position')
- this.boxcss.top = this.$box.css('top')
+ if (!this.$fullscreenPlaceholder) this.$fullscreenPlaceholder = $('
', - invisibleSpace: '', - rBlockTest: /^(P|H[1-6]|LI|ADDRESS|SECTION|HEADER|FOOTER|ASIDE|ARTICLE)$/i, - alignmentTags: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DD', 'DL', 'DT', 'DIV', 'TD', - 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'ADDRESS', 'SECTION', - 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE'], - ownLine: ['area', 'body', 'head', 'hr', 'i?frame', 'link', 'meta', 'noscript', 'style', 'script', 'table', 'tbody', 'thead', 'tfoot'], - contOwnLine: ['li', 'dt', 'dt', 'h[1-6]', 'option', 'script'], - newLevel: ['blockquote', 'div', 'dl', 'fieldset', 'form', 'frameset', 'map', 'ol', 'p', 'pre', 'select', 'td', 'th', 'tr', 'ul'], - blockLevelElements: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DD', 'DL', 'DT', 'DIV', 'LI', - 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'PRE', 'ADDRESS', 'SECTION', - 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE', 'TD'], + deniedTags: ['html', 'head', 'link', 'body', 'meta', 'script', 'style', 'applet'], + allowedTags: false, // or array + + removeComments: false, + replaceTags: [ + ['strike', 'del'] + ], + replaceStyles: [ + ['font-weight:\\s?bold', "strong"], + ['font-style:\\s?italic', "em"], + ['text-decoration:\\s?underline', "u"], + ['text-decoration:\\s?line-through', 'del'] + ], + removeDataAttr: false, + + removeAttr: false, // or multi array + allowedAttr: false, // or multi array + + removeWithoutAttr: ['span'], // or false + removeEmpty: ['p'], // or false; + + activeButtons: ['deleted', 'italic', 'bold', 'underline', 'unorderedlist', 'orderedlist', + 'alignleft', 'aligncenter', 'alignright', 'justify'], + activeButtonsStates: { + b: 'bold', + strong: 'bold', + i: 'italic', + em: 'italic', + del: 'deleted', + strike: 'deleted', + ul: 'unorderedlist', + ol: 'orderedlist', + u: 'underline' + }, + + shortcuts: { + 'ctrl+shift+m, meta+shift+m': { func: 'inline.removeFormat' }, + 'ctrl+b, meta+b': { func: 'inline.format', params: ['bold'] }, + 'ctrl+i, meta+i': { func: 'inline.format', params: ['italic'] }, + 'ctrl+h, meta+h': { func: 'inline.format', params: ['superscript'] }, + 'ctrl+l, meta+l': { func: 'inline.format', params: ['subscript'] }, + 'ctrl+k, meta+k': { func: 'link.show' }, + 'ctrl+shift+7': { func: 'list.toggle', params: ['orderedlist'] }, + 'ctrl+shift+8': { func: 'list.toggle', params: ['unorderedlist'] } + }, + shortcutsAdd: false, + + // private + buffer: [], + rebuffer: [], + emptyHtml: '
', + invisibleSpace: '', + imageTypes: ['image/png', 'image/jpeg', 'image/gif'], + indentValue: 20, + verifiedTags: ['a', 'img', 'b', 'strong', 'sub', 'sup', 'i', 'em', 'u', 'small', 'strike', 'del', 'cite', 'ul', 'ol', 'li'], // and for span tag special rule + inlineTags: ['strong', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small'], + alignmentTags: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DL', 'DT', 'DD', 'DIV', 'TD', 'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'ADDRESS', 'SECTION', 'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE'], + blockLevelElements: ['PRE', 'UL', 'OL', 'LI'], - // lang - langs: { - en: { - html: 'HTML', - video: 'Insert Video', - image: 'Insert Image', - table: 'Table', - link: 'Link', - link_insert: 'Insert link', - link_edit: 'Edit link', - unlink: 'Unlink', - formatting: 'Formatting', - paragraph: 'Normal text', - quote: 'Quote', - code: 'Code', - header1: 'Header 1', - header2: 'Header 2', - header3: 'Header 3', - header4: 'Header 4', - header5: 'Header 5', - bold: 'Bold', - italic: 'Italic', - fontcolor: 'Font Color', - backcolor: 'Back Color', - unorderedlist: 'Unordered List', - orderedlist: 'Ordered List', - outdent: 'Outdent', - indent: 'Indent', - cancel: 'Cancel', - insert: 'Insert', - save: 'Save', - _delete: 'Delete', - insert_table: 'Insert Table', - insert_row_above: 'Add Row Above', - insert_row_below: 'Add Row Below', - insert_column_left: 'Add Column Left', - insert_column_right: 'Add Column Right', - delete_column: 'Delete Column', - delete_row: 'Delete Row', - delete_table: 'Delete Table', - rows: 'Rows', - columns: 'Columns', - add_head: 'Add Head', - delete_head: 'Delete Head', - title: 'Title', - image_position: 'Position', - none: 'None', - left: 'Left', - right: 'Right', - center: 'Center', - image_web_link: 'Image Web Link', - text: 'Text', - mailto: 'Email', - web: 'URL', - video_html_code: 'Video Embed Code', - file: 'Insert File', - upload: 'Upload', - download: 'Download', - choose: 'Choose', - or_choose: 'Or choose', - drop_file_here: 'Drop file here', - align_left: 'Align text to the left', - align_center: 'Center text', - align_right: 'Align text to the right', - align_justify: 'Justify text', - horizontalrule: 'Insert Horizontal Rule', - deleted: 'Deleted', - anchor: 'Anchor', - link_new_tab: 'Open link in new tab', - underline: 'Underline', - alignment: 'Alignment', - filename: 'Name (optional)', - edit: 'Edit' - } + // lang + langs: { + en: { + html: 'HTML', + video: 'Insert Video', + image: 'Insert Image', + table: 'Table', + link: 'Link', + link_insert: 'Insert link', + link_edit: 'Edit link', + unlink: 'Unlink', + formatting: 'Formatting', + paragraph: 'Normal text', + quote: 'Quote', + code: 'Code', + header1: 'Header 1', + header2: 'Header 2', + header3: 'Header 3', + header4: 'Header 4', + header5: 'Header 5', + bold: 'Bold', + italic: 'Italic', + fontcolor: 'Font Color', + backcolor: 'Back Color', + unorderedlist: 'Unordered List', + orderedlist: 'Ordered List', + outdent: 'Outdent', + indent: 'Indent', + cancel: 'Cancel', + insert: 'Insert', + save: 'Save', + _delete: 'Delete', + insert_table: 'Insert Table', + insert_row_above: 'Add Row Above', + insert_row_below: 'Add Row Below', + insert_column_left: 'Add Column Left', + insert_column_right: 'Add Column Right', + delete_column: 'Delete Column', + delete_row: 'Delete Row', + delete_table: 'Delete Table', + rows: 'Rows', + columns: 'Columns', + add_head: 'Add Head', + delete_head: 'Delete Head', + title: 'Title', + image_position: 'Position', + none: 'None', + left: 'Left', + right: 'Right', + center: 'Center', + image_web_link: 'Image Web Link', + text: 'Text', + mailto: 'Email', + web: 'URL', + video_html_code: 'Video Embed Code or Youtube/Vimeo Link', + file: 'Insert File', + upload: 'Upload', + download: 'Download', + choose: 'Choose', + or_choose: 'Or choose', + drop_file_here: 'Drop file here', + align_left: 'Align text to the left', + align_center: 'Center text', + align_right: 'Align text to the right', + align_justify: 'Justify text', + horizontalrule: 'Insert Horizontal Rule', + deleted: 'Deleted', + anchor: 'Anchor', + link_new_tab: 'Open link in new tab', + underline: 'Underline', + alignment: 'Alignment', + filename: 'Name (optional)', + edit: 'Edit' } + } }; // Functionality @@ -312,10 +335,13 @@ DELETE: 46, DOWN: 40, ENTER: 13, + SPACE: 32, ESC: 27, TAB: 9, CTRL: 17, META: 91, + SHIFT: 16, + ALT: 18, LEFT: 37, LEFT_WIN: 91 }, @@ -323,3005 +349,2913 @@ // Initialization init: function(el, options) { - this.rtePaste = false; - this.$element = this.$source = $(el); + this.$element = $(el); this.uuid = uuid++; - // clonning options - var opts = $.extend(true, {}, $.Redactor.opts); + // if paste event detected = true + this.rtePaste = false; + this.$pasteBox = false; - // current settings - this.opts = $.extend( - {}, - opts, - this.$element.data(), - options - ); + this.loadOptions(options); + this.loadModules(); - this.start = true; - this.dropdowns = []; + // formatting storage + this.formatting = {}; - // get sizes - this.sourceHeight = this.$source.css('height'); - this.sourceWidth = this.$source.css('width'); + // block level tags + $.merge(this.opts.blockLevelElements, this.opts.alignmentTags); + this.reIsBlock = new RegExp('^(' + this.opts.blockLevelElements.join('|' ) + ')$', 'i'); - // dependency of the editor modes - if (this.opts.fullpage) this.opts.iframe = true; - if (this.opts.linebreaks) this.opts.paragraphy = false; - if (this.opts.paragraphy) this.opts.linebreaks = false; - if (this.opts.toolbarFixedBox) this.opts.toolbarFixed = true; - - // the alias for iframe mode - this.document = document; - this.window = window; - - // selection saved - this.savedSel = false; - - // clean setup - this.cleanlineBefore = new RegExp('^<(/?' + this.opts.ownLine.join('|/?' ) + '|' + this.opts.contOwnLine.join('|') + ')[ >]'); - this.cleanlineAfter = new RegExp('^<(br|/?' + this.opts.ownLine.join('|/?' ) + '|/' + this.opts.contOwnLine.join('|/') + ')[ >]'); - this.cleannewLevel = new RegExp('^?(' + this.opts.newLevel.join('|' ) + ')[ >]'); - - // block level - this.rTestBlock = new RegExp('^(' + this.opts.blockLevelElements.join('|' ) + ')$', 'i'); - - // setup formatting permissions - if (this.opts.linebreaks === false) - { - if (this.opts.allowedTags !== false) - { - var arrSearch = ['strong', 'em', 'del']; - var arrAdd = ['b', 'i', 'strike']; - - if ($.inArray('p', this.opts.allowedTags) === '-1') this.opts.allowedTags.push('p'); - - for (i in arrSearch) - { - if ($.inArray(arrSearch[i], this.opts.allowedTags) != '-1') this.opts.allowedTags.push(arrAdd[i]); - } - } - - if (this.opts.deniedTags !== false) - { - var pos = $.inArray('p', this.opts.deniedTags); - if (pos !== '-1') this.opts.deniedTags.splice(pos, pos); - } - } - - // ie & opera - if (this.browser('msie') || this.browser('opera')) - { - this.opts.buttons = this.removeFromArrayByValue(this.opts.buttons, 'horizontalrule'); - } + // setup allowed and denied tags + this.tidy.setupAllowed(); // load lang - this.opts.curLang = this.opts.langs[this.opts.lang]; + this.lang.load(); // extend shortcuts $.extend(this.opts.shortcuts, this.opts.shortcutsAdd); - // init placeholder - this.placeholderInit(); - - // Build - this.buildStart(); + // start callback + this.core.setCallback('start'); + // build + this.start = true; + this.build.run(); }, - toolbarInit: function(lang) + + loadOptions: function(options) + { + this.opts = $.extend( + {}, + $.extend(true, {}, $.Redactor.opts), + this.$element.data(), + options + ); + }, + getModuleMethods: function(object) + { + return Object.getOwnPropertyNames(object).filter(function(property) + { + return typeof object[property] == 'function'; + }); + }, + loadModules: function() + { + var len = $.Redactor.modules.length; + for (var i = 0; i < len; i++) + { + this.bindModuleMethods($.Redactor.modules[i]); + } + }, + bindModuleMethods: function(module) + { + if (typeof this[module] == 'undefined') return; + + // init module + this[module] = this[module](); + + var methods = this.getModuleMethods(this[module]); + var len = methods.length; + + // bind methods + for (var z = 0; z < len; z++) + { + this[module][methods[z]] = this[module][methods[z]].bind(this); + } + }, + + core: function() { return { - html: + getObject: function() { - title: lang.html, - func: 'toggle' + return $.extend({}, this); }, - formatting: + getEditor: function() { - title: lang.formatting, - func: 'show', - dropdown: + return this.$editor; + }, + getBox: function() + { + return this.$box; + }, + getElement: function() + { + return this.$element; + }, + getTextarea: function() + { + return this.$textarea; + }, + getToolbar: function() + { + return (this.$toolbar) ? this.$toolbar : false; + }, + addEvent: function(name) + { + this.core.event = name; + }, + getEvent: function() + { + return this.core.event; + }, + setCallback: function(type, e, data) + { + var callback = this.opts[type + 'Callback']; + if ($.isFunction(callback)) { - p: - { - title: lang.paragraph, - func: 'formatBlocks' - }, - blockquote: - { - title: lang.quote, - func: 'formatQuote', - className: 'redactor_format_blockquote' - }, - pre: - { - title: lang.code, - func: 'formatBlocks', - className: 'redactor_format_pre' - }, - h1: - { - title: lang.header1, - func: 'formatBlocks', - className: 'redactor_format_h1' - }, - h2: - { - title: lang.header2, - func: 'formatBlocks', - className: 'redactor_format_h2' - }, - h3: - { - title: lang.header3, - func: 'formatBlocks', - className: 'redactor_format_h3' - }, - h4: - { - title: lang.header4, - func: 'formatBlocks', - className: 'redactor_format_h4' - }, - h5: - { - title: lang.header5, - func: 'formatBlocks', - className: 'redactor_format_h5' - } - } - }, - bold: - { - title: lang.bold, - exec: 'bold' - }, - italic: - { - title: lang.italic, - exec: 'italic' - }, - deleted: - { - title: lang.deleted, - exec: 'strikethrough' - }, - underline: - { - title: lang.underline, - exec: 'underline' - }, - unorderedlist: - { - title: '• ' + lang.unorderedlist, - exec: 'insertunorderedlist' - }, - orderedlist: - { - title: '1. ' + lang.orderedlist, - exec: 'insertorderedlist' - }, - outdent: - { - title: '< ' + lang.outdent, - func: 'indentingOutdent' - }, - indent: - { - title: '> ' + lang.indent, - func: 'indentingIndent' - }, - image: - { - title: lang.image, - func: 'imageShow' - }, - video: - { - title: lang.video, - func: 'videoShow' - }, - file: - { - title: lang.file, - func: 'fileShow' - }, - table: - { - title: lang.table, - func: 'show', - dropdown: - { - insert_table: - { - title: lang.insert_table, - func: 'tableShow' - }, - separator_drop1: - { - name: 'separator' - }, - insert_row_above: - { - title: lang.insert_row_above, - func: 'tableAddRowAbove' - }, - insert_row_below: - { - title: lang.insert_row_below, - func: 'tableAddRowBelow' - }, - insert_column_left: - { - title: lang.insert_column_left, - func: 'tableAddColumnLeft' - }, - insert_column_right: - { - title: lang.insert_column_right, - func: 'tableAddColumnRight' - }, - separator_drop2: - { - name: 'separator' - }, - add_head: - { - title: lang.add_head, - func: 'tableAddHead' - }, - delete_head: - { - title: lang.delete_head, - func: 'tableDeleteHead' - }, - separator_drop3: - { - name: 'separator' - }, - delete_column: - { - title: lang.delete_column, - func: 'tableDeleteColumn' - }, - delete_row: - { - title: lang.delete_row, - func: 'tableDeleteRow' - }, - delete_table: - { - title: lang.delete_table, - func: 'tableDeleteTable' - } - } - }, - link: { - title: lang.link, - func: 'show', - dropdown: - { - link: - { - title: lang.link_insert, - func: 'linkShow' - }, - unlink: - { - title: lang.unlink, - exec: 'unlink' - } - } - }, - alignment: - { - title: lang.alignment, - func: 'show', - dropdown: - { - alignleft: - { - title: lang.align_left, - func: 'alignmentLeft' - }, - aligncenter: - { - title: lang.align_center, - func: 'alignmentCenter' - }, - alignright: - { - title: lang.align_right, - func: 'alignmentRight' - }, - justify: - { - title: lang.align_justify, - func: 'alignmentJustify' - } - } - }, - alignleft: - { - title: lang.align_left, - func: 'alignmentLeft' - }, - aligncenter: - { - title: lang.align_center, - func: 'alignmentCenter' - }, - alignright: - { - title: lang.align_right, - func: 'alignmentRight' - }, - alignjustify: - { - title: lang.align_justify, - func: 'alignmentJustify' - }, - horizontalrule: - { - exec: 'inserthorizontalrule', - title: lang.horizontalrule - } - - } - }, - - // CALLBACKS - callback: function(type, event, data) - { - var callback = this.opts[ type + 'Callback' ]; - if ($.isFunction(callback)) - { - if (event === false) return callback.call(this, data); - else return callback.call(this, event, data); - } - else return data; - }, - - - // DESTROY - destroy: function() - { - clearInterval(this.autosaveInterval); - - $(window).off('.redactor'); - this.$source.off('redactor-textarea'); - this.$element.off('.redactor').removeData('redactor'); - - var html = this.get(); - - if (this.opts.textareamode) - { - this.$box.after(this.$source); - this.$box.remove(); - this.$source.val(html).show(); - } - else - { - var $elem = this.$editor; - if (this.opts.iframe) $elem = this.$element; - - this.$box.after($elem); - this.$box.remove(); - - $elem.removeClass('redactor_editor').removeClass('redactor_editor_wym').removeAttr('contenteditable').html(html).show(); - } - - if (this.opts.toolbarExternal) - { - $(this.opts.toolbarExternal).html(''); - } - - if (this.opts.air) - { - $('#redactor_air_' + this.uuid).remove(); - } - }, - - // API GET - getObject: function() - { - return $.extend({}, this); - }, - getEditor: function() - { - return this.$editor; - }, - getBox: function() - { - return this.$box; - }, - getIframe: function() - { - return (this.opts.iframe) ? this.$frame : false; - }, - getToolbar: function() - { - return (this.$toolbar) ? this.$toolbar : false; - }, - - // CODE GET & SET - get: function() - { - return this.$source.val(); - }, - getCodeIframe: function() - { - this.$editor.removeAttr('contenteditable').removeAttr('dir'); - var html = this.outerHtml(this.$frame.contents().children()); - this.$editor.attr({ 'contenteditable': true, 'dir': this.opts.direction }); - - return html; - }, - set: function(html, strip, placeholderRemove) - { - html = html.toString(); - html = html.replace(/\$/g, '$'); - - if (this.opts.fullpage) this.setCodeIframe(html); - else this.setEditor(html, strip); - - if (html == '') placeholderRemove = false; - if (placeholderRemove !== false) this.placeholderRemoveFromEditor(); - }, - setEditor: function(html, strip) - { - - if (strip !== false) - { - html = this.cleanSavePreCode(html); - - html = this.cleanStripTags(html); - html = this.cleanConvertProtected(html); - html = this.cleanConvertInlineTags(html, true); - - if (this.opts.linebreaks === false) html = this.cleanConverters(html); - else html = html.replace(/([\w\W]*?)<\/p>/gi, '$2 ' + this.opts.invisibleSpace + ' ' + this.opts.invisibleSpace + ' ' + this.opts.invisibleSpace + ' ' + this.opts.invisibleSpace + ' ').append($(current).clone());
- $(current).replaceWith(node);
- var next = $(node).next();
- if (typeof(next[0]) !== 'undefined' && next[0].tagName == 'BR')
- {
- next.remove();
- }
-
- this.selectionEnd(node);
- }
-
- // convert links
- if ((this.opts.convertLinks || this.opts.convertImageLinks || this.opts.convertVideoLinks) && key === this.keyCode.ENTER)
- {
- this.buildEventKeyupConverters();
- }
-
- // if empty
- if (key === this.keyCode.DELETE || key === this.keyCode.BACKSPACE)
- {
- return this.formatEmpty(e);
- }
-
- this.callback('keyup', e);
- this.sync(e);
- },
- buildEventKeyupConverters: function()
- {
- this.formatLinkify(this.opts.linkProtocol, this.opts.convertLinks, this.opts.convertImageLinks, this.opts.convertVideoLinks, this.opts.linkSize);
-
- setTimeout($.proxy(function()
- {
- if (this.opts.convertImageLinks) this.observeImages();
- if (this.opts.observeLinks) this.observeLinks();
- }, this), 5);
- },
- buildPlugins: function()
- {
- if (!this.opts.plugins ) return;
-
- $.each(this.opts.plugins, $.proxy(function(i, s)
- {
- if (RedactorPlugins[s])
- {
- $.extend(this, RedactorPlugins[s]);
- if ($.isFunction( RedactorPlugins[ s ].init)) this.init();
- }
-
- }, this ));
- },
-
- // IFRAME
- iframeStart: function()
- {
- this.iframeCreate();
-
- if (this.opts.textareamode) this.iframeAppend(this.$source);
- else
- {
- this.$sourceOld = this.$source.hide();
- this.$source = this.buildCodearea(this.$sourceOld);
- this.iframeAppend(this.$sourceOld);
- }
- },
- iframeAppend: function(el)
- {
- this.$source.attr('dir', this.opts.direction).hide();
- this.$box.insertAfter(el).append(this.$frame).append(this.$source);
- },
- iframeCreate: function()
- {
- this.$frame = $('').one('load', $.proxy(function()
- {
- if (this.opts.fullpage)
- {
- this.iframePage();
-
- if (this.content === '') this.content = this.opts.invisibleSpace;
-
- this.$frame.contents()[0].write(this.content);
- this.$frame.contents()[0].close();
-
- var timer = setInterval($.proxy(function()
- {
- if (this.$frame.contents().find('body').html())
- {
- clearInterval(timer);
- this.iframeLoad();
+ if (this.opts.dragImageUpload || this.opts.dragFileUpload)
+ {
+ var files = e.dataTransfer.files;
+ this.upload.directUpload(files[0], e);
+ }
}
- }, this), 0);
- }
- else this.iframeLoad();
+ setTimeout($.proxy(this.clean.clearUnverified, this), 1);
- }, this));
- },
- iframeDoc: function()
- {
- return this.$frame[0].contentWindow.document;
- },
- iframePage: function()
- {
- var doc = this.iframeDoc();
- if (doc.documentElement) doc.removeChild(doc.documentElement);
+ this.core.setCallback('drop', e);
- return doc;
- },
- iframeAddCss: function(css)
- {
- css = css || this.opts.css;
+ }, this));
- if (this.isString(css))
- {
- this.$frame.contents().find('head').append('');
- }
- if ($.isArray(css))
- {
- $.each(css, $.proxy(function(i, url)
- {
- this.iframeAddCss(url);
-
- }, this));
- }
- },
- iframeLoad: function()
- {
- this.$editor = this.$frame.contents().find('body').attr({ 'contenteditable': true, 'dir': this.opts.direction });
-
- // set document & window
- if (this.$editor[0])
- {
- this.document = this.$editor[0].ownerDocument;
- this.window = this.document.defaultView || window;
- }
-
- // iframe css
- this.iframeAddCss();
-
- if (this.opts.fullpage)
- {
- this.setFullpageOnInit(this.$source.val());
- }
- else this.set(this.content, true, false);
-
- this.buildOptions();
- this.buildAfter();
- },
-
- // PLACEHOLDER
- placeholderInit: function()
- {
- if (this.opts.placeholder !== false)
- {
- this.placeholderText = this.opts.placeholder;
- this.opts.placeholder = true;
- }
- else
- {
- if (typeof this.$element.attr('placeholder') == 'undefined' || this.$element.attr('placeholder') == '')
- {
- this.opts.placeholder = false;
- }
- else
- {
- this.placeholderText = this.$element.attr('placeholder');
- this.opts.placeholder = true;
- }
- }
- },
- placeholderStart: function(html)
- {
- if (this.opts.placeholder === false)
- {
- return false;
- }
-
- if (this.isEmpty(html))
- {
- this.opts.focus = false;
- this.placeholderOnFocus();
- this.placeholderOnBlur();
-
- return this.placeholderGet();
- }
- else
- {
- this.placeholderOnBlur();
- }
-
- return false;
- },
- placeholderOnFocus: function()
- {
- this.$editor.on('focus.redactor_placeholder', $.proxy(this.placeholderFocus, this));
- },
- placeholderOnBlur: function()
- {
- this.$editor.on('blur.redactor_placeholder', $.proxy(this.placeholderBlur, this));
- },
- placeholderGet: function()
- {
- var ph = $('').data('redactor', 'verified')
- .attr('contenteditable', false).text(this.placeholderText);
-
- if (this.opts.linebreaks === false)
- {
- return $(' ').append(ph);
- }
- else return ph;
- },
- placeholderBlur: function()
- {
- var html = this.get();
- if (this.isEmpty(html))
- {
- this.placeholderOnFocus();
- this.$editor.html(this.placeholderGet());
- }
- },
- placeholderFocus: function()
- {
- this.$editor.find('span.redactor_placeholder').remove();
-
- var html = '';
- if (this.opts.linebreaks === false)
- {
- html = this.opts.emptyHtml;
- }
-
- this.$editor.off('focus.redactor_placeholder');
- this.$editor.html(html);
-
- if (this.opts.linebreaks === false)
- {
- // place the cursor inside emptyHtml
- this.selectionStart(this.$editor.children()[0]);
- }
- else
- {
- this.focus();
- }
-
- this.sync();
- },
- placeholderRemoveFromEditor: function()
- {
- this.$editor.find('span.redactor_placeholder').remove();
- this.$editor.off('focus.redactor_placeholder');
- },
- placeholderRemoveFromCode: function(html)
- {
- return html.replace(/(.*?)<\/span>/i, '');
- },
-
- // SHORTCUTS
- shortcuts: function(e, key)
- {
-
- // disable browser's hot keys for bold and italic
- if (!this.opts.shortcuts)
- {
- if ((e.ctrlKey || e.metaKey) && (key === 66 || key === 73))
- {
- e.preventDefault();
- }
-
- return false;
- }
-
- $.each(this.opts.shortcuts, $.proxy(function(str, command)
- {
- var keys = str.split(',');
- for (var i in keys)
- {
- if (typeof keys[i] === 'string')
+ // click
+ this.$editor.on('click.redactor', $.proxy(function(e)
{
- this.shortcutsHandler(e, $.trim(keys[i]), $.proxy(function()
+ var type = 'click';
+ if ((this.core.getEvent() == 'click' || this.core.getEvent() == 'arrow'))
{
- eval(command);
- }, this));
+ type = false;
+ }
+
+ this.core.addEvent(type);
+ this.utils.disableSelectAll();
+ this.core.setCallback('click', e);
+
+ }, this));
+
+ // paste
+ this.$editor.on('paste.redactor', $.proxy(this.paste.init, this));
+
+ // keydown
+ this.$editor.on('keydown.redactor', $.proxy(this.keydown.init, this));
+
+ // keyup
+ this.$editor.on('keyup.redactor', $.proxy(this.keyup.init, this));
+
+ // textarea keydown
+ if ($.isFunction(this.opts.codeKeydownCallback))
+ {
+ this.$textarea.on('keydown.redactor-textarea', $.proxy(this.opts.codeKeydownCallback, this));
}
- }
-
- }, this));
-
-
- },
- shortcutsHandler: function(e, keys, origHandler)
- {
- // based on https://github.com/jeresig/jquery.hotkeys
- var hotkeysSpecialKeys =
- {
- 8: "backspace", 9: "tab", 10: "return", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
- 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
- 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", 59: ";", 61: "=",
- 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
- 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
- 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
- 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 173: "-", 186: ";", 187: "=",
- 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'"
- };
-
-
- var hotkeysShiftNums =
- {
- "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
- "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
- ".": ">", "/": "?", "\\": "|"
- };
-
- keys = keys.toLowerCase().split(" ");
- var special = hotkeysSpecialKeys[e.keyCode],
- character = String.fromCharCode( e.which ).toLowerCase(),
- modif = "", possible = {};
-
- $.each([ "alt", "ctrl", "meta", "shift"], function(index, specialKey)
- {
- if (e[specialKey + 'Key'] && special !== specialKey)
- {
- modif += specialKey + '+';
- }
- });
-
-
- if (special)
- {
- possible[modif + special] = true;
- }
-
- if (character)
- {
- possible[modif + character] = true;
- possible[modif + hotkeysShiftNums[character]] = true;
-
- // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
- if (modif === "shift+")
- {
- possible[hotkeysShiftNums[character]] = true;
- }
- }
-
- for (var i = 0, l = keys.length; i < l; i++)
- {
- if (possible[keys[i]])
- {
- e.preventDefault();
- return origHandler.apply(this, arguments);
- }
- }
- },
-
- // FOCUS
- focus: function()
- {
- if (!this.browser('opera'))
- {
- this.window.setTimeout($.proxy(this.focusSet, this, true), 1);
- }
- else
- {
- this.$editor.focus();
- }
- },
- focusWithSaveScroll: function()
- {
- if (this.browser('msie'))
- {
- var top = this.document.documentElement.scrollTop;
- }
-
- this.$editor.focus();
-
- if (this.browser('msie'))
- {
- this.document.documentElement.scrollTop = top;
- }
- },
- focusEnd: function()
- {
- if (!this.browser('mozilla'))
- {
- this.focusSet();
- }
- else
- {
- if (this.opts.linebreaks === false)
- {
- var last = this.$editor.children().last();
-
- this.$editor.focus();
- this.selectionEnd(last);
- }
- else
- {
- this.focusSet();
- }
- }
- },
- focusSet: function(collapse, element)
- {
- this.$editor.focus();
-
- if (typeof element == 'undefined')
- {
- element = this.$editor[0];
- }
-
- var range = this.getRange();
- range.selectNodeContents(element);
-
- // collapse - controls the position of focus: the beginning (true), at the end (false).
- range.collapse(collapse || false);
-
- var sel = this.getSelection();
- sel.removeAllRanges();
- sel.addRange(range);
- },
-
- // TOGGLE
- toggle: function(direct)
- {
- if (this.opts.visual) this.toggleCode(direct);
- else this.toggleVisual();
- },
- toggleVisual: function()
- {
- var html = this.$source.hide().val();
- if (typeof this.modified !== 'undefined')
- {
- var modified = this.modified.replace(/\n/g, '');
-
- var thtml = html.replace(/\n/g, '');
- thtml = this.cleanRemoveSpaces(thtml, false);
-
- this.modified = this.cleanRemoveSpaces(modified, false) !== thtml;
- }
-
- if (this.modified)
- {
- // don't remove the iframe even if cleared all.
- if (this.opts.fullpage && html === '')
- {
- this.setFullpageOnInit(html);
- }
- else
- {
- this.set(html);
- if (this.opts.fullpage)
+ // textarea keyup
+ if ($.isFunction(this.opts.codeKeyupCallback))
{
- this.buildBindKeyboard();
+ this.$textarea.on('keyup.redactor-textarea', $.proxy(this.opts.codeKeyupCallback, this));
}
- }
- this.callback('change', false, html);
- }
+ // focus
+ if ($.isFunction(this.opts.focusCallback))
+ {
+ this.$editor.on('focus.redactor', $.proxy(this.opts.focusCallback, this));
+ }
- if (this.opts.iframe) this.$frame.show();
- else this.$editor.show();
-
- if (this.opts.fullpage) this.$editor.attr('contenteditable', true );
-
- this.$source.off('keydown.redactor-textarea-indenting');
-
- this.$editor.focus();
- this.selectionRestore();
-
- this.observeStart();
- this.buttonActiveVisual();
- this.buttonInactive('html');
- this.opts.visual = true;
-
-
- },
- toggleCode: function(direct)
- {
- if (direct !== false) this.selectionSave();
-
- var height = null;
- if (this.opts.iframe)
- {
- height = this.$frame.height();
- if (this.opts.fullpage) this.$editor.removeAttr('contenteditable');
- this.$frame.hide();
- }
- else
- {
- height = this.$editor.innerHeight();
- this.$editor.hide();
- }
-
- var html = this.$source.val();
-
- // tidy html
- if (html !== '' && this.opts.tidyHtml)
- {
- this.$source.val(this.cleanHtml(html));
- }
-
- this.modified = html;
-
- this.$source.height(height).show().focus();
-
- // textarea indenting
- this.$source.on('keydown.redactor-textarea-indenting', this.textareaIndenting);
-
- this.buttonInactiveVisual();
- this.buttonActive('html');
- this.opts.visual = false;
- },
- textareaIndenting: function(e)
- {
- if (e.keyCode === 9)
- {
- var $el = $(this);
- var start = $el.get(0).selectionStart;
- $el.val($el.val().substring(0, start) + "\t" + $el.val().substring($el.get(0).selectionEnd));
- $el.get(0).selectionStart = $el.get(0).selectionEnd = start + 1;
- return false;
- }
- },
-
- // AUTOSAVE
- autosave: function()
- {
- var savedHtml = false;
- this.autosaveInterval = setInterval($.proxy(function()
- {
- var html = this.get();
- if (savedHtml !== html)
- {
- var name = this.$source.attr('name');
- $.ajax({
- url: this.opts.autosave,
- type: 'post',
- data: 'name=' + name + '&' + name + '=' + escape(encodeURIComponent(html)),
- success: $.proxy(function(data)
- {
- var json = $.parseJSON(data);
- if (typeof json.error == 'undefined')
- {
- // success
- this.callback('autosave', false, json);
- }
- else
- {
- // error
- this.callback('autosaveError', false, json);
- }
-
- savedHtml = html;
-
- }, this)
+ var clickedElement;
+ $(document).on('mousedown', function(e) {
+ clickedElement = $(e.target);
});
+
+ // blur
+ this.$editor.on('blur.redactor', $.proxy(function(e)
+ {
+ if (this.rtePaste) return;
+
+ var $el = $(clickedElement);
+ if (!$el.hasClass('redactor-toolbar, redactor-dropdown') && !$el.is('#redactor-modal') && $el.parents('.redactor-toolbar, .redactor-dropdown, #redactor-modal').size() === 0)
+ {
+ this.utils.disableSelectAll();
+ if ($.isFunction(this.opts.blurCallback)) this.core.setCallback('blur', e);
+ }
+ }, this));
+ },
+ setHelpers: function()
+ {
+ // autosave
+ this.autosave.enable();
+
+ // placeholder
+ this.placeholder.enable();
+
+ // focus
+ if (this.opts.focus) setTimeout($.proxy(this.focus.setStart, this), 100);
+ if (this.opts.focusEnd) setTimeout($.proxy(this.focus.setEnd, this), 100);
+
+ },
+ plugins: function()
+ {
+ if (!this.opts.plugins) return;
+ if (!RedactorPlugins) return;
+
+ $.each(this.opts.plugins, $.proxy(function(i, s)
+ {
+ if (RedactorPlugins[s])
+ {
+ if (!$.isFunction(RedactorPlugins[s])) return;
+
+ this[s] = RedactorPlugins[s]();
+
+ var methods = this.getModuleMethods(this[s]);
+ var len = methods.length;
+
+ // bind methods
+ for (var z = 0; z < len; z++)
+ {
+ this[s][methods[z]] = this[s][methods[z]].bind(this);
+ }
+
+ if ($.isFunction(this[s].init)) this[s].init();
+ }
+
+ }, this));
+
+
+ },
+ disableMozillaEditing: function()
+ {
+ if (!this.utils.browser('mozilla')) return;
+
+ // FF fix
+ try {
+ document.execCommand('enableObjectResizing', false, false);
+ document.execCommand('enableInlineTableEditing', false, false);
+ } catch (e) {}
}
- }, this), this.opts.autosaveInterval*1000);
+ };
},
-
- // TOOLBAR
- toolbarBuild: function()
+ lang: function()
{
- // hide on mobile
- if (this.isMobile() && this.opts.buttonsHideOnMobile.length > 0)
- {
- $.each(this.opts.buttonsHideOnMobile, $.proxy(function(i, s)
+ return {
+ load: function()
{
- var index = this.opts.buttons.indexOf(s);
- this.opts.buttons.splice(index, 1);
-
- }, this));
- }
-
- // extend buttons
- if (this.opts.air)
- {
- this.opts.buttons = this.opts.airButtons;
- }
- else
- {
- if (!this.opts.buttonSource)
+ this.opts.curLang = this.opts.langs[this.opts.lang];
+ },
+ get: function(name)
{
+ return (typeof this.opts.curLang[name] != 'undefined') ? this.opts.curLang[name] : '';
+ }
+ };
+ },
+ toolbar: function()
+ {
+ return {
+ init: function()
+ {
+ return {
+ html:
+ {
+ title: this.lang.get('html'),
+ func: 'code.toggle'
+ },
+ formatting:
+ {
+ title: this.lang.get('formatting'),
+ dropdown:
+ {
+ p:
+ {
+ title: this.lang.get('paragraph'),
+ func: 'block.format'
+ },
+ blockquote:
+ {
+ title: this.lang.get('quote'),
+ func: 'block.format'
+ },
+ pre:
+ {
+ title: this.lang.get('code'),
+ func: 'block.format'
+ },
+ h1:
+ {
+ title: this.lang.get('header1'),
+ func: 'block.format'
+ },
+ h2:
+ {
+ title: this.lang.get('header2'),
+ func: 'block.format'
+ },
+ h3:
+ {
+ title: this.lang.get('header3'),
+ func: 'block.format'
+ },
+ h4:
+ {
+ title: this.lang.get('header4'),
+ func: 'block.format'
+ },
+ h5:
+ {
+ title: this.lang.get('header5'),
+ func: 'block.format'
+ }
+ }
+ },
+ bold:
+ {
+ title: this.lang.get('bold'),
+ func: 'inline.format'
+ },
+ italic:
+ {
+ title: this.lang.get('italic'),
+ func: 'inline.format'
+ },
+ deleted:
+ {
+ title: this.lang.get('deleted'),
+ func: 'inline.format'
+ },
+ underline:
+ {
+ title: this.lang.get('underline'),
+ func: 'inline.format'
+ },
+ unorderedlist:
+ {
+ title: '• ' + this.lang.get('unorderedlist'),
+ func: 'list.toggle'
+ },
+ orderedlist:
+ {
+ title: '1. ' + this.lang.get('orderedlist'),
+ func: 'list.toggle'
+ },
+ outdent:
+ {
+ title: '< ' + this.lang.get('outdent'),
+ func: 'indent.decrease'
+ },
+ indent:
+ {
+ title: '> ' + this.lang.get('indent'),
+ func: 'indent.increase'
+ },
+ image:
+ {
+ title: this.lang.get('image'),
+ func: 'image.show'
+ },
+ file:
+ {
+ title: this.lang.get('file'),
+ func: 'file.show'
+ },
+ link:
+ {
+ title: this.lang.get('link'),
+ dropdown:
+ {
+ link:
+ {
+ title: this.lang.get('link_insert'),
+ func: 'link.show'
+ },
+ unlink:
+ {
+ title: this.lang.get('unlink'),
+ func: 'link.unlink'
+ }
+ }
+ },
+ alignment:
+ {
+ title: this.lang.get('alignment'),
+ dropdown:
+ {
+ left:
+ {
+ title: this.lang.get('align_left'),
+ func: 'alignment.left'
+ },
+ center:
+ {
+ title: this.lang.get('align_center'),
+ func: 'alignment.center'
+ },
+ right:
+ {
+ title: this.lang.get('align_right'),
+ func: 'alignment.right'
+ },
+ justify:
+ {
+ title: this.lang.get('align_justify'),
+ func: 'alignment.justify'
+ }
+ }
+ },
+ horizontalrule:
+ {
+ title: this.lang.get('horizontalrule'),
+ func: 'line.insert'
+ }
+ };
+ },
+ build: function()
+ {
+ this.toolbar.hideButtons();
+ this.toolbar.hideButtonsOnMobile();
+ this.toolbar.isButtonSourceNeeded();
+
+ if (this.opts.buttons.length === 0) return;
+
+ this.$toolbar = this.toolbar.createContainer();
+
+ this.toolbar.setOverflow();
+ this.toolbar.append();
+ this.toolbar.setFormattingTags();
+ this.toolbar.loadButtons();
+ this.toolbar.setTabindex();
+ this.toolbar.setFixed();
+
+ // buttons response
+ if (this.opts.activeButtons)
+ {
+ this.$editor.on('mouseup.redactor keyup.redactor focus.redactor', $.proxy(this.observe.buttons, this));
+ }
+
+ },
+ createContainer: function()
+ {
+ return $('
');
- }
-
- // $ fix
- html = html.replace(/$/g, '$');
-
- html = this.cleanEmpty(html);
-
- this.$editor.html(html);
-
- // set no editable
- this.setNonEditable();
- this.setSpansVerified();
-
- this.sync();
- },
- setCodeIframe: function(html)
- {
- var doc = this.iframePage();
- this.$frame[0].src = "about:blank";
-
- html = this.cleanConvertProtected(html);
- html = this.cleanConvertInlineTags(html);
- html = this.cleanRemoveSpaces(html);
-
- doc.open();
- doc.write(html);
- doc.close();
-
- // redefine editor for fullpage mode
- if (this.opts.fullpage)
- {
- this.$editor = this.$frame.contents().find('body').attr({ 'contenteditable': true, 'dir': this.opts.direction });
- }
-
- // set no editable
- this.setNonEditable();
- this.setSpansVerified();
- this.sync();
-
- },
- setFullpageOnInit: function(html)
- {
- this.fullpageDoctype = html.match(/^<\!doctype[^>]*>/i);
- if (this.fullpageDoctype && this.fullpageDoctype.length == 1)
- {
- html = html.replace(/^<\!doctype[^>]*>/i, '');
- }
-
- html = this.cleanSavePreCode(html, true);
- html = this.cleanConverters(html);
- html = this.cleanEmpty(html);
-
- // set code
- this.$editor.html(html);
-
- // set no editable
- this.setNonEditable();
- this.setSpansVerified();
- this.sync();
- },
- setFullpageDoctype: function()
- {
- if (this.fullpageDoctype && this.fullpageDoctype.length == 1)
- {
- var source = this.fullpageDoctype[0] + '\n' + this.$source.val();
- this.$source.val(source);
- }
- },
- setSpansVerified: function()
- {
- var spans = this.$editor.find('span');
- var replacementTag = 'inline';
-
- $.each(spans, function() {
- var outer = this.outerHTML;
-
- // Replace opening tag
- var regex = new RegExp('<' + this.tagName, 'gi');
- var newTag = outer.replace(regex, '<' + replacementTag);
-
- // Replace closing tag
- regex = new RegExp('' + this.tagName, 'gi');
- newTag = newTag.replace(regex, '' + replacementTag);
-
- $(this).replaceWith(newTag);
- });
-
- },
- setSpansVerifiedHtml: function(html)
- {
- html = html.replace(//, '
') html = '';
-
- // xhtml
- if (this.opts.xhtml)
- {
- var xhtmlTags = ['br', 'hr', 'img', 'link', 'input', 'meta'];
- $.each(xhtmlTags, function(i,s)
- {
- html = html.replace(new RegExp('<' + s + '(.*?[^\/$]?)>', 'gi'), '<' + s + '$1 />');
- });
-
- }
-
- // before callback
- html = this.callback('syncBefore', false, html);
-
- this.$source.val(html);
- this.setFullpageDoctype();
-
- // onchange & after callback
- this.callback('syncAfter', false, html);
-
- if (this.start === false)
- {
-
- if (typeof e != 'undefined')
- {
- switch(e.which)
- {
- case 37: // left
- break;
- case 38: // up
- break;
- case 39: // right
- break;
- case 40: // down
- break;
-
- default: this.callback('change', false, html);
- }
- }
- else
- {
- this.callback('change', false, html);
- }
- }
-
- },
- syncClean: function(html)
- {
- if (!this.opts.fullpage) html = this.cleanStripTags(html);
-
- // trim
- html = $.trim(html);
-
- // removeplaceholder
- html = this.placeholderRemoveFromCode(html);
-
- // remove space
- html = html.replace(//gi, '');
- html = html.replace(//gi, '');
- html = html.replace(/<\/a> /gi, '<\/a> ');
- html = html.replace(/\u200B/g, '');
-
- if (html == '' || html == '
\n?<\/(P|H[1-6]|LI|ADDRESS|SECTION|HEADER|FOOTER|ASIDE|ARTICLE)>/gi, '$1>');
-
- // remove image resize
- html = html.replace(/([\w\W]*?)<\/span>/gi, '$3
');
- html = html.replace(/(.*?)<\/span>/gi, '');
- html = html.replace(/(.*?)<\/span>/gi, '');
-
- // remove empty lists
- html = html.replace(/<(ul|ol)>\s*\t*\n*<\/(ul|ol)>/gi, '');
-
- // remove font
- if (this.opts.cleanFontTag)
- {
- html = html.replace(/([\w\W]*?)<\/font>/gi, '$2');
- }
-
- // remove spans
- html = html.replace(/([\w\W]*?)<\/span>/gi, '$2');
- html = html.replace(/
/gi, '
');
-
- // special characters
- html = html.replace(/&/gi, '&');
- html = html.replace(/\u2122/gi, '™');
- html = html.replace(/\u00a9/gi, '©');
- html = html.replace(/\u2026/gi, '…');
- html = html.replace(/\u2014/gi, '—');
- html = html.replace(/\u2010/gi, '‐');
-
- html = this.cleanReConvertProtected(html);
-
- return html;
- },
-
-
-
- // BUILD
- buildStart: function()
- {
- // content
- this.content = '';
-
- // container
- this.$box = $('');
-
- // textarea test
- if (this.$source[0].tagName === 'TEXTAREA') this.opts.textareamode = true;
-
- // mobile
- if (this.opts.mobile === false && this.isMobile())
- {
- this.buildMobile();
- }
- else
- {
- // get the content at the start
- this.buildContent();
-
- if (this.opts.iframe)
- {
- // build as iframe
- this.opts.autoresize = false;
- this.iframeStart();
- }
- else if (this.opts.textareamode) this.buildFromTextarea();
- else this.buildFromElement();
-
- // options and final setup
- if (!this.opts.iframe)
- {
- this.buildOptions();
- this.buildAfter();
- }
- }
- },
- buildMobile: function()
- {
- if (!this.opts.textareamode)
- {
- this.$editor = this.$source;
- this.$editor.hide();
- this.$source = this.buildCodearea(this.$editor);
- this.$source.val(this.content);
- }
-
- this.$box.insertAfter(this.$source).append(this.$source);
- },
- buildContent: function()
- {
- if (this.opts.textareamode) this.content = $.trim(this.$source.val());
- else this.content = $.trim(this.$source.html());
- },
- buildFromTextarea: function()
- {
- this.$editor = $('');
- this.$box.insertAfter(this.$source).append(this.$editor).append(this.$source);
-
- // enable
- this.buildAddClasses(this.$editor);
- this.buildEnable();
- },
- buildFromElement: function()
- {
- this.$editor = this.$source;
- this.$source = this.buildCodearea(this.$editor);
- this.$box.insertAfter(this.$editor).append(this.$editor).append(this.$source);
-
- // enable
- this.buildEnable();
- },
- buildCodearea: function($source)
- {
- return $('').attr('name', $source.attr('id')).css('height', this.sourceHeight);
- },
- buildAddClasses: function(el)
- {
- // append textarea classes to editable layer
- $.each(this.$source.get(0).className.split(/\s+/), function(i,s)
- {
- el.addClass('redactor_' + s);
- });
- },
- buildEnable: function()
- {
- this.$editor.addClass('redactor_editor').attr({ 'contenteditable': true, 'dir': this.opts.direction });
- this.$source.attr('dir', this.opts.direction).hide();
-
- // set code
- this.set(this.content, true, false);
- },
- buildOptions: function()
- {
- var $source = this.$editor;
- if (this.opts.iframe) $source = this.$frame;
-
- // options
- if (this.opts.tabindex) $source.attr('tabindex', this.opts.tabindex);
-
- if (this.opts.minHeight) $source.css('min-height', this.opts.minHeight + 'px');
- // FF fix bug with line-height rendering
- else if (this.browser('mozilla') && this.opts.linebreaks)
- {
- this.$editor.css('min-height', '45px');
- }
- // FF fix bug with line-height rendering
- if (this.browser('mozilla') && this.opts.linebreaks)
- {
- this.$editor.css('padding-bottom', '10px');
- }
-
-
- if (this.opts.maxHeight)
- {
- this.opts.autoresize = false;
- this.sourceHeight = this.opts.maxHeight;
- }
- if (this.opts.wym) this.$editor.addClass('redactor_editor_wym');
- if (this.opts.typewriter) this.$editor.addClass('redactor-editor-typewriter');
- if (!this.opts.autoresize) $source.css('height', this.sourceHeight);
-
- },
- buildAfter: function()
- {
- this.start = false;
-
- // load toolbar
- if (this.opts.toolbar)
- {
- this.opts.toolbar = this.toolbarInit(this.opts.curLang);
- this.toolbarBuild();
- }
-
- // modal templates
- this.modalTemplatesInit();
-
- // plugins
- this.buildPlugins();
-
- // enter, tab, etc.
- this.buildBindKeyboard();
-
- // autosave
- if (this.opts.autosave) this.autosave();
-
- // observers
- setTimeout($.proxy(this.observeStart, this), 4);
-
- // FF fix
- if (this.browser('mozilla'))
- {
- try {
- this.document.execCommand('enableObjectResizing', false, false);
- this.document.execCommand('enableInlineTableEditing', false, false);
- } catch (e) {}
- }
-
- // focus
- if (this.opts.focus) setTimeout($.proxy(this.focus, this), 100);
-
- // code mode
- if (!this.opts.visual)
- {
- setTimeout($.proxy(function()
- {
- this.opts.visual = true;
- this.toggle(false);
-
- }, this), 200);
- }
-
- // init callback
- this.callback('init');
- },
- buildBindKeyboard: function()
- {
- this.dblEnter = 0;
-
- if (this.opts.dragUpload && (this.opts.imageUpload !== false || this.opts.s3 !== false))
- {
- this.$editor.on('drop.redactor', $.proxy(this.buildEventDrop, this));
- }
-
- this.$editor.on('click.redactor', $.proxy(function()
- {
- this.selectall = false;
-
- }, this));
-
- this.$editor.on('input.redactor', $.proxy(this.sync, this));
- this.$editor.on('paste.redactor', $.proxy(this.buildEventPaste, this));
- this.$editor.on('keydown.redactor', $.proxy(this.buildEventKeydown, this));
- this.$editor.on('keyup.redactor', $.proxy(this.buildEventKeyup, this));
-
- // textarea callback
- if ($.isFunction(this.opts.textareaKeydownCallback))
- {
- this.$source.on('keydown.redactor-textarea', $.proxy(this.opts.textareaKeydownCallback, this));
- }
-
- // focus callback
- if ($.isFunction(this.opts.focusCallback))
- {
- this.$editor.on('focus.redactor', $.proxy(this.opts.focusCallback, this));
- }
-
- var clickedElement;
- $(document).mousedown(function(e) {
- clickedElement = $(e.target);
- });
-
- // blur callback
- this.$editor.on('blur.redactor', $.proxy(function(e)
- {
- if (!$(clickedElement).hasClass('redactor_toolbar') && $(clickedElement).parents('.redactor_toolbar').size() == 0)
- {
- this.selectall = false;
- if ($.isFunction(this.opts.blurCallback)) this.callback('blur', e);
- }
- }, this));
-
- },
- buildEventDrop: function(e)
- {
- e = e.originalEvent || e;
-
- if (window.FormData === undefined || !e.dataTransfer) return true;
-
- var length = e.dataTransfer.files.length;
- if (length == 0) return true;
-
- e.preventDefault();
-
- var file = e.dataTransfer.files[0];
-
- if (this.opts.dnbImageTypes !== false && this.opts.dnbImageTypes.indexOf(file.type) == -1)
- {
- return true;
- }
-
- this.bufferSet();
-
- this.showProgressBar();
-
- if (this.opts.s3 === false)
- {
- this.dragUploadAjax(this.opts.imageUpload, file, true, e, this.opts.imageUploadParam);
- }
- else
- {
- this.s3uploadFile(file);
- }
-
-
- },
- buildEventPaste: function(e)
- {
- var oldsafari = false;
- if (this.browser('webkit') && navigator.userAgent.indexOf('Chrome') === -1)
- {
- var arr = this.browser('version').split('.');
- if (arr[0] < 536) oldsafari = true;
- }
-
- if (oldsafari) return true;
-
- // paste except opera (not webkit)
- if (this.browser('opera')) return true;
-
- // clipboard upload
- if (this.opts.clipboardUpload && this.buildEventClipboardUpload(e)) return true;
-
- if (this.opts.cleanup)
- {
- this.rtePaste = true;
-
- this.selectionSave();
-
- if (!this.selectall)
- {
- if (this.opts.autoresize === true && this.fullscreen !== true)
- {
- this.$editor.height(this.$editor.height());
- this.saveScroll = this.document.body.scrollTop;
+ return (typeof data == 'undefined') ? callback.call(this, e) : callback.call(this, e, data);
}
else
{
- this.saveScroll = this.$editor.scrollTop();
+ return (typeof data == 'undefined') ? e : data;
}
- }
-
- var frag = this.extractContent();
-
- setTimeout($.proxy(function()
+ },
+ destroy: function()
{
- var pastedFrag = this.extractContent();
- this.$editor.append(frag);
+ this.core.setCallback('destroy');
- this.selectionRestore();
+ // off events and remove data
+ this.$element.off('.redactor').removeData('redactor');
+ this.$editor.off('.redactor');
- var html = this.getFragmentHtml(pastedFrag);
- this.pasteClean(html);
+ // common
+ this.$editor.removeClass('redactor-editor redactor-linebreaks redactor-placeholder');
+ this.$editor.removeAttr('contenteditable');
- if (this.opts.autoresize === true && this.fullscreen !== true) this.$editor.css('height', 'auto');
+ var html = this.code.get();
- }, this), 1);
- }
+ if (this.build.isTextarea())
+ {
+ this.$box.after(this.$element);
+ this.$box.remove();
+ this.$element.val(html).show();
+ }
+ else
+ {
+ this.$box.after(this.$editor);
+ this.$box.remove();
+ this.$element.html(html).show();
+ }
+
+ // paste box
+ if (this.$pasteBox) this.$pasteBox.remove();
+
+ // modal
+ if (this.$modalBox) this.$modalBox.remove();
+ if (this.$modalOverlay) this.$modalOverlay.remove();
+
+ // buttons tooltip
+ $('.redactor-toolbar-tooltip').remove();
+
+ // autosave
+ clearInterval(this.autosaveInterval);
+
+ }
+ };
},
- buildEventClipboardUpload: function(e)
+ build: function()
{
- var event = e.originalEvent || e;
- this.clipboardFilePaste = false;
-
-
- if (typeof(event.clipboardData) === 'undefined') return false;
- if (event.clipboardData.items)
- {
- var file = event.clipboardData.items[0].getAsFile();
- if (file !== null)
+ return {
+ run: function()
{
- this.bufferSet();
- this.clipboardFilePaste = true;
- var reader = new FileReader();
- reader.onload = $.proxy(this.pasteClipboardUpload, this);
- reader.readAsDataURL(file);
+ this.build.createContainerBox();
+ this.build.loadContent();
+ this.build.loadEditor();
+ this.build.enableEditor();
+ this.build.setCodeAndCall();
- return true;
- }
- }
-
- return false;
-
- },
- buildEventKeydown: function(e)
- {
- if (this.rtePaste) return false;
-
- var key = e.which;
- var ctrl = e.ctrlKey || e.metaKey;
- var parent = this.getParent();
- var current = this.getCurrent();
- var block = this.getBlock();
- var pre = false;
-
- this.callback('keydown', e);
-
- /*
- firefox cmd+left/Cmd+right browser back/forward fix -
- http://joshrhoderick.wordpress.com/2010/05/05/how-firefoxs-command-key-bug-kills-usability-on-the-mac/
- */
- if (this.browser('mozilla') && "modify" in window.getSelection())
- {
- if ((ctrl) && (e.keyCode===37 || e.keyCode===39))
+ },
+ isTextarea: function()
{
- var selection = this.getSelection();
- var lineOrWord = (e.metaKey ? "line" : "word");
- if (e.keyCode===37)
+ return (this.$element[0].tagName === 'TEXTAREA');
+ },
+ createContainerBox: function()
+ {
+ this.$box = $('');
+ },
+ createTextarea: function()
+ {
+ this.$textarea = $('').attr('name', this.build.getTextareaName());
+ },
+ getTextareaName: function()
+ {
+ var name = this.$element.attr('id');
+ if (typeof(name) == 'undefined')
{
- selection.modify("extend","left",lineOrWord);
- if (!e.shiftKey)
- {
- selection.collapseToStart();
- }
- }
- if (e.keyCode===39)
- {
- selection.modify("extend","right",lineOrWord);
- if (!e.shiftKey)
- {
- selection.collapseToEnd();
- }
+ name = 'content-' + this.uuid;
}
- e.preventDefault();
- }
- }
-
-
- this.imageResizeHide(false);
-
- // pre & down
- if ((parent && $(parent).get(0).tagName === 'PRE') || (current && $(current).get(0).tagName === 'PRE'))
- {
- pre = true;
- if (key === this.keyCode.DOWN) this.insertAfterLastElement(block);
- }
-
- // down
- if (key === this.keyCode.DOWN)
- {
- if (parent && $(parent)[0].tagName === 'BLOCKQUOTE') this.insertAfterLastElement(parent);
- if (current && $(current)[0].tagName === 'BLOCKQUOTE') this.insertAfterLastElement(current);
-
- if (parent && $(parent)[0].tagName === 'P' && $(parent).parent()[0].tagName == 'BLOCKQUOTE')
+ return name;
+ },
+ loadContent: function()
{
- this.insertAfterLastElement(parent, $(parent).parent()[0]);
- }
- if (current && $(current)[0].tagName === 'P' && parent && $(parent)[0].tagName == 'BLOCKQUOTE')
+ var func = (this.build.isTextarea()) ? 'val' : 'html';
+ this.content = $.trim(this.$element[func]());
+ },
+ enableEditor: function()
{
- this.insertAfterLastElement(current, parent);
- }
- }
-
- // shortcuts setup
- this.shortcuts(e, key);
-
- // buffer setup
- if (ctrl && key === 90 && !e.shiftKey && !e.altKey) // z key
- {
- e.preventDefault();
- if (this.opts.buffer.length) this.bufferUndo();
- else this.document.execCommand('undo', false, false);
- return;
- }
- // undo
- else if (ctrl && key === 90 && e.shiftKey && !e.altKey)
- {
- e.preventDefault();
- if (this.opts.rebuffer.length != 0) this.bufferRedo();
- else this.document.execCommand('redo', false, false);
- return;
- }
-
- // space
- if (key == 32)
- {
- this.bufferSet();
- }
-
- // select all
- if (ctrl && key === 65)
- {
- this.bufferSet();
- this.selectall = true;
- }
- else if (key != this.keyCode.LEFT_WIN && !ctrl)
- {
- this.selectall = false;
- }
-
- // enter
- if (key == this.keyCode.ENTER && !e.shiftKey && !e.ctrlKey && !e.metaKey)
- {
- // remove selected content on enter
- var range = this.getRange();
- if (range && range.collapsed === false)
+ this.$editor.attr({ 'contenteditable': true, 'dir': this.opts.direction });
+ },
+ loadEditor: function()
{
- sel = this.getSelection();
- if (sel.rangeCount)
+ var func = (this.build.isTextarea()) ? 'fromTextarea' : 'fromElement';
+ this.build[func]();
+ },
+ fromTextarea: function()
+ {
+ this.$editor = $('');
+ this.$textarea = this.$element;
+ this.$box.insertAfter(this.$element).append(this.$editor).append(this.$element);
+ this.$editor.addClass('redactor-editor');
+
+ this.$element.hide();
+ },
+ fromElement: function()
+ {
+ this.$editor = this.$element;
+ this.build.createTextarea();
+ this.$box.insertAfter(this.$editor).append(this.$editor).append(this.$textarea);
+ this.$editor.addClass('redactor-editor');
+
+ this.$textarea.hide();
+ },
+ setCodeAndCall: function()
+ {
+ // set code
+ this.code.set(this.content);
+
+ this.build.setOptions();
+ this.build.callEditor();
+
+ // code mode
+ if (!this.opts.visual)
{
- range.deleteContents();
+ setTimeout($.proxy(this.code.showCode, this), 200);
}
- }
-
- // In ie, opera in the tables are created paragraphs, fix it.
- if (this.browser('msie') && (parent.nodeType == 1 && (parent.tagName == 'TD' || parent.tagName == 'TH')))
+ },
+ callEditor: function()
{
- e.preventDefault();
- this.bufferSet();
- this.insertNode(document.createElement('br'));
- this.callback('enter', e);
- return false;
- }
+ this.build.disableMozillaEditing();
+ this.build.setEvents();
+ this.build.setHelpers();
- // blockquote exit
- if (block && (block.tagName == 'BLOCKQUOTE' || $(block).parent()[0].tagName == 'BLOCKQUOTE'))
- {
- if (this.isEndOfElement())
+ // load toolbar
+ if (this.opts.toolbar)
{
- if (this.dblEnter == 1)
- {
- var element;
- var last;
- if (block.tagName == 'BLOCKQUOTE')
- {
- last = 'br';
- element = block;
- }
- else
- {
- last = 'p';
- element = $(block).parent()[0];
- }
-
- e.preventDefault();
- this.insertingAfterLastElement(element);
- this.dblEnter = 0;
-
- if (last == 'p')
- {
- $(block).parent().find('p').last().remove();
- }
- else
- {
- var tmp = $.trim($(block).html());
- $(block).html(tmp.replace(/
$/i, ''));
- }
-
- return;
- }
- else this.dblEnter++;
- }
- else this.dblEnter++;
- }
-
- // pre
- if (pre === true)
- {
- return this.buildEventKeydownPre(e, current);
- }
- else
- {
- if (!this.opts.linebreaks)
- {
- // lists exit
- if (block && block.tagName == 'LI')
- {
- var listCurrent = this.getBlock();
- if (listCurrent !== false || listCurrent.tagName === 'LI')
- {
- var listText = $.trim($(block).text());
- var listCurrentText = $.trim($(listCurrent).text());
- if (listText == ''
- && listCurrentText == ''
- && $(listCurrent).next('li').size() == 0
- && $(listCurrent).parents('li').size() == 0)
- {
- this.bufferSet();
-
- var $list = $(listCurrent).closest('ol, ul');
- $(listCurrent).remove();
- var node = $('
' + this.opts.invisibleSpace);
-
- $(current).replaceWith(node);
- this.selectionStart(node);
- this.sync();
- }
-
- if (typeof current.nodeValue !== 'undefined' && current.nodeValue !== null)
- {
- if (current.remove && current.nodeType === 3 && current.nodeValue.match(/[^\u200B]/g) == null)
- {
- $(current).prev().remove();
- this.sync();
- }
- }
- },
- buildEventKeydownInsertLineBreak: function(e)
- {
- this.bufferSet();
- e.preventDefault();
- this.insertLineBreak();
- this.callback('enter', e);
- return;
- },
- buildEventKeyup: function(e)
- {
- if (this.rtePaste) return false;
-
- var key = e.which;
- var parent = this.getParent();
- var current = this.getCurrent();
-
- // replace to p before / after the table or body
- if (!this.opts.linebreaks && current.nodeType == 3 && (parent == false || parent.tagName == 'BODY'))
- {
- var node = $('').addClass('redactor-toolbar').attr('id', 'redactor-toolbar-' + this.uuid);
+ },
+ setFormattingTags: function()
+ {
+ $.each(this.opts.toolbar.formatting.dropdown, $.proxy(function (i, s)
+ {
+ if ($.inArray(i, this.opts.formatting) == -1) delete this.opts.toolbar.formatting.dropdown[i];
+ }, this));
+
+ },
+ loadButtons: function()
+ {
+ $.each(this.opts.buttons, $.proxy(function(i, btnName)
+ {
+ if (!this.opts.toolbar[btnName]) return;
+
+ if (this.opts.fileUpload === false && btnName === 'file') return true;
+ if (this.opts.imageUpload === false && btnName === 'image') return true;
+
+ var btnObject = this.opts.toolbar[btnName];
+ this.$toolbar.append($('
').addClass('redactor_toolbar').attr('id', 'redactor_toolbar_' + this.uuid);
-
- if (this.opts.typewriter)
- {
- this.$toolbar.addClass('redactor-toolbar-typewriter');
- }
-
- if (this.opts.toolbarOverflow && this.isMobile())
- {
- this.$toolbar.addClass('redactor-toolbar-overflow');
- }
-
- if (this.opts.air)
- {
- // air box
- this.$air = $('