Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eteri
erp5
Commits
b54b55dd
Commit
b54b55dd
authored
Jan 17, 2017
by
Romain Courteaud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[erp5_xhtml_style] Do not crash the UI in case of gadget error
parent
48b1447b
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
150 additions
and
125 deletions
+150
-125
product/ERP5/bootstrap/erp5_xhtml_style/SkinTemplateItem/portal_skins/erp5_xhtml_style/erp5_gadgetfield.js.js
...Item/portal_skins/erp5_xhtml_style/erp5_gadgetfield.js.js
+150
-125
No files found.
product/ERP5/bootstrap/erp5_xhtml_style/SkinTemplateItem/portal_skins/erp5_xhtml_style/erp5_gadgetfield.js.js
View file @
b54b55dd
/*global window, rJS, RSVP, document*/
/*global window, rJS, RSVP, document
, console
*/
/*jslint nomen: true, maxlen:80, indent:2*/
(
function
(
window
,
document
,
rJS
,
RSVP
)
{
(
function
(
window
,
rJS
,
RSVP
,
document
,
console
)
{
"
use strict
"
;
function
promiseEventListener
(
target
,
type
,
useCapture
)
{
//////////////////////////
// Resolve the promise as soon as the event is triggered
...
...
@@ -27,109 +28,124 @@
return
new
RSVP
.
Promise
(
resolver
,
canceller
);
}
function
displayFieldError
(
error
)
{
console
.
warn
(
error
);
// Display the error message in the portal_status location
// As renderJS does not report which element is failing while loading
// a gadget
var
error_element
=
document
.
getElementById
(
'
transition_message
'
);
error_element
.
textContent
=
error
+
'
.
'
+
error_element
.
textContent
;
}
function
getGadgetContent
(
gadget
)
{
return
gadget
.
getContent
()
.
push
(
undefined
,
function
(
error
)
{
// Do not crash if gadget getContent is wrongly implemented,
// ie, UI should work even if one gadget does not
displayFieldError
(
error
);
return
{};
});
}
rJS
(
window
)
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.
ready
(
function
(
g
)
{
g
.
props
=
{};
.
setState
({
rejected_dict
:
{},
field_list
:
[],
gadget_list
:
[]
})
// Assign the element to a variable
.
ready
(
function
(
g
)
{
return
g
.
getElement
()
.
push
(
function
(
element
)
{
g
.
props
.
element
=
element
;
});
.
allowPublicAcquisition
(
'
reportGadgetDeclarationError
'
,
function
(
argument_list
,
scope
)
{
// Do not crash the UI in case of wrongly configured gadget,
// bad network, loading bug.
this
.
state
.
rejected_dict
[
scope
]
=
null
;
return
displayFieldError
(
argument_list
[
0
]);
})
.
allowPublicAcquisition
(
'
reportServiceError
'
,
function
(
argument_list
)
{
// Do not crash the UI in case of gadget service error.
return
displayFieldError
(
argument_list
[
0
]);
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.
declareService
(
function
()
{
var
g
=
this
,
i
,
list_gadget
=
document
.
querySelectorAll
(
"
[data-gadget-url]
"
),
all_gadget
,
list
=
[],
gadget_attributes
=
[],
url
,
form
=
g
.
props
.
element
.
querySelector
(
"
form
"
),
scope
,
value
,
key
,
tmp
;
for
(
i
=
0
;
i
<
list_gadget
.
length
;
i
+=
1
)
{
url
=
list_gadget
[
i
].
getAttribute
(
"
data-gadget-url
"
);
key
=
list_gadget
[
i
].
getAttribute
(
"
data-gadget-editable
"
);
value
=
list_gadget
[
i
].
getAttribute
(
"
data-gadget-value
"
);
//renderable
if
(
url
!==
undefined
&&
url
!==
null
)
{
tmp
=
{};
scope
=
list_gadget
[
i
].
getAttribute
(
"
data-gadget-scope
"
);
list
.
push
(
g
.
getDeclaredGadget
(
scope
));
tmp
.
sandbox
=
list_gadget
[
i
].
getAttribute
(
"
data-gadget-sandbox
"
);
tmp
.
editable
=
key
;
tmp
.
key
=
key
;
tmp
.
value
=
value
;
gadget_attributes
.
push
(
tmp
);
}
}
// Call render on all gadget fields
var
gadget
=
this
,
field_list
=
[],
i
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
RSVP
.
all
(
list
);
})
.
push
(
function
(
results
)
{
all_gadget
=
results
;
list
=
[];
for
(
i
=
0
;
i
<
gadget_attributes
.
length
;
i
+=
1
)
{
if
(
gadget_attributes
[
i
].
sandbox
===
"
iframe
"
)
{
list
.
push
(
all_gadget
[
i
].
getElement
());
var
field_element_list
=
gadget
.
element
.
querySelectorAll
(
"
[data-gadget-url]
"
),
field_element
,
field_scope
,
field_url
,
promise_list
=
[];
for
(
i
=
0
;
i
<
field_element_list
.
length
;
i
+=
1
)
{
field_element
=
field_element_list
[
i
];
field_url
=
field_element
.
getAttribute
(
"
data-gadget-url
"
);
field_scope
=
field_element
.
getAttribute
(
"
data-gadget-scope
"
);
// Renderable
if
((
field_url
!==
undefined
)
&&
(
field_url
!==
null
)
&&
(
field_scope
!==
null
)
&&
(
!
gadget
.
state
.
rejected_dict
.
hasOwnProperty
(
field_scope
)))
{
field_list
.
push
({
sandbox
:
field_element
.
getAttribute
(
"
data-gadget-sandbox
"
),
editable
:
field_element
.
getAttribute
(
"
data-gadget-editable
"
),
key
:
field_element
.
getAttribute
(
"
data-gadget-editable
"
),
value
:
field_element
.
getAttribute
(
"
data-gadget-value
"
)
});
promise_list
.
push
(
gadget
.
getDeclaredGadget
(
field_scope
));
}
}
return
RSVP
.
all
(
list
);
gadget
.
state
.
field_list
=
field_list
;
return
RSVP
.
all
(
promise_list
);
})
.
push
(
function
(
elements
)
{
.
push
(
function
(
result_list
)
{
gadget
.
state
.
gadget_list
=
result_list
;
var
iframe
,
j
,
sub_element
,
sub_value
,
sub_key
;
list
=
[];
for
(
i
=
0
,
j
=
0
;
i
<
gadget_attributes
.
length
;
i
+=
1
)
{
if
(
all_gadget
[
i
].
render
!==
undefined
)
{
sub_value
=
gadget_attributes
[
i
].
value
;
sub_key
=
gadget_attributes
[
i
].
key
;
list
.
push
(
all_gadget
[
i
].
render
(
{
"
key
"
:
sub_key
,
"
value
"
:
sub_value
}
).
push
(
undefined
,
function
(
error
)
{
/* TODO: Highlight the gadget element with a small colored
sub_key
,
promise_list
=
[];
for
(
i
=
0
;
i
<
field_list
.
length
;
i
+=
1
)
{
if
(
result_list
[
i
].
render
!==
undefined
)
{
sub_value
=
field_list
[
i
].
value
;
sub_key
=
field_list
[
i
].
key
;
promise_list
.
push
(
result_list
[
i
].
render
({
key
:
sub_key
,
value
:
sub_value
})
.
push
(
undefined
,
displayFieldError
)
/* XXX Highlight the gadget element with a small colored
* error message. Clicking on the element could unroll
* more information like the traceback. */
console
.
log
(
error
);
})
);
}
if
(
gadget_attributes
[
i
].
sandbox
===
"
iframe
"
)
{
iframe
=
elements
[
j
].
querySelector
(
'
iframe
'
);
if
(
field_list
[
i
].
sandbox
===
"
iframe
"
)
{
sub_element
=
result_list
[
i
].
element
;
iframe
=
sub_element
.
querySelector
(
'
iframe
'
);
//xxx input field
elements
[
j
]
.
parentNode
.
style
.
width
=
"
100%
"
;
elements
[
j
]
.
parentNode
.
style
.
height
=
"
100%
"
;
sub_element
.
parentNode
.
style
.
width
=
"
100%
"
;
sub_element
.
parentNode
.
style
.
height
=
"
100%
"
;
//xxx section div
elements
[
j
]
.
style
.
width
=
"
100%
"
;
elements
[
j
]
.
style
.
height
=
"
100%
"
;
sub_element
.
style
.
width
=
"
100%
"
;
sub_element
.
style
.
height
=
"
100%
"
;
iframe
.
style
.
width
=
"
100%
"
;
iframe
.
style
.
height
=
"
100%
"
;
iframe
.
allowFullscreen
=
true
;
j
+=
1
;
}
}
return
RSVP
.
all
(
list
);
return
RSVP
.
all
(
promise_list
);
});
})
.
push
(
function
()
{
.
declareService
(
function
()
{
/*Do not use ajax call but submit an hidden form.
So in this way, we can use form submit mecanisme
provided by browser.
...
...
@@ -142,28 +158,37 @@
submit/image button.
After all, submit the form manually again.
*/
var
input_images
=
g
.
props
.
element
.
querySelectorAll
(
"
input[type='image']
"
),
input_submits
=
g
.
props
.
element
.
querySelectorAll
(
"
button[type='submit']
"
);
list
=
[];
if
(
input_images
.
length
||
input_submits
.
length
)
{
list
.
push
(
promiseEventListener
(
g
.
props
.
element
,
"
submit
"
,
false
));
for
(
i
=
0
;
i
<
input_images
.
length
;
i
+=
1
)
{
list
.
push
(
promiseEventListener
(
input_images
[
i
],
"
click
"
,
false
));
}
for
(
i
=
0
;
i
<
input_submits
.
length
;
i
+=
1
)
{
list
.
push
(
promiseEventListener
(
input_submits
[
i
],
"
click
"
,
false
));
}
return
RSVP
.
any
(
list
);
}
return
promiseEventListener
(
g
.
props
.
element
,
"
submit
"
,
false
);
var
context
=
this
,
form
=
this
.
element
.
querySelector
(
"
form
"
);
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
var
image_list
=
context
.
element
.
querySelectorAll
(
"
input[type='image']
"
),
submit_list
=
context
.
element
.
querySelectorAll
(
"
button[type='submit']
"
),
i
,
promise_list
=
[];
promise_list
.
push
(
promiseEventListener
(
context
.
element
,
"
submit
"
,
false
));
for
(
i
=
0
;
i
<
image_list
.
length
;
i
+=
1
)
{
promise_list
.
push
(
promiseEventListener
(
image_list
[
i
],
"
click
"
,
false
));
}
for
(
i
=
0
;
i
<
submit_list
.
length
;
i
+=
1
)
{
promise_list
.
push
(
promiseEventListener
(
submit_list
[
i
],
"
click
"
,
false
));
}
return
RSVP
.
any
(
promise_list
);
})
.
push
(
function
(
evt
)
{
var
input
,
hidden_button
,
target
;
list
=
[];
target
,
i
,
promise_list
=
[];
if
(
evt
.
type
===
"
click
"
)
{
input
=
document
.
createElement
(
"
input
"
);
input
.
setAttribute
(
"
type
"
,
"
hidden
"
);
...
...
@@ -171,34 +196,34 @@
input
.
setAttribute
(
"
name
"
,
target
.
getAttribute
(
"
name
"
));
form
.
appendChild
(
input
);
}
else
{
hidden_button
=
g
.
props
.
element
.
querySelector
(
"
.hidden_button
"
);
hidden_button
=
context
.
element
.
querySelector
(
"
.hidden_button
"
);
hidden_button
.
setAttribute
(
"
type
"
,
"
hidden
"
);
}
for
(
i
=
0
;
i
<
all_gadge
t
.
length
;
i
+=
1
)
{
if
(
all_gadge
t
[
i
].
getContent
!==
undefined
&&
gadget_attributes
[
i
].
editable
!==
null
)
{
list
.
push
(
all_gadget
[
i
].
getContent
(
));
for
(
i
=
0
;
i
<
context
.
state
.
gadget_lis
t
.
length
;
i
+=
1
)
{
if
(
context
.
state
.
gadget_lis
t
[
i
].
getContent
!==
undefined
&&
context
.
state
.
field_list
[
i
].
editable
!==
null
)
{
promise_list
.
push
(
getGadgetContent
(
context
.
state
.
gadget_list
[
i
]
));
}
}
return
RSVP
.
all
(
list
);
return
RSVP
.
all
(
promise_
list
);
})
.
push
(
function
(
all_conten
t
)
{
.
push
(
function
(
content_lis
t
)
{
var
input
,
i
,
name
;
for
(
i
=
0
;
i
<
all_conten
t
.
length
;
i
+=
1
)
{
for
(
name
in
all_conten
t
[
i
])
{
if
(
all_conten
t
[
i
].
hasOwnProperty
(
name
))
{
for
(
i
=
0
;
i
<
content_lis
t
.
length
;
i
+=
1
)
{
for
(
name
in
content_lis
t
[
i
])
{
if
(
content_lis
t
[
i
].
hasOwnProperty
(
name
))
{
input
=
document
.
createElement
(
"
input
"
);
input
.
setAttribute
(
"
type
"
,
"
hidden
"
);
input
.
setAttribute
(
"
name
"
,
name
);
input
.
setAttribute
(
"
value
"
,
all_conten
t
[
i
][
name
]);
input
.
setAttribute
(
"
value
"
,
content_lis
t
[
i
][
name
]);
form
.
appendChild
(
input
);
}
}
}
})
.
push
(
function
()
{
form
.
submit
();
return
form
.
submit
();
});
});
}(
window
,
document
,
rJS
,
RSVP
));
\ No newline at end of file
}(
window
,
rJS
,
RSVP
,
document
,
console
));
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment