Index: core/admin_templates/js/inp_ckconfig.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/admin_templates/js/inp_ckconfig.js (revision 15892) +++ core/admin_templates/js/inp_ckconfig.js (revision ) @@ -1,3 +1,5 @@ +CKEDITOR.config.title = ''; + /* * Append here extra CSS rules that should be applied into the editing area. * Example: @@ -20,8 +22,10 @@ //CKEDITOR.config.PluginsPath = CKEDITOR.config.BasePath + 'plugins/' ; -CKEDITOR.config.extraPlugins = 'my_link,my_document,my_maximize,MediaEmbed'; +CKEDITOR.config.entities = false; +CKEDITOR.config.extraPlugins = 'my_link,my_document,my_maximize,my_inline'; + //CKEDITOR.plugins.add('MySource'); //CKEDITOR.plugins.add('MyPreview'); //CKEDITOR.plugins.add('MyLink'); @@ -48,6 +52,15 @@ ['Styles','Font','FontSize','RemoveFormat','-','Scayt','-', /*My*/'Source', 'Maximize', 'ShowBlocks'] ]; +CKEDITOR.config.toolbar_Inline = [ + ['InlineSave', 'InlineCancel'], + ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Image', 'Document', 'MediaEmbed', 'Link', '-', 'Undo', 'Redo'], + ['Find', 'Replace', 'Scayt'], + '/', + ['Styles'], ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], + ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'] +]; + /*CKEDITOR.config.toolbar_Simple = [ ['Styles'], ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], @@ -75,28 +88,28 @@ CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR ; // p | div | br CKEDITOR.config.shiftEnterMode = CKEDITOR.ENTER_P ; // p | div | br -CKEDITOR.config.keystrokes = [ - [ CKEDITOR.CTRL + 65 /*A*/, true ], - [ CKEDITOR.CTRL + 67 /*C*/, true ], - [ CKEDITOR.CTRL + 70 /*F*/, true ], - [ CKEDITOR.CTRL + 83 /*S*/, true ], - [ CKEDITOR.CTRL + 84 /*T*/, true ], - [ CKEDITOR.CTRL + 88 /*X*/, true ], - [ CKEDITOR.CTRL + 86 /*V*/, 'Paste' ], - [ CKEDITOR.CTRL + 45 /*INS*/, true ], - [ CKEDITOR.SHIFT + 45 /*INS*/, 'Paste' ], - [ CKEDITOR.CTRL + 88 /*X*/, 'Cut' ], - [ CKEDITOR.SHIFT + 46 /*DEL*/, 'Cut' ], - [ CKEDITOR.CTRL + 90 /*Z*/, 'Undo' ], - [ CKEDITOR.CTRL + 89 /*Y*/, 'Redo' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'Redo' ], - [ CKEDITOR.CTRL + 76 /*L*/, 'Link' ], - [ CKEDITOR.CTRL + 66 /*B*/, 'Bold' ], - [ CKEDITOR.CTRL + 73 /*I*/, 'Italic' ], - [ CKEDITOR.CTRL + 85 /*U*/, 'Underline' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 83 /*S*/, 'Save' ], - [ CKEDITOR.CTRL + CKEDITOR.ALT + 13 /*ENTER*/, 'FitWindow' ] -] ; +/*CKEDITOR.config.keystrokes = [ + [ CKEDITOR.CTRL + 65 *//*A*//*, true ], + [ CKEDITOR.CTRL + 67 *//*C*//*, true ], + [ CKEDITOR.CTRL + 70 *//*F*//*, true ], + [ CKEDITOR.CTRL + 83 *//*S*//*, true ], + [ CKEDITOR.CTRL + 84 *//*T*//*, true ], + [ CKEDITOR.CTRL + 88 *//*X*//*, true ], + [ CKEDITOR.CTRL + 86 *//*V*//*, 'Paste' ], + [ CKEDITOR.CTRL + 45 *//*INS*//*, true ], + [ CKEDITOR.SHIFT + 45 *//*INS*//*, 'Paste' ], + [ CKEDITOR.CTRL + 88 *//*X*//*, 'Cut' ], + [ CKEDITOR.SHIFT + 46 *//*DEL*//*, 'Cut' ], + [ CKEDITOR.CTRL + 90 *//*Z*//*, 'Undo' ], + [ CKEDITOR.CTRL + 89 *//*Y*//*, 'Redo' ], + [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 *//*Z*//*, 'Redo' ], + [ CKEDITOR.CTRL + 76 *//*L*//*, 'Link' ], + [ CKEDITOR.CTRL + 66 *//*B*//*, 'Bold' ], + [ CKEDITOR.CTRL + 73 *//*I*//*, 'Italic' ], + [ CKEDITOR.CTRL + 85 *//*U*//*, 'Underline' ], + [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 83 *//*S*//*, 'Save' ], + [ CKEDITOR.CTRL + CKEDITOR.ALT + 13 *//*ENTER*//*, 'FitWindow' ] +] ;*/ //CKEDITOR.config.menu_groups = 'generic,anchor,flash,select,textarea,checkbox,radio,textfield,hiddenfield,imagebutton,button,bulletedlist,numberedlist,table,form'; Index: core/units/categories/categories_tag_processor.php IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/units/categories/categories_tag_processor.php (revision 15892) +++ core/units/categories/categories_tag_processor.php (revision ) @@ -1246,22 +1246,45 @@ } $edit_code_before = $edit_code_after = ''; + $inline_editing = isset($params['mode']) && $params['mode'] == 'inline'; if ( EDITING_MODE == EDITING_MODE_CONTENT ) { + if ( $inline_editing ) { + $params['name'] = 'content_block_' . $num; + + $editing_hint = $this->Application->Phrase('la_hint_ClickToEdit', false, true); + + $edit_code_before = ' +
+
+
+
'; + + $edit_code_after = '
' . $this->FCKEditor($params); + } + else { - $button_code = $this->Application->ProcessParsedTag($content->getPrefixSpecial(), 'AdminEditButton', $params); + $button_code = $this->Application->ProcessParsedTag($content->getPrefixSpecial(), 'AdminEditButton', $params); - $edit_code_before = ' -
- ' . $button_code . ' -
'; + $edit_code_before = ' +
+ ' . $button_code . ' +
'; - $edit_code_after = '
'; - } + $edit_code_after = '
'; + } + } if ( $this->Application->GetVar('_editor_preview_') == 1 ) { $data = $this->Application->RecallVar('_editor_preview_content_'); } + elseif ( EDITING_MODE == EDITING_MODE_CONTENT && $inline_editing ) { + // don't use formatter, that replaced "@@ID@@" links + $content->SetFieldOption('Content', 'using_fck', false); + $data = $content->GetField('Content'); + $content->SetFieldOption('Content', 'using_fck', true); + } else { + // use formatter, that replaced "@@ID@@" links $data = $content->GetField('Content'); } @@ -1447,17 +1470,22 @@ $url_params = Array ('theme-file_event' => 'OnSaveLayout', 'source' => $template, 'pass' => 'all,theme-file', '__NO_REWRITE__' => 1, 'no_amp' => 1); $save_layout_url = $this->Application->HREF('index', '', $url_params); + $url_params = Array ('content_event' => 'OnSaveContentBlock', 'pass' => 'all,content', '__NO_REWRITE__' => 1, 'no_amp' => 1); + $save_content_url = $this->Application->HREF('index', ADMIN_DIRECTORY, $url_params, 'index.php'); + $page =& $this->_getPage($params); $page_helper = $this->Application->recallObject('PageHelper'); /* @var $page_helper PageHelper */ $class_params = Array ( + 'languagePrefix' => 'l' . $this->Application->GetVar('m_lang') . '_', 'pageId' => $page->GetID(), 'pageInfo' => $page->isLoaded() ? $page_helper->getPageInfo( $page->GetID() ) : Array (), 'editUrl' => $edit_template_url, 'browseUrl' => $this->Application->HREF('', '', Array ('editing_mode' => '#EDITING_MODE#', '__NO_REWRITE__' => 1, 'no_amp' => 1)), 'saveLayoutUrl' => $save_layout_url, + 'saveContentUrl' => $save_content_url, 'editingMode' => (int)EDITING_MODE, ); @@ -1628,18 +1656,13 @@ $revision = $this->Application->recallObject('page-revision.current'); /* @var $revision kDBItem */ - if ( !$revision->GetDBField('IsDraft') ) { - $edit_code .= $tabs . 'a_toolbar.DisableButton("select");' . $tabs . 'a_toolbar.DisableButton("delete");' . $tabs . 'a_toolbar.DisableButton("preview");'; - } + $page_helper = $this->Application->recallObject('PageHelper'); + /* @var $page_helper PageHelper */ - if ( $revision->GetDBField('Status') == STATUS_ACTIVE || $revision->GetDBField('IsDraft') ) { - $edit_code .= $tabs . 'a_toolbar.DisableButton("approve");'; + foreach ( $page_helper->getToolbarButtonsState($revision) as $toolbar_button => $is_enabled ) { + $edit_code .= $tabs . 'a_toolbar.SetEnabled("' . $toolbar_button . '", ' . json_encode($is_enabled) . ');'; } - if ( $revision->GetDBField('Status') == STATUS_DISABLED || $revision->GetDBField('IsLive') || $revision->GetDBField('IsDraft') ) { - $edit_code .= $tabs . 'a_toolbar.DisableButton("decline");'; - } - $publishing_tools = $this->Application->Phrase('la_btn_PublishingTools', false, true); $edit_code .= substr($tabs, 0, -1) . ' @@ -1709,9 +1732,10 @@ function toolbarButton($name, $title, $tabs) { - $phrase = $this->Application->Phrase($title, false, true); + $action = 'function() { aTemplateManager.revisionToolbarClick("' . $name . '"); }'; + $phrase = kUtil::escape($this->Application->Phrase($title, false, true), kUtil::ESCAPE_HTML . '+' . kUtil::ESCAPE_JS); - return $tabs . 'a_toolbar.AddButton( new ToolBarButton("' . $name . '", "' . kUtil::escape($phrase, kUtil::ESCAPE_HTML . '+' . kUtil::ESCAPE_JS) . '") );'; + return $tabs . 'a_toolbar.AddButton(new ToolBarButton("' . $name . '", "' . $phrase . '", ' . $action . '));'; } function _getThemeFileId() \ No newline at end of file Index: core/units/helpers/page_helper.php IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/units/helpers/page_helper.php (revision 15892) +++ core/units/helpers/page_helper.php (revision ) @@ -26,7 +26,44 @@ { list ($user_id, $history_permission) = $this->getHistoryPermissionAndUser($page_id); - $where_clause = Array ( + $users = $this->getEditors($page_id, $user_id); + + return array( + 'current_revision' => $this->getCurrentRevisionInfo(), + 'editors' => $users, + 'editors_warning' => $this->getEditorsWarning($users), + 'revisions' => $history_permission ? $this->getPageRevisions($page_id) : array(), + ); + } + + /** + * Returns current admin user id (even, when called from front-end) and it's revision history view permission + * + * @param int $page_id + * @return Array + */ + protected function getHistoryPermissionAndUser($page_id) + { + $perm_helper = $this->Application->recallObject('PermissionsHelper'); + /* @var $perm_helper kPermissionsHelper */ + + $user_id = (int)$this->Application->RecallVar($this->Application->isAdmin ? 'user_id' : 'admin_user_id'); + $history_permission = $perm_helper->CheckUserPermission($user_id, 'CATEGORY.REVISION.HISTORY.VIEW', 0, $page_id); + + return Array ($user_id, $history_permission); + } + + /** + * Returns information about given page editors. + * + * @param integer $page_id Page, that is being edited. + * @param integer $user_id User, who is editing a page. + * + * @return array + */ + protected function getEditors($page_id, $user_id) + { + $where_clause = array( 'pr.PageId = ' . $page_id, 'pr.CreatedById <> ' . $user_id, 'pr.IsDraft = 1', @@ -36,65 +73,112 @@ FROM ' . $this->Application->getUnitOption('page-revision', 'TableName') . ' pr LEFT JOIN ' . TABLE_PREFIX . 'Users u ON u.PortalUserId = pr.CreatedById WHERE (' . implode(') AND (', $where_clause) . ')'; - $users = $this->Conn->GetCol($sql); - $page_revisions = Array (); + return $this->Conn->GetCol($sql); + } - if ( $history_permission ) { - $tag_params = Array ('per_page' => -1, 'skip_parent_filter' => 1, 'requery' => 1, 'page_id' => $page_id); + /** + * Returns information about current revision. + * + * @return array + */ + protected function getCurrentRevisionInfo() + { + $revision = $this->Application->recallObject('page-revision.current'); + /* @var $revision kDBItem */ - $revisions = $this->Application->recallObject('page-revision.list', 'page-revision_List', $tag_params); - /* @var $revisions kDBList */ + $status_label = $this->getRevisionStatusText($revision); - $revisions->Query(); - $revisions->GoFirst(); + $draft = $revision->GetDBField('IsDraft'); + $title = $this->getAdminPhrase($draft ? 'la_title_EditingDraft' : 'la_title_ViewingRevision'); - $status_options = $revisions->GetFieldOptions('Status'); - $draft_label = $this->Application->Phrase('la_Draft', false, true); - $title_label = $this->Application->Phrase('la_RevisionNumber', false, true); - $by_label = $this->Application->Phrase('la_By', false, true); + $current_revision_info = array( + 'title' => sprintf($title, $revision->GetDBField('RevisionNumber'), $status_label), + 'status' => $revision->GetDBField('Status'), + 'saved' => '', + 'toolbar_state' => $this->getToolbarButtonsState($revision), + ); - while ( !$revisions->EOL() ) { - $status = $revisions->GetDBField('Status'); - $status_label = $this->Application->Phrase($status_options['options'][$status], false, true); + $auto_save_time = $revision->GetDBField('AutoSavedOn'); - $page_revisions[ 'r' . $revisions->GetDBField('RevisionNumber') ] = Array ( - 'title' => $revisions->GetDBField('IsDraft') ? $draft_label : sprintf($title_label, $revisions->GetDBField('RevisionNumber')), - 'status' => $status, - 'status_label' => mb_strtolower($status_label), - 'datetime' => $revisions->GetField('CreatedOn'), - 'author' => $by_label . ': ' . $revisions->GetField('CreatedById'), - 'draft' => (int)$revisions->GetDBField('IsDraft'), - ); + if ( $auto_save_time ) { + $phrase = $this->getAdminPhrase($draft ? 'la_DraftSavedAt' : 'la_SavedAt'); + $current_revision_info['saved'] = sprintf($phrase, $revision->GetField('AutoSavedOn_time') . ' (' . $this->getAgoTime($auto_save_time) . ')'); + } - $revisions->GoNext(); + return $current_revision_info; - } + } + + /** + * Returns state of all CMS revision toolbar buttons. + * + * @param kDBItem $revision Page Revision. + * + * @return array + */ + public function getToolbarButtonsState(kDBItem $revision) + { + $ret = array(); + + foreach ( $this->getToolbarButtons() as $toolbar_button ) { + $ret[$toolbar_button] = $this->isToolbarButtonEnabled($toolbar_button, $revision); } - $current_revision = $this->Application->recallObject('page-revision.current'); - /* @var $current_revision kDBItem */ + return $ret; + } - $revision_status = $current_revision->GetDBField('Status'); - $status_options = $current_revision->GetFieldOptions('Status'); - $status_label = $this->Application->Phrase($status_options['options'][$revision_status], false, true); + /** + * Returns list of CMS revision toolbar buttons. + * + * @return array + */ + protected function getToolbarButtons() + { + return array('select', 'delete', 'approve', 'decline', 'preview', 'history'); + } - $revision_phase = $current_revision->GetDBField('IsDraft') ? 'la_title_EditingDraft' : 'la_title_ViewingRevision'; - $revision_title = sprintf($this->Application->Phrase($revision_phase, false, true), $current_revision->GetDBField('RevisionNumber'), mb_strtolower($status_label)); - $current_revision_info = Array ('title' => $revision_title, 'status' => $revision_status, 'saved' => ''); + /** + * Checks if given CMS revision toolbar button is enabled for given revision. + * + * @param string $button_name Toolbar button name. + * @param kDBItem $revision Revision to check against. + * + * @return boolean + */ + protected function isToolbarButtonEnabled($button_name, kDBItem $revision) + { + $is_draft = $revision->GetDBField('IsDraft'); - $autosave_time = $current_revision->GetDBField('AutoSavedOn'); + if ( $button_name == 'select' || $button_name == 'delete' || $button_name == 'preview' ) { + return (bool)$is_draft; + } - if ( $autosave_time ) { - $phrase = $this->Application->Phrase($current_revision->GetDBField('IsDraft') ? 'la_DraftSavedAt' : 'la_SavedAt', false, true); - $current_revision_info['saved'] = sprintf($phrase, $current_revision->GetField('AutoSavedOn_time') . ' (' . $this->getAgoTime($autosave_time) . ')'); + if ( $button_name == 'approve' ) { + return $revision->GetDBField('Status') != STATUS_ACTIVE && !$is_draft; } + if ( $button_name == 'decline' ) { + return $revision->GetDBField('Status') != STATUS_DISABLED && !$revision->GetDBField('IsLive') && !$is_draft; + } + + return true; + } + + /** + * Returns warning to be shown in case of parallel editing attempts. + * + * @param array $users Users, that are editing a page. + * + * @return string + */ + protected function getEditorsWarning(array $users) + { $ml_helper = $this->Application->recallObject('kMultiLanguageHelper'); /* @var $ml_helper kMultiLanguageHelper */ - $currently_editing = $ml_helper->getPluralPhrase( + $ret = $ml_helper->getPluralPhrase( count($users), - Array ( + array( 'phrase1' => 'la_PageCurrentlyEditing1', 'phrase2' => 'la_PageCurrentlyEditing2', 'phrase5' => 'la_PageCurrentlyEditing5', @@ -102,19 +186,110 @@ false, true ); - $currently_editing = sprintf($currently_editing, implode(', ', $users)); + return sprintf($ret, implode(', ', $users)); + } - return Array ('current_revision' => $current_revision_info, 'editors' => $users, 'editors_warning' => $currently_editing, 'revisions' => $page_revisions); + /** + * Returns information about given page revisions. + * + * @param integer $page_id Page, that is being edited. + * + * @return array + */ + protected function getPageRevisions($page_id) + { + $ret = Array (); + + $tag_params = Array ('per_page' => -1, 'skip_parent_filter' => 1, 'requery' => 1, 'page_id' => $page_id); + + $revisions = $this->Application->recallObject('page-revision.list', 'page-revision_List', $tag_params); + /* @var $revisions kDBList */ + + $revisions->Query(); + $revisions->GoFirst(); + + while ( !$revisions->EOL() ) { + $ret[ 'r' . $revisions->GetDBField('RevisionNumber') ] = array( + 'title' => $this->getRevisionTitle($revisions), + 'status' => $revisions->GetDBField('Status'), + 'status_label' => $this->getRevisionStatusText($revisions), + 'datetime' => $revisions->GetField('CreatedOn'), + 'author' => $this->getRevisionAuthor($revisions), + 'draft' => (int)$revisions->GetDBField('IsDraft'), + ); + + $revisions->GoNext(); - } + } /** + * Returns title for given revision. + * + * @param kDBBase $revision Page Revision. + * + * @return string + */ + protected function getRevisionTitle(kDBBase $revision) + { + if ( $revision->GetDBField('IsDraft') ) { + return $this->getAdminPhrase('la_Draft'); + } + + $title = $this->getAdminPhrase('la_RevisionNumber'); + + return sprintf($title, $revision->GetDBField('RevisionNumber')); + } + + /** + * Returns status text for given revision. + * + * @param kDBBase $revision Page Revision. + * + * @return string + */ + protected function getRevisionStatusText(kDBBase $revision) + { + $status = $revision->GetDBField('Status'); + $options = $revision->GetFieldOptions('Status'); + + return mb_strtolower($this->getAdminPhrase($options['options'][$status])); + } + + /** + * Returns author of given revision. + * + * @param kDBBase $revision Page Revision. + * + * @return string + */ + protected function getRevisionAuthor(kDBBase $revision) + { + $by_label = $this->getAdminPhrase('la_By'); + + return $by_label . ': ' . $revision->GetField('CreatedById'); + } + + /** + * Returns Admin's non-editable translation of given phrase. + * + * @param string $label Phrase label. + * + * @return string + */ + protected function getAdminPhrase($label) + { + return $this->Application->Phrase($label, false, true); + } + + /** * Returns time passed between 2 given dates in "X minutes Y seconds ago" format * * @param int $from_date * @param int $to_date + * @param integer $max_levels + * * @return string */ - function getAgoTime($from_date, $to_date = null, $max_levels = 1) + public function getAgoTime($from_date, $to_date = null, $max_levels = 1) { $blocks = Array ( Array ('name' => 'year', 'amount' => 60*60*24*365), @@ -157,6 +332,9 @@ return implode(' ', $result) . ' ago'; } + return $ret; + } + /** * Returns where clause for loading correct revision for a given page * @@ -165,7 +343,7 @@ * @param string $table_name * @return string */ - function getRevsionWhereClause($page_id, $live_revision_number, $table_name = '') + public function getRevsionWhereClause($page_id, $live_revision_number, $table_name = '') { $revision = (int)$this->Application->GetVar('revision'); list ($user_id, $has_permission) = $this->getHistoryPermissionAndUser($page_id); @@ -186,26 +364,12 @@ } /** - * Returns current admin user id (even, when called from front-end) and it's revision history view permission - * - * @param int $page_id - * @return Array - */ - function getHistoryPermissionAndUser($page_id) - { - $user_id = (int)$this->Application->RecallVar($this->Application->isAdmin ? 'user_id' : 'admin_user_id'); - $history_permission = $this->Application->CheckAdminPermission('CATEGORY.REVISION.HISTORY.VIEW', 0, $page_id); - - return Array ($user_id, $history_permission); - } - - /** * Creates new content block in every revision that misses it. Plus creates first page revision * * @param int $page_id * @param int $num */ - function createNewContentBlock($page_id, $num) + public function createNewContentBlock($page_id, $num) { $sql = 'SELECT pc.PageContentId, pr.RevisionId FROM ' . TABLE_PREFIX . 'PageRevisions pr @@ -251,7 +415,7 @@ * * @return bool */ - function loadContentBlock(&$content_block, &$page, $num) + public function loadContentBlock(&$content_block, &$page, $num) { $page_id = $page->GetID(); Index: core/kernel/db/db_tag_processor.php IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/kernel/db/db_tag_processor.php (revision 15892) +++ core/kernel/db/db_tag_processor.php (revision ) @@ -1534,7 +1534,6 @@ return Array($id, $field); } - /** * Returns input field name to * be placed on form (for correct @@ -2484,168 +2483,33 @@ return $value; } - /** - * Returns FCKEditor locale, that matches default site language - * - * @return string - */ - function _getFCKLanguage() + function FCKEditor($params) { - static $language_code = null; + $editor_name = array_key_exists('name', $params) ? $params['name'] : $this->InputName($params); - if (!isset($language_code)) { - $language_code = 'en'; // defaut value + $fck_helper = $this->Application->recallObject('FCKHelper'); + /* @var $fck_helper fckFCKHelper */ - if ($this->Application->isAdmin) { - $language_id = $this->Application->Phrases->LanguageId; + if ( isset($params['mode']) && $params['mode'] == 'inline' ) { + return $fck_helper->CKEditorInlineTag($editor_name, $params); - } + } - else { - $language_id = $this->Application->GetDefaultLanguageId(); // $this->Application->GetVar('m_lang'); - } - $sql = 'SELECT Locale - FROM '. $this->Application->getUnitOption('lang', 'TableName') . ' - WHERE LanguageId = ' . $language_id; - $locale = strtolower( $this->Conn->GetOne($sql) ); - - if (file_exists(FULL_PATH . EDITOR_PATH . 'editor/lang/' . $locale . '.js')) { - // found language file, that exactly matches locale name (e.g. "en") - $language_code = $locale; + return $fck_helper->CKEditorTag($editor_name, $this->CKEditorValue($params), $params); - } + } - else { - $locale = explode('-', $locale); - if (file_exists(FULL_PATH . EDITOR_PATH . 'editor/lang/' . $locale[0] . '.js')) { - // language file matches first part of locale (e.g. "ru-RU") - $language_code = $locale[0]; - } - } - } - return $language_code; - } - - - function FCKEditor($params) + /** + * Returns value, used by FCKEditor tag + * + * @param array $params + * + * @return string + */ + protected function CKEditorValue($params) { $params['no_special'] = 1; $params['format'] = array_key_exists('format', $params) ? $params['format'] . ';fck_ready' : 'fck_ready'; - $value = $this->Field($params); - $name = array_key_exists('name', $params) ? $params['name'] : $this->InputName($params); - $theme_path = $this->Application->GetFrontThemePath() . '/inc'; - - if ( file_exists(FULL_PATH . $theme_path . '/style.css') ) { - $url_params = Array ( - 'events[fck]' => 'OnGetsEditorStyles', - 'no_pass_through' => 1, 'pass' => 'm', 'no_amp' => 1 - ); - - $styles_css = $this->Application->HREF('index', '_FRONT_END_', $url_params, 'index.php'); - } - else { - $theme_path = rtrim(EDITOR_PATH, '/'); - $styles_css = $this->Application->BaseURL($theme_path) . 'style.css'; - } - - $styles_js = $this->Application->BaseURL($theme_path) . 'styles.js'; - - /*$page_id = $this->Application->GetVar('c_id'); - $content_id = $this->Application->GetVar('content_id'); - $preview_url = ''; - - if ($page_id && $content_id) { - // editing content block from Front-End, not category in admin - $sql = 'SELECT NamedParentPath - FROM ' . $this->Application->getUnitOption('c', 'TableName') . ' - WHERE ' . $this->Application->getUnitOption('c', 'IDField') . ' = ' . (int)$page_id; - $template = strtolower( $this->Conn->GetOne($sql) ); - - $url_params = Array ('m_cat_id' => $page_id, 'no_amp' => 1, 'editing_mode' => EDITING_MODE_CONTENT, 'pass' => 'm'); - $preview_url = $this->Application->HREF($template, '_FRONT_END_', $url_params, 'index.php'); - $preview_url = preg_replace('/&(admin|editing_mode)=[\d]/', '', $preview_url); - }*/ - - include_once(FULL_PATH . EDITOR_PATH . 'ckeditor.php'); - - $oCKeditor = new CKeditor(BASE_PATH . EDITOR_PATH); - -// $oFCKeditor->FullUrl = $this->Application->BaseURL(); -// $oFCKeditor->BaseUrl = BASE_PATH . '/'; // used by custom document plugin -// $oFCKeditor->PreviewUrl = $preview_url; // used by custom MyPreview plugin - - $oCKeditor->lateLoad = array_key_exists('late_load', $params) && $params['late_load']; - - $width = $params['width']; - $height = $params['height']; - - if ( preg_match('/^[\d]+$/', $width) ) { - $width .= 'px'; - } - - if ( preg_match('/^[\d]+$/', $height) ) { - $height .= 'px'; - } - - $oCKeditor->textareaAttributes = Array ( - 'style' => 'width: ' . $width . '; height: ' . $height . ';' - ); - - if ( file_exists(SYSTEM_PRESET_PATH . DIRECTORY_SEPARATOR . 'inp_ckconfig.js') ) { - $file_helper = $this->Application->recallObject('FileHelper'); - /* @var $file_helper FileHelper */ - - $config_js = $file_helper->pathToUrl(SYSTEM_PRESET_PATH . DIRECTORY_SEPARATOR . 'inp_ckconfig.js'); - } - else { - $config_js = $this->Application->BaseURL() . 'core/admin_templates/js/inp_ckconfig.js'; - } - - $fck_helper = $this->Application->recallObject('FCKHelper'); - /* @var $fck_helper fckFCKHelper */ - - $transit_params = $fck_helper->getTransitParams($params); - - $oCKeditor->config = Array ( - 'toolbar' => $this->Application->isDebugMode() ? 'DebugMode' : 'Default', // $page_id && $content_id ? 'Advanced' : 'Default', - - 'baseHref' => $this->Application->BaseURL( rtrim(EDITOR_PATH, '/') ), - -// 'ProjectPath' => BASE_PATH . '/', // used by custom MyPreview plugin - - 'customConfig' => $config_js, - 'stylesSet' => 'portal:' . $styles_js, - 'contentsCss' => $styles_css, -// 'DefaultStyleLabel' => $this->Application->Phrase('la_editor_default_style'), // not ported to ckeditor - 'Admin' => 1, // for custom file browser to work - 'K4' => 1, // for custom file browser to work -// 'PreviewUrl' => $preview_url, -// 'BaseUrl' => BASE_PATH . '/', // used by custom document plugin & by file browser - 'language' => $this->_getFCKLanguage(), - 'height' => $height, // editor area height - ); - - if ( isset($transit_params['bgcolor']) && $transit_params['bgcolor'] ) { - $oCKeditor->config['extraCss'] = 'body { background-color: ' . $transit_params['bgcolor'] . '; }'; - } - - foreach ($transit_params as $param_name => $param_value) { - if ( !$param_value ) { - continue; - } - - $param_key = str_replace(' ', '', ucwords(str_replace('_', ' ', $param_name))); - $param_key[0] = strtolower($param_key[0]); - - $oCKeditor->config[$param_key] = $param_value; - } - - $oCKeditor->returnOutput = true; - - $events = Array ( - 'configLoaded' => 'function(ev) { ev.editor.addCss(ev.editor.config.extraCss); }', - ); - - return $oCKeditor->editor($name, $value, Array (), $events); + return $this->Field($params); } function IsNewItem($params) \ No newline at end of file Index: core/units/content/content_eh.php IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/units/content/content_eh.php (revision 15892) +++ core/units/content/content_eh.php (revision ) @@ -44,12 +44,19 @@ */ function OnSaveContentBlock($event) { - if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { + if ( $this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) ) { $event->status = kEvent::erFAIL; + - return ; + return; } - if ( !$this->saveContentBlock($event, false) ) { + $updated = $this->saveContentBlock($event, false); + + if ( $this->Application->GetVar('ajax') == 'yes' ) { + $event->status = kEvent::erSTOP; + echo ($updated === false) ? 'FAILED' : 'OK'; + } + elseif ( !$updated ) { $event->status = kEvent::erFAIL; } @@ -133,34 +140,33 @@ */ function saveContentBlock($event, $is_draft) { - $object = $event->getObject( Array('skip_autoload' => true) ); - /* @var $object kDBItem */ - - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); + $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); + if ( !$items_info ) { return ''; } list ($object, $revision) = $this->getContentBlockAndRevision($event); /* @var $revision kDBItem */ + /* @var $object kDBItem */ list (, $field_values) = each($items_info); $object->SetFieldsFromHash($field_values, $this->getRequestProtectedFields($field_values)); $updated = $object->Update(); if ( $updated ) { - $revision->SetDBField('AutoSavedOn_date', adodb_mktime()); - $revision->SetDBField('AutoSavedOn_time', adodb_mktime()); + $revision->SetDBField('AutoSavedOn_date', time()); + $revision->SetDBField('AutoSavedOn_time', time()); - $revision->Update(); + $revision->Update(); } if ( $is_draft ) { if ( $updated ) { - $page_helper = $this->Application->recallObject('PageHelper'); - /* @var $page_helper PageHelper */ + $page_helper = $this->Application->recallObject('PageHelper'); + /* @var $page_helper PageHelper */ - return $revision->GetField('AutoSavedOn') . ' (' . $page_helper->getAgoTime( $revision->GetDBField('AutoSavedOn') ) . ')'; + return $revision->GetField('AutoSavedOn') . ' (' . $page_helper->getAgoTime($revision->GetDBField('AutoSavedOn')) . ')'; - } + } } else { return $updated; @@ -179,20 +185,20 @@ $event->status = kEvent::erSTOP; if ( $this->Application->GetVar('ajax') != 'yes' ) { - return ; + return; } - list ($object, $revision) = $this->getContentBlockAndRevision($event); + list (, $revision) = $this->getContentBlockAndRevision($event); /* @var $revision kDBItem */ $page_helper = $this->Application->recallObject('PageHelper'); - /* @var $page_helper PageHelper */ + /* @var $page_helper PageHelper */ - $time = $revision->GetField('AutoSavedOn'); + $time = $revision->GetField('AutoSavedOn'); - if ( $time ) { + if ( $time ) { - echo $time . ' (' . $page_helper->getAgoTime( $revision->GetDBField('AutoSavedOn') ) . ')'; + echo $time . ' (' . $page_helper->getAgoTime($revision->GetDBField('AutoSavedOn')) . ')'; - } + } } /** @@ -203,7 +209,7 @@ */ function loadFromRevision(&$object, &$revision) { - $load_keys = Array ( + $load_keys = Array( 'PageId' => $object->GetDBField('PageId'), 'ContentNum' => $object->GetDBField('ContentNum'), 'RevisionId' => $revision->GetID(), @@ -212,27 +218,34 @@ $object->Load($load_keys); } - function getContentBlockAndRevision($event) + /** + * Returns content block. + * + * @param kEvent $event + * + * @return kDBItem[] + */ + function getContentBlockAndRevision(kEvent $event) { - $object = $event->getObject( Array('skip_autoload' => true) ); + $object = $event->getObject(Array('skip_autoload' => true)); /* @var $object kDBItem */ - $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); + $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); if ( !$items_info ) { - return ; + return array(); } - list ($id, $field_values) = each($items_info); + list ($id,) = each($items_info); $object->Load($id); - $revision = $this->Application->recallObject('page-revision', null, Array ('skip_autoload' => true)); + $revision = $this->Application->recallObject('page-revision', null, Array('skip_autoload' => true)); /* @var $revision kDBItem */ - $revision->Load( $object->GetDBField('RevisionId') ); + $revision->Load($object->GetDBField('RevisionId')); if ( $this->Application->ConfigValue('EnablePageContentRevisionControl') && !$revision->GetDBField('IsDraft') ) { // editing live revision of a page's content block -> get draft for current user and page - $load_keys = Array ( + $load_keys = Array( 'PageId' => $revision->GetDBField('PageId'), 'IsDraft' => 1, 'CreatedById' => $this->Application->RecallVar('user_id'), @@ -255,6 +268,6 @@ } } - return Array (&$object, &$revision); + return Array(&$object, &$revision); } } \ No newline at end of file Index: core/units/helpers/fck_helper.php IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/units/helpers/fck_helper.php (revision 15892) +++ core/units/helpers/fck_helper.php (revision ) @@ -387,6 +387,220 @@ return substr( $fileName, 0, strrpos( $fileName, '.' ) ) ; } + public function CKEditorTag($editor_name, $editor_value, $params) + { + $editor = $this->prepareConfig($this->getEditor(), $params); + + $width = $this->normalizeDimension($params['width']); + $height = $this->normalizeDimension($params['height']); + + $editor->textareaAttributes = Array ( + 'style' => 'width: ' . $width . '; height: ' . $height . ';' + ); + + $editor->config['height'] = $height; // editor area height + + $events = Array ( + 'configLoaded' => 'function(ev) { CKEDITOR.addCss(ev.editor.config.extraCss); }', + ); + + return $editor->editor($editor_name, $editor_value, Array (), $events); + } + + public function CKEditorInlineTag($editor_name, $params) + { + $editor = $this->prepareConfig($this->getEditor(), $params); + + $events = Array ( + 'configLoaded' => 'function(ev) { CKEDITOR.addCss(ev.editor.config.extraCss); }', + 'focus' => 'function(ev) { $("body").trigger("InlineEditor.Focus", [ev]); }', + 'blur' => 'function(ev) { $("body").trigger("InlineEditor.Blur", [ev]); }', + ); + + return $editor->inline($editor_name, Array (), $events); + } + + /** + * Adds measurement units to editor dimensions. + * + * @param string $dimension Dimension. + * + * @return string + */ + protected function normalizeDimension($dimension) + { + if ( preg_match('/^[\d]+$/', $dimension) ) { + $dimension .= 'px'; + } + + return $dimension; + } + + /** + * Returns editor instance. + * + * @return CKEditor + */ + protected function getEditor() + { + include_once(FULL_PATH . EDITOR_PATH . 'ckeditor.php'); + $editor = new CKeditor(BASE_PATH . EDITOR_PATH); + $editor->returnOutput = true; + + return $editor; + } + + /** + * Prepares editor config. + * + * @param CKEditor $editor Editor. + * @param array $tag_params Tag params. + * + * @return CKEditor + */ + protected function prepareConfig(CKEditor $editor, array $tag_params) + { + $editor->lateLoad = array_key_exists('late_load', $tag_params) && $tag_params['late_load']; + + list($styles_css, $styles_js) = $this->getStyles(); + + if ( isset($tag_params['toolbar']) ) { + $toolbar = $tag_params['toolbar']; + } + elseif ( isset($tag_params['mode']) && $tag_params['mode'] == 'inline' ) { + $toolbar = 'Inline'; + } + else { + $toolbar = $this->Application->isDebugMode() ? 'DebugMode' : 'Default'; + } + + $editor->config = Array ( + 'toolbar' => $toolbar, + 'baseHref' => $this->Application->BaseURL( rtrim(EDITOR_PATH, '/') ), + 'customConfig' => $this->getJavaScriptConfig(), + 'stylesSet' => 'portal:' . $styles_js, + 'contentsCss' => $styles_css, + 'Admin' => 1, // for custom file browser to work + 'K4' => 1, // for custom file browser to work + 'language' => $this->getLanguage(), + ); + + $this->injectTransitParams($editor, $this->getTransitParams($tag_params)); + + return $editor; + } + + /** + * Transforms transit params into editor config. + * + * @param CKEditor $editor Editor. + * @param array $transit_params Transit params. + * + * @return void + */ + protected function injectTransitParams(CKEditor $editor, array $transit_params) + { + if ( isset($transit_params['bgcolor']) && $transit_params['bgcolor'] ) { + $editor->config['extraCss'] = 'body { background-color: ' . $transit_params['bgcolor'] . '; }'; + } + + foreach ($transit_params as $param_name => $param_value) { + if ( !$param_value ) { + continue; + } + + $param_key = str_replace(' ', '', ucwords(str_replace('_', ' ', $param_name))); + $param_key[0] = strtolower($param_key[0]); + + $editor->config[$param_key] = $param_value; + } + } + + /** + * Returns url to CSS and JS style configuration. + * + * @return array + */ + protected function getStyles() + { + $theme_path = $this->Application->GetFrontThemePath() . '/inc'; + + if ( file_exists(FULL_PATH . $theme_path . '/style.css') ) { + $url_params = Array ( + 'events[fck]' => 'OnGetsEditorStyles', + 'no_pass_through' => 1, 'pass' => 'm', 'no_amp' => 1 + ); + + $styles_css = $this->Application->HREF('index', '_FRONT_END_', $url_params, 'index.php'); + } + else { + $theme_path = rtrim(EDITOR_PATH, '/'); + $styles_css = $this->Application->BaseURL($theme_path) . 'style.css'; + } + + $styles_js = $this->Application->BaseURL($theme_path) . 'styles.js'; + + return array($styles_css, $styles_js); + } + + /** + * Returns url to JavaScript configuration file. + * + * @return string + */ + protected function getJavaScriptConfig() + { + if ( file_exists(SYSTEM_PRESET_PATH . DIRECTORY_SEPARATOR . 'inp_ckconfig.js') ) { + $file_helper = $this->Application->recallObject('FileHelper'); + /* @var $file_helper FileHelper */ + + return $file_helper->pathToUrl(SYSTEM_PRESET_PATH . DIRECTORY_SEPARATOR . 'inp_ckconfig.js'); + } + + return $this->Application->BaseURL() . 'core/admin_templates/js/inp_ckconfig.js'; + } + + /** + * Returns CKEditor locale, that matches default site language. + * + * @return string + */ + protected function getLanguage() + { + static $language_code = null; + + if ( !isset($language_code) ) { + $language_code = 'en'; // default value + + if ( $this->Application->isAdmin ) { + $language_id = $this->Application->Phrases->LanguageId; + } + else { + $language_id = $this->Application->GetDefaultLanguageId(); // $this->Application->GetVar('m_lang'); + } + + $sql = 'SELECT Locale + FROM ' . $this->Application->getUnitOption('lang', 'TableName') . ' + WHERE LanguageId = ' . $language_id; + $locale = strtolower($this->Conn->GetOne($sql)); + + if ( file_exists(FULL_PATH . EDITOR_PATH . 'editor/lang/' . $locale . '.js') ) { + // found language file, that exactly matches locale name (e.g. "en") + $language_code = $locale; + } + else { + $locale = explode('-', $locale); + + if ( file_exists(FULL_PATH . EDITOR_PATH . 'editor/lang/' . $locale[0] . '.js') ) { + // language file matches first part of locale (e.g. "ru-RU") + $language_code = $locale[0]; + } + } + } + + return $language_code; + } + /** * Returns transit parameters, that should be passed to every used CKEditor instance * \ No newline at end of file Index: admin/system_presets/simple/inp_ckconfig.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- admin/system_presets/simple/inp_ckconfig.js (revision 15892) +++ admin/system_presets/simple/inp_ckconfig.js (revision ) @@ -1,3 +1,5 @@ +CKEDITOR.config.title = ''; + /* * Append here extra CSS rules that should be applied into the editing area. * Example: @@ -20,8 +22,10 @@ //CKEDITOR.config.PluginsPath = CKEDITOR.config.BasePath + 'plugins/' ; -CKEDITOR.config.extraPlugins = 'my_link,my_document,my_maximize,MediaEmbed'; +CKEDITOR.config.entities = false; +CKEDITOR.config.extraPlugins = 'my_link,my_document,my_maximize,my_inline'; + //CKEDITOR.plugins.add('MySource'); //CKEDITOR.plugins.add('MyPreview'); //CKEDITOR.plugins.add('MyLink'); @@ -36,7 +40,7 @@ ['Styles'], ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'], - ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'], + ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Image', 'Document', 'MediaEmbed', 'Link', '-', 'Undo', 'Redo'], ['Find', 'Replace', 'Scayt'] ]; @@ -48,6 +52,23 @@ ['Styles','Font','FontSize','RemoveFormat','-','Scayt','-', /*My*/'Source', 'Maximize', 'ShowBlocks'] ]; +CKEDITOR.config.toolbar_Inline = [ + ['InlineSave', 'InlineCancel'], + ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Image', 'Document', 'MediaEmbed', 'Link', '-', 'Undo', 'Redo'], + ['Find', 'Replace', 'Scayt'], + '/', + ['Styles'], ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], + ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'] +]; + +/*CKEDITOR.config.toolbar_Simple = [ + ['Styles'], + ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat'], + ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'], + ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'], + ['Find', 'Replace', 'Scayt'] +];*/ + //CKEDITOR.config.toolbar_Full = [ // [ 'Source','-','Save','NewPage','DocProps','Preview','Print','-','Templates' ], // [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ], @@ -67,28 +88,28 @@ CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR ; // p | div | br CKEDITOR.config.shiftEnterMode = CKEDITOR.ENTER_P ; // p | div | br -CKEDITOR.config.keystrokes = [ - [ CKEDITOR.CTRL + 65 /*A*/, true ], - [ CKEDITOR.CTRL + 67 /*C*/, true ], - [ CKEDITOR.CTRL + 70 /*F*/, true ], - [ CKEDITOR.CTRL + 83 /*S*/, true ], - [ CKEDITOR.CTRL + 84 /*T*/, true ], - [ CKEDITOR.CTRL + 88 /*X*/, true ], - [ CKEDITOR.CTRL + 86 /*V*/, 'Paste' ], - [ CKEDITOR.CTRL + 45 /*INS*/, true ], - [ CKEDITOR.SHIFT + 45 /*INS*/, 'Paste' ], - [ CKEDITOR.CTRL + 88 /*X*/, 'Cut' ], - [ CKEDITOR.SHIFT + 46 /*DEL*/, 'Cut' ], - [ CKEDITOR.CTRL + 90 /*Z*/, 'Undo' ], - [ CKEDITOR.CTRL + 89 /*Y*/, 'Redo' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, 'Redo' ], - [ CKEDITOR.CTRL + 76 /*L*/, 'Link' ], - [ CKEDITOR.CTRL + 66 /*B*/, 'Bold' ], - [ CKEDITOR.CTRL + 73 /*I*/, 'Italic' ], - [ CKEDITOR.CTRL + 85 /*U*/, 'Underline' ], - [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 83 /*S*/, 'Save' ], - [ CKEDITOR.CTRL + CKEDITOR.ALT + 13 /*ENTER*/, 'FitWindow' ] -] ; +/*CKEDITOR.config.keystrokes = [ + [ CKEDITOR.CTRL + 65 *//*A*//*, true ], + [ CKEDITOR.CTRL + 67 *//*C*//*, true ], + [ CKEDITOR.CTRL + 70 *//*F*//*, true ], + [ CKEDITOR.CTRL + 83 *//*S*//*, true ], + [ CKEDITOR.CTRL + 84 *//*T*//*, true ], + [ CKEDITOR.CTRL + 88 *//*X*//*, true ], + [ CKEDITOR.CTRL + 86 *//*V*//*, 'Paste' ], + [ CKEDITOR.CTRL + 45 *//*INS*//*, true ], + [ CKEDITOR.SHIFT + 45 *//*INS*//*, 'Paste' ], + [ CKEDITOR.CTRL + 88 *//*X*//*, 'Cut' ], + [ CKEDITOR.SHIFT + 46 *//*DEL*//*, 'Cut' ], + [ CKEDITOR.CTRL + 90 *//*Z*//*, 'Undo' ], + [ CKEDITOR.CTRL + 89 *//*Y*//*, 'Redo' ], + [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 *//*Z*//*, 'Redo' ], + [ CKEDITOR.CTRL + 76 *//*L*//*, 'Link' ], + [ CKEDITOR.CTRL + 66 *//*B*//*, 'Bold' ], + [ CKEDITOR.CTRL + 73 *//*I*//*, 'Italic' ], + [ CKEDITOR.CTRL + 85 *//*U*//*, 'Underline' ], + [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 83 *//*S*//*, 'Save' ], + [ CKEDITOR.CTRL + CKEDITOR.ALT + 13 *//*ENTER*//*, 'FitWindow' ] +] ;*/ //CKEDITOR.config.menu_groups = 'generic,anchor,flash,select,textarea,checkbox,radio,textfield,hiddenfield,imagebutton,button,bulletedlist,numberedlist,table,form'; Index: core/admin_templates/categories/edit_content.tpl IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/admin_templates/categories/edit_content.tpl (revision 15892) +++ core/admin_templates/categories/edit_content.tpl (revision ) @@ -1,7 +1,6 @@ - \ No newline at end of file Index: core/admin_templates/js/template_manager.js IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/admin_templates/js/template_manager.js (revision 15892) +++ core/admin_templates/js/template_manager.js (revision ) @@ -1,231 +1,268 @@ function TemplateManager ( $settings ) { + this.languagePrefix = ''; this.pageId = 0; this.editUrl = ''; this.browseUrl = ''; this.saveLayoutUrl = ''; + this.saveContentUrl = ''; this.editingMode = 0; // from {1 - browse, 2 - content, 3 - design} this.pageInfo = {editors: [], revisions: {}}; // information about page in "Content Mode" + this.pageInfoUpdateTimer = null; + this.revisionStatusMap = { + 1: 'cms-revision-published', + 2: 'cms-revision-pending', + 0: 'cms-revision-declined' + }; + this._blocks = {}; - this._blockOrder = Array (); + this._blockOrder = []; this.inDrag = false; // don't process mouse over/out events while in drag mode $.extend(this, $settings); - var $template_manager = this; + var $me = this; - $(document).ready( - function() { - $template_manager.searchBlocks(); + $(document).ready(function() { + $me.init(); + }); +} - if (!$template_manager.editingMode) { +TemplateManager.prototype.init = function () { + this.searchBlocks(); + + if ( !this.editingMode ) { - return ; + return; - } + } - // show special toolbar when in any of 3 browse modes + // show special toolbar when in any of 3 browse modes - var $head_frame = getFrame('head'); - var $extra_toolbar = $head_frame.$('div.front-extra-toolbar').clone(); // clone to keep original untouched + var $template_manager = this, + $head_frame = getFrame('head'), + $extra_toolbar = $head_frame.$('div.front-extra-toolbar').clone(); // clone to keep original untouched - $('a', $extra_toolbar).each( - function() { + $('a', $extra_toolbar).each(function () { - // cut from end, because IE7 adds base_href to beginning of href - var $editing_mode = $(this).attr('href'); - $editing_mode = $editing_mode.substr($editing_mode.length - 1, 1); + // cut from end, because IE7 adds base_href to beginning of href + var $editing_mode = $(this).attr('href'); + $editing_mode = $editing_mode.substr($editing_mode.length - 1, 1); - $(this).attr('href', $template_manager.browseUrl.replace('#EDITING_MODE#', $editing_mode)); + $(this).attr('href', $template_manager.browseUrl.replace('#EDITING_MODE#', $editing_mode)); - if ($editing_mode == $template_manager.editingMode) { + if ( $editing_mode == $template_manager.editingMode ) { - $(this).parents('td:first').addClass('button-active').prevAll('td:first').addClass('button-active'); - } + $(this).parents('td:first').addClass('button-active').prevAll('td:first').addClass('button-active'); + } - } - ); + }); - $head_frame.$('#extra_toolbar').html( $extra_toolbar.html() ); + $head_frame.$('#extra_toolbar').html($extra_toolbar.html()); - var $hover_effect = []; + var $hover_effect = []; - if ($template_manager.editingMode > 1) { + if ( $template_manager.editingMode > 1 ) { - // all modes except for "Browse Mode" + // all modes except for "Browse Mode" -// $hover_effect.push('div.cms-section-properties-btn:first'); +// $hover_effect.push('div.cms-section-properties-btn:first'); - } + } - if ($template_manager.editingMode == 2) { + if ( $template_manager.editingMode == 2 ) { - // Content Mode + // Content Mode -// $hover_effect.push('div.cms-edit-btn'); +// $hover_effect.push('div.cms-edit-btn'); -// $hover_effect.push('div.admin-edit-btn'); +// $hover_effect.push('div.admin-edit-btn'); - // make all spans with phrases clickable - $template_manager.setupEditTranslationButtons(document); + // make all spans with phrases clickable + $template_manager.setupEditTranslationButtons(document); - // hide "Revision History" div on every body click (bubbled), but not a "toolbar button", that opens it + // hide "Revision History" div on every body click (bubbled), but not a "toolbar button", that opens it - $('body').click( - function ($e) { + $('body').click(function ($e) { - var $target = $($e.target), - $id = $target.attr('id'); + var $target = $($e.target), + $id = $target.attr('id'); - if ( $id && ($id == 'div_history' || $target.parent().attr('id') == 'div_history') ) { + if ( $id && ($id == 'div_history' || $target.parent().attr('id') == 'div_history') ) { - return ; + return; - } + } - $('#cms-revision-dropdown:visible').hide(); + $('#cms-revision-dropdown:visible').hide(); + }); - } + } - ); - } - if ($template_manager.editingMode == 3) { + if ( $template_manager.editingMode == 3 ) { - // Design Mode + // Design Mode -// $hover_effect.push('div.cms-save-layout-btn:first, div.cms-cancel-layout-btn:first'); +// $hover_effect.push('div.cms-save-layout-btn:first, div.cms-cancel-layout-btn:first'); - $template_manager.renumberMovableElements(); + $template_manager.renumberMovableElements(); - $('div.movable-area').sortable( - { + $('div.movable-area').sortable({ - placeholder: 'move-helper', - handle: '.movable-header', - items: 'div.movable-element', - connectWith: ['div.movable-area'], - tolerance: 'pointer', + placeholder: 'move-helper', + handle: '.movable-header', + items: 'div.movable-element', + connectWith: ['div.movable-area'], + tolerance: 'pointer', - start: function(e, ui) { + start: function (e, ui) { - $template_manager.inDrag = true; + $template_manager.inDrag = true; - ui.placeholder.height( ui.item.height() ); + ui.placeholder.height(ui.item.height()); - }, + }, - stop: function(e, ui) { + stop: function (e, ui) { - $template_manager.inDrag = false; + $template_manager.inDrag = false; - // mouseout doesn't happen while in drag, so compensate it here - var $header = $('.movable-header', ui.item); - $('div.block-edit-block-btn-container', $header).mouseout(); - }, + // mouseout doesn't happen while in drag, so compensate it here + var $header = $('.movable-header', ui.item); + $('div.block-edit-block-btn-container', $header).mouseout(); + }, - change: function(e, ui) { + change: function (e, ui) { - $('div.cms-layout-btn-container').show(); - } + $('div.cms-layout-btn-container').show(); + } + }); - } + } - ); - } - // make requested elements fully visible on mouseover - if ( $hover_effect.length ) { - $($hover_effect.join(', ')) + // make requested elements fully visible on mouseover + if ( $hover_effect.length ) { + $($hover_effect.join(', ')) - .mouseover( - function(e) { + .mouseover(function (e) { - $(this).css('opacity', 1); + $(this).css('opacity', 1); - } - ) - .mouseout( - function(e) { + }) + .mouseout(function (e) { - $(this).css('opacity', 0.5); + $(this).css('opacity', 0.5); + }); - } + } - ); - } - // related to content revision control toolbar + // related to content revision control toolbar - $('#cms-toggle-revision-toolbar').click( - function ($e) { + if ( $template_manager.revisionToolbarEnabled() ) { + $template_manager.initRevisionToolbar(); + } + + $('body') + .bind('InlineEditor.Focus', function ($e, $editor_event) { + $template_manager.inlineEditorFocus($editor_event); + }) + .bind('InlineEditor.Blur', function ($e, $editor_event) { + $template_manager.inlineEditorBlur($editor_event); + }); +}; + +TemplateManager.prototype.revisionToolbarEnabled = function () { + return $('#cms-revision-toolbar-layer').length == 1; +}; + +TemplateManager.prototype.initRevisionToolbar = function () { + var $template_manager = this; + + $('#cms-toggle-revision-toolbar').click(function ($e) { - var $me = $(this); + var $me = $(this); - if ( $me.hasClass('opened') ) { - var $height = $('#cms-revision-toolbar').height(); + if ( $me.hasClass('opened') ) { + var $height = $('#cms-revision-toolbar').height(); - $('#cms-revision-toolbar-layer').animate({top: (-1) * $height}, 'fast'); - $('#cms-editing-notice, #cms-revision-dropdown').hide(); - setCookie('toolbar_hidden', 1); - } - else { - $('#cms-revision-toolbar-layer').animate({top: 0}, 'fast'); - setCookie('toolbar_hidden', 0); - } + $('#cms-revision-toolbar-layer').animate({top: (-1) * $height}, 'fast'); + $('#cms-editing-notice, #cms-revision-dropdown').hide(); + setCookie('toolbar_hidden', 1); + } + else { + $('#cms-revision-toolbar-layer').animate({top: 0}, 'fast'); + setCookie('toolbar_hidden', 0); + } - $me.toggleClass('opened'); + $me.toggleClass('opened'); - return false; - } - ); + $e.preventDefault(); + }); - $('#cms-close-toolbar').click( - function () { + $('#cms-close-toolbar').click(function ($e) { - var $height = $('#cms-revision-toolbar').height(); + var $height = $('#cms-revision-toolbar').height(); - $('#cms-toggle-revision-toolbar').removeClass('opened'); - $('#cms-revision-toolbar-layer').css('top', (-1) * $height); + $('#cms-toggle-revision-toolbar').removeClass('opened'); + $('#cms-revision-toolbar-layer').css('top', (-1) * $height); - $('#cms-editing-notice, #cms-revision-dropdown').hide(); - setCookie('toolbar_hidden', 1); + $('#cms-editing-notice, #cms-revision-dropdown').hide(); + setCookie('toolbar_hidden', 1); - return false; - } - ); + $e.preventDefault(); + }); - $('#cms-close-editing-notice').click( - function () { + $('#cms-close-editing-notice').click(function ($e) { - $('#cms-editing-notice').hide(); + $('#cms-editing-notice').hide(); - return false; + $e.preventDefault(); + }); + + $('body').on('click', '#cms-revision-dropdown .top .item', function ($e) { + $('a:first', this).click(); + + $e.preventDefault(); + }); + + $template_manager.requirePageInfoUpdate(); + + if ( !$.isEmptyObject($template_manager.pageInfo) ) { + $template_manager.processPageInfo(); - } + } - ); +}; - $('.toolbar-button', '#cms-revision-toolbar').click( - function ($e) { - var $button_name = $(this).attr('id').replace(/^(tool|div)_/, ''); +TemplateManager.prototype.requirePageInfoUpdate = function ($now) { + var $me = this; - $template_manager.revisionToolbarClick($button_name); + if ( $now === undefined || $now === false ) { + clearTimeout(this.pageInfoUpdateTimer); + this.pageInfoUpdateTimer = setInterval(function () { $me.requirePageInfoUpdate(true); }, 20 * 1000); // 20 seconds + + return; - } + } - ); - setInterval( - function () { - $.getJSON( + $.getJSON( - $('#kf_revisions_' + $template_manager.pageId).attr('action') + '&events[page-revision]=OnGetInfo', + $('#kf_revisions_' + this.pageId).attr('action') + '&events[page-revision]=OnGetInfo', - function ($data) { + function ($data) { - $template_manager.pageInfo = $data; - $template_manager.processPageInfo(); + $me.pageInfo = $data; + $me.processPageInfo(); - } - ); + } + ); - }, 20 * 1000 // 20 seconds - ); +}; - if ( !$.isEmptyObject($template_manager.pageInfo) ) { - $template_manager.processPageInfo(); +TemplateManager.prototype.processPageInfo = function () { + this.updateCurrentRevision(); + + if ( $('#cms-toggle-revision-toolbar').hasClass('opened') ) { + this.showEditingNotice(); - } + } - } - ); -} -TemplateManager.prototype.processPageInfo = function () { - var $class_mapping = { - 1: 'cms-revision-published', - 2: 'cms-revision-pending', - 0: 'cms-revision-declined' + this.updateRevisionHistory(); - }; +}; - var $title = $('.revision-title', '#cms-current-revision-info'); +TemplateManager.prototype.updateCurrentRevision = function () { + var $me = this, + $title = $('.revision-title', '#cms-current-revision-info'); - $title.html( this.pageInfo.current_revision.title ); + $title.html(this.pageInfo.current_revision.title); - $('.draft-saved', '#cms-current-revision-info').html( this.pageInfo.current_revision.saved ); + $('.draft-saved', '#cms-current-revision-info').html(this.pageInfo.current_revision.saved); - for (var $status in $class_mapping) { - $title.toggleClass( $class_mapping[$status], $status === this.pageInfo.current_revision.status ); - } + $.each(this.revisionStatusMap, function ($status, $class_name) { + $title.toggleClass($class_name, $status === $me.pageInfo.current_revision.status); + }); - if ( $('#cms-toggle-revision-toolbar').hasClass('opened') ) { + $.each(this.pageInfo.current_revision.toolbar_state, function ($button_name, $is_enabled) { + a_toolbar.SetEnabled($button_name, $is_enabled); + }); +}; + +TemplateManager.prototype.showEditingNotice = function () { - var $notice = $('#cms-editing-notice'); + var $notice = $('#cms-editing-notice'); - if ( this.pageInfo.editors.length ) { + if ( this.pageInfo.editors.length ) { - if ( $('span:first', $notice).attr('prev_editors') != this.pageInfo.editors.join(',') ) { + var $notice_span = $('span:first', $notice); + + if ( $notice_span.data('prev_editors') != this.pageInfo.editors.join(',') ) { - // show notice, only when editors change occurs + // show notice, only when editors change occurs - $('span:first', $notice).html(this.pageInfo.editors_warning).attr('prev_editors', this.pageInfo.editors.join(',')); + $notice_span.html(this.pageInfo.editors_warning).data('prev_editors', this.pageInfo.editors.join(',')); - if ( $notice.is(':hidden') ) { - $notice.fadeIn(); - } - } - } - else if ( $notice.is(':visible') ) { - $notice.fadeOut(); - } + if ( $notice.is(':hidden') ) { + $notice.fadeIn(); + } + } + } + else if ( $notice.is(':visible') ) { + $notice.fadeOut(); + } - } +}; - var $revision_container = $('.top', '#cms-revision-dropdown'), +TemplateManager.prototype.updateRevisionHistory = function () { + var $me = this, + $revision_container = $('.top', '#cms-revision-dropdown'), $revision_mask = '
\ {TITLE} ({STATUS_LABEL})\
{DATETIME}
\ @@ -236,48 +273,69 @@ $revision_container.empty(); if ( $.isArray(this.pageInfo.revisions) ) { - // no revisions yet + return; } - else { - for (var $revision in this.pageInfo.revisions) { - var $html = $revision_mask, - $revision_info = this.pageInfo.revisions[$revision]; - for (var $field in $revision_info) { - $html = $html.replace( new RegExp('{' + $field.toUpperCase() + '}', 'g'), $revision_info[$field] ); - } + $.each(this.pageInfo.revisions, function ($revision_number, $revision_info) { + var $html = $revision_mask; - $html = $html.replace(/{CLASS}/g, $class_mapping[$revision_info.status] ); + $.each($revision_info, function ($field, $value) { + $html = $html.replace(new RegExp('{' + $field.toUpperCase() + '}', 'g'), $value); + }); + $html = $html.replace(/{CLASS}/g, $me.revisionStatusMap[$revision_info.status]); + - if ( $revision_info['draft'] ) { + if ( $revision_info['draft'] ) { - $html = $html.replace(/{LINK}/g, this.browseUrl.replace('#EDITING_MODE#', 2) ); + $html = $html.replace(/{LINK}/g, $me.browseUrl.replace('#EDITING_MODE#', '2')); - } - else { + } + else { - $html = $html.replace(/{LINK}/g, this.browseUrl.replace('#EDITING_MODE#', 2) + '&revision=' + $revision.substr(1) ); + $html = $html.replace(/{LINK}/g, $me.browseUrl.replace('#EDITING_MODE#', '2') + '&revision=' + $revision_number.substr(1)); - } + } - $revision_container.append($html); + $revision_container.append($html); + }); +}; + +TemplateManager.prototype.inlineEditorFocus = function ($editor_event) { + var $container = $($editor_event.editor.element.$).parent('.cms-edit-btn-container'); + + $container.removeClass('mode-inline-edit'); +}; + +TemplateManager.prototype.inlineEditorBlur = function ($editor_event) { + var $me = this, + $element = $($editor_event.editor.element.$), + $container = $element.parent('.cms-edit-btn-container'), + $url_params = {}, + $content_id = $container.data('content-id'); + + if ( $element.data('no_save_on_blur') === true ) { + $element.data('no_save_on_blur', null); + return; - } + } - $('.item', '#cms-revision-dropdown .top').each( - function () { - var $row = $(this); + $element.css('position', 'static'); + $container.addClass('mode-inline-saving'); - $('a:first', $row).click( - function ($e) { - $e.stopPropagation(); + $url_params["content[" + $content_id + "][" + this.languagePrefix + "Content]"] = $editor_event.editor.getData(); + + $.post( + this.saveContentUrl, + $url_params, + function ($data) { + if ( $data != 'OK' ) { + return; - } + } - ); - $row.click( - function ($e) { - window.location.href = $('a:first', this).attr('href'); + if ( $me.revisionToolbarEnabled() ) { + $me.requirePageInfoUpdate(true); - } + } - ); + + $element.css('position', 'relative'); + $container.removeClass('mode-inline-saving').addClass('mode-inline-edit'); - } - ); + } + ); - } -} +}; TemplateManager.prototype.revisionToolbarClick = function ($button_name) { // console.log('button ', $button_name, ' clicked'); @@ -293,113 +351,105 @@ $form_name = 'kf_revisions_' + this.pageId; submit_event('page-revision', $button_event_map[$button_name]); - return ; + return; } switch ( $button_name ) { case 'preview': var $url = this.browseUrl.replace('#EDITING_MODE#', 0).replace(/&(admin|editing_mode)=[\d]/g, ''); - window.open( $url + '&preview=1' ); + window.open($url + '&preview=1'); break; case 'history': $('#cms-revision-dropdown').toggle(); break; } -} +}; TemplateManager.prototype.setupEditTranslationButtons = function ($container) { - $("span[name='cms-translate-phrase']", $container).each( - function() { - var $me = $(this); - var $parent_link = $me.parents('a:first'); + $("span[name='cms-translate-phrase']", $container).each(function() { + var $me = $(this), + $parent_link = $me.parents('a:first'); - if ($parent_link.length == 0) { + if ( $parent_link.length == 0 ) { - // span in not inside "a" tag + // span in not inside "a" tag - - $me.prepend('
Edit
'); - $('div.cms-edit-btn:first', $me).click(TemplateManager.prototype.translatePhrase); + $me.prepend('
Edit
'); + $('div.cms-edit-btn:first', $me).click(TemplateManager.prototype.translatePhrase); - $me.dblclick( - function ($e) { + + $me.dblclick(function ($e) { - $('div.cms-edit-btn:first', this).click(); + $('div.cms-edit-btn:first', this).click(); - return false; - } - ); + $e.preventDefault(); + }); + - var $effect_element = $me; - } - else { - // span is inside "a" tag - var $clone = $me.clone(); - $clone.empty().attr('title', ''); + var $effect_element = $me; + } + else { + // span is inside "a" tag + var $clone = $me.clone(); + $clone.empty().attr('title', ''); - // in case if "a" tag is "display: block", then make "span" the same - $clone.css('display', $parent_link.css('display')); + // in case if "a" tag is "display: block", then make "span" the same + $clone.css('display', $parent_link.css('display')); - $parent_link.html( $me.html() ).wrap($clone); + $parent_link.html($me.html()).wrap($clone); - $parent_link.before('
Edit
'); - $parent_link.prev('div.cms-edit-btn:first').click(TemplateManager.prototype.translatePhrase); + $parent_link.before('
Edit
'); + $parent_link.prev('div.cms-edit-btn:first').click(TemplateManager.prototype.translatePhrase); - var $effect_element = $parent_link.parents("span[name='cms-translate-phrase']:first"); - } + var $effect_element = $parent_link.parents("span[name='cms-translate-phrase']:first"); + } - $effect_element + $effect_element - .mouseover( - function($e) { + .mouseover(function($e) { - $('div.cms-edit-btn', this).css('display', 'inline'); + $('div.cms-edit-btn', this).css('display', 'inline'); - } - ) - .mouseout( - function($e) { + }) + .mouseout(function($e) { - $('div.cms-edit-btn', this).hide(); + $('div.cms-edit-btn', this).hide(); - } - ); - } - ); -} + }); + }); +}; TemplateManager.prototype.translatePhrase = function ($e) { var $translate_url = $(this).parents("span[name='cms-translate-phrase']:first").attr('href'); - if ($translate_url.match(/javascript:(.*)/)) { + if ( $translate_url.match(/javascript:(.*)/) ) { eval(RegExp.$1); } else { window.location.href = $translate_url; } - return false; -} + $e.preventDefault(); +}; TemplateManager.prototype.renumberMovableElements = function () { var $area_index = 0; + // 1. dynamically assign IDs to all movable elements - $('div.movable-area').each( - function() { + $('div.movable-area').each(function () { - var $element_index = 0; + var $element_index = 0; - $('div.movable-element', this).each( - function() { + + $('div.movable-element', this).each(function () { - $(this).attr('id', 'target_order_a' + $area_index + 'e' + $element_index); - $element_index++; + $(this).attr('id', 'target_order_a' + $area_index + 'e' + $element_index); + $element_index++; - } - ); + }); - $area_index++; + $area_index++; - } - ); -} + }); +}; TemplateManager.prototype.saveLayout = function () { // prepare order string var $sort_order = []; - $('div.movable-area').each( - function($area_index) { + + $('div.movable-area').each(function ($area_index) { - var $order = $(this).sortable('serialize').replace(/target_order\[\]/g, 'target_order[' + $area_index + '][]'); + var $order = $(this).sortable('serialize').replace(/target_order\[\]/g, 'target_order[' + $area_index + '][]'); + - if ($order) { + if ( $order ) { - $sort_order.push($order); - } + $sort_order.push($order); + } - } - ); + }); + $sort_order = $sort_order.join('&'); // save order string @@ -411,7 +461,7 @@ onDataReceived: function ($data) { var $message = ''; - if ($data == 'OK') { + if ( $data == 'OK' ) { $message = 'New Layout Saved'; $('div.cms-layout-btn-container').hide(); $me.renumberMovableElements(); @@ -426,13 +476,13 @@ } }; - TB.setWindowTitle( window.top.document.title.replace(main_title + ' :: ', '') ); + TB.setWindowTitle(window.top.document.title.replace(main_title + ' :: ', '')); TB.show($settings); -} +}; TemplateManager.prototype.cancelLayout = function () { window.location.href = window.location.href; -} +}; TemplateManager.prototype.onBtnClick = function ($e, $element) { var $id = $element.id.replace(/_btn$/, ''); @@ -442,20 +492,21 @@ direct_edit('theme-file', $url); $e.stopPropagation(); -} +}; TemplateManager.prototype.onMouseOver = function ($e, $element) { - if (this.inDrag) { + if ( this.inDrag ) { - return ; + return; } $element = $($element); - if ($element.hasClass('block-edit-design-btn-container')) { + if ( $element.hasClass('block-edit-design-btn-container') ) { $($element).addClass('block-edit-design-btn-container-over'); var $button_group = $('div.cms-edit-design-btn-container:first', $element); + - if ($button_group.length) { + if ( $button_group.length ) { $button_group.show(); } else { @@ -468,20 +519,21 @@ } $e.stopPropagation(); -} +}; TemplateManager.prototype.onMouseOut = function ($e, $element) { - if (this.inDrag) { + if ( this.inDrag ) { - return ; + return; } $element = $($element); - if ($element.hasClass('block-edit-design-btn-container')) { + if ( $element.hasClass('block-edit-design-btn-container') ) { $($element).removeClass('block-edit-design-btn-container-over'); var $button_group = $('div.cms-edit-design-btn-container:first', $element); + - if ($button_group.length) { + if ( $button_group.length ) { $button_group.hide(); } else { @@ -494,61 +546,55 @@ } $e.stopPropagation(); -} +}; TemplateManager.prototype.searchBlocks = function () { var $design_containers = $('div.block-edit-design-btn-container'); var $block_containers = $('div.block-edit-block-btn-container'); - $design_containers.each( - function() { + $design_containers.each(function () { - var $block_container = $('div.block-edit-block-btn-container:first', this); + var $block_container = $('div.block-edit-block-btn-container:first', this); - if ($block_container.length) { + if ( $block_container.length ) { - $block_containers = $block_containers.not($block_container); + $block_containers = $block_containers.not($block_container); - // place "Edit Block" button near "Edit Design" button - var $edit_design_btn = $('.cms-edit-design-btn:first', this); - var $edit_block_btn = $('.cms-edit-block-btn:first', $block_container); + // place "Edit Block" button near "Edit Design" button + var $edit_design_btn = $('.cms-edit-design-btn:first', this); + var $edit_block_btn = $('.cms-edit-block-btn:first', $block_container); - $edit_design_btn - .wrap('
') + $edit_design_btn + .wrap('
') - .before( $edit_block_btn.clone() ); + .before($edit_block_btn.clone()); - $edit_block_btn.remove(); + $edit_block_btn.remove(); - // make "hint" from "Edit Block" button container main - $(this).attr('title', $block_container.attr('title')); - $block_container.attr('title', ''); + // make "hint" from "Edit Block" button container main + $(this).attr('title', $block_container.attr('title')); + $block_container.attr('title', ''); - TemplateManager.prototype.registerBlock.call(aTemplateManager, $block_container.get(0), ['hover']); - } + TemplateManager.prototype.registerBlock.call(aTemplateManager, $block_container.get(0), ['hover']); + } - TemplateManager.prototype.registerBlock.call(aTemplateManager, this, ['dblclick']); + TemplateManager.prototype.registerBlock.call(aTemplateManager, this, ['dblclick']); - } - ); + }); - $block_containers.each( - function() { + $block_containers.each(function() { - TemplateManager.prototype.registerBlock.call(aTemplateManager, this); + TemplateManager.prototype.registerBlock.call(aTemplateManager, this); - } - ); + }); -// $('div').each ( -// function () { -// /*var $id = $(this).attr('id'); -// -// if (!$id || $id.match(/parser_block\[.*\].*_btn$/) || !$id.match(/parser_block\[.*\]/)) { -// // skip other divs -// return true; -// }*/ -// -// -// TemplateManager.prototype.registerBlock.call(aTemplateManager, this); -// } -// ); -} + /*$('div').each (function () { + *//*var $id = $(this).attr('id'); + if ( !$id || $id.match(/parser_block\[.*\].*_btn$/) || !$id.match(/parser_block\[.*\]/) ) { + // skip other divs + return true; + }*//* + + + TemplateManager.prototype.registerBlock.call(aTemplateManager, this); + });*/ +}; + TemplateManager.prototype.registerBlock = function ($element, $skip_events) { var $params = $element.getAttribute('params').split(':'); @@ -559,38 +605,29 @@ var $btn = document.getElementById($element.id + '_btn'); - $($btn).click( - function(ev) { + $($btn).click(function (ev) { - TemplateManager.prototype.onBtnClick.call(aTemplateManager, ev, this); + TemplateManager.prototype.onBtnClick.call(aTemplateManager, ev, this); - } - ); + }); - if ($skip_events === undefined) { + if ( $skip_events === undefined ) { $skip_events = []; } - if (!in_array('dblclick', $skip_events)) { + if ( !in_array('dblclick', $skip_events) ) { - $($element) - .dblclick( - function(ev) { + $($element).dblclick(function (ev) { - TemplateManager.prototype.onBtnClick.call(aTemplateManager, ev, this); + TemplateManager.prototype.onBtnClick.call(aTemplateManager, ev, this); + }); - } + } - ) - } - if (!in_array('hover', $skip_events)) { + if ( !in_array('hover', $skip_events) ) { $($element) - .mouseover( - function(ev) { + .mouseover(function (ev) { - TemplateManager.prototype.onMouseOver.call(aTemplateManager, ev, this); + TemplateManager.prototype.onMouseOver.call(aTemplateManager, ev, this); - } - ) - .mouseout( - function(ev) { + }) + .mouseout(function (ev) { - TemplateManager.prototype.onMouseOut.call(aTemplateManager, ev, this); + TemplateManager.prototype.onMouseOut.call(aTemplateManager, ev, this); + }); - } + } - ); - } this._blockOrder.push($element.id); -} \ No newline at end of file +}; \ No newline at end of file Index: core/admin_templates/incs/cms.css IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- core/admin_templates/incs/cms.css (revision 15892) +++ core/admin_templates/incs/cms.css (revision ) @@ -14,6 +14,7 @@ div.cms-btn-content { padding: 5px; + min-height: 15px; } .cms-edit-btn { @@ -94,7 +95,32 @@ } div.cms-edit-btn-container { + position: relative; border: 1px dashed #FF6E00; +} + +.cms-edit-btn-container[data-content-id] .cms-btn-content { padding: 0; min-height: 25px; } +.cms-edit-btn-container .inline-edit-layer, .cms-edit-btn-container .inline-saving-layer { display: none; } + +.cms-edit-btn-container.mode-inline-edit .inline-edit-layer { display: block; } + +.cms-edit-btn-container .inline-edit-layer { + position: absolute; + background: url(@templates_base@/img/top_frame/icons/content_mode.png) center no-repeat; + width: 20px; + height: 20px; + top: 0px; + right: 0px; +} + +.cms-edit-btn-container.mode-inline-saving .inline-saving-layer { display: block; } + +.cms-edit-btn-container .inline-saving-layer { + position: absolute; + background: url(@templates_base@/img/top_frame/icons/saving_indicator.gif) no-repeat 100% 0px rgba(255, 255, 255, .9); + width: 100%; + top: 0px; + bottom: 0px; } div.cms-edit-btn { \ No newline at end of file