From 3a31e149c1ccc7557cb5ae007b59b05378d051bb Mon Sep 17 00:00:00 2001
From: Ivan Tyagov <ivan@nexedi.com>
Date: Thu, 2 Dec 2010 15:05:17 +0000
Subject: [PATCH] Make ID generation "safe" whenever instant switching between
 pads is involved. Use JSON to load new pads.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@41037 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 .../Base_viewKnowledgePadMacroLibrary.xml     | 31 ++++----
 .../ERP5Site_viewHomeAreaRenderer.xml         | 17 +++--
 .../KnowledgePad_viewColumnWidget.xml         |  7 +-
 .../KnowledgePad_viewNavigationWidget.xml     | 74 +++++++++++++++++++
 .../KnowledgePag_getPadAsHTML.xml             | 22 ++++--
 .../erp5_knowledge_box.js.xml                 | 54 ++++++++++----
 bt5/erp5_knowledge_pad/bt/revision            |  2 +-
 7 files changed, 163 insertions(+), 44 deletions(-)
 create mode 100644 bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewNavigationWidget.xml

diff --git a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/Base_viewKnowledgePadMacroLibrary.xml b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/Base_viewKnowledgePadMacroLibrary.xml
index 34fcc81428..c183bfc674 100644
--- a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/Base_viewKnowledgePadMacroLibrary.xml
+++ b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/Base_viewKnowledgePadMacroLibrary.xml
@@ -185,39 +185,42 @@
                   <tal:block  \n
                     tal:define="knowledge_pad_relative_url knowledge_pad/getRelativeUrl;\n
                                 active_knowledge_pad_relative_url active_knowledge_pad/getRelativeUrl;\n
-                                is_active python: knowledge_pad_relative_url==active_knowledge_pad_relative_url"> \n
+                                is_active python: knowledge_pad_relative_url==active_knowledge_pad_relative_url;\n
+                                dom_id python: \'%s\' %knowledge_pad_relative_url.replace(\'/\', \'_\')"> \n
 \n
-                    <li tal:condition="is_active"\n
-                        class="tab tab_selected">\n
+                    <li tal:attributes="id dom_id;\n
+                                        class python: test(is_active, \'tab tab_selected\', \'tab\')">\n
+                      <div class="pad-actions"\n
+                           tal:attributes="style python: test(is_active, \'display:block\', \'display:none\')">\n
                         <span id="active_knowledge_pad_title" \n
                               tal:content="knowledge_pad/title"/>\n
-\n
                         <span title="Settings"\n
                               i18n:attributes="title"\n
                               i18n:domain="ui"\n
                               class="clickable_image rename_tab_dialog_image"\n
                               onclick="showRenamePadPopup();"></span>\n
-\n
                         <span title="Remove"\n
                               i18n:attributes="title"\n
                               i18n:domain="ui"\n
                               class="clickable_image remove_tab_dialog_image"\n
                               tal:attributes="onclick string: removeKnowledgePadFromServer(\n
                                                                 \'${active_knowledge_pad_relative_url}\', \'${mode}\')"/>\n
-                    </li>\n
+                      </div>\n
+                      <div class="pad-switch"\n
+                           tal:attributes="style python: test(is_active, \'display:none\', \'display:block\')">\n
+<!--\n
+                       <span tal:attributes="onclick string:loadPadFromServer(\'${knowledge_pad_relative_url}\', \'${dom_id}\', \'${mode}\')" \n
+                             tal:content="knowledge_pad/getTitle"/>-->\n
 \n
-                    <li tal:condition="not: is_active"\n
-                        class="tab">\n
-                     <a tal:attributes="href python:\n
+                        <a tal:attributes="href python:\n
                                           \'ERP5Site_toggleActiveKnowledgePad?knowledge_pad_url=%s&mode=%s\'\n
                                           %(knowledge_pad.getRelativeUrl(), mode)">\n
-                             <span tal:content="knowledge_pad/getTitle"/>\n
-                      </a>\n
-                       <!-- XXX: instant switch-->\n
-<!--                       <span tal:attributes="onclick string:loadPadFromServer(\'${knowledge_pad_relative_url}\', \'page_wrapper\', \'${mode}\')" \n
-                             tal:content="knowledge_pad/getTitle"/>-->\n
+                             <span tal:content="knowledge_pad/getTitle"/></a>\n
+\n
+                      </div>\n
 \n
                     </li>\n
+\n
                   </tal:block>\n
                 </tal:block>\n
                 <li class="tab"\n
diff --git a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/ERP5Site_viewHomeAreaRenderer.xml b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/ERP5Site_viewHomeAreaRenderer.xml
index d8d5c91a2a..77750e0370 100644
--- a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/ERP5Site_viewHomeAreaRenderer.xml
+++ b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/ERP5Site_viewHomeAreaRenderer.xml
@@ -61,19 +61,22 @@
                                       active_knowledge_pad is not None">\n
 \n
       <tal:block tal:condition="not: isAnon"> \n
-        <span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/navigation"/>\n
+        <div id="pad-navigation-wrapper">\n
+          <span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/navigation"/>\n
+        </div>\n
         <span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/knowledge_pad_security_check"/> \n
         <span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/disable_server_integration"/>\n
         <span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/disable_server_integration"/> \n
       </tal:block>\n
 \n
       <!-- Render active Knowledge pad -->\n
-      <span tal:condition="active_knowledge_pad"\n
-            tal:replace="structure python: active_knowledge_pad.KnowledgePad_viewDashboardWidget(\n
-                                                                  columns=columns,\n
-                                                                  real_context=here,\n
-                                                                  cancel_url=cancel_url)"/>\n
-      \n
+      <div id="pad-body-wrapper"\n
+           tal:condition="active_knowledge_pad">\n
+        <tal:block tal:replace="structure python: active_knowledge_pad.KnowledgePad_viewDashboardWidget(\n
+                                                                       columns=columns,\n
+                                                                       real_context=here,\n
+                                                                       cancel_url=cancel_url)"/>\n
+      </div>\n
       <!-- Hidden dialogs -->\n
       <span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/hidden_dialogs"/>\n
       \n
diff --git a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewColumnWidget.xml b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewColumnWidget.xml
index 2169626e98..0bfa119939 100644
--- a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewColumnWidget.xml
+++ b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewColumnWidget.xml
@@ -43,8 +43,9 @@
   <tal:block \n
         tal:condition="python: getattr(here, box_id, None) is not None"\n
         tal:define="box python: getattr(here, box_id);\n
-                    view_form_dom_id python: \'visual_%s\' %box_id;\n
-                    edit_form_dom_id python: \'edit_form_%s\' %box_id;\n
+                    box_dom_id python: \'%s\' %box.getRelativeUrl().replace(\'/\', \'_\');\n
+                    view_form_dom_id python: \'%s_content\' %box_dom_id;\n
+                    edit_form_dom_id python: \'%s_edit_form\' %box_dom_id;\n
                     gadget python: box.getSpecialiseValue();\n
                     dummy python: request.set(\'is_gadget_mode\', \'1\');\n
                     dummy python: request.set(\'box_relative_url\', box.getRelativeUrl());\n
@@ -71,7 +72,7 @@
 \n
     <div class="block" \n
       tal:condition="python: gadget is not None"\n
-      tal:attributes="id python: \'%s_%s\' %(here.getRelativeUrl().replace(\'/\',\'_\'), box_id)">\n
+      tal:attributes="id box_dom_id">\n
 \n
       <h3 class="handle">\n
         <span class="handle">\n
diff --git a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewNavigationWidget.xml b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewNavigationWidget.xml
new file mode 100644
index 0000000000..e79fa3af2d
--- /dev/null
+++ b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePad_viewNavigationWidget.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_text</string> </key>
+            <value> <unicode encoding="cdata"><![CDATA[
+
+<tal:block  \n
+  tal:define="mode python: options.get(\'mode\', \'erp5_front\');\n
+              default_pad_group python: options.get(\'default_pad_group\', \'\');\n
+              kw python: dict(mode=mode, default_pad_group=default_pad_group);\n
+              knowledge_pads python:  here.ERP5Site_getKnowledgePadListForUser(**kw);\n
+              struct python: here.ERP5Site_getActiveKnowledgePadForUser(knowledge_pads, **kw);\n
+              global active_knowledge_pad python: struct[0];\n
+              knowledge_pads python: struct[1];\n
+              columns python: options.get(\'columns\', 3);\n
+              hasUserActivity python:  here.ERP5Site_hasUserActivity(active_knowledge_pad, **kw);\n
+              isAnon python: here.portal_membership.isAnonymousUser();\n
+              createDefaultPadForUser  python: len(knowledge_pads)==0 and not hasUserActivity;\n
+              waitForActivitiesOnServer python: active_knowledge_pad is None and hasUserActivity;\n
+              isUserAllowedToCreateKnowledgePads context/Base_isUserAllowedToUseKnowledgePad;\n
+              isKnowledgePadTemplateUsed python: request.get(\'is_knowledge_pad_template_used\', 0);\n
+              isAnonymousKnowledgePadUsed python: request.get(\'use_anonymous_knowledge_pad\', False);\n
+              cancel_url here/absolute_url;">\n
+\n
+<span metal:use-macro="container/Base_viewKnowledgePadMacroLibrary/macros/navigation"/>\n
+\n
+</tal:block>
+
+]]></unicode> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>KnowledgePad_viewNavigationWidget</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePag_getPadAsHTML.xml b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePag_getPadAsHTML.xml
index 88badf17f1..7387c79454 100644
--- a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePag_getPadAsHTML.xml
+++ b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/KnowledgePag_getPadAsHTML.xml
@@ -57,17 +57,27 @@
   browser.\n
 """\n
 pad = context.restrictedTraverse(pad_relative_url)\n
+\n
 # we set this as a temp hack to force all gadgets rendering as synchronous\n
-context.REQUEST.set(\'force_synchronous_gadget_rendering\', 1)\n
+#context.REQUEST.set(\'force_synchronous_gadget_rendering\', 1)\n
 \n
 # render Pad\'s html\n
+body = pad.KnowledgePad_viewDashboardWidget(real_context=context, page_wrapper_id=\'\')\n
 \n
-html = pad.KnowledgePad_viewDashboardWidget(real_context=context, page_wrapper_id=\'\')\n
 # toggle new active pad \n
 context.ERP5Site_toggleActiveKnowledgePad(pad_relative_url, mode, redirect=False)\n
 \n
-context.REQUEST.RESPONSE.setHeader(\'Content-Type\', \'text/html;; charset=utf-8\')\n
-return html\n
+# XXX: generate navigation\n
+#navigation = pad.KnowledgePad_viewNavigationWidget(real_context=context, page_wrapper_id=\'\')\n
+\n
+# XXX: generate all JS updater code\n
+javascript = \'\'\'updater(\'http://localhost/km/ERP5Site_viewRssGadget\', \'knowledge_pad_module/65/2\', \'visual_2\', \'web_site_module/km_test_web_site\', \'0\', {});\n
+updater(\'http://localhost/km/ERP5Site_viewRssGadget\', \'knowledge_pad_module/64/3\', \'visual_3\', \'\', \'0\', {}); \'\'\'\n
+\n
+# return JSON\n
+result = {\'body\': body,\n
+          \'javascript\': javascript }\n
+return \'%s\' % result\n
 </string> </value>
         </item>
         <item>
@@ -109,8 +119,10 @@ return html\n
                             <string>_getattr_</string>
                             <string>context</string>
                             <string>pad</string>
-                            <string>html</string>
+                            <string>body</string>
                             <string>False</string>
+                            <string>javascript</string>
+                            <string>result</string>
                           </tuple>
                         </value>
                     </item>
diff --git a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/erp5_knowledge_box.js.xml b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/erp5_knowledge_box.js.xml
index 9a30659ad3..0045f2a69c 100644
--- a/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/erp5_knowledge_box.js.xml
+++ b/bt5/erp5_knowledge_pad/SkinTemplateItem/portal_skins/erp5_knowledge_pad/erp5_knowledge_box.js.xml
@@ -12,7 +12,7 @@
         </item>
         <item>
             <key> <string>_EtagSupport__etag</string> </key>
-            <value> <string>ts91285696.36</string> </value>
+            <value> <string>ts91301986.39</string> </value>
         </item>
         <item>
             <key> <string>__name__</string> </key>
@@ -266,19 +266,45 @@ function showRenamePadPopup(){\n
    setTimeout("MochiKit.DOM.getElement(\'new_knowledge_pad_title\').focus()", 500 );\n
 }\n
 \n
-function loadPadFromServer(pad_relative_url, wrapper_dom_id, mode){\n
+function loadPadFromServer(pad_relative_url, selected_pad_dom_id, mode){\n
   /* Load Pad from server */\n
-  d = MochiKit.Async.doSimpleXMLHttpRequest(\'KnowledgePag_getPadAsHTML\', \n
-                                            {\'pad_relative_url\':pad_relative_url,\n
-                                             \'mode\':mode});\n
-  d.addCallback(handleServerSuccess);\n
-  function handleServerSuccess(res){\n
-    response = res.responseText;\n
-//     removeElement(wrapper_dom_id);\n
-//     div = document.createElement("div")\n
-   dom = getElement(wrapper_dom_id);\n
-    dom.innerHTML = response;\n
-//     alert(div);\n
+  // XXX: show some animation ?\n
+    \n
+  d = MochiKit.Async.loadJSONDoc(\'KnowledgePag_getPadAsHTML\', \n
+                                 {\'pad_relative_url\':pad_relative_url,\n
+                                  \'mode\':mode});\n
+  //d.addCallback(handleServerSuccess);\n
+  d.addCallbacks(handleServerSuccess, metadataFetchFailed);\n
+\n
+  // set old pad to not selected\n
+  pads_container = getElement("tabs");\n
+  old_selected_pad = getFirstElementByTagAndClassName("li", "tab_selected", pads_container);\n
+  old_selected_pad.setAttribute("class", "tab");\n
+  pad_actions = getFirstElementByTagAndClassName("div", "pad-actions", old_selected_pad);\n
+  pad_switch = getFirstElementByTagAndClassName("div", "pad-switch", old_selected_pad); \n
+  pad_actions.style.display="none";\n
+  pad_switch.style.display="block";\n
+  \n
+  // set new selected pad class \n
+  new_selected_pad = getElement(selected_pad_dom_id);\n
+  new_selected_pad.setAttribute("class", "tab tab_selected");\n
+  \n
+  // enable "settings" for this pad and hide instant switch\n
+  pad_actions = getFirstElementByTagAndClassName("div", "pad-actions", new_selected_pad);\n
+  pad_switch = getFirstElementByTagAndClassName("div", "pad-switch", new_selected_pad); \n
+  pad_actions.style.display="block";\n
+  pad_switch.style.display="none";\n
+ \n
+   \n
+  function metadataFetchFailed(meta){}\n
+  \n
+  function handleServerSuccess(meta){\n
+    body = meta.body\n
+    javascript = meta.javascript\n
+    body_element = getElement(\'pad-body-wrapper\');\n
+    body_element.innerHTML = body;\n
+    // execute JS code\n
+    eval(javascript);\n
   }\n
 }\n
 \n
@@ -449,7 +475,7 @@ MochiKit.DOM.addLoadEvent(initialize);\n
         </item>
         <item>
             <key> <string>size</string> </key>
-            <value> <int>16600</int> </value>
+            <value> <int>17637</int> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_knowledge_pad/bt/revision b/bt5/erp5_knowledge_pad/bt/revision
index a869e998c0..5628fa72e9 100644
--- a/bt5/erp5_knowledge_pad/bt/revision
+++ b/bt5/erp5_knowledge_pad/bt/revision
@@ -1 +1 @@
-638
\ No newline at end of file
+639
\ No newline at end of file
-- 
2.30.9