Commit 8056ec16 authored by Ayush Tiwari's avatar Ayush Tiwari

Historical Revision: Use DiffTool to show differences in Historical Revisions

/reviewed-on !747
parents a2747dde 15a041c4
<?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>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testHistoricalDiff</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test History Available from edit_workflow</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test History and edit_workflow</td></tr>
</thead><tbody>
<tr>
<td>store</td>
<td tal:content="python:here.getPortalObject().absolute_url()">http://example.com/erp5</td>
<td>base_url</td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/FooModule_createObjects?portal_type=Bar&amp;num:int=1</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/0</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 2</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 3</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-1 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number"]</td>
<td>1 records</td> <!-- Only one property changed. -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Title 0</td> <!-- before -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 1</td> <!-- after -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
<tr>
<td>clickAndWait</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]//a</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Title0+Version1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-1 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]//a</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Version1+Version3</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?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>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testHistoricalDiffNoLinkForCurrentChange</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test History Available from edit_workflow</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">Test Historical Diff For Links</td></tr>
</thead><tbody>
<tr>
<td>store</td>
<td tal:content="python:here.getPortalObject().absolute_url()">http://example.com/erp5</td>
<td>base_url</td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/ListBoxZuite_reset</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/FooModule_createObjects?portal_type=Bar&amp;num:int=1</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/bar_module/0</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 1</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 2</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_title</td>
<td>Version 3</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-3 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number"]</td>
<td>1 records</td> <!-- Only one property changed. -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Version 2</td> <!-- before -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 3</td> <!-- after -->
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
<tr>
<td>clickAndWait</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]//a</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[1]</td>
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Version2+Version3</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=History</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//span[@class="listbox-current-page-total-number x0_listbox-current-page-total-number"]</td>
<td>4 records</td> <!-- Creation + edited 3 times -->
</tr>
<!-- First modification -->
<tr>
<td>clickAndWait</td>
<td>//tr[@class='x0_listbox-data-line-3 DataB']/td[4]/a</td>
<td></td>
</tr>
<tr>
<td>assertTitle</td>
<td>Historical Comparison - Version 3*</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]//a</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -130,21 +130,20 @@
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Title 0</td> <!-- before -->
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 1</td> <!-- after -->
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Title0+Version1</td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
</tal:block>
<tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'">
......@@ -191,21 +190,20 @@
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Version 1</td> <!-- before -->
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 2</td> <!-- after -->
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Version1+Version2</td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
</tal:block>
<tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'">
......@@ -270,21 +268,20 @@
<td>title</td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox="public"]</td>
<td></td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[2]</td>
<td>Version 2</td> <!-- before -->
</tr>
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//tr[@class='listbox-data-line-0 DataA']/td[2]/div[@data-gadget-sandbox='public']", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.getAttribute('data-gadget-value');</td>
<td>_data_gadget_value</td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[3]</td>
<td>Version 3</td> <!-- after -->
</tr>
<tr>
<td>verifyEval</td>
<td>storedVars['_data_gadget_value'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>---+++@@-1+1@@-Version2+Version3</td>
<td>assertText</td>
<td>//tr[@class='listbox-data-line-0 DataA']/td[4]</td>
<td>Version 3</td> <!-- now -->
</tr>
</tal:block>
<tal:block tal:condition="python: context.TestTool_getSkinName()=='Mobile'">
......
......@@ -64,6 +64,21 @@
<td>A new foo</td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name='field_my_lines_list']</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>//textarea[@name='field_my_lines_list']</td>
<td>
Foo
Bar
</td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/save" />
<!-- Go to History tab -->
......@@ -130,9 +145,56 @@
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[2]</td>
<td>Diff Viewer</td>
<td>Old Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[3]</td>
<td>New Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[4]</td>
<td>Current Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[3]</td>
<td>New Value</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/thead/tr[1]/th[4]</td>
<td>Current Value</td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_listbox_loaded" />
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[1]</td>
<td>short_title</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[2]</td>
<td></td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[3]</td>
<td>A new foo</td>
</tr>
<tr>
<td>verifyText</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[4]</td>
<td>A new foo</td>
</tr>
<!-- Click on the link to see the diff between old and new value -->
<tr>
<td>click</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[1]/td[3]/a</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[@data-gadget-scope='field_listbox']//table/tbody/tr[2]/td[2]//iframe</td>
......@@ -143,7 +205,7 @@
<td>1000</td>
<td></td>
</tr>
<!-- Check for the value of diff in Iframe -->
<!-- Check for the value of diff in IFrame -->
<tr>
<td>storeEval</td>
<td>document.querySelector('#selenium_myiframe').contentWindow.document.evaluate("//div[@data-gadget-scope='field_listbox']//table/tbody/tr[2]/td[2]//iframe", document.querySelector('#selenium_myiframe').contentWindow.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.contentWindow.document.body.textContent</td>
......@@ -153,7 +215,7 @@
<td>verifyEval</td>
<!-- Verify the value after removing the spaces and line breaks -->
<td>storedVars['diff_content'].replace(/(\r\n\t|\n|\r\t)/gm,"").replace(/\s+/g, '')</td>
<td>1-1+Anewfoo</td>
<td>1-1+('Foo','Bar')</td>
</tr>
</tbody></table>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_hidden</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view_historical_diff</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>108.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View Historical Diff</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: object.absolute_url() + \'/Base_viewHistoricalComparisonDiff\'</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
This URL script is used for Historical comparison list
to show the diff between the new value and current value.
In case there new value is the current value, there is no
need to show the diff link.
"""
request = context.REQUEST
# In this case, the second serial should be the current value, i.e, 0.0.0.0
first_serial = getattr(brain, 'next_serial', '0.0.0.0')
second_serial = '0.0.0.0'
time = getattr(brain, 'time', '')
action = getattr(brain, 'action', '')
actor = getattr(brain, 'actor', '')
# There is no need to compare revisions in case its the
# first version.
if first_serial != second_serial:
if url_dict:
return {'command': 'index',
'options': {
# XXX: This shouldn't be the referred way to get
# relative URL, but if we directly use context here
# to get the relative URL, it will return us the
# URL of tempbase object of list, which is not
# what we desire, thus taking the approach to
# get it via REQUEST
'jio_key': request.get('relative_url'),
},
'view_kw': {
'view': 'view_historical_diff',
'jio_key': request.get('relative_url'),
'extra_param_json': {
'first_serial': first_serial,
'second_serial': second_serial,
'time': time,
'action': action,
'actor': actor,
}
}
}
return 'Base_viewHistoricalComparisonDiff?first_serial=%s&amp;second_serial=%s&amp;time=%s&amp;action=%s&amp;actor=%s'\
% ( first_serial, second_serial, time, action, actor )
elif url_dict:
return {}
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<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_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<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>_params</string> </key>
<value> <string>brain, url_dict=False, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getCurrentDiffUrl</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
This URL script is used for Historical comparison list
to get diff between old and new value
"""
request = context.REQUEST
first_serial = getattr(brain, 'serial', '0.0.0.0')
second_serial = getattr(brain, 'next_serial', '0.0.0.0')
time = getattr(brain, 'time', '')
action = getattr(brain, 'action', '')
actor = getattr(brain, 'actor', '')
# There is no need to compare revisions in case its the
# first version.
if url_dict:
return {'command': 'index',
'options': {
# XXX: This shouldn't be the referred way to get
# relative URL, but if we directly use context here
# to get the relative URL, it will return us the
# URL of tempbase object of list, which is not
# what we desire, thus taking the approach to
# get it via REQUEST
'jio_key': request.get('relative_url'),
},
'view_kw': {
'view': 'view_historical_diff',
'jio_key': request.get('relative_url'),
'extra_param_json': {
'first_serial': first_serial,
'second_serial': second_serial,
'time': time,
'action': action,
'actor': actor,
}
}
}
return 'Base_viewHistoricalComparisonDiff?first_serial=%s&amp;second_serial=%s&amp;time=%s&amp;action=%s&amp;actor=%s'\
% ( first_serial, second_serial, time, action, actor )
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<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_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<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>_params</string> </key>
<value> <string>brain, url_dict=False, serial=None, next_serial=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_getDiffUrl</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from Products.ERP5Type.Document import newTempBase
from Products.PythonScripts.standard import Object
from ZODB.POSException import ConflictError
from zExceptions import Unauthorized
from Products.ERP5Type.Document import newTempBase
Base_translateString = context.Base_translateString
portal = context.getPortalObject()
portal_diff = portal.portal_diff
try:
context.HistoricalRevisions[serial]
except (ConflictError, Unauthorized):
raise
except Exception:
return [newTempBase(portal, Base_translateString('Historical revisions are'
except Exception: # POSKeyError
return [Object(property_name=Base_translateString('Historical revisions are'
' not available, maybe the database has been packed'))]
if next_serial == '0.0.0.0':
# In case the next serial is 0.0.0.0, we should always be considering the
# new object as the current context
new_getProperty = context.getProperty
new = context
else:
new = context.HistoricalRevisions[next_serial]
new_getProperty = new.getProperty
old = context.HistoricalRevisions[serial]
result = []
# XXX: Instead of creating a separate property list here, we can use DiffTool
# to directly find out the beautified diff and send it to the listbox
binary_data_explanation = Base_translateString("Binary data can't be displayed")
base_error_message = Base_translateString('(value retrieval failed)')
diff = portal_diff.diffPortalObject(old, new).asBeautifiedJSONDiff()
tempbase_list = []
uid = 900
for x in diff:
temp_obj = newTempBase(portal,
x['path'],
for prop_dict in context.getPropertyMap():
prop = prop_dict['id']
error = False
try:
current_value = context.getProperty(prop)
except TypeError:
error = True
current_value = base_error_message
try:
old_value = old.getProperty(prop)
except TypeError:
error = True
old_value = base_error_message
try:
new_value = new_getProperty(prop)
except TypeError:
error = True
new_value = base_error_message
if new_value != old_value or error:
# check if values are unicode convertible (binary are not)
if isinstance(new_value, (str, unicode)):
try:
unicode(str(new_value), 'utf-8')
except UnicodeDecodeError:
new_value = binary_data_explanation
if isinstance(old_value, (str, unicode)):
try:
unicode(str(old_value), 'utf-8')
except UnicodeDecodeError:
old_value = binary_data_explanation
if isinstance(current_value, (str, unicode)):
try:
unicode(str(current_value), 'utf-8')
except UnicodeDecodeError:
current_value = binary_data_explanation
x = {'property_name': prop,
'new_value': new_value,
'old_value': old_value,
'current_value': current_value,
}
tmp_obj = newTempBase(context,
'',
**x)
temp_obj.setUid('new_%s' % uid)
uid = uid + 1
tempbase_list.append(temp_obj)
return tempbase_list
tmp_obj.setProperty('serial', serial)
tmp_obj.setProperty('next_serial', next_serial)
tmp_obj.setProperty('action', action)
tmp_obj.setProperty('actor', actor)
tmp_obj.setProperty('time', time)
result.append(tmp_obj)
return result
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>serial, next_serial, **kw</string> </value>
<value> <string>serial, next_serial, action, actor, time, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -11,6 +11,9 @@ request = context.REQUEST
serial = getattr(brain, 'serial', '0.0.0.0')
next_serial = getattr(brain, 'next_serial', '0.0.0.0')
time = getattr(brain, 'time', '')
action = getattr(brain, 'action', '')
actor = getattr(brain, 'actor', '')
# There is no need to compare revisions in case its the
# first version.
......@@ -32,12 +35,14 @@ if serial != '0.0.0.0':
'extra_param_json': {
'serial': serial,
'next_serial': next_serial,
'time': brain.time
'time': time,
'action': action,
'actor': actor,
}
}
}
return 'Base_viewHistoricalComparison?serial=%s&amp;next_serial=%s&amp;time=%s'\
% ( serial, next_serial, brain.time )
return 'Base_viewHistoricalComparison?serial=%s&amp;next_serial=%s&amp;time=%s&amp;action=%s&amp;actor=%s'\
% ( serial, next_serial, time, action, actor )
elif url_dict:
return {}
......@@ -39,7 +39,7 @@
</item>
<item>
<key> <string>description</string> </key>
<value> <string>bar</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
......@@ -90,9 +90,7 @@
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_diff</string>
</list>
<list/>
</value>
</item>
<item>
......@@ -146,6 +144,10 @@
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -2,24 +2,10 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
<global name="ListBox" module="Products.ERP5Form.ListBox"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>columns</string>
<string>count_method</string>
<string>lines</string>
<string>list_method</string>
<string>selection_name</string>
<string>title</string>
<string>url_columns</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
......@@ -32,6 +18,10 @@
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -40,11 +30,171 @@
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<key> <string>all_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>anchor</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_display_style</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_style_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>meta_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>row_css_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<key> <string>search</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>select</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>style_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>untranslatable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>url_columns</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
......@@ -55,11 +205,173 @@
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<key> <string>all_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>anchor</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>count_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_display_style</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_style_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>list_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>meta_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>report_tree</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>row_css_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>select</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<key> <string>stat_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>style_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>untranslatable_columns</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>url_columns</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
......@@ -69,17 +381,39 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>all_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>anchor</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>path</string>
<string>property_name</string>
<string>Property Name</string>
</tuple>
<tuple>
<string>diff</string>
<string>Diff Viewer</string>
<string>old_value</string>
<string>Old Value</string>
</tuple>
<tuple>
<string>new_value</string>
<string>New Value</string>
</tuple>
<tuple>
<string>current_value</string>
<string>Current Value</string>
</tuple>
</list>
</value>
......@@ -89,43 +423,199 @@
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
<key> <string>default_display_style</string> </key>
<value> <string>table</string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<key> <string>default_params</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>display_style_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>domain_root_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>domain_tree</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>global_attributes</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>global_search_column</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>hide_rows_on_no_search_criterion</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <int>20</int> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>meta_types</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>page_navigation_template</string> </key>
<value> <string>ListBox_viewSliderPageNavigationRenderer</string> </value>
</item>
<item>
<key> <string>page_template</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>report_root_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>report_tree</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>row_css_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>search</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>search_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>select</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>historical_comparison_selection</string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>sort_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>stat_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>stat_method</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>style_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Differences</string> </value>
</item>
<item>
<key> <string>untranslatable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>url_columns</string> </key>
<value>
<list>
<tuple>
<string>path</string>
<string>property_name</string>
<string></string>
</tuple>
<tuple>
<string>diff</string>
<string>old_value</string>
<string></string>
</tuple>
<tuple>
<string>new_value</string>
<string>Base_getDiffUrl</string>
</tuple>
<tuple>
<string>current_value</string>
<string>Base_getCurrentDiffUrl</string>
</tuple>
</list>
</value>
</item>
......@@ -136,6 +626,19 @@
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>string:${here/getRelativeUrl}/HistoricalRevisions/${request/serial}/view?portal_status_message=Version%20from%20${request/time}</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list>
<string>listbox_diff</string>
</list>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_action</string>
<string>my_actor</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_datetime</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_viewHistoricalComparisonDiff</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Base_viewHistoricalComparisonDiff</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Historical Differences</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>selection_name</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>ERP5Site_viewDiffTwoObjectDialog</string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_diff</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>listbox_diff</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>ERP5Site_viewDiffTwoObjectDialog</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_action</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Action</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: request.get(\'action\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>default</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_actor</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Actor</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: request.get(\'actor\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -10,17 +10,16 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>css_class</string>
<string>date_only</string>
<string>default</string>
<string>gadget_url</string>
<string>js_sandbox</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox_diff</string> </value>
<value> <string>my_datetime</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -53,7 +52,7 @@
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<key> <string>date_only</string> </key>
<value> <string></string> </value>
</item>
<item>
......@@ -63,24 +62,16 @@
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>gadget_url</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
......@@ -94,32 +85,30 @@
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string>listbox-gadget</string> </value>
<key> <string>date_only</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_gadget_field</string> </value>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>gadget_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>js_sandbox</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Diff Viewer</string> </value>
<value> <string>Date Time</string> </value>
</item>
</dictionary>
</value>
......@@ -135,33 +124,7 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: cell.diff</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: field.restrictedTraverse(\'gadget_erp5_side_by_side_diff.html\').absolute_url()</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.Base_getDiffGadgetSandbox()</string> </value>
<value> <string>python: request.get(\'time\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
......
"""
Script that returns the list of diff of 2 historical states of ERP5 object(s).
This script gets 2 ERP5 objects based on the parameters provided, either by
using path and datetime or by using context and serial and then creates a
diff between the 2 objects.
This should is used as a 'list method' as it returns a list of temp base object
which have its properties as : `path` and `diff`.
The diff returned is a list of Tempbase object with properties `path` and `diff`.
"""
from Products.ERP5Type.Document import newTempBase
from ZODB.POSException import ConflictError
from zExceptions import Unauthorized
portal = context.getPortalObject()
portal_diff = portal.portal_diff
......@@ -12,6 +15,9 @@ request = context.REQUEST
object_revision_list = []
history_size = portal.portal_preferences.getPreferredHtmlStyleZodbHistorySize()
first_object = None
second_object = None
# In case the request has been made via action on any ERP5 object, we get the
# paths as `your_<field_name>` as this is what use as field in dialog. Hence,
# its better to check for path in the request also.
......@@ -20,69 +26,100 @@ if first_path is None:
if second_path is None:
second_path = request.get('your_second_path', None)
# Case I: When we try to access the dialog directly from `portal_diff` or from
# selections in a module. If the paths are None, then return an empty list
# or try to get the paths from selection and then return the diff.
if first_path is None and second_path is None:
list_selection_name = request.get('list_selection_name', None)
# In case the list_selection_name is there, it can be the case of selection
# from the module, hence we get the paths from the selection and use them to
# create diff.
if list_selection_name is not None:
selected_obj_list = portal.portal_selections.getSelectionCheckedValueList(selection_name=list_selection_name)
object_revision_list.extend(selected_obj_list)
# If first_path and second_path exists, get their current revision from ZODB
if first_path not in (None, ''):
first_object = portal.restrictedTraverse(first_path)
if second_path not in (None, ''):
second_object = portal.restrictedTraverse(second_path)
# Try to get the objects from the serials.
if first_serial:
if not first_object:
first_object = context
try:
first_object = first_object.HistoricalRevisions[first_serial]
except (ConflictError, Unauthorized):
raise
except Exception:
return [newTempBase(portal, context.Base_translateString('Historical revisions are'
' not available, maybe the database has been packed'))]
if second_serial:
if second_serial == '0.0.0.0':
# In case the second serial is 0.0.0.0, we should consider the second object as
# the current version of context
second_object = context
else:
# Return an empty list here. This would be the case when we first access
# the dialog and then it try to get list of items to dipslay on the listbox
return []
if not second_object:
second_object = context
try:
second_object = second_object.HistoricalRevisions[second_serial]
except (ConflictError, Unauthorized):
raise
except Exception:
return [newTempBase(portal, context.Base_translateString('Historical revisions are'
' not available, maybe the database has been packed'))]
# Case II: Get object revision from the date of the revisions.
# The default dates for revision are the 1st and 2nd
# revision dates.
if first_date not in (None, ''):
first_obj = portal.restrictedTraverse(first_path)
old_state_revision = context.Base_getRevisionFromDate(first_obj, first_date)
object_revision_list.append(old_state_revision)
if second_date not in (None, ''):
second_obj = portal.restrictedTraverse(second_path)
new_state_revision = context.Base_getRevisionFromDate(second_obj, second_date)
object_revision_list.append(new_state_revision)
# Here if the datetime and the paths exist in params, we always give priority
# to get the objects via these params.
# Case III: When the paths exist, but there is no revision given
# for the paths, we diff the current revision
if first_path != second_path:
# Diff the current verison if both the paths are different
if first_path is not None and first_date in (None, ''):
object_revision_list.append(portal.restrictedTraverse(first_path))
if second_path is not None and second_date in (None, ''):
object_revision_list.append(portal.restrictedTraverse(second_path))
else:
# If both the paths are same, diff between the current version
if (first_object is not None and (first_object == second_object)):
# If both the objects are same, diff between the current version
# and the last version(if it exists)
# Get the historical revisions for the object and check if there
# is more than one revision
obj = portal.restrictedTraverse(first_path)
revision_date_list = obj.Base_getRevisionDateList(obj, size=history_size)
revision_date_list = first_object.Base_getRevisionDateList(first_object, size=history_size)
if len(revision_date_list) > 1:
object_revision_list.append(obj.Base_getRevisionFromDate(obj, revision_date_list[1]))
object_revision_list.append(obj.Base_getRevisionFromDate(obj, revision_date_list[0]))
first_object = first_object.Base_getRevisionFromDate(first_object, revision_date_list[1])
second_object = second_object.Base_getRevisionFromDate(second_object, revision_date_list[0])
# Get object revision from the date of the revisions.
# The default dates for revision are the 1st and 2nd
# revision dates.
if first_date not in (None, ''):
if isinstance(first_object, dict):
# If the object type is dictionary because historical revisions are present
# as dictionaries, then we get the object using restrictedTraverse
first_object = portal.restrictedTraverse(first_path)
first_object = context.Base_getRevisionFromDate(first_object, first_date)
if second_date not in (None, ''):
if isinstance(second_object, dict):
second_object = portal.restrictedTraverse(second_path)
second_object = context.Base_getRevisionFromDate(second_object, second_date)
# When we try to access the dialog directly from `portal_diff` or from
# selections in a module. If the paths are None, then return an empty list
# or try to get the paths from selection and then return the diff.
if ((first_path is None and second_path is None) and
(first_object is None and second_object is None)):
# Make sure to always check if the first_object and second_object is empty, because this script
# is used outside of Diff Tool also, where we might have list_selection_name which will
# end up getting useless selection.
list_selection_name = request.get('list_selection_name', None)
# In case the list_selection_name is there, it can be the case of selection
# from the module, hence we get the paths from the selection and use them to
# create diff.
if list_selection_name is not None:
selected_object_list = portal.portal_selections.getSelectionCheckedValueList(
selection_name=list_selection_name)
first_object = selected_object_list[0]
second_object = selected_object_list[1]
# Use DiffTool to get the diff between the 2 objects in object_revision_list List.
# These 2 objects can be revisions of same object, 2 different revisions of
# different objects or 2 current ERP5 object.
if len(object_revision_list) > 1:
# Using this last 2 Historical revision dicts, create a Diff
diff_list = portal_diff.diffPortalObject(object_revision_list[0], object_revision_list[1]).asBeautifiedJSONDiff()
if first_object and second_object:
diff_list = portal_diff.diffPortalObject(first_object, second_object).asBeautifiedJSONDiff()
# Return a list of TempBase objects which can be displayed in a listbox
uid = 1
tempbase_list = []
for diff_unit in diff_list:
temp_obj = newTempBase(portal,
temp_object = newTempBase(portal,
diff_unit['path'],
**diff_unit)
temp_obj.setUid(uid)
temp_object.setUid(uid)
uid = uid + 1
tempbase_list.append(temp_obj)
tempbase_list.append(temp_object)
return tempbase_list
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>first_date=None, second_date=None, first_path=None, second_path=None, **kw</string> </value>
<value> <string>first_date=None, second_date=None, first_path=None, second_path=None, first_serial=None, second_serial=None, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -172,6 +172,7 @@ portal_actions | search
portal_actions | sort_on
portal_actions | types_tool
portal_actions | view_historical_comparison
portal_actions | view_historical_diff
portal_membership | login
portal_membership | logout
portal_membership | preferences
......
......@@ -239,7 +239,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'object_action': [{'id': 'post_query', 'title': 'Post a Query'},
{'id': 'diff_object_action', 'title': 'Diff Object'}],
'object_hidden': [{'id': 'view_historical_comparison',
'title': 'View Historical Comparison'}],
'title': 'View Historical Comparison'},
{'id': 'view_historical_diff',
'title': 'View Historical Diff'}],
'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'},
{'id': 'jump_query', 'title': 'Queries'}],
'object_search': [{'title': 'Search', 'id': 'search'}],
......@@ -263,7 +265,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'object': [],
'object_action': [{'id': 'diff_object_action', 'title': 'Diff Object'}],
'object_hidden': [{'id': 'view_historical_comparison',
'title': 'View Historical Comparison'}],
'title': 'View Historical Comparison'},
{'id': 'view_historical_diff',
'title': 'View Historical Diff'}],
'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}],
'object_search': [{'title': 'Search', 'id': 'search'}],
'object_sort': [{'title': 'Sort', 'id': 'sort_on'}],
......@@ -282,7 +286,9 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
'object': [],
'object_action': [{'id': 'diff_object_action', 'title': 'Diff Object'}],
'object_hidden': [{'id': 'view_historical_comparison',
'title': 'View Historical Comparison'}],
'title': 'View Historical Comparison'},
{'id': 'view_historical_diff',
'title': 'View Historical Diff'}],
'object_jump': [{'id': 'jump_related_object', 'title': 'Related Objects'}],
'object_search': [{'title': 'Search', 'id': 'search'}],
'object_sort': [{'title': 'Sort', 'id': 'sort_on'}],
......
......@@ -50,7 +50,7 @@ class TestXHTMLMixin(ERP5TypeTestCase):
# some forms have intentionally empty listbox selections like RSS generators
FORM_LISTBOX_EMPTY_SELECTION_PATH_LIST = ['erp5_web_widget_library/WebSection_viewContentListAsRSS',
'erp5_core/Base_viewHistoricalComparison',
'erp5_core/Base_viewHistoricalComparisonDiff',
'erp5_diff/ERP5Site_viewDiffTwoObjectDialog',]
JSL_IGNORE_FILE_LIST = (
'diff2html.js',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment