001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ade.containerpage.client; 029 030import org.opencms.ade.containerpage.client.CmsContainerpageController.I_ReloadHandler; 031import org.opencms.ade.containerpage.client.ui.CmsContainerPageContainer; 032import org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel; 033import org.opencms.ade.containerpage.client.ui.CmsOptionDialog; 034import org.opencms.ade.containerpage.client.ui.I_CmsDropContainer; 035import org.opencms.ade.containerpage.shared.CmsCntPageData; 036import org.opencms.ade.containerpage.shared.CmsDialogOptionsAndInfo; 037import org.opencms.ade.contenteditor.client.CmsContentEditor; 038import org.opencms.ade.contenteditor.client.CmsEditorContext; 039import org.opencms.ade.contenteditor.client.I_CmsEditorCloseHandler; 040import org.opencms.ade.contenteditor.shared.CmsContentDefinition; 041import org.opencms.ade.contenteditor.shared.CmsEditHandlerData; 042import org.opencms.ade.publish.shared.CmsPublishOptions; 043import org.opencms.gwt.client.CmsCoreProvider; 044import org.opencms.gwt.client.CmsEditableData; 045import org.opencms.gwt.client.I_CmsEditableData; 046import org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog; 047import org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog.DialogOptions; 048import org.opencms.gwt.client.ui.contenteditor.I_CmsContentEditorHandler; 049import org.opencms.gwt.client.util.CmsDebugLog; 050import org.opencms.gwt.client.util.CmsDomUtil; 051import org.opencms.gwt.client.util.I_CmsSimpleCallback; 052import org.opencms.gwt.shared.CmsGwtConstants; 053import org.opencms.util.CmsStringUtil; 054import org.opencms.util.CmsUUID; 055 056import java.util.ArrayList; 057import java.util.HashMap; 058import java.util.List; 059import java.util.Map; 060 061import com.google.gwt.dom.client.Element; 062import com.google.gwt.http.client.URL; 063import com.google.gwt.json.client.JSONBoolean; 064import com.google.gwt.json.client.JSONNumber; 065import com.google.gwt.json.client.JSONObject; 066import com.google.gwt.json.client.JSONString; 067import com.google.gwt.user.client.Command; 068import com.google.gwt.user.client.History; 069import com.google.gwt.user.client.Window; 070 071import jsinterop.base.Js; 072 073/** 074 * The container-page editor implementation of the XML content editor handler.<p> 075 * 076 * @since 8.0.0 077 */ 078public class CmsContentEditorHandler implements I_CmsContentEditorHandler { 079 080 /** Content editor hash key whre a return to the opened editor is not possible. */ 081 private static final String EDITOR_FOR_NO_RETURN_HASH_KEY = "cE"; 082 083 /** Content editor hash key used for history management. */ 084 private static final String EDITOR_HASH_KEY = "cE:"; 085 086 /** The container-page handler. */ 087 CmsContainerpageHandler m_handler; 088 089 /** The content element to be replaced by the edited content. */ 090 CmsContainerPageElementPanel m_replaceElement; 091 092 /** The currently edited element's id. */ 093 private String m_currentElementId; 094 095 /** The depending element's id. */ 096 private String m_dependingElementId; 097 098 /** Flag indicating the content editor is currently opened. */ 099 private boolean m_editorOpened; 100 101 /** 102 * Constructor.<p> 103 * 104 * @param handler the container-page handler 105 */ 106 public CmsContentEditorHandler(CmsContainerpageHandler handler) { 107 108 m_handler = handler; 109 } 110 111 /** 112 * Closes the content editor.<p> 113 */ 114 public void closeContentEditor() { 115 116 CmsContentEditor.getInstance().closeEditor(); 117 m_editorOpened = false; 118 } 119 120 /** 121 * @see org.opencms.gwt.client.ui.contenteditor.I_CmsContentEditorHandler#onClose(java.lang.String, org.opencms.util.CmsUUID, boolean, boolean, boolean) 122 */ 123 public void onClose( 124 String sitePath, 125 CmsUUID structureId, 126 boolean isNew, 127 boolean hasChangedSettings, 128 boolean usedPublishDialog) { 129 130 if (m_currentElementId == null) { 131 m_currentElementId = structureId.toString(); 132 } 133 // we keep track of how many reloads are still ongoing - if all of them are done, we can send the edit events 134 final int[] reloadCounter = {0}; 135 136 I_ReloadHandler reloadHandler = new I_ReloadHandler() { 137 138 private List<Runnable> m_todo = new ArrayList<>(); 139 140 @Override 141 public void finish() { 142 143 if (usedPublishDialog) { 144 m_handler.m_controller.startPublishLockCheck(); 145 } 146 reloadCounter[0] -= 1; 147 if (reloadCounter[0] <= 0) { 148 m_todo.forEach(item -> item.run()); 149 } 150 151 } 152 153 @Override 154 public void onReload(CmsContainerPageElementPanel oldElement, CmsContainerPageElementPanel newElement) { 155 156 m_todo.add(() -> { 157 m_handler.m_controller.sendElementEditedContent( 158 newElement, 159 Js.cast(oldElement.getElement()), 160 isNew); 161 162 }); 163 } 164 165 }; 166 167 if (m_replaceElement != null) { 168 if ((m_handler.m_controller.getData().getDetailId() != null) 169 && m_replaceElement.getId().startsWith(m_handler.m_controller.getData().getDetailId().toString())) { 170 Window.Location.assign( 171 CmsStringUtil.joinPaths( 172 CmsCoreProvider.get().getVfsPrefix(), 173 CmsContainerpageController.getCurrentUri(), 174 CmsContainerpageController.getServerId(m_currentElementId))); 175 } 176 reloadCounter[0] += 1; 177 m_handler.m_controller.replaceElement( 178 m_replaceElement, 179 m_currentElementId, 180 reloadHandler); 181 m_replaceElement = null; 182 if (m_dependingElementId != null) { 183 reloadCounter[0] += 1; 184 m_handler.m_controller.reloadElements(new String[] {m_dependingElementId}, reloadHandler); 185 m_dependingElementId = null; 186 } 187 } else if (m_dependingElementId != null) { 188 reloadCounter[0] += 1; 189 m_handler.m_controller.reloadElements(new String[] {m_currentElementId, m_dependingElementId}, reloadHandler); 190 m_dependingElementId = null; 191 } else { 192 reloadCounter[0] += 1; 193 m_handler.m_controller.reloadElements(new String[] {m_currentElementId}, reloadHandler); 194 } 195 if (m_currentElementId != null) { 196 m_handler.addToRecent(m_currentElementId); 197 } 198 m_handler.enableToolbarButtons(); 199 m_handler.activateSelection(); 200 m_handler.m_controller.setContentEditing(false); 201 m_handler.m_controller.reInitInlineEditing(); 202 m_currentElementId = null; 203 if (hasChangedSettings) { 204 m_handler.m_controller.setPageChanged(new Runnable[] {}); 205 } 206 m_editorOpened = false; 207 } 208 209 /** 210 * Opens the XML content editor.<p> 211 * 212 * @param element the container element widget 213 * @param inline <code>true</code> to open the in-line editor for the given element if available 214 * @param wasNew <code>true</code> in case this is a newly created element not previously edited 215 */ 216 public void openDialog(final CmsContainerPageElementPanel element, final boolean inline, boolean wasNew) { 217 218 if (!inline && element.hasEditHandler()) { 219 m_handler.m_controller.getEditOptions( 220 element.getId(), 221 false, 222 new I_CmsSimpleCallback<CmsDialogOptionsAndInfo>() { 223 224 public void execute(CmsDialogOptionsAndInfo editOptions) { 225 226 final I_CmsSimpleCallback<CmsUUID> editCallBack = new I_CmsSimpleCallback<CmsUUID>() { 227 228 public void execute(CmsUUID arg) { 229 230 String contentId = element.getId(); 231 if (!element.getId().startsWith(arg.toString())) { 232 // the content structure ID has changed, the current element needs to be replaced after editing 233 m_replaceElement = element; 234 contentId = arg.toString(); 235 } 236 internalOpenDialog(element, contentId, inline, wasNew); 237 } 238 }; 239 if (editOptions == null) { 240 internalOpenDialog(element, element.getId(), inline, wasNew); 241 } else if (editOptions.getOptions().getOptions().size() == 1) { 242 m_handler.m_controller.prepareForEdit( 243 element.getId(), 244 editOptions.getOptions().getOptions().get(0).getValue(), 245 editCallBack); 246 } else { 247 CmsOptionDialog dialog = new CmsOptionDialog( 248 Messages.get().key(Messages.GUI_EDIT_HANDLER_SELECT_EDIT_OPTION_0), 249 editOptions.getOptions(), 250 editOptions.getInfo(), 251 new I_CmsSimpleCallback<String>() { 252 253 public void execute(String arg) { 254 255 m_handler.m_controller.prepareForEdit(element.getId(), arg, editCallBack); 256 } 257 }); 258 dialog.addDialogClose(new Command() { 259 260 public void execute() { 261 262 cancelEdit(); 263 } 264 }); 265 dialog.center(); 266 } 267 } 268 }); 269 } else { 270 internalOpenDialog(element, element.getId(), inline, wasNew); 271 } 272 } 273 274 /** 275 * Opens the XML content editor, checking for if an edit handler is configured first.<p> 276 * 277 * @param editableData the data of the element to edit 278 * @param isNew <code>true</code> if a new resource should be created 279 * @param dependingElementId the id of a depending element 280 * @param mode the element creation mode 281 * @param handlerDataForNew the edit handler data, if we are using an edit handler to create a new element; null otherwise 282 */ 283 public void openDialog( 284 final I_CmsEditableData editableData, 285 final boolean isNew, 286 final String dependingElementId, 287 final String mode, 288 final CmsEditHandlerData handlerDataForNew) { 289 290 if (!m_editorOpened) { 291 m_editorOpened = true; 292 m_handler.disableToolbarButtons(); 293 m_handler.deactivateCurrentButton(); 294 295 if (!isNew && (editableData.getStructureId() != null) && editableData.hasEditHandler()) { 296 final String elementId = CmsContentEditor.getClientIdForEditable(editableData); 297 m_handler.m_controller.getEditOptions( 298 elementId, 299 true, 300 new I_CmsSimpleCallback<CmsDialogOptionsAndInfo>() { 301 302 public void execute(CmsDialogOptionsAndInfo editOptions) { 303 304 final I_CmsSimpleCallback<CmsUUID> editCallBack = new I_CmsSimpleCallback<CmsUUID>() { 305 306 public void execute(CmsUUID arg) { 307 308 I_CmsEditableData data = editableData; 309 if (!data.getStructureId().equals(arg)) { 310 // the content structure ID has changed, change the editableData 311 data = new CmsEditableData(data); 312 ((CmsEditableData)data).setStructureId(arg); 313 } 314 internalOpenDialog(data, isNew, dependingElementId, mode, null); 315 } 316 }; 317 if (editOptions == null) { 318 internalOpenDialog(editableData, isNew, dependingElementId, mode, null); 319 } else if (editOptions.getOptions().getOptions().size() == 1) { 320 m_handler.m_controller.prepareForEdit( 321 elementId, 322 editOptions.getOptions().getOptions().get(0).getValue(), 323 editCallBack); 324 } else { 325 CmsOptionDialog dialog = new CmsOptionDialog( 326 Messages.get().key(Messages.GUI_EDIT_HANDLER_SELECT_EDIT_OPTION_0), 327 editOptions.getOptions(), 328 editOptions.getInfo(), 329 new I_CmsSimpleCallback<String>() { 330 331 public void execute(String arg) { 332 333 m_handler.m_controller.prepareForEdit(elementId, arg, editCallBack); 334 } 335 }); 336 dialog.addDialogClose(new Command() { 337 338 public void execute() { 339 340 cancelEdit(); 341 } 342 }); 343 dialog.center(); 344 } 345 } 346 }); 347 } else { 348 internalOpenDialog(editableData, isNew, dependingElementId, mode, handlerDataForNew); 349 } 350 351 } else { 352 CmsDebugLog.getInstance().printLine("Editor is already being opened."); 353 } 354 } 355 356 /** 357 * Opens the content editor according to the history hash.<p> 358 * 359 * @param historyHash the history hash 360 */ 361 public void openEditorForHistory(String historyHash) { 362 363 if (historyHash.startsWith(EDITOR_HASH_KEY)) { 364 if (!m_editorOpened) { 365 m_editorOpened = true; 366 CmsDebugLog.getInstance().printLine("EditorHandler - Opening editor from history"); 367 m_handler.m_controller.setContentEditing(true); 368 String id = historyHash.substring(EDITOR_HASH_KEY.length(), historyHash.indexOf(";")); 369 if (id.contains(",")) { 370 String[] ids = id.split(","); 371 m_currentElementId = URL.decodePathSegment(ids[0]); 372 m_dependingElementId = URL.decodePathSegment(ids[1]); 373 } else { 374 m_currentElementId = URL.decodePathSegment(id); 375 } 376 I_CmsEditorCloseHandler onClose = new I_CmsEditorCloseHandler() { 377 378 public void onClose(boolean hasChangedSettings, boolean usedPublishDialog) { 379 380 addClosedEditorHistoryItem(); 381 CmsContentEditorHandler.this.onClose( 382 null, 383 new CmsUUID(getCurrentElementId()), 384 false, 385 hasChangedSettings, 386 usedPublishDialog); 387 } 388 }; 389 String editorLocale = CmsCoreProvider.get().getLocale(); 390 391 CmsContentEditor.getInstance().openFormEditor( 392 getEditorContext(), 393 editorLocale, 394 m_currentElementId, 395 null, 396 null, 397 null, 398 null, 399 null, 400 m_handler.m_controller.getData().getMainLocale(), 401 null, 402 onClose); 403 } 404 } else { 405 closeContentEditor(); 406 } 407 } 408 409 /** 410 * Returns the currently edited element's id.<p> 411 * 412 * @return the currently edited element's id 413 */ 414 protected String getCurrentElementId() { 415 416 return m_currentElementId; 417 } 418 419 /** 420 * Adds a history item for the closed editor.<p> 421 */ 422 void addClosedEditorHistoryItem() { 423 424 History.newItem("", false); 425 } 426 427 /** 428 * Cancels opening the editor.<p> 429 */ 430 void cancelEdit() { 431 432 m_handler.enableToolbarButtons(); 433 m_handler.activateSelection(); 434 m_handler.m_controller.setContentEditing(false); 435 m_handler.m_controller.reInitInlineEditing(); 436 m_replaceElement = null; 437 m_dependingElementId = null; 438 m_currentElementId = null; 439 m_editorOpened = false; 440 } 441 442 /** 443 * Gets the editor context to use for the Acacia editor.<p> 444 * 445 * @return the editor context 446 */ 447 CmsEditorContext getEditorContext() { 448 449 CmsEditorContext result = new CmsEditorContext(); 450 result.getPublishParameters().put( 451 CmsPublishOptions.PARAM_CONTAINERPAGE, 452 "" + CmsCoreProvider.get().getStructureId()); 453 result.getPublishParameters().put( 454 CmsPublishOptions.PARAM_DETAIL, 455 "" + CmsContainerpageController.get().getData().getDetailId()); 456 result.getPublishParameters().put(CmsPublishOptions.PARAM_START_WITH_CURRENT_PAGE, ""); 457 elemental2.dom.HTMLMetaElement meta = Js.cast( 458 elemental2.dom.DomGlobal.document.querySelector( 459 "meta[name=" + CmsGwtConstants.META_EDITOR_STYLESHEET + "]")); 460 if (meta != null) { 461 result.setEditorStylesheet(meta.content); 462 } 463 return result; 464 } 465 466 /** 467 * Opens the edit dialog.<p> 468 * 469 * @param element the element to edit 470 * @param editContentId the edit content id 471 * @param inline <code>true</code> to edit the content inline 472 * @param wasNew <code>true</code> in case this is a newly created element not previously edited 473 */ 474 void internalOpenDialog( 475 final CmsContainerPageElementPanel element, 476 String editContentId, 477 final boolean inline, 478 boolean wasNew) { 479 480 if (!m_editorOpened) { 481 m_editorOpened = true; 482 m_handler.disableToolbarButtons(); 483 m_handler.deactivateCurrentButton(); 484 m_currentElementId = editContentId; 485 final String serverId = CmsContainerpageController.getServerId(m_currentElementId); 486 final Runnable classicEdit = new Runnable() { 487 488 public void run() { 489 490 CmsEditableData editableData = new CmsEditableData(); 491 editableData.setElementLanguage(CmsCoreProvider.get().getLocale()); 492 editableData.setStructureId(new CmsUUID(serverId)); 493 editableData.setSitePath(element.getSitePath()); 494 editableData.setMainLanguage(m_handler.m_controller.getData().getMainLocale()); 495 CmsContentEditorDialog.get().openEditDialog( 496 editableData, 497 false, 498 null, 499 new DialogOptions(), 500 CmsContentEditorHandler.this); 501 } 502 }; 503 504 if (m_handler.m_controller.getData().isUseClassicEditor() || element.isNewEditorDisabled()) { 505 classicEdit.run(); 506 } else { 507 String editorLocale = CmsCoreProvider.get().getLocale(); 508 final String mainLocale; 509 if (m_handler.m_controller.getData().getMainLocale() == null) { 510 Element htmlEl = CmsDomUtil.querySelector( 511 "[" + CmsGwtConstants.ATTR_DATA_ID + "*='" + serverId + "']", 512 element.getElement()); 513 if (htmlEl != null) { 514 String entityId = htmlEl.getAttribute(CmsGwtConstants.ATTR_DATA_ID); 515 mainLocale = CmsContentDefinition.getLocaleFromId(entityId); 516 } else { 517 mainLocale = null; 518 } 519 } else { 520 mainLocale = m_handler.m_controller.getData().getMainLocale(); 521 } 522 I_CmsEditorCloseHandler onClose = new I_CmsEditorCloseHandler() { 523 524 public void onClose(boolean hasChangedSettings, boolean usedPublishDialog) { 525 526 addClosedEditorHistoryItem(); 527 CmsContentEditorHandler.this.onClose( 528 element.getSitePath(), 529 new CmsUUID(serverId), 530 wasNew, 531 hasChangedSettings, 532 usedPublishDialog); 533 534 } 535 }; 536 if (inline && CmsContentEditor.hasEditable(element.getElement())) { 537 addEditingHistoryItem(true); 538 CmsEditorContext context = getEditorContext(); 539 context.setReusedElement(element.isReused()); 540 context.setHtmlContextInfo(getContextInfo(element)); 541 // remove expired style before initializing the editor 542 element.setReleasedAndNotExpired(true); 543 // in case of new elements, ignore load time 544 long loadTime = wasNew ? Long.MAX_VALUE : m_handler.m_controller.getLoadTime(); 545 CmsContentEditor.getInstance().openInlineEditor( 546 context, 547 new CmsUUID(serverId), 548 editorLocale, 549 element, 550 mainLocale, 551 loadTime, 552 onClose); 553 } else { 554 addEditingHistoryItem(false); 555 Map<String, String> settingPresets = new HashMap<String, String>(); 556 CmsEditorContext context = getEditorContext(); 557 context.setReusedElement(element.isReused()); 558 I_CmsDropContainer dropContainer = element.getParentTarget(); 559 if (dropContainer instanceof CmsContainerPageContainer) { 560 CmsContainerPageContainer container = (CmsContainerPageContainer)dropContainer; 561 settingPresets.putAll(container.getSettingPresets()); 562 } 563 context.setSettingPresets(settingPresets); 564 565 boolean allowSettings = m_handler.m_controller.getData().allowSettingsInEditor() 566 && !m_handler.m_controller.isEditingDisabled() 567 && !serverId.equals(String.valueOf(m_handler.m_controller.getData().getDetailId())); 568 I_CmsSimpleCallback<Boolean> openEditor = new I_CmsSimpleCallback<Boolean>() { 569 570 public void execute(Boolean lockedPage) { 571 572 CmsContentEditor.getInstance().openFormEditor( 573 context, 574 editorLocale, 575 serverId, 576 lockedPage.booleanValue() ? getCurrentElementId() : null, 577 null, 578 null, 579 null, 580 null, 581 mainLocale, 582 null, 583 onClose); 584 } 585 }; 586 if (allowSettings) { 587 if (m_handler.m_controller.getData().getDetailContainerPage() != null) { 588 CmsCoreProvider.get().lock( 589 m_handler.m_controller.getData().getDetailContainerPage(), 590 m_handler.m_controller.getLoadTime(), 591 openEditor); 592 } else { 593 CmsCoreProvider.get().lock( 594 CmsCoreProvider.get().getStructureId(), 595 m_handler.m_controller.getLoadTime(), 596 openEditor); 597 } 598 } else { 599 openEditor.execute(Boolean.FALSE); 600 } 601 602 } 603 } 604 } else { 605 CmsDebugLog.getInstance().printLine("Editor is already being opened."); 606 } 607 } 608 609 /** 610 * Opens the XML content editor internally.<p> 611 * 612 * @param editableData the data of the element to edit 613 * @param isNew <code>true</code> if a new resource should be created 614 * @param dependingElementId the id of a depending element 615 * @param mode the element creation mode 616 * @param editHandlerData the edit handler data, if we are using an edit handler to create a new element; null otherwise 617 */ 618 void internalOpenDialog( 619 final I_CmsEditableData editableData, 620 final boolean isNew, 621 String dependingElementId, 622 String mode, 623 CmsEditHandlerData editHandlerData) { 624 625 if ((editableData.getStructureId() != null) && !isNew) { 626 m_currentElementId = editableData.getStructureId().toString(); 627 } else { 628 m_currentElementId = null; 629 } 630 m_dependingElementId = dependingElementId; 631 if (m_handler.m_controller.getData().isUseClassicEditor()) { 632 CmsContentEditorDialog.get().openEditDialog(editableData, isNew, mode, new DialogOptions(), this); 633 } else { 634 String newLink = null; 635 if (isNew) { 636 newLink = editableData.getNewLink(); 637 // the new link is URL encoded twice, decode it 638 newLink = URL.decodeQueryString(newLink); 639 newLink = URL.decodeQueryString(newLink); 640 } 641 addEditingHistoryItem(isNew); 642 CmsContentEditor.getInstance().openFormEditor( 643 getEditorContext(), 644 CmsCoreProvider.get().getLocale(), 645 editableData.getStructureId().toString(), 646 null, 647 newLink, 648 null, 649 editableData.getPostCreateHandler(), 650 mode, 651 m_handler.m_controller.getData().getMainLocale(), 652 editHandlerData, 653 new I_CmsEditorCloseHandler() { 654 655 public void onClose(boolean hasChangedSettings, boolean usedPublishDialog) { 656 657 addClosedEditorHistoryItem(); 658 CmsContentEditorHandler.this.onClose( 659 editableData.getSitePath(), 660 editableData.getStructureId(), 661 isNew, 662 hasChangedSettings, 663 usedPublishDialog); 664 } 665 }); 666 } 667 668 } 669 670 /** 671 * Adds a history item for the opened editor.<p> 672 * Use the prohibitReturn flag to deny a return to the opened editor through the browser history. 673 * Use this feature for inline editing or when opening the editor for new resources.<p> 674 * 675 * @param prohibitReturn if <code>true</code> returning to the opened editor through the browser history is denied 676 */ 677 private void addEditingHistoryItem(boolean prohibitReturn) { 678 679 if (prohibitReturn) { 680 History.newItem(EDITOR_FOR_NO_RETURN_HASH_KEY, false); 681 } else { 682 History.newItem( 683 EDITOR_HASH_KEY 684 + CmsContainerpageController.getServerId(getCurrentElementId()) 685 + (m_dependingElementId != null ? "," + m_dependingElementId + ";" : ";"), 686 false); 687 } 688 } 689 690 /** 691 * Returns the HTML context info for the given element.<p> 692 * 693 * @param element the edited element 694 * 695 * @return the JSON string 696 */ 697 private String getContextInfo(CmsContainerPageElementPanel element) { 698 699 CmsContainerPageContainer container; 700 if (m_handler.m_controller.isGroupcontainerEditing()) { 701 container = (CmsContainerPageContainer)((CmsContainerPageElementPanel)element.getParentTarget()).getParentTarget(); 702 } else { 703 container = (CmsContainerPageContainer)element.getParentTarget(); 704 } 705 JSONObject result = new JSONObject(); 706 putString(result, CmsCntPageData.JSONKEY_ELEMENT_ID, element.getId()); 707 CmsUUID detailId = m_handler.m_controller.getData().getDetailId(); 708 if (detailId != null) { 709 putString(result, CmsCntPageData.JSONKEY_DETAIL_ELEMENT_ID, "" + detailId); 710 } 711 putString(result, CmsCntPageData.JSONKEY_NAME, "" + container.getContainerId()); 712 putString(result, CmsCntPageData.JSONKEY_TYPE, "" + container.getContainerType()); 713 result.put(CmsCntPageData.JSONKEY_WIDTH, new JSONNumber(container.getConfiguredWidth())); 714 result.put(CmsCntPageData.JSONKEY_DETAILVIEW, JSONBoolean.getInstance(container.isDetailView())); 715 result.put( 716 CmsCntPageData.JSONKEY_ISDETAILVIEWCONTAINER, 717 JSONBoolean.getInstance(container.isDetailViewContainer())); 718 result.put(CmsCntPageData.JSONKEY_DETAILONLY, JSONBoolean.getInstance(container.isDetailOnly())); 719 result.put(CmsCntPageData.JSONKEY_MAXELEMENTS, new JSONNumber(1)); 720 JSONObject presets = new JSONObject(); 721 Map<String, String> presetsMap = container.getSettingPresets(); 722 for (Map.Entry<String, String> entry : presetsMap.entrySet()) { 723 presets.put(entry.getKey(), new JSONString(entry.getValue())); 724 } 725 result.put(CmsCntPageData.JSONKEY_PRESETS, presets); 726 return result.toString(); 727 } 728 729 /** 730 * Adds a String value to the JSON object.<p> 731 * 732 * @param obj the object to manipulate 733 * @param key the key 734 * @param val the value 735 */ 736 private void putString(JSONObject obj, String key, String val) { 737 738 obj.put(key, new JSONString(val)); 739 } 740 741}