Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
renderjs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gabriel Monnerat
renderjs
Commits
a86fa637
Commit
a86fa637
authored
Jun 25, 2013
by
Romain Courteaud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix indentation
parent
55e79740
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
773 additions
and
751 deletions
+773
-751
renderjs.js
renderjs.js
+773
-751
No files found.
renderjs.js
View file @
a86fa637
/*! RenderJs v0.2 */
/*! RenderJs v0.2 */
/*global console, require, $, localStorage, document, jIO */
/*global console, require, $, localStorage, document, jIO */
/*jslint evil: true,
white: true
*/
/*jslint evil: true,
indent: 2, maxerr: 3
*/
"
use strict
"
;
"
use strict
"
;
/*
/*
* RenderJs - Generic Gadget library renderer.
* RenderJs - Generic Gadget library renderer.
...
@@ -40,8 +40,8 @@ var RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE = true;
...
@@ -40,8 +40,8 @@ var RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE = true;
// fallback for IE
// fallback for IE
if
(
console
===
undefined
||
console
.
log
===
undefined
)
{
if
(
console
===
undefined
||
console
.
log
===
undefined
)
{
var
console
=
{};
var
console
=
{};
console
.
log
=
function
()
{};
console
.
log
=
function
()
{};
}
}
/**
/**
...
@@ -53,7 +53,7 @@ var RenderJs = (function () {
...
@@ -53,7 +53,7 @@ var RenderJs = (function () {
// a variable indicating if current gadget loading is over or not
// a variable indicating if current gadget loading is over or not
var
is_ready
=
false
,
current_gadget
;
var
is_ready
=
false
,
current_gadget
;
function
setSelfGadget
(
gadget
)
{
function
setSelfGadget
(
gadget
)
{
/*
/*
* Only used internally to set current gadget being executed.
* Only used internally to set current gadget being executed.
*/
*/
...
@@ -62,826 +62,848 @@ var RenderJs = (function () {
...
@@ -62,826 +62,848 @@ var RenderJs = (function () {
return
{
return
{
init
:
function
()
{
init
:
function
()
{
/*
/*
* Do all initialization
* Do all initialization
*/
*/
if
(
RENDERJS_ENABLE_IMPLICIT_GADGET_RENDERING
)
{
if
(
RENDERJS_ENABLE_IMPLICIT_GADGET_RENDERING
)
{
RenderJs
.
bootstrap
(
$
(
'
body
'
));
RenderJs
.
bootstrap
(
$
(
'
body
'
));
}
var
root_gadget
=
RenderJs
.
GadgetIndex
.
getRootGadget
();
if
(
RENDERJS_ENABLE_IMPLICIT_INTERACTION_BIND
||
RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE
)
{
// We might have a page without gadgets.
// Be careful, right now we can be in this case because
// asynchronous gadget loading is not finished
if
(
root_gadget
!==
undefined
)
{
RenderJs
.
bindReady
(
function
()
{
if
(
RENDERJS_ENABLE_IMPLICIT_INTERACTION_BIND
)
{
// examine all Intaction Gadgets and bind accordingly
RenderJs
.
InteractionGadget
.
init
();
}
if
(
RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE
)
{
// create all routes between gadgets
RenderJs
.
RouteGadget
.
init
();
}
}
);
}
}
var
root_gadget
=
RenderJs
.
GadgetIndex
.
getRootGadget
();
}
if
(
RENDERJS_ENABLE_IMPLICIT_INTERACTION_BIND
||
RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE
)
{
},
// We might have a page without gadgets.
// Be careful, right now we can be in this case because
bootstrap
:
function
(
root
)
{
// asynchronous gadget loading is not finished
/*
if
(
root_gadget
!==
undefined
)
{
* Load all gadgets for this DOM element
RenderJs
.
bindReady
(
* (including recursively contained ones)
function
()
{
*/
if
(
RENDERJS_ENABLE_IMPLICIT_INTERACTION_BIND
)
{
var
gadget_id
,
is_gadget
;
// examine all Intaction Gadgets and bind accordingly
gadget_id
=
root
.
attr
(
"
id
"
);
RenderJs
.
InteractionGadget
.
init
();
is_gadget
=
root
.
attr
(
"
data-gadget
"
)
!==
undefined
;
}
// this will make RenderJs fire "ready" event when all gadgets are loaded.
if
(
RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE
)
{
RenderJs
.
setReady
(
false
);
// create all routes between gadgets
if
(
is_gadget
&&
gadget_id
!==
undefined
)
{
RenderJs
.
RouteGadget
.
init
();
// bootstart root gadget only if it is indeed a gadget
}
RenderJs
.
loadGadget
(
root
);
});
}
RenderJs
.
loadRecursiveGadget
(
root
);
},
loadRecursiveGadget
:
function
(
root
)
{
/*
* Load all contained gadgets inside passed DOM element.
*/
var
gadget_list
,
gadget
,
gadget_id
,
gadget_js
;
gadget_list
=
root
.
find
(
"
[data-gadget]
"
);
// register all gadget in advance so checkAndTriggerReady
// can have accurate information for list of all gadgets
gadget_list
.
each
(
function
()
{
gadget
=
$
(
this
);
gadget_id
=
gadget
.
attr
(
"
id
"
);
gadget_js
=
new
RenderJs
.
Gadget
(
gadget_id
,
gadget
);
RenderJs
.
GadgetIndex
.
registerGadget
(
gadget_js
);
});
// Load chilren
gadget_list
.
each
(
function
()
{
RenderJs
.
loadGadget
(
$
(
this
));
});
},
setGadgetAndRecurse
:
function
(
gadget
,
data
)
{
/*
* Set gadget data and recursively load it in case it holds another
* gadgets.
*/
// set current gadget as being loaded so gadget instance itself knows which gadget it is
setSelfGadget
(
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget
.
attr
(
"
id
"
)));
gadget
.
append
(
data
);
// reset as no longer current gadget
setSelfGadget
(
undefined
);
// a gadget may contain sub gadgets
RenderJs
.
loadRecursiveGadget
(
gadget
);
},
getSelfGadget
:
function
()
{
/*
* Get current gadget being loaded
* This function must be used with care as it relies on Javascript nature of being a single
* threaded application. Currently current gadget is set in a global RenderJs variable
* before its HTML is inserted into DOM and if multiple threads were running (which is not the case currently)
* this could lead to reace conditions and unreliable getSelfGadget results.
* Additionally this function is available only at gadget's script load time - i.e.
* it can't be used in after that calls. In this case gagdget can save this value internally.
*/
return
current_gadget
;
},
loadGadget
:
function
(
gadget
)
{
/*
* Load gadget's SPECs from URL
*/
var
url
,
gadget_id
,
gadget_property
,
cacheable
,
cache_id
,
i
,
gadget_index
,
gadget_index_id
,
app_cache
,
data
,
gadget_js
,
is_update_gadget_data_running
;
url
=
gadget
.
attr
(
"
data-gadget
"
);
gadget_id
=
gadget
.
attr
(
"
id
"
);
gadget_js
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
gadget_index
=
RenderJs
.
GadgetIndex
.
getGadgetList
();
if
(
gadget_js
===
undefined
)
{
// register gadget in javascript namespace if not already registered
gadget_js
=
new
RenderJs
.
Gadget
(
gadget_id
,
gadget
);
RenderJs
.
GadgetIndex
.
registerGadget
(
gadget_js
);
}
if
(
gadget_js
.
isReady
())
{
// avoid loading again gadget which was loaded before in same page
return
;
}
// update Gadget's instance with contents of "data-gadget-property"
gadget_property
=
gadget
.
attr
(
"
data-gadget-property
"
);
if
(
gadget_property
!==
undefined
)
{
gadget_property
=
$
.
parseJSON
(
gadget_property
);
$
.
each
(
gadget_property
,
function
(
key
,
value
)
{
gadget_js
[
key
]
=
value
;
});
}
if
(
url
!==
undefined
&&
url
!==
""
)
{
cacheable
=
gadget
.
attr
(
"
data-gadget-cacheable
"
);
cache_id
=
gadget
.
attr
(
"
data-gadget-cache-id
"
);
if
(
cacheable
!==
undefined
&&
cache_id
!==
undefined
)
{
cacheable
=
Boolean
(
parseInt
(
cacheable
,
10
));
}
//cacheable = false ; // to develop faster
if
(
cacheable
)
{
// get from cache if possible, use last part from URL as
// cache_key
app_cache
=
RenderJs
.
Cache
.
get
(
cache_id
,
undefined
);
if
(
app_cache
===
undefined
||
app_cache
===
null
)
{
// not in cache so we pull from network and cache
$
.
ajax
({
url
:
url
,
yourCustomData
:
{
"
gadget_id
"
:
gadget_id
,
"
cache_id
"
:
cache_id
},
success
:
function
(
data
)
{
cache_id
=
this
.
yourCustomData
.
cache_id
;
gadget_id
=
this
.
yourCustomData
.
gadget_id
;
RenderJs
.
Cache
.
set
(
cache_id
,
data
);
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
).
setReady
();
RenderJs
.
setGadgetAndRecurse
(
gadget
,
data
);
RenderJs
.
checkAndTriggerReady
();
RenderJs
.
updateGadgetData
(
gadget
);
}
});
}
else
{
// get from cache
data
=
app_cache
;
gadget_js
.
setReady
();
this
.
setGadgetAndRecurse
(
gadget
,
data
);
this
.
checkAndTriggerReady
();
RenderJs
.
updateGadgetData
(
gadget
);
}
}
}
else
{
// not to be cached
$
.
ajax
({
url
:
url
,
yourCustomData
:
{
"
gadget_id
"
:
gadget_id
},
success
:
function
(
data
)
{
gadget_id
=
this
.
yourCustomData
.
gadget_id
;
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
).
setReady
();
RenderJs
.
setGadgetAndRecurse
(
gadget
,
data
);
RenderJs
.
checkAndTriggerReady
();
RenderJs
.
updateGadgetData
(
gadget
);
}
});
}
}
else
{
// gadget is an inline (InteractorGadget or one using
// data-gadget-source / data-gadget-handler) so no need
// to load it from network
is_update_gadget_data_running
=
RenderJs
.
updateGadgetData
(
gadget
);
if
(
!
is_update_gadget_data_running
)
{
// no update is running so gadget is basically ready
// if update is running then it should take care and set status
gadget_js
.
setReady
();
}
}
},
RenderJs
.
checkAndTriggerReady
();
}
},
isReady
:
function
()
{
/*
* Get rendering status
*/
return
is_ready
;
},
setReady
:
function
(
value
)
{
/*
* Update rendering status
*/
is_ready
=
value
;
},
bindReady
:
function
(
ready_function
)
{
/*
* Bind a function on ready gadget loading.
*/
$
(
"
body
"
).
one
(
"
ready
"
,
ready_function
);
},
checkAndTriggerReady
:
function
()
{
/*
* Trigger "ready" event only if all gadgets were marked as "ready"
*/
var
is_gadget_list_loaded
;
is_gadget_list_loaded
=
RenderJs
.
GadgetIndex
.
isGadgetListLoaded
();
if
(
is_gadget_list_loaded
)
{
if
(
!
RenderJs
.
isReady
())
{
// backwards compatability with already written code
RenderJs
.
GadgetIndex
.
getRootGadget
().
getDom
().
trigger
(
"
ready
"
);
// trigger ready on root body element
$
(
"
body
"
).
trigger
(
"
ready
"
);
// this set will make sure we fire this event only once
RenderJs
.
setReady
(
true
);
}
}
return
is_gadget_list_loaded
;
},
updateGadgetData
:
function
(
gadget
)
{
/*
* Gadget can be updated from "data-gadget-source" (i.e. a json)
* and "data-gadget-handler" attributes (i.e. a namespace Javascript)
*/
var
data_source
,
data_handler
;
data_source
=
gadget
.
attr
(
"
data-gadget-source
"
);
data_handler
=
gadget
.
attr
(
"
data-gadget-handler
"
);
// acquire data and pass it to method handler
if
(
data_source
!==
undefined
&&
data_source
!==
""
)
{
$
.
ajax
({
url
:
data_source
,
dataType
:
"
json
"
,
yourCustomData
:
{
"
data_handler
"
:
data_handler
,
"
gadget_id
"
:
gadget
.
attr
(
"
id
"
)},
success
:
function
(
result
)
{
var
data_handler
,
gadget_id
;
data_handler
=
this
.
yourCustomData
.
data_handler
;
gadget_id
=
this
.
yourCustomData
.
gadget_id
;
if
(
data_handler
!==
undefined
)
{
// eval is not nice to use
eval
(
data_handler
+
"
(result)
"
);
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
// mark gadget as loaded and fire a check
// to see if all gadgets are loaded
gadget
.
setReady
();
RenderJs
.
checkAndTriggerReady
();
}
}
});
// asynchronous update happens and respective thread will update status
return
true
;
}
return
false
;
},
addGadget
:
function
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
gadget_data_source
,
bootstrap
)
{
/*
* add new gadget and render it
*/
var
html_string
,
tab_container
,
tab_gadget
;
tab_container
=
$
(
'
#
'
+
dom_id
);
tab_container
.
empty
();
html_string
=
[
'
<div id="
'
+
gadget_id
+
'
"
'
,
'
data-gadget="
'
+
gadget
+
'
"
'
,
'
data-gadget-handler="
'
+
gadget_data_handler
+
'
"
'
,
'
data-gadget-source="
'
+
gadget_data_source
+
'
"></div>
'
].
join
(
'
\n
'
);
tab_container
.
append
(
html_string
);
tab_gadget
=
tab_container
.
find
(
'
#
'
+
gadget_id
);
// render new gadget
if
(
bootstrap
!==
false
)
{
RenderJs
.
bootstrap
(
tab_container
);
}
return
tab_gadget
;
},
Cache
:
(
function
()
{
/*
* Generic cache implementation that can fall back to local
* namespace storage if no "modern" storage like localStorage
* is available
*/
return
{
ROOT_CACHE_ID
:
'
APP_CACHE
'
,
getCacheId
:
function
(
cache_id
)
{
/*
* We should have a way to 'purge' localStorage by setting a
* ROOT_CACHE_ID in all browser instances
*/
return
this
.
ROOT_CACHE_ID
+
cache_id
;
},
bootstrap
:
function
(
root
)
{
hasLocalStorage
:
function
(
)
{
/*
/*
* Load all gadgets for this DOM element
* Feature test if localStorage is supported
* (including recursively contained ones)
*/
*/
var
gadget_id
,
is_gadget
;
var
mod
;
gadget_id
=
root
.
attr
(
"
id
"
);
mod
=
'
localstorage_test_12345678
'
;
is_gadget
=
root
.
attr
(
"
data-gadget
"
)
!==
undefined
;
try
{
// this will make RenderJs fire "ready" event when all gadgets are loaded.
localStorage
.
setItem
(
mod
,
mod
);
RenderJs
.
setReady
(
false
);
localStorage
.
removeItem
(
mod
);
if
(
is_gadget
&&
gadget_id
!==
undefined
)
{
return
true
;
// bootstart root gadget only if it is indeed a gadget
}
catch
(
e
)
{
RenderJs
.
loadGadget
(
root
);
return
false
;
}
},
get
:
function
(
cache_id
,
default_value
)
{
/* Get cache key value */
cache_id
=
this
.
getCacheId
(
cache_id
);
if
(
this
.
hasLocalStorage
())
{
return
this
.
LocalStorageCachePlugin
.
get
(
cache_id
,
default_value
);
}
}
RenderJs
.
loadRecursiveGadget
(
root
);
//fallback to javscript namespace cache
},
return
this
.
NameSpaceStorageCachePlugin
.
get
(
cache_id
,
default_value
);
},
set
:
function
(
cache_id
,
data
)
{
/* Set cache key value */
cache_id
=
this
.
getCacheId
(
cache_id
);
if
(
this
.
hasLocalStorage
())
{
this
.
LocalStorageCachePlugin
.
set
(
cache_id
,
data
);
}
else
{
this
.
NameSpaceStorageCachePlugin
.
set
(
cache_id
,
data
);
}
},
loadRecursiveGadget
:
function
(
root
)
{
LocalStorageCachePlugin
:
(
function
(
)
{
/*
/*
*
Load all contained gadgets inside passed DOM element
.
*
This plugin saves using HTML5 localStorage
.
*/
*/
var
gadget_list
,
gadget
,
gadget_id
,
gadget_js
;
return
{
gadget_list
=
root
.
find
(
"
[data-gadget]
"
);
get
:
function
(
cache_id
,
default_value
)
{
/* Get cache key value */
// register all gadget in advance so checkAndTriggerReady
if
(
localStorage
.
getItem
(
cache_id
)
!==
null
)
{
// can have accurate information for list of all gadgets
return
JSON
.
parse
(
localStorage
.
getItem
(
cache_id
));
gadget_list
.
each
(
function
()
{
}
gadget
=
$
(
this
);
return
default_value
;
gadget_id
=
gadget
.
attr
(
"
id
"
);
},
gadget_js
=
new
RenderJs
.
Gadget
(
gadget_id
,
gadget
);
RenderJs
.
GadgetIndex
.
registerGadget
(
gadget_js
);
});
// Load chilren
set
:
function
(
cache_id
,
data
)
{
gadget_list
.
each
(
function
()
{
/* Set cache key value */
RenderJs
.
loadGadget
(
$
(
this
));
localStorage
.
setItem
(
cache_id
,
JSON
.
stringify
(
data
));
});
}
},
};
}()),
setGadgetAndRecurse
:
function
(
gadget
,
data
)
{
NameSpaceStorageCachePlugin
:
(
function
(
)
{
/*
/*
* Set gadget data and recursively load it in case it holds another
* This plugin saves within current page namespace.
* gadgets.
*/
*/
// set current gadget as being loaded so gadget instance itself knows which gadget it is
var
namespace
=
{};
setSelfGadget
(
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget
.
attr
(
"
id
"
)));
gadget
.
append
(
data
);
// reset as no longer current gadget
setSelfGadget
(
undefined
);
// a gadget may contain sub gadgets
RenderJs
.
loadRecursiveGadget
(
gadget
);
},
getSelfGadget
:
function
()
{
/*
* Get current gadget being loaded
* This function must be used with care as it relies on Javascript nature of being a single
* threaded application. Currently current gadget is set in a global RenderJs variable
* before its HTML is inserted into DOM and if multiple threads were running (which is not the case currently)
* this could lead to reace conditions and unreliable getSelfGadget results.
* Additionally this function is available only at gadget's script load time - i.e.
* it can't be used in after that calls. In this case gagdget can save this value internally.
*/
return
current_gadget
;
},
loadGadget
:
function
(
gadget
)
{
return
{
get
:
function
(
cache_id
,
default_value
)
{
/* Get cache key value */
return
namespace
[
cache_id
];
},
set
:
function
(
cache_id
,
data
)
{
/* Set cache key value */
namespace
[
cache_id
]
=
data
;
}
};
}())
};
}()),
Gadget
:
function
(
gadget_id
,
dom
)
{
/*
* Javascript Gadget representation
*/
this
.
id
=
gadget_id
;
this
.
dom
=
dom
;
this
.
is_ready
=
false
;
},
TabbularGadget
:
(
function
()
{
/*
* Generic tabular gadget
*/
var
gadget_list
=
[];
return
{
toggleVisibility
:
function
(
visible_dom
)
{
/*
/*
*
Load gadget's SPECs from URL
*
Set tab as active visually and mark as not active rest.
*/
*/
var
url
,
gadget_id
,
gadget_property
,
cacheable
,
cache_id
,
$
(
"
.selected
"
).
addClass
(
"
not_selected
"
);
i
,
gadget_index
,
gadget_index_id
,
$
(
"
.selected
"
).
removeClass
(
"
selected
"
);
app_cache
,
data
,
gadget_js
,
is_update_gadget_data_running
;
visible_dom
.
addClass
(
"
selected
"
);
visible_dom
.
removeClass
(
"
not_selected
"
);
url
=
gadget
.
attr
(
"
data-gadget
"
);
},
gadget_id
=
gadget
.
attr
(
"
id
"
);
gadget_js
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
addNewTabGadget
:
function
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
gadget_index
=
RenderJs
.
GadgetIndex
.
getGadgetList
();
gadget_data_source
,
bootstrap
)
{
/*
if
(
gadget_js
===
undefined
)
{
* add new gadget and render it
// register gadget in javascript namespace if not already registered
*/
gadget_js
=
new
RenderJs
.
Gadget
(
gadget_id
,
gadget
);
var
tab_gadget
;
RenderJs
.
GadgetIndex
.
registerGadget
(
gadget_js
);
tab_gadget
=
RenderJs
.
addGadget
(
}
dom_id
,
if
(
gadget_js
.
isReady
())
{
gadget_id
,
// avoid loading again gadget which was loaded before in same page
gadget
,
return
;
gadget_data_handler
,
}
gadget_data_source
,
bootstrap
);
// we should unregister all gadgets part of this TabbularGadget
$
.
each
(
gadget_list
,
function
(
index
,
gadget_id
)
{
var
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
gadget
.
remove
();
// update list of root gadgets inside TabbularGadget
gadget_list
.
splice
(
$
.
inArray
(
gadget_id
,
gadget_list
),
1
);
}
);
// add it as root gadget
gadget_list
.
push
(
tab_gadget
.
attr
(
"
id
"
));
}
};
}()),
// update Gadget's instance with contents of "data-gadget-property"
GadgetIndex
:
(
function
()
{
gadget_property
=
gadget
.
attr
(
"
data-gadget-property
"
);
/*
if
(
gadget_property
!==
undefined
)
{
* Generic gadget index placeholder
gadget_property
=
$
.
parseJSON
(
gadget_property
);
*/
$
.
each
(
gadget_property
,
function
(
key
,
value
)
{
var
gadget_list
=
[];
gadget_js
[
key
]
=
value
;
});
}
if
(
url
!==
undefined
&&
url
!==
""
)
{
return
{
cacheable
=
gadget
.
attr
(
"
data-gadget-cacheable
"
);
cache_id
=
gadget
.
attr
(
"
data-gadget-cache-id
"
);
if
(
cacheable
!==
undefined
&&
cache_id
!==
undefined
)
{
cacheable
=
Boolean
(
parseInt
(
cacheable
,
10
));
}
//cacheable = false ; // to develop faster
if
(
cacheable
)
{
// get from cache if possible, use last part from URL as
// cache_key
app_cache
=
RenderJs
.
Cache
.
get
(
cache_id
,
undefined
);
if
(
app_cache
===
undefined
||
app_cache
===
null
)
{
// not in cache so we pull from network and cache
$
.
ajax
({
url
:
url
,
yourCustomData
:
{
"
gadget_id
"
:
gadget_id
,
"
cache_id
"
:
cache_id
},
success
:
function
(
data
)
{
cache_id
=
this
.
yourCustomData
.
cache_id
;
gadget_id
=
this
.
yourCustomData
.
gadget_id
;
RenderJs
.
Cache
.
set
(
cache_id
,
data
);
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
).
setReady
();
RenderJs
.
setGadgetAndRecurse
(
gadget
,
data
);
RenderJs
.
checkAndTriggerReady
();
RenderJs
.
updateGadgetData
(
gadget
);
}
});
}
else
{
// get from cache
data
=
app_cache
;
gadget_js
.
setReady
();
this
.
setGadgetAndRecurse
(
gadget
,
data
);
this
.
checkAndTriggerReady
();
RenderJs
.
updateGadgetData
(
gadget
);
}
}
else
{
// not to be cached
$
.
ajax
({
url
:
url
,
yourCustomData
:
{
"
gadget_id
"
:
gadget_id
},
success
:
function
(
data
)
{
gadget_id
=
this
.
yourCustomData
.
gadget_id
;
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
).
setReady
();
RenderJs
.
setGadgetAndRecurse
(
gadget
,
data
);
RenderJs
.
checkAndTriggerReady
();
RenderJs
.
updateGadgetData
(
gadget
);
}
});
}
}
else
{
// gadget is an inline (InteractorGadget or one using
// data-gadget-source / data-gadget-handler) so no need
// to load it from network
is_update_gadget_data_running
=
RenderJs
.
updateGadgetData
(
gadget
);
if
(
!
is_update_gadget_data_running
)
{
// no update is running so gadget is basically ready
// if update is running then it should take care and set status
gadget_js
.
setReady
();
}
RenderJs
.
checkAndTriggerReady
();
}
},
isReady
:
function
(
)
{
getGadgetIdListFromDom
:
function
(
dom
)
{
/*
/*
* Get
rendering status
* Get
list of all gadget's ID from DOM
*/
*/
return
is_ready
;
var
gadget_id_list
=
[];
},
$
.
each
(
dom
.
find
(
'
[data-gadget]
'
),
function
(
index
,
value
)
{
setReady
:
function
(
value
)
{
gadget_id_list
.
push
(
$
(
value
).
attr
(
"
id
"
));
}
);
return
gadget_id_list
;
},
setGadgetList
:
function
(
gadget_list_value
)
{
/*
/*
*
Update rendering statu
s
*
Set list of registered gadget
s
*/
*/
is_ready
=
value
;
gadget_list
=
gadget_list_
value
;
},
},
bindReady
:
function
(
ready_function
)
{
getGadgetList
:
function
(
)
{
/*
/*
*
Bind a function on ready gadget loading.
*
Return list of registered gadgets
*/
*/
$
(
"
body
"
).
one
(
"
ready
"
,
ready_function
)
;
return
gadget_list
;
},
},
checkAndTriggerReady
:
function
(
)
{
registerGadget
:
function
(
gadget
)
{
/*
/*
*
Trigger "ready" event only if all gadgets were marked as "ready"
*
Register gadget
*/
*/
var
is_gadget_list_loaded
;
if
(
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget
.
id
)
===
undefined
)
{
is_gadget_list_loaded
=
RenderJs
.
GadgetIndex
.
isGadgetListLoaded
();
// register only if not already added
if
(
is_gadget_list_loaded
)
{
gadget_list
.
push
(
gadget
);
if
(
!
RenderJs
.
isReady
())
{
// backwards compatability with already written code
RenderJs
.
GadgetIndex
.
getRootGadget
().
getDom
().
trigger
(
"
ready
"
);
// trigger ready on root body element
$
(
"
body
"
).
trigger
(
"
ready
"
);
// this set will make sure we fire this event only once
RenderJs
.
setReady
(
true
);
}
}
}
return
is_gadget_list_loaded
;
},
},
updateGadgetData
:
function
(
gadget
)
{
unregisterGadget
:
function
(
gadget
)
{
/*
/*
* Gadget can be updated from "data-gadget-source" (i.e. a json)
* Unregister gadget
* and "data-gadget-handler" attributes (i.e. a namespace Javascript)
*/
*/
var
data_source
,
data_handler
;
var
index
=
$
.
inArray
(
gadget
,
gadget_list
);
data_source
=
gadget
.
attr
(
"
data-gadget-source
"
);
if
(
index
!==
-
1
)
{
data_handler
=
gadget
.
attr
(
"
data-gadget-handler
"
);
gadget_list
.
splice
(
index
,
1
);
// acquire data and pass it to method handler
if
(
data_source
!==
undefined
&&
data_source
!==
""
)
{
$
.
ajax
({
url
:
data_source
,
dataType
:
"
json
"
,
yourCustomData
:
{
"
data_handler
"
:
data_handler
,
"
gadget_id
"
:
gadget
.
attr
(
"
id
"
)},
success
:
function
(
result
)
{
var
data_handler
,
gadget_id
;
data_handler
=
this
.
yourCustomData
.
data_handler
;
gadget_id
=
this
.
yourCustomData
.
gadget_id
;
if
(
data_handler
!==
undefined
)
{
// eval is not nice to use
eval
(
data_handler
+
"
(result)
"
);
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
// mark gadget as loaded and fire a check
// to see if all gadgets are loaded
gadget
.
setReady
();
RenderJs
.
checkAndTriggerReady
();
}
}
});
// asynchronous update happens and respective thread will update status
return
true
;
}
}
return
false
;
},
},
addGadget
:
function
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
getGadgetById
:
function
(
gadget_id
)
{
gadget_data_source
,
bootstrap
)
{
/*
/*
*
add new gadget and render it
*
Get gadget javascript representation by its Id
*/
*/
var
html_string
,
tab_container
,
tab_gadget
;
var
gadget
;
tab_container
=
$
(
'
#
'
+
dom_id
);
gadget
=
undefined
;
tab_container
.
empty
();
$
(
RenderJs
.
GadgetIndex
.
getGadgetList
()).
each
(
html_string
=
[
function
(
index
,
value
)
{
'
<div id="
'
+
gadget_id
+
'
"
'
,
if
(
value
.
getId
()
===
gadget_id
)
{
'
data-gadget="
'
+
gadget
+
'
"
'
,
gadget
=
value
;
'
data-gadget-handler="
'
+
gadget_data_handler
+
'
"
'
,
}
'
data-gadget-source="
'
+
gadget_data_source
+
'
"></div>
'
}
].
join
(
'
\n
'
);
);
return
gadget
;
tab_container
.
append
(
html_string
);
},
tab_gadget
=
tab_container
.
find
(
'
#
'
+
gadget_id
);
// render new gadget
if
(
bootstrap
!==
false
)
{
RenderJs
.
bootstrap
(
tab_container
);
}
return
tab_gadget
;
},
Cache
:
(
function
()
{
getRootGadget
:
function
()
{
/*
/*
* Generic cache implementation that can fall back to local
* Return root gadget (always first one in list)
* namespace storage if no "modern" storage like localStorage
* is available
*/
*/
return
{
return
this
.
getGadgetList
()[
0
];
ROOT_CACHE_ID
:
'
APP_CACHE
'
,
},
getCacheId
:
function
(
cache_id
)
{
/*
* We should have a way to 'purge' localStorage by setting a
* ROOT_CACHE_ID in all browser instances
*/
return
this
.
ROOT_CACHE_ID
+
cache_id
;
},
hasLocalStorage
:
function
()
{
/*
* Feature test if localStorage is supported
*/
var
mod
;
mod
=
'
localstorage_test_12345678
'
;
try
{
localStorage
.
setItem
(
mod
,
mod
);
localStorage
.
removeItem
(
mod
);
return
true
;
}
catch
(
e
)
{
return
false
;
}
},
get
:
function
(
cache_id
,
default_value
)
{
/* Get cache key value */
cache_id
=
this
.
getCacheId
(
cache_id
);
if
(
this
.
hasLocalStorage
())
{
return
this
.
LocalStorageCachePlugin
.
get
(
cache_id
,
default_value
);
}
//fallback to javscript namespace cache
return
this
.
NameSpaceStorageCachePlugin
.
get
(
cache_id
,
default_value
);
},
set
:
function
(
cache_id
,
data
)
{
isGadgetListLoaded
:
function
()
{
/* Set cache key value */
cache_id
=
this
.
getCacheId
(
cache_id
);
if
(
this
.
hasLocalStorage
())
{
this
.
LocalStorageCachePlugin
.
set
(
cache_id
,
data
);
}
else
{
this
.
NameSpaceStorageCachePlugin
.
set
(
cache_id
,
data
);
}
},
LocalStorageCachePlugin
:
(
function
()
{
/*
* This plugin saves using HTML5 localStorage.
*/
return
{
get
:
function
(
cache_id
,
default_value
)
{
/* Get cache key value */
if
(
localStorage
.
getItem
(
cache_id
)
!==
null
)
{
return
JSON
.
parse
(
localStorage
.
getItem
(
cache_id
));
}
return
default_value
;
},
set
:
function
(
cache_id
,
data
)
{
/* Set cache key value */
localStorage
.
setItem
(
cache_id
,
JSON
.
stringify
(
data
));
}
};
}()),
NameSpaceStorageCachePlugin
:
(
function
()
{
/*
* This plugin saves within current page namespace.
*/
var
namespace
=
{};
return
{
get
:
function
(
cache_id
,
default_value
)
{
/* Get cache key value */
return
namespace
[
cache_id
];
},
set
:
function
(
cache_id
,
data
)
{
/* Set cache key value */
namespace
[
cache_id
]
=
data
;
}
};
}())
};
}()),
Gadget
:
function
(
gadget_id
,
dom
)
{
/*
/*
* Javascript Gadget representation
* Return True if all gadgets were loaded from network or
* cache
*/
*/
this
.
id
=
gadget_id
;
var
result
;
this
.
dom
=
dom
;
result
=
true
;
this
.
is_ready
=
false
;
$
(
this
.
getGadgetList
()).
each
(
},
function
(
index
,
value
)
{
if
(
value
.
isReady
()
===
false
)
{
result
=
false
;
}
}
);
return
result
;
}
};
}()),
GadgetCatalog
:
(
function
()
{
/*
* Gadget catalog provides API to get list of gadgets from a repository
*/
var
cache_id
=
"
setGadgetIndexUrlList
"
;
function
updateGadgetIndexFromURL
(
url
)
{
// split to base and document url
var
url_list
=
url
.
split
(
'
/
'
),
document_url
=
url_list
[
url_list
.
length
-
1
],
d
=
url_list
.
splice
(
$
.
inArray
(
document_url
,
url_list
),
1
),
base_url
=
url_list
.
join
(
'
/
'
),
web_dav
=
jIO
.
newJio
({
"
type
"
:
"
dav
"
,
"
username
"
:
""
,
"
password
"
:
""
,
"
url
"
:
base_url
});
web_dav
.
get
(
document_url
,
function
(
err
,
response
)
{
RenderJs
.
Cache
.
set
(
url
,
response
);
});
}
TabbularGadget
:
(
function
()
{
return
{
updateGadgetIndex
:
function
()
{
/*
/*
*
Generic tabular gadget
*
Update gadget index from all configured remote repositories.
*/
*/
var
gadget_list
=
[];
$
.
each
(
RenderJs
.
GadgetCatalog
.
getGadgetIndexUrlList
(),
return
{
function
(
index
,
value
)
{
toggleVisibility
:
function
(
visible_dom
)
{
updateGadgetIndexFromURL
(
value
);
/*
});
* Set tab as active visually and mark as not active rest.
},
*/
$
(
"
.selected
"
).
addClass
(
"
not_selected
"
);
$
(
"
.selected
"
).
removeClass
(
"
selected
"
);
visible_dom
.
addClass
(
"
selected
"
);
visible_dom
.
removeClass
(
"
not_selected
"
);
},
addNewTabGadget
:
function
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
setGadgetIndexUrlList
:
function
(
url_list
)
{
gadget_data_source
,
bootstrap
)
{
/*
/*
* Set list of Gadget Index repositories.
* add new gadget and render it
*/
*/
// store in Cache (html5 storage)
var
tab_gadget
;
RenderJs
.
Cache
.
set
(
cache_id
,
url_list
);
tab_gadget
=
RenderJs
.
addGadget
(
},
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
gadget_data_source
,
bootstrap
);
// we should unregister all gadgets part of this TabbularGadget
getGadgetIndexUrlList
:
function
()
{
$
.
each
(
gadget_list
,
/*
function
(
index
,
gadget_id
)
{
* Get list of Gadget Index repositories.
var
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
*/
gadget
.
remove
();
// get from Cache (html5 storage)
// update list of root gadgets inside TabbularGadget
return
RenderJs
.
Cache
.
get
(
cache_id
,
undefined
);
gadget_list
.
splice
(
$
.
inArray
(
gadget_id
,
gadget_list
),
1
);
},
}
);
// add it as root gadget
gadget_list
.
push
(
tab_gadget
.
attr
(
"
id
"
));
}
};
}()),
GadgetIndex
:
(
function
(
)
{
getGadgetListThatProvide
:
function
(
service
)
{
/*
/*
* Generic gadget index placeholder
* Return list of all gadgets that providen a given service.
* Read this list from data structure created in HTML5 local
* storage by updateGadgetIndexFromURL
*/
*/
// get from Cache stored index and itterate over it
// to find matching ones
var
gadget_list
=
[];
var
gadget_list
=
[];
$
.
each
(
RenderJs
.
GadgetCatalog
.
getGadgetIndexUrlList
(),
return
{
function
(
index
,
url
)
{
// get repos from cache
getGadgetIdListFromDom
:
function
(
dom
)
{
var
cached_repo
=
RenderJs
.
Cache
.
get
(
url
);
/*
$
.
each
(
cached_repo
.
gadget_list
,
* Get list of all gadget's ID from DOM
function
(
index
,
gadget
)
{
*/
if
(
$
.
inArray
(
service
,
gadget
.
service_list
)
>
-
1
)
{
var
gadget_id_list
=
[];
// gadget provides a service, add to list
$
.
each
(
dom
.
find
(
'
[data-gadget]
'
),
function
(
index
,
value
)
{
gadget_id_list
.
push
(
$
(
value
).
attr
(
"
id
"
));}
);
return
gadget_id_list
;
},
setGadgetList
:
function
(
gadget_list_value
)
{
/*
* Set list of registered gadgets
*/
gadget_list
=
gadget_list_value
;
},
getGadgetList
:
function
()
{
/*
* Return list of registered gadgets
*/
return
gadget_list
;
},
registerGadget
:
function
(
gadget
)
{
/*
* Register gadget
*/
if
(
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget
.
id
)
===
undefined
)
{
// register only if not already added
gadget_list
.
push
(
gadget
);
gadget_list
.
push
(
gadget
);
}
}
},
}
unregisterGadget
:
function
(
gadget
)
{
/*
* Unregister gadget
*/
var
index
=
$
.
inArray
(
gadget
,
gadget_list
);
if
(
index
!==
-
1
)
{
gadget_list
.
splice
(
index
,
1
);
}
},
getGadgetById
:
function
(
gadget_id
)
{
/*
* Get gadget javascript representation by its Id
*/
var
gadget
;
gadget
=
undefined
;
$
(
RenderJs
.
GadgetIndex
.
getGadgetList
()).
each
(
function
(
index
,
value
)
{
if
(
value
.
getId
()
===
gadget_id
)
{
gadget
=
value
;
}
}
);
);
return
gadget
;
});
},
return
gadget_list
;
},
getRootGadget
:
function
()
{
registerServiceList
:
function
(
gadget
,
service_list
)
{
/*
/*
* Return root gadget (always first one in list)
* Register a service provided by a gadget.
*/
*/
return
this
.
getGadgetList
()[
0
];
}
},
};
}()),
isGadgetListLoaded
:
function
()
{
InteractionGadget
:
(
function
()
{
/*
/*
* Return True if all gadgets were loaded from network or
* Basic gadget interaction gadget implementation.
* cache
*/
*/
return
{
var
result
;
result
=
true
;
$
(
this
.
getGadgetList
()).
each
(
function
(
index
,
value
)
{
if
(
value
.
isReady
()
===
false
)
{
result
=
false
;
}
}
);
return
result
;
}
};
}()),
GadgetCatalog
:
(
function
(
)
{
init
:
function
(
force
)
{
/*
/*
* Gadget catalog provides API to get list of gadgets from a repository
* Inspect DOM and initialize this gadget
*/
*/
var
cache_id
=
"
setGadgetIndexUrlList
"
;
var
dom_list
,
gadget_id
;
if
(
force
===
1
)
{
function
updateGadgetIndexFromURL
(
url
)
{
// we explicitly want to re-init elements even if already this is done before
// split to base and document url
dom_list
=
$
(
"
div[data-gadget-connection]
"
);
var
url_list
=
url
.
split
(
'
/
'
),
}
else
{
document_url
=
url_list
[
url_list
.
length
-
1
],
// XXX: improve and save 'bound' on javascript representation of a gadget not DOM
d
=
url_list
.
splice
(
$
.
inArray
(
document_url
,
url_list
),
1
),
dom_list
=
$
(
"
div[data-gadget-connection]
"
)
base_url
=
url_list
.
join
(
'
/
'
),
.
filter
(
function
()
{
return
$
(
this
).
data
(
"
bound
"
)
!==
true
;
})
web_dav
=
jIO
.
newJio
({
.
data
(
'
bound
'
,
true
);
"
type
"
:
"
dav
"
,
"
username
"
:
""
,
"
password
"
:
""
,
"
url
"
:
base_url
});
web_dav
.
get
(
document_url
,
function
(
err
,
response
)
{
RenderJs
.
Cache
.
set
(
url
,
response
);
});
}
}
dom_list
.
each
(
function
(
index
,
element
)
{
RenderJs
.
InteractionGadget
.
bind
(
$
(
element
));
});
},
return
{
bind
:
function
(
gadget_dom
)
{
updateGadgetIndex
:
function
()
{
/*
* Update gadget index from all configured remote repositories.
*/
$
.
each
(
RenderJs
.
GadgetCatalog
.
getGadgetIndexUrlList
(),
function
(
index
,
value
)
{
updateGadgetIndexFromURL
(
value
);
});
},
setGadgetIndexUrlList
:
function
(
url_list
)
{
/*
* Set list of Gadget Index repositories.
*/
// store in Cache (html5 storage)
RenderJs
.
Cache
.
set
(
cache_id
,
url_list
);
},
getGadgetIndexUrlList
:
function
()
{
/*
* Get list of Gadget Index repositories.
*/
// get from Cache (html5 storage)
return
RenderJs
.
Cache
.
get
(
cache_id
,
undefined
);
},
getGadgetListThatProvide
:
function
(
service
)
{
/*
* Return list of all gadgets that providen a given service.
* Read this list from data structure created in HTML5 local
* storage by updateGadgetIndexFromURL
*/
// get from Cache stored index and itterate over it
// to find matching ones
var
gadget_list
=
[];
$
.
each
(
RenderJs
.
GadgetCatalog
.
getGadgetIndexUrlList
(),
function
(
index
,
url
)
{
// get repos from cache
var
cached_repo
=
RenderJs
.
Cache
.
get
(
url
);
$
.
each
(
cached_repo
.
gadget_list
,
function
(
index
,
gadget
)
{
if
(
$
.
inArray
(
service
,
gadget
.
service_list
)
>
-
1
)
{
// gadget provides a service, add to list
gadget_list
.
push
(
gadget
);
}
}
);
});
return
gadget_list
;
},
registerServiceList
:
function
(
gadget
,
service_list
)
{
/*
* Register a service provided by a gadget.
*/
}
};
}()),
InteractionGadget
:
(
function
()
{
/*
/*
* B
asic gadget interaction gadget implementation
.
* B
ind event between gadgets
.
*/
*/
return
{
var
gadget_id
,
gadget_connection_list
,
createMethodInteraction
=
function
(
init
:
function
(
force
)
{
original_source_method_id
,
/*
source_gadget_id
,
* Inspect DOM and initialize this gadget
source_method_id
,
*/
destination_gadget_id
,
var
dom_list
,
gadget_id
;
destination_method_id
if
(
force
===
1
)
{
)
{
// we explicitly want to re-init elements even if already this is done before
var
interaction
=
function
()
{
dom_list
=
$
(
"
div[data-gadget-connection]
"
);
// execute source method
}
RenderJs
.
GadgetIndex
.
getGadgetById
(
else
{
source_gadget_id
// XXX: improve and save 'bound' on javascript representation of a gadget not DOM
)[
original_source_method_id
].
dom_list
=
$
(
"
div[data-gadget-connection]
"
)
apply
(
null
,
arguments
);
.
filter
(
function
()
{
return
$
(
this
).
data
(
"
bound
"
)
!==
true
;
})
// call trigger so bind can be asynchronously called
.
data
(
'
bound
'
,
true
);
RenderJs
.
GadgetIndex
.
getGadgetById
(
}
destination_gadget_id
dom_list
.
each
(
function
(
index
,
element
)
{
).
dom
.
trigger
(
source_method_id
);
RenderJs
.
InteractionGadget
.
bind
(
$
(
element
));});
};
},
return
interaction
;
},
createTriggerInteraction
=
function
(
destination_gadget_id
,
destination_method_id
)
{
var
interaction
=
function
()
{
RenderJs
.
GadgetIndex
.
getGadgetById
(
destination_gadget_id
)[
destination_method_id
].
apply
(
null
,
arguments
);
};
return
interaction
;
};
gadget_id
=
gadget_dom
.
attr
(
"
id
"
);
gadget_connection_list
=
gadget_dom
.
attr
(
"
data-gadget-connection
"
);
gadget_connection_list
=
$
.
parseJSON
(
gadget_connection_list
);
$
.
each
(
gadget_connection_list
,
function
(
key
,
value
)
{
var
source
,
source_gadget_id
,
source_method_id
,
source_gadget
,
destination
,
destination_gadget_id
,
destination_method_id
,
destination_gadget
,
original_source_method_id
;
source
=
value
.
source
.
split
(
"
.
"
);
source_gadget_id
=
source
[
0
];
source_method_id
=
source
[
1
];
source_gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
source_gadget_id
);
destination
=
value
.
destination
.
split
(
"
.
"
);
destination_gadget_id
=
destination
[
0
];
destination_method_id
=
destination
[
1
];
destination_gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
destination_gadget_id
);
if
(
source_gadget
.
hasOwnProperty
(
source_method_id
))
{
// direct javascript use case
original_source_method_id
=
"
original_
"
+
source_method_id
;
source_gadget
[
original_source_method_id
]
=
source_gadget
[
source_method_id
];
source_gadget
[
source_method_id
]
=
createMethodInteraction
(
original_source_method_id
,
source_gadget_id
,
source_method_id
,
destination_gadget_id
,
destination_method_id
);
// we use html custom events for asyncronous method call so
// bind destination_gadget to respective event
destination_gadget
.
dom
.
bind
(
source_method_id
,
createTriggerInteraction
(
destination_gadget_id
,
destination_method_id
)
);
}
else
{
// this is a custom event attached to HTML gadget
// representation
source_gadget
.
dom
.
bind
(
source_method_id
,
createTriggerInteraction
(
destination_gadget_id
,
destination_method_id
)
);
}
});
}
};
}()),
bind
:
function
(
gadget_dom
)
{
RouteGadget
:
(
function
()
{
/*
/*
* Bind event between gadgets.
* A gadget that defines possible routes (i.e. URL changes) between gadgets.
*/
*/
var
gadget_id
,
gadget_connection_list
,
var
route_list
=
[];
createMethodInteraction
=
function
(
return
{
original_source_method_id
,
source_gadget_id
,
source_method_id
,
destination_gadget_id
,
destination_method_id
)
{
var
interaction
=
function
()
{
// execute source method
RenderJs
.
GadgetIndex
.
getGadgetById
(
source_gadget_id
)[
original_source_method_id
].
apply
(
null
,
arguments
);
// call trigger so bind can be asynchronously called
RenderJs
.
GadgetIndex
.
getGadgetById
(
destination_gadget_id
).
dom
.
trigger
(
source_method_id
);
};
return
interaction
;
},
createTriggerInteraction
=
function
(
destination_gadget_id
,
destination_method_id
)
{
var
interaction
=
function
()
{
RenderJs
.
GadgetIndex
.
getGadgetById
(
destination_gadget_id
)[
destination_method_id
].
apply
(
null
,
arguments
);
};
return
interaction
;
};
gadget_id
=
gadget_dom
.
attr
(
"
id
"
);
gadget_connection_list
=
gadget_dom
.
attr
(
"
data-gadget-connection
"
);
gadget_connection_list
=
$
.
parseJSON
(
gadget_connection_list
);
$
.
each
(
gadget_connection_list
,
function
(
key
,
value
)
{
var
source
,
source_gadget_id
,
source_method_id
,
source_gadget
,
destination
,
destination_gadget_id
,
destination_method_id
,
destination_gadget
,
original_source_method_id
;
source
=
value
.
source
.
split
(
"
.
"
);
source_gadget_id
=
source
[
0
];
source_method_id
=
source
[
1
];
source_gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
source_gadget_id
);
destination
=
value
.
destination
.
split
(
"
.
"
);
destination_gadget_id
=
destination
[
0
];
destination_method_id
=
destination
[
1
];
destination_gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
destination_gadget_id
);
if
(
source_gadget
.
hasOwnProperty
(
source_method_id
))
{
// direct javascript use case
original_source_method_id
=
"
original_
"
+
source_method_id
;
source_gadget
[
original_source_method_id
]
=
source_gadget
[
source_method_id
];
source_gadget
[
source_method_id
]
=
createMethodInteraction
(
original_source_method_id
,
source_gadget_id
,
source_method_id
,
destination_gadget_id
,
destination_method_id
);
// we use html custom events for asyncronous method call so
// bind destination_gadget to respective event
destination_gadget
.
dom
.
bind
(
source_method_id
,
createTriggerInteraction
(
destination_gadget_id
,
destination_method_id
)
);
}
else
{
// this is a custom event attached to HTML gadget
// representation
source_gadget
.
dom
.
bind
(
source_method_id
,
createTriggerInteraction
(
destination_gadget_id
,
destination_method_id
)
);
}
});
}
};
}()),
RouteGadget
:
(
function
()
{
init
:
function
()
{
/*
/*
*
A gadget that defines possible routes (i.e. URL changes) between gadgets.
*
Inspect DOM and initialize this gadget
*/
*/
var
route_list
=
[];
$
(
"
div[data-gadget-route]
"
).
each
(
function
(
index
,
element
)
{
return
{
RenderJs
.
RouteGadget
.
route
(
$
(
element
));
});
init
:
function
()
{
},
/*
* Inspect DOM and initialize this gadget
*/
$
(
"
div[data-gadget-route]
"
).
each
(
function
(
index
,
element
)
{
RenderJs
.
RouteGadget
.
route
(
$
(
element
));
});
},
route
:
function
(
gadget_dom
)
{
/*
* Create routes between gadgets.
*/
var
body
=
$
(
"
body
"
),
handler_func
,
priority
,
gadget_route_list
=
gadget_dom
.
attr
(
"
data-gadget-route
"
);
gadget_route_list
=
$
.
parseJSON
(
gadget_route_list
);
$
.
each
(
gadget_route_list
,
function
(
key
,
gadget_route
)
{
handler_func
=
function
()
{
var
gadget_id
=
gadget_route
.
destination
.
split
(
'
.
'
)[
0
],
method_id
=
gadget_route
.
destination
.
split
(
'
.
'
)[
1
],
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
// set gadget value so getSelfGadget can work
setSelfGadget
(
gadget
);
gadget
[
method_id
].
apply
(
null
,
arguments
);
// reset as no longer needed
setSelfGadget
(
undefined
);
};
// add route itself
priority
=
gadget_route
.
priority
;
if
(
priority
===
undefined
)
{
// default is 1 -i.e.first level
priority
=
1
;
}
RenderJs
.
RouteGadget
.
add
(
gadget_route
.
source
,
handler_func
,
priority
);
});
},
add
:
function
(
path
,
handler_func
,
priority
)
{
route
:
function
(
gadget_dom
)
{
/*
/*
* Add a route between path (hashable) and a handler function (part of Gadget's API).
* Create routes between gadgets.
*/
*/
var
body
=
$
(
"
body
"
);
var
body
=
$
(
"
body
"
),
body
handler_func
,
.
route
(
"
add
"
,
path
,
1
)
priority
,
.
done
(
handler_func
);
gadget_route_list
=
gadget_dom
.
attr
(
"
data-gadget-route
"
);
// save locally
gadget_route_list
=
$
.
parseJSON
(
gadget_route_list
);
route_list
.
push
({
"
path
"
:
path
,
$
.
each
(
gadget_route_list
,
function
(
key
,
gadget_route
)
{
"
handler_func
"
:
handler_func
,
handler_func
=
function
()
{
"
priority
"
:
priority
});
var
gadget_id
=
gadget_route
.
destination
.
split
(
'
.
'
)[
0
],
},
method_id
=
gadget_route
.
destination
.
split
(
'
.
'
)[
1
],
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget_id
);
// set gadget value so getSelfGadget can work
setSelfGadget
(
gadget
);
gadget
[
method_id
].
apply
(
null
,
arguments
);
// reset as no longer needed
setSelfGadget
(
undefined
);
};
// add route itself
priority
=
gadget_route
.
priority
;
if
(
priority
===
undefined
)
{
// default is 1 -i.e.first level
priority
=
1
;
}
RenderJs
.
RouteGadget
.
add
(
gadget_route
.
source
,
handler_func
,
priority
);
});
},
go
:
function
(
path
,
handler_func
,
priority
)
{
add
:
function
(
path
,
handler_func
,
priority
)
{
/*
/*
* Go a route.
* Add a route between path (hashable) and a handler function (part of Gadget's API).
*/
*/
var
body
=
$
(
"
body
"
);
var
body
=
$
(
"
body
"
);
body
body
.
route
(
"
go
"
,
path
,
priority
)
.
route
(
"
add
"
,
path
,
1
)
.
fail
(
handler_func
);
.
done
(
handler_func
);
},
// save locally
route_list
.
push
({
"
path
"
:
path
,
"
handler_func
"
:
handler_func
,
"
priority
"
:
priority
});
},
go
:
function
(
path
,
handler_func
,
priority
)
{
/*
* Go a route.
*/
var
body
=
$
(
"
body
"
);
body
.
route
(
"
go
"
,
path
,
priority
)
.
fail
(
handler_func
);
},
remove
:
function
(
path
)
{
remove
:
function
(
path
)
{
/*
/*
* Remove a route.
* Remove a route.
*/
*/
// XXX: implement remove a route when route.js supports it
// XXX: implement remove a route when route.js supports it
},
},
getRouteList
:
function
()
{
getRouteList
:
function
()
{
/*
/*
* Get list of all router
* Get list of all router
*/
*/
return
route_list
;
return
route_list
;
}
}
};
};
}())
}())
};
};
}());
}());
// Define Gadget prototype
// Define Gadget prototype
RenderJs
.
Gadget
.
prototype
.
getId
=
function
()
{
RenderJs
.
Gadget
.
prototype
.
getId
=
function
()
{
...
@@ -915,7 +937,7 @@ RenderJs.Gadget.prototype.remove = function () {
...
@@ -915,7 +937,7 @@ RenderJs.Gadget.prototype.remove = function () {
RenderJs
.
GadgetIndex
.
unregisterGadget
(
this
);
RenderJs
.
GadgetIndex
.
unregisterGadget
(
this
);
// gadget might contain sub gadgets so before remove entire
// gadget might contain sub gadgets so before remove entire
// DOM we must unregister them from GadgetIndex
// DOM we must unregister them from GadgetIndex
this
.
getDom
().
find
(
"
[data-gadget]
"
).
each
(
function
()
{
this
.
getDom
().
find
(
"
[data-gadget]
"
).
each
(
function
()
{
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
$
(
this
).
attr
(
"
id
"
));
gadget
=
RenderJs
.
GadgetIndex
.
getGadgetById
(
$
(
this
).
attr
(
"
id
"
));
RenderJs
.
GadgetIndex
.
unregisterGadget
(
gadget
);
RenderJs
.
GadgetIndex
.
unregisterGadget
(
gadget
);
});
});
...
...
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