Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
ecommerce-ui
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
ecommerce-ui
Commits
5c1e4b25
Commit
5c1e4b25
authored
Dec 17, 2013
by
Sven Franck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
stabilized authentication, updating expiry per validated JIO command
parent
bff47a45
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
422 additions
and
221 deletions
+422
-221
js/erp5_loader.js
js/erp5_loader.js
+422
-221
No files found.
js/erp5_loader.js
View file @
5c1e4b25
...
...
@@ -179,7 +179,7 @@
* @param {object} obj Action Object
**/
"
logout_user
"
:
function
(
obj
)
{
var
temp_store
=
app
.
default_dict
.
state_dict
.
preserve_in
;
var
provider
,
temp_store
=
app
.
default_dict
.
state_dict
.
preserve_in
;
hello
(
obj
.
id
).
logout
(
function
(
x
){
return
;
...
...
@@ -187,7 +187,11 @@
// update flux
if
(
flux
&&
flux
.
state
)
{
delete
flux
.
state
[
obj
.
id
.
slice
(
0
,
2
)];
if
(
flux
.
state
[
obj
.
id
.
slice
(
0
,
2
)])
{
delete
flux
.
stat
[
obj
.
id
.
slice
(
0
,
2
)]
}
else
{
delete
flux
.
state
[
"
self
"
];
}
}
// update preserve
...
...
@@ -214,8 +218,6 @@
factory
.
util
.
convertDict
(
undefined
,
"
login
"
,
true
),
obj
.
element
);
// TODO: Shoudl we also remove the user from storage?
},
/**
...
...
@@ -224,14 +226,12 @@
* @param {object} obj Action Object
**/
"
login_user
"
:
function
(
obj
)
{
var
signature
,
match_string
,
reply
,
element
,
provider
,
temp_store
,
links
,
login
,
i
,
query
,
user
,
token
;
var
signature
,
match_string
,
reply
,
element
;
// create signature and ticket
element
=
obj
.
element
;
signature
=
util
.
generateRandomIdentifier
(
36
);
flux
[
signature
]
=
util
.
generateUuid
();
temp_store
=
app
.
default_dict
.
state_dict
.
preserve_in
;
// pass to 3rd party
hello
.
settings
.
state
=
signature
;
...
...
@@ -248,52 +248,16 @@
// valid roundtrip
if
(
flux
[
match_string
])
{
if
(
flux
.
state
===
undefined
)
{
flux
.
state
=
{};
}
provider
=
response
.
network
.
slice
(
0
,
2
);
// store in flux
flux
.
state
[
provider
]
=
response
.
authResponse
.
access_token
;
// catch errors
try
{
// store in preserve
if
(
temp_store
)
{
switch
(
temp_store
)
{
case
"
sessionStorage
"
:
window
.
sessionStorage
.
setItem
(
"
state
"
,
JSON
.
stringify
(
flux
.
state
));
break
;
// WARNING: you should not!
case
"
localStorage
"
:
window
.
localStorage
.
setItem
(
"
state
"
,
JSON
.
stringify
(
flux
.
state
));
break
;
// WARNING: you really should NOT!!!
case
"
cookie
"
:
util
.
cookieHandler
.
setItem
(
"
state
"
,
JSON
.
stringify
(
flux
.
state
));
break
;
};
}
// clear token and set flux
delete
flux
[
match_string
];
// update flux
app
.
setLoginStatus
(
response
,
undefined
);
}
catch
(
e
)
{
util
.
errorHandler
(
e
);
}
}
// update/replace button
// TODO: don't access it like this!!!
links
=
util
.
getHeader
().
getElementsByTagName
(
"
A
"
);
for
(
i
=
0
;
i
<
links
.
length
;
i
+=
1
)
{
if
(
links
[
i
].
getAttribute
(
"
data-depend
"
)
===
"
login_state
"
)
{
login
=
links
[
i
];
login
.
parentNode
.
replaceChild
(
factory
.
util
.
convertDict
(
undefined
,
"
logoff
"
,
true
),
login
);
}
}
}
// since we are jquerying, close (all) popups
...
...
@@ -751,12 +715,10 @@
* @returns {object} config Configuration object to pass to factory
**/
"
mapFormField
"
:
function
(
spec
,
overrides
,
passed_value
)
{
var
validation_list
,
class_list
,
element
,
type
,
prevail
,
clear
,
var
validation_list
,
class_list
,
element
,
type
,
prevail
,
clear
,
config
,
error_log
;
// build config object
config
=
{};
// set empty overrides if none are passed
...
...
@@ -787,6 +749,7 @@
// required
if
(
prevail
.
properties
.
required
||
spec
.
properties
.
required
)
{
class_list
+=
"
required
"
;
error_log
=
true
;
}
// maximum_length
...
...
@@ -1341,7 +1304,14 @@
target
=
document
.
createDocumentFragment
();
if
(
answer
.
data
.
total_rows
===
0
)
{
// no auth
if
(
answer
===
null
)
{
target
.
appendChild
(
app
.
noItemsFound
(
"
auth
"
));
return
target
;
}
if
((
answer
.
data
&&
answer
.
data
.
total_rows
===
0
)
||
(
answer
.
data
===
undefined
&&
answer
.
request_new
===
undefined
))
{
target
.
appendChild
(
app
.
noItemsFound
());
}
else
{
for
(
i
=
0
;
i
<
spec
.
children
.
length
;
i
+=
1
)
{
...
...
@@ -1349,13 +1319,13 @@
// new
if
(
element
.
type
===
"
form
"
)
{
if
(
answer
&&
answer
.
data
)
{
if
(
answer
.
data
.
total_rows
>
1
)
{
if
(
answer
&&
(
answer
.
data
||
answer
.
request_new
))
{
if
(
answer
.
request_new
||
answer
.
data
.
total_rows
===
0
)
{
element
.
data
=
{};
}
else
if
(
answer
.
data
.
total_rows
>
1
)
{
util
.
errorHandler
({
"
error
"
:
"
Fieldlist: More than 1 record
"
});
}
else
if
(
answer
.
data
.
total_rows
===
0
)
{
element
.
data
=
{};
}
else
{
element
.
data
=
answer
.
data
.
rows
[
0
].
doc
;
}
...
...
@@ -1367,7 +1337,6 @@
target
.
appendChild
(
app
.
setContent
(
element
));
}
}
return
target
;
}
};
...
...
@@ -1603,7 +1572,6 @@
* @param {object} spec configuration of gadget
* @return {object} form object of fragment
*/
// TODO: the gadget should not be wrapped by the form - only the form should
factory
.
util
.
wrapInForm
=
function
(
spec
)
{
if
(
spec
.
form
)
{
return
factory
.
element
(
...
...
@@ -1614,7 +1582,8 @@
"
id
"
:
spec
.
id
,
"
className
"
:
(
spec
.
class_list
||
""
)
},
{
"
data-ajax
"
:
false
}
{
"
data-ajax
"
:
false
,
"
autocomplete
"
:
"
off
"
},
{
"
data-set
"
:
spec
.
update
||
null
}
);
}
return
document
.
createDocumentFragment
();
...
...
@@ -2050,13 +2019,19 @@
* @return controlgroup
*/
// TODO: crap to use both layout and children!
// TODO: the submit button should have a data-reference to the login gadget
// which will not be in the DOM, so it can update after success. Until then
// data-reference will be like helloJS "google", only use "self"
// NOTE: securing ? http://nedbatchelder.com/text/stopbots.html
factory
.
form
=
function
(
spec
)
{
var
i
,
j
,
k
,
layout
,
element
,
container
,
area
,
field
,
overrides
,
position
,
doc
,
config
,
value
,
stamp
,
sauce
,
encode
,
secure
,
safety_box
,
noscript
,
fragment
,
wrap
;
safety_box
,
noscript
,
fragment
,
wrap
,
update
;
secure
=
spec
.
property_dict
.
secure
;
if
(
spec
.
property_dict
.
update
)
{
spec
.
update
=
spec
.
property_dict
.
update
;
}
fragment
=
factory
.
util
.
wrapInForm
(
spec
);
wrap
=
function
(
area
,
captcha
)
{
var
keys
=
{};
...
...
@@ -3246,10 +3221,13 @@
// helper
addLabel
=
function
(
config
,
label_class_list
)
{
var
star
=
util
.
testForString
(
"
equire
"
,
config
.
direct
.
className
,
true
);
return
factory
.
element
(
"
label
"
,
{
"
className
"
:
label_class_list
+
"
translate
"
+
(
star
?
"
required_label
"
:
"
"
)
+
((
label
===
undefined
||
config
.
logic
.
text
===
""
)
?
"
ui-hidden-accessible
"
:
""
)
},
...
...
@@ -3362,6 +3340,10 @@
config
.
attributes
[
"
data-type
"
]
=
"
search
"
;
text
=
"
search
"
;
}
// disable IOS auto functionality
config
.
attributes
.
autocapitalize
=
"
off
"
;
config
.
attributes
.
autocorrect
=
"
off
"
;
// update class_list
container_class_list
=
"
ui-input-
"
+
text
+
"
ui-body-inherit
"
;
}
break
;
...
...
@@ -3670,20 +3652,14 @@
// TODO: generate common promise handler for add/remove/clone/export/etc
// TODO: make form validation and captcha generic
storage
.
add
=
function
(
config
)
{
var
property
,
replace
,
i
,
obj
,
value
,
form_elements
,
form_element
,
pass
=
false
,
test_full
,
test_empty
,
test_time
,
form_to_submit
=
document
.
getElementById
(
config
.
id
),
anti_spam
=
document
.
getElementById
(
form_to_submit
.
id
+
"
_not_a_secret
"
),
formData
=
new
FormData
(),
var
property
,
replace
,
i
,
obj
,
value
,
form_elements
,
form_element
,
pass
,
test_full
,
test_empty
,
test_time
,
form_to_submit
,
anti_spam
,
formData
,
valid
;
pass
=
false
form_to_submit
=
document
.
getElementById
(
config
.
id
);
anti_spam
=
document
.
getElementById
(
form_to_submit
.
id
+
"
_not_a_secret
"
);
formData
=
new
FormData
();
valid
=
$
(
form_to_submit
).
triggerHandler
(
"
submitForm
"
);
if
(
valid
!==
false
)
{
...
...
@@ -3711,9 +3687,6 @@
}
}
// NOTE: secret is passed along with timestamp, so varying the secret
// along with the timestamp will prevent playback bots
// can we pass
if
(
test_empty
&&
test_full
&&
test_time
)
{
pass
=
true
;
...
...
@@ -3739,25 +3712,26 @@
}
}
// create ERP5 event
// TODO: remove once normal access is possible
util
.
updateStatus
(
"
show
"
,
""
,
"
global_dict.status_dict.uploading
"
);
util
.
ajax
({
"
url
"
:
"
https://nexedi.erp5.net/
"
+
"
ERP5Site_addApplicationSubmissionRequest
"
,
"
type
"
:
"
POST
"
,
"
data
"
:
formData
util
.
updateStatus
(
"
show
"
,
""
,
"
global_dict.status_dict.saving
"
);
// TODO: a post should always include all required fields
// TODO: find a way to set default fields, like timestamp etc
app
.
postDataToStorage
({
"
response
"
:
[
obj
],
"
pass
"
:
{
"
type
"
:
config
.
gadget
.
state
.
type
,
"
reply
"
:
true
}
})
// .then(function () {
// // TODO: a post should always include all required fields
// // TODO: find a way to set default fields, like timestamp etc
// return app.postDataToStorage({
// "response": [obj],
// "pass": {"type": config.portal_type_source}
// })
// })
.
then
(
function
()
{
$
.
mobile
.
changePage
(
"
#thanks
"
);
.
then
(
function
(
answer
)
{
// TODO: This is not the correct place to run all status updates!
if
(
answer
.
response
.
result
===
"
success
"
)
{
switch
(
config
.
gadget
.
getAttribute
(
"
data-set
"
))
{
case
"
login_state
"
:
app
.
setLoginStatus
(
answer
.
response
,
config
.
portal_type_source
);
break
;
}
util
.
updateStatus
(
"
show
"
,
""
,
"
global_dict.status_dict.saved
"
,
"
check
"
);
}
})
.
fail
(
util
.
errorHandler
);
}
...
...
@@ -4162,12 +4136,68 @@
};
/**
* return a placeholder with b
ack b
utton in case no items were found
* return a placeholder with button in case no items were found
* @method noItemsFound
* @param {string} type Type of placeholder to create
* @return {object} HTML fragment
*/
app
.
noItemsFound
=
function
()
{
var
reply
=
factory
.
element
(
// TODO: don't get global popup like this!!!!!!
// TODO: make this element fit to whoever calls (tr, li, div...)
app
.
noItemsFound
=
function
(
type
)
{
var
reply
,
content
,
message
,
message_i18n
;
// TODO: find less content-heavy way!
switch
(
type
)
{
case
"
auth
"
:
message
=
"
Requires authorization.
"
;
message_i18n
=
"
validation_dict.requires_auth
"
;
content
=
{
"
generate
"
:
"
widget
"
,
"
type
"
:
"
controlgroup
"
,
"
property_dict
"
:
{
"
direction
"
:
"
horizontal
"
},
"
children
"
:
[{
"
type
"
:
"
a
"
,
"
direct
"
:{
"
className
"
:
"
translate action
"
,
"
href
"
:
"
#global-popup
"
},
"
attributes
"
:{
"
data-i18n
"
:
"
global_dict.common_dict.login
"
,
"
data-action
"
:
"
login
"
,
"
data-icon
"
:
"
lock
"
,
"
data-rel
"
:
"
popup
"
},
"
logic
"
:
{
"
text
"
:
"
Login
"
}
},
{
"
type
"
:
"
a
"
,
"
direct
"
:
{
"
className
"
:
"
translate
"
,
"
href
"
:
"
#person::new
"
},
"
attributes
"
:
{
"
data-i18n
"
:
"
global_dict.common_dict.register
"
,
"
data-icon
"
:
"
edit
"
},
"
logic
"
:
{
"
text
"
:
"
Register
"
}
}
]
};
break
;
default
:
message
=
"
No items found.
"
;
message_i18n
=
"
validation_dict.no_items_found
"
;
content
=
{
"
type
"
:
"
a
"
,
"
direct
"
:
{
"
href
"
:
"
#
"
,
"
className
"
:
"
ui-corner-all ui-btn ui-shadow ui-btn-inline
"
+
"
ui-icon-chevron-sign-left ui-btn-icon-left translate
"
},
"
attributes
"
:
{
"
data-rel
"
:
"
back
"
,
"
data-i18n
"
:
"
global_dict.pagination_dict.back
"
},
"
logic
"
:
{
"
Text
"
:
"
Back
"
}
}
break
;
};
// <p> is not flexible...
reply
=
factory
.
element
(
"
p
"
,
{
"
className
"
:
"
responsive ui-content-element
"
}
);
...
...
@@ -4175,32 +4205,88 @@
reply
.
appendChild
(
factory
.
element
(
"
span
"
,
{
"
className
"
:
"
translate
"
},
{
"
data-i18n
"
:
"
validation_dict.no_items_found
"
},
{
"
text
"
:
"
No items found
"
}
));
reply
.
appendChild
(
factory
.
element
(
"
a
"
,
{
"
className
"
:
"
ui-corner-all ui-btn ui-shadow ui-btn-inline
"
+
"
ui-icon-chevron-sign-left ui-btn-icon-left translate
"
},
{
"
data-i18n
"
:
"
global_dict.pagination_dict.back
"
,
"
data-rel
"
:
"
back
"
},
{
"
text
"
:
"
Back
"
}
{
"
data-i18n
"
:
message_i18n
},
{
"
text
"
:
message
}
));
reply
.
appendChild
(
app
.
setContent
(
content
));
return
reply
;
};
/**
* Update login status
* @method updateLoginStatus
* @param {object} response Object initiating the status update
* @param {string} portal_type Portal Type concerned
**/
app
.
setLoginStatus
=
function
(
response
,
portal_type
)
{
var
temp_store
,
stamp
,
provider
,
auth
,
links
,
i
,
login
;
temp_store
=
app
.
default_dict
.
state_dict
.
preserve_in
;
stamp
=
Date
.
now
();
provider
=
response
.
network
?
response
.
network
.
slice
(
0
,
2
)
:
"
self
"
;
auth
=
response
.
authResponse
;
if
(
flux
.
state
===
undefined
)
{
flux
.
state
=
{};
}
// store in flux
flux
.
state
[
provider
]
=
{
"
token
"
:
auth
?
auth
.
access_token
:
response
.
id
,
"
issued
"
:
stamp
,
"
expires
"
:
auth
?
auth
.
expires_in
:
3600
}
// if specified store in preserve
if
(
temp_store
)
{
switch
(
temp_store
)
{
case
"
sessionStorage
"
:
window
.
sessionStorage
.
setItem
(
"
state
"
,
JSON
.
stringify
(
flux
.
state
));
break
;
// WARNING: you should not!
case
"
localStorage
"
:
window
.
localStorage
.
setItem
(
"
state
"
,
JSON
.
stringify
(
flux
.
state
));
break
;
// WARNING: you really should NOT!!!
case
"
cookie
"
:
util
.
cookieHandler
.
setItem
(
"
state
"
,
JSON
.
stringify
(
flux
.
state
));
break
;
};
}
// need to update the .... button
// TODO: make a login gadget, store dependend buttons in state
links
=
util
.
getHeader
().
getElementsByTagName
(
"
A
"
);
for
(
i
=
0
;
i
<
links
.
length
;
i
+=
1
)
{
if
(
links
[
i
].
getAttribute
(
"
data-depend
"
)
===
"
login_state
"
)
{
login
=
links
[
i
];
login
.
parentNode
.
replaceChild
(
factory
.
util
.
convertDict
(
undefined
,
"
logoff
"
,
true
),
login
);
}
}
};
/**
* Check if a login status is still valid
* @method checkLoginStatus
* @param {boolean} skip Return out
* @param {object} pass Passed information to be returned
* @return {boolean} true/false
**/
// TODO: make this work with a regular login, too!!!
app
.
checkLoginStatus
=
function
(
skip
)
{
var
state
,
temp_store
,
lookup
,
logger
,
provider
,
verify
,
url
,
influx
,
info
;
app
.
checkLoginStatus
=
function
(
skip
,
pass
)
{
var
state
,
temp_store
,
lookup
,
logger
,
provider
,
verify
,
url
,
influx
,
info
,
valid
,
auth_config
,
stamp
,
expires
,
expired
,
token
;
if
(
skip
===
undefined
)
{
// TODO: name collusion! make normal pass object!
return
RSVP
.
resolve
({
"
pass
"
:
skip
});
}
else
{
logger
=
app
.
default_dict
.
state_dict
.
login_pointer
;
...
...
@@ -4234,12 +4320,40 @@
if
(
state
)
{
for
(
provider
in
state
)
{
if
(
state
.
hasOwnProperty
(
provider
))
{
auth_config
=
state
[
provider
];
stamp
=
Date
.
now
();
// assemble url
switch
(
provider
)
{
case
"
go
"
:
url
=
verify
.
google
+
state
.
go
;
break
;
case
"
go
"
:
url
=
verify
.
google
+
auth_config
.
token
;
break
;
case
"
self
"
:
url
=
undefined
;
break
;
}
// test for timeout
if
(
auth_config
.
issued
&&
auth_config
.
expires
)
{
expires
=
auth_config
.
issued
+
auth_config
.
expires
;
if
(
expires
<
stamp
)
{
valid
=
true
;
}
else
{
expired
=
true
;
delete
state
[
provider
];
}
}
}
}
}
// token in memory still valid, add it to the pass object
if
(
valid
)
{
if
(
pass
)
{
pass
.
active_login
=
true
;
pass
.
token
=
auth_config
.
token
;
pass
.
expires_in
=
expires
;
return
RSVP
.
resolve
(
pass
);
}
return
RSVP
.
resolve
({
"
expires_in
"
:
expires
});
}
// if we have a url, we have an access token, check if it's valid
if
(
url
)
{
...
...
@@ -4255,7 +4369,11 @@
throw
util
.
parseIfNeeded
(
event
.
target
);
});
}
return
RSVP
.
resolve
({
"
error
"
:
"
no state found
"
});
if
(
pass
)
{
pass
.
active_login
=
false
;
return
RSVP
.
resolve
(
pass
);
}
return
RSVP
.
resolve
({
"
error
"
:
"
no state found/not logged in
"
});
}
else
{
util
.
errorHandler
({
"
error
"
:
"
loginStatus: Missing login handler.
"
});
}
...
...
@@ -4388,45 +4506,6 @@
}
};
/**
* parse a link into query-able parameters
* @method parseLink
* @param {string} url Url to go to
* @return {object} pointer object
*/
// TODO: renderJS should parse a link
app
.
parseLink
=
function
(
url
)
{
var
i
,
query
,
parameter
,
path
=
$
.
mobile
.
path
.
parseUrl
(
url
.
replace
(
$
.
mobile
.
dialogHashKey
,
""
)),
clean_hash
=
path
.
hash
.
replace
(
"
#
"
,
""
),
config
=
{
"
url
"
:
url
};
if
(
clean_hash
===
""
)
{
config
.
id
=
config
.
layout_identifier
=
util
.
getActivePage
();
}
else
{
// do we have a mode?
query
=
clean_hash
.
split
(
"
?
"
);
for
(
i
=
0
;
i
<
query
.
length
;
i
+=
1
)
{
parameter
=
query
[
i
].
split
(
"
=
"
);
if
(
parameter
.
length
===
2
&&
parameter
[
0
]
===
"
mode
"
)
{
config
.
mode
=
parameter
[
1
];
}
}
config
.
fragment_list
=
clean_hash
.
split
(
"
::
"
);
config
.
id
=
clean_hash
;
config
.
layout_level
=
config
.
fragment_list
.
length
-
1
;
config
.
deeplink
=
true
;
config
.
layout_identifier
=
clean_hash
.
split
(
"
::
"
)[
0
];
}
return
config
;
};
/**
* Action handler, routing actions to specified method
* @method action
...
...
@@ -4573,13 +4652,58 @@
return
obj
;
};
/**
* parse a link into query-able parameters
* @method parseLink
* @param {string} url Url to go to
* @return {object} pointer object
*/
// TODO: renderJS should parse a link
app
.
generateLinkObject
=
function
(
url
)
{
var
i
,
query
,
parameter
,
path
,
clean_hash
,
config
;
parameter
=
0
;
path
=
$
.
mobile
.
path
.
parseUrl
(
url
.
replace
(
$
.
mobile
.
dialogHashKey
,
""
)),
clean_hash
=
path
.
hash
.
replace
(
"
#
"
,
""
),
config
=
{
"
url
"
:
url
};
if
(
clean_hash
===
""
)
{
config
.
id
=
config
.
layout_identifier
=
util
.
getActivePage
();
}
else
{
// NOTE: as the hash will be set as page id by JQM, we cannot pass
// complex structures or query parameters to not produce invalid HTML
// check for mode(s)
query
=
clean_hash
.
split
(
"
::
"
);
for
(
i
=
0
;
i
<
query
.
length
;
i
+=
1
)
{
switch
(
query
[
i
])
{
case
"
new
"
:
// person::new = create a new entry for person
// NOTE: this will allow loading of field definitions in auth!
config
.
mode
=
"
new
"
;
parameter
=
1
;
break
;
};
}
config
.
fragment_list
=
clean_hash
.
split
(
"
::
"
);
config
.
id
=
clean_hash
;
config
.
layout_level
=
config
.
fragment_list
.
length
-
1
-
parameter
;
config
.
deeplink
=
true
;
config
.
layout_identifier
=
clean_hash
.
split
(
"
::
"
)[
0
];
}
return
config
;
};
/**
* Generate an action object (vs duplicate in every action call)
* @method generateActionObject
* @param {object} e Event triggering an action
* @return {object} action object
*/
// TODO: integrate in popup handler, make sure "pop" works!
// TODO: id ... is crap
// TODO: passing empty state is not good, refactor, when adding state
app
.
generateActionObject
=
function
(
e
)
{
...
...
@@ -4749,6 +4873,7 @@
"
pass
"
:
pass
})
.
then
(
app
.
parseConfiguration
)
.
then
(
app
.
loadFieldDefinition
)
// ===== SAMPLE DATA ========
.
then
(
app
.
testStorageForData
)
.
then
(
app
.
retrieveSampleData
)
...
...
@@ -4829,11 +4954,12 @@
* @return {object} response object/promise
*/
app
.
generateGadgetContent
=
function
(
reply
)
{
var
selector
,
element
,
translate
,
pass
=
reply
.
pass
,
var
selector
,
element
,
pass
,
constructor
,
translate
,
request_new
;
pass
=
reply
.
pass
;
constructor
=
map
.
gadgets
[
pass
.
constructor
];
// TODO: this always sets "new" urls to an empty result. Good?
request_new
=
pass
.
mode
===
"
new
"
?
{
"
request_new
"
:
true
}
:
null
;
if
(
constructor
===
undefined
)
{
util
.
errorHandler
(
...
...
@@ -4845,10 +4971,11 @@
if
(
pass
.
skip
)
{
return
constructor
(
pass
.
content_dict
,
pass
.
url_dict
);
}
else
{
// generate content
element
=
constructor
(
pass
.
config
,
(
reply
.
response
?
util
.
parseIfNeeded
(
reply
.
response
)
:
null
),
(
reply
.
response
?
util
.
parseIfNeeded
(
reply
.
response
)
:
request_new
),
pass
.
fields
,
(
pass
.
create
===
false
?
true
:
null
),
{
"
layout
"
:
(
pass
.
layout_level
||
0
),
"
fragment_list
"
:
pass
.
fragment_list
}
...
...
@@ -4857,15 +4984,21 @@
// translate
map
.
actions
.
translateNodeList
(
element
);
// not auth, no mojo!
if
(
pass
.
no_auth
||
(
pass
.
auth
&&
pass
.
active_login
||
pass
.
mode
===
"
new
"
))
{
if
(
pass
.
create
===
false
)
{
selector
=
pass
.
state
.
gadget
;
}
else
{
// NOTE: in case of update, element will be the section to update
// not the gadget/fragment, so we need to find the gadget
// NOTE: in case of forms, we find the form!
// NOTE: in case of fragments, we punt to the firstElementChild...
selector
=
element
.
querySelector
(
"
#
"
+
pass
.
id
)
||
document
.
getElementById
(
pass
.
config
.
form
)
||
element
;
(
element
.
tagName
===
undefined
?
element
.
firstElementChild
:
element
);
pass
.
state
.
gadget
=
selector
;
}
...
...
@@ -4881,6 +5014,7 @@
pass
.
state
.
query
,
pass
.
state
.
total
);
}
return
element
;
}
...
...
@@ -4895,7 +5029,8 @@
app
.
fetchDataQuery
=
function
(
reply
)
{
var
parsed
,
pass
=
reply
.
pass
;
if
(
pass
.
skip
===
undefined
)
{
if
(
pass
.
skip
===
undefined
&&
(
pass
.
no_auth
||
(
pass
.
auth
&&
pass
.
active_login
)))
{
// single item query
if
(
reply
.
response
)
{
...
...
@@ -4937,7 +5072,9 @@
app
.
fetchDataTotal
=
function
(
reply
)
{
var
pass
=
reply
.
pass
;
if
(
pass
.
skip
===
undefined
)
{
if
(
pass
.
skip
===
undefined
&&
(
pass
.
no_auth
||
(
pass
.
auth
&&
pass
.
active_login
||
pass
.
mode
===
"
new
"
)))
{
// create or update state object
if
(
pass
.
create
===
false
)
{
...
...
@@ -4947,6 +5084,7 @@
pass
.
state
.
query
.
limit
=
[];
}
else
{
pass
.
state
=
{};
pass
.
state
.
type
=
pass
.
type
;
pass
.
state
.
method
=
pass
.
constructor
;
pass
.
state
.
fragment_list
=
pass
.
fragment_list
;
...
...
@@ -4969,7 +5107,6 @@
// skip total for single item layouts!
if
(
pass
.
config
.
initial_query
)
{
// make sure limit is reset from any sample loading [0,1]
pass
.
state
.
query
.
limit
=
[];
...
...
@@ -4995,7 +5132,9 @@
* @return {object} promise object/pass
*/
app
.
postDataToStorage
=
function
(
reply
)
{
var
i
,
obj
,
key
,
promises
,
record
,
items
,
store
,
pass
;
var
i
,
obj
,
key
,
promises
,
record
,
items
,
store
,
pass
,
send_status
,
method
;
pass
=
reply
.
pass
;
if
(
reply
.
response
)
{
...
...
@@ -5017,13 +5156,25 @@
}
// add portal type
obj
.
portal_type
=
pass
.
type
;
// post to JIO with generated id
promises
[
i
]
=
store
.
post
(
obj
);
// make sure to overwrite existing files, so try to fetch...
// TODO: is there no easier way to check whether to put/post
console
.
log
(
obj
)
console
.
log
(
flux
)
console
.
log
(
pass
)
promises
[
i
]
=
store
.
post
(
obj
)
.
then
(
function
(
answer
)
{
return
answer
;
});
}
return
RSVP
.
all
(
promises
)
.
then
(
function
()
{
.
then
(
function
(
response
)
{
// for single item actions, allow to return a status message
if
(
response
.
length
===
1
&&
reply
.
pass
.
reply
)
{
send_status
=
response
[
0
];
}
return
{
"
response
"
:
undefined
,
"
response
"
:
send_status
,
"
pass
"
:
pass
};
})
...
...
@@ -5063,7 +5214,9 @@
.
fail
(
util
.
errorHandler
);
}
}
return
{
"
pass
"
:
pass
};
return
{
"
pass
"
:
pass
};
};
/**
...
...
@@ -5081,7 +5234,9 @@
}
// try to get 1 record
if
(
pass
.
create
!==
false
&&
pass
.
config
.
initial_query
)
{
if
(
pass
.
create
!==
false
&&
pass
.
config
.
initial_query
&&
(
pass
.
no_auth
||
(
pass
.
auth
&&
pass
.
active_login
)))
{
return
app
.
fetchData
({
"
storage
"
:
"
items
"
,
"
query
"
:
app
.
generateQueryObject
({
"
limit
"
:
[
0
,
1
]},
pass
.
type
),
...
...
@@ -5094,6 +5249,42 @@
};
};
// ======================== SAMPLE DATA ==================================
/**
* Load field definitions if necessary
* @method loadFieldDefinition
* @param {object} pass through
* @return {object} field defintions and pass through
*/
app
.
loadFieldDefinition
=
function
(
reply
)
{
var
pass
=
reply
.
pass
;
// active login?
if
(
pass
.
auth
)
{
if
(
pass
.
active_login
)
{
pass
.
grant
=
true
;
}
}
else
{
pass
.
no_auth
=
true
;
}
// fetch field definitions
if
(
pass
.
skip
===
undefined
&&
(
pass
.
no_auth
||
(
pass
.
auth
&&
pass
.
active_login
||
pass
.
mode
===
"
new
"
))
&&
pass
.
create
!==
false
&&
pass
.
config
.
portal_type_fields
)
{
return
app
.
fetchConfiguration
({
"
storage
"
:
app
.
default_dict
.
storage_dict
.
settings
,
"
file
"
:
app
.
default_dict
.
storage_dict
.
data_type
,
"
attachment
"
:
pass
.
config
.
portal_type_fields
,
"
pass
"
:
pass
});
}
return
{
"
pass
"
:
pass
};
};
/**
* parses a gadget configuration file
* @method parseConfiguration
...
...
@@ -5107,21 +5298,26 @@
parsed
=
util
.
parseIfNeeded
(
reply
.
response
);
pass
.
config
=
parsed
;
pass
.
type
=
parsed
.
portal_type_source
;
// if app uses login and gadget requires auth
if
(
app
.
default_dict
.
state_dict
.
login
&&
parsed
.
property_dict
.
requires_authentication
)
{
pass
.
auth
=
parsed
.
property_dict
.
requires_authentication
;
}
}
if
(
pass
.
skip
===
undefined
&&
pass
.
create
!==
false
&&
pass
.
config
.
portal_type_fields
)
{
return
app
.
fetchConfiguration
(
{
"
storage
"
:
app
.
default_dict
.
storage_dict
.
settings
,
"
file
"
:
app
.
default_dict
.
storage_dict
.
data_type
,
"
attachment
"
:
pass
.
config
.
portal_type_fields
,
"
pass
"
:
pass
}
);
// test for authentication
if
(
pass
.
auth
)
{
return
app
.
checkLoginStatus
(
true
,
pass
)
.
then
(
function
(
new_pass
)
{
return
{
"
pass
"
:
new_pass
}
})
.
fail
(
util
.
errorHandler
);
}
return
{
"
pass
"
:
pass
}
;
}
};
/**
...
...
@@ -5291,7 +5487,7 @@
}
if
(
typeof
raw_url
===
"
string
"
)
{
config
=
app
.
parseLink
(
raw_url
);
config
=
app
.
generateLinkObject
(
raw_url
);
if
(
e
)
{
page
=
document
.
getElementById
(
raw_url
.
split
(
"
#
"
).
pop
());
...
...
@@ -5300,16 +5496,16 @@
if
(
first
||
(
page
&&
base
)
||
raw_url
===
$
.
mobile
.
getDocumentUrl
()
||
data
.
options
.
role
===
"
popup
"
)
{
//
console.log("STOP us, JQM go")
console
.
log
(
"
STOP us, JQM go
"
)
return
;
}
if
((
document
.
getElementById
(
config
.
id
)
&&
base
!==
null
))
{
e
.
preventDefault
();
//
console.log("STOP us, STOP JQM")
console
.
log
(
"
STOP us, STOP JQM
"
)
return
;
}
handle
=
true
;
//
console.log("GO us, STOP JQM")
console
.
log
(
"
GO us, STOP JQM
"
)
e
.
preventDefault
();
}
else
{
...
...
@@ -5334,7 +5530,6 @@
if
(
config
.
deeplink
)
{
create
=
true
;
}
// prevent browser loading hash?query.json
if
(
config
.
layout_identifier
.
split
(
"
?
"
).
length
>
1
)
{
destination
=
config
.
layout_identifier
.
split
(
"
?
"
)[
0
];
...
...
@@ -5362,12 +5557,15 @@
*/
//TODO: merge with pagebindings, so all jQuery is at one place!
app
.
setGlobalBindings
=
function
()
{
console
.
log
(
"
SETTING BINDING
"
)
$
(
document
)
.
enhanceWithin
()
// generate dynamic pages
.
on
(
"
pagebeforechange
"
,
function
(
e
,
data
)
{
console
.
log
(
"
PBC
"
)
console
.
log
(
e
)
console
.
log
(
data
)
app
.
parsePage
(
e
,
data
);
})
...
...
@@ -5403,7 +5601,7 @@
default
:
val
=
element
.
value
;
last
=
element
.
getAttribute
(
"
data-last
"
);
if
((
last
&&
last
===
val
)
&&
type
!==
"
S
ubmit
"
)
{
if
((
last
&&
last
===
val
)
&&
type
!==
"
s
ubmit
"
)
{
return
;
}
util
.
clearTimer
();
...
...
@@ -5752,9 +5950,10 @@
* @param {boolean} show Whether to show or hide the loader
* @param {string} message The message to display in the loader
* @param {string} msg_i18n lookup for status message
* @param {string} theme background theme
* @param {string} icon Which icon to display when overriding the loader
*/
util
.
updateStatus
=
function
(
show
,
message
,
msg_i18n
,
icon
)
{
util
.
updateStatus
=
function
(
show
,
message
,
msg_i18n
,
icon
,
theme
)
{
var
text_to_display
=
i18n
&&
msg_i18n
?
map
.
actions
.
translateLookup
(
msg_i18n
)
:
message
;
...
...
@@ -5768,17 +5967,16 @@
"
textVisible
"
:
true
,
"
theme
"
:
app
.
default_dict
.
loader_theme
,
"
html
"
:
"
<span class='ui-icon-
"
+
(
icon
?
(
icon
+
"
load
ing
_icon
"
)
:
"
loading
"
)
+
"
'> </span>
"
+
(
icon
?
(
icon
+
"
load
er
_icon
"
)
:
"
loading
"
)
+
"
'> </span>
"
+
"
<h1 class='loader_message'>
"
+
text_to_display
+
"
</h1>
"
}
);
// allow multiple updates and remove after 1000ms
util
.
clearTimer
();
app
.
timer
=
window
.
setTimeout
(
function
()
{
$
.
mobile
.
loading
(
"
hide
"
);
},
500
);
},
2
500
);
}
else
{
util
.
errorHandler
({
"
error
"
:
"
showStatus: Loader not enabled
"
});
}
...
...
@@ -6045,9 +6243,12 @@
**/
app
.
contentLoaded
(
window
,
function
()
{
// TODO: don't dump, sync...
// Don't wipe if opened in a popup (like in oAuth redirect_uri)
if
(
window
.
opener
===
null
)
{
// TODO: don't wipe, sync...
window
.
localStorage
.
clear
();
window
.
sessionStorage
.
clear
();
}
app
.
getFromDisk
({
"
url
"
:
util
.
getPathFromScriptTag
(
"
data-storage
"
),
...
...
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