Commit 89ef7b43 authored by Romain Courteaud's avatar Romain Courteaud :octopus:
Browse files

[erp5_web_renderjs_ui] Rewrite the URL navigation handling

Stop using the patched renderJS version which forces to use a fix URL pattern (#a=b&c=d).
Instead, the URL logic was moved to the router gadget which becomes responsible to build and parse URL.

This will allow applications to support their own URL pattern (HTML5 pushState for example).

In case of the ERP5 JS UI, it provides now a stateful URL building (next URL depends on the current one).

This is used to support browser side "selection" (ie, stored query parameters), needed to support pagination from one document to another.
Example:
  * go to a module
  * filter with a search
  * click on the first document line and review it
  * click on the "next" icon, to directly see the second document without going back to the list

Stateful URL are also used to provides a "global" navigation history on the browser side.
  Example:
   * go to a module
   * click on the first document (A) and review it
   * use a jump button to go to a linked document (B) and review it
   * click on the "back" button to go back to A
   * click on the "back" button to go back to the module
Please note that this history works even if you open a new tab, as it is persistent in IndexedDB.
TODO: it will be required to clean IndexedDB from time to time to not fill it

The current URL patterns are:
  #/jio_key?a=b&c=d (used to display an ERP5 document)
  #!command?a=b&c=d (used to apply some operations on the URL)
parent 5abadc55
master accessor_setter_security accounting_constraint_bug_ignore_acquired_source_destination_when_closing accounting_grouping_reference_ignore_mirror_account bt_review budget_component budget_time_variation cleanup/translation_mapping_utf8 cleanup_interface code_mirror code_mirror_jerome_patches_2file_bt codemirror_5.13.4 delivery_type_information dist-0.4.63 do_not_modify_folder_while_migratinng erp5-vifib-print-and-hashseed feat/accounting_add_back_third_party_column_in_gl feat/accounting_balance_sheet_profit_and_loss_cleanups feat/accounting_grouping_dialog_search_by_section_category_and_fixs feat/accounting_internal_invoice feat/accounting_sort_aged_balance feat/activities-clean-shutdown feat/bank_reconciliation_direct_stock_columns feat/bt_xml_zope2_zope4 feat/cmfactivity_notification feat/coverage feat/data_protection feat/doc-generator feat/jedi feat/less-seleniumrunner-install feat/line-report-parrallel feat/monaco-ruff feat/note_before_migration feat/pdm_measure_cell_range feat/py2zope4 feat/random_runUnitTest_port feat/remove_owner_role_permissions_on_document_workflow feat/restricted_collections feat/simplemde feat/simplemde-text-editor feat/support_request_translation feat/yapf fix/#20170313-5DDBB0 fix/988_workaround fix/auth-cookies fix/bug_20161227-D1FA4 fix/category-export fix/check_authentication_policy fix/configurator_consistency fix/control-characters-in-odf-syles fix/egg_test_revision_history fix/enable-xml-rpc fix/erp5testnode-build-failures fix/graph_editor fix/hashseed fix/mobyt-new-url fix/python3-syntax fix/remove_obfuscated_url_from_test fix/runUnitTest_localhost fix/testnode-killProcess fix/testnode-loose-supervisord fix/testnode_proctitle fix/trial_balance_empty_gap for_testrunner_1 inventory_api_do_not_group_movement_history_list inventory_api_flow inventory_api_group_by_time_sequence inventory_api_group_by_time_sequence_backport_master_no_guard_on_workflow_transition inventory_api_group_by_time_sequence_first_try inventory_api_group_by_time_sequence_rebased inventory_api_interpolation_method jerome_clone_transformation ledger_vs_grouping_reference linecache_ipython3 listbox_module_proxy_field listbox_proxy_field_more_columns listbox_unicode_url_method live_test_lets_crash master_calendar_wip_patchs master_no_guard_on_workflow_transition_plus_calendar_wip_patchs_plus_upgrader_refactoring move_budget_to_component ods_style_sheet_per_report_section_deferred_style_before_rebase ooo_url_remove_address_port periodicity_getNextPeriodicityDate_test_give_up py2zope4 pyflake_vs_pylint sms_activate_before_rebase sms_more_than_140_characters spellcheck_slowdown_chrome style_on_accounting_reports tax_return_and_type_of_type test/selenium_repro tmp/authentication_policy2_wip tmp/authentication_policy_fixes_before_rebase tmp/authentication_policy_no_immediateReindex tmp/constructUrlFor tmp/georges tmp/invalid_html_to_verify_w3_validator tmp/mr185_review tmp/rjs-translations tmp/tmp tmp/tmpx tmp1 tmp_commits_for_nicolas upgrader_post_upgrade_after_upgrade_activities web_site_clone_before_traversal_hooks wip/adapative_folder_mt_index wip/catalog_tool_extra_column_list_for_inventory_api_slot_index wip/chartsjs_and_worklists wip/cmf_activity_runtime_grouped wip/component_editor_gadget wip/configurator_trade wip/copy_reg_NamedAssignment wip/corporate_cloudooo_fonts wip/empty_criterion wip/feat/payment_transaction_group_ERPJS wip/interpolation_0_rebase wip/loyalty_with_tml wip/monaco wip/monaco-editor wip/monaco-jshint wip/neo wip/quick_erp5_test wip/restricted_iterator wip/seleniumserver wip/stock_browser wip/testUpgradeInstanceWithOldDataFs_reference_json wip/testnode-kill-previous-before-reinitializing wip/tmp wip/wip wip/xiaowu_convert_round_debit_credit wip_search_portal_component wipwipwip work zope4py2 zope4py2b zope4py3 zope4py3-before-arnaud-rebase zope4py3-bt-protocol1onpy3 zope4py3-rebase-starting-point zope4py3-tmp zope4py3-wip 0.4.59.1 0.4.59 wip/configurator_trade_old erp5.util-0.4.64 erp5.util-0.4.63 erp5.util-0.4.62 erp5.util-0.4.61 erp5.util-0.4.58 erp5.util-0.4.57 erp5.util-0.4.56 erp5.util-0.4.55 erp5.util-0.4.54 erp5.util-0.4.53 erp5.util-0.4.52 erp5.util-0.4.49 erp5.util-0.4.46 erp5.util-0.4.44
No related merge requests found
......@@ -99,9 +99,11 @@
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string>/*global window, rJS, RSVP */\n
/*jslint indent: 2, maxerr: 3 */\n
(function (window, rJS, RSVP) {\n
<value> <string encoding="cdata"><![CDATA[
/*global window, rJS, RSVP, UriTemplate, URI */\n
/*jslint indent: 2, maxerr: 3, nomen: true */\n
(function (window, rJS, RSVP, UriTemplate, URI) {\n
"use strict";\n
\n
rJS(window)\n
......@@ -134,9 +136,44 @@
});\n
})\n
\n
.declareMethod(\'allDocs\', function () {\n
.declareMethod(\'allDocs\', function (option_dict) {\n
// throw new Error(\'do not use all docs\');\n
var storage = this.state_parameter_dict.jio_storage;\n
return storage.allDocs.apply(storage, arguments);\n
\n
if (option_dict.list_method_template === undefined) {\n
return storage.allDocs.apply(storage, arguments);\n
}\n
return storage.getAttachment(\n
// XXX Ugly hardcoded meaningless id...\n
"erp5",\n
new UriTemplate.parse(option_dict.list_method_template)\n
.expand(option_dict),\n
{format: "json"}\n
)\n
.push(function (catalog_json) {\n
var data = catalog_json._embedded.contents,\n
count = data.length,\n
k,\n
uri,\n
item,\n
result = [];\n
for (k = 0; k < count; k += 1) {\n
item = data[k];\n
uri = new URI(item._links.self.href);\n
delete item._links;\n
result.push({\n
id: uri.segment(2),\n
doc: {},\n
value: item\n
});\n
}\n
return {\n
data: {\n
rows: result,\n
total_rows: result.length\n
}\n
};\n
});\n
})\n
.declareMethod(\'getAttachment\', function (id, name) {\n
return this.state_parameter_dict.jio_storage.getAttachment(id, name, {format: "json"});\n
......@@ -145,7 +182,9 @@
return this.state_parameter_dict.jio_storage.putAttachment(id, name, JSON.stringify(json));\n
});\n
\n
}(window, rJS, RSVP));</string> </value>
}(window, rJS, RSVP, UriTemplate, URI));
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
......@@ -280,7 +319,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.54088.9321.61678</string> </value>
<value> <string>946.24288.2744.26624</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -298,7 +337,7 @@
</tuple>
<state>
<tuple>
<float>1442582911.35</float>
<float>1444640714.39</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -304,11 +304,6 @@
//////////////////////////////////////////\n
// Page rendering\n
//////////////////////////////////////////\n
/*\n
function redirectToDefaultPage(gadget) {\n
return gadget.pleaseRedirectMyHash(\'#\');\n
}\n
*/\n
rJS(window)\n
.ready(function (g) {\n
g.props = {};\n
......@@ -382,11 +377,12 @@
return panel_gadget.render();\n
});\n
})\n
\n
//////////////////////////////////////////\n
// Acquired method\n
//////////////////////////////////////////\n
.declareAcquiredMethod(\'pleaseRedirectMyHash\', \'pleaseRedirectMyHash\')\n
.ready(function (g) {\n
return g.getDeclaredGadget(\'router\')\n
.push(function (router_gadget) {\n
return router_gadget.start();\n
});\n
})\n
\n
//////////////////////////////////////////\n
// Allow Acquisition\n
......@@ -422,16 +418,32 @@
return translation_gadget.translate(argument_list[0]);\n
});\n
})\n
\n
.allowPublicAcquisition("redirect", function (param_list) {\n
var gadget = this;\n
return gadget.aq_pleasePublishMyState.apply(gadget, param_list)\n
.push(gadget.pleaseRedirectMyHash.bind(gadget));\n
return this.getDeclaredGadget(\'router\')\n
.push(function (router_gadget) {\n
return router_gadget.getCommandUrlFor.apply(router_gadget,\n
param_list);\n
})\n
.push(function (hash) {\n
window.location.replace(hash);\n
});\n
})\n
.allowPublicAcquisition(\'reload\', function () {\n
return location.reload();\n
})\n
.allowPublicAcquisition("getUrlParameter", function (param_list) {\n
return this.getDeclaredGadget(\'router\')\n
.push(function (router_gadget) {\n
return router_gadget.getUrlParameter.apply(router_gadget, param_list);\n
});\n
})\n
.allowPublicAcquisition("getUrlFor", function (param_list) {\n
return this.aq_pleasePublishMyState(param_list[0]);\n
return this.getDeclaredGadget(\'router\')\n
.push(function (router_gadget) {\n
return router_gadget.getCommandUrlFor.apply(router_gadget,\n
param_list);\n
});\n
})\n
\n
.allowPublicAcquisition("updateHeader", function (param_list) {\n
......@@ -475,7 +487,6 @@
}\n
}\n
if (count > 2) {\n
console.log(\'Has subheader\');\n
gadget.props.sub_header_class = "ui-has-subheader";\n
}\n
});\n
......@@ -515,8 +526,11 @@
/////////////////////////////////////////////////////////////////\n
// declared methods\n
/////////////////////////////////////////////////////////////////\n
.allowPublicAcquisition("renderApplication", function (param_list) {\n
return this.renderXXX.apply(this, param_list);\n
})\n
// Render the page\n
.declareMethod(\'render\', function (options) {\n
.declareMethod(\'renderXXX\', function (options) {\n
var gadget = this;\n
\n
gadget.props.options = options;\n
......@@ -762,7 +776,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.54027.26221.22152</string> </value>
<value> <string>946.35764.39446.32955</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -780,7 +794,7 @@
</tuple>
<state>
<tuple>
<float>1442581058.21</float>
<float>1445329252.77</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -136,10 +136,9 @@
// acquired method\n
//////////////////////////////////////////////\n
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")\n
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")\n
.declareAcquiredMethod("translateHtml", "translateHtml")\n
.declareAcquiredMethod("getUrlFor", "getUrlFor")\n
.declareAcquiredMethod("pleasePublishMyState", "pleasePublishMyState")\n
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")\n
.declareAcquiredMethod("getFieldTypeGadgetUrl", "getFieldTypeGadgetUrl")\n
//////////////////////////////////////////////\n
// initialize the gadget content\n
......@@ -155,7 +154,6 @@
i;\n
\n
gadget.props.field_json = field_json;\n
gadget.props.begin_from = parseInt(options.begin_from, 10) || 0;\n
gadget.props.extended_search = options.extended_search;\n
if (field_json.show_anchor) {\n
th = document.createElement("th");\n
......@@ -172,6 +170,14 @@
thead.appendChild(tr);\n
return new RSVP.Queue()\n
.push(function () {\n
// XXX Fix in case of multiple listboxes\n
return gadget.getUrlParameter(field_json.key + \'_begin_from\');\n
})\n
.push(function (result) {\n
if (result === undefined) {\n
result = \'0\';\n
}\n
gadget.props.begin_from = parseInt(result, 10) || 0;\n
return gadget.translateHtml(document_table.innerHTML);\n
})\n
.push(function (my_translate_html) {\n
......@@ -197,9 +203,8 @@
dataset,\n
counter,\n
i,\n
list_method_promise = function () {\n
return gadget.jio_allDocs.apply(gadget, arguments);\n
};\n
gadget_path;\n
\n
if (field_json.query === undefined) {\n
original_tfoot.textContent = "Unsupported list method: \'" + field_json.list_method + "\'";\n
return;\n
......@@ -217,51 +222,30 @@
select_list.push(field_json.column_list[i][0]);\n
}\n
\n
if (field_json.list_method_template !== undefined) {\n
list_method_promise = function (option_dict) {\n
return gadget.jio_getAttachment(\n
// XXX Ugly hardcoded meaningless id...\n
"erp5",\n
new UriTemplate.parse(field_json.list_method_template)\n
.expand(option_dict)\n
)\n
.push(function (catalog_json) {\n
var data = catalog_json._embedded.contents,\n
count = data.length,\n
k,\n
uri,\n
item,\n
result = [];\n
for (k = 0; k < count; k += 1) {\n
item = data[k];\n
uri = new URI(item._links.self.href);\n
delete item._links;\n
result.push({\n
id: uri.segment(2),\n
doc: {},\n
value: item\n
});\n
}\n
return {\n
data: {\n
rows: result,\n
total_rows: result.length\n
}\n
};\n
});\n
};\n
}\n
\n
return list_method_promise({\n
"query": new URI(field_json.query).query(true).query + query_string,\n
"limit": [begin_from, begin_from + lines + 1],\n
"select_list": select_list\n
}).push(function (result) {\n
return this.getGadgetPath()\n
.push(function (result) {\n
gadget_path = result;\n
return gadget.jio_allDocs({\n
// XXX Not jIO compatible, but until a better api is found...\n
"list_method_template": field_json.list_method_template,\n
"query": new URI(field_json.query).query(true).query + query_string,\n
"limit": [begin_from, lines + 1],\n
"select_list": select_list\n
});\n
}).push(function (result) {\n
var promise_list = [result];\n
counter = Math.min(result.data.total_rows, lines);\n
for (i = 0; i < counter; i += 1) {\n
promise_list.push(\n
gadget.getUrlFor({jio_key: result.data.rows[i].id})\n
gadget.getUrlFor({\n
command: \'index\',\n
options: {\n
jio_key: result.data.rows[i].id,\n
selection_index: begin_from + i,\n
query: new URI(field_json.query).query(true).query + query_string,\n
list_method_template: field_json.list_method_template\n
}\n
})\n
);\n
}\n
return RSVP.all(promise_list);\n
......@@ -355,20 +339,19 @@
\n
function setNext() {\n
if (dataset.data.rows.length > lines) {\n
next_param.begin_from = begin_from + lines;\n
next_param[gadget.props.field_json.key + \'_begin_from\'] = begin_from + lines;\n
}\n
}\n
\n
if (begin_from === 0) {\n
setNext();\n
} else {\n
prev_param.begin_from = begin_from - lines;\n
prev_param[gadget.props.field_json.key + \'_begin_from\'] = begin_from - lines;\n
setNext();\n
}\n
\n
return RSVP.all([\n
gadget.pleasePublishMyState(prev_param),\n
gadget.pleasePublishMyState(next_param)\n
gadget.getUrlFor({command: \'change\', options: prev_param}),\n
gadget.getUrlFor({command: \'change\', options: next_param})\n
]);\n
\n
}).push(function (url_list) {\n
......@@ -626,7 +609,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52783.20655.48793</string> </value>
<value> <string>946.34578.58020.60808</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -644,7 +627,7 @@
</tuple>
<state>
<tuple>
<float>1442504640.91</float>
<float>1445266646.36</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -292,7 +292,12 @@ promiseEventListener */\n
if (field_json.allow_jump && allow_jump) {\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.getUrlFor({jio_key: field_json.relation_item_relative_url[i]});\n
return gadget.getUrlFor({\n
command: \'index\',\n
options: {\n
jio_key: field_json.relation_item_relative_url[i]\n
}\n
});\n
})\n
.push(function (my_url) {\n
a2.href = my_url;\n
......@@ -475,7 +480,12 @@ promiseEventListener */\n
props.select_uid_list[i] = element.getAttribute("name");\n
wrapper.querySelector("input").value = element.textContent;\n
clearResults(wrapper, "skip");\n
return my_gadget.getUrlFor({jio_key: jump_url});\n
return my_gadget.getUrlFor({\n
command: \'index\',\n
options: {\n
jio_key: jump_url\n
}\n
});\n
}\n
}).push(function (my_url) {\n
if (my_url !== undefined) {\n
......@@ -683,7 +693,7 @@ promiseEventListener */\n
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52422.65165.14080</string> </value>
<value> <string>945.52745.24179.54220</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -701,7 +711,7 @@ promiseEventListener */\n
</tuple>
<state>
<tuple>
<float>1442502322.12</float>
<float>1444984956.18</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -155,10 +155,10 @@
return new RSVP.Queue()\n
.push(function () {\n
return RSVP.all([\n
g.getUrlFor({page: "front"}),\n
g.getUrlFor({page: "history"}),\n
g.getUrlFor({page: "preference"}),\n
g.getUrlFor({page: "logout"})\n
g.getUrlFor({command: \'display\', options: {page: "front"}}),\n
g.getUrlFor({command: \'display\', options: {page: "history"}}),\n
g.getUrlFor({command: \'display\', options: {page: "preference"}}),\n
g.getUrlFor({command: \'display\', options: {page: "logout"}})\n
]);\n
})\n
.push(function (all_result) {\n
......@@ -344,7 +344,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.53861.25077.18602</string> </value>
<value> <string>946.30031.56342.5324</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -362,7 +362,7 @@
</tuple>
<state>
<tuple>
<float>1442569620.96</float>
<float>1444985342.36</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -154,8 +154,8 @@
.push(function (result) {\n
var i,\n
promise_list = [\n
gadget.getUrlFor({jio_key: options.jio_key, view: options.view, editable: options.editable}),\n
gadget.getUrlFor({jio_key: options.jio_key, view: options.view, editable: options.editable, page: "breadcrumb"})\n
gadget.getUrlFor({command: \'change\', options: {page: undefined}}),\n
gadget.getUrlFor({command: \'change\', options: {page: "breadcrumb"}})\n
];\n
erp5_document = result;\n
view_list = erp5_document._links.action_workflow || [];\n
......@@ -165,10 +165,7 @@
}\n
\n
for (i = 0; i < view_list.length; i += 1) {\n
promise_list.push(gadget.getUrlFor({\n
jio_key: options.jio_key,\n
view: view_list[i].href\n
}));\n
promise_list.push(gadget.getUrlFor({command: \'change\', options: {view: view_list[i].href, page: undefined, editable: undefined}}));\n
}\n
return RSVP.all(promise_list);\n
})\n
......@@ -340,7 +337,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52786.43920.26777</string> </value>
<value> <string>946.30039.19211.22562</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -358,7 +355,7 @@
</tuple>
<state>
<tuple>
<float>1442504825.27</float>
<float>1444985792.56</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -165,7 +165,7 @@
});\n
} else {\n
// Parent is an ERP5 document\n
return gadget.getUrlFor({jio_key: jio_key})\n
return gadget.getUrlFor({command: \'display\', options: {jio_key: jio_key}})\n
.push(function (parent_href) {\n
parent_list.unshift({\n
title: parent_link.name,\n
......@@ -182,7 +182,7 @@
});\n
}\n
\n
return gadget.getUrlFor({jio_key: options.jio_key, view: options.view, editable: options.editable})\n
return gadget.getUrlFor({command: \'change\', options: {page: undefined}})\n
.push(function (back_url) {\n
header_options.back_url = back_url;\n
return gadget.jio_getAttachment(options.jio_key, "links");\n
......@@ -343,7 +343,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52768.52090.60757</string> </value>
<value> <string>946.30044.42475.51968</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -361,7 +361,7 @@
</tuple>
<state>
<tuple>
<float>1442504878.86</float>
<float>1444986060.46</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -212,8 +212,8 @@
section.innerHTML = my_translation_html;\n
return RSVP.all([\n
erp5_form.render(form_options),\n
form_gadget.getUrlFor({jio_key: form_gadget.props.id}),\n
form_gadget.getUrlFor({jio_key: form_gadget.props.id, page: "breadcrumb"})\n
form_gadget.getUrlFor({command: \'change\', options: {page: undefined, view: undefined}}),\n
form_gadget.getUrlFor({command: \'change\', options: {page: "breadcrumb"}})\n
]);\n
})\n
.push(function (all_result) {\n
......@@ -265,11 +265,11 @@
var location = evt.target.getResponseHeader("X-Location");\n
if (location === undefined || location === null) {\n
// No redirection, stay on the same document\n
return form_gadget.getUrlFor({jio_key: form_gadget.props.id, view: "view"});\n
return form_gadget.getUrlFor({command: \'change\', options: {view: "view", page: undefined}});\n
}\n
return RSVP.all([\n
form_gadget.notifySubmitted(),\n
form_gadget.redirect({jio_key: new URI(location).segment(2), editable: form_gadget.props.editable})\n
form_gadget.redirect({command: \'display\', options: {jio_key: new URI(location).segment(2), editable: form_gadget.props.editable}})\n
]);\n
});\n
}\n
......@@ -420,7 +420,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.54063.48707.15940</string> </value>
<value> <string>946.30291.61878.2013</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -438,7 +438,7 @@
</tuple>
<state>
<tuple>
<float>1442581458.69</float>
<float>1445000905.46</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -122,6 +122,12 @@
\n
</head>\n
<body>\n
\n
<!-- XXX action, method, fieldset -->\n
<form class="dialog_form">\n
<button type="submit" data-i18n="Submit" class="ui-btn ui-btn-b ui-btn-inline\n
ui-icon-action ui-btn-icon-right ui-screen-hidden">Submit</button>\n
\n
<div data-gadget-url="gadget_erp5_searchfield.html"\n
data-gadget-scope="erp5_searchfield"\n
data-gadget-sandbox="public"></div>\n
......@@ -129,6 +135,8 @@
<div data-gadget-url="gadget_erp5_form.html"\n
data-gadget-scope="erp5_form"\n
data-gadget-sandbox="public"></div>\n
\n
</form>\n
\n
</body>\n
</html>
......@@ -268,7 +276,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>936.46405.53164.22289</string> </value>
<value> <string>945.61017.50891.24046</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -286,7 +294,7 @@
</tuple>
<state>
<tuple>
<float>1407339467.24</float>
<float>1442998685.54</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -99,18 +99,41 @@
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string>/*global window, rJS, RSVP */\n
<value> <string>/*global window, rJS, RSVP, loopEventListener */\n
/*jslint nomen: true, indent: 2, maxerr: 3 */\n
(function (window, rJS, RSVP) {\n
(function (window, rJS, RSVP, loopEventListener) {\n
"use strict";\n
\n
rJS(window)\n
/////////////////////////////////////////////////////////////////\n
// ready\n
/////////////////////////////////////////////////////////////////\n
// Init local properties\n
.ready(function (g) {\n
g.props = {};\n
})\n
\n
// Assign the element to a variable\n
.ready(function (g) {\n
return g.getElement()\n
.push(function (element) {\n
g.props.element = element;\n
});\n
})\n
\n
.ready(function (g) {\n
return g.getGadgetPath()\n
.push(function (path) {\n
g.props.path = path;\n
});\n
})\n
/////////////////////////////////////////////////////////////////\n
// Acquired methods\n
/////////////////////////////////////////////////////////////////\n
.declareAcquiredMethod("updateHeader", "updateHeader")\n
.declareAcquiredMethod("getUrlFor", "getUrlFor")\n
.declareAcquiredMethod("redirect", "redirect")\n
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")\n
\n
/////////////////////////////////////////////////////////////////\n
// declared methods\n
......@@ -122,18 +145,21 @@
\n
form_options.erp5_document = options.erp5_document;\n
form_options.form_definition = options.form_definition;\n
// XXX not generic, fix later\n
if (options.erp5_searchfield) {\n
form_options.form_definition.extended_search = options.erp5_searchfield.extended_search;\n
search_options.extended_search = options.erp5_searchfield.extended_search;\n
}\n
form_options.view = options.view;\n
\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.getUrlParameter(\'extended_search\');\n
})\n
.push(function (extended_search) {\n
// XXX not generic, fix later\n
if (extended_search) {\n
form_options.form_definition.extended_search = extended_search;\n
search_options.extended_search = extended_search;\n
}\n
var new_content_action = options.erp5_document._links.action_object_new_content_action;\n
if (new_content_action !== undefined) {\n
new_content_action = gadget.getUrlFor({jio_key: options.jio_key, view: new_content_action.href, editable: true});\n
new_content_action = gadget.getUrlFor({command: \'change\', options: {view: new_content_action.href, editable: true}});\n
} else {\n
new_content_action = "";\n
}\n
......@@ -141,9 +167,9 @@
return RSVP.all([\n
gadget.getDeclaredGadget("erp5_searchfield"),\n
gadget.getDeclaredGadget("erp5_form"),\n
gadget.getUrlFor({jio_key: options.jio_key, view: options.view, page: "breadcrumb"}),\n
gadget.getUrlFor({command: \'change\', options: {page: "breadcrumb"}}),\n
new_content_action,\n
gadget.getUrlFor({jio_key: options.jio_key, page: "action", view: options.view})\n
gadget.getUrlFor({command: \'change\', options: {page: "action"}})\n
]);\n
})\n
.push(function (all_gadget) {\n
......@@ -164,9 +190,30 @@
]);\n
});\n
\n
})\n
\n
.declareService(function () {\n
var gadget = this;\n
\n
function formSubmit() {\n
return gadget.getDeclaredGadget("erp5_searchfield")\n
.push(function (search_gadget) {\n
return search_gadget.getContent();\n
})\n
.push(function (data) {\n
return gadget.redirect({command: \'change\', options: {extended_search: data.search, begin_from: undefined}});\n
});\n
}\n
// Listen to form submit\n
return loopEventListener(\n
gadget.props.element.querySelector(\'form\'),\n
\'submit\',\n
false,\n
formSubmit\n
);\n
});\n
\n
}(window, rJS, RSVP));</string> </value>
}(window, rJS, RSVP, loopEventListener));</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......@@ -301,7 +348,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52360.36060.34423</string> </value>
<value> <string>946.34728.38206.10615</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -319,7 +366,7 @@
</tuple>
<state>
<tuple>
<float>1442480580.57</float>
<float>1445329431.72</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -99,9 +99,9 @@
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string>/*global window, rJS, RSVP, loopEventListener, URI, document */\n
<value> <string>/*global window, rJS, RSVP, loopEventListener, document */\n
/*jslint nomen: true, indent: 2, maxerr: 3 */\n
(function (window, rJS, RSVP, loopEventListener, URI) {\n
(function (window, rJS, RSVP, loopEventListener) {\n
"use strict";\n
\n
rJS(window)\n
......@@ -161,19 +161,19 @@
\n
new_content_action = options.erp5_document._links.action_object_new_content_action;\n
if (new_content_action !== undefined) {\n
new_content_action = form_gadget.getUrlFor({jio_key: options.jio_key, view: new_content_action.href, editable: true});\n
new_content_action = form_gadget.getUrlFor({command: \'change\', options: {view: new_content_action.href, editable: true}});\n
} else {\n
new_content_action = "";\n
}\n
\n
return RSVP.all([\n
erp5_form.render(form_options),\n
form_gadget.getUrlFor({jio_key: options.jio_key}),\n
form_gadget.getUrlFor({jio_key: options.jio_key, page: "tab", view: options.view}),\n
form_gadget.getUrlFor({jio_key: options.jio_key, page: "action", view: options.view, editable: true}),\n
form_gadget.getUrlFor({jio_key: options.jio_key, page: "breadcrumb", view: options.view, editable: true}),\n
form_gadget.getUrlFor({command: \'change\', options: {}}),\n
form_gadget.getUrlFor({command: \'change\', options: {page: "tab"}}),\n
form_gadget.getUrlFor({command: \'change\', options: {page: "action", editable: true}}),\n
form_gadget.getUrlFor({command: \'change\', options: {page: "breadcrumb", editable: true}}),\n
new_content_action,\n
form_gadget.getUrlFor({jio_key: (new URI(options.erp5_document._links.parent.href)).segment(2)})\n
form_gadget.getUrlFor({command: \'history_previous\'})\n
]);\n
})\n
.push(function (all_result) {\n
......@@ -238,7 +238,7 @@
);\n
});\n
\n
}(window, rJS, RSVP, loopEventListener, URI));</string> </value>
}(window, rJS, RSVP, loopEventListener));</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......@@ -373,7 +373,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52387.43932.904</string> </value>
<value> <string>946.30054.11308.16162</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -391,7 +391,7 @@
</tuple>
<state>
<tuple>
<float>1442505369.77</float>
<float>1445329477.85</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -101,9 +101,9 @@
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*global window, rJS, RSVP, URI */\n
/*global window, rJS, RSVP */\n
/*jslint nomen: true, indent: 2, maxerr: 3 */\n
(function (window, rJS, RSVP, URI) {\n
(function (window, rJS, RSVP) {\n
"use strict";\n
\n
// Precompile the templates while loading the first gadget instance\n
......@@ -154,10 +154,12 @@
\n
return RSVP.all([\n
form_gadget.render(form_options),\n
gadget.getUrlFor({jio_key: options.jio_key, view: options.view, editable: true}),\n
gadget.getUrlFor({jio_key: options.jio_key, page: "action", view: options.view}),\n
gadget.getUrlFor({jio_key: options.jio_key, page: "breadcrumb", view: options.view}),\n
gadget.getUrlFor({jio_key: (new URI(options.erp5_document._links.parent.href)).segment(2)})\n
gadget.getUrlFor({command: \'change\', options: {editable: true}}),\n
gadget.getUrlFor({command: \'change\', options: {page: "action"}}),\n
gadget.getUrlFor({command: \'change\', options: {page: "breadcrumb"}}),\n
gadget.getUrlFor({command: \'history_previous\'}),\n
gadget.getUrlFor({command: \'selection_previous\'}),\n
gadget.getUrlFor({command: \'selection_next\'})\n
]);\n
})\n
.push(function (all_result) {\n
......@@ -165,8 +167,8 @@
return gadget.updateHeader({\n
jump_url: "",\n
actions_url: all_result[2],\n
previous_url: "",\n
next_url: "",\n
previous_url: all_result[5],\n
next_url: all_result[6],\n
export_url: "",\n
edit_url: all_result[1],\n
selection_url: all_result[4],\n
......@@ -176,7 +178,7 @@
});\n
});\n
\n
}(window, rJS, RSVP, URI));
}(window, rJS, RSVP));
]]></string> </value>
</item>
......@@ -313,7 +315,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52385.13762.21094</string> </value>
<value> <string>946.35769.25581.7594</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -331,7 +333,7 @@
</tuple>
<state>
<tuple>
<float>1442481653.09</float>
<float>1445329536.24</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -156,7 +156,7 @@
i;\n
for (i = 0; i < result.data.rows.length; i += 1) {\n
result_list.push(RSVP.all([\n
gadget.getUrlFor({jio_key: result.data.rows[i].id}),\n
gadget.getUrlFor({command: \'display\', options: {jio_key: result.data.rows[i].id}}),\n
result.data.rows[i].value.title || result.data.rows[i].id,\n
result.data.rows[i].value.business_application_title\n
]));\n
......@@ -369,7 +369,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.49517.32009.34013</string> </value>
<value> <string>946.4325.1841.2867</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -387,7 +387,7 @@
</tuple>
<state>
<tuple>
<float>1442308668.56</float>
<float>1445266444.15</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -167,16 +167,17 @@
if (options.view === view_list[i].href) {\n
matching = i;\n
}\n
promise_list.push(gadget.getUrlFor({\n
jio_key: options.jio_key,\n
promise_list.push(gadget.getUrlFor({command: \'change\', options: {\n
view: view_list[i].href,\n
editable: true\n
}));\n
editable: true,\n
page: undefined\n
}}));\n
}\n
promise_list.push(gadget.getUrlFor({\n
jio_key: options.jio_key,\n
view: "view"\n
}));\n
promise_list.push(gadget.getUrlFor({command: \'change\', options: {\n
view: "view",\n
page: undefined,\n
editable: undefined\n
}}));\n
return RSVP.all(promise_list);\n
})\n
.push(function (all_result) {\n
......@@ -213,11 +214,10 @@
cancel_url: tab_list[matching].link\n
});\n
}\n
return gadget.getUrlFor({\n
jio_key: options.jio_key,\n
return gadget.getUrlFor({command: \'change\', options: {\n
view: "view",\n
editable: true\n
})\n
}})\n
.push(function (url) {\n
return gadget.updateHeader({cancel_url: url});\n
});\n
......@@ -362,7 +362,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52770.44221.26572</string> </value>
<value> <string>946.30248.23538.25292</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -380,7 +380,7 @@
</tuple>
<state>
<tuple>
<float>1442504976.31</float>
<float>1444998449.41</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -279,7 +279,12 @@ promiseEventListener */\n
if (target_url && field_json.allow_jump) {\n
return new RSVP.Queue()\n
.push(function () {\n
return my_gadget.getUrlFor({jio_key: target_url});\n
return my_gadget.getUrlFor({\n
command: \'index\',\n
options: {\n
jio_key: target_url\n
}\n
});\n
})\n
.push(function (my_url) {\n
var plane = props.plane;\n
......@@ -759,7 +764,7 @@ promiseEventListener */\n
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.52421.57221.18466</string> </value>
<value> <string>945.64113.53120.10205</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -777,7 +782,7 @@ promiseEventListener */\n
</tuple>
<state>
<tuple>
<float>1442502350.67</float>
<float>1444727907.98</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -128,6 +128,7 @@
\n
</head>\n
<body>\n
<div data-gadget-url="gadget_jio.html" data-gadget-scope="jio_selection"></div>\n
</body>\n
</html>\n
......@@ -267,7 +268,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.43744.60869.2304</string> </value>
<value> <string>945.59812.18070.18176</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -285,7 +286,7 @@
</tuple>
<state>
<tuple>
<float>1442582305.38</float>
<float>1442926344.74</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -109,30 +109,546 @@
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
/*global window, rJS */\n
/*global window, rJS, RSVP, loopEventListener, document, jIO */\n
/*jslint nomen: true, indent: 2 */\n
(function (window, rJS) {\n
(function (window, rJS, RSVP, loopEventListener, document, jIO) {\n
"use strict";\n
\n
rJS(window)\n
// Keep reference of the latest allDocs params which reach to this view\n
// var SELECTION_KEY = "s",\n
// Keep reference in the global navigation pattern\n
// HISTORY KEY = "h"\n
// Current display parameter\n
// DISPLAY KEY = "d"\n
var PREVIOUS_KEY = "p",\n
NEXT_KEY = "n",\n
PREFIX_DISPLAY = "/",\n
PREFIX_COMMAND = "!",\n
// PREFIX_ERROR = "?",\n
COMMAND_DISPLAY_STATE = "display",\n
COMMAND_CHANGE_STATE = "change",\n
COMMAND_INDEX_STATE = "index",\n
COMMAND_SELECTION_PREVIOUS = "selection_previous",\n
COMMAND_SELECTION_NEXT = "selection_next",\n
COMMAND_HISTORY_PREVIOUS = "history_previous",\n
VALID_URL_COMMAND_DICT = {};\n
VALID_URL_COMMAND_DICT[COMMAND_DISPLAY_STATE] = null;\n
VALID_URL_COMMAND_DICT[COMMAND_CHANGE_STATE] = null;\n
VALID_URL_COMMAND_DICT[COMMAND_INDEX_STATE] = null;\n
VALID_URL_COMMAND_DICT[COMMAND_SELECTION_PREVIOUS] = null;\n
VALID_URL_COMMAND_DICT[COMMAND_SELECTION_NEXT] = null;\n
VALID_URL_COMMAND_DICT[COMMAND_HISTORY_PREVIOUS] = null;\n
\n
//////////////////////////////////////////////////////////////////\n
// Change URL functions\n
//////////////////////////////////////////////////////////////////\n
function changeState(hash) {\n
// window.location = hash;\n
return window.location.replace(hash);\n
}\n
\n
function synchronousChangeState(hash) {\n
changeState(hash);\n
// prevent returning unexpected response\n
// wait for the hash change to occur\n
// fail if nothing happens\n
return RSVP.timeout(\'5000\');\n
}\n
\n
//////////////////////////////////////////////////////////////////\n
// Selection functions\n
//////////////////////////////////////////////////////////////////\n
function getSelection(gadget, selection_id) {\n
return gadget.props.jio_gadget.get(selection_id)\n
.push(function (result) {\n
return result.data;\n
});\n
}\n
\n
function getHistory(gadget, history_id) {\n
var previous_id;\n
return gadget.props.jio_gadget.get(history_id)\n
.push(function (history) {\n
previous_id = history.previous_history_id;\n
return gadget.props.jio_gadget.get(history.options_id);\n
})\n
.push(function (result) {\n
return [result, previous_id];\n
}, function (error) {\n
// XXX Check if 404\n
if ((error instanceof jIO.util.jIOError) &&\n
(error.status_code === 404)) {\n
return [{data: {}}, undefined];\n
}\n
throw error;\n
});\n
}\n
\n
function addHistory(gadget, options, previous_selection_id) {\n
var options_blob = {\n
type: "options",\n
data: options\n
},\n
blob_id;\n
\n
return gadget.props.jio_gadget.post(options_blob)\n
.push(function (result) {\n
blob_id = result;\n
return gadget.props.jio_gadget.get(previous_selection_id)\n
.push(undefined, function () {\n
previous_selection_id = undefined;\n
});\n
})\n
.push(function () {\n
var data_history = {\n
type: "history",\n
options_id: blob_id,\n
previous_history_id: previous_selection_id\n
};\n
return gadget.props.jio_gadget.post(data_history);\n
})\n
.push(function (id) {\n
return id;\n
});\n
}\n
\n
function addSelection(gadget, options) {\n
var data_blob = {\n
type: "selection",\n
data: options\n
};\n
return gadget.props.jio_gadget.post(data_blob);\n
}\n
\n
//////////////////////////////////////////////////////////////////\n
// Build URL functions\n
//////////////////////////////////////////////////////////////////\n
function getCommandUrlFor(gadget, command, options) {\n
var result = "#" + PREFIX_COMMAND + (command || ""),\n
prefix = "?",\n
key,\n
tmp_dict;\n
tmp_dict = gadget.props.options;\n
for (key in tmp_dict) {\n
if (tmp_dict.hasOwnProperty(key)) {\n
if (tmp_dict[key] === undefined) {\n
tmp_dict[key] = \'\';\n
}\n
result += prefix + PREVIOUS_KEY + "." + encodeURIComponent(key) + "=" + encodeURIComponent(tmp_dict[key]);\n
prefix = "&";\n
}\n
}\n
for (key in options) {\n
if (options.hasOwnProperty(key)) {\n
if (options[key] === undefined) {\n
options[key] = \'\';\n
}\n
result += prefix + NEXT_KEY + "." + encodeURIComponent(key) + "=" + encodeURIComponent(options[key]);\n
prefix = "&";\n
}\n
}\n
return result;\n
}\n
\n
function getDisplayUrlFor(jio_key, options) {\n
var prefix = \'?\',\n
result,\n
key;\n
result = "#" + PREFIX_DISPLAY + (jio_key || "");\n
for (key in options) {\n
if (options.hasOwnProperty(key) && options[key] !== undefined) {\n
// Don\'t keep empty values\n
result += prefix + encodeURIComponent(key) + "=" + encodeURIComponent(options[key]);\n
prefix = \'&\';\n
}\n
}\n
return result;\n
}\n
\n
//////////////////////////////////////////////////////////////////\n
// exec command functions\n
//////////////////////////////////////////////////////////////////\n
function execDisplayCommand(next_options) {\n
// console.warn(command_options);\n
var jio_key = next_options.jio_key;\n
delete next_options.jio_key;\n
// XXX Implement history management\n
return synchronousChangeState(\n
getDisplayUrlFor(jio_key, next_options)\n
);\n
}\n
\n
function execChangeCommand(previous_options, next_options) {\n
var key,\n
jio_key;\n
for (key in previous_options) {\n
if (previous_options.hasOwnProperty(key)) {\n
if (!next_options.hasOwnProperty(key)) {\n
next_options[key] = previous_options[key];\n
}\n
}\n
}\n
for (key in next_options) {\n
if (next_options.hasOwnProperty(key)) {\n
if (!next_options[key]) {\n
delete next_options[key];\n
}\n
}\n
}\n
jio_key = next_options.jio_key;\n
delete next_options.jio_key;\n
return synchronousChangeState(\n
getDisplayUrlFor(jio_key, next_options)\n
);\n
}\n
\n
function execIndexCommand(gadget, previous_options, next_options) {\n
var jio_key = next_options.jio_key,\n
selection_options = {};\n
delete next_options.jio_key;\n
// selection_options.index = next_options.index;\n
selection_options.query = next_options.query;\n
selection_options.list_method_template = next_options.list_method_template;\n
// Store selection in local DB\n
return addSelection(gadget, selection_options)\n
.push(function (id) {\n
next_options.selection = id;\n
// XXX Implement history management\n
return addHistory(gadget, previous_options);\n
})\n
.push(function (id) {\n
next_options.history = id;\n
return synchronousChangeState(\n
getDisplayUrlFor(jio_key, next_options)\n
);\n
});\n
}\n
\n
function execSelectionNextCommand(gadget, previous_options) {\n
// Get the selection parameters\n
// Query all docs with those parameters + expected index\n
// Redirect to the result document\n
return getSelection(gadget, previous_options.selection)\n
.push(function (selection) {\n
return gadget.jio_allDocs({\n
"query": selection.query,\n
"list_method_template": selection.list_method_template,\n
"limit": [parseInt(previous_options.selection_index, 10) + 1, 1]\n
})\n
.push(function (result) {\n
if (result.data.rows.length === 0) {\n
return synchronousChangeState(\n
getCommandUrlFor(gadget, COMMAND_HISTORY_PREVIOUS, previous_options)\n
);\n
}\n
return synchronousChangeState(\n
getDisplayUrlFor(result.data.rows[0].id, {\n
selection: previous_options.selection,\n
selection_index: parseInt(previous_options.selection_index, 10) + 1,\n
history: previous_options.history\n
})\n
);\n
});\n
}, function (error) {\n
if ((error instanceof jIO.util.jIOError) &&\n
(error.status_code === 404)) {\n
return synchronousChangeState(\n
getCommandUrlFor(gadget, COMMAND_HISTORY_PREVIOUS, previous_options)\n
); \n
}\n
throw error;\n
});\n
}\n
\n
function execSelectionPreviousCommand(gadget, previous_options) {\n
// Get the selection parameters\n
// Query all docs with those parameters + expected index\n
// Redirect to the result document\n
return getSelection(gadget, previous_options.selection)\n
.push(function (selection) {\n
if (parseInt(previous_options.selection_index, 10) < 1) {\n
return synchronousChangeState(\n
getCommandUrlFor(gadget, COMMAND_HISTORY_PREVIOUS, previous_options)\n
);\n
}\n
return gadget.jio_allDocs({\n
"query": selection.query,\n
"list_method_template": selection.list_method_template,\n
"limit": [parseInt(previous_options.selection_index, 10) - 1, 1]\n
})\n
.push(function (result) {\n
if (result.data.rows.length === 0) {\n
return synchronousChangeState(\n
getCommandUrlFor(gadget, COMMAND_HISTORY_PREVIOUS, previous_options)\n
);\n
}\n
return synchronousChangeState(\n
getDisplayUrlFor(result.data.rows[0].id, {\n
selection: previous_options.selection,\n
selection_index: parseInt(previous_options.selection_index, 10) - 1,\n
history: previous_options.history\n
})\n
);\n
});\n
}, function (error) {\n
if ((error instanceof jIO.util.jIOError) &&\n
(error.status_code === 404)) {\n
return synchronousChangeState(\n
getCommandUrlFor(gadget, COMMAND_HISTORY_PREVIOUS, previous_options)\n
); \n
}\n
throw error;\n
});\n
}\n
\n
\n
function execHistoryPreviousCommand(gadget, previous_options) {\n
var history = previous_options.history;\n
if (history === undefined) {\n
return synchronousChangeState(\n
getDisplayUrlFor(undefined, {page: \'front\'})\n
);\n
}\n
return getHistory(gadget, previous_options.history)\n
.push(function (result_list) {\n
var options = result_list[0].data,\n
jio_key = options.jio_key;\n
delete options.jio_key;\n
return synchronousChangeState(\n
getDisplayUrlFor(jio_key, options)\n
);\n
});\n
}\n
\n
//////////////////////////////////////////////////////////////////\n
// Command URL functions\n
//////////////////////////////////////////////////////////////////\n
function routeMethodLess() {\n
// Nothing. Go to front page\n
return synchronousChangeState(\n
getDisplayUrlFor(undefined, {page: \'front\'})\n
);\n
}\n
\n
function routeDisplay(gadget, command_options) {\n
if (command_options.path) {\n
if (command_options.args.page === undefined) {\n
return synchronousChangeState(\n
getDisplayUrlFor(command_options.path, {\n
page: \'form\',\n
editable: command_options.args.editable,\n
view: command_options.args.view || \'view\',\n
selection: command_options.args.selection,\n
selection_index: command_options.args.selection_index,\n
history: command_options.args.history\n
})\n
);\n
}\n
}\n
\n
if (command_options.args.page === undefined) {\n
return synchronousChangeState(\n
getDisplayUrlFor(undefined, {\n
page: \'front\'\n
})\n
);\n
}\n
\n
.declareMethod(\'route\', function (options) {\n
command_options.args.jio_key = command_options.path;\n
\n
if ((options.jio_key !== undefined) && (options.page === undefined)) {\n
options.page = "form";\n
// XXX Hardcoded default \'view\'\n
options.view = options.view || \'view\';\n
// Store current options to handle navigation\n
gadget.props.options = JSON.parse(JSON.stringify(command_options.args));\n
\n
return {\n
url: "gadget_erp5_page_" + command_options.args.page + ".html",\n
// XXX Drop this options thing.\n
// Implement a "getSelection" method \n
options: command_options.args\n
// options: {}\n
};\n
\n
}\n
\n
function routeCommand(gadget, command_options) {\n
var args = command_options.args,\n
key,\n
split_list,\n
previous_options = {},\n
next_options = {},\n
valid = true;\n
// Rebuild the previous and next parameter dict\n
for (key in args) {\n
if (args.hasOwnProperty(key)) {\n
split_list = key.split(\'.\', 2);\n
if (split_list.length !== 2) {\n
valid = false;\n
break;\n
}\n
if (split_list[0] === PREVIOUS_KEY) {\n
previous_options[split_list[1]] = args[key];\n
} else if (split_list[0] === NEXT_KEY) {\n
next_options[split_list[1]] = args[key];\n
} else {\n
valid = false;\n
break;\n
}\n
}\n
}\n
if (!valid) {\n
throw new Error(\'Unsupported parameters: \' + key);\n
}\n
\n
if (command_options.path === COMMAND_DISPLAY_STATE) {\n
return execDisplayCommand(next_options);\n
}\n
if (command_options.path === COMMAND_INDEX_STATE) {\n
return execIndexCommand(gadget, previous_options, next_options);\n
}\n
if (command_options.path === COMMAND_CHANGE_STATE) {\n
return execChangeCommand(previous_options, next_options);\n
}\n
if (command_options.path === COMMAND_SELECTION_NEXT) {\n
return execSelectionNextCommand(gadget, previous_options, next_options);\n
}\n
if (command_options.path === COMMAND_SELECTION_PREVIOUS) {\n
return execSelectionPreviousCommand(gadget, previous_options, next_options);\n
}\n
if (command_options.path === COMMAND_HISTORY_PREVIOUS) {\n
return execHistoryPreviousCommand(gadget, previous_options);\n
}\n
throw new Error(\'Unsupported command \' + command_options.path);\n
\n
}\n
\n
function listenHashChange(gadget) {\n
// Handle hash in this format: #$path1/path2?a=b&c=d\n
function extractHashAndDispatch(evt) {\n
var hash = (evt.newURL || window.location.toString()).split(\'#\')[1],\n
split,\n
command = "",\n
query = "",\n
subhashes,\n
subhash,\n
keyvalue,\n
index,\n
args = {};\n
if (hash !== undefined) {\n
split = hash.split(\'?\');\n
command = split[0] || "";\n
query = split[1] || "";\n
}\n
if (options.page === undefined) {\n
options.page = \'front\';\n
subhashes = query.split(\'&\');\n
for (index in subhashes) {\n
if (subhashes.hasOwnProperty(index)) {\n
subhash = subhashes[index];\n
if (subhash !== \'\') {\n
keyvalue = subhash.split(\'=\');\n
if (keyvalue.length === 2) {\n
args[decodeURIComponent(keyvalue[0])] = decodeURIComponent(keyvalue[1]);\n
}\n
}\n
}\n
}\n
return {\n
url: "gadget_erp5_page_" + options.page + ".html",\n
options: options\n
\n
return gadget.renderApplication({\n
method: command[0],\n
path: command.substr(1),\n
args: args\n
});\n
\n
}\n
\n
var result = loopEventListener(window, \'hashchange\', false,\n
extractHashAndDispatch),\n
event = document.createEvent("Event");\n
event.initEvent(\'hashchange\', true, true);\n
event.newURL = window.location.toString();\n
window.dispatchEvent(event);\n
return result;\n
}\n
\n
\n
rJS(window)\n
.ready(function (gadget) {\n
gadget.props = {\n
options: {},\n
start_deferred: RSVP.defer()\n
};\n
})\n
\n
.ready(function (gadget) {\n
return gadget.getDeclaredGadget("jio_selection")\n
.push(function (jio_gadget) {\n
gadget.props.jio_gadget = jio_gadget;\n
return jio_gadget.createJio({\n
type: "sha",\n
sub_storage: {\n
type: "indexeddb",\n
database: "selection"\n
}\n
});\n
});\n
})\n
\n
.declareMethod(\'getCommandUrlFor\', function (options) {\n
var command = options.command,\n
args = options.options,\n
valid = true,\n
key;\n
// Only authorize \'command\' and \'options\' keys\n
// Drop all other kind of parameters, to detect issue more easily\n
for (key in options) {\n
if (options.hasOwnProperty(key)) {\n
if ((key !== \'command\') && (key !== \'options\')) {\n
valid = false;\n
}\n
}\n
}\n
if (valid && (options.command) && (VALID_URL_COMMAND_DICT.hasOwnProperty(options.command))) {\n
return getCommandUrlFor(this, command, args);\n
}\n
return getCommandUrlFor(this, \'error\', options);\n
})\n
\n
.declareMethod(\'getUrlParameter\', function (key) {\n
return this.props.options[key];\n
})\n
\n
.declareMethod(\'route\', function (command_options) {\n
var gadget = this;\n
\n
if (command_options.method === PREFIX_DISPLAY) {\n
return routeDisplay(gadget, command_options);\n
}\n
if (command_options.method === PREFIX_COMMAND) {\n
return routeCommand(gadget, command_options);\n
}\n
if (command_options.method) {\n
throw new Error(\'Unsupported hash method: \' + command_options.method);\n
}\n
return routeMethodLess();\n
})\n
\n
.declareMethod(\'start\', function () {\n
this.props.start_deferred.resolve();\n
})\n
\n
.declareAcquiredMethod(\'renderApplication\', \'renderApplication\')\n
.declareAcquiredMethod(\'jio_allDocs\', \'jio_allDocs\')\n
\n
.declareService(function () {\n
var gadget = this;\n
return new RSVP.Queue()\n
.push(function () {\n
return gadget.props.start_deferred.promise;\n
})\n
.push(function () {\n
// console.info(\'router service: listen to hash change\');\n
return listenHashChange(gadget);\n
});\n
});\n
\n
}(window, rJS));\n
}(window, rJS, RSVP, loopEventListener, document, jIO));\n
]]></string> </value>
......@@ -270,7 +786,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>945.54079.55977.57258</string> </value>
<value> <string>946.35999.6366.29491</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -288,7 +804,7 @@
</tuple>
<state>
<tuple>
<float>1442582410.13</float>
<float>1445343438.7</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -137,7 +137,7 @@
\n
</head>\n
<body>\n
<form class="save_form document_form"></form>\n
<div class="save_form document_form"></div>\n
</body>\n
</html>
......@@ -262,7 +262,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>super_sven</string> </value>
<value> <string>romain</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -276,7 +276,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>939.54156.55991.39765</string> </value>
<value> <string>945.50880.23560.7150</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -294,7 +294,7 @@
</tuple>
<state>
<tuple>
<float>1419427478.55</float>
<float>1442998364.27</float>
<string>GMT</string>
</tuple>
</state>
......
......@@ -135,8 +135,6 @@
// acquired method\n
//////////////////////////////////////////////\n
.declareAcquiredMethod("translateHtml", "translateHtml")\n
.declareAcquiredMethod("pleasePublishMyState", "pleasePublishMyState")\n
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")\n
\n
/////////////////////////////////////////////////////////////////\n
// declared methods\n
......@@ -163,44 +161,18 @@
}));\n
})\n
.push(function (my_translated_html) {\n
search_gadget.props.element.querySelector("form").innerHTML =\n
search_gadget.props.element.querySelector("div").innerHTML =\n
my_translated_html;\n
return search_gadget;\n
});\n
})\n
\n
.declareMethod(\'getContent\', function () {\n
var input = this.__element.querySelector(\'input\'),\n
var input = this.props.element.querySelector(\'input\'),\n
result = {};\n
\n
result[input.getAttribute(\'name\')] = input.value;\n
return result;\n
})\n
\n
.declareService(function () {\n
var search_form = this;\n
\n
function formSubmit() {\n
return new RSVP.Queue()\n
.push(function () {\n
return search_form.getContent();\n
})\n
.push(function (data) {\n
return search_form.pleasePublishMyState({\n
"extended_search": data.search\n
});\n
})\n
.push(function (url) {\n
return search_form.pleaseRedirectMyHash(url);\n
});\n
}\n
// Listen to form submit\n
return loopEventListener(\n
search_form.props.element.querySelector(\'form\'),\n
\'submit\',\n
false,\n
formSubmit\n
);\n
});\n
\n
}(window, rJS, RSVP, loopEventListener, Handlebars));</string> </value>
......@@ -324,7 +296,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
<value> <string>romain</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -338,7 +310,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>940.11553.26313.55261</string> </value>
<value> <string>945.61050.10650.48093</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -356,7 +328,7 @@
</tuple>
<state>
<tuple>
<float>1421080302.1</float>
<float>1445265843.55</float>
<string>GMT</string>
</tuple>
</state>
......
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