Commit b34042dd authored by Romain Courteaud's avatar Romain Courteaud

WIP [erp5_web_jabber_client] Reuse ERP5JS gadgets

This is still a not working prototype.
Pasting multitext has not yet been reimplemented.
Way to slow to be usable.
parent 7f1415a0
......@@ -52,7 +52,7 @@
}
function disconnectOnbeforeunload(connection) {
return function (event) {
return function () {
/* XXX it can be interfere with changed warning
if (changed && $('button.save')) {
return unsaved_warn_message;
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.56116.24375.61559</string> </value>
<value> <string>963.11851.42215.35874</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1458087635.15</float>
<float>1509724529.27</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -12,11 +12,12 @@
<script src="jiodev.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_jio.js" type="text/javascript"></script>
</head>
<body>
<div class="ui-hidden-accessible connection-gadget-container"></div>
<div class="ui-screen-hidden connection-gadget-container"></div>
<div data-gadget-url='gadget_jio.html' data-gadget-scope='persistent_jio'></div>
</body>
......
......@@ -232,7 +232,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.35373.28357.37512</string> </value>
<value> <string>963.13564.52429.46011</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -250,7 +250,7 @@
</tuple>
<state>
<tuple>
<float>1456843116.28</float>
<float>1509720807.28</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -140,7 +140,7 @@
function markOffline(key) {
return gadget.state_parameter_dict.volatile_jio.get(key)
.push(function (doc) {
doc.offline = true;
doc.connected = false;
return gadget.state_parameter_dict.volatile_jio.put(key, doc);
});
}
......@@ -178,8 +178,8 @@
(error.status_code === 404)) {
return {
jid: jid,
offline: true,
read: true
connected: false,
notification: false
};
}
throw error;
......@@ -252,9 +252,9 @@
.push(function (doc) {
if ((type === "unavailable") || (type === "unsubscribed")) {
// Bye dear contact
doc.offline = true;
doc.connected = false;
} else {
doc.offline = false;
doc.connected = true;
}
return gadget.state_parameter_dict.volatile_jio.put(from, doc);
})
......@@ -278,7 +278,7 @@
return initializeContact(gadget, argument_list[0]);
})
.push(function (doc) {
doc.read = false;
doc.notification = true;
return gadget.state_parameter_dict.volatile_jio.put(argument_list[0], doc);
})
.push(function () {
......@@ -423,7 +423,7 @@
.declareMethod('allDocs', function (options) {
if (!this.state_parameter_dict.connected) {
return this.redirect({command: 'display', options: {page: 'connect'}});
return this.redirect({command: 'display', options: {page: 'jabberclient_connect'}});
}
return this.state_parameter_dict.volatile_jio.allDocs(options);
})
......@@ -432,7 +432,7 @@
var gadget = this,
result;
if (!this.state_parameter_dict.connected) {
return this.redirect({command: 'display', options: {page: 'connect'}});
return this.redirect({command: 'display', options: {page: 'jabberclient_connect'}});
}
if (name === 'enclosure') {
return getLog(this, id, options)
......@@ -441,7 +441,7 @@
return initializeContact(gadget, id);
})
.push(function (doc) {
doc.read = true;
doc.notification = false;
return gadget.state_parameter_dict.volatile_jio.put(id, doc);
})
.push(function () {
......@@ -454,7 +454,7 @@
.declareMethod('putAttachment', function (id, name, blob) {
var gadget = this;
if (!this.state_parameter_dict.connected) {
return this.redirect({command: 'display', options: {page: 'connect'}});
return this.redirect({command: 'display', options: {page: 'jabberclient_connect'}});
}
if (name === 'MESSAGE') {
return this.getDeclaredGadget(CONNECTION_GADGET_SCOPE)
......
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.57481.62457.42496</string> </value>
<value> <string>963.13623.60350.63692</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1458172700.61</float>
<float>1509724327.32</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -10,11 +10,9 @@
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_page_connect.js" type="text/javascript"></script>
<script src="gadget_erp5_page_jabberclient_connect.js" type="text/javascript"></script>
</head>
<body>
<pre></pre>
<form class="dialog_form">
<button type="submit" data-i18n="Submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-action ui-btn-icon-right ui-screen-hidden">Submit</button>
......
......@@ -75,7 +75,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_connect.html</string> </value>
<value> <string>gadget_erp5_page_jabberclient_connect.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.25270.37532.52872</string> </value>
<value> <string>963.11985.30461.59170</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1456843234.23</float>
<float>1509627042.14</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, loopEventListener*/
/*global window, rJS, RSVP*/
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, loopEventListener) {
(function (window, rJS, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
......@@ -26,6 +11,7 @@
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_put", "jio_put")
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("redirect", "redirect")
......@@ -34,11 +20,11 @@
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('triggerSubmit', function () {
this.props.element.querySelector('button').click();
this.element.querySelector('button').click();
})
.declareMethod("render", function () {
var page_gadget = this,
data;
var page_gadget = this;
return page_gadget.updateHeader({
page_title: 'Connect to a Jabber server',
submit_action: true
......@@ -46,17 +32,25 @@
.push(function () {
return page_gadget.jio_get("CONNECTION");
})
.push(function (result) {
data = result;
return page_gadget.getDeclaredGadget("erp5_form");
})
.push(function (data) {
return page_gadget.changeState({
server: data.server,
jid: data.jid,
passwd: data.passwd
});
});
})
.onStateChange(function () {
var page_gadget = this;
return page_gadget.getDeclaredGadget("erp5_form")
.push(function (form_gadget) {
return form_gadget.render({
erp5_document: {"_embedded": {"_view": {
"server": {
"description": "",
"title": "Server URL",
"default": data.server,
"default": page_gadget.state.server,
"css_class": "",
"required": 1,
"editable": 1,
......@@ -67,7 +61,7 @@
"jid": {
"description": "",
"title": "Jabber ID",
"default": data.jid,
"default": page_gadget.state.jid,
"css_class": "",
"required": 1,
"editable": 1,
......@@ -78,7 +72,7 @@
"passwd": {
"description": "",
"title": "Password",
"default": data.passwd,
"default": page_gadget.state.passwd,
"css_class": "",
"required": 1,
"editable": 1,
......@@ -97,44 +91,36 @@
});
})
.declareService(function () {
var form_gadget = this;
function formSubmit() {
return form_gadget.notifySubmitting()
.push(function () {
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
return erp5_form.getContent();
})
.push(function (content_dict) {
return form_gadget.jio_put(
'CONNECTION',
content_dict
);
})
.push(function () {
return RSVP.all([
form_gadget.notifySubmitted(),
form_gadget.redirect({command: 'display', options: {page: 'contact'}})
]);
})
.push(undefined, function (error) {
return form_gadget.notifySubmitted()
.push(function () {
form_gadget.props.element.querySelector('pre').textContent = error;
});
});
}
.onEvent('submit', function () {
var page_gadget = this;
// Listen to form submit
return loopEventListener(
form_gadget.props.element.querySelector('form'),
'submit',
false,
formSubmit
);
return page_gadget.notifySubmitting()
.push(function () {
return page_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
return erp5_form.getContent();
})
.push(function (content_dict) {
return page_gadget.jio_put(
'CONNECTION',
content_dict
);
})
.push(function () {
return RSVP.all([
page_gadget.notifySubmitted(),
page_gadget.redirect({command: 'display', options: {page: 'jabberclient_contact'}})
]);
}, function (error) {
return RSVP.all([
page_gadget.notifySubmitted(),
page_gadget.notifyChange({
'message': error,
'status': 'error'
})
]);
});
});
}(window, rJS, RSVP, loopEventListener));
\ No newline at end of file
}(window, rJS, RSVP));
\ No newline at end of file
......@@ -71,7 +71,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_connect.js</string> </value>
<value> <string>gadget_erp5_page_jabberclient_connect.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.35328.64444.1843</string> </value>
<value> <string>963.13625.4155.47957</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1456843227.61</float>
<float>1509724755.89</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -5,45 +5,17 @@
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>JabberClient Gadget Page Contact</title>
<script id="contact-list-template" type="text/x-handlebars-template">
<ul data-role="listview" data-inset="true">
{{#each contact}}
<li>
{{#if status}}
{{#if url}}
<a href="{{url}}" class="ui-btn ui-btn-icon-left ui-icon-check">
{{#if new_message}}
<span class="ui-li-count">!</span>
{{/if}}
{{jid}}</a>
{{else}}
{{jid}}
{{/if}}
{{else}}
{{#if url}}
<a href="{{url}}" class="ui-btn ui-btn-icon-left ui-icon-forbidden">
{{#if new_message}}
<span class="ui-li-count">!</span>
{{/if}}
{{jid}}</a>
{{else}}
{{jid}}
{{/if}}
{{/if}}
</li>
{{/each}}
</ul>
</script>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_page_contact.js" type="text/javascript"></script>
<script src="gadget_erp5_page_jabberclient_contact.js" type="text/javascript"></script>
</head>
<body>
<div data-gadget-url="gadget_erp5_pt_form_list.html"
data-gadget-scope="form_list"
data-gadget-sandbox="public">
</div>
</body>
</html>
\ No newline at end of file
......@@ -75,7 +75,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_contact.html</string> </value>
<value> <string>gadget_erp5_page_jabberclient_contact.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.26690.60508.50432</string> </value>
<value> <string>963.12017.54400.15923</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1456843145.34</float>
<float>1509628438.87</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, Handlebars*/
/*global window, rJS*/
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS) {
"use strict";
function compareContact(a, b) {
var result;
if (a.new_message && (!b.new_message)) {
result = -1;
} else if (b.new_message && (!a.new_message)) {
result = 1;
} else if (a.status && (!b.status)) {
result = -1;
} else if (b.status && (!a.status)) {
result = 1;
} else if (b.jid < a.jid) {
result = 1;
} else if (a.jid < b.jid) {
result = -1;
} else {
result = 0;
}
return result;
}
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
source = gadget_klass.__template_element
.getElementById("contact-list-template")
.innerHTML,
table_template = Handlebars.compile(source);
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
// declared methods
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
.allowPublicAcquisition('updateHeader', function () {
return;
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
.allowPublicAcquisition('getUrlFor', function (argument_list) {
if (argument_list[0].command === 'index') {
return this.getUrlFor({command: 'display', options: {jio_key: argument_list[0].options.jio_key,
page: 'jabberclient_dialog'}});
}
return this.getUrlFor.apply(this, argument_list);
})
.allowPublicAcquisition("jio_allDocs", function (param_list) {
var gadget = this;
return gadget.jio_allDocs(param_list[0])
.push(function (result) {
var i, len = result.data.total_rows;
for (i = 0; i < len; i += 1) {
if (result.data.rows[i].value.hasOwnProperty("connected")) {
result.data.rows[i].value.connected = {
editable: 0,
hidden: 0,
"default": result.data.rows[i].value.connected,
key: "field_connected",
required: 0,
type: "CheckBoxField"
};
result.data.rows[i].value["listbox_uid:list"] = {
key: "listbox_uid:list",
value: 2713
};
}
if (result.data.rows[i].value.hasOwnProperty("notification")) {
result.data.rows[i].value.notification = {
editable: 0,
hidden: 0,
"default": result.data.rows[i].value.notification,
key: "field_notification",
required: 0,
type: "CheckBoxField"
};
result.data.rows[i].value["listbox_uid:list"] = {
key: "listbox_uid:list",
value: 2713
};
}
}
return result;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareMethod("triggerSubmit", function () {
var argument_list = arguments;
return this.getDeclaredGadget('form_list')
.push(function (gadget) {
return gadget.triggerSubmit.apply(gadget, argument_list);
});
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function () {
var page_gadget = this,
contact_list = [],
gadget = this;
var gadget = this,
header_dict = {
page_title: 'Contacts',
page_icon: 'puzzle-piece',
filter_action: true
};
return page_gadget.updateHeader({
page_title: 'Contact'
})
return gadget.updateHeader(header_dict)
.push(function () {
return page_gadget.jio_allDocs({select_list: ['jid', 'read', 'offline']});
})
.push(function (result) {
var i,
contact,
promise_list = [];
for (i = 0; i < result.data.total_rows; i += 1) {
contact = result.data.rows[i].value;
contact_list.push({
jid: contact.jid,
new_message: !contact.read,
status: !contact.offline
});
promise_list.push(gadget.getUrlFor({command: 'display', options: {page: 'dialog', jid: contact.jid}}));
}
return RSVP.all(promise_list);
return gadget.getDeclaredGadget('form_list');
})
.push(function (url_list) {
var i;
for (i = 0; i < url_list.length; i += 1) {
contact_list[i].url = url_list[i];
}
contact_list.sort(compareContact);
gadget.props.element.innerHTML =
table_template({
contact: contact_list
});
.push(function (form_gadget) {
var column_list = [
['jid', 'Name'],
['notification', 'Notification'],
['connected', 'Connected']
];
return form_gadget.render({
erp5_document: {"_embedded": {"_view": {
"listbox": {
"column_list": column_list,
"show_anchor": 0,
"default_params": {},
"editable": 1,
"editable_column_list": column_list,
"key": "field_listbox",
"lines": 1000,
"list_method": "portal_catalog",
"query": "urn:jio:allDocs",
"portal_type": [],
"search_column_list": column_list,
"sort_column_list": column_list,
"sort": [['notification', 'DESC'], ['connected', 'DESC'], ['jid', 'ASC']],
"title": "Contacts",
"type": "ListBox"
}
}},
"_links": {
"type": {
// form_list display portal_type in header
name: ""
}
}
},
form_definition: {
group_list: [[
"bottom",
[["listbox"]]
]]
}
});
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS));
\ No newline at end of file
......@@ -71,7 +71,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_contact.js</string> </value>
<value> <string>gadget_erp5_page_jabberclient_contact.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.36448.18833.13141</string> </value>
<value> <string>963.13593.12902.41028</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1456907564.65</float>
<float>1509722579.38</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -10,31 +10,20 @@
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_page_dialog.js" type="text/javascript"></script>
<script src="gadget_erp5_page_jabberclient_dialog.js" type="text/javascript"></script>
<script id="input-template" type="text/x-handlebars-template">
<input class="input-content" type="text" data-enhanced="true" name="content"
placeholder="Write something..." value="" required>
</script>
<script id="textarea-template" type="text/x-handlebars-template">
<textarea class="textarea-content" type="text" data-enhanced="true" name="content"
placeholder="Write a multi-line message..." value="" required></textarea>
</script>
</head>
<body>
<div class="discussion-content"></div>
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
<form class="message-form">
<div class="ui-input-text ui-corner-all ui-body-inherit ui-shadow-inset ui-input-has-clear ui-input-has-multiline">
<div class="custom-mode-change ui-btn ui-btn-icon-notext ui-input-clear ui-input-btn ui-corner-all ui-icon-comment ui-btn-left">
<input data-enhanced="true" type="button" value="">
</div>
<div class="ui-btn ui-input-clear ui-input-btn ui-corner-all ui-icon-edit ui-btn-icon-notext">
<input data-enhanced="true" type="submit" value="Send">
</div>
</div>
</form>
<form class="dialog_form">
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="discussion_form"
data-gadget-sandbox="public">
</div>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="input_form"
data-gadget-sandbox="public">
</div>
<input class="dialogconfirm" data-theme="b" data-inline="true" type="submit" data-i18n="[value]Send" value="Send" data-icon="check" />
</form>
</body>
</html>
\ No newline at end of file
......@@ -75,7 +75,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_dialog.html</string> </value>
<value> <string>gadget_erp5_page_jabberclient_dialog.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>950.63332.2255.41369</string> </value>
<value> <string>963.13312.9778.47496</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1462370312.21</float>
<float>1509718172.58</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, document, rJS, RSVP, Handlebars, loopEventListener*/
/*global window, document, rJS, RSVP*/
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, document, rJS, RSVP, Handlebars, loopEventListener) {
(function (window, document, rJS, RSVP) {
"use strict";
function scroll(g) {
var gadget = g;
RSVP.Queue()
.push(function () {
return RSVP.delay(0);
})
.push(function () {
window.scrollTo(0, gadget.props.element.scrollHeight || document.body.scrollHeight || document.documentElement.scrollHeight);
});
}
// 30 minutes
var MESSAGE_FRESHNESS = 1800000;
function getDomFromString(str) {
var temp_div = document.createElement('div');
temp_div.innerHTML = str.trim();
return temp_div.firstChild;
}
function calculateMessageList(text) {
var message_list = [],
line_list = text.split('\n'),
line_count = line_list.length,
line,
tmp_line,
i,
index,
displayed_text = '',
is_incoming = true,
is_handled,
is_old,
message_date,
previous_message_date,
message_is_incoming;
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
input_source = gadget_klass.__template_element
.getElementById("input-template")
.innerHTML,
input_template = Handlebars.compile(input_source),
textarea_source = gadget_klass.__template_element
.getElementById("textarea-template")
.innerHTML,
textarea_template = Handlebars.compile(textarea_source),
// MESSAGE_FRESHNESS 30 minutes
MESSAGE_FRESHNESS = 1800000;
function appendMessage(displayed_text, incoming, date) {
if (displayed_text) {
message_list.push({
text: displayed_text,
incoming: incoming,
message_date: date
});
}
}
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
for (i = 0; i < line_count - 1; i += 1) {
line = line_list[i];
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.template_container = element.querySelector('.ui-input-has-multiline');
g.props.keep_text_dict = {'oneline': '', 'textarea': ''};
g.props.template_container.insertBefore(getDomFromString(input_template()),
g.props.template_container.firstChild);
});
})
is_handled = false;
is_old = false;
if (line.indexOf('[') === 0) {
index = line.indexOf('] ');
if (index !== -1) {
// Check message freshness
// If we receive one multiline message, then the lines after the first
// would not start with the date. So this would return Invalid Date
message_date = new Date(line.substring(1, index));
// Check direction and cut the date from the start of the line.
// This should be done only if it is a unique line or the first
// line of a multi-line message. Other lines will retain direction
// of the first
if (isNaN(message_date) === false) {
if (previous_message_date === undefined) {
previous_message_date = new Date(message_date - MESSAGE_FRESHNESS - 2);
}
if (message_date - previous_message_date > MESSAGE_FRESHNESS) {
is_old = true;
}
tmp_line = line.substring(index + 2);
if (tmp_line.indexOf('> ') === 0) {
message_is_incoming = false;
} else if (tmp_line.indexOf('< ') === 0) {
message_is_incoming = true;
}
line = tmp_line.substring(2);
}
if (message_is_incoming !== is_incoming || is_old) {
appendMessage(displayed_text, is_incoming, previous_message_date);
is_incoming = message_is_incoming;
is_handled = true;
displayed_text = line + '\n';
}
}
}
previous_message_date = message_date;
if (!is_handled) {
displayed_text += line + '\n';
}
}
appendMessage(displayed_text, is_incoming, message_date);
return message_list;
}
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
......@@ -64,203 +89,178 @@
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareAcquiredMethod("refresh", "refresh")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareJob('scroll', function () {
window.scrollTo(0, this.element.scrollHeight ||
document.body.scrollHeight ||
document.documentElement.scrollHeight);
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
var gadget = this,
ul = document.createElement("ul"),
template_container = gadget.props.template_container;
ul.setAttribute("data-role", "listview");
gadget.props.jid = options.jid;
template_container.children[0].focus();
return gadget.updateHeader({
page_title: options.jid
})
.push(function () {
return gadget.jio_getAttachment(options.jid, "enclosure", {format: 'text'});
})
.declareMethod('render', function (options) {
var gadget = this;
return gadget.jio_getAttachment(options.jio_key, "enclosure", {format: 'text'})
.push(function (text) {
var line_list = text.split('\n'),
line,
tmp_line,
i,
index,
displayed_text = '',
is_incoming = true,
is_handled,
previous_message_date,
is_old,
message_date,
message_is_incoming;
function appendText(txt, incoming) {
var li, pre;
if (txt) {
li = document.createElement("li");
if (incoming) {
li.setAttribute("style", "padding-right: 5em;");
} else {
li.setAttribute("style", "text-align: right; padding-left: 5em;");
}
pre = document.createElement("pre");
pre.setAttribute("style", "white-space: pre-wrap;");
pre.textContent = txt;
li.appendChild(pre);
ul.appendChild(li);
}
}
function appendDate(date) {
var li,
i_element;
li = document.createElement("li");
li.setAttribute("style", "text-align: center; padding-left: 5em; padding: 0;");
i_element = document.createElement("i");
i_element.setAttribute("style", "white-space: pre-wrap; padding: 0.5em 0 0.5em 0; display: block;");
i_element.textContent = date.toLocaleString();
li.appendChild(i_element);
ul.appendChild(li);
}
for (i = 0; i < line_list.length - 1; i += 1) {
line = line_list[i];
is_handled = false;
is_old = false;
if (line.indexOf('[') === 0) {
index = line.indexOf('] ');
if (index !== -1) {
// Check message freshness
// If we receive one multiline message, then the lines after the first
// would not start with the date. So this would return Invalid Date
message_date = new Date(line.substring(1, index));
// Check direction and cut the date from the start of the line.
// This should be done only if it is a unique line or the first
// line of a multi-line message. Other lines will retain direction
// of the first
if (isNaN(message_date) === false) {
if (previous_message_date === undefined) {
previous_message_date = new Date(message_date - MESSAGE_FRESHNESS - 2);
}
if (message_date - previous_message_date > MESSAGE_FRESHNESS) {
is_old = true;
}
tmp_line = line.substring(index + 2);
if (tmp_line.indexOf('> ') === 0) {
message_is_incoming = false;
} else if (tmp_line.indexOf('< ') === 0) {
message_is_incoming = true;
}
line = tmp_line.substring(2);
}
if (message_is_incoming !== is_incoming || is_old) {
appendText(displayed_text, is_incoming);
is_incoming = message_is_incoming;
is_handled = true;
displayed_text = line + '\n';
}
if (is_old) {
appendDate(message_date);
}
}
}
previous_message_date = message_date;
if (!is_handled) {
displayed_text += line + '\n';
}
}
appendText(displayed_text, is_incoming);
gadget.props.element.querySelector(".discussion-content").innerHTML = "";
gadget.props.element.querySelector(".discussion-content").appendChild(ul);
return scroll(gadget);
return gadget.changeState({
jio_key: options.jio_key,
text: text,
refresh: options.refresh || 1
});
});
})
.declareService(function () {
var form_gadget = this,
template_container = form_gadget.props.template_container,
keep_text_dict = form_gadget.props.keep_text_dict;
function formSubmit(submit_event) {
return form_gadget.notifySubmitting()
.push(function () {
var text = submit_event.target[0].value;
submit_event.target[0].value = "";
keep_text_dict.oneline = "";
keep_text_dict.textarea = "";
template_container.removeChild(template_container.firstChild);
template_container.insertBefore(getDomFromString(input_template()),
template_container.firstChild);
template_container.children[0].focus();
template_container.children[0].select();
return form_gadget.jio_putAttachment(
form_gadget.props.jid,
'MESSAGE',
text
);
})
.onStateChange(function (modification_dict) {
var gadget = this,
queue = new RSVP.Queue();
if (modification_dict.hasOwnProperty('jio_key')) {
queue
.push(function () {
return form_gadget.refresh();
return RSVP.all([
gadget.getUrlFor({command: 'display', options: {page: 'jabberclient_contact'}})
// gadget.getUrlFor({command: 'selection_previous'}),
// gadget.getUrlFor({command: 'selection_next'})
]);
})
.push(function (all_result) {
return gadget.updateHeader({
selection_url: all_result[0],
// previous_url: all_result[1],
// next_url: all_result[2],
page_title: gadget.state.jio_key
});
});
}
if (modification_dict.hasOwnProperty('refresh')) {
queue
.push(function () {
return form_gadget.notifySubmitted();
return gadget.getDeclaredGadget('input_form');
})
.push(undefined, function (error) {
return form_gadget.notifySubmitted()
.push(function () {
throw error;
});
.push(function (form_gadget) {
var field_dict = {};
field_dict.your_message = {
"description": "",
"title": "Message",
"default": "",
"css_class": "",
"required": 1,
"editable": 1,
"key": "your_message",
"hidden": 0,
"type": "StringField"
};
return form_gadget.render({
erp5_document: {"_embedded": {"_view": field_dict}},
form_definition: {
group_list: [
["bottom", [["your_message"]]]
]
}
});
});
}
// Listen to form submit
return loopEventListener(
form_gadget.props.element.querySelector('form'),
'submit',
false,
formSubmit
);
})
if (modification_dict.hasOwnProperty('text')) {
queue
.push(function () {
return gadget.getDeclaredGadget('discussion_form');
})
.push(function (form_gadget) {
var text = gadget.state.text,
message_list = calculateMessageList(text),
field_list = [],
field_dict = {},
i,
now = (new Date()).toDateString();
.declareService(function () {
var gadget = this,
template_container = gadget.props.template_container,
keep_text_dict = gadget.props.keep_text_dict;
function changeMode() {
if (template_container.children[0].className === 'input-content') {
keep_text_dict.oneline = template_container.children[0].value;
template_container.removeChild(template_container.firstChild);
template_container.insertBefore(getDomFromString(textarea_template()),
template_container.firstChild);
template_container.children[0].value = keep_text_dict.textarea;
} else {
keep_text_dict.textarea = template_container.children[0].value;
template_container.removeChild(template_container.firstChild);
template_container.insertBefore(getDomFromString(input_template()),
template_container.firstChild);
template_container.children[0].value = keep_text_dict.oneline;
}
var typing_field = template_container.children[0];
typing_field.focus();
typing_field.select();
typing_field.selectionStart = typing_field.selectionEnd = typing_field.value.length;
function appendField(message) {
var field_id,
field_title,
current_field;
field_id = message.message_date.toLocaleString();
if (message.incoming) {
field_title = '< ';
} else {
field_title = '> ';
}
if (now === message.message_date.toDateString()) {
field_title += message.message_date.toLocaleTimeString();
} else {
field_title += message.message_date.toLocaleDateString();
}
field_list.push([field_id]);
current_field = {
"description": "",
"title": field_title,
"default": message.text,
"css_class": "",
"required": 0,
"editable": 0,
"key": field_id,
"hidden": 0,
"type": "TextAreaField"
};
field_dict[field_id] = current_field;
}
for (i = 0; i < message_list.length; i += 1) {
appendField(message_list[i]);
}
return form_gadget.render({
erp5_document: {"_embedded": {"_view": field_dict}},
form_definition: {
group_list: [
["center", field_list]
]
}
});
});
}
// Listen to button click
return loopEventListener(
gadget.props.element.querySelector('.custom-mode-change'),
'click',
false,
changeMode
);
if (modification_dict.hasOwnProperty('jio_key') ||
modification_dict.hasOwnProperty('refresh')) {
// Only scroll when displaying a new user discussion
// This allow to read discussion history without being annoyed by scroll
queue
.push(function () {
return gadget.scroll();
});
}
return queue;
})
.declareService(function () {
return scroll(this);
.onEvent('submit', function () {
var page_gadget = this;
return page_gadget.notifySubmitting()
.push(function () {
return page_gadget.getDeclaredGadget('input_form');
})
.push(function (input_form_gadget) {
return input_form_gadget.getContent();
})
.push(function (content) {
return page_gadget.jio_putAttachment(
page_gadget.state.jio_key,
'MESSAGE',
content.your_message
);
})
.push(function () {
return page_gadget.notifySubmitted();
})
.push(function () {
return page_gadget.render({
jio_key: page_gadget.state.jio_key,
refresh: new Date().getTime()
});
});
});
}(window, document, rJS, RSVP, Handlebars, loopEventListener));
\ No newline at end of file
}(window, document, rJS, RSVP));
\ No newline at end of file
......@@ -71,7 +71,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_dialog.js</string> </value>
<value> <string>gadget_erp5_page_jabberclient_dialog.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>951.19073.8210.16640</string> </value>
<value> <string>963.13465.59114.24746</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1463643257.07</float>
<float>1509719800.62</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -10,18 +10,16 @@
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_page_password.js" type="text/javascript"></script>
<script src="gadget_erp5_page_jabberclient_password.js" type="text/javascript"></script>
</head>
<body>
<pre></pre>
<form class="dialog_form">
<button type="submit" data-i18n="Submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-action ui-btn-icon-right ui-screen-hidden">Submit</button>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="erp5_form"
data-gadget-sandbox="public">
</div>
<input class="dialogconfirm" data-theme="b" data-inline="true" type="submit" data-i18n="[value]Change" value="Change" data-icon="check" />
</form>
</body>
</html>
\ No newline at end of file
......@@ -75,7 +75,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_password.html</string> </value>
<value> <string>gadget_erp5_page_jabberclient_password.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.26853.9657.64102</string> </value>
<value> <string>963.13535.17463.63488</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1456843254.57</float>
<float>1509719016.16</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, loopEventListener*/
/*global window, rJS, RSVP*/
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, loopEventListener) {
(function (window, rJS, RSVP) {
"use strict";
function validatePassword(password1, password2) {
......@@ -8,21 +8,6 @@
}
rJS(window)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
......@@ -30,6 +15,7 @@
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_put", "jio_put")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("redirect", "redirect")
......@@ -44,7 +30,7 @@
var page_gadget = this;
return page_gadget.updateHeader({
page_title: 'Reset Password',
submit_action: true
page_icon: 'power-off'
})
.push(function () {
// Ensure user is connected...
......@@ -100,48 +86,45 @@
});
})
.declareService(function () {
.onEvent('submit', function () {
var form_gadget = this;
function formSubmit() {
return form_gadget.notifySubmitting()
.push(function () {
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
return erp5_form.getContent();
})
.push(function (content_dict) {
if (validatePassword(content_dict.new_passwd, content_dict.repeat_passwd)) {
return form_gadget.jio_put(
'PASSWORD',
content_dict
);
}
// XXX Uses field validation instead...
throw new Error('Password does not match.');
})
.push(function () {
return RSVP.all([
form_gadget.notifySubmitted(),
form_gadget.redirect({command: 'display', options: {page: 'contact'}})
]);
})
.push(undefined, function (error) {
return form_gadget.notifySubmitted()
return form_gadget.notifySubmitting()
.push(function () {
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
return erp5_form.getContent();
})
.push(function (content_dict) {
if (validatePassword(content_dict.new_passwd, content_dict.repeat_passwd)) {
return form_gadget.jio_put(
'PASSWORD',
content_dict
)
.push(function () {
return RSVP.all([
form_gadget.notifySubmitted(),
form_gadget.notifyChange({
'message': "Password changed",
'status': 'success'
})
]);
})
.push(function () {
throw error;
return form_gadget.redirect({command: 'display',
options: {page: 'jabberclient_contact'}});
});
});
}
// Listen to form submit
return loopEventListener(
form_gadget.props.element.querySelector('form'),
'submit',
false,
formSubmit
);
}
// XXX Uses field validation instead...
return RSVP.all([
form_gadget.notifySubmitted(),
form_gadget.notifyChange({
'message': "Password does not match.",
'status': 'error'
})
]);
});
});
}(window, rJS, RSVP, loopEventListener));
\ No newline at end of file
}(window, rJS, RSVP));
\ No newline at end of file
......@@ -71,7 +71,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_password.js</string> </value>
<value> <string>gadget_erp5_page_jabberclient_password.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.26900.6119.6246</string> </value>
<value> <string>963.13541.25372.11042</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1456843245.07</float>
<float>1509719421.2</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -10,18 +10,16 @@
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_global.js" type="text/javascript"></script>
<script src="gadget_jabberclient_page_subscribe.js" type="text/javascript"></script>
<script src="gadget_erp5_page_jabberclient_new_contact.js" type="text/javascript"></script>
</head>
<body>
<pre></pre>
<form class="dialog_form">
<button type="submit" data-i18n="Submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-action ui-btn-icon-right ui-screen-hidden">Submit</button>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="erp5_form"
data-gadget-sandbox="public">
</div>
<input class="dialogconfirm" data-theme="b" data-inline="true" type="submit" data-i18n="[value]Add" value="Add" data-icon="check" />
</form>
</body>
</html>
\ No newline at end of file
......@@ -75,7 +75,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_subscribe.html</string> </value>
<value> <string>gadget_erp5_page_jabberclient_new_contact.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.26823.54523.58094</string> </value>
<value> <string>963.13508.24026.19831</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1456843200.45</float>
<float>1509717763.65</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, loopEventListener*/
/*global window, rJS, RSVP*/
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, loopEventListener) {
(function (window, rJS, RSVP) {
"use strict";
rJS(window)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
......@@ -26,6 +11,7 @@
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", "notifySubmitted")
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareAcquiredMethod("jio_put", "jio_put")
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("redirect", "redirect")
......@@ -34,13 +20,13 @@
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('triggerSubmit', function () {
this.props.element.querySelector('button').click();
this.element.querySelector('button').click();
})
.declareMethod("render", function () {
var page_gadget = this;
return page_gadget.updateHeader({
page_title: 'New Contact',
submit_action: true
page_icon: 'gear'
})
.push(function () {
// Ensure user is connected...
......@@ -74,44 +60,35 @@
});
})
.declareService(function () {
.onEvent('submit', function () {
var form_gadget = this;
function formSubmit() {
return form_gadget.notifySubmitting()
.push(function () {
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
return erp5_form.getContent();
})
.push(function (content_dict) {
return form_gadget.jio_put(
'SUBSCRIBE',
content_dict
);
})
.push(function () {
return RSVP.all([
form_gadget.notifySubmitted(),
form_gadget.redirect({command: 'display', options: {page: 'contact'}})
]);
})
.push(undefined, function (error) {
return form_gadget.notifySubmitted()
.push(function () {
throw error;
});
});
}
// Listen to form submit
return loopEventListener(
form_gadget.props.element.querySelector('form'),
'submit',
false,
formSubmit
);
return form_gadget.notifySubmitting()
.push(function () {
return form_gadget.getDeclaredGadget("erp5_form");
})
.push(function (erp5_form) {
return erp5_form.getContent();
})
.push(function (content_dict) {
return form_gadget.jio_put(
'SUBSCRIBE',
content_dict
);
})
.push(function () {
return RSVP.all([
form_gadget.notifySubmitted(),
form_gadget.notifyChange({
'message': "Contact added",
'status': 'success'
})
]);
})
.push(function () {
return form_gadget.redirect({command: 'display',
options: {page: 'jabberclient_contact'}});
});
});
}(window, rJS, RSVP, loopEventListener));
\ No newline at end of file
}(window, rJS, RSVP));
\ No newline at end of file
......@@ -71,7 +71,7 @@
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_page_subscribe.js</string> </value>
<value> <string>gadget_erp5_page_jabberclient_new_contact.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.26838.22974.62054</string> </value>
<value> <string>963.13526.23121.58146</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1456843207.84</float>
<float>1509718633.02</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -3,43 +3,70 @@
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>ERP5 Panel</title>
<title>Jabber Panel</title>
<!--
data-i18n=Editable
-->
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script src="jquery.js" type="text/javascript"></script>
<script src="jquerymobile.js" type="text/javascript"></script>
<script id="panel-template-header" type="text/x-handlebars-template">
<div data-role="header" class="ui-bar-inherit">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
<form action="#" method="post">
<input type="submit" data-i18n="[value]Close" data-icon="delete" data-iconpos="notext" value="Close" />
</form>
</div>
</div>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
<a href="#" class="ui-btn ui-btn-icon-notext ui-icon-home" data-i18n="Home">Home</a>
<button data-i18n="Close" class="ui-btn ui-btn-icon-notext ui-icon-delete">Close</button>
</div>
</div>
<!--div class="panel_img">
<img class="ui-title" alt="ERP5" src="gadget_erp5_panel.png?format=png"/>
</div-->
</div>
</script>
<script id="panel-template-body" type="text/x-handlebars-template">
<div class="ui-content">
<ul data-role="listview" class="ui-listview" data-enhanced="true">
<li class="ui-first-child"><a href="{{contact_href}}" class="ui-btn ui-btn-icon-left ui-icon-puzzle-piece" data-i18n="Contacts">Contacts</a></li>
<li><a href="{{subscribe_href}}" class="ui-btn ui-btn-icon-left ui-icon-gear" data-i18n="New Contact">New Contact</a></li>
<li class="ui-last-child"><a href="{{password_href}}" class="ui-btn ui-btn-icon-left ui-icon-power-off" data-i18n="Password">Password</a></li>
</ul>
<!--form class="dialog_form">
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-action ui-btn-icon-right ui-screen-hidden">Submit</button>
<div data-gadget-url="gadget_erp5_searchfield.html"
data-gadget-scope="erp5_searchfield"
data-gadget-sandbox="public"></div>
</form-->
<ul data-role="listview" class="ui-listview" data-enhanced="true"></ul>
<div data-gadget-url="gadget_erp5_field_checkbox.html"
data-gadget-scope="erp5_checkbox"
data-gadget-sandbox="public"></div>
<dl></dl>
</div>
</script>
<script id="panel-template-body-list" type="text/x-handlebars-template">
<li class="ui-first-child"><a href="{{contact_href}}" class="ui-btn ui-btn-icon-left ui-icon-puzzle-piece" data-i18n="Contacts">Contacts</a></li>
<li><a href="{{new_contact_href}}" class="ui-btn ui-btn-icon-left ui-icon-gear" data-i18n="New Contact" accesskey="m">New Contact</a></li>
<li><a href="{{password_href}}" class="ui-btn ui-btn-icon-left ui-icon-power-off" data-i18n="Password" accesskey="w">Password</a></li>
</script>
<!--script id="panel-template-body-desktop" type="text/x-handlebars-template">
<dt class="ui-content-title ui-body-c ui-btn ui-btn-icon-left ui-icon-eye" data-i18n="Views">Views</dt>
{{#each view_list}}
<dd data-role="listview" data-theme="c" data-inset="true" class="document-listview">
<a data-i18n="{{title}}" class="ui-body-inherit" href="{{href}}">{{title}}</a>
</dd>
{{/each}}
<dt class="ui-content-title ui-body-c ui-btn ui-btn-icon-left ui-icon-cogs" data-i18n="Decisions">Decisions</dt>
{{#each workflow_list}}
<dd data-role="listview" data-theme="c" data-inset="true" class="document-listview">
<a data-i18n="{{title}}" class="ui-body-inherit" href="{{href}}">{{title}}</a>
</dd>
{{/each}}
</script-->
<!-- custom script -->
<script src="gadget_jabberclient_panel.js" type="text/javascript"></script>
......@@ -47,6 +74,5 @@
<body>
<div class="jqm-navmenu-panel"></div>
</body>
</html>
\ No newline at end of file
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.35375.42111.29422</string> </value>
<value> <string>963.13496.32563.39014</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1456843184.4</float>
<float>1509724597.78</float>
<string>UTC</string>
</tuple>
</state>
......
/*jslint nomen: true, indent: 2, maxerr: 3 */
/*global window, rJS, Handlebars, jQuery, RSVP, loopEventListener */
(function (window, rJS, Handlebars, $, RSVP, loopEventListener) {
/*jslint nomen: true, indent: 2, maxerr: 3, unparam: true */
/*global window, document, rJS, Handlebars, RSVP, Node, loopEventListener */
(function (window, document, rJS, Handlebars, RSVP, Node, loopEventListener) {
"use strict";
/////////////////////////////////////////////////////////////////
......@@ -8,108 +8,235 @@
/////////////////////////////////////////////////////////////////
// Precompile templates while loading the first gadget instance
var gadget_klass = rJS(window),
source_header = gadget_klass.__template_element
template_element = gadget_klass.__template_element,
panel_template_header = Handlebars.compile(template_element
.getElementById("panel-template-header")
.innerHTML,
panel_template_header = Handlebars.compile(source_header),
source_body = gadget_klass.__template_element
.innerHTML),
panel_template_body = Handlebars.compile(template_element
.getElementById("panel-template-body")
.innerHTML,
panel_template_body = Handlebars.compile(source_body);
.innerHTML),
panel_template_body_list = Handlebars.compile(template_element
.getElementById("panel-template-body-list")
.innerHTML);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
.setState({
visible: false,
desktop: false
})
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.jelement = $(element.querySelector("div"));
g.props.render_deferred = RSVP.defer();
});
})
.ready(function (g) {
g.props.jelement.panel({
display: "overlay",
position: "left",
theme: "d"
// animate: false
});
})
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("translate", "translate")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod('toggle', function () {
this.props.jelement.panel("toggle");
return this.changeState({
visible: !this.state.visible
});
})
.declareMethod('close', function () {
this.props.jelement.panel("close");
return this.changeState({
visible: false
});
})
.declareMethod('render', function () {
var g = this;
return new RSVP.Queue()
.push(function () {
return RSVP.all([
g.getUrlFor({command: 'display', options: {page: "contact"}}),
g.getUrlFor({command: 'display', options: {page: "subscribe"}}),
g.getUrlFor({command: 'display', options: {page: "password"}})
]);
})
.push(function (all_result) {
// XXX: Customize panel header!
var tmp = panel_template_header();
tmp += panel_template_body({
"contact_href": all_result[0],
"subscribe_href": all_result[1],
"password_href": all_result[2]
.declareMethod('render', function (options) {
var erp5_document = options.erp5_document,
workflow_list,
view_list,
context = this;
if (erp5_document !== undefined) {
workflow_list = erp5_document._links.action_workflow || [];
view_list = erp5_document._links.action_object_view || [];
if (workflow_list.constructor !== Array) {
workflow_list = [workflow_list];
}
if (view_list.constructor !== Array) {
view_list = [view_list];
}
// Prevent has much as possible to modify the DOM panel
// stateChange prefer to compare strings
workflow_list = JSON.stringify(workflow_list);
view_list = JSON.stringify(view_list);
}
return context.getUrlParameter('editable')
.push(function (editable) {
return context.changeState({
workflow_list: workflow_list,
view_list: view_list,
global: true,
editable: options.editable || editable || false
});
return tmp;
})
.push(function (my_translated_or_plain_html) {
g.props.jelement.html(my_translated_or_plain_html);
g.props.jelement.trigger("create");
g.props.render_deferred.resolve();
});
})
/////////////////////////////////////////////////////////////////
// declared services
/////////////////////////////////////////////////////////////////
.declareService(function () {
var panel_gadget = this;
.onStateChange(function (modification_dict) {
var context = this,
queue = new RSVP.Queue(),
tmp_element;
function formSubmit() {
panel_gadget.toggle();
if (modification_dict.hasOwnProperty("visible")) {
if (this.state.visible) {
if (!this.element.classList.contains('visible')) {
this.element.classList.toggle('visible');
}
} else {
if (this.element.classList.contains('visible')) {
this.element.classList.remove('visible');
}
}
}
return new RSVP.Queue()
.push(function () {
return panel_gadget.props.render_deferred.promise;
})
.push(function () {
return loopEventListener(
panel_gadget.props.element.querySelector('form'),
'submit',
false,
formSubmit
);
if (modification_dict.hasOwnProperty("global")) {
queue
.push(function () {
// XXX: Customize panel header!
return context.translateHtml(
panel_template_header() +
panel_template_body()
);
})
.push(function (my_translated_or_plain_html) {
tmp_element = document.createElement('div');
tmp_element.innerHTML = my_translated_or_plain_html;
context.element.querySelector("div").appendChild(tmp_element);
return context.listenResize();
});
}
if (modification_dict.hasOwnProperty("editable")) {
queue
// Update the global links
.push(function () {
return RSVP.all([
context.getUrlFor({command: 'display', options: {page: "jabberclient_contact"}}),
context.getUrlFor({command: 'display', options: {page: "jabberclient_new_contact"}}),
context.getUrlFor({command: 'display', options: {page: "jabberclient_password"}})
]);
})
.push(function (result_list) {
return context.translateHtml(
panel_template_body_list({
"contact_href": result_list[0],
"new_contact_href": result_list[1],
"password_href": result_list[2]
})
);
})
.push(function (result) {
context.element.querySelector("ul").innerHTML = result;
});
}
/*
if ((this.state.global === true) &&
(modification_dict.hasOwnProperty("desktop") ||
modification_dict.hasOwnProperty("editable") ||
modification_dict.hasOwnProperty("workflow_list") ||
modification_dict.hasOwnProperty("view_list"))) {
if (!(this.state.desktop && (this.state.view_list !== undefined))) {
queue
.push(function () {
gadget.element.querySelector("dl").textContent = '';
});
} else {
queue
.push(function () {
var i = 0,
promise_list = [],
workflow_list = JSON.parse(gadget.state.workflow_list),
view_list = JSON.parse(gadget.state.view_list);
for (i = 0; i < workflow_list.length; i += 1) {
promise_list.push(
gadget.getUrlFor({
command: 'change',
options: {
view: workflow_list[i].href,
page: undefined
}
})
);
}
for (i = 0; i < view_list.length; i += 1) {
promise_list.push(
gadget.getUrlFor({
command: 'change',
options: {
view: view_list[i].href,
page: undefined
}
})
);
}
return RSVP.all(promise_list);
})
.push(function (result_list) {
var i,
result_workflow_list = [],
result_view_list = [],
workflow_list = JSON.parse(gadget.state.workflow_list),
view_list = JSON.parse(gadget.state.view_list);
for (i = 0; i < workflow_list.length; i += 1) {
result_workflow_list.push({
title: workflow_list[i].title,
href: result_list[i]
});
}
for (i = 0; i < view_list.length; i += 1) {
result_view_list.push({
title: view_list[i].title,
href: result_list[i + workflow_list.length]
});
}
gadget.element.querySelector("dl").innerHTML = panel_template_body_desktop({
workflow_list: result_workflow_list,
view_list: result_view_list
});
});
}
}
*/
return queue;
})
.declareJob('listenResize', function () {
// resize should be only trigger after the render method
// as displaying the panel rely on external gadget (for translation for example)
var result,
event,
context = this;
function extractSizeAndDispatch() {
if (window.matchMedia("(min-width: 85em)").matches) {
return context.changeState({
desktop: true
});
}
return context.changeState({
desktop: false
});
}
result = loopEventListener(window, 'resize', false,
extractSizeAndDispatch);
event = document.createEvent("Event");
event.initEvent('resize', true, true);
window.dispatchEvent(event);
return result;
})
});
.onEvent('click', function (evt) {
if ((evt.target.nodeType === Node.ELEMENT_NODE) &&
(evt.target.tagName === 'BUTTON')) {
return this.toggle();
}
}, false, false);
}(window, rJS, Handlebars, jQuery, RSVP, loopEventListener));
\ No newline at end of file
}(window, document, rJS, Handlebars, RSVP, Node, loopEventListener));
......@@ -230,7 +230,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.26657.64277.54118</string> </value>
<value> <string>963.13497.47750.35106</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -248,7 +248,7 @@
</tuple>
<state>
<tuple>
<float>1456843167.64</float>
<float>1509724562.9</float>
<string>UTC</string>
</tuple>
</state>
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Router Gadget</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="gadget_jabberclient_router.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Page" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_router.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jabber_gadget_router_html</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Page</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>JabberClient Gadget Router</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1456334074.25</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.24010.37433.15462</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1456843272.44</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1456333611.93</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
/*global window, rJS, RSVP, loopEventListener, document, URL */
/*jslint nomen: true, indent: 2 */
(function (window, rJS, RSVP, loopEventListener, document, URL) {
"use strict";
// Keep reference of the latest allDocs params which reach to this view
// var SELECTION_KEY = "s",
// Keep reference in the global navigation pattern
// HISTORY KEY = "h"
// Current display parameter
// DISPLAY KEY = "d"
var PREVIOUS_KEY = "p",
NEXT_KEY = "n",
DROP_KEY = "u",
PREFIX_DISPLAY = "/",
PREFIX_COMMAND = "!",
// PREFIX_ERROR = "?",
COMMAND_DISPLAY_STATE = "display",
COMMAND_LOGIN = "login",
COMMAND_RAW = "raw",
COMMAND_RELOAD = "reload",
COMMAND_DISPLAY_STORED_STATE = "display_stored_state",
COMMAND_CHANGE_STATE = "change",
COMMAND_STORE_AND_CHANGE_STATE = "store_and_change",
COMMAND_INDEX_STATE = "index",
COMMAND_SELECTION_PREVIOUS = "selection_previous",
COMMAND_SELECTION_NEXT = "selection_next",
COMMAND_HISTORY_PREVIOUS = "history_previous",
COMMAND_PUSH_HISTORY = "push_history",
REDIRECT_TIMEOUT = 5000,
VALID_URL_COMMAND_DICT = {};
VALID_URL_COMMAND_DICT[COMMAND_DISPLAY_STATE] = null;
VALID_URL_COMMAND_DICT[COMMAND_DISPLAY_STORED_STATE] = null;
VALID_URL_COMMAND_DICT[COMMAND_CHANGE_STATE] = null;
VALID_URL_COMMAND_DICT[COMMAND_STORE_AND_CHANGE_STATE] = null;
VALID_URL_COMMAND_DICT[COMMAND_INDEX_STATE] = null;
VALID_URL_COMMAND_DICT[COMMAND_SELECTION_PREVIOUS] = null;
VALID_URL_COMMAND_DICT[COMMAND_SELECTION_NEXT] = null;
VALID_URL_COMMAND_DICT[COMMAND_HISTORY_PREVIOUS] = null;
VALID_URL_COMMAND_DICT[COMMAND_PUSH_HISTORY] = null;
VALID_URL_COMMAND_DICT[COMMAND_LOGIN] = null;
VALID_URL_COMMAND_DICT[COMMAND_RAW] = null;
VALID_URL_COMMAND_DICT[COMMAND_RELOAD] = null;
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
//////////////////////////////////////////////////////////////////
// Change URL functions
//////////////////////////////////////////////////////////////////
function changeState(hash) {
// window.location = hash;
return window.location.replace(hash);
}
function synchronousChangeState(hash) {
changeState(hash);
// prevent returning unexpected response
// wait for the hash change to occur
// fail if nothing happens
return RSVP.timeout(REDIRECT_TIMEOUT);
}
//////////////////////////////////////////////////////////////////
// Build URL functions
//////////////////////////////////////////////////////////////////
function getCommandUrlFor(gadget, command, options) {
if (command === COMMAND_RAW) {
return options.url;
}
var result = "#" + PREFIX_COMMAND + (command || ""),
prefix = "?",
key,
tmp,
tmp_dict;
tmp_dict = gadget.props.options;
for (key in tmp_dict) {
if (tmp_dict.hasOwnProperty(key) && (tmp_dict[key] !== undefined)) {
tmp = tmp_dict[key];
if (endsWith(key, ":json")) {
tmp = JSON.stringify(tmp);
}
result += prefix + PREVIOUS_KEY + "." + encodeURIComponent(key) + "=" + encodeURIComponent(tmp);
prefix = "&";
}
}
for (key in options) {
if (options.hasOwnProperty(key)) {
tmp = options[key];
if (tmp === undefined) {
// Key should be dropped from the URL
result += prefix + DROP_KEY + "." + encodeURIComponent(key) + "=";
} else {
if (endsWith(key, ":json")) {
tmp = JSON.stringify(tmp);
}
result += prefix + NEXT_KEY + "." + encodeURIComponent(key) + "=" + encodeURIComponent(tmp);
}
prefix = "&";
}
}
if (command === COMMAND_LOGIN) {
// Build URL template to allow getting user information
result += '{' + prefix + 'n.me}';
}
return result;
}
function getDisplayUrlFor(jio_key, options) {
var prefix = '?',
result,
tmp,
key;
result = "#" + PREFIX_DISPLAY + (jio_key || "");
for (key in options) {
if (options.hasOwnProperty(key) && options[key] !== undefined) {
// Don't keep empty values
tmp = options[key];
if (endsWith(key, ":json")) {
tmp = JSON.stringify(tmp);
}
result += prefix + encodeURIComponent(key) + "=" + encodeURIComponent(tmp);
prefix = '&';
}
}
return result;
}
//////////////////////////////////////////////////////////////////
// exec command functions
//////////////////////////////////////////////////////////////////
function execDisplayCommand(next_options) {
// console.warn(command_options);
var jio_key = next_options.jio_key,
hash;
delete next_options.jio_key;
hash = getDisplayUrlFor(jio_key, next_options);
return new RSVP.Queue()
.push(function () {
return synchronousChangeState(hash);
});
}
//////////////////////////////////////////////////////////////////
// Command URL functions
//////////////////////////////////////////////////////////////////
function routeMethodLess() {
// Nothing. Go to front page
return synchronousChangeState(
getDisplayUrlFor(undefined, {page: 'contact'})
);
}
function routeDisplay(command_options) {
if (command_options.args.page === undefined) {
return routeMethodLess();
}
return {
url: "gadget_jabberclient_page_" + command_options.args.page + ".html",
options: command_options.args
};
}
function routeCommand(command_options) {
var args = command_options.args,
key,
split_list,
previous_options = {},
next_options = {},
drop_options = {},
valid = true;
// Rebuild the previous and next parameter dict
for (key in args) {
if (args.hasOwnProperty(key)) {
split_list = key.split('.', 2);
if (split_list.length !== 2) {
valid = false;
break;
}
if (split_list[0] === PREVIOUS_KEY) {
previous_options[split_list[1]] = args[key];
} else if (split_list[0] === NEXT_KEY) {
next_options[split_list[1]] = args[key];
} else if (split_list[0] === DROP_KEY) {
drop_options[split_list[1]] = args[key];
} else {
valid = false;
break;
}
}
}
if (!valid) {
throw new Error('Unsupported parameters: ' + key);
}
if (command_options.path === COMMAND_DISPLAY_STATE) {
return execDisplayCommand(next_options);
}
throw new Error('Unsupported command ' + command_options.path);
}
function listenHashChange(gadget) {
// Handle hash in this format: #$path1/path2?a=b&c=d
function extractHashAndDispatch(evt) {
var hash = (evt.newURL || window.location.toString()).split('#')[1],
split,
command = "",
query = "",
subhashes,
subhash,
keyvalue,
index,
key,
tmp,
args = {};
if (hash !== undefined) {
split = hash.split('?');
command = split[0] || "";
query = split[1] || "";
}
subhashes = query.split('&');
for (index in subhashes) {
if (subhashes.hasOwnProperty(index)) {
subhash = subhashes[index];
if (subhash !== '') {
keyvalue = subhash.split('=');
if (keyvalue.length === 2) {
key = decodeURIComponent(keyvalue[0]);
tmp = decodeURIComponent(keyvalue[1]);
if (endsWith(key, ":json")) {
tmp = JSON.parse(tmp);
}
args[key] = tmp;
}
}
}
}
return gadget.renderApplication({
method: command[0],
path: command.substr(1),
args: args
});
}
var result = loopEventListener(window, 'hashchange', false,
extractHashAndDispatch),
event = document.createEvent("Event");
event.initEvent('hashchange', true, true);
event.newURL = window.location.toString();
window.dispatchEvent(event);
return result;
}
rJS(window)
.ready(function (gadget) {
gadget.props = {
options: {},
start_deferred: RSVP.defer()
};
})
.declareMethod('getCommandUrlFor', function (options) {
var command = options.command,
absolute_url = options.absolute_url,
hash,
args = options.options,
valid = true,
key;
// Only authorize 'command', 'options', 'absolute_url' keys
// Drop all other kind of parameters, to detect issue more easily
for (key in options) {
if (options.hasOwnProperty(key)) {
if ((key !== 'command') && (key !== 'options') && (key !== 'absolute_url')) {
valid = false;
}
}
}
if (valid && (options.command) && (VALID_URL_COMMAND_DICT.hasOwnProperty(options.command))) {
hash = getCommandUrlFor(this, command, args);
} else {
hash = getCommandUrlFor(this, 'error', options);
}
if (absolute_url) {
hash = new URL(hash, window.location.href).href;
}
return hash;
})
.declareMethod('redirect', function (options) {
return this.getCommandUrlFor(options)
.push(function (hash) {
window.location.replace(hash);
// prevent returning unexpected response
// wait for the hash change to occur
// fail if nothing happens
return RSVP.timeout(REDIRECT_TIMEOUT);
});
})
.declareMethod('getUrlParameter', function (key) {
return this.props.options[key];
})
.declareMethod('route', function (command_options) {
if (command_options.method === PREFIX_DISPLAY) {
return routeDisplay(command_options);
}
if (command_options.method === PREFIX_COMMAND) {
return routeCommand(command_options);
}
if (command_options.method) {
throw new Error('Unsupported hash method: ' + command_options.method);
}
return routeMethodLess();
})
.declareMethod('start', function () {
this.props.start_deferred.resolve();
})
.declareAcquiredMethod('renderApplication', 'renderApplication')
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.start_deferred.promise;
})
.push(function () {
// console.info('router service: listen to hash change');
return listenHashChange(gadget);
});
});
}(window, rJS, RSVP, loopEventListener, document, URL));
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_jabberclient_router.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jabber_gadget_router_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>JabberClient Gadget Router JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1456334186.39</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>949.35416.23201.12748</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1456845631.45</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1456333611.91</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
......@@ -249,6 +249,16 @@
<value> <string>string</string> </value>
</item>
</dictionary>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>configuration_frontpage_gadget_url</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
......@@ -283,7 +293,7 @@
<value>
<tuple>
<string>caching_policy/must-revalidate</string>
<string>aggregate/web_page_module/rjs_gadget_erp5_html</string>
<string>aggregate/web_page_module/rjs_gadget_erp5_launcher_html</string>
</tuple>
</value>
</item>
......@@ -293,11 +303,17 @@
</item>
<item>
<key> <string>configuration_content_security_policy</string> </key>
<value> <string>default-src \'none\'; img-src \'self\' data:; media-src \'self\' blob:; connect-src \'self\' data:; script-src \'self\' \'unsafe-eval\'; font-src \'self\'; style-src \'self\' netdna.bootstrapcdn.com \'unsafe-inline\' data:; frame-src \'self\' data:</string> </value>
<value> <string>default-src \'none\'; img-src \'self\' data:; media-src \'self\' blob:; connect-src \'self\' data:; script-src \'self\' \'unsafe-eval\'; font-src \'self\'; style-src \'self\' \'unsafe-inline\' data:; frame-src \'self\' data:</string> </value>
</item>
<item>
<key> <string>configuration_frontpage_gadget_url</string> </key>
<value> <string>jabberclient_contact</string> </value>
</item>
<item>
<key> <string>configuration_header_gadget_url</string> </key>
<value> <string>gadget_officejs_header.html</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>configuration_jio_gadget_url</string> </key>
......@@ -305,7 +321,9 @@
</item>
<item>
<key> <string>configuration_manifest_url</string> </key>
<value> <string>gadget_jabberclient.appcache</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>configuration_panel_gadget_url</string> </key>
......@@ -313,7 +331,9 @@
</item>
<item>
<key> <string>configuration_router_gadget_url</string> </key>
<value> <string>gadget_jabberclient_router.html</string> </value>
<value>
<none/>
</value>
</item>
<item>
<key> <string>configuration_translation_gadget_url</string> </key>
......@@ -540,7 +560,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>vincent</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -554,7 +574,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>961.17525.46862.41420</string> </value>
<value> <string>963.11902.18137.7850</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -572,7 +592,7 @@
</tuple>
<state>
<tuple>
<float>1509358218.96</float>
<float>1509715169.81</float>
<string>UTC</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