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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Laurent S
erp5
Commits
fb0fdae3
Commit
fb0fdae3
authored
Mar 20, 2017
by
Vincent Bechu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_dms: delete rsvp and renderjs from pdf viewer files
parent
c7ce159a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
0 additions
and
3107 deletions
+0
-3107
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/renderjs.js.js
...nTemplateItem/portal_skins/erp5_dms/pdf_js/renderjs.js.js
+0
-2050
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/renderjs.js.xml
...TemplateItem/portal_skins/erp5_dms/pdf_js/renderjs.js.xml
+0
-28
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/rsvp.js.js
.../SkinTemplateItem/portal_skins/erp5_dms/pdf_js/rsvp.js.js
+0
-1001
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/rsvp.js.xml
...SkinTemplateItem/portal_skins/erp5_dms/pdf_js/rsvp.js.xml
+0
-28
No files found.
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/renderjs.js.js
deleted
100644 → 0
View file @
c7ce159a
/*
* js_channel is a very lightweight abstraction on top of
* postMessage which defines message formats and semantics
* to support interactions more rich than just message passing
* js_channel supports:
* + query/response - traditional rpc
* + query/update/response - incremental async return of results
* to a query
* + notifications - fire and forget
* + error handling
*
* js_channel is based heavily on json-rpc, but is focused at the
* problem of inter-iframe RPC.
*
* Message types:
* There are 5 types of messages that can flow over this channel,
* and you may determine what type of message an object is by
* examining its parameters:
* 1. Requests
* + integer id
* + string method
* + (optional) any params
* 2. Callback Invocations (or just "Callbacks")
* + integer id
* + string callback
* + (optional) params
* 3. Error Responses (or just "Errors)
* + integer id
* + string error
* + (optional) string message
* 4. Responses
* + integer id
* + (optional) any result
* 5. Notifications
* + string method
* + (optional) any params
*/
;
var
Channel
=
(
function
()
{
"
use strict
"
;
// current transaction id, start out at a random *odd* number between 1 and a million
// There is one current transaction counter id per page, and it's shared between
// channel instances. That means of all messages posted from a single javascript
// evaluation context, we'll never have two with the same id.
var
s_curTranId
=
Math
.
floor
(
Math
.
random
()
*
1000001
);
// no two bound channels in the same javascript evaluation context may have the same origin, scope, and window.
// futher if two bound channels have the same window and scope, they may not have *overlapping* origins
// (either one or both support '*'). This restriction allows a single onMessage handler to efficiently
// route messages based on origin and scope. The s_boundChans maps origins to scopes, to message
// handlers. Request and Notification messages are routed using this table.
// Finally, channels are inserted into this table when built, and removed when destroyed.
var
s_boundChans
=
{
};
// add a channel to s_boundChans, throwing if a dup exists
function
s_addBoundChan
(
win
,
origin
,
scope
,
handler
)
{
function
hasWin
(
arr
)
{
for
(
var
i
=
0
;
i
<
arr
.
length
;
i
++
)
if
(
arr
[
i
].
win
===
win
)
return
true
;
return
false
;
}
// does she exist?
var
exists
=
false
;
if
(
origin
===
'
*
'
)
{
// we must check all other origins, sadly.
for
(
var
k
in
s_boundChans
)
{
if
(
!
s_boundChans
.
hasOwnProperty
(
k
))
continue
;
if
(
k
===
'
*
'
)
continue
;
if
(
typeof
s_boundChans
[
k
][
scope
]
===
'
object
'
)
{
exists
=
hasWin
(
s_boundChans
[
k
][
scope
]);
if
(
exists
)
break
;
}
}
}
else
{
// we must check only '*'
if
((
s_boundChans
[
'
*
'
]
&&
s_boundChans
[
'
*
'
][
scope
]))
{
exists
=
hasWin
(
s_boundChans
[
'
*
'
][
scope
]);
}
if
(
!
exists
&&
s_boundChans
[
origin
]
&&
s_boundChans
[
origin
][
scope
])
{
exists
=
hasWin
(
s_boundChans
[
origin
][
scope
]);
}
}
if
(
exists
)
throw
"
A channel is already bound to the same window which overlaps with origin '
"
+
origin
+
"
' and has scope '
"
+
scope
+
"
'
"
;
if
(
typeof
s_boundChans
[
origin
]
!=
'
object
'
)
s_boundChans
[
origin
]
=
{
};
if
(
typeof
s_boundChans
[
origin
][
scope
]
!=
'
object
'
)
s_boundChans
[
origin
][
scope
]
=
[
];
s_boundChans
[
origin
][
scope
].
push
({
win
:
win
,
handler
:
handler
});
}
function
s_removeBoundChan
(
win
,
origin
,
scope
)
{
var
arr
=
s_boundChans
[
origin
][
scope
];
for
(
var
i
=
0
;
i
<
arr
.
length
;
i
++
)
{
if
(
arr
[
i
].
win
===
win
)
{
arr
.
splice
(
i
,
1
);
}
}
if
(
s_boundChans
[
origin
][
scope
].
length
===
0
)
{
delete
s_boundChans
[
origin
][
scope
];
}
}
function
s_isArray
(
obj
)
{
if
(
Array
.
isArray
)
return
Array
.
isArray
(
obj
);
else
{
return
(
obj
.
constructor
.
toString
().
indexOf
(
"
Array
"
)
!=
-
1
);
}
}
// No two outstanding outbound messages may have the same id, period. Given that, a single table
// mapping "transaction ids" to message handlers, allows efficient routing of Callback, Error, and
// Response messages. Entries are added to this table when requests are sent, and removed when
// responses are received.
var
s_transIds
=
{
};
// class singleton onMessage handler
// this function is registered once and all incoming messages route through here. This
// arrangement allows certain efficiencies, message data is only parsed once and dispatch
// is more efficient, especially for large numbers of simultaneous channels.
var
s_onMessage
=
function
(
e
)
{
try
{
var
m
=
JSON
.
parse
(
e
.
data
);
if
(
typeof
m
!==
'
object
'
||
m
===
null
)
throw
"
malformed
"
;
}
catch
(
e
)
{
// just ignore any posted messages that do not consist of valid JSON
return
;
}
var
w
=
e
.
source
;
var
o
=
e
.
origin
;
var
s
,
i
,
meth
;
if
(
typeof
m
.
method
===
'
string
'
)
{
var
ar
=
m
.
method
.
split
(
'
::
'
);
if
(
ar
.
length
==
2
)
{
s
=
ar
[
0
];
meth
=
ar
[
1
];
}
else
{
meth
=
m
.
method
;
}
}
if
(
typeof
m
.
id
!==
'
undefined
'
)
i
=
m
.
id
;
// w is message source window
// o is message origin
// m is parsed message
// s is message scope
// i is message id (or undefined)
// meth is unscoped method name
// ^^ based on these factors we can route the message
// if it has a method it's either a notification or a request,
// route using s_boundChans
if
(
typeof
meth
===
'
string
'
)
{
var
delivered
=
false
;
if
(
s_boundChans
[
o
]
&&
s_boundChans
[
o
][
s
])
{
for
(
var
j
=
0
;
j
<
s_boundChans
[
o
][
s
].
length
;
j
++
)
{
if
(
s_boundChans
[
o
][
s
][
j
].
win
===
w
)
{
s_boundChans
[
o
][
s
][
j
].
handler
(
o
,
meth
,
m
);
delivered
=
true
;
break
;
}
}
}
if
(
!
delivered
&&
s_boundChans
[
'
*
'
]
&&
s_boundChans
[
'
*
'
][
s
])
{
for
(
var
j
=
0
;
j
<
s_boundChans
[
'
*
'
][
s
].
length
;
j
++
)
{
if
(
s_boundChans
[
'
*
'
][
s
][
j
].
win
===
w
)
{
s_boundChans
[
'
*
'
][
s
][
j
].
handler
(
o
,
meth
,
m
);
break
;
}
}
}
}
// otherwise it must have an id (or be poorly formed
else
if
(
typeof
i
!=
'
undefined
'
)
{
if
(
s_transIds
[
i
])
s_transIds
[
i
](
o
,
meth
,
m
);
}
};
// Setup postMessage event listeners
if
(
window
.
addEventListener
)
window
.
addEventListener
(
'
message
'
,
s_onMessage
,
false
);
else
if
(
window
.
attachEvent
)
window
.
attachEvent
(
'
onmessage
'
,
s_onMessage
);
/* a messaging channel is constructed from a window and an origin.
* the channel will assert that all messages received over the
* channel match the origin
*
* Arguments to Channel.build(cfg):
*
* cfg.window - the remote window with which we'll communicate
* cfg.origin - the expected origin of the remote window, may be '*'
* which matches any origin
* cfg.scope - the 'scope' of messages. a scope string that is
* prepended to message names. local and remote endpoints
* of a single channel must agree upon scope. Scope may
* not contain double colons ('::').
* cfg.debugOutput - A boolean value. If true and window.console.log is
* a function, then debug strings will be emitted to that
* function.
* cfg.debugOutput - A boolean value. If true and window.console.log is
* a function, then debug strings will be emitted to that
* function.
* cfg.postMessageObserver - A function that will be passed two arguments,
* an origin and a message. It will be passed these immediately
* before messages are posted.
* cfg.gotMessageObserver - A function that will be passed two arguments,
* an origin and a message. It will be passed these arguments
* immediately after they pass scope and origin checks, but before
* they are processed.
* cfg.onReady - A function that will be invoked when a channel becomes "ready",
* this occurs once both sides of the channel have been
* instantiated and an application level handshake is exchanged.
* the onReady function will be passed a single argument which is
* the channel object that was returned from build().
*/
return
{
build
:
function
(
cfg
)
{
var
debug
=
function
(
m
)
{
if
(
cfg
.
debugOutput
&&
window
.
console
&&
window
.
console
.
log
)
{
// try to stringify, if it doesn't work we'll let javascript's built in toString do its magic
try
{
if
(
typeof
m
!==
'
string
'
)
m
=
JSON
.
stringify
(
m
);
}
catch
(
e
)
{
}
console
.
log
(
"
[
"
+
chanId
+
"
]
"
+
m
);
}
};
/* browser capabilities check */
if
(
!
window
.
postMessage
)
throw
(
"
jschannel cannot run this browser, no postMessage
"
);
if
(
!
window
.
JSON
||
!
window
.
JSON
.
stringify
||
!
window
.
JSON
.
parse
)
{
throw
(
"
jschannel cannot run this browser, no JSON parsing/serialization
"
);
}
/* basic argument validation */
if
(
typeof
cfg
!=
'
object
'
)
throw
(
"
Channel build invoked without a proper object argument
"
);
if
(
!
cfg
.
window
||
!
cfg
.
window
.
postMessage
)
throw
(
"
Channel.build() called without a valid window argument
"
);
/* we'd have to do a little more work to be able to run multiple channels that intercommunicate the same
* window... Not sure if we care to support that */
if
(
window
===
cfg
.
window
)
throw
(
"
target window is same as present window -- not allowed
"
);
// let's require that the client specify an origin. if we just assume '*' we'll be
// propagating unsafe practices. that would be lame.
var
validOrigin
=
false
;
if
(
typeof
cfg
.
origin
===
'
string
'
)
{
var
oMatch
;
if
(
cfg
.
origin
===
"
*
"
)
validOrigin
=
true
;
// allow valid domains under http and https. Also, trim paths off otherwise valid origins.
else
if
(
null
!==
(
oMatch
=
cfg
.
origin
.
match
(
/^https
?
:
\/\/(?:[
-a-zA-Z0-9_
\.])
+
(?:
:
\d
+
)?
/
)))
{
cfg
.
origin
=
oMatch
[
0
].
toLowerCase
();
validOrigin
=
true
;
}
}
if
(
!
validOrigin
)
throw
(
"
Channel.build() called with an invalid origin
"
);
if
(
typeof
cfg
.
scope
!==
'
undefined
'
)
{
if
(
typeof
cfg
.
scope
!==
'
string
'
)
throw
'
scope, when specified, must be a string
'
;
if
(
cfg
.
scope
.
split
(
'
::
'
).
length
>
1
)
throw
"
scope may not contain double colons: '::'
"
;
}
/* private variables */
// generate a random and psuedo unique id for this channel
var
chanId
=
(
function
()
{
var
text
=
""
;
var
alpha
=
"
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
"
;
for
(
var
i
=
0
;
i
<
5
;
i
++
)
text
+=
alpha
.
charAt
(
Math
.
floor
(
Math
.
random
()
*
alpha
.
length
));
return
text
;
})();
// registrations: mapping method names to call objects
var
regTbl
=
{
};
// current oustanding sent requests
var
outTbl
=
{
};
// current oustanding received requests
var
inTbl
=
{
};
// are we ready yet? when false we will block outbound messages.
var
ready
=
false
;
var
pendingQueue
=
[
];
var
createTransaction
=
function
(
id
,
origin
,
callbacks
)
{
var
shouldDelayReturn
=
false
;
var
completed
=
false
;
return
{
origin
:
origin
,
invoke
:
function
(
cbName
,
v
)
{
// verify in table
if
(
!
inTbl
[
id
])
throw
"
attempting to invoke a callback of a nonexistent transaction:
"
+
id
;
// verify that the callback name is valid
var
valid
=
false
;
for
(
var
i
=
0
;
i
<
callbacks
.
length
;
i
++
)
if
(
cbName
===
callbacks
[
i
])
{
valid
=
true
;
break
;
}
if
(
!
valid
)
throw
"
request supports no such callback '
"
+
cbName
+
"
'
"
;
// send callback invocation
postMessage
({
id
:
id
,
callback
:
cbName
,
params
:
v
});
},
error
:
function
(
error
,
message
)
{
completed
=
true
;
// verify in table
if
(
!
inTbl
[
id
])
throw
"
error called for nonexistent message:
"
+
id
;
// remove transaction from table
delete
inTbl
[
id
];
// send error
postMessage
({
id
:
id
,
error
:
error
,
message
:
message
});
},
complete
:
function
(
v
)
{
completed
=
true
;
// verify in table
if
(
!
inTbl
[
id
])
throw
"
complete called for nonexistent message:
"
+
id
;
// remove transaction from table
delete
inTbl
[
id
];
// send complete
postMessage
({
id
:
id
,
result
:
v
});
},
delayReturn
:
function
(
delay
)
{
if
(
typeof
delay
===
'
boolean
'
)
{
shouldDelayReturn
=
(
delay
===
true
);
}
return
shouldDelayReturn
;
},
completed
:
function
()
{
return
completed
;
}
};
};
var
setTransactionTimeout
=
function
(
transId
,
timeout
,
method
)
{
return
window
.
setTimeout
(
function
()
{
if
(
outTbl
[
transId
])
{
// XXX: what if client code raises an exception here?
var
msg
=
"
timeout (
"
+
timeout
+
"
ms) exceeded on method '
"
+
method
+
"
'
"
;
(
1
,
outTbl
[
transId
].
error
)(
"
timeout_error
"
,
msg
);
delete
outTbl
[
transId
];
delete
s_transIds
[
transId
];
}
},
timeout
);
};
var
onMessage
=
function
(
origin
,
method
,
m
)
{
// if an observer was specified at allocation time, invoke it
if
(
typeof
cfg
.
gotMessageObserver
===
'
function
'
)
{
// pass observer a clone of the object so that our
// manipulations are not visible (i.e. method unscoping).
// This is not particularly efficient, but then we expect
// that message observers are primarily for debugging anyway.
try
{
cfg
.
gotMessageObserver
(
origin
,
m
);
}
catch
(
e
)
{
debug
(
"
gotMessageObserver() raised an exception:
"
+
e
.
toString
());
}
}
// now, what type of message is this?
if
(
m
.
id
&&
method
)
{
// a request! do we have a registered handler for this request?
if
(
regTbl
[
method
])
{
var
trans
=
createTransaction
(
m
.
id
,
origin
,
m
.
callbacks
?
m
.
callbacks
:
[
]);
inTbl
[
m
.
id
]
=
{
};
try
{
// callback handling. we'll magically create functions inside the parameter list for each
// callback
if
(
m
.
callbacks
&&
s_isArray
(
m
.
callbacks
)
&&
m
.
callbacks
.
length
>
0
)
{
for
(
var
i
=
0
;
i
<
m
.
callbacks
.
length
;
i
++
)
{
var
path
=
m
.
callbacks
[
i
];
var
obj
=
m
.
params
;
var
pathItems
=
path
.
split
(
'
/
'
);
for
(
var
j
=
0
;
j
<
pathItems
.
length
-
1
;
j
++
)
{
var
cp
=
pathItems
[
j
];
if
(
typeof
obj
[
cp
]
!==
'
object
'
)
obj
[
cp
]
=
{
};
obj
=
obj
[
cp
];
}
obj
[
pathItems
[
pathItems
.
length
-
1
]]
=
(
function
()
{
var
cbName
=
path
;
return
function
(
params
)
{
return
trans
.
invoke
(
cbName
,
params
);
};
})();
}
}
var
resp
=
regTbl
[
method
](
trans
,
m
.
params
);
if
(
!
trans
.
delayReturn
()
&&
!
trans
.
completed
())
trans
.
complete
(
resp
);
}
catch
(
e
)
{
// automagic handling of exceptions:
var
error
=
"
runtime_error
"
;
var
message
=
null
;
// * if it's a string then it gets an error code of 'runtime_error' and string is the message
if
(
typeof
e
===
'
string
'
)
{
message
=
e
;
}
else
if
(
typeof
e
===
'
object
'
)
{
// either an array or an object
// * if it's an array of length two, then array[0] is the code, array[1] is the error message
if
(
e
&&
s_isArray
(
e
)
&&
e
.
length
==
2
)
{
error
=
e
[
0
];
message
=
e
[
1
];
}
// * if it's an object then we'll look form error and message parameters
else
if
(
typeof
e
.
error
===
'
string
'
)
{
error
=
e
.
error
;
if
(
!
e
.
message
)
message
=
""
;
else
if
(
typeof
e
.
message
===
'
string
'
)
message
=
e
.
message
;
else
e
=
e
.
message
;
// let the stringify/toString message give us a reasonable verbose error string
}
}
// message is *still* null, let's try harder
if
(
message
===
null
)
{
try
{
message
=
JSON
.
stringify
(
e
);
/* On MSIE8, this can result in 'out of memory', which
* leaves message undefined. */
if
(
typeof
(
message
)
==
'
undefined
'
)
message
=
e
.
toString
();
}
catch
(
e2
)
{
message
=
e
.
toString
();
}
}
trans
.
error
(
error
,
message
);
}
}
}
else
if
(
m
.
id
&&
m
.
callback
)
{
if
(
!
outTbl
[
m
.
id
]
||!
outTbl
[
m
.
id
].
callbacks
||
!
outTbl
[
m
.
id
].
callbacks
[
m
.
callback
])
{
debug
(
"
ignoring invalid callback, id:
"
+
m
.
id
+
"
(
"
+
m
.
callback
+
"
)
"
);
}
else
{
// XXX: what if client code raises an exception here?
outTbl
[
m
.
id
].
callbacks
[
m
.
callback
](
m
.
params
);
}
}
else
if
(
m
.
id
)
{
if
(
!
outTbl
[
m
.
id
])
{
debug
(
"
ignoring invalid response:
"
+
m
.
id
);
}
else
{
// XXX: what if client code raises an exception here?
if
(
m
.
error
)
{
(
1
,
outTbl
[
m
.
id
].
error
)(
m
.
error
,
m
.
message
);
}
else
{
if
(
m
.
result
!==
undefined
)
(
1
,
outTbl
[
m
.
id
].
success
)(
m
.
result
);
else
(
1
,
outTbl
[
m
.
id
].
success
)();
}
delete
outTbl
[
m
.
id
];
delete
s_transIds
[
m
.
id
];
}
}
else
if
(
method
)
{
// tis a notification.
if
(
regTbl
[
method
])
{
// yep, there's a handler for that.
// transaction has only origin for notifications.
regTbl
[
method
]({
origin
:
origin
},
m
.
params
);
// if the client throws, we'll just let it bubble out
// what can we do? Also, here we'll ignore return values
}
}
};
// now register our bound channel for msg routing
s_addBoundChan
(
cfg
.
window
,
cfg
.
origin
,
((
typeof
cfg
.
scope
===
'
string
'
)
?
cfg
.
scope
:
''
),
onMessage
);
// scope method names based on cfg.scope specified when the Channel was instantiated
var
scopeMethod
=
function
(
m
)
{
if
(
typeof
cfg
.
scope
===
'
string
'
&&
cfg
.
scope
.
length
)
m
=
[
cfg
.
scope
,
m
].
join
(
"
::
"
);
return
m
;
};
// a small wrapper around postmessage whose primary function is to handle the
// case that clients start sending messages before the other end is "ready"
var
postMessage
=
function
(
msg
,
force
)
{
if
(
!
msg
)
throw
"
postMessage called with null message
"
;
// delay posting if we're not ready yet.
var
verb
=
(
ready
?
"
post
"
:
"
queue
"
);
debug
(
verb
+
"
message:
"
+
JSON
.
stringify
(
msg
));
if
(
!
force
&&
!
ready
)
{
pendingQueue
.
push
(
msg
);
}
else
{
if
(
typeof
cfg
.
postMessageObserver
===
'
function
'
)
{
try
{
cfg
.
postMessageObserver
(
cfg
.
origin
,
msg
);
}
catch
(
e
)
{
debug
(
"
postMessageObserver() raised an exception:
"
+
e
.
toString
());
}
}
cfg
.
window
.
postMessage
(
JSON
.
stringify
(
msg
),
cfg
.
origin
);
}
};
var
onReady
=
function
(
trans
,
type
)
{
debug
(
'
ready msg received
'
);
if
(
ready
)
throw
"
received ready message while in ready state. help!
"
;
if
(
type
===
'
ping
'
)
{
chanId
+=
'
-R
'
;
}
else
{
chanId
+=
'
-L
'
;
}
obj
.
unbind
(
'
__ready
'
);
// now this handler isn't needed any more.
ready
=
true
;
debug
(
'
ready msg accepted.
'
);
if
(
type
===
'
ping
'
)
{
obj
.
notify
({
method
:
'
__ready
'
,
params
:
'
pong
'
});
}
// flush queue
while
(
pendingQueue
.
length
)
{
postMessage
(
pendingQueue
.
pop
());
}
// invoke onReady observer if provided
if
(
typeof
cfg
.
onReady
===
'
function
'
)
cfg
.
onReady
(
obj
);
};
var
obj
=
{
// tries to unbind a bound message handler. returns false if not possible
unbind
:
function
(
method
)
{
if
(
regTbl
[
method
])
{
if
(
!
(
delete
regTbl
[
method
]))
throw
(
"
can't delete method:
"
+
method
);
return
true
;
}
return
false
;
},
bind
:
function
(
method
,
cb
)
{
if
(
!
method
||
typeof
method
!==
'
string
'
)
throw
"
'method' argument to bind must be string
"
;
if
(
!
cb
||
typeof
cb
!==
'
function
'
)
throw
"
callback missing from bind params
"
;
if
(
regTbl
[
method
])
throw
"
method '
"
+
method
+
"
' is already bound!
"
;
regTbl
[
method
]
=
cb
;
return
this
;
},
call
:
function
(
m
)
{
if
(
!
m
)
throw
'
missing arguments to call function
'
;
if
(
!
m
.
method
||
typeof
m
.
method
!==
'
string
'
)
throw
"
'method' argument to call must be string
"
;
if
(
!
m
.
success
||
typeof
m
.
success
!==
'
function
'
)
throw
"
'success' callback missing from call
"
;
// now it's time to support the 'callback' feature of jschannel. We'll traverse the argument
// object and pick out all of the functions that were passed as arguments.
var
callbacks
=
{
};
var
callbackNames
=
[
];
var
pruneFunctions
=
function
(
path
,
obj
)
{
if
(
typeof
obj
===
'
object
'
)
{
for
(
var
k
in
obj
)
{
if
(
!
obj
.
hasOwnProperty
(
k
))
continue
;
var
np
=
path
+
(
path
.
length
?
'
/
'
:
''
)
+
k
;
if
(
typeof
obj
[
k
]
===
'
function
'
)
{
callbacks
[
np
]
=
obj
[
k
];
callbackNames
.
push
(
np
);
delete
obj
[
k
];
}
else
if
(
typeof
obj
[
k
]
===
'
object
'
)
{
pruneFunctions
(
np
,
obj
[
k
]);
}
}
}
};
pruneFunctions
(
""
,
m
.
params
);
// build a 'request' message and send it
var
msg
=
{
id
:
s_curTranId
,
method
:
scopeMethod
(
m
.
method
),
params
:
m
.
params
};
if
(
callbackNames
.
length
)
msg
.
callbacks
=
callbackNames
;
if
(
m
.
timeout
)
// XXX: This function returns a timeout ID, but we don't do anything with it.
// We might want to keep track of it so we can cancel it using clearTimeout()
// when the transaction completes.
setTransactionTimeout
(
s_curTranId
,
m
.
timeout
,
scopeMethod
(
m
.
method
));
// insert into the transaction table
outTbl
[
s_curTranId
]
=
{
callbacks
:
callbacks
,
error
:
m
.
error
,
success
:
m
.
success
};
s_transIds
[
s_curTranId
]
=
onMessage
;
// increment current id
s_curTranId
++
;
postMessage
(
msg
);
},
notify
:
function
(
m
)
{
if
(
!
m
)
throw
'
missing arguments to notify function
'
;
if
(
!
m
.
method
||
typeof
m
.
method
!==
'
string
'
)
throw
"
'method' argument to notify must be string
"
;
// no need to go into any transaction table
postMessage
({
method
:
scopeMethod
(
m
.
method
),
params
:
m
.
params
});
},
destroy
:
function
()
{
s_removeBoundChan
(
cfg
.
window
,
cfg
.
origin
,
((
typeof
cfg
.
scope
===
'
string
'
)
?
cfg
.
scope
:
''
));
if
(
window
.
removeEventListener
)
window
.
removeEventListener
(
'
message
'
,
onMessage
,
false
);
else
if
(
window
.
detachEvent
)
window
.
detachEvent
(
'
onmessage
'
,
onMessage
);
ready
=
false
;
regTbl
=
{
};
inTbl
=
{
};
outTbl
=
{
};
cfg
.
origin
=
null
;
pendingQueue
=
[
];
debug
(
"
channel destroyed
"
);
chanId
=
""
;
}
};
obj
.
bind
(
'
__ready
'
,
onReady
);
setTimeout
(
function
()
{
postMessage
({
method
:
scopeMethod
(
'
__ready
'
),
params
:
"
ping
"
},
true
);
},
0
);
return
obj
;
}
};
})();
;
/*
* DOMParser HTML extension
* 2012-09-04
*
* By Eli Grey, http://eligrey.com
* Public domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
/*! @source https://gist.github.com/1129031 */
(
function
(
DOMParser
)
{
"
use strict
"
;
var
DOMParser_proto
=
DOMParser
.
prototype
,
real_parseFromString
=
DOMParser_proto
.
parseFromString
;
// Firefox/Opera/IE throw errors on unsupported types
try
{
// WebKit returns null on unsupported types
if
((
new
DOMParser
()).
parseFromString
(
""
,
"
text/html
"
))
{
// text/html parsing is natively supported
return
;
}
}
catch
(
ignore
)
{}
DOMParser_proto
.
parseFromString
=
function
(
markup
,
type
)
{
var
result
,
doc
,
doc_elt
,
first_elt
;
if
(
/^
\s
*text
\/
html
\s
*
(?:
;|$
)
/i
.
test
(
type
))
{
doc
=
document
.
implementation
.
createHTMLDocument
(
""
);
doc_elt
=
doc
.
documentElement
;
doc_elt
.
innerHTML
=
markup
;
first_elt
=
doc_elt
.
firstElementChild
;
if
(
doc_elt
.
childElementCount
===
1
&&
first_elt
.
localName
.
toLowerCase
()
===
"
html
"
)
{
doc
.
replaceChild
(
first_elt
,
doc_elt
);
}
result
=
doc
;
}
else
{
result
=
real_parseFromString
.
apply
(
this
,
arguments
);
}
return
result
;
};
}(
DOMParser
));
;
// IE does not support have Document.prototype.contains.
if
(
typeof
document
.
contains
!==
'
function
'
)
{
Document
.
prototype
.
contains
=
function
(
node
)
{
if
(
node
===
this
||
node
.
parentNode
===
this
)
return
true
;
return
this
.
documentElement
.
contains
(
node
);
}
}
;
/*! RenderJs */
/*jslint nomen: true*/
/*
* renderJs - Generic Gadget library renderer.
* http://www.renderjs.org/documentation
*/
(
function
(
document
,
window
,
RSVP
,
DOMParser
,
Channel
,
MutationObserver
,
Node
,
FileReader
,
Blob
)
{
"
use strict
"
;
function
readBlobAsDataURL
(
blob
)
{
var
fr
=
new
FileReader
();
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
fr
.
addEventListener
(
"
load
"
,
function
(
evt
)
{
resolve
(
evt
.
target
.
result
);
});
fr
.
addEventListener
(
"
error
"
,
reject
);
fr
.
readAsDataURL
(
blob
);
},
function
()
{
fr
.
abort
();
});
}
function
ajax
(
url
)
{
var
xhr
;
function
resolver
(
resolve
,
reject
)
{
function
handler
()
{
try
{
if
(
xhr
.
readyState
===
0
)
{
// UNSENT
reject
(
xhr
);
}
else
if
(
xhr
.
readyState
===
4
)
{
// DONE
if
((
xhr
.
status
<
200
)
||
(
xhr
.
status
>=
300
)
||
(
!
/^text
\/
html
[
;
]?
/
.
test
(
xhr
.
getResponseHeader
(
"
Content-Type
"
)
||
""
)))
{
reject
(
xhr
);
}
else
{
resolve
(
xhr
);
}
}
}
catch
(
e
)
{
reject
(
e
);
}
}
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
"
GET
"
,
url
);
xhr
.
onreadystatechange
=
handler
;
xhr
.
setRequestHeader
(
'
Accept
'
,
'
text/html
'
);
xhr
.
withCredentials
=
true
;
xhr
.
send
();
}
function
canceller
()
{
if
((
xhr
!==
undefined
)
&&
(
xhr
.
readyState
!==
xhr
.
DONE
))
{
xhr
.
abort
();
}
}
return
new
RSVP
.
Promise
(
resolver
,
canceller
);
}
var
gadget_model_dict
=
{},
javascript_registration_dict
=
{},
stylesheet_registration_dict
=
{},
gadget_loading_klass
,
loading_klass_promise
,
renderJS
,
Monitor
,
scope_increment
=
0
,
isAbsoluteOrDataURL
=
new
RegExp
(
'
^(?:[a-z]+:)?//|data:
'
,
'
i
'
);
/////////////////////////////////////////////////////////////////
// Helper functions
/////////////////////////////////////////////////////////////////
function
removeHash
(
url
)
{
var
index
=
url
.
indexOf
(
'
#
'
);
if
(
index
>
0
)
{
url
=
url
.
substring
(
0
,
index
);
}
return
url
;
}
function
letsCrash
(
e
)
{
if
(
e
.
constructor
===
XMLHttpRequest
)
{
e
=
{
readyState
:
e
.
readyState
,
status
:
e
.
status
,
statusText
:
e
.
statusText
,
response_headers
:
e
.
getAllResponseHeaders
()
};
}
if
(
e
.
constructor
===
Array
||
e
.
constructor
===
String
||
e
.
constructor
===
Object
)
{
try
{
e
=
JSON
.
stringify
(
e
);
}
catch
(
ignore
)
{
}
}
document
.
getElementsByTagName
(
'
body
'
)[
0
].
textContent
=
e
;
// XXX Do not crash the application if it fails
// Where to write the error?
/*global console*/
console
.
error
(
e
.
stack
);
console
.
error
(
e
);
}
/////////////////////////////////////////////////////////////////
// Service Monitor promise
/////////////////////////////////////////////////////////////////
function
ResolvedMonitorError
(
message
)
{
this
.
name
=
"
resolved
"
;
if
((
message
!==
undefined
)
&&
(
typeof
message
!==
"
string
"
))
{
throw
new
TypeError
(
'
You must pass a string.
'
);
}
this
.
message
=
message
||
"
Default Message
"
;
}
ResolvedMonitorError
.
prototype
=
new
Error
();
ResolvedMonitorError
.
prototype
.
constructor
=
ResolvedMonitorError
;
Monitor
=
function
()
{
var
monitor
=
this
,
promise_list
=
[],
promise
,
reject
,
notify
,
resolved
;
if
(
!
(
this
instanceof
Monitor
))
{
return
new
Monitor
();
}
function
canceller
()
{
var
len
=
promise_list
.
length
,
i
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
promise_list
[
i
].
cancel
();
}
// Clean it to speed up other canceller run
promise_list
=
[];
}
promise
=
new
RSVP
.
Promise
(
function
(
done
,
fail
,
progress
)
{
reject
=
function
(
rejectedReason
)
{
if
(
resolved
)
{
return
;
}
monitor
.
isRejected
=
true
;
monitor
.
rejectedReason
=
rejectedReason
;
resolved
=
true
;
canceller
();
return
fail
(
rejectedReason
);
};
notify
=
progress
;
},
canceller
);
monitor
.
cancel
=
function
()
{
if
(
resolved
)
{
return
;
}
resolved
=
true
;
promise
.
cancel
();
promise
.
fail
(
function
(
rejectedReason
)
{
monitor
.
isRejected
=
true
;
monitor
.
rejectedReason
=
rejectedReason
;
});
};
monitor
.
then
=
function
()
{
return
promise
.
then
.
apply
(
promise
,
arguments
);
};
monitor
.
fail
=
function
()
{
return
promise
.
fail
.
apply
(
promise
,
arguments
);
};
monitor
.
monitor
=
function
(
promise_to_monitor
)
{
if
(
resolved
)
{
throw
new
ResolvedMonitorError
();
}
var
queue
=
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
promise_to_monitor
;
})
.
push
(
function
(
fulfillmentValue
)
{
// Promise to monitor is fullfilled, remove it from the list
var
len
=
promise_list
.
length
,
sub_promise_to_monitor
,
new_promise_list
=
[],
i
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
sub_promise_to_monitor
=
promise_list
[
i
];
if
(
!
(
sub_promise_to_monitor
.
isFulfilled
||
sub_promise_to_monitor
.
isRejected
))
{
new_promise_list
.
push
(
sub_promise_to_monitor
);
}
}
promise_list
=
new_promise_list
;
},
function
(
rejectedReason
)
{
if
(
rejectedReason
instanceof
RSVP
.
CancellationError
)
{
if
(
!
(
promise_to_monitor
.
isFulfilled
&&
promise_to_monitor
.
isRejected
))
{
// The queue could be cancelled before the first push is run
promise_to_monitor
.
cancel
();
}
}
reject
(
rejectedReason
);
throw
rejectedReason
;
},
function
(
notificationValue
)
{
notify
(
notificationValue
);
return
notificationValue
;
});
promise_list
.
push
(
queue
);
return
this
;
};
};
Monitor
.
prototype
=
Object
.
create
(
RSVP
.
Promise
.
prototype
);
Monitor
.
prototype
.
constructor
=
Monitor
;
/////////////////////////////////////////////////////////////////
// RenderJSGadget
/////////////////////////////////////////////////////////////////
function
RenderJSGadget
()
{
if
(
!
(
this
instanceof
RenderJSGadget
))
{
return
new
RenderJSGadget
();
}
}
RenderJSGadget
.
prototype
.
__title
=
""
;
RenderJSGadget
.
prototype
.
__interface_list
=
[];
RenderJSGadget
.
prototype
.
__path
=
""
;
RenderJSGadget
.
prototype
.
__html
=
""
;
RenderJSGadget
.
prototype
.
__required_css_list
=
[];
RenderJSGadget
.
prototype
.
__required_js_list
=
[];
function
createMonitor
(
g
)
{
if
(
g
.
__monitor
!==
undefined
)
{
g
.
__monitor
.
cancel
();
}
g
.
__monitor
=
new
Monitor
();
g
.
__monitor
.
fail
(
function
(
error
)
{
if
(
!
(
error
instanceof
RSVP
.
CancellationError
))
{
return
g
.
aq_reportServiceError
(
error
);
}
}).
fail
(
function
(
error
)
{
// Crash the application if the acquisition generates an error.
return
letsCrash
(
error
);
});
}
function
clearGadgetInternalParameters
(
g
)
{
g
.
__sub_gadget_dict
=
{};
createMonitor
(
g
);
}
function
loadSubGadgetDOMDeclaration
(
g
)
{
var
element_list
=
g
.
__element
.
querySelectorAll
(
'
[data-gadget-url]
'
),
element
,
promise_list
=
[],
scope
,
url
,
sandbox
,
i
;
for
(
i
=
0
;
i
<
element_list
.
length
;
i
+=
1
)
{
element
=
element_list
[
i
];
scope
=
element
.
getAttribute
(
"
data-gadget-scope
"
);
url
=
element
.
getAttribute
(
"
data-gadget-url
"
);
sandbox
=
element
.
getAttribute
(
"
data-gadget-sandbox
"
);
if
(
url
!==
null
)
{
promise_list
.
push
(
g
.
declareGadget
(
url
,
{
element
:
element
,
scope
:
scope
||
undefined
,
sandbox
:
sandbox
||
undefined
}));
}
}
return
RSVP
.
all
(
promise_list
);
}
RenderJSGadget
.
__ready_list
=
[
clearGadgetInternalParameters
,
loadSubGadgetDOMDeclaration
];
RenderJSGadget
.
ready
=
function
(
callback
)
{
this
.
__ready_list
.
push
(
callback
);
return
this
;
};
RenderJSGadget
.
__service_list
=
[];
RenderJSGadget
.
declareService
=
function
(
callback
)
{
this
.
__service_list
.
push
(
callback
);
return
this
;
};
function
startService
(
gadget
)
{
gadget
.
__monitor
.
monitor
(
new
RSVP
.
Queue
()
.
push
(
function
()
{
var
i
,
service_list
=
gadget
.
constructor
.
__service_list
;
for
(
i
=
0
;
i
<
service_list
.
length
;
i
+=
1
)
{
gadget
.
__monitor
.
monitor
(
service_list
[
i
].
apply
(
gadget
));
}
})
);
}
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareMethod
/////////////////////////////////////////////////////////////////
RenderJSGadget
.
declareMethod
=
function
(
name
,
callback
)
{
this
.
prototype
[
name
]
=
function
()
{
var
context
=
this
,
argument_list
=
arguments
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
callback
.
apply
(
context
,
argument_list
);
});
};
// Allow chain
return
this
;
};
RenderJSGadget
.
declareMethod
(
'
getInterfaceList
'
,
function
()
{
// Returns the list of gadget prototype
return
this
.
__interface_list
;
})
.
declareMethod
(
'
getRequiredCSSList
'
,
function
()
{
// Returns a list of CSS required by the gadget
return
this
.
__required_css_list
;
})
.
declareMethod
(
'
getRequiredJSList
'
,
function
()
{
// Returns a list of JS required by the gadget
return
this
.
__required_js_list
;
})
.
declareMethod
(
'
getPath
'
,
function
()
{
// Returns the path of the code of a gadget
return
this
.
__path
;
})
.
declareMethod
(
'
getTitle
'
,
function
()
{
// Returns the title of a gadget
return
this
.
__title
;
})
.
declareMethod
(
'
getElement
'
,
function
()
{
// Returns the DOM Element of a gadget
if
(
this
.
__element
===
undefined
)
{
throw
new
Error
(
"
No element defined
"
);
}
return
this
.
__element
;
});
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareAcquiredMethod
/////////////////////////////////////////////////////////////////
function
acquire
(
child_gadget
,
method_name
,
argument_list
)
{
var
gadget
=
this
,
key
,
gadget_scope
;
for
(
key
in
gadget
.
__sub_gadget_dict
)
{
if
(
gadget
.
__sub_gadget_dict
.
hasOwnProperty
(
key
))
{
if
(
gadget
.
__sub_gadget_dict
[
key
]
===
child_gadget
)
{
gadget_scope
=
key
;
}
}
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
// Do not specify default __acquired_method_dict on prototype
// to prevent modifying this default value (with
// allowPublicAcquiredMethod for example)
var
aq_dict
=
gadget
.
__acquired_method_dict
||
{};
if
(
aq_dict
.
hasOwnProperty
(
method_name
))
{
return
aq_dict
[
method_name
].
apply
(
gadget
,
[
argument_list
,
gadget_scope
]);
}
throw
new
renderJS
.
AcquisitionError
(
"
aq_dynamic is not defined
"
);
})
.
push
(
undefined
,
function
(
error
)
{
if
(
error
instanceof
renderJS
.
AcquisitionError
)
{
return
gadget
.
__aq_parent
(
method_name
,
argument_list
);
}
throw
error
;
});
}
RenderJSGadget
.
declareAcquiredMethod
=
function
(
name
,
method_name_to_acquire
)
{
this
.
prototype
[
name
]
=
function
()
{
var
argument_list
=
Array
.
prototype
.
slice
.
call
(
arguments
,
0
),
gadget
=
this
;
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
gadget
.
__aq_parent
(
method_name_to_acquire
,
argument_list
);
});
};
// Allow chain
return
this
;
};
RenderJSGadget
.
declareAcquiredMethod
(
"
aq_reportServiceError
"
,
"
reportServiceError
"
);
/////////////////////////////////////////////////////////////////
// RenderJSGadget.allowPublicAcquisition
/////////////////////////////////////////////////////////////////
RenderJSGadget
.
allowPublicAcquisition
=
function
(
method_name
,
callback
)
{
this
.
prototype
.
__acquired_method_dict
[
method_name
]
=
callback
;
// Allow chain
return
this
;
};
// Set aq_parent on gadget_instance which call acquire on parent_gadget
function
setAqParent
(
gadget_instance
,
parent_gadget
)
{
gadget_instance
.
__aq_parent
=
function
(
method_name
,
argument_list
)
{
return
acquire
.
apply
(
parent_gadget
,
[
gadget_instance
,
method_name
,
argument_list
]);
};
}
/////////////////////////////////////////////////////////////////
// RenderJSEmbeddedGadget
/////////////////////////////////////////////////////////////////
// Class inheritance
function
RenderJSEmbeddedGadget
()
{
if
(
!
(
this
instanceof
RenderJSEmbeddedGadget
))
{
return
new
RenderJSEmbeddedGadget
();
}
RenderJSGadget
.
call
(
this
);
}
RenderJSEmbeddedGadget
.
__ready_list
=
RenderJSGadget
.
__ready_list
.
slice
();
RenderJSEmbeddedGadget
.
__service_list
=
RenderJSGadget
.
__service_list
.
slice
();
RenderJSEmbeddedGadget
.
ready
=
RenderJSGadget
.
ready
;
RenderJSEmbeddedGadget
.
declareService
=
RenderJSGadget
.
declareService
;
RenderJSEmbeddedGadget
.
prototype
=
new
RenderJSGadget
();
RenderJSEmbeddedGadget
.
prototype
.
constructor
=
RenderJSEmbeddedGadget
;
/////////////////////////////////////////////////////////////////
// privateDeclarePublicGadget
/////////////////////////////////////////////////////////////////
function
privateDeclarePublicGadget
(
url
,
options
,
parent_gadget
)
{
var
gadget_instance
;
if
(
options
.
element
===
undefined
)
{
options
.
element
=
document
.
createElement
(
"
div
"
);
}
function
loadDependency
(
method
,
url
)
{
return
function
()
{
return
method
(
url
);
};
}
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
renderJS
.
declareGadgetKlass
(
url
);
})
// Get the gadget class and instanciate it
.
push
(
function
(
Klass
)
{
var
i
,
template_node_list
=
Klass
.
__template_element
.
body
.
childNodes
;
gadget_loading_klass
=
Klass
;
gadget_instance
=
new
Klass
();
gadget_instance
.
__element
=
options
.
element
;
for
(
i
=
0
;
i
<
template_node_list
.
length
;
i
+=
1
)
{
gadget_instance
.
__element
.
appendChild
(
template_node_list
[
i
].
cloneNode
(
true
)
);
}
setAqParent
(
gadget_instance
,
parent_gadget
);
// Load dependencies if needed
return
RSVP
.
all
([
gadget_instance
.
getRequiredJSList
(),
gadget_instance
.
getRequiredCSSList
()
]);
})
// Load all JS/CSS
.
push
(
function
(
all_list
)
{
var
q
=
new
RSVP
.
Queue
(),
i
;
// Load JS
for
(
i
=
0
;
i
<
all_list
[
0
].
length
;
i
+=
1
)
{
q
.
push
(
loadDependency
(
renderJS
.
declareJS
,
all_list
[
0
][
i
]));
}
// Load CSS
for
(
i
=
0
;
i
<
all_list
[
1
].
length
;
i
+=
1
)
{
q
.
push
(
loadDependency
(
renderJS
.
declareCSS
,
all_list
[
1
][
i
]));
}
return
q
;
})
.
push
(
function
()
{
return
gadget_instance
;
});
}
/////////////////////////////////////////////////////////////////
// RenderJSIframeGadget
/////////////////////////////////////////////////////////////////
function
RenderJSIframeGadget
()
{
if
(
!
(
this
instanceof
RenderJSIframeGadget
))
{
return
new
RenderJSIframeGadget
();
}
RenderJSGadget
.
call
(
this
);
}
RenderJSIframeGadget
.
__ready_list
=
RenderJSGadget
.
__ready_list
.
slice
();
RenderJSIframeGadget
.
ready
=
RenderJSGadget
.
ready
;
RenderJSIframeGadget
.
__service_list
=
RenderJSGadget
.
__service_list
.
slice
();
RenderJSIframeGadget
.
declareService
=
RenderJSGadget
.
declareService
;
RenderJSIframeGadget
.
prototype
=
new
RenderJSGadget
();
RenderJSIframeGadget
.
prototype
.
constructor
=
RenderJSIframeGadget
;
/////////////////////////////////////////////////////////////////
// privateDeclareIframeGadget
/////////////////////////////////////////////////////////////////
function
privateDeclareIframeGadget
(
url
,
options
,
parent_gadget
)
{
var
gadget_instance
,
iframe
,
iframe_loading_deferred
=
RSVP
.
defer
();
if
(
options
.
element
===
undefined
)
{
throw
new
Error
(
"
DOM element is required to create Iframe Gadget
"
+
url
);
}
// Check if the element is attached to the DOM
if
(
!
document
.
contains
(
options
.
element
))
{
throw
new
Error
(
"
The parent element is not attached to the DOM for
"
+
url
);
}
gadget_instance
=
new
RenderJSIframeGadget
();
setAqParent
(
gadget_instance
,
parent_gadget
);
iframe
=
document
.
createElement
(
"
iframe
"
);
// gadget_instance.element.setAttribute("seamless", "seamless");
iframe
.
setAttribute
(
"
src
"
,
url
);
gadget_instance
.
__path
=
url
;
gadget_instance
.
__element
=
options
.
element
;
// Attach it to the DOM
options
.
element
.
appendChild
(
iframe
);
// XXX Manage unbind when deleting the gadget
// Create the communication channel with the iframe
gadget_instance
.
__chan
=
Channel
.
build
({
window
:
iframe
.
contentWindow
,
origin
:
"
*
"
,
scope
:
"
renderJS
"
});
// Create new method from the declareMethod call inside the iframe
gadget_instance
.
__chan
.
bind
(
"
declareMethod
"
,
function
(
trans
,
method_name
)
{
gadget_instance
[
method_name
]
=
function
()
{
var
argument_list
=
arguments
,
wait_promise
=
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
gadget_instance
.
__chan
.
call
({
method
:
"
methodCall
"
,
params
:
[
method_name
,
Array
.
prototype
.
slice
.
call
(
argument_list
,
0
)],
success
:
function
(
s
)
{
resolve
(
s
);
},
error
:
function
(
e
)
{
reject
(
e
);
}
});
});
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
wait_promise
;
});
};
return
"
OK
"
;
});
// Wait for the iframe to be loaded before continuing
gadget_instance
.
__chan
.
bind
(
"
ready
"
,
function
(
trans
)
{
iframe_loading_deferred
.
resolve
(
gadget_instance
);
return
"
OK
"
;
});
gadget_instance
.
__chan
.
bind
(
"
failed
"
,
function
(
trans
,
params
)
{
iframe_loading_deferred
.
reject
(
params
);
return
"
OK
"
;
});
gadget_instance
.
__chan
.
bind
(
"
acquire
"
,
function
(
trans
,
params
)
{
gadget_instance
.
__aq_parent
.
apply
(
gadget_instance
,
params
)
.
then
(
function
(
g
)
{
trans
.
complete
(
g
);
}).
fail
(
function
(
e
)
{
trans
.
error
(
e
.
toString
());
});
trans
.
delayReturn
(
true
);
});
return
RSVP
.
any
([
iframe_loading_deferred
.
promise
,
// Timeout to prevent non renderJS embeddable gadget
// XXX Maybe using iframe.onload/onerror would be safer?
RSVP
.
timeout
(
25000
)
]);
}
/////////////////////////////////////////////////////////////////
// privateDeclareDataUrlGadget
/////////////////////////////////////////////////////////////////
function
privateDeclareDataUrlGadget
(
url
,
options
,
parent_gadget
)
{
return
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
ajax
(
url
);
})
.
push
(
function
(
xhr
)
{
// Insert a "base" element, in order to resolve all relative links
// which could get broken with a data url
var
doc
=
(
new
DOMParser
()).
parseFromString
(
xhr
.
responseText
,
'
text/html
'
),
base
=
doc
.
createElement
(
'
base
'
),
blob
;
base
.
href
=
url
;
doc
.
head
.
insertBefore
(
base
,
doc
.
head
.
firstChild
);
blob
=
new
Blob
([
doc
.
documentElement
.
outerHTML
],
{
type
:
"
text/html;charset=UTF-8
"
});
return
readBlobAsDataURL
(
blob
);
})
.
push
(
function
(
data_url
)
{
return
privateDeclareIframeGadget
(
data_url
,
options
,
parent_gadget
);
});
}
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareGadget
/////////////////////////////////////////////////////////////////
RenderJSGadget
.
declareMethod
(
'
declareGadget
'
,
function
(
url
,
options
)
{
var
queue
,
parent_gadget
=
this
,
local_loading_klass_promise
,
previous_loading_klass_promise
=
loading_klass_promise
;
if
(
options
===
undefined
)
{
options
=
{};
}
if
(
options
.
sandbox
===
undefined
)
{
options
.
sandbox
=
"
public
"
;
}
// transform url to absolute url if it is relative
url
=
renderJS
.
getAbsoluteURL
(
url
,
this
.
__path
);
// Change the global variable to update the loading queue
loading_klass_promise
=
new
RSVP
.
Queue
()
// Wait for previous gadget loading to finish first
.
push
(
function
()
{
return
previous_loading_klass_promise
;
})
.
push
(
undefined
,
function
()
{
// Forget previous declareGadget error
return
;
})
.
push
(
function
()
{
var
method
;
if
(
options
.
sandbox
===
"
public
"
)
{
method
=
privateDeclarePublicGadget
;
}
else
if
(
options
.
sandbox
===
"
iframe
"
)
{
method
=
privateDeclareIframeGadget
;
}
else
if
(
options
.
sandbox
===
"
dataurl
"
)
{
method
=
privateDeclareDataUrlGadget
;
}
else
{
throw
new
Error
(
"
Unsupported sandbox options '
"
+
options
.
sandbox
+
"
'
"
);
}
return
method
(
url
,
options
,
parent_gadget
);
})
// Set the HTML context
.
push
(
function
(
gadget_instance
)
{
// Drop the current loading klass info used by selector
gadget_loading_klass
=
undefined
;
return
gadget_instance
;
})
.
push
(
undefined
,
function
(
e
)
{
// Drop the current loading klass info used by selector
// even in case of error
gadget_loading_klass
=
undefined
;
throw
e
;
});
local_loading_klass_promise
=
loading_klass_promise
;
queue
=
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
local_loading_klass_promise
;
})
// Set the HTML context
.
push
(
function
(
gadget_instance
)
{
var
i
,
scope
;
// Trigger calling of all ready callback
function
ready_wrapper
()
{
return
gadget_instance
;
}
for
(
i
=
0
;
i
<
gadget_instance
.
constructor
.
__ready_list
.
length
;
i
+=
1
)
{
// Put a timeout?
queue
.
push
(
gadget_instance
.
constructor
.
__ready_list
[
i
]);
// Always return the gadget instance after ready function
queue
.
push
(
ready_wrapper
);
}
// Store local reference to the gadget instance
scope
=
options
.
scope
;
if
(
scope
===
undefined
)
{
scope
=
'
RJS_
'
+
scope_increment
;
scope_increment
+=
1
;
while
(
parent_gadget
.
__sub_gadget_dict
.
hasOwnProperty
(
scope
))
{
scope
=
'
RJS_
'
+
scope_increment
;
scope_increment
+=
1
;
}
}
parent_gadget
.
__sub_gadget_dict
[
scope
]
=
gadget_instance
;
gadget_instance
.
__element
.
setAttribute
(
"
data-gadget-scope
"
,
scope
);
// Put some attribute to ease page layout comprehension
gadget_instance
.
__element
.
setAttribute
(
"
data-gadget-url
"
,
url
);
gadget_instance
.
__element
.
setAttribute
(
"
data-gadget-sandbox
"
,
options
.
sandbox
);
gadget_instance
.
__element
.
_gadget
=
gadget_instance
;
if
(
document
.
contains
(
gadget_instance
.
__element
))
{
// Put a timeout
queue
.
push
(
startService
);
}
// Always return the gadget instance after ready function
queue
.
push
(
ready_wrapper
);
return
gadget_instance
;
});
return
queue
;
})
.
declareMethod
(
'
getDeclaredGadget
'
,
function
(
gadget_scope
)
{
if
(
!
this
.
__sub_gadget_dict
.
hasOwnProperty
(
gadget_scope
))
{
throw
new
Error
(
"
Gadget scope '
"
+
gadget_scope
+
"
' is not known.
"
);
}
return
this
.
__sub_gadget_dict
[
gadget_scope
];
})
.
declareMethod
(
'
dropGadget
'
,
function
(
gadget_scope
)
{
if
(
!
this
.
__sub_gadget_dict
.
hasOwnProperty
(
gadget_scope
))
{
throw
new
Error
(
"
Gadget scope '
"
+
gadget_scope
+
"
' is not known.
"
);
}
// http://perfectionkills.com/understanding-delete/
delete
this
.
__sub_gadget_dict
[
gadget_scope
];
});
/////////////////////////////////////////////////////////////////
// renderJS selector
/////////////////////////////////////////////////////////////////
renderJS
=
function
(
selector
)
{
var
result
;
if
(
selector
===
window
)
{
// window is the 'this' value when loading a javascript file
// In this case, use the current loading gadget constructor
result
=
gadget_loading_klass
;
}
if
(
result
===
undefined
)
{
throw
new
Error
(
"
Unknown selector '
"
+
selector
+
"
'
"
);
}
return
result
;
};
/////////////////////////////////////////////////////////////////
// renderJS.AcquisitionError
/////////////////////////////////////////////////////////////////
renderJS
.
AcquisitionError
=
function
(
message
)
{
this
.
name
=
"
AcquisitionError
"
;
if
((
message
!==
undefined
)
&&
(
typeof
message
!==
"
string
"
))
{
throw
new
TypeError
(
'
You must pass a string.
'
);
}
this
.
message
=
message
||
"
Acquisition failed
"
;
};
renderJS
.
AcquisitionError
.
prototype
=
new
Error
();
renderJS
.
AcquisitionError
.
prototype
.
constructor
=
renderJS
.
AcquisitionError
;
/////////////////////////////////////////////////////////////////
// renderJS.getAbsoluteURL
/////////////////////////////////////////////////////////////////
renderJS
.
getAbsoluteURL
=
function
(
url
,
base_url
)
{
var
doc
,
base
,
link
,
html
=
"
<!doctype><html><head></head></html>
"
;
if
(
url
&&
base_url
&&
!
isAbsoluteOrDataURL
.
test
(
url
))
{
doc
=
(
new
DOMParser
()).
parseFromString
(
html
,
'
text/html
'
);
base
=
doc
.
createElement
(
'
base
'
);
link
=
doc
.
createElement
(
'
link
'
);
doc
.
head
.
appendChild
(
base
);
doc
.
head
.
appendChild
(
link
);
base
.
href
=
base_url
;
link
.
href
=
url
;
return
link
.
href
;
}
return
url
;
};
/////////////////////////////////////////////////////////////////
// renderJS.declareJS
/////////////////////////////////////////////////////////////////
renderJS
.
declareJS
=
function
(
url
)
{
// Prevent infinite recursion if loading render.js
// more than once
var
result
;
if
(
javascript_registration_dict
.
hasOwnProperty
(
url
))
{
result
=
RSVP
.
resolve
();
}
else
{
result
=
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
var
newScript
;
newScript
=
document
.
createElement
(
'
script
'
);
newScript
.
type
=
'
text/javascript
'
;
newScript
.
src
=
url
;
newScript
.
onload
=
function
()
{
javascript_registration_dict
[
url
]
=
null
;
resolve
();
};
newScript
.
onerror
=
function
(
e
)
{
reject
(
e
);
};
document
.
head
.
appendChild
(
newScript
);
});
}
return
result
;
};
/////////////////////////////////////////////////////////////////
// renderJS.declareCSS
/////////////////////////////////////////////////////////////////
renderJS
.
declareCSS
=
function
(
url
)
{
// https://github.com/furf/jquery-getCSS/blob/master/jquery.getCSS.js
// No way to cleanly check if a css has been loaded
// So, always resolve the promise...
// http://requirejs.org/docs/faq-advanced.html#css
var
result
;
if
(
stylesheet_registration_dict
.
hasOwnProperty
(
url
))
{
result
=
RSVP
.
resolve
();
}
else
{
result
=
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
var
link
;
link
=
document
.
createElement
(
'
link
'
);
link
.
rel
=
'
stylesheet
'
;
link
.
type
=
'
text/css
'
;
link
.
href
=
url
;
link
.
onload
=
function
()
{
stylesheet_registration_dict
[
url
]
=
null
;
resolve
();
};
link
.
onerror
=
function
(
e
)
{
reject
(
e
);
};
document
.
head
.
appendChild
(
link
);
});
}
return
result
;
};
/////////////////////////////////////////////////////////////////
// renderJS.declareGadgetKlass
/////////////////////////////////////////////////////////////////
renderJS
.
declareGadgetKlass
=
function
(
url
)
{
var
result
;
function
parse
(
xhr
)
{
var
tmp_constructor
,
key
,
parsed_html
;
if
(
!
gadget_model_dict
.
hasOwnProperty
(
url
))
{
// Class inheritance
tmp_constructor
=
function
()
{
RenderJSGadget
.
call
(
this
);
};
tmp_constructor
.
__ready_list
=
RenderJSGadget
.
__ready_list
.
slice
();
tmp_constructor
.
__service_list
=
RenderJSGadget
.
__service_list
.
slice
();
tmp_constructor
.
declareMethod
=
RenderJSGadget
.
declareMethod
;
tmp_constructor
.
declareAcquiredMethod
=
RenderJSGadget
.
declareAcquiredMethod
;
tmp_constructor
.
allowPublicAcquisition
=
RenderJSGadget
.
allowPublicAcquisition
;
tmp_constructor
.
ready
=
RenderJSGadget
.
ready
;
tmp_constructor
.
declareService
=
RenderJSGadget
.
declareService
;
tmp_constructor
.
prototype
=
new
RenderJSGadget
();
tmp_constructor
.
prototype
.
constructor
=
tmp_constructor
;
tmp_constructor
.
prototype
.
__path
=
url
;
tmp_constructor
.
prototype
.
__acquired_method_dict
=
{};
// https://developer.mozilla.org/en-US/docs/HTML_in_XMLHttpRequest
// https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
// https://developer.mozilla.org/en-US/docs/Code_snippets/HTML_to_DOM
tmp_constructor
.
__template_element
=
(
new
DOMParser
()).
parseFromString
(
xhr
.
responseText
,
"
text/html
"
);
parsed_html
=
renderJS
.
parseGadgetHTMLDocument
(
tmp_constructor
.
__template_element
,
url
);
for
(
key
in
parsed_html
)
{
if
(
parsed_html
.
hasOwnProperty
(
key
))
{
tmp_constructor
.
prototype
[
'
__
'
+
key
]
=
parsed_html
[
key
];
}
}
gadget_model_dict
[
url
]
=
tmp_constructor
;
}
return
gadget_model_dict
[
url
];
}
if
(
gadget_model_dict
.
hasOwnProperty
(
url
))
{
// Return klass object if it already exists
result
=
RSVP
.
resolve
(
gadget_model_dict
[
url
]);
}
else
{
// Fetch the HTML page and parse it
result
=
new
RSVP
.
Queue
()
.
push
(
function
()
{
return
ajax
(
url
);
})
.
push
(
function
(
xhr
)
{
return
parse
(
xhr
);
});
}
return
result
;
};
/////////////////////////////////////////////////////////////////
// renderJS.clearGadgetKlassList
/////////////////////////////////////////////////////////////////
// For test purpose only
renderJS
.
clearGadgetKlassList
=
function
()
{
gadget_model_dict
=
{};
javascript_registration_dict
=
{};
stylesheet_registration_dict
=
{};
};
/////////////////////////////////////////////////////////////////
// renderJS.parseGadgetHTMLDocument
/////////////////////////////////////////////////////////////////
renderJS
.
parseGadgetHTMLDocument
=
function
(
document_element
,
url
)
{
var
settings
=
{
title
:
""
,
interface_list
:
[],
required_css_list
:
[],
required_js_list
:
[]
},
i
,
element
;
if
(
!
url
||
!
isAbsoluteOrDataURL
.
test
(
url
))
{
throw
new
Error
(
"
The url should be absolute:
"
+
url
);
}
if
(
document_element
.
nodeType
===
9
)
{
settings
.
title
=
document_element
.
title
;
if
(
document_element
.
head
!==
null
)
{
for
(
i
=
0
;
i
<
document_element
.
head
.
children
.
length
;
i
+=
1
)
{
element
=
document_element
.
head
.
children
[
i
];
if
(
element
.
href
!==
null
)
{
// XXX Manage relative URL during extraction of URLs
// element.href returns absolute URL in firefox but "" in chrome;
if
(
element
.
rel
===
"
stylesheet
"
)
{
settings
.
required_css_list
.
push
(
renderJS
.
getAbsoluteURL
(
element
.
getAttribute
(
"
href
"
),
url
)
);
}
else
if
(
element
.
nodeName
===
"
SCRIPT
"
&&
(
element
.
type
===
"
text/javascript
"
||
!
element
.
type
))
{
settings
.
required_js_list
.
push
(
renderJS
.
getAbsoluteURL
(
element
.
getAttribute
(
"
src
"
),
url
)
);
}
else
if
(
element
.
rel
===
"
http://www.renderjs.org/rel/interface
"
)
{
settings
.
interface_list
.
push
(
renderJS
.
getAbsoluteURL
(
element
.
getAttribute
(
"
href
"
),
url
)
);
}
}
}
}
}
else
{
throw
new
Error
(
"
The first parameter should be an HTMLDocument
"
);
}
return
settings
;
};
/////////////////////////////////////////////////////////////////
// global
/////////////////////////////////////////////////////////////////
window
.
rJS
=
window
.
renderJS
=
renderJS
;
window
.
__RenderJSGadget
=
RenderJSGadget
;
window
.
__RenderJSEmbeddedGadget
=
RenderJSEmbeddedGadget
;
window
.
__RenderJSIframeGadget
=
RenderJSIframeGadget
;
///////////////////////////////////////////////////
// Bootstrap process. Register the self gadget.
///////////////////////////////////////////////////
function
bootstrap
()
{
var
url
=
removeHash
(
window
.
location
.
href
),
tmp_constructor
,
root_gadget
,
loading_gadget_promise
=
new
RSVP
.
Queue
(),
declare_method_count
=
0
,
embedded_channel
,
notifyReady
,
notifyDeclareMethod
,
gadget_ready
=
false
,
iframe_top_gadget
,
last_acquisition_gadget
,
declare_method_list_waiting
=
[],
gadget_failed
=
false
,
gadget_error
,
connection_ready
=
false
;
// Create the gadget class for the current url
if
(
gadget_model_dict
.
hasOwnProperty
(
url
))
{
throw
new
Error
(
"
bootstrap should not be called twice
"
);
}
loading_klass_promise
=
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
last_acquisition_gadget
=
new
RenderJSGadget
();
last_acquisition_gadget
.
__acquired_method_dict
=
{
getTopURL
:
function
()
{
return
url
;
},
reportServiceError
:
function
(
param_list
)
{
letsCrash
(
param_list
[
0
]);
}
};
// Stop acquisition on the last acquisition gadget
// Do not put this on the klass, as their could be multiple instances
last_acquisition_gadget
.
__aq_parent
=
function
(
method_name
)
{
throw
new
renderJS
.
AcquisitionError
(
"
No gadget provides
"
+
method_name
);
};
//we need to determine tmp_constructor's value before exit bootstrap
//because of function : renderJS
//but since the channel checking is async,
//we can't use code structure like:
// if channel communication is ok
// tmp_constructor = RenderJSGadget
// else
// tmp_constructor = RenderJSEmbeddedGadget
if
(
window
.
self
===
window
.
top
)
{
// XXX Copy/Paste from declareGadgetKlass
tmp_constructor
=
function
()
{
RenderJSGadget
.
call
(
this
);
};
tmp_constructor
.
declareMethod
=
RenderJSGadget
.
declareMethod
;
tmp_constructor
.
declareAcquiredMethod
=
RenderJSGadget
.
declareAcquiredMethod
;
tmp_constructor
.
allowPublicAcquisition
=
RenderJSGadget
.
allowPublicAcquisition
;
tmp_constructor
.
__ready_list
=
RenderJSGadget
.
__ready_list
.
slice
();
tmp_constructor
.
ready
=
RenderJSGadget
.
ready
;
tmp_constructor
.
__service_list
=
RenderJSGadget
.
__service_list
.
slice
();
tmp_constructor
.
declareService
=
RenderJSGadget
.
declareService
;
tmp_constructor
.
prototype
=
new
RenderJSGadget
();
tmp_constructor
.
prototype
.
constructor
=
tmp_constructor
;
tmp_constructor
.
prototype
.
__path
=
url
;
gadget_model_dict
[
url
]
=
tmp_constructor
;
// Create the root gadget instance and put it in the loading stack
root_gadget
=
new
gadget_model_dict
[
url
]();
setAqParent
(
root_gadget
,
last_acquisition_gadget
);
}
else
{
// Create the root gadget instance and put it in the loading stack
tmp_constructor
=
RenderJSEmbeddedGadget
;
tmp_constructor
.
__ready_list
=
RenderJSGadget
.
__ready_list
.
slice
();
tmp_constructor
.
__service_list
=
RenderJSGadget
.
__service_list
.
slice
();
tmp_constructor
.
prototype
.
__path
=
url
;
root_gadget
=
new
RenderJSEmbeddedGadget
();
setAqParent
(
root_gadget
,
last_acquisition_gadget
);
// Create the communication channel
embedded_channel
=
Channel
.
build
({
window
:
window
.
parent
,
origin
:
"
*
"
,
scope
:
"
renderJS
"
,
onReady
:
function
()
{
var
k
;
iframe_top_gadget
=
false
;
//Default: Define __aq_parent to inform parent window
root_gadget
.
__aq_parent
=
tmp_constructor
.
prototype
.
__aq_parent
=
function
(
method_name
,
argument_list
,
time_out
)
{
return
new
RSVP
.
Promise
(
function
(
resolve
,
reject
)
{
embedded_channel
.
call
({
method
:
"
acquire
"
,
params
:
[
method_name
,
argument_list
],
success
:
function
(
s
)
{
resolve
(
s
);
},
error
:
function
(
e
)
{
reject
(
e
);
},
timeout
:
time_out
});
});
};
// Channel is ready, so now declare Function
notifyDeclareMethod
=
function
(
name
)
{
declare_method_count
+=
1
;
embedded_channel
.
call
({
method
:
"
declareMethod
"
,
params
:
name
,
success
:
function
()
{
declare_method_count
-=
1
;
notifyReady
();
},
error
:
function
()
{
declare_method_count
-=
1
;
}
});
};
for
(
k
=
0
;
k
<
declare_method_list_waiting
.
length
;
k
+=
1
)
{
notifyDeclareMethod
(
declare_method_list_waiting
[
k
]);
}
declare_method_list_waiting
=
[];
// If Gadget Failed Notify Parent
if
(
gadget_failed
)
{
embedded_channel
.
notify
({
method
:
"
failed
"
,
params
:
gadget_error
});
return
;
}
// Get Top URL
return
tmp_constructor
.
prototype
.
__aq_parent
(
'
getTopURL
'
,
[])
.
then
(
function
(
topURL
)
{
var
base
=
document
.
createElement
(
'
base
'
);
base
.
href
=
topURL
;
base
.
target
=
"
_top
"
;
document
.
head
.
appendChild
(
base
);
connection_ready
=
true
;
notifyReady
();
//the channel is ok
//so bind calls to renderJS method on the instance
embedded_channel
.
bind
(
"
methodCall
"
,
function
(
trans
,
v
)
{
root_gadget
[
v
[
0
]].
apply
(
root_gadget
,
v
[
1
])
.
then
(
function
(
g
)
{
trans
.
complete
(
g
);
}).
fail
(
function
(
e
)
{
trans
.
error
(
e
.
toString
());
});
trans
.
delayReturn
(
true
);
});
})
.
fail
(
function
(
error
)
{
throw
error
;
});
}
});
// Notify parent about gadget instanciation
notifyReady
=
function
()
{
if
((
declare_method_count
===
0
)
&&
(
gadget_ready
===
true
))
{
embedded_channel
.
notify
({
method
:
"
ready
"
});
}
};
// Inform parent gadget about declareMethod calls here.
notifyDeclareMethod
=
function
(
name
)
{
declare_method_list_waiting
.
push
(
name
);
};
notifyDeclareMethod
(
"
getInterfaceList
"
);
notifyDeclareMethod
(
"
getRequiredCSSList
"
);
notifyDeclareMethod
(
"
getRequiredJSList
"
);
notifyDeclareMethod
(
"
getPath
"
);
notifyDeclareMethod
(
"
getTitle
"
);
// Surcharge declareMethod to inform parent window
tmp_constructor
.
declareMethod
=
function
(
name
,
callback
)
{
var
result
=
RenderJSGadget
.
declareMethod
.
apply
(
this
,
[
name
,
callback
]
);
notifyDeclareMethod
(
name
);
return
result
;
};
tmp_constructor
.
declareService
=
RenderJSGadget
.
declareService
;
tmp_constructor
.
declareAcquiredMethod
=
RenderJSGadget
.
declareAcquiredMethod
;
tmp_constructor
.
allowPublicAcquisition
=
RenderJSGadget
.
allowPublicAcquisition
;
iframe_top_gadget
=
true
;
}
tmp_constructor
.
prototype
.
__acquired_method_dict
=
{};
gadget_loading_klass
=
tmp_constructor
;
function
init
()
{
// XXX HTML properties can only be set when the DOM is fully loaded
var
settings
=
renderJS
.
parseGadgetHTMLDocument
(
document
,
url
),
j
,
key
;
for
(
key
in
settings
)
{
if
(
settings
.
hasOwnProperty
(
key
))
{
tmp_constructor
.
prototype
[
'
__
'
+
key
]
=
settings
[
key
];
}
}
tmp_constructor
.
__template_element
=
document
.
createElement
(
"
div
"
);
root_gadget
.
__element
=
document
.
body
;
for
(
j
=
0
;
j
<
root_gadget
.
__element
.
childNodes
.
length
;
j
+=
1
)
{
tmp_constructor
.
__template_element
.
appendChild
(
root_gadget
.
__element
.
childNodes
[
j
].
cloneNode
(
true
)
);
}
RSVP
.
all
([
root_gadget
.
getRequiredJSList
(),
root_gadget
.
getRequiredCSSList
()])
.
then
(
function
(
all_list
)
{
var
i
,
js_list
=
all_list
[
0
],
css_list
=
all_list
[
1
];
for
(
i
=
0
;
i
<
js_list
.
length
;
i
+=
1
)
{
javascript_registration_dict
[
js_list
[
i
]]
=
null
;
}
for
(
i
=
0
;
i
<
css_list
.
length
;
i
+=
1
)
{
stylesheet_registration_dict
[
css_list
[
i
]]
=
null
;
}
gadget_loading_klass
=
undefined
;
}).
then
(
function
()
{
// select the target node
var
target
=
document
.
querySelector
(
'
body
'
),
// create an observer instance
observer
=
new
MutationObserver
(
function
(
mutations
)
{
var
i
,
k
,
len
,
len2
,
node
,
added_list
;
mutations
.
forEach
(
function
(
mutation
)
{
if
(
mutation
.
type
===
'
childList
'
)
{
len
=
mutation
.
removedNodes
.
length
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
node
=
mutation
.
removedNodes
[
i
];
if
(
node
.
nodeType
===
Node
.
ELEMENT_NODE
)
{
if
(
node
.
hasAttribute
(
"
data-gadget-url
"
)
&&
(
node
.
_gadget
!==
undefined
))
{
createMonitor
(
node
.
_gadget
);
}
added_list
=
node
.
querySelectorAll
(
"
[data-gadget-url]
"
);
len2
=
added_list
.
length
;
for
(
k
=
0
;
k
<
len2
;
k
+=
1
)
{
node
=
added_list
[
k
];
if
(
node
.
_gadget
!==
undefined
)
{
createMonitor
(
node
.
_gadget
);
}
}
}
}
len
=
mutation
.
addedNodes
.
length
;
for
(
i
=
0
;
i
<
len
;
i
+=
1
)
{
node
=
mutation
.
addedNodes
[
i
];
if
(
node
.
nodeType
===
Node
.
ELEMENT_NODE
)
{
if
(
node
.
hasAttribute
(
"
data-gadget-url
"
)
&&
(
node
.
_gadget
!==
undefined
))
{
if
(
document
.
contains
(
node
))
{
startService
(
node
.
_gadget
);
}
}
added_list
=
node
.
querySelectorAll
(
"
[data-gadget-url]
"
);
len2
=
added_list
.
length
;
for
(
k
=
0
;
k
<
len2
;
k
+=
1
)
{
node
=
added_list
[
k
];
if
(
document
.
contains
(
node
))
{
if
(
node
.
_gadget
!==
undefined
)
{
startService
(
node
.
_gadget
);
}
}
}
}
}
}
});
}),
// configuration of the observer:
config
=
{
childList
:
true
,
subtree
:
true
,
attributes
:
false
,
characterData
:
false
};
// pass in the target node, as well as the observer options
observer
.
observe
(
target
,
config
);
return
root_gadget
;
}).
then
(
resolve
,
function
(
e
)
{
reject
(
e
);
console
.
error
(
e
);
throw
e
;
});
}
document
.
addEventListener
(
'
DOMContentLoaded
'
,
init
,
false
);
});
loading_gadget_promise
.
push
(
function
()
{
return
loading_klass_promise
;
})
.
push
(
function
(
root_gadget
)
{
var
i
;
function
ready_wrapper
()
{
return
root_gadget
;
}
tmp_constructor
.
ready
(
function
(
g
)
{
return
startService
(
g
);
});
loading_gadget_promise
.
push
(
ready_wrapper
);
for
(
i
=
0
;
i
<
tmp_constructor
.
__ready_list
.
length
;
i
+=
1
)
{
// Put a timeout?
loading_gadget_promise
.
push
(
tmp_constructor
.
__ready_list
[
i
])
// Always return the gadget instance after ready function
.
push
(
ready_wrapper
);
}
});
if
(
window
.
self
===
window
.
top
)
{
loading_gadget_promise
.
fail
(
function
(
e
)
{
letsCrash
(
e
);
throw
e
;
});
}
else
{
// Inform parent window that gadget is correctly loaded
loading_gadget_promise
.
then
(
function
()
{
gadget_ready
=
true
;
if
(
connection_ready
)
{
notifyReady
();
}
})
.
fail
(
function
(
e
)
{
//top gadget in iframe
if
(
iframe_top_gadget
)
{
gadget_failed
=
true
;
gadget_error
=
e
.
toString
();
letsCrash
(
e
);
}
else
{
embedded_channel
.
notify
({
method
:
"
failed
"
,
params
:
e
.
toString
()});
}
throw
e
;
});
}
}
bootstrap
();
}(
document
,
window
,
RSVP
,
DOMParser
,
Channel
,
MutationObserver
,
Node
,
FileReader
,
Blob
));
\ No newline at end of file
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/renderjs.js.xml
deleted
100644 → 0
View file @
c7ce159a
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"File"
module=
"OFS.Image"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
__name__
</string>
</key>
<value>
<string>
renderjs.js
</string>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
application/javascript
</string>
</value>
</item>
<item>
<key>
<string>
precondition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
renderjs.js
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/rsvp.js.js
deleted
100644 → 0
View file @
c7ce159a
(
function
(
globals
)
{
var
define
,
requireModule
;
(
function
()
{
var
registry
=
{},
seen
=
{};
define
=
function
(
name
,
deps
,
callback
)
{
registry
[
name
]
=
{
deps
:
deps
,
callback
:
callback
};
};
requireModule
=
function
(
name
)
{
if
(
seen
[
name
])
{
return
seen
[
name
];
}
seen
[
name
]
=
{};
var
mod
=
registry
[
name
];
if
(
!
mod
)
{
throw
new
Error
(
"
Module '
"
+
name
+
"
' not found.
"
);
}
var
deps
=
mod
.
deps
,
callback
=
mod
.
callback
,
reified
=
[],
exports
;
for
(
var
i
=
0
,
l
=
deps
.
length
;
i
<
l
;
i
++
)
{
if
(
deps
[
i
]
===
'
exports
'
)
{
reified
.
push
(
exports
=
{});
}
else
{
reified
.
push
(
requireModule
(
deps
[
i
]));
}
}
var
value
=
callback
.
apply
(
this
,
reified
);
return
seen
[
name
]
=
exports
||
value
;
};
})();
define
(
"
rsvp/all
"
,
[
"
rsvp/promise
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
/* global toString */
function
promiseAtLeast
(
expected_count
,
promises
)
{
if
(
Object
.
prototype
.
toString
.
call
(
promises
)
!==
"
[object Array]
"
)
{
throw
new
TypeError
(
'
You must pass an array to all.
'
);
}
function
canceller
()
{
var
promise
;
for
(
var
i
=
0
;
i
<
promises
.
length
;
i
++
)
{
promise
=
promises
[
i
];
if
(
promise
&&
typeof
promise
.
then
===
'
function
'
&&
typeof
promise
.
cancel
===
'
function
'
)
{
promise
.
cancel
();
}
}
}
return
new
Promise
(
function
(
resolve
,
reject
,
notify
)
{
var
results
=
[],
remaining
=
promises
.
length
,
promise
,
remaining_count
=
promises
.
length
-
expected_count
;
if
(
remaining
===
0
)
{
if
(
expected_count
===
1
)
{
resolve
();
}
else
{
resolve
([]);
}
}
function
resolver
(
index
)
{
return
function
(
value
)
{
resolveAll
(
index
,
value
);
};
}
function
resolveAll
(
index
,
value
)
{
results
[
index
]
=
value
;
if
(
--
remaining
===
remaining_count
)
{
if
(
remaining_count
===
0
)
{
resolve
(
results
);
}
else
{
resolve
(
value
);
canceller
();
}
}
}
function
notifier
(
index
)
{
return
function
(
value
)
{
notify
({
"
index
"
:
index
,
"
value
"
:
value
});
};
}
function
cancelAll
(
rejectionValue
)
{
reject
(
rejectionValue
);
canceller
();
}
for
(
var
i
=
0
;
i
<
promises
.
length
;
i
++
)
{
promise
=
promises
[
i
];
if
(
promise
&&
typeof
promise
.
then
===
'
function
'
)
{
promise
.
then
(
resolver
(
i
),
cancelAll
,
notifier
(
i
));
}
else
{
resolveAll
(
i
,
promise
);
}
}
},
canceller
);
}
function
all
(
promises
)
{
return
promiseAtLeast
(
promises
.
length
,
promises
);
}
function
any
(
promises
)
{
return
promiseAtLeast
(
1
,
promises
);
}
__exports__
.
all
=
all
;
__exports__
.
any
=
any
;
});
define
(
"
rsvp/async
"
,
[
"
exports
"
],
function
(
__exports__
)
{
"
use strict
"
;
var
browserGlobal
=
(
typeof
window
!==
'
undefined
'
)
?
window
:
{};
var
BrowserMutationObserver
=
browserGlobal
.
MutationObserver
||
browserGlobal
.
WebKitMutationObserver
;
var
async
;
var
local
=
(
typeof
global
!==
'
undefined
'
)
?
global
:
this
;
// old node
function
useNextTick
()
{
return
function
(
callback
,
arg
)
{
process
.
nextTick
(
function
()
{
callback
(
arg
);
});
};
}
// node >= 0.10.x
function
useSetImmediate
()
{
return
function
(
callback
,
arg
)
{
/* global setImmediate */
setImmediate
(
function
(){
callback
(
arg
);
});
};
}
function
useMutationObserver
()
{
var
queue
=
[];
var
observer
=
new
BrowserMutationObserver
(
function
()
{
var
toProcess
=
queue
.
slice
();
queue
=
[];
toProcess
.
forEach
(
function
(
tuple
)
{
var
callback
=
tuple
[
0
],
arg
=
tuple
[
1
];
callback
(
arg
);
});
});
var
element
=
document
.
createElement
(
'
div
'
);
observer
.
observe
(
element
,
{
attributes
:
true
});
// Chrome Memory Leak: https://bugs.webkit.org/show_bug.cgi?id=93661
window
.
addEventListener
(
'
unload
'
,
function
(){
observer
.
disconnect
();
observer
=
null
;
},
false
);
return
function
(
callback
,
arg
)
{
queue
.
push
([
callback
,
arg
]);
element
.
setAttribute
(
'
drainQueue
'
,
'
drainQueue
'
);
};
}
function
useSetTimeout
()
{
return
function
(
callback
,
arg
)
{
local
.
setTimeout
(
function
()
{
callback
(
arg
);
},
1
);
};
}
if
(
typeof
setImmediate
===
'
function
'
)
{
async
=
useSetImmediate
();
}
else
if
(
typeof
process
!==
'
undefined
'
&&
{}.
toString
.
call
(
process
)
===
'
[object process]
'
)
{
async
=
useNextTick
();
}
else
if
(
BrowserMutationObserver
)
{
async
=
useMutationObserver
();
}
else
{
async
=
useSetTimeout
();
}
__exports__
.
async
=
async
;
});
define
(
"
rsvp/cancellation_error
"
,
[
"
exports
"
],
function
(
__exports__
)
{
"
use strict
"
;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function
CancellationError
(
message
)
{
this
.
name
=
"
cancel
"
;
if
((
message
!==
undefined
)
&&
(
typeof
message
!==
"
string
"
))
{
throw
new
TypeError
(
'
You must pass a string.
'
);
}
this
.
message
=
message
||
"
Default Message
"
;
}
CancellationError
.
prototype
=
new
Error
();
CancellationError
.
prototype
.
constructor
=
CancellationError
;
__exports__
.
CancellationError
=
CancellationError
;
});
define
(
"
rsvp/config
"
,
[
"
rsvp/async
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
async
=
__dependency1__
.
async
;
var
config
=
{};
config
.
async
=
async
;
__exports__
.
config
=
config
;
});
define
(
"
rsvp/defer
"
,
[
"
rsvp/promise
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
function
defer
()
{
var
deferred
=
{
// pre-allocate shape
resolve
:
undefined
,
reject
:
undefined
,
promise
:
undefined
};
deferred
.
promise
=
new
Promise
(
function
(
resolve
,
reject
)
{
deferred
.
resolve
=
resolve
;
deferred
.
reject
=
reject
;
});
return
deferred
;
}
__exports__
.
defer
=
defer
;
});
define
(
"
rsvp/events
"
,
[
"
exports
"
],
function
(
__exports__
)
{
"
use strict
"
;
var
Event
=
function
(
type
,
options
)
{
this
.
type
=
type
;
for
(
var
option
in
options
)
{
if
(
!
options
.
hasOwnProperty
(
option
))
{
continue
;
}
this
[
option
]
=
options
[
option
];
}
};
var
indexOf
=
function
(
callbacks
,
callback
)
{
for
(
var
i
=
0
,
l
=
callbacks
.
length
;
i
<
l
;
i
++
)
{
if
(
callbacks
[
i
][
0
]
===
callback
)
{
return
i
;
}
}
return
-
1
;
};
var
callbacksFor
=
function
(
object
)
{
var
callbacks
=
object
.
_promiseCallbacks
;
if
(
!
callbacks
)
{
callbacks
=
object
.
_promiseCallbacks
=
{};
}
return
callbacks
;
};
var
EventTarget
=
{
mixin
:
function
(
object
)
{
object
.
on
=
this
.
on
;
object
.
off
=
this
.
off
;
object
.
trigger
=
this
.
trigger
;
return
object
;
},
on
:
function
(
eventNames
,
callback
,
binding
)
{
var
allCallbacks
=
callbacksFor
(
this
),
callbacks
,
eventName
;
eventNames
=
eventNames
.
split
(
/
\s
+/
);
binding
=
binding
||
this
;
while
(
eventName
=
eventNames
.
shift
())
{
callbacks
=
allCallbacks
[
eventName
];
if
(
!
callbacks
)
{
callbacks
=
allCallbacks
[
eventName
]
=
[];
}
if
(
indexOf
(
callbacks
,
callback
)
===
-
1
)
{
callbacks
.
push
([
callback
,
binding
]);
}
}
},
off
:
function
(
eventNames
,
callback
)
{
var
allCallbacks
=
callbacksFor
(
this
),
callbacks
,
eventName
,
index
;
eventNames
=
eventNames
.
split
(
/
\s
+/
);
while
(
eventName
=
eventNames
.
shift
())
{
if
(
!
callback
)
{
allCallbacks
[
eventName
]
=
[];
continue
;
}
callbacks
=
allCallbacks
[
eventName
];
index
=
indexOf
(
callbacks
,
callback
);
if
(
index
!==
-
1
)
{
callbacks
.
splice
(
index
,
1
);
}
}
},
trigger
:
function
(
eventName
,
options
)
{
var
allCallbacks
=
callbacksFor
(
this
),
callbacks
,
callbackTuple
,
callback
,
binding
,
event
;
if
(
callbacks
=
allCallbacks
[
eventName
])
{
// Don't cache the callbacks.length since it may grow
for
(
var
i
=
0
;
i
<
callbacks
.
length
;
i
++
)
{
callbackTuple
=
callbacks
[
i
];
callback
=
callbackTuple
[
0
];
binding
=
callbackTuple
[
1
];
if
(
typeof
options
!==
'
object
'
)
{
options
=
{
detail
:
options
};
}
event
=
new
Event
(
eventName
,
options
);
callback
.
call
(
binding
,
event
);
}
}
}
};
__exports__
.
EventTarget
=
EventTarget
;
});
define
(
"
rsvp/hash
"
,
[
"
rsvp/defer
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
defer
=
__dependency1__
.
defer
;
function
size
(
object
)
{
var
s
=
0
;
for
(
var
prop
in
object
)
{
s
++
;
}
return
s
;
}
function
hash
(
promises
)
{
var
results
=
{},
deferred
=
defer
(),
remaining
=
size
(
promises
);
if
(
remaining
===
0
)
{
deferred
.
resolve
({});
}
var
resolver
=
function
(
prop
)
{
return
function
(
value
)
{
resolveAll
(
prop
,
value
);
};
};
var
resolveAll
=
function
(
prop
,
value
)
{
results
[
prop
]
=
value
;
if
(
--
remaining
===
0
)
{
deferred
.
resolve
(
results
);
}
};
var
rejectAll
=
function
(
error
)
{
deferred
.
reject
(
error
);
};
for
(
var
prop
in
promises
)
{
if
(
promises
[
prop
]
&&
typeof
promises
[
prop
].
then
===
'
function
'
)
{
promises
[
prop
].
then
(
resolver
(
prop
),
rejectAll
);
}
else
{
resolveAll
(
prop
,
promises
[
prop
]);
}
}
return
deferred
.
promise
;
}
__exports__
.
hash
=
hash
;
});
define
(
"
rsvp/node
"
,
[
"
rsvp/promise
"
,
"
rsvp/all
"
,
"
exports
"
],
function
(
__dependency1__
,
__dependency2__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
var
all
=
__dependency2__
.
all
;
function
makeNodeCallbackFor
(
resolve
,
reject
)
{
return
function
(
error
,
value
)
{
if
(
error
)
{
reject
(
error
);
}
else
if
(
arguments
.
length
>
2
)
{
resolve
(
Array
.
prototype
.
slice
.
call
(
arguments
,
1
));
}
else
{
resolve
(
value
);
}
};
}
function
denodeify
(
nodeFunc
)
{
return
function
()
{
var
nodeArgs
=
Array
.
prototype
.
slice
.
call
(
arguments
),
resolve
,
reject
;
var
thisArg
=
this
;
var
promise
=
new
Promise
(
function
(
nodeResolve
,
nodeReject
)
{
resolve
=
nodeResolve
;
reject
=
nodeReject
;
});
all
(
nodeArgs
).
then
(
function
(
nodeArgs
)
{
nodeArgs
.
push
(
makeNodeCallbackFor
(
resolve
,
reject
));
try
{
nodeFunc
.
apply
(
thisArg
,
nodeArgs
);
}
catch
(
e
)
{
reject
(
e
);
}
});
return
promise
;
};
}
__exports__
.
denodeify
=
denodeify
;
});
define
(
"
rsvp/promise
"
,
[
"
rsvp/config
"
,
"
rsvp/events
"
,
"
rsvp/cancellation_error
"
,
"
exports
"
],
function
(
__dependency1__
,
__dependency2__
,
__dependency3__
,
__exports__
)
{
"
use strict
"
;
var
config
=
__dependency1__
.
config
;
var
EventTarget
=
__dependency2__
.
EventTarget
;
var
CancellationError
=
__dependency3__
.
CancellationError
;
function
objectOrFunction
(
x
)
{
return
isFunction
(
x
)
||
(
typeof
x
===
"
object
"
&&
x
!==
null
);
}
function
isFunction
(
x
){
return
typeof
x
===
"
function
"
;
}
var
Promise
=
function
(
resolver
,
canceller
)
{
var
promise
=
this
,
resolved
=
false
;
if
(
typeof
resolver
!==
'
function
'
)
{
throw
new
TypeError
(
'
You must pass a resolver function as the sole argument to the promise constructor
'
);
}
if
((
canceller
!==
undefined
)
&&
(
typeof
canceller
!==
'
function
'
))
{
throw
new
TypeError
(
'
You can only pass a canceller function
'
+
'
as the second argument to the promise constructor
'
);
}
if
(
!
(
promise
instanceof
Promise
))
{
return
new
Promise
(
resolver
,
canceller
);
}
var
resolvePromise
=
function
(
value
)
{
if
(
resolved
)
{
return
;
}
resolved
=
true
;
resolve
(
promise
,
value
);
};
var
rejectPromise
=
function
(
value
)
{
if
(
resolved
)
{
return
;
}
resolved
=
true
;
reject
(
promise
,
value
);
};
var
notifyPromise
=
function
(
value
)
{
if
(
resolved
)
{
return
;
}
notify
(
promise
,
value
);
};
this
.
on
(
'
promise:failed
'
,
function
(
event
)
{
this
.
trigger
(
'
error
'
,
{
detail
:
event
.
detail
});
},
this
);
this
.
on
(
'
error
'
,
onerror
);
this
.
cancel
=
function
()
{
// For now, simply reject the promise and does not propagate the cancel
// to parent or children
if
(
resolved
)
{
return
;
}
if
(
canceller
!==
undefined
)
{
try
{
canceller
();
}
catch
(
e
)
{
rejectPromise
(
e
);
return
;
}
}
// Trigger cancel?
rejectPromise
(
new
CancellationError
());
};
try
{
resolver
(
resolvePromise
,
rejectPromise
,
notifyPromise
);
}
catch
(
e
)
{
rejectPromise
(
e
);
}
};
function
onerror
(
event
)
{
if
(
config
.
onerror
)
{
config
.
onerror
(
event
.
detail
);
}
}
var
invokeCallback
=
function
(
type
,
promise
,
callback
,
event
)
{
var
hasCallback
=
isFunction
(
callback
),
value
,
error
,
succeeded
,
failed
;
if
(
promise
.
isFulfilled
)
{
return
;
}
if
(
promise
.
isRejected
)
{
return
;
}
if
(
hasCallback
)
{
try
{
value
=
callback
(
event
.
detail
);
succeeded
=
true
;
}
catch
(
e
)
{
failed
=
true
;
error
=
e
;
}
}
else
{
value
=
event
.
detail
;
succeeded
=
true
;
}
if
(
handleThenable
(
promise
,
value
))
{
return
;
}
else
if
(
hasCallback
&&
succeeded
)
{
resolve
(
promise
,
value
);
}
else
if
(
failed
)
{
reject
(
promise
,
error
);
}
else
if
(
type
===
'
resolve
'
)
{
resolve
(
promise
,
value
);
}
else
if
(
type
===
'
reject
'
)
{
reject
(
promise
,
value
);
}
};
var
invokeNotifyCallback
=
function
(
promise
,
callback
,
event
)
{
var
value
;
if
(
typeof
callback
===
'
function
'
)
{
try
{
value
=
callback
(
event
.
detail
);
}
catch
(
e
)
{
// stop propagating
return
;
}
notify
(
promise
,
value
);
}
else
{
notify
(
promise
,
event
.
detail
);
}
};
Promise
.
prototype
=
{
constructor
:
Promise
,
isRejected
:
undefined
,
isFulfilled
:
undefined
,
rejectedReason
:
undefined
,
fulfillmentValue
:
undefined
,
then
:
function
(
done
,
fail
,
progress
)
{
this
.
off
(
'
error
'
,
onerror
);
var
thenPromise
=
new
this
.
constructor
(
function
()
{},
function
()
{
thenPromise
.
trigger
(
'
promise:cancelled
'
,
{});
});
if
(
this
.
isFulfilled
)
{
config
.
async
(
function
(
promise
)
{
invokeCallback
(
'
resolve
'
,
thenPromise
,
done
,
{
detail
:
promise
.
fulfillmentValue
});
},
this
);
}
if
(
this
.
isRejected
)
{
config
.
async
(
function
(
promise
)
{
invokeCallback
(
'
reject
'
,
thenPromise
,
fail
,
{
detail
:
promise
.
rejectedReason
});
},
this
);
}
this
.
on
(
'
promise:resolved
'
,
function
(
event
)
{
invokeCallback
(
'
resolve
'
,
thenPromise
,
done
,
event
);
});
this
.
on
(
'
promise:failed
'
,
function
(
event
)
{
invokeCallback
(
'
reject
'
,
thenPromise
,
fail
,
event
);
});
this
.
on
(
'
promise:notified
'
,
function
(
event
)
{
invokeNotifyCallback
(
thenPromise
,
progress
,
event
);
});
return
thenPromise
;
},
fail
:
function
(
fail
)
{
return
this
.
then
(
null
,
fail
);
},
always
:
function
(
fail
)
{
return
this
.
then
(
fail
,
fail
);
}
};
EventTarget
.
mixin
(
Promise
.
prototype
);
function
resolve
(
promise
,
value
)
{
if
(
promise
===
value
)
{
fulfill
(
promise
,
value
);
}
else
if
(
!
handleThenable
(
promise
,
value
))
{
fulfill
(
promise
,
value
);
}
}
function
handleThenable
(
promise
,
value
)
{
var
then
=
null
,
resolved
;
try
{
if
(
promise
===
value
)
{
throw
new
TypeError
(
"
A promises callback cannot return that same promise.
"
);
}
if
(
objectOrFunction
(
value
))
{
then
=
value
.
then
;
if
(
isFunction
(
then
))
{
if
(
isFunction
(
value
.
on
))
{
value
.
on
(
'
promise:notified
'
,
function
(
event
)
{
notify
(
promise
,
event
.
detail
);
});
}
promise
.
on
(
'
promise:cancelled
'
,
function
(
event
)
{
if
(
isFunction
(
value
.
cancel
))
{
value
.
cancel
();
}
});
then
.
call
(
value
,
function
(
val
)
{
if
(
resolved
)
{
return
true
;
}
resolved
=
true
;
if
(
value
!==
val
)
{
resolve
(
promise
,
val
);
}
else
{
fulfill
(
promise
,
val
);
}
},
function
(
val
)
{
if
(
resolved
)
{
return
true
;
}
resolved
=
true
;
reject
(
promise
,
val
);
});
return
true
;
}
}
}
catch
(
error
)
{
reject
(
promise
,
error
);
return
true
;
}
return
false
;
}
function
fulfill
(
promise
,
value
)
{
config
.
async
(
function
()
{
if
(
promise
.
isFulfilled
)
{
return
;
}
if
(
promise
.
isRejected
)
{
return
;
}
promise
.
trigger
(
'
promise:resolved
'
,
{
detail
:
value
});
promise
.
isFulfilled
=
true
;
promise
.
fulfillmentValue
=
value
;
});
}
function
reject
(
promise
,
value
)
{
config
.
async
(
function
()
{
if
(
promise
.
isFulfilled
)
{
return
;
}
if
(
promise
.
isRejected
)
{
return
;
}
promise
.
trigger
(
'
promise:failed
'
,
{
detail
:
value
});
promise
.
isRejected
=
true
;
promise
.
rejectedReason
=
value
;
});
}
function
notify
(
promise
,
value
)
{
config
.
async
(
function
()
{
promise
.
trigger
(
'
promise:notified
'
,
{
detail
:
value
});
});
}
__exports__
.
Promise
=
Promise
;
});
define
(
"
rsvp/queue
"
,
[
"
rsvp/promise
"
,
"
rsvp/resolve
"
,
"
exports
"
],
function
(
__dependency1__
,
__dependency2__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
var
resolve
=
__dependency2__
.
resolve
;
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
function
ResolvedQueueError
(
message
)
{
this
.
name
=
"
resolved
"
;
if
((
message
!==
undefined
)
&&
(
typeof
message
!==
"
string
"
))
{
throw
new
TypeError
(
'
You must pass a string.
'
);
}
this
.
message
=
message
||
"
Default Message
"
;
}
ResolvedQueueError
.
prototype
=
new
Error
();
ResolvedQueueError
.
prototype
.
constructor
=
ResolvedQueueError
;
var
Queue
=
function
()
{
var
queue
=
this
,
promise_list
=
[],
promise
,
fulfill
,
reject
,
notify
,
resolved
;
if
(
!
(
this
instanceof
Queue
))
{
return
new
Queue
();
}
function
canceller
()
{
for
(
var
i
=
0
;
i
<
2
;
i
++
)
{
promise_list
[
i
].
cancel
();
}
}
promise
=
new
Promise
(
function
(
done
,
fail
,
progress
)
{
fulfill
=
function
(
fulfillmentValue
)
{
if
(
resolved
)
{
return
;}
queue
.
isFulfilled
=
true
;
queue
.
fulfillmentValue
=
fulfillmentValue
;
resolved
=
true
;
return
done
(
fulfillmentValue
);
};
reject
=
function
(
rejectedReason
)
{
if
(
resolved
)
{
return
;}
queue
.
isRejected
=
true
;
queue
.
rejectedReason
=
rejectedReason
;
resolved
=
true
;
return
fail
(
rejectedReason
);
};
notify
=
progress
;
},
canceller
);
promise_list
.
push
(
resolve
());
promise_list
.
push
(
promise_list
[
0
].
then
(
function
()
{
promise_list
.
splice
(
0
,
2
);
if
(
promise_list
.
length
===
0
)
{
fulfill
();
}
}));
queue
.
cancel
=
function
()
{
if
(
resolved
)
{
return
;}
resolved
=
true
;
promise
.
cancel
();
promise
.
fail
(
function
(
rejectedReason
)
{
queue
.
isRejected
=
true
;
queue
.
rejectedReason
=
rejectedReason
;
});
};
queue
.
then
=
function
()
{
return
promise
.
then
.
apply
(
promise
,
arguments
);
};
queue
.
push
=
function
(
done
,
fail
,
progress
)
{
var
last_promise
=
promise_list
[
promise_list
.
length
-
1
],
next_promise
;
if
(
resolved
)
{
throw
new
ResolvedQueueError
();
}
next_promise
=
last_promise
.
then
(
done
,
fail
,
progress
);
promise_list
.
push
(
next_promise
);
// Handle pop
last_promise
=
next_promise
.
then
(
function
(
fulfillmentValue
)
{
promise_list
.
splice
(
0
,
2
);
if
(
promise_list
.
length
===
0
)
{
fulfill
(
fulfillmentValue
);
}
else
{
return
fulfillmentValue
;
}
},
function
(
rejectedReason
)
{
promise_list
.
splice
(
0
,
2
);
if
(
promise_list
.
length
===
0
)
{
reject
(
rejectedReason
);
}
else
{
throw
rejectedReason
;
}
},
function
(
notificationValue
)
{
if
(
promise_list
[
promise_list
.
length
-
1
]
===
last_promise
)
{
notify
(
notificationValue
);
}
return
notificationValue
;
});
promise_list
.
push
(
last_promise
);
return
this
;
};
};
Queue
.
prototype
=
Object
.
create
(
Promise
.
prototype
);
Queue
.
prototype
.
constructor
=
Queue
;
__exports__
.
Queue
=
Queue
;
__exports__
.
ResolvedQueueError
=
ResolvedQueueError
;
});
define
(
"
rsvp/reject
"
,
[
"
rsvp/promise
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
function
reject
(
reason
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
reject
(
reason
);
});
}
__exports__
.
reject
=
reject
;
});
define
(
"
rsvp/resolve
"
,
[
"
rsvp/promise
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
function
resolve
(
thenable
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
if
(
typeof
thenable
===
"
object
"
&&
thenable
!==
null
)
{
var
then
=
thenable
.
then
;
if
((
then
!==
undefined
)
&&
(
typeof
then
===
"
function
"
))
{
return
then
.
apply
(
thenable
,
[
resolve
,
reject
]);
}
}
return
resolve
(
thenable
);
},
function
()
{
if
((
thenable
!==
undefined
)
&&
(
thenable
.
cancel
!==
undefined
))
{
thenable
.
cancel
();
}
});
}
__exports__
.
resolve
=
resolve
;
});
define
(
"
rsvp/rethrow
"
,
[
"
exports
"
],
function
(
__exports__
)
{
"
use strict
"
;
var
local
=
(
typeof
global
===
"
undefined
"
)
?
this
:
global
;
function
rethrow
(
reason
)
{
local
.
setTimeout
(
function
()
{
throw
reason
;
});
throw
reason
;
}
__exports__
.
rethrow
=
rethrow
;
});
define
(
"
rsvp/timeout
"
,
[
"
rsvp/promise
"
,
"
exports
"
],
function
(
__dependency1__
,
__exports__
)
{
"
use strict
"
;
var
Promise
=
__dependency1__
.
Promise
;
function
promiseSetTimeout
(
millisecond
,
should_reject
,
message
)
{
var
timeout_id
;
function
resolver
(
resolve
,
reject
)
{
timeout_id
=
setTimeout
(
function
()
{
if
(
should_reject
)
{
reject
(
message
);
}
else
{
resolve
(
message
);
}
},
millisecond
);
}
function
canceller
()
{
clearTimeout
(
timeout_id
);
}
return
new
Promise
(
resolver
,
canceller
);
}
function
delay
(
millisecond
,
message
)
{
return
promiseSetTimeout
(
millisecond
,
false
,
message
);
}
function
timeout
(
millisecond
)
{
return
promiseSetTimeout
(
millisecond
,
true
,
"
Timed out after
"
+
millisecond
+
"
ms
"
);
}
Promise
.
prototype
.
delay
=
function
(
millisecond
)
{
return
this
.
then
(
function
(
fulfillmentValue
)
{
return
delay
(
millisecond
,
fulfillmentValue
);
});
};
__exports__
.
delay
=
delay
;
__exports__
.
timeout
=
timeout
;
});
define
(
"
rsvp
"
,
[
"
rsvp/events
"
,
"
rsvp/cancellation_error
"
,
"
rsvp/promise
"
,
"
rsvp/node
"
,
"
rsvp/all
"
,
"
rsvp/queue
"
,
"
rsvp/timeout
"
,
"
rsvp/hash
"
,
"
rsvp/rethrow
"
,
"
rsvp/defer
"
,
"
rsvp/config
"
,
"
rsvp/resolve
"
,
"
rsvp/reject
"
,
"
exports
"
],
function
(
__dependency1__
,
__dependency2__
,
__dependency3__
,
__dependency4__
,
__dependency5__
,
__dependency6__
,
__dependency7__
,
__dependency8__
,
__dependency9__
,
__dependency10__
,
__dependency11__
,
__dependency12__
,
__dependency13__
,
__exports__
)
{
"
use strict
"
;
var
EventTarget
=
__dependency1__
.
EventTarget
;
var
CancellationError
=
__dependency2__
.
CancellationError
;
var
Promise
=
__dependency3__
.
Promise
;
var
denodeify
=
__dependency4__
.
denodeify
;
var
all
=
__dependency5__
.
all
;
var
any
=
__dependency5__
.
any
;
var
Queue
=
__dependency6__
.
Queue
;
var
ResolvedQueueError
=
__dependency6__
.
ResolvedQueueError
;
var
delay
=
__dependency7__
.
delay
;
var
timeout
=
__dependency7__
.
timeout
;
var
hash
=
__dependency8__
.
hash
;
var
rethrow
=
__dependency9__
.
rethrow
;
var
defer
=
__dependency10__
.
defer
;
var
config
=
__dependency11__
.
config
;
var
resolve
=
__dependency12__
.
resolve
;
var
reject
=
__dependency13__
.
reject
;
function
configure
(
name
,
value
)
{
config
[
name
]
=
value
;
}
__exports__
.
CancellationError
=
CancellationError
;
__exports__
.
Promise
=
Promise
;
__exports__
.
EventTarget
=
EventTarget
;
__exports__
.
all
=
all
;
__exports__
.
any
=
any
;
__exports__
.
Queue
=
Queue
;
__exports__
.
ResolvedQueueError
=
ResolvedQueueError
;
__exports__
.
delay
=
delay
;
__exports__
.
timeout
=
timeout
;
__exports__
.
hash
=
hash
;
__exports__
.
rethrow
=
rethrow
;
__exports__
.
defer
=
defer
;
__exports__
.
denodeify
=
denodeify
;
__exports__
.
configure
=
configure
;
__exports__
.
resolve
=
resolve
;
__exports__
.
reject
=
reject
;
});
window
.
RSVP
=
requireModule
(
"
rsvp
"
);
})(
window
);
\ No newline at end of file
bt5/erp5_dms/SkinTemplateItem/portal_skins/erp5_dms/pdf_js/rsvp.js.xml
deleted
100644 → 0
View file @
c7ce159a
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"File"
module=
"OFS.Image"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
__name__
</string>
</key>
<value>
<string>
rsvp.js
</string>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
application/javascript
</string>
</value>
</item>
<item>
<key>
<string>
precondition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
rsvp.js
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
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