diff --git a/CHANGELOG.md b/CHANGELOG.md index 28204ea51..595ec50b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +* **Build 304** (2015-10-09) + - Added new `where` and `whereComponent` methods for querying CMS template properties. + +* **Build 300** (2015-10-03) + - **Happy 2nd Birthday October!** + - Page settings now support infinite array nesting with October flavored INI syntax via `Ini::parse` and `Ini::render`. + - Added new helper `Twig::parse` for parsing Twig (see Services > Parser docs). + +* **Build 298** (2015-09-24) + - Added the ability to use a wildcard URL parameter in CMS pages (see CMS > Pages docs). + +* **Build 297** (2015-09-19) + - Introduced new `Revisionable` trait for storing model history (see Database > Traits docs). + - Added `timetense` list column type (see Backend > Lists docs), along with `|time_since` and `|time_tense` Twig filters. + - Fixed a bug in deferred binding that allowed repeat bindings and ignored add/delete pairs. + +* **Build 293** (2015-09-07) + - Corrected a flaw in the Behavior/Extension logic that previously made protected methods and properties accessible as if they were public. + * **Build 292** (2015-08-28) - Added a new controller method `fireViewEvent()` for extending views and partials (see Plugins > Events docs). - Fixes a bug where the database falls asleep during an update. diff --git a/README.md b/README.md index dfd714366..621795737 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The best place to learn October is by [reading the documentation](http://october ### Installing October -Instructions on how to install October can be found at the [installation guide](http://octobercms.com/docs/help/install). +Instructions on how to install October can be found at the [installation guide](http://octobercms.com/docs/setup/installation). ### Development Team diff --git a/modules/backend/ServiceProvider.php b/modules/backend/ServiceProvider.php index 3937b82cc..f362936dc 100644 --- a/modules/backend/ServiceProvider.php +++ b/modules/backend/ServiceProvider.php @@ -111,6 +111,14 @@ class ServiceProvider extends ModuleServiceProvider 'label' => 'system::lang.permissions.manage_other_administrators', 'tab' => 'system::lang.permissions.name' ], + 'backend.manage_preferences' => [ + 'label' => 'system::lang.permissions.manage_preferences', + 'tab' => 'system::lang.permissions.name' + ], + 'backend.manage_editor' => [ + 'label' => 'system::lang.permissions.manage_editor', + 'tab' => 'system::lang.permissions.name' + ], 'backend.manage_branding' => [ 'label' => 'system::lang.permissions.manage_branding', 'tab' => 'system::lang.permissions.name' @@ -208,6 +216,7 @@ class ServiceProvider extends ModuleServiceProvider 'category' => SettingsManager::CATEGORY_MYSETTINGS, 'icon' => 'icon-laptop', 'class' => 'Backend\Models\BackendPreferences', + 'permissions' => ['backend.manage_preferences'], 'order' => 510, 'context' => 'mysettings' ], @@ -217,6 +226,7 @@ class ServiceProvider extends ModuleServiceProvider 'category' => SettingsManager::CATEGORY_MYSETTINGS, 'icon' => 'icon-code', 'url' => Backend::URL('backend/editorpreferences'), + 'permissions' => ['backend.manage_editor'], 'order' => 520, 'context' => 'mysettings' ], diff --git a/modules/backend/assets/css/october.css b/modules/backend/assets/css/october.css index 20801cacf..0d94b2f16 100644 --- a/modules/backend/assets/css/october.css +++ b/modules/backend/assets/css/october.css @@ -85,7 +85,6 @@ .pulseWarningIns{-webkit-animation:pulseWarningIns 0.75s infinite alternate;animation:pulseWarningIns 0.75s infinite alternate} .sweet-overlay{background-color:rgba(0,0,0,0.4);position:fixed;left:0;right:0;top:0;bottom:0;display:none;z-index:8050} .sweet-alert{background-color:#f9f9f9;width:478px;padding:17px;border-radius:5px;text-align:center;position:fixed;left:50%;top:50%;margin-left:-256px;margin-top:-200px;overflow:hidden;display:none;z-index:9050} -.sweet-alert h4{margin:30px 0;word-wrap:break-word} @media all and (max-width:767px){.sweet-alert{width:auto;margin-left:0;margin-right:0;left:15px;right:15px} } .sweet-alert .icon{width:80px;height:80px;border:4px solid gray;border-radius:50%;margin:20px auto;position:relative;box-sizing:content-box} @@ -117,7 +116,7 @@ .sweet-alert .btn-warning:focus{border-color:#eea236;outline:0} .sweet-alert button::-moz-focus-inner{border:0} .sweet-alert{text-align:right} -.sweet-alert h4{word-break:word-break;word-wrap:break-word;max-height:350px;overflow-y:auto;margin:10px 0 17px 0;color:#2b3e50;text-align:left;font-size:15px;line-height:23px} +.sweet-alert h2{word-break:word-break;word-wrap:break-word;max-height:350px;overflow-y:auto;margin:10px 0 17px 0;color:#2b3e50;text-align:left;font-size:15px;line-height:23px} .sweet-alert p{margin:0} .sweet-alert p.text-muted{margin-bottom:20px;color:#555555} .control-simplelist{font-size:13px} @@ -395,7 +394,7 @@ .control-treeview ol > li.drop-target.has-subitems > div:before{background-position:0px -102px} } .sidenav-tree{width:280px;background:#34495e} -.sidenav-tree .control-toolbar{height:auto;padding:20px 0 20px 20px} +.sidenav-tree .control-toolbar{padding:20px 0 20px 20px} .sidenav-tree .control-toolbar input.form-control{border:none} .sidenav-tree ul{padding:0;margin:0;list-style:none} .sidenav-tree div.scrollbar-thumb{background:#2b3e50 !important} @@ -629,7 +628,7 @@ body.slim-container .layout.layout-container,body.slim-container .layout .layout .layout.responsive-sidebar > .layout-cell:last-child .layout-absolute{position:static} } body.mainmenu-open{overflow:hidden} -nav#layout-mainmenu.navbar{background-color:#111111;height:auto;padding:0 0 0 20px;line-height:0;white-space:nowrap} +nav#layout-mainmenu.navbar{background-color:#111111;padding:0 0 0 20px;line-height:0;white-space:nowrap} nav#layout-mainmenu.navbar a{text-decoration:none} nav#layout-mainmenu.navbar a:focus{background:transparent} nav#layout-mainmenu.navbar ul{margin:0;padding:0;list-style:none;float:left;font-weight:600;white-space:nowrap;overflow:hidden} @@ -666,6 +665,8 @@ nav#layout-mainmenu.navbar ul li a,nav#layout-mainmenu .menu-toggle,.mainmenu-co nav#layout-mainmenu.navbar ul li a:hover,nav#layout-mainmenu .menu-toggle:hover,.mainmenu-collapsed li a:hover{background-color:transparent !important} nav#layout-mainmenu.navbar ul li a:active,nav#layout-mainmenu .menu-toggle:active,.mainmenu-collapsed li a:active,nav#layout-mainmenu.navbar ul li a:focus,nav#layout-mainmenu .menu-toggle:focus,.mainmenu-collapsed li a:focus{text-decoration:none;color:#555555} nav#layout-mainmenu.navbar ul li a i,nav#layout-mainmenu .menu-toggle i,.mainmenu-collapsed li a i{line-height:1;font-size:35px;vertical-align:middle;margin-right:10px} +nav#layout-mainmenu.navbar ul li a i{font-size:28px} +nav#layout-mainmenu.navbar ul li.active a i{font-size:35px} .mainmenu-collapsed li a i{width:40px;text-align:left;display:inline-block} nav#layout-mainmenu.navbar ul li:hover a:active,.mainmenu-collapsed li:hover a:active,nav#layout-mainmenu.navbar ul li:hover a:focus,.mainmenu-collapsed li:hover a:focus{color:#ffffff !important} .touch .mainmenu-collapsed li a:hover{color:#555555} diff --git a/modules/backend/assets/js/october-min.js b/modules/backend/assets/js/october-min.js index 2217eb381..9d04aa730 100644 --- a/modules/backend/assets/js/october-min.js +++ b/modules/backend/assets/js/october-min.js @@ -415,15 +415,15 @@ ratio=py/ih;if(ratio===0){return 1;}else{return ratio;}};drawImageIOSFix=functio (e.type==="load"?win:doc)[rem](pre+e.type,init,false);if(!done&&(done=true)){return fn.call(win,e.type||e);}};poll=function(){var e;try{root.doScroll("left");}catch(_error){e=_error;setTimeout(poll,50);return;} return init("poll");};if(doc.readyState!=="complete"){if(doc.createEventObject&&root.doScroll){try{top=!win.frameElement;}catch(_error){} if(top){poll();}} -doc[add](pre+"DOMContentLoaded",init,false);doc[add](pre+"readystatechange",init,false);return win[add](pre+"load",init,false);}};Dropzone._autoDiscoverFunction=function(){if(Dropzone.autoDiscover){return Dropzone.discover();}};contentLoaded(window,Dropzone._autoDiscoverFunction);}).call(this);(function(window,document){var modalClass='.sweet-alert',overlayClass='.sweet-overlay',alertTypes=['error','warning','info','success'],defaultParams={title:'',text:'',type:null,allowOutsideClick:false,showCancelButton:false,closeOnConfirm:true,closeOnCancel:true,confirmButtonText:'OK',confirmButtonClass:'btn-primary',cancelButtonText:'Cancel',cancelButtonClass:'btn-default',imageUrl:null,imageSize:null,timer:null};var getModal=function(){return document.querySelector(modalClass);},getOverlay=function(){return document.querySelector(overlayClass);},hasClass=function(elem,className){return new RegExp(' '+className+' ').test(' '+elem.className+' ');},addClass=function(elem,className){if(!hasClass(elem,className)){elem.className+=' '+className;}},removeClass=function(elem,className){var newClass=' '+elem.className.replace(/[\t\r\n]/g,' ')+' ';if(hasClass(elem,className)){while(newClass.indexOf(' '+className+' ')>=0){newClass=newClass.replace(' '+className+' ',' ');} +doc[add](pre+"DOMContentLoaded",init,false);doc[add](pre+"readystatechange",init,false);return win[add](pre+"load",init,false);}};Dropzone._autoDiscoverFunction=function(){if(Dropzone.autoDiscover){return Dropzone.discover();}};contentLoaded(window,Dropzone._autoDiscoverFunction);}).call(this);(function(window,document){var modalClass='.sweet-alert',overlayClass='.sweet-overlay',alertTypes=['error','warning','info','success'],defaultParams={title:'',text:'',type:null,allowOutsideClick:false,showCancelButton:false,showConfirmButton:true,closeOnConfirm:true,closeOnCancel:true,confirmButtonText:'OK',confirmButtonClass:'btn-primary',cancelButtonText:'Cancel',cancelButtonClass:'btn-default',containerClass:'',titleClass:'',textClass:'',imageUrl:null,imageSize:null,timer:null};var getModal=function(){return document.querySelector(modalClass);},getOverlay=function(){return document.querySelector(overlayClass);},hasClass=function(elem,className){return new RegExp(' '+className+' ').test(' '+elem.className+' ');},addClass=function(elem,className){if(className&&!hasClass(elem,className)){elem.className+=' '+className;}},removeClass=function(elem,className){var newClass=' '+elem.className.replace(/[\t\r\n]/g,' ')+' ';if(hasClass(elem,className)){while(newClass.indexOf(' '+className+' ')>=0){newClass=newClass.replace(' '+className+' ',' ');} elem.className=newClass.replace(/^\s+|\s+$/g,'');}},escapeHtml=function(str){var div=document.createElement('div');div.appendChild(document.createTextNode(str));return div.innerHTML;},_show=function(elem){elem.style.opacity='';elem.style.display='block';},show=function(elems){if(elems&&!elems.length){return _show(elems);} for(var i=0;i0){setTimeout(tick,interval);}else{elem.style.display='none';}};tick();},fireClick=function(node){if(MouseEvent){var mevt=new MouseEvent('click',{view:window,bubbles:false,cancelable:true});node.dispatchEvent(mevt);}else if(document.createEvent){var evt=document.createEvent('MouseEvents');evt.initEvent('click',false,false);node.dispatchEvent(evt);}else if(document.createEventObject){node.fireEvent('onclick');}else if(typeof node.onclick==='function'){node.onclick();}},stopEventPropagation=function(e){if(typeof e.stopPropagation==='function'){e.stopPropagation();e.preventDefault();}else if(window.event&&window.event.hasOwnProperty('cancelBubble')){window.event.cancelBubble=true;}};var previousActiveElement,previousDocumentClick,previousWindowKeyDown,lastFocusedButton;window.sweetAlertInitialize=function(){var sweetHTML='

Title

Text

',sweetWrap=document.createElement('div');sweetWrap.innerHTML=sweetHTML;document.body.appendChild(sweetWrap);} +return false;},getTopMargin=function(elem){elem.style.left='-9999px';elem.style.display='block';var height=elem.clientHeight;var padding=parseInt(getComputedStyle(elem).getPropertyValue('padding'),10);elem.style.left='';elem.style.display='none';return('-'+parseInt(height/2+padding)+'px');},fadeIn=function(elem,interval){if(+elem.style.opacity<1){interval=interval||16;elem.style.opacity=0;elem.style.display='block';var last=+new Date();var tick=function(){elem.style.opacity=+elem.style.opacity+(new Date()-last)/100;last=+new Date();if(+elem.style.opacity<1){setTimeout(tick,interval);}};tick();}},fadeOut=function(elem,interval){interval=interval||16;elem.style.opacity=1;var last=+new Date();var tick=function(){elem.style.opacity=+elem.style.opacity-(new Date()-last)/100;last=+new Date();if(+elem.style.opacity>0){setTimeout(tick,interval);}else{elem.style.display='none';}};tick();},fireClick=function(node){if(MouseEvent){var mevt=new MouseEvent('click',{view:window,bubbles:false,cancelable:true});node.dispatchEvent(mevt);}else if(document.createEvent){var evt=document.createEvent('MouseEvents');evt.initEvent('click',false,false);node.dispatchEvent(evt);}else if(document.createEventObject){node.fireEvent('onclick');}else if(typeof node.onclick==='function'){node.onclick();}},stopEventPropagation=function(e){if(typeof e.stopPropagation==='function'){e.stopPropagation();e.preventDefault();}else if(window.event&&window.event.hasOwnProperty('cancelBubble')){window.event.cancelBubble=true;}};var previousActiveElement,previousDocumentClick,previousWindowKeyDown,lastFocusedButton;window.sweetAlertInitialize=function(){var sweetHTML='

Title

Text

',sweetWrap=document.createElement('div');sweetWrap.innerHTML=sweetHTML;document.body.appendChild(sweetWrap);} window.sweetAlert=window.swal=function(){if(arguments[0]===undefined){window.console.error('sweetAlert expects at least 1 attribute!');return false;} var params=extend({},defaultParams);switch(typeof arguments[0]){case'string':params.title=arguments[0];params.text=arguments[1]||'';params.type=arguments[2]||'';break;case'object':if(arguments[0].title===undefined){window.console.error('Missing "title" argument!');return false;} -params.title=arguments[0].title;params.text=arguments[0].text||defaultParams.text;params.type=arguments[0].type||defaultParams.type;params.allowOutsideClick=arguments[0].allowOutsideClick||defaultParams.allowOutsideClick;params.showCancelButton=arguments[0].showCancelButton!==undefined?arguments[0].showCancelButton:defaultParams.showCancelButton;params.closeOnConfirm=arguments[0].closeOnConfirm!==undefined?arguments[0].closeOnConfirm:defaultParams.closeOnConfirm;params.closeOnCancel=arguments[0].closeOnCancel!==undefined?arguments[0].closeOnCancel:defaultParams.closeOnCancel;params.timer=arguments[0].timer||defaultParams.timer;params.confirmButtonText=(defaultParams.showCancelButton)?'Confirm':defaultParams.confirmButtonText;params.confirmButtonText=arguments[0].confirmButtonText||defaultParams.confirmButtonText;params.confirmButtonClass=arguments[0].confirmButtonClass||defaultParams.confirmButtonClass;params.cancelButtonText=arguments[0].cancelButtonText||defaultParams.cancelButtonText;params.cancelButtonClass=arguments[0].cancelButtonClass||defaultParams.cancelButtonClass;params.imageUrl=arguments[0].imageUrl||defaultParams.imageUrl;params.imageSize=arguments[0].imageSize||defaultParams.imageSize;params.doneFunction=arguments[1]||null;break;default:window.console.error('Unexpected type of argument! Expected "string" or "object", got '+typeof arguments[0]);return false;} +params.title=arguments[0].title;params.text=arguments[0].text||defaultParams.text;params.type=arguments[0].type||defaultParams.type;params.allowOutsideClick=arguments[0].allowOutsideClick||defaultParams.allowOutsideClick;params.showCancelButton=arguments[0].showCancelButton!==undefined?arguments[0].showCancelButton:defaultParams.showCancelButton;params.showConfirmButton=arguments[0].showConfirmButton!==undefined?arguments[0].showConfirmButton:defaultParams.showConfirmButton;params.closeOnConfirm=arguments[0].closeOnConfirm!==undefined?arguments[0].closeOnConfirm:defaultParams.closeOnConfirm;params.closeOnCancel=arguments[0].closeOnCancel!==undefined?arguments[0].closeOnCancel:defaultParams.closeOnCancel;params.timer=arguments[0].timer||defaultParams.timer;params.confirmButtonText=(defaultParams.showCancelButton)?'Confirm':defaultParams.confirmButtonText;params.confirmButtonText=arguments[0].confirmButtonText||defaultParams.confirmButtonText;params.confirmButtonClass=arguments[0].confirmButtonClass||(arguments[0].type?'btn-'+arguments[0].type:null)||defaultParams.confirmButtonClass;params.cancelButtonText=arguments[0].cancelButtonText||defaultParams.cancelButtonText;params.cancelButtonClass=arguments[0].cancelButtonClass||defaultParams.cancelButtonClass;params.containerClass=arguments[0].containerClass||defaultParams.containerClass;params.titleClass=arguments[0].titleClass||defaultParams.titleClass;params.textClass=arguments[0].textClass||defaultParams.textClass;params.imageUrl=arguments[0].imageUrl||defaultParams.imageUrl;params.imageSize=arguments[0].imageSize||defaultParams.imageSize;params.doneFunction=arguments[1]||null;break;default:window.console.error('Unexpected type of argument! Expected "string" or "object", got '+typeof arguments[0]);return false;} setParameters(params);fixVerticalPosition();openModal();var modal=getModal();var onButtonEvent=function(e){var target=e.target||e.srcElement,targetedConfirm=(target.className.indexOf('confirm')>-1),modalIsVisible=hasClass(modal,'visible'),doneFunctionExists=(params.doneFunction&&modal.getAttribute('data-has-done-function')==='true');switch(e.type){case("click"):if(targetedConfirm&&doneFunctionExists&&modalIsVisible){params.doneFunction(true);if(params.closeOnConfirm){closeModal();}}else if(doneFunctionExists&&modalIsVisible){var functionAsStr=String(params.doneFunction).replace(/\s/g,'');var functionHandlesCancel=functionAsStr.substring(0,9)==="function("&&functionAsStr.substring(9,10)!==")";if(functionHandlesCancel){params.doneFunction(false);} if(params.closeOnCancel){closeModal();}}else{closeModal();} break;}};var $buttons=modal.querySelectorAll('button');for(var i=0;i<$buttons.length;i++){$buttons[i].onclick=onButtonEvent;} @@ -437,17 +437,19 @@ if(modalIsVisible){var btnIndex=-1;if($focusElement!==null){for(var i=0;i<$modal if(btnIndex===-1){$targetElement.focus();}}else{lastFocusedButton=$targetElement;}}} $okButton.onblur=handleOnBlur;$cancelButton.onblur=handleOnBlur;window.onfocus=function(){window.setTimeout(function(){if(lastFocusedButton!==undefined){lastFocusedButton.focus();lastFocusedButton=undefined;}},0);};};window.swal.setDefaults=function(userParams){if(!userParams){throw new Error('userParams is required');} if(typeof userParams!=='object'){throw new Error('userParams has to be a object');} -extend(defaultParams,userParams);};function setParameters(params){var modal=getModal();var $title=modal.querySelector('h4'),$text=modal.querySelector('p'),$cancelBtn=modal.querySelector('button.cancel'),$confirmBtn=modal.querySelector('button.confirm');$title.innerHTML=escapeHtml(params.title).split("\n").join("
");$text.innerHTML=escapeHtml(params.text||'').split("\n").join("
");if(params.text){show($text);} +extend(defaultParams,userParams);};window.swal.close=function(){closeModal();} +function setParameters(params){var modal=getModal();var $title=modal.querySelector('h2'),$text=modal.querySelector('p'),$cancelBtn=modal.querySelector('button.cancel'),$confirmBtn=modal.querySelector('button.confirm');$title.innerHTML=escapeHtml(params.title).split("\n").join("
");$text.innerHTML=escapeHtml(params.text||'').split("\n").join("
");if(params.text){show($text);} hide(modal.querySelectorAll('.icon'));if(params.type){var validType=false;for(var i=0;igetController(), $calledClass)) { return; } - $callback($widget, $widget->model, $widget->getContext()); + call_user_func_array($callback, [$widget, $widget->model, $widget->getContext()]); }); } diff --git a/modules/backend/behaviors/ImportExportController.php b/modules/backend/behaviors/ImportExportController.php index a78a1707f..1663fadf0 100644 --- a/modules/backend/behaviors/ImportExportController.php +++ b/modules/backend/behaviors/ImportExportController.php @@ -5,6 +5,7 @@ use Lang; use View; use Response; use Backend; +use BackendAuth; use Backend\Classes\ControllerBehavior; use League\Csv\Reader as CsvReader; use League\Csv\Writer as CsvWriter; @@ -620,7 +621,7 @@ class ImportExportController extends ControllerBehavior { if ( ($permissions = $this->getConfig($type.'[permissions]')) && - (!$this->controller->user->hasAnyAccess((array) $permissions)) + (!BackendAuth::getUser()->hasAnyAccess((array) $permissions)) ) { return Response::make(View::make('backend::access_denied'), 403); } diff --git a/modules/backend/behaviors/ListController.php b/modules/backend/behaviors/ListController.php index 34830a1b1..54315e998 100644 --- a/modules/backend/behaviors/ListController.php +++ b/modules/backend/behaviors/ListController.php @@ -411,7 +411,7 @@ class ListController extends ControllerBehavior if (!is_a($widget->getController(), $calledClass)) { return; } - $callback($widget, $widget->model); + call_user_func_array($callback, [$widget, $widget->model]); }); } } diff --git a/modules/backend/behaviors/RelationController.php b/modules/backend/behaviors/RelationController.php index 2ff9331fa..07d4ab4f4 100644 --- a/modules/backend/behaviors/RelationController.php +++ b/modules/backend/behaviors/RelationController.php @@ -3,10 +3,11 @@ use Db; use Lang; use Event; +use Request; use Form as FormHelper; use Backend\Classes\ControllerBehavior; -use ApplicationException; use October\Rain\Database\Model; +use ApplicationException; /** * Relation Controller Behavior @@ -318,6 +319,13 @@ class RelationController extends ControllerBehavior $this->toolbarWidget->bindToController(); } + /* + * Search widget + */ + if ($this->searchWidget = $this->makeSearchWidget()) { + $this->searchWidget->bindToController(); + } + /* * View widget */ @@ -484,17 +492,6 @@ class RelationController extends ControllerBehavior // Widgets // - protected function makeSearchWidget() - { - $config = $this->makeConfig(); - $config->alias = $this->alias . 'ManageSearch'; - $config->growable = false; - $config->prompt = 'backend::lang.list.search_prompt'; - $widget = $this->makeWidget('Backend\Widgets\Search', $config); - $widget->cssClasses[] = 'recordfinder-search'; - return $widget; - } - protected function makeToolbarWidget() { $defaultConfig = []; @@ -539,6 +536,29 @@ class RelationController extends ControllerBehavior return $toolbarWidget; } + protected function makeSearchWidget() + { + if (!$this->getConfig('manage[showSearch]')) { + return null; + } + + $config = $this->makeConfig(); + $config->alias = $this->alias . 'ManageSearch'; + $config->growable = false; + $config->prompt = 'backend::lang.list.search_prompt'; + $widget = $this->makeWidget('Backend\Widgets\Search', $config); + $widget->cssClasses[] = 'recordfinder-search'; + + /* + * Persist the search term across AJAX requests only + */ + if (!Request::ajax()) { + $widget->setActiveTerm(null); + } + + return $widget; + } + protected function makeViewWidget() { /* @@ -555,7 +575,8 @@ class RelationController extends ControllerBehavior $config->recordUrl = $this->getConfig('view[recordUrl]', null); $defaultOnClick = sprintf( - "$.oc.relationBehavior.clickViewListRecord(':id', '%s', '%s')", + "$.oc.relationBehavior.clickViewListRecord(':%s', '%s', '%s')", + $this->relationModel->getKeyName(), $this->field, $this->relationGetSessionKey() ); @@ -613,7 +634,15 @@ class RelationController extends ControllerBehavior return $widget->onRefresh(); }); - $searchWidget->setActiveTerm(null); + /* + * Persist the search term across AJAX requests only + */ + if (Request::ajax()) { + $widget->setSearchTerm($searchWidget->getActiveTerm()); + } + else { + $searchWidget->setActiveTerm(null); + } } } } @@ -680,15 +709,18 @@ class RelationController extends ControllerBehavior /* * Link the Search Widget to the List Widget */ - if ($this->getConfig('manage[showSearch]')) { - $this->searchWidget = $this->makeSearchWidget(); - $this->searchWidget->bindToController(); + if ($this->searchWidget) { $this->searchWidget->bindEvent('search.submit', function () use ($widget) { $widget->setSearchTerm($this->searchWidget->getActiveTerm()); return $widget->onRefresh(); }); - $this->searchWidget->setActiveTerm(null); + /* + * Persist the search term across AJAX requests only + */ + if (Request::ajax()) { + $widget->setSearchTerm($this->searchWidget->getActiveTerm()); + } } } /* @@ -1112,24 +1144,29 @@ class RelationController extends ControllerBehavior $this->beforeAjax(); /* - * Add the checked IDs to the pivot table + * If the pivot model fails for some reason, abort the sync */ - $foreignIds = (array) $this->foreignId; - $this->relationObject->sync($foreignIds, false); + Db::transaction(function () { + /* + * Add the checked IDs to the pivot table + */ + $foreignIds = (array) $this->foreignId; + $this->relationObject->sync($foreignIds, false); - /* - * Save data to models - */ - $foreignKeyName = $this->relationModel->getQualifiedKeyName(); - $hyrdatedModels = $this->relationObject->whereIn($foreignKeyName, $foreignIds)->get(); - $saveData = $this->pivotWidget->getSaveData(); + /* + * Save data to models + */ + $foreignKeyName = $this->relationModel->getQualifiedKeyName(); + $hyrdatedModels = $this->relationObject->whereIn($foreignKeyName, $foreignIds)->get(); + $saveData = $this->pivotWidget->getSaveData(); - foreach ($hyrdatedModels as $hydratedModel) { - $modelsToSave = $this->prepareModelsToSave($hydratedModel, $saveData); - foreach ($modelsToSave as $modelToSave) { - $modelToSave->save(); + foreach ($hyrdatedModels as $hydratedModel) { + $modelsToSave = $this->prepareModelsToSave($hydratedModel, $saveData); + foreach ($modelsToSave as $modelToSave) { + $modelToSave->save(); + } } - } + }); return ['#'.$this->relationGetId('view') => $this->relationRenderView()]; } diff --git a/modules/backend/behaviors/ReorderController.php b/modules/backend/behaviors/ReorderController.php index 6102b5500..7d50e4ce6 100644 --- a/modules/backend/behaviors/ReorderController.php +++ b/modules/backend/behaviors/ReorderController.php @@ -2,6 +2,7 @@ use Lang; use Backend; +use ApplicationException; use Backend\Classes\ControllerBehavior; /** @@ -263,4 +264,4 @@ class ReorderController extends ControllerBehavior return $contents; } -} \ No newline at end of file +} diff --git a/modules/backend/behaviors/UserPreferencesModel.php b/modules/backend/behaviors/UserPreferencesModel.php index e5b73d9db..d65b40623 100644 --- a/modules/backend/behaviors/UserPreferencesModel.php +++ b/modules/backend/behaviors/UserPreferencesModel.php @@ -27,7 +27,7 @@ class UserPreferencesModel extends SettingsModel { parent::__construct($model); - $this->model->table = 'backend_user_preferences'; + $this->model->setTable('backend_user_preferences'); } /** diff --git a/modules/backend/behaviors/relationcontroller/partials/_manage_pivot.htm b/modules/backend/behaviors/relationcontroller/partials/_manage_pivot.htm index 57cc1b53a..bda2792b8 100644 --- a/modules/backend/behaviors/relationcontroller/partials/_manage_pivot.htm +++ b/modules/backend/behaviors/relationcontroller/partials/_manage_pivot.htm @@ -38,3 +38,9 @@ + \ No newline at end of file diff --git a/modules/backend/behaviors/relationcontroller/partials/_pivot_form.htm b/modules/backend/behaviors/relationcontroller/partials/_pivot_form.htm index 1e356ca42..c27b4d6e5 100644 --- a/modules/backend/behaviors/relationcontroller/partials/_pivot_form.htm +++ b/modules/backend/behaviors/relationcontroller/partials/_pivot_form.htm @@ -2,7 +2,7 @@ ['_relation_field' => $relationField, 'manage_id' => $relationManageId], - 'data-stripe-load-indicator' => true + 'data-popup-load-indicator' => true ]) ?>

diff --git a/modules/backend/controllers/users/myaccount.htm b/modules/backend/controllers/users/myaccount.htm index fefdde1a4..54b561d7c 100644 --- a/modules/backend/controllers/users/myaccount.htm +++ b/modules/backend/controllers/users/myaccount.htm @@ -28,15 +28,17 @@ class="btn btn-primary"> - + user->hasAccess('backend.manage_users')): ?> + + diff --git a/modules/backend/formwidgets/codeeditor/assets/js/build-min.js b/modules/backend/formwidgets/codeeditor/assets/js/build-min.js index 7245d135c..3fa617592 100644 --- a/modules/backend/formwidgets/codeeditor/assets/js/build-min.js +++ b/modules/backend/formwidgets/codeeditor/assets/js/build-min.js @@ -566,10 +566,10 @@ function intLength(num){num=num.replace(/^\-/,'');if(~num.indexOf('.')){return n return num.length;} var actions=require('actions');_.each([1,-1,10,-10,0.1,-0.1],function(num){var prefix=num>0?'increment':'decrement';actions.add(prefix+'_number_by_'+String(Math.abs(num)).replace('.','').substring(0,2),function(editor){return incrementNumber(editor,num);},{label:'Numbers/'+prefix.charAt(0).toUpperCase()+prefix.substring(1)+' number by '+Math.abs(num)});});});emmet.exec(function(require,_){var actions=require('actions');var prefs=require('preferences');prefs.define('css.closeBraceIndentation','\n','Indentation before closing brace of CSS rule. Some users prefere ' +'indented closing brace of CSS rule for better readability. ' -+'This preference’s value will be automatically inserted before ' ++'This preference’s value will be automatically inserted before ' +'closing brace when user adds newline in newly created CSS rule ' -+'(e.g. when “Insert formatted linebreak” action will be performed ' -+'in CSS file). If you’re such user, you may want to write put a value ' ++'(e.g. when “Insert formatted linebreak” action will be performed ' ++'in CSS file). If you’re such user, you may want to write put a value ' +'like \\n\\t in this preference.');actions.add('insert_formatted_line_break_only',function(editor){var utils=require('utils');var res=require('resources');var info=require('editorUtils').outputInfo(editor);var caretPos=editor.getCaretPos();var nl=utils.getNewline();if(_.include(['html','xml','xsl'],info.syntax)){var pad=res.getVariable('indentation');var tag=require('htmlMatcher').tag(info.content,caretPos);if(tag&&!tag.innerRange.length()){editor.replaceContent(nl+pad+utils.getCaretPlaceholder()+nl,caretPos);return true;}}else if(info.syntax=='css'){var content=info.content;if(caretPos&&content.charAt(caretPos-1)=='{'){var append=prefs.get('css.closeBraceIndentation');var pad=res.getVariable('indentation');var hasCloseBrace=content.charAt(caretPos)=='}';if(!hasCloseBrace){for(var i=caretPos,il=content.length,ch;i-bxsh). With this option enabled, you don’t ' ++'(e.g. -bxsh). With this option enabled, you don’t ' +'need dashes before abbreviations: Emmet will produce ' +'vendor-prefixed properties for you.');var descTemplate=_.template('A comma-separated list of CSS properties that may have ' +'<%= vendor %> vendor prefix. This list is used to generate ' @@ -624,7 +624,7 @@ return true;});});emmet.define('cssResolver',function(require,_){var module=null +'properties to original set. To add a new property, simply write its name, ' +'to remove it, precede property with hyphen.
' +'For example, to add foo property and remove border-radius one, ' -+'the preference value will look like this: foo, -border-radius.');var props={'webkit':'animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-clip, background-composite, background-origin, background-size, border-fit, border-horizontal-spacing, border-image, border-vertical-spacing, box-align, box-direction, box-flex, box-flex-group, box-lines, box-ordinal-group, box-orient, box-pack, box-reflect, box-shadow, color-correction, column-break-after, column-break-before, column-break-inside, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-span, column-width, dashboard-region, font-smoothing, highlight, hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphens, line-box-contain, line-break, line-clamp, locale, margin-before-collapse, margin-after-collapse, marquee-direction, marquee-increment, marquee-repetition, marquee-style, mask-attachment, mask-box-image, mask-box-image-outset, mask-box-image-repeat, mask-box-image-slice, mask-box-image-source, mask-box-image-width, mask-clip, mask-composite, mask-image, mask-origin, mask-position, mask-repeat, mask-size, nbsp-mode, perspective, perspective-origin, rtl-ordering, text-combine, text-decorations-in-effect, text-emphasis-color, text-emphasis-position, text-emphasis-style, text-fill-color, text-orientation, text-security, text-stroke-color, text-stroke-width, transform, transition, transform-origin, transform-style, transition-delay, transition-duration, transition-property, transition-timing-function, user-drag, user-modify, user-select, writing-mode, svg-shadow, box-sizing, border-radius','moz':'animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-inline-policy, binding, border-bottom-colors, border-image, border-left-colors, border-right-colors, border-top-colors, box-align, box-direction, box-flex, box-ordinal-group, box-orient, box-pack, box-shadow, box-sizing, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-width, float-edge, font-feature-settings, font-language-override, force-broken-image-icon, hyphens, image-region, orient, outline-radius-bottomleft, outline-radius-bottomright, outline-radius-topleft, outline-radius-topright, perspective, perspective-origin, stack-sizing, tab-size, text-blink, text-decoration-color, text-decoration-line, text-decoration-style, text-size-adjust, transform, transform-origin, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-focus, user-input, user-modify, user-select, window-shadow, background-clip, border-radius','ms':'accelerator, backface-visibility, background-position-x, background-position-y, behavior, block-progression, box-align, box-direction, box-flex, box-line-progression, box-lines, box-ordinal-group, box-orient, box-pack, content-zoom-boundary, content-zoom-boundary-max, content-zoom-boundary-min, content-zoom-chaining, content-zoom-snap, content-zoom-snap-points, content-zoom-snap-type, content-zooming, filter, flow-from, flow-into, font-feature-settings, grid-column, grid-column-align, grid-column-span, grid-columns, grid-layer, grid-row, grid-row-align, grid-row-span, grid-rows, high-contrast-adjust, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-zone, hyphens, ime-mode, interpolation-mode, layout-flow, layout-grid, layout-grid-char, layout-grid-line, layout-grid-mode, layout-grid-type, line-break, overflow-style, perspective, perspective-origin, perspective-origin-x, perspective-origin-y, scroll-boundary, scroll-boundary-bottom, scroll-boundary-left, scroll-boundary-right, scroll-boundary-top, scroll-chaining, scroll-rails, scroll-snap-points-x, scroll-snap-points-y, scroll-snap-type, scroll-snap-x, scroll-snap-y, scrollbar-arrow-color, scrollbar-base-color, scrollbar-darkshadow-color, scrollbar-face-color, scrollbar-highlight-color, scrollbar-shadow-color, scrollbar-track-color, text-align-last, text-autospace, text-justify, text-kashida-space, text-overflow, text-size-adjust, text-underline-position, touch-action, transform, transform-origin, transform-origin-x, transform-origin-y, transform-origin-z, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-select, word-break, word-wrap, wrap-flow, wrap-margin, wrap-through, writing-mode','o':'dashboard-region, animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, border-image, link, link-source, object-fit, object-position, tab-size, table-baseline, transform, transform-origin, transition, transition-delay, transition-duration, transition-property, transition-timing-function, accesskey, input-format, input-required, marquee-dir, marquee-loop, marquee-speed, marquee-style'};_.each(props,function(v,k){prefs.define('css.'+k+'Properties',v,descTemplate({vendor:k}));prefs.define('css.'+k+'PropertiesAddon','',descAddonTemplate({vendor:k}));});prefs.define('css.unitlessProperties','z-index, line-height, opacity, font-weight, zoom','The list of properties whose values ​​must not contain units.');prefs.define('css.intUnit','px','Default unit for integer values');prefs.define('css.floatUnit','em','Default unit for float values');prefs.define('css.keywords','auto, inherit','A comma-separated list of valid keywords that can be used in CSS abbreviations.');prefs.define('css.keywordAliases','a:auto, i:inherit, s:solid, da:dashed, do:dotted, t:transparent','A comma-separated list of keyword aliases, used in CSS abbreviation. ' ++'the preference value will look like this: foo, -border-radius.');var props={'webkit':'animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-clip, background-composite, background-origin, background-size, border-fit, border-horizontal-spacing, border-image, border-vertical-spacing, box-align, box-direction, box-flex, box-flex-group, box-lines, box-ordinal-group, box-orient, box-pack, box-reflect, box-shadow, color-correction, column-break-after, column-break-before, column-break-inside, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-span, column-width, dashboard-region, font-smoothing, highlight, hyphenate-character, hyphenate-limit-after, hyphenate-limit-before, hyphens, line-box-contain, line-break, line-clamp, locale, margin-before-collapse, margin-after-collapse, marquee-direction, marquee-increment, marquee-repetition, marquee-style, mask-attachment, mask-box-image, mask-box-image-outset, mask-box-image-repeat, mask-box-image-slice, mask-box-image-source, mask-box-image-width, mask-clip, mask-composite, mask-image, mask-origin, mask-position, mask-repeat, mask-size, nbsp-mode, perspective, perspective-origin, rtl-ordering, text-combine, text-decorations-in-effect, text-emphasis-color, text-emphasis-position, text-emphasis-style, text-fill-color, text-orientation, text-security, text-stroke-color, text-stroke-width, transform, transition, transform-origin, transform-style, transition-delay, transition-duration, transition-property, transition-timing-function, user-drag, user-modify, user-select, writing-mode, svg-shadow, box-sizing, border-radius','moz':'animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, appearance, backface-visibility, background-inline-policy, binding, border-bottom-colors, border-image, border-left-colors, border-right-colors, border-top-colors, box-align, box-direction, box-flex, box-ordinal-group, box-orient, box-pack, box-shadow, box-sizing, column-count, column-gap, column-rule-color, column-rule-style, column-rule-width, column-width, float-edge, font-feature-settings, font-language-override, force-broken-image-icon, hyphens, image-region, orient, outline-radius-bottomleft, outline-radius-bottomright, outline-radius-topleft, outline-radius-topright, perspective, perspective-origin, stack-sizing, tab-size, text-blink, text-decoration-color, text-decoration-line, text-decoration-style, text-size-adjust, transform, transform-origin, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-focus, user-input, user-modify, user-select, window-shadow, background-clip, border-radius','ms':'accelerator, backface-visibility, background-position-x, background-position-y, behavior, block-progression, box-align, box-direction, box-flex, box-line-progression, box-lines, box-ordinal-group, box-orient, box-pack, content-zoom-boundary, content-zoom-boundary-max, content-zoom-boundary-min, content-zoom-chaining, content-zoom-snap, content-zoom-snap-points, content-zoom-snap-type, content-zooming, filter, flow-from, flow-into, font-feature-settings, grid-column, grid-column-align, grid-column-span, grid-columns, grid-layer, grid-row, grid-row-align, grid-row-span, grid-rows, high-contrast-adjust, hyphenate-limit-chars, hyphenate-limit-lines, hyphenate-limit-zone, hyphens, ime-mode, interpolation-mode, layout-flow, layout-grid, layout-grid-char, layout-grid-line, layout-grid-mode, layout-grid-type, line-break, overflow-style, perspective, perspective-origin, perspective-origin-x, perspective-origin-y, scroll-boundary, scroll-boundary-bottom, scroll-boundary-left, scroll-boundary-right, scroll-boundary-top, scroll-chaining, scroll-rails, scroll-snap-points-x, scroll-snap-points-y, scroll-snap-type, scroll-snap-x, scroll-snap-y, scrollbar-arrow-color, scrollbar-base-color, scrollbar-darkshadow-color, scrollbar-face-color, scrollbar-highlight-color, scrollbar-shadow-color, scrollbar-track-color, text-align-last, text-autospace, text-justify, text-kashida-space, text-overflow, text-size-adjust, text-underline-position, touch-action, transform, transform-origin, transform-origin-x, transform-origin-y, transform-origin-z, transform-style, transition, transition-delay, transition-duration, transition-property, transition-timing-function, user-select, word-break, word-wrap, wrap-flow, wrap-margin, wrap-through, writing-mode','o':'dashboard-region, animation, animation-delay, animation-direction, animation-duration, animation-fill-mode, animation-iteration-count, animation-name, animation-play-state, animation-timing-function, border-image, link, link-source, object-fit, object-position, tab-size, table-baseline, transform, transform-origin, transition, transition-delay, transition-duration, transition-property, transition-timing-function, accesskey, input-format, input-required, marquee-dir, marquee-loop, marquee-speed, marquee-style'};_.each(props,function(v,k){prefs.define('css.'+k+'Properties',v,descTemplate({vendor:k}));prefs.define('css.'+k+'PropertiesAddon','',descAddonTemplate({vendor:k}));});prefs.define('css.unitlessProperties','z-index, line-height, opacity, font-weight, zoom','The list of properties whose values ​​must not contain units.');prefs.define('css.intUnit','px','Default unit for integer values');prefs.define('css.floatUnit','em','Default unit for float values');prefs.define('css.keywords','auto, inherit','A comma-separated list of valid keywords that can be used in CSS abbreviations.');prefs.define('css.keywordAliases','a:auto, i:inherit, s:solid, da:dashed, do:dotted, t:transparent','A comma-separated list of keyword aliases, used in CSS abbreviation. ' +'Each alias should be defined as alias:keyword_name.');prefs.define('css.unitAliases','e:em, p:%, x:ex, r:rem','A comma-separated list of unit aliases, used in CSS abbreviation. ' +'Each alias should be defined as alias:unit_value.');prefs.define('css.color.short',true,'Should color values like #ffffff be shortened to ' +'#fff after abbreviation with color was expanded.');prefs.define('css.color.case','keep','Letter case of color values generated by abbreviations with color ' @@ -727,7 +727,7 @@ cs.position=1;if('position'in cs){var start=colorStops[from].position||0;var ste function textualDirection(direction){var angle=parseFloat(direction);if(!_.isNaN(angle)){switch(angle%360){case 0:return'left';case 90:return'bottom';case 180:return'right';case 240:return'top';}} return direction;} function oldWebkitDirection(direction){direction=textualDirection(direction);if(reDeg.test(direction)) -throw"The direction is an angle that can’t be converted.";var v=function(pos){return~direction.indexOf(pos)?'100%':'0';};return v('right')+' '+v('bottom')+', '+v('left')+' '+v('top');} +throw"The direction is an angle that can’t be converted.";var v=function(pos){return~direction.indexOf(pos)?'100%':'0';};return v('right')+' '+v('bottom')+', '+v('left')+' '+v('top');} function getPrefixedNames(name){var prefixes=prefs.getArray('css.gradient.prefixes');var names=prefixes?_.map(prefixes,function(p){return'-'+p+'-'+name;}):[];names.push(name);return names;} function getPropertiesForGradient(gradient,propertyName){var props=[];var css=require('cssResolver');if(prefs.get('css.gradient.fallback')&&~propertyName.toLowerCase().indexOf('background')){props.push({name:'background-color',value:'${1:'+gradient.colorStops[0].color+'}'});} _.each(prefs.getArray('css.gradient.prefixes'),function(prefix){var name=css.prefixed(propertyName,prefix);if(prefix=='webkit'&&prefs.get('css.gradient.oldWebkit')){try{props.push({name:name,value:module.oldWebkitLinearGradient(gradient)});}catch(e){}} @@ -771,8 +771,8 @@ return this.getMapping(name);if(this.isInlineLevel(name)) return'span';return'div';},getMapping:function(name){return elementMap[name.toLowerCase()];},isInlineLevel:function(name){return this.isTypeOf(name,'inlineLevel');},isBlockLevel:function(name){return this.isTypeOf(name,'blockLevel');},isEmptyElement:function(name){return this.isTypeOf(name,'empty');},isTypeOf:function(name,type){return _.include(elementTypes[type],name);},addMapping:function(parent,child){elementMap[parent]=child;},removeMapping:function(parent){if(parent in elementMap) delete elementMap[parent];},addElementToCollection:function(name,collection){if(!elementTypes[collection]) elementTypes[collection]=[];var col=this.getCollection(collection);if(!_.include(col,name)) -col.push(name);},removeElementFromCollection:function(name,collection){if(collection in elementTypes){elementTypes[collection]=_.without(this.getCollection(collection),name);}},getCollection:function(name){return elementTypes[name];}};});emmet.exec(function(require,_){var prefs=require('preferences');prefs.define('bem.elementSeparator','__','Class name’s element separator.');prefs.define('bem.modifierSeparator','_','Class name’s modifier separator.');prefs.define('bem.shortElementPrefix','-','Symbol for describing short “block-element” notation. Class names ' -+'prefixed with this symbol will be treated as element name for parent‘s ' +col.push(name);},removeElementFromCollection:function(name,collection){if(collection in elementTypes){elementTypes[collection]=_.without(this.getCollection(collection),name);}},getCollection:function(name){return elementTypes[name];}};});emmet.exec(function(require,_){var prefs=require('preferences');prefs.define('bem.elementSeparator','__','Class name’s element separator.');prefs.define('bem.modifierSeparator','_','Class name’s modifier separator.');prefs.define('bem.shortElementPrefix','-','Symbol for describing short “block-element” notation. Class names ' ++'prefixed with this symbol will be treated as element name for parent‘s ' +'block name. Each symbol instance traverses one level up in parsed ' +'tree for block name lookup. Empty value will disable short notation.');var shouldRunHtmlFilter=false;function getSeparators(){return{element:prefs.get('bem.elementSeparator'),modifier:prefs.get('bem.modifierSeparator')};} function bemParse(item){if(require('abbreviationUtils').isSnippet(item)) @@ -801,13 +801,13 @@ return tree;});});emmet.exec(function(require,_){var prefs=require('preferences' +'function (see Underscore.js docs for details). In template context, ' +'the following properties and functions are availabe:\n' +'

');prefs.define('filter.commentBefore','','A definition of comment that should be placed before matched ' +'element when comment filter is applied. ' @@ -872,7 +872,7 @@ item.start=item.start.replace(reNl,'');item.end=item.end.replace(reNl,'');item.c item.content=item.content.replace(re,'');process(item,re);});return tree;} require('filters').add('t',function(tree){var re=new RegExp(require('preferences').get('filter.trimRegexp'));return process(tree,re);});});emmet.exec(function(require,_){var tags={'xsl:variable':1,'xsl:with-param':1};function trimAttribute(node){node.start=node.start.replace(/\s+select\s*=\s*(['"]).*?\1/,'');} require('filters').add('xsl',function process(tree){var abbrUtils=require('abbreviationUtils');_.each(tree.children,function(item){if(!abbrUtils.isSnippet(item)&&(item.name()||'').toLowerCase()in tags&&item.children.length) -trimAttribute(item);process(item);});return tree;});});emmet.define('lorem',function(require,_){var langs={en:{common:['lorem','ipsum','dolor','sit','amet','consectetur','adipisicing','elit'],words:['exercitationem','perferendis','perspiciatis','laborum','eveniet','sunt','iure','nam','nobis','eum','cum','officiis','excepturi','odio','consectetur','quasi','aut','quisquam','vel','eligendi','itaque','non','odit','tempore','quaerat','dignissimos','facilis','neque','nihil','expedita','vitae','vero','ipsum','nisi','animi','cumque','pariatur','velit','modi','natus','iusto','eaque','sequi','illo','sed','ex','et','voluptatibus','tempora','veritatis','ratione','assumenda','incidunt','nostrum','placeat','aliquid','fuga','provident','praesentium','rem','necessitatibus','suscipit','adipisci','quidem','possimus','voluptas','debitis','sint','accusantium','unde','sapiente','voluptate','qui','aspernatur','laudantium','soluta','amet','quo','aliquam','saepe','culpa','libero','ipsa','dicta','reiciendis','nesciunt','doloribus','autem','impedit','minima','maiores','repudiandae','ipsam','obcaecati','ullam','enim','totam','delectus','ducimus','quis','voluptates','dolores','molestiae','harum','dolorem','quia','voluptatem','molestias','magni','distinctio','omnis','illum','dolorum','voluptatum','ea','quas','quam','corporis','quae','blanditiis','atque','deserunt','laboriosam','earum','consequuntur','hic','cupiditate','quibusdam','accusamus','ut','rerum','error','minus','eius','ab','ad','nemo','fugit','officia','at','in','id','quos','reprehenderit','numquam','iste','fugiat','sit','inventore','beatae','repellendus','magnam','recusandae','quod','explicabo','doloremque','aperiam','consequatur','asperiores','commodi','optio','dolor','labore','temporibus','repellat','veniam','architecto','est','esse','mollitia','nulla','a','similique','eos','alias','dolore','tenetur','deleniti','porro','facere','maxime','corrupti']},ru:{common:['даНокО-даНокО','Са','словесными','горами','в стране','гласных','и согласных','живут','рыбные','тексты'],words:['вдаНи','от всех','Они','буквенных','домах','на берегу','семантика','большого','языкового','Окоана','маленький','ручеек','даль','журчит','пО всоК','обеспечивает','оо','всоПи','необходимыми','правилами','эта','парадигматическая','страна','которой','жаренные','предложения','залетают','прямо','рот','даМо','всемогущая','пунктуация','но','имеет','власти','над','рыбными','текстами','ведущими','безорфографичный','образ','МиСни','однажды','Одна','маленькая','строчка','рыбного','текста','иПони','lorem','ipsum','решила','выйти','большой','мир','грамматики','воНикиК','ОксПОкс','предупреждал','Đž','злых','запятых','диких','знаках','вопроса','коварных','точках','запятой','нО','текст','даН','сбить','себя','толку','Он','собрал','семь','своих','заглавных','йукв','подпоясал','инициал','Са','пояс','пустился','дорогу','взобравшись','первую','вершину','курсивных','гор','бросил','пОсНодниК','взгляд','наСад','силуэт','свОогО','родного','города','буквоград','СагОНОвОк','деревни','алфавит','пОдСагОНОвОк','свОогО','переулка','грустный','реторический','вопрос','скатился','огО','щеке','продолжил','свОК','путь','дороге','встретил','рукопись','Она','предупредила','ПОоК','всо','переписывается','несколько','раз','единственное','что','меня','осталось','это','приставка','возвращайся','ты','лучше','свою','безопасную','страну','послушавшись','рукописи','наш','продолжил','свОК','путь','вскоре','оПу','повстречался','коварный','составитель','рекламных','текстов','напОившиК','языком','речью','СаПанившиК','свОо','агенство','которое','использовало','снОва','снОва','своих','проектах','осНи','переписали','то','живет','там','Đ´Đž','сих','пор']}};var prefs=require('preferences');prefs.define('lorem.defaultLang','en');require('abbreviationParser').addPreprocessor(function(tree,options){var re=/^(?:lorem|lipsum)([a-z]{2})?(\d*)$/i,match;tree.findAll(function(node){if(node._name&&(match=node._name.match(re))){var wordCound=match[2]||30;var lang=match[1]||prefs.get('lorem.defaultLang')||'en';node._name='';node.data('forceNameResolving',node.isRepeating()||node.attributeList().length);node.data('pasteOverwrites',true);node.data('paste',function(i,content){return paragraph(lang,wordCound,!i);});}});});function randint(from,to){return Math.round(Math.random()*(to-from)+from);} +trimAttribute(item);process(item);});return tree;});});emmet.define('lorem',function(require,_){var langs={en:{common:['lorem','ipsum','dolor','sit','amet','consectetur','adipisicing','elit'],words:['exercitationem','perferendis','perspiciatis','laborum','eveniet','sunt','iure','nam','nobis','eum','cum','officiis','excepturi','odio','consectetur','quasi','aut','quisquam','vel','eligendi','itaque','non','odit','tempore','quaerat','dignissimos','facilis','neque','nihil','expedita','vitae','vero','ipsum','nisi','animi','cumque','pariatur','velit','modi','natus','iusto','eaque','sequi','illo','sed','ex','et','voluptatibus','tempora','veritatis','ratione','assumenda','incidunt','nostrum','placeat','aliquid','fuga','provident','praesentium','rem','necessitatibus','suscipit','adipisci','quidem','possimus','voluptas','debitis','sint','accusantium','unde','sapiente','voluptate','qui','aspernatur','laudantium','soluta','amet','quo','aliquam','saepe','culpa','libero','ipsa','dicta','reiciendis','nesciunt','doloribus','autem','impedit','minima','maiores','repudiandae','ipsam','obcaecati','ullam','enim','totam','delectus','ducimus','quis','voluptates','dolores','molestiae','harum','dolorem','quia','voluptatem','molestias','magni','distinctio','omnis','illum','dolorum','voluptatum','ea','quas','quam','corporis','quae','blanditiis','atque','deserunt','laboriosam','earum','consequuntur','hic','cupiditate','quibusdam','accusamus','ut','rerum','error','minus','eius','ab','ad','nemo','fugit','officia','at','in','id','quos','reprehenderit','numquam','iste','fugiat','sit','inventore','beatae','repellendus','magnam','recusandae','quod','explicabo','doloremque','aperiam','consequatur','asperiores','commodi','optio','dolor','labore','temporibus','repellat','veniam','architecto','est','esse','mollitia','nulla','a','similique','eos','alias','dolore','tenetur','deleniti','porro','facere','maxime','corrupti']},ru:{common:['далеко-далеко','за','словесными','горами','в стране','гласных','и согласных','живут','рыбные','тексты'],words:['вдали','от всех','они','буквенных','домах','на берегу','семантика','большого','языкового','океана','маленький','ручеек','даль','журчит','по всей','обеспечивает','ее','всеми','необходимыми','правилами','эта','парадигматическая','страна','которой','жаренные','предложения','залетают','прямо','рот','даже','всемогущая','пунктуация','не','имеет','власти','над','рыбными','текстами','ведущими','безорфографичный','образ','жизни','однажды','одна','маленькая','строчка','рыбного','текста','имени','lorem','ipsum','решила','выйти','большой','мир','грамматики','великий','оксмокс','предупреждал','о','злых','запятых','диких','знаках','вопроса','коварных','точках','запятой','но','текст','дал','сбить','себя','толку','он','собрал','семь','своих','заглавных','букв','подпоясал','инициал','за','пояс','пустился','дорогу','взобравшись','первую','вершину','курсивных','гор','бросил','последний','взгляд','назад','силуэт','своего','родного','города','буквоград','заголовок','деревни','алфавит','подзаголовок','своего','переулка','грустный','реторический','вопрос','скатился','его','щеке','продолжил','свой','путь','дороге','встретил','рукопись','она','предупредила','моей','все','переписывается','несколько','раз','единственное','что','меня','осталось','это','приставка','возвращайся','ты','лучше','свою','безопасную','страну','послушавшись','рукописи','наш','продолжил','свой','путь','вскоре','ему','повстречался','коварный','составитель','рекламных','текстов','напоивший','языком','речью','заманивший','свое','агенство','которое','использовало','снова','снова','своих','проектах','если','переписали','то','живет','там','до','сих','пор']}};var prefs=require('preferences');prefs.define('lorem.defaultLang','en');require('abbreviationParser').addPreprocessor(function(tree,options){var re=/^(?:lorem|lipsum)([a-z]{2})?(\d*)$/i,match;tree.findAll(function(node){if(node._name&&(match=node._name.match(re))){var wordCound=match[2]||30;var lang=match[1]||prefs.get('lorem.defaultLang')||'en';node._name='';node.data('forceNameResolving',node.isRepeating()||node.attributeList().length);node.data('pasteOverwrites',true);node.data('paste',function(i,content){return paragraph(lang,wordCound,!i);});}});});function randint(from,to){return Math.round(Math.random()*(to-from)+from);} function sample(arr,count){var len=arr.length;var iterations=Math.min(len,count);var result=[];while(result.length 2) { if (this.tabstops.length) arg.push(arg.splice(2, 1)[0]); @@ -860,7 +860,7 @@ changeTracker.setPosition = function(row, column) { }; changeTracker.update = function(pos, delta, $insertRight) { this.$insertRight = $insertRight; - this.pos = pos; + this.pos = pos; this.onChange(delta); }; @@ -961,15 +961,15 @@ AceEmmetEditor.prototype = { if (end == null) end = start == null ? this.getContent().length : start; if (start == null) - start = 0; - + start = 0; + var editor = this.ace; var doc = editor.session.doc; var range = Range.fromPoints(doc.indexToPosition(start), doc.indexToPosition(end)); editor.session.remove(range); - + range.end = range.start; - + value = this.$updateTabstops(value); snippetManager.insertSnippet(editor, value); }, @@ -1061,7 +1061,7 @@ AceEmmetEditor.prototype = { } else if (lastZero) { value = emmet.require('utils').replaceSubstring(value, '${0}', lastZero); } - + return value; } }; @@ -1101,23 +1101,23 @@ exports.runEmmetCommand = function(editor) { if (editorProxy.getSyntax() == "php") return false; var actions = emmet.require("actions"); - + if (this.action == "expand_abbreviation_with_tab") { if (!editor.selection.isEmpty()) return false; } - + if (this.action == "wrap_with_abbreviation") { return setTimeout(function() { actions.run("wrap_with_abbreviation", editorProxy); }, 0); } - + var pos = editor.selection.lead; var token = editor.session.getTokenAt(pos.row, pos.column); if (token && /\btag\b/.test(token.type)) return false; - + var result = actions.run(this.action, editorProxy); } catch(e) { editor._signal("changeStatus", typeof e == "string" ? e : e.message); @@ -1187,4 +1187,3 @@ exports.setCore = function(e) { (function() { ace.require(["ace/ext/emmet"], function() {}); })(); - \ No newline at end of file diff --git a/modules/backend/formwidgets/codeeditor/assets/vendor/emmet/emmet.js b/modules/backend/formwidgets/codeeditor/assets/vendor/emmet/emmet.js index e67ec59d7..89260e50c 100644 --- a/modules/backend/formwidgets/codeeditor/assets/vendor/emmet/emmet.js +++ b/modules/backend/formwidgets/codeeditor/assets/vendor/emmet/emmet.js @@ -614,11 +614,11 @@ var _ = (function() { // Retrieve the names of an object's properties. // Delegates to **ECMAScript 5**'s native `Object.keys` _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; + return keys; + }; // Retrieve the values of an object's properties. _.values = function(obj) { @@ -788,8 +788,8 @@ var _ = (function() { // Is a given value an array? // Delegates to ECMA5's native Array.isArray _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; + return toString.call(obj) == '[object Array]'; + }; // Is a given variable an object? _.isObject = function(obj) { @@ -975,8 +975,8 @@ var _ = (function() { if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; source = "var __p='';" + - "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" + - source + "return __p;\n"; + "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" + + source + "return __p;\n"; var render = new Function(settings.variable || 'obj', '_', source); if (data) return render(data, _); @@ -987,7 +987,7 @@ var _ = (function() { // Provide the compiled function source as a convenience for build time // precompilation. template.source = 'function(' + (settings.variable || 'obj') + '){\n' + - source + '}'; + source + '}'; return template; }; @@ -1144,7 +1144,7 @@ var emmet = (function(global) { var moduleLoader = null; /** - * Generic Emmet module loader (actually, it doesn’t load anything, just + * Generic Emmet module loader (actually, it doesn’t load anything, just * returns module reference). Not using `require` name to avoid conflicts * with Node.js and RequireJS */ @@ -1395,7 +1395,7 @@ emmet.define('abbreviationParser', function(require, _) { }, /** - * Removes current node from parent‘s child list + * Removes current node from parent‘s child list * @returns {AbbreviationNode} Current node itself */ remove: function() { @@ -1407,7 +1407,7 @@ emmet.define('abbreviationParser', function(require, _) { }, /** - * Replaces current node in parent‘s children list with passed nodes + * Replaces current node in parent‘s children list with passed nodes * @param {AbbreviationNode} node Replacement node or array of nodes */ replace: function() { @@ -1572,7 +1572,7 @@ emmet.define('abbreviationParser', function(require, _) { }, /** - * Returns index of current node in parent‘s children list + * Returns index of current node in parent‘s children list * @returns {Number} */ index: function() { @@ -1739,7 +1739,7 @@ emmet.define('abbreviationParser', function(require, _) { /** * Returns stripped string: a string without first and last character. - * Used for “unquoting” strings + * Used for “unquoting” strings * @param {String} str * @returns {String} */ @@ -2027,7 +2027,7 @@ emmet.define('abbreviationParser', function(require, _) { } /** - * “Un-rolls“ contents of current node: recursively replaces all repeating + * “Un-rolls“ contents of current node: recursively replaces all repeating * children with their repeated clones * @param {AbbreviationNode} node * @returns {AbbreviationNode} @@ -2110,7 +2110,7 @@ emmet.define('abbreviationParser', function(require, _) { var tree = parseAbbreviation(abbr); if (options.contextNode) { - // add info about context node – + // add info about context node – // a parent XHTML node in editor inside which abbreviation is // expanded tree._name = options.contextNode.name; @@ -2244,7 +2244,7 @@ emmet.exec(function(require, _) { if (_.isString(r)) { child.data('resource', elements.create('snippet', r)); } else if (elements.is(r, 'reference')) { - // it’s a reference to another abbreviation: + // it’s a reference to another abbreviation: // parse it and insert instead of current child /** @type AbbreviationNode */ var subtree = parser.parse(r.data, { @@ -2264,7 +2264,7 @@ emmet.exec(function(require, _) { }); } - // move child‘s children into the deepest child of new subtree + // move child‘s children into the deepest child of new subtree var deepestChild = subtree.deepestChild(); if (deepestChild) { _.each(child.children, function(c) { @@ -2301,7 +2301,7 @@ emmet.exec(function(require, _) { });/** * Pasted content abbreviation processor. A pasted content is a content that * should be inserted into implicitly repeated abbreviation nodes. - * This processor powers “Wrap With Abbreviation” action + * This processor powers “Wrap With Abbreviation” action * @param {Function} require * @param {Underscore} _ */ @@ -2357,7 +2357,7 @@ emmet.exec(function(require, _) { } /** - * Check if parsed node contains output placeholder – a target where + * Check if parsed node contains output placeholder – a target where * pasted content should be inserted * @param {AbbreviationNode} node * @returns {Boolean} @@ -4226,7 +4226,7 @@ emmet.define('handlerList', function(require, _) { * Adds function handler * @param {Function} fn Handler * @param {Object} options Handler options. Possible values are:

- * order : (Number) – order in handler list. Handlers + * order : (Number) – order in handler list. Handlers * with higher order value will be executed earlier. */ add: function(fn, options) { @@ -4527,8 +4527,8 @@ emmet.define('stringStream', function(require, _) { }, /** - * Act like a multi-character eat—if consume is true or - * not given—or a look-ahead that doesn't update the stream position—if + * Act like a multi-character eat—if consume is true or + * not given—or a look-ahead that doesn't update the stream position—if * it is false. pattern can be either a string or a * regular expression starting with ^. When it is a string, * caseInsensitive can be set to true to make the match @@ -4883,7 +4883,6 @@ emmet.define('resources', function(require, _) { sectionKey = section['extends']; } while (sectionKey && !_.include(memo, sectionKey)); - cache[cacheKey] = _.extend.apply(_, stack.reverse()); } @@ -4900,15 +4899,15 @@ emmet.define('actions', function(require, _, zc) { var actions = {}; /** - * “Humanizes” action name, makes it more readable for people + * “Humanizes” action name, makes it more readable for people * @param {String} name Action name (like 'expand_abbreviation') * @return Humanized name (like 'Expand Abbreviation') */ function humanizeActionName(name) { return require('utils').trim(name.charAt(0).toUpperCase() - + name.substring(1).replace(/_[a-z]/g, function(str) { - return ' ' + str.charAt(1).toUpperCase(); - })); + + name.substring(1).replace(/_[a-z]/g, function(str) { + return ' ' + str.charAt(1).toUpperCase(); + })); } return { @@ -4917,9 +4916,9 @@ emmet.define('actions', function(require, _, zc) { * @param {String} name Action name * @param {Function} fn Action function * @param {Object} options Custom action options:
- * label : (String) – Human-readable action name. + * label : (String) – Human-readable action name. * May contain '/' symbols as submenu separators
- * hidden : (Boolean) – Indicates whether action + * hidden : (Boolean) – Indicates whether action * should be displayed in menu (getMenu() method) * * @memberOf actions @@ -5575,7 +5574,7 @@ emmet.define('actionUtils', function(require, _) { }, /** - * Common syntax detection method for editors that doesn’t provide any + * Common syntax detection method for editors that doesn’t provide any * info about current syntax scope. * @param {IEmmetEditor} editor Current editor * @param {String} hint Any syntax hint that editor can provide @@ -5882,7 +5881,7 @@ emmet.define('base64', function(require, _) { });/** * HTML matcher: takes string and searches for HTML tag pairs for given position * - * Unlike “classic” matchers, it parses content from the specified + * Unlike “classic” matchers, it parses content from the specified * position, not from the start, so it may work even outside HTML documents * (for example, inside strings of programming languages like JavaScript, Python * etc.) @@ -6234,23 +6233,23 @@ emmet.define('tabStops', function(require, _) { * @param {String} text Text to process * @param {Object} options List of processor options:
* - * replaceCarets : Boolean — replace all default + * replaceCarets : Boolean — replace all default * caret placeholders (like {%::emmet-caret::%}) with ${0:caret}
* - * escape : Function — function that handle escaped + * escape : Function — function that handle escaped * characters (mostly '$'). By default, it returns the character itself * to be displayed as is in output, but sometimes you will use * extract method as intermediate solution for further * processing and want to keep character escaped. Thus, you should override * escape method to return escaped symbol (e.g. '\\$')
* - * tabstop : Function – a tabstop handler. Receives - * a single argument – an object describing token: its position, number + * tabstop : Function – a tabstop handler. Receives + * a single argument – an object describing token: its position, number * group, placeholder and token itself. Should return a replacement * string that will appear in final output * - * variable : Function – variable handler. Receives - * a single argument – an object describing token: its position, name + * variable : Function – variable handler. Receives + * a single argument – an object describing token: its position, name * and original token itself. Should return a replacement * string that will appear in final output * @@ -6439,7 +6438,7 @@ emmet.define('tabStops', function(require, _) { var placeholderMemo = {}; var res = require('resources'); return function(str, varName) { - // do not mark `child` variable as placeholder – it‘s a reserved + // do not mark `child` variable as placeholder – it‘s a reserved // variable name if (varName == 'child') return str; @@ -6938,13 +6937,13 @@ emmet.define('elements', function(require, _) { return result; });/** * Abstract implementation of edit tree interface. - * Edit tree is a named container of editable “name-value” child elements, + * Edit tree is a named container of editable “name-value” child elements, * parsed from source. This container provides convenient methods * for editing/adding/removing child elements. All these update actions are * instantly reflected in the source code with respect of formatting. *

* For example, developer can create an edit tree from CSS rule and add or - * remove properties from it–all changes will be immediately reflected in the + * remove properties from it–all changes will be immediately reflected in the * original source. *

* All classes defined in this module should be extended the same way as in @@ -7114,7 +7113,7 @@ emmet.define('editTree', function(require, _, core) { return element.value(value); if (!_.isUndefined(value)) { - // no such element — create it + // no such element — create it return this.add(name, value, pos); } }, @@ -7479,7 +7478,7 @@ emmet.define('cssEditTree', function(require, _) { if (token.type == '}' || token.type == ';') { // found value end trimWhitespaceTokens(tokens, WHITESPACE_REMOVE_FROM_START - | (token.type == '}' ? WHITESPACE_REMOVE_FROM_END : 0)); + | (token.type == '}' ? WHITESPACE_REMOVE_FROM_END : 0)); if (tokens.length) { start = tokens[0].start; @@ -7634,7 +7633,7 @@ emmet.define('cssEditTree', function(require, _) { // characters between rules may lead to undesired behavior, // especially when current rule is duplicated or used as a donor // to create new rule. - // To solve this issue, we‘ll take only last newline indentation + // To solve this issue, we‘ll take only last newline indentation var lines = utils.splitByLines(p.styleBefore); if (lines.length > 1) { p.styleBefore = '\n' + _.last(lines); @@ -7982,7 +7981,7 @@ emmet.define('xmlEditTree', function(require, _) { var attribute = new XMLEditElement(this, editTree.createToken(start + styles.styleBefore.length, name), editTree.createToken(start + styles.styleBefore.length + name.length - + styles.styleSeparator.length, value) + + styles.styleSeparator.length, value) ); _.extend(attribute, styles); @@ -8350,7 +8349,7 @@ emmet.define('wrapWithAbbreviation', function(require, _) { });/** * Toggles HTML and CSS comments depending on current caret context. Unlike * the same action in most editors, this action toggles comment on currently - * matched item—HTML tag or CSS selector—when nothing is selected. + * matched item—HTML tag or CSS selector—when nothing is selected. * * @param {Function} require * @param {Underscore} _ @@ -8424,7 +8423,7 @@ emmet.exec(function(require, _) { return _.find(rule.list(), function(item) { if (item.range().end === relPos) { // at the end of property, but outside of it - // if there’s a space character at current position, + // if there’s a space character at current position, // use current property return reSafeChar.test(rule.source.charAt(relPos)); } @@ -8514,9 +8513,9 @@ emmet.exec(function(require, _) { // should add comment // make sure that there's no comment inside selection newContent = commentStart + ' ' + - range.substring(content) - .replace(new RegExp(utils.escapeForRegexp(commentStart) + '\\s*|\\s*' + utils.escapeForRegexp(commentEnd), 'g'), '') + - ' ' + commentEnd; + range.substring(content) + .replace(new RegExp(utils.escapeForRegexp(commentStart) + '\\s*|\\s*' + utils.escapeForRegexp(commentEnd), 'g'), '') + + ' ' + commentEnd; // adjust caret position caretPos += commentStart.length + 1; @@ -8569,7 +8568,7 @@ emmet.exec(function(require, _) { /** * Search for new caret insertion point * @param {IEmmetEditor} editor Editor instance - * @param {Number} inc Search increment: -1 — search left, 1 — search right + * @param {Number} inc Search increment: -1 — search left, 1 — search right * @param {Number} offset Initial offset relative to current caret position * @return {Number} Returns -1 if insertion point wasn't found */ @@ -8949,9 +8948,9 @@ emmet.exec(function(require, _) { // locate parts of complex values. // some examples: - // – 1px solid red: 3 parts - // – arial, sans-serif: enumeration, 2 parts - // – url(image.png): function value part + // – 1px solid red: 3 parts + // – arial, sans-serif: enumeration, 2 parts + // – url(image.png): function value part var value = property.value(); _.each(property.valueParts(), function(r) { // add absolute range @@ -9277,8 +9276,8 @@ emmet.exec(function(require, _) { }); /** * Splits or joins tag, e.g. transforms it into a short notation and vice versa:
- * <div></div> → <div /> : join
- * <div /> → <div></div> : split + * <div></div> → <div /> : join
+ * <div /> → <div></div> : split * @param {Function} require * @param {Underscore} _ * @memberOf __splitJoinTagAction @@ -9435,7 +9434,7 @@ emmet.define('reflectCSSValue', function(require, _) { * Returns value that should be reflected for refName CSS property * from curName property. This function is used for special cases, * when the same result must be achieved with different properties for different - * browsers. For example: opаcity:0.5; → filter:alpha(opacity=50);

+ * browsers. For example: opаcity:0.5; → filter:alpha(opacity=50);

* * This function does value conversion between different CSS properties * @@ -9629,10 +9628,10 @@ emmet.exec(function(require, _) { prefs.define('css.closeBraceIndentation', '\n', 'Indentation before closing brace of CSS rule. Some users prefere ' + 'indented closing brace of CSS rule for better readability. ' - + 'This preference’s value will be automatically inserted before ' + + 'This preference’s value will be automatically inserted before ' + 'closing brace when user adds newline in newly created CSS rule ' - + '(e.g. when “Insert formatted linebreak” action will be performed ' - + 'in CSS file). If you’re such user, you may want to write put a value ' + + '(e.g. when “Insert formatted linebreak” action will be performed ' + + 'in CSS file). If you’re such user, you may want to write put a value ' + 'like \\n\\t in this preference.'); /** @@ -9872,7 +9871,7 @@ emmet.exec(function(require, _) { } b64 = 'data:' + (actionUtils.mimeTypes[String(file.getExt(realImgPath))] || defaultMimeType) + - ';base64,' + b64; + ';base64,' + b64; editor.replaceContent('$0' + b64, pos, pos + imgPath.length); }); @@ -10002,7 +10001,7 @@ emmet.exec(function(require, _) { } require('actions').add('update_image_size', function(editor) { - // this action will definitely won’t work in SASS dialect, + // this action will definitely won’t work in SASS dialect, // but may work in SCSS or LESS if (_.include(['css', 'less', 'scss'], String(editor.getSyntax()))) { updateImageSizeCSS(editor); @@ -10134,23 +10133,23 @@ emmet.define('cssResolver', function(require, _) { 'Automatically generate vendor-prefixed copies of expanded CSS ' + 'property. By default, Emmet will generate vendor-prefixed ' + 'properties only when you put dash before abbreviation ' - + '(e.g. -bxsh). With this option enabled, you don’t ' + + '(e.g. -bxsh). With this option enabled, you don’t ' + 'need dashes before abbreviations: Emmet will produce ' + 'vendor-prefixed properties for you.'); var descTemplate = _.template('A comma-separated list of CSS properties that may have ' - + '<%= vendor %> vendor prefix. This list is used to generate ' - + 'a list of prefixed properties when expanding -property ' - + 'abbreviations. Empty list means that all possible CSS values may ' - + 'have <%= vendor %> prefix.'); + + '<%= vendor %> vendor prefix. This list is used to generate ' + + 'a list of prefixed properties when expanding -property ' + + 'abbreviations. Empty list means that all possible CSS values may ' + + 'have <%= vendor %> prefix.'); var descAddonTemplate = _.template('A comma-separated list of additional CSS properties ' - + 'for css.<%= vendor %>Preperties preference. ' - + 'You should use this list if you want to add or remove a few CSS ' - + 'properties to original set. To add a new property, simply write its name, ' - + 'to remove it, precede property with hyphen.
' - + 'For example, to add foo property and remove border-radius one, ' - + 'the preference value will look like this: foo, -border-radius.'); + + 'for css.<%= vendor %>Preperties preference. ' + + 'You should use this list if you want to add or remove a few CSS ' + + 'properties to original set. To add a new property, simply write its name, ' + + 'to remove it, precede property with hyphen.
' + + 'For example, to add foo property and remove border-radius one, ' + + 'the preference value will look like this: foo, -border-radius.'); // properties list is created from cssFeatures.html file var props = { @@ -10166,7 +10165,7 @@ emmet.define('cssResolver', function(require, _) { }); prefs.define('css.unitlessProperties', 'z-index, line-height, opacity, font-weight, zoom', - 'The list of properties whose values ​​must not contain units.'); + 'The list of properties whose values ​​must not contain units.'); prefs.define('css.intUnit', 'px', 'Default unit for integer values'); prefs.define('css.floatUnit', 'em', 'Default unit for float values'); @@ -10391,8 +10390,8 @@ emmet.define('cssResolver', function(require, _) { function formatProperty(property, syntax) { var ix = property.indexOf(':'); property = property.substring(0, ix).replace(/\s+$/, '') - + getSyntaxPreference('valueSeparator', syntax) - + require('utils').trim(property.substring(ix + 1)); + + getSyntaxPreference('valueSeparator', syntax) + + require('utils').trim(property.substring(ix + 1)); return property.replace(/\s*;\s*$/, getSyntaxPreference('propertyEnd', syntax)); } @@ -10776,7 +10775,7 @@ emmet.define('cssResolver', function(require, _) { } if (!snippet && prefs.get('css.fuzzySearch')) { - // let’s try fuzzy search + // let’s try fuzzy search snippet = resources.fuzzyFindSnippet(syntax, abbrData.property, parseFloat(prefs.get('css.fuzzySearchMinScore'))); } @@ -10794,8 +10793,8 @@ emmet.define('cssResolver', function(require, _) { var result = []; if (!value && abbrData.values) { value = _.map(abbrData.values, function(val) { - return this.normalizeValue(val, snippetObj.name); - }, this).join(' ') + ';'; + return this.normalizeValue(val, snippetObj.name); + }, this).join(' ') + ';'; } snippetObj.value = value || snippetObj.value; @@ -11085,7 +11084,7 @@ emmet.define('cssGradient', function(require, _) { direction = textualDirection(direction); if(reDeg.test(direction)) - throw "The direction is an angle that can’t be converted."; + throw "The direction is an angle that can’t be converted."; var v = function(pos) { return ~direction.indexOf(pos) ? '100%' : '0'; @@ -11330,7 +11329,7 @@ emmet.define('cssGradient', function(require, _) { cssProp = cssRule.itemFromPosition(pos, true); if (!cssProp) { // in case user just started writing CSS property - // and didn't include semicolon–try another approach + // and didn't include semicolon–try another approach cssProp = _.find(cssRule.list(), function(elem) { return elem.range(true).end == pos; }); @@ -11672,7 +11671,7 @@ emmet.define('tagName', function(require, _) { }, /** - * Adds new parent–child mapping + * Adds new parent–child mapping * @param {String} parent * @param {String} child */ @@ -11735,11 +11734,11 @@ emmet.define('tagName', function(require, _) { */ emmet.exec(function(require, _) { var prefs = require('preferences'); - prefs.define('bem.elementSeparator', '__', 'Class name’s element separator.'); - prefs.define('bem.modifierSeparator', '_', 'Class name’s modifier separator.'); + prefs.define('bem.elementSeparator', '__', 'Class name’s element separator.'); + prefs.define('bem.modifierSeparator', '_', 'Class name’s modifier separator.'); prefs.define('bem.shortElementPrefix', '-', - 'Symbol for describing short “block-element” notation. Class names ' - + 'prefixed with this symbol will be treated as element name for parent‘s ' + 'Symbol for describing short “block-element” notation. Class names ' + + 'prefixed with this symbol will be treated as element name for parent‘s ' + 'block name. Each symbol instance traverses one level up in parsed ' + 'tree for block name lookup. Empty value will disable short notation.'); @@ -11778,8 +11777,8 @@ emmet.exec(function(require, _) { if (!item.__bem.block) { reBlockName = /^[a-z]/i; item.__bem.block = _.find(classNames, function(name) { - return reBlockName.test(name); - }) || ''; + return reBlockName.test(name); + }) || ''; } classNames = _.chain(classNames) @@ -11937,16 +11936,16 @@ emmet.exec(function(require, _) { * It does several things:
*
    *
  • Expands complex class name (according to BEM symbol semantics): - * .block__elem_modifier → .block.block__elem.block__elem_modifier + * .block__elem_modifier → .block.block__elem.block__elem_modifier *
  • *
  • Inherits block name on child elements: - * .b-block > .__el > .__el → .b-block > .b-block__el > .b-block__el__el + * .b-block > .__el > .__el → .b-block > .b-block__el > .b-block__el__el *
  • *
  • Treats first dash symbol as '__'
  • - *
  • Double underscore (or typographic '–') is also treated as an element - * level lookup, e.g. ____el will search for element definition in parent’s + *
  • Double underscore (or typographic '–') is also treated as an element + * level lookup, e.g. ____el will search for element definition in parent’s * parent element: - * .b-block > .__el1 > .____el2 → .b-block > .b-block__el1 > .b-block__el2 + * .b-block > .__el1 > .____el2 → .b-block > .b-block__el1 > .b-block__el2 *
  • *
* @@ -12003,16 +12002,16 @@ emmet.exec(function(require, _) { + 'the following properties and functions are availabe:\n' + '
    ' - + '
  • attr(name, before, after) – a function that outputs' + + '
  • attr(name, before, after) – a function that outputs' + 'specified attribute value concatenated with before ' + 'and after strings. If attribute doesn\'t exists, the ' + 'empty string will be returned.
  • ' - + '
  • node – current node (instance of AbbreviationNode)
  • ' + + '
  • node – current node (instance of AbbreviationNode)
  • ' - + '
  • name – name of current tag
  • ' + + '
  • name – name of current tag
  • ' - + '
  • padding – current string padding, can be used ' + + '
  • padding – current string padding, can be used ' + 'for formatting
  • ' +'
'); @@ -12223,7 +12222,7 @@ emmet.exec(function(require, _){ function processSnippet(item, profile, level) { item.start = item.end = ''; if (!isVeryFirstChild(item) && profile.tag_nl !== false && shouldAddLineBreak(item, profile)) { - // check if we’re not inside inline element + // check if we’re not inside inline element if (isRoot(item.parent) || !require('abbreviationUtils').isInline(item.parent)) { item.start = require('utils').getNewline() + item.start; } @@ -12658,11 +12657,11 @@ emmet.exec(function(require, _) { * https://code.djangoproject.com/browser/django/trunk/django/contrib/webdesign/lorem_ipsum.py *

* Examples to test:
- * lipsum – generates 30 words text.
- * lipsum*6 – generates 6 paragraphs (autowrapped with <p> element) of text.
- * ol>lipsum10*5 — generates ordered list with 5 list items (autowrapped with <li> tag) + * lipsum – generates 30 words text.
+ * lipsum*6 – generates 6 paragraphs (autowrapped with <p> element) of text.
+ * ol>lipsum10*5 — generates ordered list with 5 list items (autowrapped with <li> tag) * with text of 10 words on each line
- * span*3>lipsum20 – generates 3 paragraphs of 20-words text, each wrapped with <span> element . + * span*3>lipsum20 – generates 3 paragraphs of 20-words text, each wrapped with <span> element . * Each paragraph phrase is unique * @param {Function} require * @param {Underscore} _ @@ -12704,33 +12703,33 @@ emmet.define('lorem', function(require, _) { 'maxime', 'corrupti'] }, ru: { - common: ['даНокО-даНокО', 'Са', 'словесными', 'горами', 'в стране', 'гласных', 'и согласных', 'живут', 'рыбные', 'тексты'], - words: ['вдаНи', 'от всех', 'Они', 'буквенных', 'домах', 'на берегу', 'семантика', - 'большого', 'языкового', 'Окоана', 'маленький', 'ручеек', 'даль', - 'журчит', 'пО всоК', 'обеспечивает', 'оо','всоПи', 'необходимыми', - 'правилами', 'эта', 'парадигматическая', 'страна', 'которой', 'жаренные', - 'предложения', 'залетают', 'прямо', 'рот', 'даМо', 'всемогущая', - 'пунктуация', 'но', 'имеет', 'власти', 'над', 'рыбными', 'текстами', - 'ведущими', 'безорфографичный', 'образ', 'МиСни', 'однажды', 'Одна', - 'маленькая', 'строчка','рыбного', 'текста', 'иПони', 'lorem', 'ipsum', - 'решила', 'выйти', 'большой', 'мир', 'грамматики', 'воНикиК', 'ОксПОкс', - 'предупреждал', 'Đž', 'злых', 'запятых', 'диких', 'знаках', 'вопроса', - 'коварных', 'точках', 'запятой', 'нО', 'текст', 'даН', 'сбить', - 'себя', 'толку', 'Он', 'собрал', 'семь', 'своих', 'заглавных', 'йукв', - 'подпоясал', 'инициал', 'Са', 'пояс', 'пустился', 'дорогу', - 'взобравшись', 'первую', 'вершину', 'курсивных', 'гор', 'бросил', - 'пОсНодниК', 'взгляд', 'наСад', 'силуэт', 'свОогО', 'родного', 'города', - 'буквоград', 'СагОНОвОк', 'деревни', 'алфавит', 'пОдСагОНОвОк', 'свОогО', - 'переулка', 'грустный', 'реторический', 'вопрос', 'скатился', 'огО', - 'щеке', 'продолжил', 'свОК', 'путь', 'дороге', 'встретил', 'рукопись', - 'Она', 'предупредила', 'ПОоК', 'всо', 'переписывается', 'несколько', - 'раз', 'единственное', 'что', 'меня', 'осталось', 'это', 'приставка', - 'возвращайся', 'ты', 'лучше', 'свою', 'безопасную', 'страну', 'послушавшись', - 'рукописи', 'наш', 'продолжил', 'свОК', 'путь', 'вскоре', 'оПу', - 'повстречался', 'коварный', 'составитель', 'рекламных', 'текстов', - 'напОившиК', 'языком', 'речью', 'СаПанившиК', 'свОо', 'агенство', - 'которое', 'использовало', 'снОва', 'снОва', 'своих', 'проектах', - 'осНи', 'переписали', 'то', 'живет', 'там', 'Đ´Đž', 'сих', 'пор'] + common: ['далеко-далеко', 'за', 'словесными', 'горами', 'в стране', 'гласных', 'и согласных', 'живут', 'рыбные', 'тексты'], + words: ['вдали', 'от всех', 'они', 'буквенных', 'домах', 'на берегу', 'семантика', + 'большого', 'языкового', 'океана', 'маленький', 'ручеек', 'даль', + 'журчит', 'по всей', 'обеспечивает', 'ее','всеми', 'необходимыми', + 'правилами', 'эта', 'парадигматическая', 'страна', 'которой', 'жаренные', + 'предложения', 'залетают', 'прямо', 'рот', 'даже', 'всемогущая', + 'пунктуация', 'не', 'имеет', 'власти', 'над', 'рыбными', 'текстами', + 'ведущими', 'безорфографичный', 'образ', 'жизни', 'однажды', 'одна', + 'маленькая', 'строчка','рыбного', 'текста', 'имени', 'lorem', 'ipsum', + 'решила', 'выйти', 'большой', 'мир', 'грамматики', 'великий', 'оксмокс', + 'предупреждал', 'о', 'злых', 'запятых', 'диких', 'знаках', 'вопроса', + 'коварных', 'точках', 'запятой', 'но', 'текст', 'дал', 'сбить', + 'себя', 'толку', 'он', 'собрал', 'семь', 'своих', 'заглавных', 'букв', + 'подпоясал', 'инициал', 'за', 'пояс', 'пустился', 'дорогу', + 'взобравшись', 'первую', 'вершину', 'курсивных', 'гор', 'бросил', + 'последний', 'взгляд', 'назад', 'силуэт', 'своего', 'родного', 'города', + 'буквоград', 'заголовок', 'деревни', 'алфавит', 'подзаголовок', 'своего', + 'переулка', 'грустный', 'реторический', 'вопрос', 'скатился', 'его', + 'щеке', 'продолжил', 'свой', 'путь', 'дороге', 'встретил', 'рукопись', + 'она', 'предупредила', 'моей', 'все', 'переписывается', 'несколько', + 'раз', 'единственное', 'что', 'меня', 'осталось', 'это', 'приставка', + 'возвращайся', 'ты', 'лучше', 'свою', 'безопасную', 'страну', 'послушавшись', + 'рукописи', 'наш', 'продолжил', 'свой', 'путь', 'вскоре', 'ему', + 'повстречался', 'коварный', 'составитель', 'рекламных', 'текстов', + 'напоивший', 'языком', 'речью', 'заманивший', 'свое', 'агенство', + 'которое', 'использовало', 'снова', 'снова', 'своих', 'проектах', + 'если', 'переписали', 'то', 'живет', 'там', 'до', 'сих', 'пор'] } }; diff --git a/modules/backend/formwidgets/markdowneditor/assets/js/markdowneditor.js b/modules/backend/formwidgets/markdowneditor/assets/js/markdowneditor.js index c4433e366..1969c1634 100644 --- a/modules/backend/formwidgets/markdowneditor/assets/js/markdowneditor.js +++ b/modules/backend/formwidgets/markdowneditor/assets/js/markdowneditor.js @@ -516,6 +516,9 @@ publicUrl = items[i].publicUrl } + // Spaces in URLs break Markdown syntax + publicUrl = publicUrl.replace(/\s/g, '%20') + onSuccess(publicUrl) this.hide() diff --git a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css index 3c836b425..a6a9af91c 100755 --- a/modules/backend/formwidgets/richeditor/assets/css/richeditor.css +++ b/modules/backend/formwidgets/richeditor/assets/css/richeditor.css @@ -200,7 +200,8 @@ to{background-position:0 0} .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 blockquote{margin-left:1.6em !important;padding-left:0;color:#777;font-style:italic} +.redactor-editor blockquote{margin-left:1.6em !important;padding:0;text-align:left;color:#777;font-style:italic} +.redactor-editor blockquote:before,.redactor-editor blockquote:after{content:''} .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 ol ol li{list-style-type:lower-alpha} diff --git a/modules/backend/formwidgets/richeditor/assets/js/build-min.js b/modules/backend/formwidgets/richeditor/assets/js/build-min.js index 3ffc38e8d..138bf87c0 100755 --- a/modules/backend/formwidgets/richeditor/assets/js/build-min.js +++ b/modules/backend/formwidgets/richeditor/assets/js/build-min.js @@ -22,7 +22,7 @@ else {$.data(this,'redactor',{});$.data(this,'redactor',Redactor(this,options));});} if(val.length===0)return this;else if(val.length===1)return val[0];else return val;};function Redactor(el,options) {return new Redactor.prototype.init(el,options);} -$.Redactor=Redactor;$.Redactor.VERSION='10.2.2';$.Redactor.modules=['alignment','autosave','block','buffer','build','button','caret','clean','code','core','dropdown','file','focus','image','indent','inline','insert','keydown','keyup','lang','line','link','linkify','list','modal','observe','paragraphize','paste','placeholder','progress','selection','shortcuts','tabifier','tidy','toolbar','upload','utils'];$.Redactor.opts={lang:'en',direction:'ltr',plugins:false,focus:false,focusEnd:false,placeholder:false,visual:true,tabindex:false,minHeight:false,maxHeight:false,linebreaks:false,replaceDivs:true,paragraphize:true,cleanStyleOnEnter:false,enterKey:true,cleanOnPaste:true,cleanSpaces:true,pastePlainText:false,autosave:false,autosaveName:false,autosaveInterval:60,autosaveOnChange:false,autosaveFields:false,linkTooltip:true,linkProtocol:'http',linkNofollow:false,linkSize:50,imageEditable:true,imageLink:true,imagePosition:true,imageFloatMargin:'10px',imageResizable:true,imageUpload:null,imageUploadParam:'file',uploadImageField:false,dragImageUpload:true,fileUpload:null,fileUploadParam:'file',dragFileUpload:true,s3:false,convertLinks:true,convertUrlLinks:true,convertImageLinks:true,convertVideoLinks:true,preSpaces:4,tabAsSpaces:false,tabKey:true,scrollTarget:false,toolbar:true,toolbarFixed:true,toolbarFixedTarget:document,toolbarFixedTopOffset:0,toolbarExternal:false,toolbarOverflow:false,source:true,buttons:['html','formatting','bold','italic','deleted','unorderedlist','orderedlist','outdent','indent','image','file','link','alignment','horizontalrule'],buttonsHide:[],buttonsHideOnMobile:[],formatting:['p','blockquote','pre','h1','h2','h3','h4','h5','h6'],formattingAdd:false,tabifier:true,deniedTags:['script','style'],allowedTags:false,paragraphizeBlocks:['table','div','pre','form','ul','ol','h1','h2','h3','h4','h5','h6','dl','blockquote','figcaption','address','section','header','footer','aside','article','object','style','script','iframe','select','input','textarea','button','option','map','area','math','hr','fieldset','legend','hgroup','nav','figure','details','menu','summary','p'],removeComments:false,replaceTags:[['strike','del'],['b','strong']],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,allowedAttr:false,removeWithoutAttr:['span'],removeEmpty:['p'],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,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'],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'],highContrast:false,observe:{dropdowns:[]},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',upload_label:'Drop file here or '}},linkify:{regexps:{youtube:/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig,vimeo:/https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,image:/((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/ig,url:/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/ig,}},codemirror:false};Redactor.fn=$.Redactor.prototype={keyCode:{BACKSPACE:8,DELETE:46,UP:38,DOWN:40,ENTER:13,SPACE:32,ESC:27,TAB:9,CTRL:17,META:91,SHIFT:16,ALT:18,RIGHT:39,LEFT:37,LEFT_WIN:91},init:function(el,options) +$.Redactor=Redactor;$.Redactor.VERSION='10.2.5';$.Redactor.modules=['alignment','autosave','block','buffer','build','button','caret','clean','code','core','dropdown','file','focus','image','indent','inline','insert','keydown','keyup','lang','line','link','linkify','list','modal','observe','paragraphize','paste','placeholder','progress','selection','shortcuts','tabifier','tidy','toolbar','upload','utils'];$.Redactor.opts={lang:'en',direction:'ltr',plugins:false,focus:false,focusEnd:false,placeholder:false,visual:true,tabindex:false,minHeight:false,maxHeight:false,linebreaks:false,replaceDivs:true,paragraphize:true,cleanStyleOnEnter:false,enterKey:true,cleanOnPaste:true,cleanSpaces:true,pastePlainText:false,autosave:false,autosaveName:false,autosaveInterval:60,autosaveOnChange:false,autosaveFields:false,linkTooltip:true,linkProtocol:'http',linkNofollow:false,linkSize:50,imageEditable:true,imageLink:true,imagePosition:true,imageFloatMargin:'10px',imageResizable:true,imageUpload:null,imageUploadParam:'file',uploadImageField:false,dragImageUpload:true,fileUpload:null,fileUploadParam:'file',dragFileUpload:true,s3:false,convertLinks:true,convertUrlLinks:true,convertImageLinks:true,convertVideoLinks:true,preSpaces:4,tabAsSpaces:false,tabKey:true,scrollTarget:false,toolbar:true,toolbarFixed:true,toolbarFixedTarget:document,toolbarFixedTopOffset:0,toolbarExternal:false,toolbarOverflow:false,source:true,buttons:['html','formatting','bold','italic','deleted','unorderedlist','orderedlist','outdent','indent','image','file','link','alignment','horizontalrule'],buttonsHide:[],buttonsHideOnMobile:[],formatting:['p','blockquote','pre','h1','h2','h3','h4','h5','h6'],formattingAdd:false,tabifier:true,deniedTags:['script','style'],allowedTags:false,paragraphizeBlocks:['table','div','pre','form','ul','ol','h1','h2','h3','h4','h5','h6','dl','blockquote','figcaption','address','section','header','footer','aside','article','object','style','script','iframe','select','input','textarea','button','option','map','area','math','hr','fieldset','legend','hgroup','nav','figure','details','menu','summary','p'],removeComments:false,replaceTags:[['strike','del'],['b','strong']],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,allowedAttr:false,removeWithoutAttr:['span'],removeEmpty:['p'],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,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'],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'],highContrast:false,observe:{dropdowns:[]},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',upload_label:'Drop file here or '}},linkify:{regexps:{youtube:/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig,vimeo:/https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,image:/((https?|www)[^\s]+\.)(jpe?g|png|gif)(\?[^\s-]+)?/ig,url:/(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/ig,}},codemirror:false};Redactor.fn=$.Redactor.prototype={keyCode:{BACKSPACE:8,DELETE:46,UP:38,DOWN:40,ENTER:13,SPACE:32,ESC:27,TAB:9,CTRL:17,META:91,SHIFT:16,ALT:18,RIGHT:39,LEFT:37,LEFT_WIN:91},init:function(el,options) {this.$element=$(el);this.uuid=uuid++;this.rtePaste=false;this.$pasteBox=false;this.loadOptions(options);this.loadModules();this.formatting={};$.merge(this.opts.blockLevelElements,this.opts.alignmentTags);this.reIsBlock=new RegExp('^('+this.opts.blockLevelElements.join('|')+')$','i');this.tidy.setupAllowed();if(this.opts.deniedTags!==false) {var tags=['html','head','link','body','meta','applet'];for(var i=0;i');},createTextarea:function() @@ -231,7 +233,8 @@ this.modal.loadTemplates();this.build.plugins();setTimeout($.proxy(this.observe. {$(this.$textarea).attr('dir',this.opts.direction);if(this.opts.linebreaks)this.$editor.addClass('redactor-linebreaks');if(this.opts.tabindex)this.$editor.attr('tabindex',this.opts.tabindex);if(this.opts.minHeight)this.$editor.css('minHeight',this.opts.minHeight);if(this.opts.maxHeight)this.$editor.css('maxHeight',this.opts.maxHeight);},setEventDropUpload:function(e) {e.preventDefault();if(!this.opts.dragImageUpload||!this.opts.dragFileUpload)return;var files=e.dataTransfer.files;this.upload.directUpload(files[0],e);},setEventDrop:function(e) {this.code.sync();setTimeout(this.clean.clearUnverified,1);this.core.setCallback('drop',e);},setEvents:function() -{this.$editor.on('drop.redactor',$.proxy(function(e) +{this.$editor.on('dragover.redactor dragenter.redactor',function(e) +{e.preventDefault();e.stopPropagation();});this.$editor.on('drop.redactor',$.proxy(function(e) {e=e.originalEvent||e;if(window.FormData===undefined||!e.dataTransfer)return true;if(e.dataTransfer.files.length===0) {return this.build.setEventDrop(e);} else @@ -241,11 +244,16 @@ setTimeout(this.clean.clearUnverified,1);this.core.setCallback('drop',e);},this) {this.$textarea.on('keydown.redactor-textarea',$.proxy(this.opts.codeKeydownCallback,this));} if($.isFunction(this.opts.codeKeyupCallback)) {this.$textarea.on('keyup.redactor-textarea',$.proxy(this.opts.codeKeyupCallback,this));} -if($.isFunction(this.opts.focusCallback)) -{this.$editor.on('focus.redactor',$.proxy(this.opts.focusCallback,this));} -$(document).on('mousedown.redactor.'+this.uuid,$.proxy(function(e){this.blurClickedElement=e.target;},this));this.$editor.on('blur.redactor',$.proxy(function(e) -{if(this.start)return;if(this.rtePaste)return;if(!this.build.isBlured())return;this.utils.disableSelectAll();if($.isFunction(this.opts.blurCallback))this.core.setCallback('blur',e);},this));},isBlured:function() -{if(this.blurClickedElement===true)return true;var $el=$(this.blurClickedElement);return(!$el.hasClass('redactor-toolbar, redactor-dropdown')&&!$el.is('#redactor-modal')&&$el.parents('.redactor-toolbar, .redactor-dropdown, #redactor-modal').length===0);},setHelpers:function() +this.$editor.on('focus.redactor',$.proxy(function(e) +{if($.isFunction(this.opts.focusCallback)) +{this.core.setCallback('focus',e);} +this.build.focused=true;this.build.blured=false;if(this.selection.getCurrent()===false) +{this.selection.get();this.range.setStart(this.$editor[0],0);this.range.setEnd(this.$editor[0],0);this.selection.addRange();}},this));$(document).on('mousedown.redactor-blur.'+this.uuid,$.proxy(function(e) +{if(this.start)return;if(this.rtePaste)return;if($(e.target).closest('.redactor-editor, .redactor-toolbar, .redactor-dropdown').size()!==0) +{return;} +this.utils.disableSelectAll();if(!this.build.blured&&$.isFunction(this.opts.blurCallback)) +{this.core.setCallback('blur',e);} +this.build.focused=false;this.build.blured=true;},this));},setHelpers:function() {if(this.linkify.isEnabled()) {this.linkify.format();} this.placeholder.enable();if(this.opts.focus)setTimeout(this.focus.setStart,100);if(this.opts.focusEnd)setTimeout(this.focus.setEnd,100);},plugins:function() @@ -273,10 +281,12 @@ else if(btnObject.dropdown) {type='dropdown';callback=false;} this.button.onClick(e,btnName,type,callback);},this));},createTooltip:function($button,name,title) {var $tooltip=$('').addClass('redactor-toolbar-tooltip redactor-toolbar-tooltip-'+this.uuid+' redactor-toolbar-tooltip-'+name).hide().html(title);$tooltip.appendTo('body');$button.on('mouseover',function() -{if($(this).hasClass('redactor-button-disabled'))return;var pos=$button.offset();$tooltip.show();$tooltip.css({top:(pos.top+$button.innerHeight())+'px',left:(pos.left+$button.innerWidth()/2-$tooltip.innerWidth()/2)+'px'});});$button.on('mouseout',function() +{if($(this).hasClass('redactor-button-disabled')) +{return;} +var pos=$button.offset();$tooltip.css({top:(pos.top+$button.innerHeight())+'px',left:(pos.left+$button.innerWidth()/2-$tooltip.innerWidth()/2)+'px'});$tooltip.show();});$button.on('mouseout',function() {$tooltip.hide();});},onClick:function(e,btnName,type,callback) -{this.button.caretOffset=this.caret.getOffset();e.preventDefault();if(this.utils.browser('msie'))e.returnValue=false;if(type=='command')this.inline.format(callback);else if(type=='dropdown')this.dropdown.show(e,btnName);else this.button.onClickCallback(e,callback,btnName);},onClickCallback:function(e,callback,btnName) -{var func;this.blurClickedElement=true;if($.isFunction(callback))callback.call(this,btnName);else if(callback.search(/\./)!='-1') +{this.button.caretOffset=this.caret.getOffset();e.preventDefault();$(document).find('.redactor-toolbar-tooltip').hide();if(this.utils.browser('msie'))e.returnValue=false;if(type=='command')this.inline.format(callback);else if(type=='dropdown')this.dropdown.show(e,btnName);else this.button.onClickCallback(e,callback,btnName);},onClickCallback:function(e,callback,btnName) +{var func;if($.isFunction(callback))callback.call(this,btnName);else if(callback.search(/\./)!='-1') {func=callback.split('.');if(typeof this[func[0]]=='undefined')return;this[func[0]][func[1]](btnName);} else this[callback](btnName);this.observe.buttons(e,btnName);},get:function(key) {return this.$toolbar.find('a.re-'+key);},setActive:function(key) @@ -341,7 +351,7 @@ this.range.collapse(false);this.selection.addRange();},getOffsetOfElement:functi {var offset=0;var sel=window.getSelection();if(sel.rangeCount>0) {var range=window.getSelection().getRangeAt(0);var caretRange=range.cloneRange();caretRange.selectNodeContents(this.$editor[0]);caretRange.setEnd(range.endContainer,range.endOffset);offset=caretRange.toString().length;} return offset;},setOffset:function(start,end) -{if(typeof end=='undefined')end=start;if(!this.focus.isFocused())this.focus.setStart();var sel=this.selection.get();var node,offset=0;var walker=document.createTreeWalker(this.$editor[0],NodeFilter.SHOW_TEXT,null,null);while(node==walker.nextNode()) +{if(typeof end=='undefined')end=start;if(!this.focus.isFocused())this.focus.setStart();var sel=this.selection.get();var node,offset=0;var walker=document.createTreeWalker(this.$editor[0],NodeFilter.SHOW_TEXT,null,null);while(node=walker.nextNode()) {offset+=node.nodeValue.length;if(offset>start) {this.range.setStart(node,node.nodeValue.length+start-offset);start=Infinity;} if(offset>=end) @@ -350,10 +360,10 @@ this.range.collapse(false);this.selection.addRange();},setToPoint:function(start {this.caret.setOffset(start,end);},getCoords:function() {return this.caret.getOffset();}};},clean:function() {return{onSet:function(html) -{html=html.replace(/]?)>([\w\W]*?)<\/script>/gi,'');html=html.replace(/\$/g,'$');html=html.replace(//gi,'');if(this.opts.replaceDivs)html=this.clean.replaceDivs(html);if(this.opts.linebreaks)html=this.clean.replaceParagraphsToBr(html);html=this.clean.saveFormTags(html);var $div=$('
');$div.html(html);var fonts=$div.find('font[style]');if(fonts.length!==0) +{html=this.clean.savePreCode(html);html=html.replace(/]?)>([\w\W]*?)<\/script>/gi,'');html=html.replace(/\$/g,'$');html=html.replace(//gi,'');if(this.opts.replaceDivs&&!this.opts.linebreaks)html=this.clean.replaceDivs(html);if(this.opts.linebreaks)html=this.clean.replaceParagraphsToBr(html);html=this.clean.saveFormTags(html);var $div=$('
');$div.html(html);var fonts=$div.find('font[style]');if(fonts.length!==0) {fonts.replaceWith(function() {var $el=$(this);var $span=$('').attr('style',$el.attr('style'));return $span.append($el.contents());});html=$div.html();} -$div.remove();html=html.replace(//gi,'');html=html.replace(/<\/font>/gi,'');html=this.tidy.load(html);if(this.opts.paragraphize)html=this.paragraphize.load(html);html=this.clean.setVerified(html);html=this.clean.convertInline(html);html=html.replace(/&/g,'&');return html;},onSync:function(html) +$div.remove();html=html.replace(//gi,'');html=html.replace(/<\/font>/gi,'');html=this.tidy.load(html);if(this.opts.paragraphize)html=this.paragraphize.load(html);html=this.clean.setVerified(html);html=this.clean.convertInline(html);html=html.replace(/&/g,'&');return html;},onSync:function(html) {html=html.replace(/\u200B/g,'');html=html.replace(/​/gi,'');if(this.opts.cleanSpaces) {html=html.replace(/ /gi,' ');} if(html.search(/^

(||\s|||| )<\/p>$/i)!=-1) @@ -361,8 +371,8 @@ if(html.search(/^

(||\s|||| )<\/p>$/i)!=-1) html=html.replace(/