diff --git a/CHANGELOG.md b/CHANGELOG.md index 300d3f690..e2ed0d4a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ * **Build 14x** (2014-09-xx) - Added new `hint` form field type (see Backend > Forms docs). + - Added new `containerAttributes` property to form fields (see Backend > Forms docs). * **Build 145** (2014-09-13) - Standard setting pages now have **Save** and **Save and Close** buttons. diff --git a/app/config/view.php b/app/config/view.php index eba10a4cf..34b8f3873 100644 --- a/app/config/view.php +++ b/app/config/view.php @@ -26,6 +26,6 @@ return array( | */ - 'pagination' => 'pagination::slider', + 'pagination' => 'pagination::slider-3', ); diff --git a/modules/backend/assets/js/october.inputpreset.js b/modules/backend/assets/js/october.inputpreset.js index 21b04926b..11ab61b83 100644 --- a/modules/backend/assets/js/october.inputpreset.js +++ b/modules/backend/assets/js/october.inputpreset.js @@ -86,6 +86,9 @@ 'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m', 'ن':'n', 'ه':'h', 'و':'o', 'ي':'y' }, + PERSIAN_MAP = { + 'آ':'a', 'ا':'a', 'پ':'p', 'چ':'ch', 'ژ':'zh', 'ک':'k', 'گ':'gh', 'ی':'y' + }, LITHUANIAN_MAP = { 'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u', 'ž':'z', @@ -111,6 +114,7 @@ POLISH_MAP, LATVIAN_MAP, ARABIC_MAP, + PERSIAN_MAP, LITHUANIAN_MAP, SERBIAN_MAP, AZERBAIJANI_MAP diff --git a/modules/backend/assets/js/october.triggerapi.js b/modules/backend/assets/js/october.triggerapi.js index aa5b811da..a57c3f52b 100644 --- a/modules/backend/assets/js/october.triggerapi.js +++ b/modules/backend/assets/js/october.triggerapi.js @@ -1,22 +1,22 @@ /* * The trigger API. * - * The API allows to change elements' visibility or status (enabled/disabled) basing on + * The API allows to change elements' visibility or status (enabled/disabled) basing on * other elements' statuses. Example: enable a button if any checkbox inside another * element is checked. * * Supported data attributes: - * - data-trigger-type, values: display, hide, enable, disable + * - data-trigger-type, values: display, hide, enable, disable, empty * - data-trigger: a CSS selector for elements that trigger the action (checkboxes) - * - data-trigger-condition, values: + * - data-trigger-condition, values: * - checked: determines the condition the elements specified in the data-trigger * should satisfy in order the condition to be considered as "true". * - value[somevalue]: determines if the value of data-trigger equals the specified value (somevalue) * the condition is considered "true". * - * Example: * * Supported events: @@ -83,6 +83,8 @@ this.$el.prop('disabled', !status).trigger('disable', [!status]).toggleClass('control-disabled', !status) else if (this.options.triggerType == 'disable') this.$el.prop('disabled', status).trigger('disable', [status]).toggleClass('control-disabled', status) + else if (this.options.triggerType == 'empty' && status) + this.$el.trigger('empty').val('') if (this.options.triggerType == 'display' || this.options.triggerType == 'hide') this.fixButtonClasses() diff --git a/modules/backend/classes/BackendHelper.php b/modules/backend/classes/BackendHelper.php index cc1a8b5db..60dfd700e 100644 --- a/modules/backend/classes/BackendHelper.php +++ b/modules/backend/classes/BackendHelper.php @@ -2,7 +2,6 @@ use URL; use Config; -use Session; use Request; use October\Rain\Router\Helper as RouterHelper; @@ -29,9 +28,8 @@ class BackendHelper */ public function skinAsset($path = null) { - $path = RouterHelper::normalizeUrl($path); - $skinPath = Skin::getActive()->skinPath; - return URL::asset($skinPath . $path); + $skinPath = Skin::getActive()->getPath($path, true); + return URL::asset($skinPath); } /** diff --git a/modules/backend/classes/Controller.php b/modules/backend/classes/Controller.php index dee0402d9..b4dcd6b8a 100644 --- a/modules/backend/classes/Controller.php +++ b/modules/backend/classes/Controller.php @@ -127,7 +127,7 @@ class Controller extends Extendable * Define layout and view paths */ $this->layout = 'default'; - $this->layoutPath = ['modules/backend/layouts']; + $this->layoutPath = Skin::getActive()->getLayoutPaths(); // Option A: (@todo Determine which is faster by benchmark) // $relativePath = strtolower(str_replace('\\', '/', get_called_class())); diff --git a/modules/backend/classes/FormField.php b/modules/backend/classes/FormField.php index 68ae63e67..6646b71fd 100644 --- a/modules/backend/classes/FormField.php +++ b/modules/backend/classes/FormField.php @@ -1,6 +1,7 @@ placeholder = $config['placeholder']; if (isset($config['default'])) $this->defaults = $config['default']; if (isset($config['cssClass'])) $this->cssClass = $config['cssClass']; - if (isset($config['attributes'])) $this->attributes = $config['attributes']; + if (isset($config['attributes'])) $this->attributes($config['attributes']); + if (isset($config['containerAttributes'])) $this->attributes($config['containerAttributes'], 'container'); if (isset($config['depends'])) $this->depends = $config['depends']; if (isset($config['path'])) $this->path = $config['path']; @@ -266,6 +268,41 @@ class FormField return $this; } + /** + * Sets the attributes for this field in a given position. + * - field: Attributes are added to the form field element (input, select, textarea, etc) + * - container: Attributes are added to the form field container (div.form-group) + * @param array $items + * @param strubg $position + * @return void + */ + public function attributes($items, $position = 'field') + { + if (!is_array($items)) + return; + + $multiArray = array_filter($items, 'is_array'); + if (!$multiArray) { + $this->attributes[$position] = $items; + return; + } + + foreach ($items as $_position => $_items) { + $this->attributes($_items, $_position); + } + } + + /** + * Returns the attributes for this field at a given position. + * @param string $position + * @return array + */ + public function getAttributes($position = 'field', $htmlBuild = true) + { + $result = array_get($this->attributes, $position, []); + return $htmlBuild ? HTML::attributes($result) : $result; + } + /** * Returns a value suitable for the field name property. * @param string $arrayName Specify a custom array name diff --git a/modules/backend/classes/Skin.php b/modules/backend/classes/Skin.php index e2ded69a6..39598eba7 100644 --- a/modules/backend/classes/Skin.php +++ b/modules/backend/classes/Skin.php @@ -1,6 +1,9 @@ skinPath = str_replace('\\', '/', get_called_class()); + $this->defaultSkinPath = PATH_BASE . '/modules/backend'; + + /* + * Guess the skin path + */ + $class = get_called_class(); + $classFolder = strtolower(Str::getRealClass($class)); + $classFile = realpath(dirname(File::fromClass($class))); + $this->skinPath = $classFile + ? $classFile . '/' . $classFolder + : $this->defaultSkinPath; + + $this->publicSkinPath = File::localToPublic($this->skinPath); + $this->defaultPublicSkinPath = File::localToPublic($this->defaultSkinPath); + } + + /** + * Looks up a path to a skin-based file, if it doesn't exist, the default path is used. + * @param string $path + * @param boolean $isPublic + * @return string + */ + public function getPath($path = null, $isPublic = false) + { + $path = RouterHelper::normalizeUrl($path); + $assetFile = $this->skinPath . $path; + + if (File::isFile($assetFile)) { + return $isPublic + ? $this->publicSkinPath . $path + : $this->skinPath . $path; + } + else { + return $isPublic + ? $this->defaultPublicSkinPath . $path + : $this->defaultSkinPath . $path; + } + } + + /** + * Returns an array of paths where skin layouts can be found. + * @return array + */ + public function getLayoutPaths() + { + return [$this->skinPath.'/layouts', $this->defaultSkinPath.'/layouts']; } /** diff --git a/modules/backend/classes/WidgetManager.php b/modules/backend/classes/WidgetManager.php index 007ad3571..827c7aa56 100644 --- a/modules/backend/classes/WidgetManager.php +++ b/modules/backend/classes/WidgetManager.php @@ -136,8 +136,11 @@ class WidgetManager return $this->formWidgets; } - /* + /** * Registers a single form form widget. + * @param string $className Widget class name. + * @param array $widgetInfo Registration information, can contain an 'alias' key. + * @return void */ public function registerFormWidget($className, $widgetInfo = null) { diff --git a/modules/backend/composer.json b/modules/backend/composer.json index 32560e89c..4e4289b34 100644 --- a/modules/backend/composer.json +++ b/modules/backend/composer.json @@ -21,8 +21,8 @@ "october/rain": "~1.0" }, "autoload": { - "psr-0": { - "Backend": "" + "psr-4": { + "Backend\\": "" } }, "extra": { diff --git a/modules/backend/formwidgets/Relation.php b/modules/backend/formwidgets/Relation.php index debdaf3dc..575275ceb 100644 --- a/modules/backend/formwidgets/Relation.php +++ b/modules/backend/formwidgets/Relation.php @@ -3,6 +3,7 @@ use Lang; use Backend\Classes\FormWidgetBase; use System\Classes\SystemException; +use Illuminate\Database\Eloquent\Relations\Relation as RelationBase; /** * Form Relationship @@ -89,30 +90,40 @@ class Relation extends FormWidgetBase */ protected function makeRenderFormField() { - $field = clone $this->formField; - $relatedObj = $this->model->makeRelation($this->relationName); - $query = $relatedObj->newQuery(); + return $this->renderFormField = RelationBase::noConstraints(function() { - if (in_array($this->relationType, ['belongsToMany', 'morphToMany', 'morphedByMany'])) { - $field->type = 'checkboxlist'; - } - else if ($this->relationType == 'belongsTo') { - $field->type = 'dropdown'; - $field->placeholder = $this->emptyOption; - } + $field = clone $this->formField; - // It is safe to assume that if the model and related model are of - // the exact same class, then it cannot be related to itself - if ($this->model->exists && (get_class($this->model) == get_class($relatedObj))) { - $query->where($relatedObj->getKeyName(), '<>', $this->model->id); - } + list($model, $attribute) = $this->getModelArrayAttribute($this->relationName); + $relatedObj = $model->makeRelation($attribute); + $query = $model->{$attribute}()->newQuery(); - if (in_array('October\Rain\Database\Traits\NestedTree', class_uses($relatedObj))) - $field->options = $query->listsNested($this->nameFrom, $relatedObj->getKeyName()); - else - $field->options = $query->lists($this->nameFrom, $relatedObj->getKeyName()); + if (in_array($this->relationType, ['belongsToMany', 'morphToMany', 'morphedByMany'])) { + $field->type = 'checkboxlist'; + } + else if ($this->relationType == 'belongsTo') { + $field->type = 'dropdown'; + $field->placeholder = $this->emptyOption; + } - return $this->renderFormField = $field; + // It is safe to assume that if the model and related model are of + // the exact same class, then it cannot be related to itself + if ($model->exists && (get_class($model) == get_class($relatedObj))) { + $query->where($relatedObj->getKeyName(), '<>', $model->getKey()); + } + + // Even though "no constraints" is applied, belongsToMany constrains the query + // by joining its pivot table. Remove all joins from the query. + $query->getQuery()->getQuery()->joins = []; + + $treeTraits = ['October\Rain\Database\Traits\NestedTree', 'October\Rain\Database\Traits\SimpleTree']; + if (count(array_intersect($treeTraits, class_uses($relatedObj))) > 0) + $field->options = $query->listsNested($this->nameFrom, $relatedObj->getKeyName()); + else + $field->options = $query->lists($this->nameFrom, $relatedObj->getKeyName()); + + return $field; + }); } /** diff --git a/modules/backend/formwidgets/RichEditor.php b/modules/backend/formwidgets/RichEditor.php index 3108edb3b..4167a0432 100644 --- a/modules/backend/formwidgets/RichEditor.php +++ b/modules/backend/formwidgets/RichEditor.php @@ -49,17 +49,14 @@ class RichEditor extends FormWidgetBase */ public function loadAssets() { - // Plugins $this->addJs('js/plugin.cleanup.js', 'core'); $this->addJs('js/plugin.fullscreen.js', 'core'); $this->addJs('js/plugin.figure.js', 'core'); $this->addJs('js/plugin.quote.js', 'core'); + $this->addJs('js/plugin.table.js', 'core'); + $this->addJs('js/plugin.image.js', 'core'); - // Redactor - // $this->addCss('vendor/redactor/redactor.css', 'core'); $this->addJs('vendor/redactor/redactor.js', 'core'); - - // Rich editor $this->addCss('css/richeditor.css', 'core'); $this->addJs('js/richeditor.js', 'core'); diff --git a/modules/backend/formwidgets/richeditor/assets/css/cms-default.css b/modules/backend/formwidgets/richeditor/assets/css/cms-default.css new file mode 100644 index 000000000..9dc825cd0 --- /dev/null +++ b/modules/backend/formwidgets/richeditor/assets/css/cms-default.css @@ -0,0 +1,213 @@ +figure { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +figure { + position: relative; +} +figcaption { + text-align: center; + line-height: 24px; + font-size: 16px; +} +figure[data-type=table] { + clear: both; +} +figure[data-type=video] { + position: relative; + margin-bottom: 24px; + text-align: center; + clear: both; +} +figure[data-type=video] p { + margin: 0; +} +figure[data-type=video].oc-figure-full p { + position: relative; + padding-bottom: 51%; + width: 100%; + height: 0; +} +figure[data-type=video].oc-figure-full iframe { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; +} +figure[data-type=image] { + position: relative; + margin-bottom: 24px; +} +figure[data-type=image] img { + width: 100%; +} +figure[data-type=image].oc-figure-large { + width: 100%; + clear: both; +} +figure[data-type=image].oc-figure-medium { + width: 50%; +} +figure[data-type=image].oc-figure-small { + width: 33%; +} +figure[data-type=quote] { + font-family: "Georgia", serif; + margin-bottom: 24px; + margin-left: 24px; + font-style: italic; + position: relative; + border-left: solid 5px #404040; + padding-left: 24px; +} +figure[data-type=quote] figcaption { + font-weight: bold; + text-align: left; +} +figure[data-type=quote].oc-figure-medium { + font-size: 20px; +} +figure[data-type=quote].oc-figure-large { + font-size: 24px; +} +figure[data-type=quote].oc-figure-right { + width: 33%; +} +figure[data-type=quote].oc-figure-left { + width: 33%; + border-left: none; + border-right: solid 5px #404040; + padding-left: 0; + padding-right: 24px; + margin-left: 0; + margin-right: 24px; +} +figure[data-type=quote] cite { + display: block; + text-align: left; + font-weight: bold; +} +figure[data-type=quote] cite:before { + content: "\2014\00a0"; +} +.oc-figure-right { + float: right; + margin-left: 24px; +} +.oc-figure-right .oc-figure-controls { + right: 0; +} +.oc-figure-left { + float: left; + margin-right: 24px; +} +@media screen and (max-width: 480px) { + figure[data-type=image] { + width: 100% !important; + float: none !important; + margin-left: 0; + margin-right: 0; + } + figure[data-type=video] iframe { + width: 100% !important; + height: auto !important; + } +} +.oc-table { + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin-bottom: 20px; +} +.oc-table caption { + color: #000; + font: italic 85%/1 arial, sans-serif; + padding: 1em 0; + text-align: center; +} +.oc-table td, +.oc-table th { + font-size: 90%; + margin: 0; + overflow: visible; + padding: 8px; +} +.oc-table td:first-child, +.oc-table th:first-child { + border-left-width: 0; +} +.oc-table thead { + color: #000; + text-align: left; + vertical-align: bottom; + white-space: nowrap; +} +.oc-table thead th { + font-weight: bold; + border-bottom: solid 2px #dddddd; +} +.oc-table td { + background-color: transparent; + vertical-align: middle; +} +.oc-table td p { + line-height: 15px; +} +.oc-table td p:last-child { + margin-bottom: 0; +} +.oc-table .oc-table-cell-min { + width: 1%; + padding-right: 0; +} +.oc-table .oc-table-cell-min input[type=checkbox], +.oc-table .oc-table-cell-min input[type=checkbox] { + margin: 0; +} +.oc-table-secondary { + color: #333333; + font-size: 90%; +} +.oc-table-tertiary { + color: #333333; + font-size: 80%; +} +.oc-table-odd td, +.oc-table-striped tr:nth-child(2n-1) td { + background-color: #f9f9f9; +} +.oc-table-backed { + background-color: #f9f9f9; +} +.oc-table-bordered-all { + border: 1px solid #dddddd; +} +.oc-table-bordered-all td { + border-bottom: 1px solid #dddddd; + border-left: 1px solid #dddddd; +} +.oc-table-bordered-all tbody > tr:last-child td { + border-bottom-width: 0; +} +.oc-table-bordered { + border: 1px solid #dddddd; +} +.oc-table-bordered-rows td { + border-bottom: 1px solid #dddddd; +} +.oc-table-bordered-rows tbody > tr:last-child td { + border-bottom-width: 0; +} +.oc-table-horizontal tbody > tr:last-child td { + border-bottom-width: 0; +} +.oc-table-horizontal td, +.oc-table-horizontal th { + border-width: 0 0 1px 0; + border-bottom: 1px solid #dddddd; +} +.oc-table-horizontal tbody > tr:last-child td { + border-bottom-width: 0; +} diff --git a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css index ff79fa996..4cb6da475 100644 --- a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css +++ b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css @@ -61,7 +61,7 @@ #redactor_modal_overlay, #redactor_modal, .redactor_dropdown { - z-index: 1061 !important; + z-index: 1062 !important; } body .redactor_air { position: absolute; @@ -148,7 +148,6 @@ body .redactor_box_fullscreen .redactor_editor { .redactor_editor p, .redactor_editor ul, .redactor_editor ol, -.redactor_editor table, .redactor_editor dl, .redactor_editor blockquote, .redactor_editor pre { @@ -188,19 +187,6 @@ body .redactor_box_fullscreen .redactor_editor { .redactor_editor dd { margin-left: 1em; } -.redactor_editor table { - border-collapse: collapse; - font-size: 1em !important; -} -.redactor_editor table td { - padding: 5px !important; - border: 1px solid #ddd; - vertical-align: top; -} -.redactor_editor table thead td { - border-bottom: 2px solid #000 !important; - font-weight: bold !important; -} .redactor_editor code { background-color: #d8d7d7 !important; } @@ -274,7 +260,7 @@ body .redactor_box_fullscreen .redactor_editor { line-height: 1 !important; border: none; background: #dddddd; - z-index: 1063; + z-index: 1061; } .redactor_toolbar:after { content: ""; @@ -939,7 +925,7 @@ body .redactor_air .redactor_toolbar { .redactor_editor figure[data-type=video] p { margin: 0; } -.redactor_editor figure[data-type=video].wy-figure-full:before { +.redactor_editor figure[data-type=video].oc-figure-full:before { position: relative; padding-bottom: 51%; width: 100%; @@ -947,7 +933,7 @@ body .redactor_air .redactor_toolbar { content: ""; display: block; } -.redactor_editor figure[data-type=video].wy-figure-full iframe { +.redactor_editor figure[data-type=video].oc-figure-full iframe { width: 100%; height: 100%; position: absolute; @@ -958,20 +944,20 @@ body .redactor_air .redactor_toolbar { position: relative; margin-bottom: 20px; } -.redactor_editor figure[data-type=image] .wy-figure-controls { +.redactor_editor figure[data-type=image] .oc-figure-controls { top: 0px; } .redactor_editor figure[data-type=image] img { width: 100%; } -.redactor_editor figure[data-type=image].wy-figure-large { +.redactor_editor figure[data-type=image].oc-figure-large { width: 100%; clear: both; } -.redactor_editor figure[data-type=image].wy-figure-medium { +.redactor_editor figure[data-type=image].oc-figure-medium { width: 50%; } -.redactor_editor figure[data-type=image].wy-figure-small { +.redactor_editor figure[data-type=image].oc-figure-small { width: 33%; } .redactor_editor figure[data-type=quote] { @@ -987,30 +973,30 @@ body .redactor_air .redactor_toolbar { font-weight: bold; text-align: left; } -.redactor_editor figure[data-type=quote] .wy-figure-controls { +.redactor_editor figure[data-type=quote] .oc-figure-controls { margin-left: -5px; } -.redactor_editor figure[data-type=quote].wy-figure-medium, -.redactor_editor figure[data-type=quote].wy-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].wy-figure-large, -.redactor_editor figure[data-type=quote].wy-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].wy-figure-right { +.redactor_editor figure[data-type=quote].oc-figure-right { width: 33%; } -.redactor_editor figure[data-type=quote].wy-figure-left { +.redactor_editor figure[data-type=quote].oc-figure-left { width: 33%; border-left: none; - border-right: solid 5px #333333; + border-right: solid 4px #cccccc; padding-left: 0; padding-right: 20px; margin-left: 0; margin-right: 20px; } -.redactor_editor figure[data-type=quote].wy-figure-left .wy-figure-controls { +.redactor_editor figure[data-type=quote].oc-figure-left .oc-figure-controls { margin-left: 0; margin-right: -5px; } @@ -1026,10 +1012,14 @@ body .redactor_air .redactor_toolbar { opacity: 0.4; content: "\2014 Type to add citation (optional)"; } -.redactor_box figure:hover .wy-figure-controls { +.redactor_box figure:hover .oc-figure-controls { display: block; } -.redactor_box .wy-figure-controls { +.redactor_box figcaption:empty:before { + opacity: .4; + content: "Type to add caption (optional)"; +} +.redactor_box .oc-figure-controls { background: #dddddd !important; padding: 0; position: absolute; @@ -1046,7 +1036,7 @@ body .redactor_air .redactor_toolbar { z-index: 1560; text-align: center; } -.redactor_box .wy-figure-controls span { +.redactor_box .oc-figure-controls span { display: inline-block; border: none; background: none; @@ -1059,35 +1049,35 @@ body .redactor_air .redactor_toolbar { text-align: center; cursor: pointer; } -.redactor_box .wy-figure-controls span:before { +.redactor_box .oc-figure-controls span:before { line-height: 24px; } -.redactor_box .wy-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 .wy-figure-controls span.on { +.redactor_box .oc-figure-controls span.on { background: #fff; color: #555555; background-color: #404040; color: #ffffff; } -.redactor_box .wy-figure-controls span.wy-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 .wy-figure-controls span.wy-figure-controls-small { +.redactor_box .oc-figure-controls span.oc-figure-controls-small { font-size: 7px; } -.redactor_box .wy-figure-controls span.wy-figure-controls-medium { +.redactor_box .oc-figure-controls span.oc-figure-controls-medium { font-size: 10px; } -.redactor_box .wy-figure-controls span.wy-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; @@ -1096,7 +1086,7 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f060"; } -.redactor_box .wy-figure-controls span.wy-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; @@ -1105,7 +1095,7 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f061"; } -.redactor_box .wy-figure-controls span.wy-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; @@ -1114,7 +1104,7 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f062"; } -.redactor_box .wy-figure-controls span.wy-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; @@ -1123,7 +1113,7 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f063"; } -.redactor_box .wy-figure-controls span.wy-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; @@ -1132,7 +1122,7 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f065"; } -.redactor_box .wy-figure-controls span.wy-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; @@ -1141,10 +1131,10 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f066"; } -.redactor_box .wy-figure-controls span.wy-figure-controls-delete { +.redactor_box .oc-figure-controls span.oc-figure-controls-delete { margin-left: 20px; } -.redactor_box .wy-figure-controls span.wy-figure-controls-delete:before { +.redactor_box .oc-figure-controls span.oc-figure-controls-delete:before { font-family: FontAwesome; font-weight: normal; font-style: normal; @@ -1153,15 +1143,16 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f014"; } -.redactor_box .wy-figure-controls span.wy-figure-controls-delete:hover { +.redactor_box .oc-figure-controls span.oc-figure-controls-delete:hover { background: #c63e26; } -.redactor_box .wy-figure-controls span.wy-figure-controls-table { +.redactor_box .oc-figure-controls span.oc-figure-controls-table { width: auto; - padding-left: 5px; + padding-left: 10px; + padding-right: 10px; text-align: left; } -.redactor_box .wy-figure-controls span.wy-figure-controls-table:before { +.redactor_box .oc-figure-controls span.oc-figure-controls-table:before { font-family: FontAwesome; font-weight: normal; font-style: normal; @@ -1170,17 +1161,34 @@ body .redactor_air .redactor_toolbar { *margin-right: .3em; content: "\f0ce"; } -.redactor_box .wy-figure-right { +.redactor_box .oc-figure-right { float: right; margin-left: 20px; } -.redactor_box .wy-figure-right .wy-figure-controls { +.redactor_box .oc-figure-right .oc-figure-controls { right: 0; } -.redactor_box .wy-figure-left { +.redactor_box .oc-figure-left { float: left; margin-right: 20px; } +.redactor_box .oc-dropdown-menu, +.redactor_box .oc-dropdown-menu ul { + padding: 0 !important; +} +.redactor_box .oc-dropdown-menu ul { + background-color: #ffffff !important; +} +.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 { + color: #ffffff !important; +} @media (max-width: 769px) { .redactor_box figure[data-type=image] { width: 100% !important; @@ -1193,6 +1201,102 @@ body .redactor_air .redactor_toolbar { height: auto !important; } } +.oc-table { + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + margin-bottom: 20px; +} +.oc-table caption { + color: #000; + font: italic 85%/1 arial, sans-serif; + padding: 1em 0; + text-align: center; +} +.oc-table td, +.oc-table th { + font-size: 90%; + margin: 0; + overflow: visible; + padding: 8px; +} +.oc-table td:first-child, +.oc-table th:first-child { + border-left-width: 0; +} +.oc-table thead { + color: #000; + text-align: left; + vertical-align: bottom; + white-space: nowrap; +} +.oc-table thead th { + font-weight: bold; + border-bottom: solid 2px #dddddd; +} +.oc-table td { + background-color: transparent; + vertical-align: middle; +} +.oc-table td p { + line-height: 15px; +} +.oc-table td p:last-child { + margin-bottom: 0; +} +.oc-table .oc-table-cell-min { + width: 1%; + padding-right: 0; +} +.oc-table .oc-table-cell-min input[type=checkbox], +.oc-table .oc-table-cell-min input[type=checkbox] { + margin: 0; +} +.oc-table-secondary { + color: #333333; + font-size: 90%; +} +.oc-table-tertiary { + color: #333333; + font-size: 80%; +} +.oc-table-odd td, +.oc-table-striped tr:nth-child(2n-1) td { + background-color: #f9f9f9; +} +.oc-table-backed { + background-color: #f9f9f9; +} +.oc-table-bordered-all { + border: 1px solid #dddddd; +} +.oc-table-bordered-all td { + border-bottom: 1px solid #dddddd; + border-left: 1px solid #dddddd; +} +.oc-table-bordered-all tbody > tr:last-child td { + border-bottom-width: 0; +} +.oc-table-bordered { + border: 1px solid #dddddd; +} +.oc-table-bordered-rows td { + border-bottom: 1px solid #dddddd; +} +.oc-table-bordered-rows tbody > tr:last-child td { + border-bottom-width: 0; +} +.oc-table-horizontal tbody > tr:last-child td { + border-bottom-width: 0; +} +.oc-table-horizontal td, +.oc-table-horizontal th { + border-width: 0 0 1px 0; + border-bottom: 1px solid #dddddd; +} +.oc-table-horizontal tbody > tr:last-child td { + border-bottom-width: 0; +} .field-flush .field-richeditor, .field-flush .field-richeditor.editor-focus { border: none; diff --git a/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js b/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js index 30158e7e0..41fc60864 100644 --- a/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js +++ b/modules/backend/formwidgets/richeditor/assets/js/plugin.figure.js @@ -77,8 +77,8 @@ showToolbar: function (event) { var $figure = $(event.currentTarget), - $toolbar = this.getToolbar(type).data('figure', $figure).prependTo($figure), - type = $figure.data('type') || 'default' + type = $figure.data('type') || 'default', + $toolbar = this.getToolbar(type).data('figure', $figure).prependTo($figure) if (this.redactor[type] && this.redactor[type].onShow) { this.redactor[type].onShow($figure, $toolbar) @@ -86,7 +86,7 @@ }, hideToolbar: function (event) { - $(event.currentTarget).find('.wy-figure-controls').appendTo(this.redactor.$box) + $(event.currentTarget).find('.oc-figure-controls').appendTo(this.redactor.$box) }, observeToolbars: function () { @@ -94,12 +94,12 @@ /* * Before clicking a command, make sure we save the current node within the editor */ - this.redactor.$editor.on('mousedown', '.wy-figure-controls', $.proxy(function () { + this.redactor.$editor.on('mousedown', '.oc-figure-controls', $.proxy(function () { event.preventDefault() this.current = this.redactor.getCurrent() }, this)) - this.redactor.$editor.on('click', '.wy-figure-controls span, .wy-figure-controls a', $.proxy(function (event) { + this.redactor.$editor.on('click', '.oc-figure-controls span, .oc-figure-controls a', $.proxy(function (event) { event.stopPropagation() var $target = $(event.currentTarget), command = $target.data('command'), @@ -122,7 +122,7 @@ * If $editor is focused, click doesn't seem to fire */ this.redactor.$editor.on('touchstart', 'figure', function (event) { - if (event.target.nodeName !== 'FIGCAPTION' && $(event.target).parents('.wy-figure-controls').length) { + if (event.target.nodeName !== 'FIGCAPTION' && $(event.target).parents('.oc-figure-controls').length) { $(this).trigger('click', event) } }) @@ -153,15 +153,13 @@ }, getToolbar: function (type) { - - if (this.toolbar[type]) { + if (this.toolbar[type]) return this.toolbar[type] - } var controlGroup = (this.redactor[type] && this.redactor[type].controlGroup) || this.controlGroup, controls = $.extend({}, this.control, (this.redactor[type] && this.redactor[type].control) || {}), $controls = this.buildControls(controlGroup, controls), - $toolbar = $('
').append($controls) + $toolbar = $('
').append($controls) this.toolbar[type] = $toolbar @@ -183,7 +181,7 @@ control = controls[command] $controls = $controls.add($('', { - 'class': 'wy-figure-controls-' + control.classSuffix, + 'class': 'oc-figure-controls-' + control.classSuffix, 'text': control.text }).data({ command: command, @@ -196,31 +194,38 @@ else if (typeof command === 'object') { $.each(command, $.proxy(function (text, commands) { - var dropdown = $('').text(' ' + text).addClass('wy-figure-controls-table wy-dropdown') + var $button = $('').text(' ' + text).addClass('oc-figure-controls-table dropdown'), + $dropdown = $('