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 */
/*global console, require, $, localStorage, document, jIO */
/*jslint evil: true,
white: true
*/
/*jslint evil: true,
indent: 2, maxerr: 3
*/
"
use strict
"
;
/*
* RenderJs - Generic Gadget library renderer.
...
...
@@ -40,8 +40,8 @@ var RENDERJS_ENABLE_IMPLICIT_ROUTE_CREATE = true;
// fallback for IE
if
(
console
===
undefined
||
console
.
log
===
undefined
)
{
var
console
=
{};
console
.
log
=
function
()
{};
var
console
=
{};
console
.
log
=
function
()
{};
}
/**
...
...
@@ -53,7 +53,7 @@ var RenderJs = (function () {
// a variable indicating if current gadget loading is over or not
var
is_ready
=
false
,
current_gadget
;
function
setSelfGadget
(
gadget
)
{
function
setSelfGadget
(
gadget
)
{
/*
* Only used internally to set current gadget being executed.
*/
...
...
@@ -62,826 +62,848 @@ var RenderJs = (function () {
return
{
init
:
function
()
{
/*
* Do all initialization
*/
if
(
RENDERJS_ENABLE_IMPLICIT_GADGET_RENDERING
)
{
RenderJs
.
bootstrap
(
$
(
'
body
'
));
init
:
function
()
{
/*
* Do all initialization
*/
if
(
RENDERJS_ENABLE_IMPLICIT_GADGET_RENDERING
)
{
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
// 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
();
}
});
}
},
bootstrap
:
function
(
root
)
{
/*
* Load all gadgets for this DOM element
* (including recursively contained ones)
*/
var
gadget_id
,
is_gadget
;
gadget_id
=
root
.
attr
(
"
id
"
);
is_gadget
=
root
.
attr
(
"
data-gadget
"
)
!==
undefined
;
// this will make RenderJs fire "ready" event when all gadgets are loaded.
RenderJs
.
setReady
(
false
);
if
(
is_gadget
&&
gadget_id
!==
undefined
)
{
// 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
* (including recursively contained ones)
* Feature test if localStorage is supported
*/
var
gadget_id
,
is_gadget
;
gadget_id
=
root
.
attr
(
"
id
"
);
is_gadget
=
root
.
attr
(
"
data-gadget
"
)
!==
undefined
;
// this will make RenderJs fire "ready" event when all gadgets are loaded.
RenderJs
.
setReady
(
false
);
if
(
is_gadget
&&
gadget_id
!==
undefined
)
{
// bootstart root gadget only if it is indeed a gadget
RenderJs
.
loadGadget
(
root
);
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
);
}
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
;
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
);
});
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
;
},
// Load chilren
gadget_list
.
each
(
function
()
{
RenderJs
.
loadGadget
(
$
(
this
));
});
},
set
:
function
(
cache_id
,
data
)
{
/* Set cache key value */
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
* gadgets.
* This plugin saves within current page namespace.
*/
// 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
;
},
var
namespace
=
{};
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
,
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
;
}
$
(
"
.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
,
gadget_data_source
,
bootstrap
)
{
/*
* add new gadget and render it
*/
var
tab_gadget
;
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
$
.
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"
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
;
});
}
GadgetIndex
:
(
function
()
{
/*
* Generic gadget index placeholder
*/
var
gadget_list
=
[];
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
();
}
},
return
{
isReady
:
function
(
)
{
getGadgetIdListFromDom
:
function
(
dom
)
{
/*
* Get
rendering status
* Get
list of all gadget's ID from DOM
*/
return
is_ready
;
},
setReady
:
function
(
value
)
{
var
gadget_id_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
)
{
/*
*
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
;
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
);
}
if
(
RenderJs
.
GadgetIndex
.
getGadgetById
(
gadget
.
id
)
===
undefined
)
{
// register only if not already added
gadget_list
.
push
(
gadget
);
}
return
is_gadget_list_loaded
;
},
},
updateGadgetData
:
function
(
gadget
)
{
unregisterGadget
:
function
(
gadget
)
{
/*
* Gadget can be updated from "data-gadget-source" (i.e. a json)
* and "data-gadget-handler" attributes (i.e. a namespace Javascript)
* Unregister gadget
*/
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
;
var
index
=
$
.
inArray
(
gadget
,
gadget_list
);
if
(
index
!==
-
1
)
{
gadget_list
.
splice
(
index
,
1
);
}
return
false
;
},
},
addGadget
:
function
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
gadget_data_source
,
bootstrap
)
{
getGadgetById
:
function
(
gadget_id
)
{
/*
*
add new gadget and render it
*
Get gadget javascript representation by its Id
*/
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
;
},
var
gadget
;
gadget
=
undefined
;
$
(
RenderJs
.
GadgetIndex
.
getGadgetList
()).
each
(
function
(
index
,
value
)
{
if
(
value
.
getId
()
===
gadget_id
)
{
gadget
=
value
;
}
}
);
return
gadget
;
},
Cache
:
(
function
()
{
getRootGadget
:
function
()
{
/*
* Generic cache implementation that can fall back to local
* namespace storage if no "modern" storage like localStorage
* is available
* Return root gadget (always first one in list)
*/
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
;
},
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
);
},
return
this
.
getGadgetList
()[
0
];
},
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
);
}
},
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
)
{
isGadgetListLoaded
:
function
()
{
/*
* Javascript Gadget representation
* Return True if all gadgets were loaded from network or
* cache
*/
this
.
id
=
gadget_id
;
this
.
dom
=
dom
;
this
.
is_ready
=
false
;
},
var
result
;
result
=
true
;
$
(
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
=
[];
return
{
toggleVisibility
:
function
(
visible_dom
)
{
/*
* 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
"
);
},
$
.
each
(
RenderJs
.
GadgetCatalog
.
getGadgetIndexUrlList
(),
function
(
index
,
value
)
{
updateGadgetIndexFromURL
(
value
);
});
},
addNewTabGadget
:
function
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
gadget_data_source
,
bootstrap
)
{
/*
* add new gadget and render it
*/
var
tab_gadget
;
tab_gadget
=
RenderJs
.
addGadget
(
dom_id
,
gadget_id
,
gadget
,
gadget_data_handler
,
gadget_data_source
,
bootstrap
);
setGadgetIndexUrlList
:
function
(
url_list
)
{
/*
* Set list of Gadget Index repositories.
*/
// store in Cache (html5 storage)
RenderJs
.
Cache
.
set
(
cache_id
,
url_list
);
},
// 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
"
));
}
};
}()),
getGadgetIndexUrlList
:
function
()
{
/*
* Get list of Gadget Index repositories.
*/
// get from Cache (html5 storage)
return
RenderJs
.
Cache
.
get
(
cache_id
,
undefined
);
},
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
=
[];
return
{
getGadgetIdListFromDom
:
function
(
dom
)
{
/*
* Get list of all gadget's ID from DOM
*/
var
gadget_id_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
$
.
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
);
}
},
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
()
{
/*
* Return root gadget (always first one in list)
*/
return
this
.
getGadgetList
()[
0
];
},
registerServiceList
:
function
(
gadget
,
service_list
)
{
/*
* Register a service provided by a gadget.
*/
}
};
}()),
isGadgetListLoaded
:
function
()
{
/*
* Return True if all gadgets were loaded from network or
* cache
*/
var
result
;
result
=
true
;
$
(
this
.
getGadgetList
()).
each
(
function
(
index
,
value
)
{
if
(
value
.
isReady
()
===
false
)
{
result
=
false
;
}
}
);
return
result
;
}
};
}()),
InteractionGadget
:
(
function
()
{
/*
* Basic gadget interaction gadget implementation.
*/
return
{
GadgetCatalog
:
(
function
(
)
{
init
:
function
(
force
)
{
/*
* 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
);
});
* Inspect DOM and initialize this gadget
*/
var
dom_list
,
gadget_id
;
if
(
force
===
1
)
{
// we explicitly want to re-init elements even if already this is done before
dom_list
=
$
(
"
div[data-gadget-connection]
"
);
}
else
{
// XXX: improve and save 'bound' on javascript representation of a gadget not DOM
dom_list
=
$
(
"
div[data-gadget-connection]
"
)
.
filter
(
function
()
{
return
$
(
this
).
data
(
"
bound
"
)
!==
true
;
})
.
data
(
'
bound
'
,
true
);
}
dom_list
.
each
(
function
(
index
,
element
)
{
RenderJs
.
InteractionGadget
.
bind
(
$
(
element
));
});
},
return
{
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
()
{
bind
:
function
(
gadget_dom
)
{
/*
* B
asic gadget interaction gadget implementation
.
* B
ind event between gadgets
.
*/
return
{
init
:
function
(
force
)
{
/*
* Inspect DOM and initialize this gadget
*/
var
dom_list
,
gadget_id
;
if
(
force
===
1
)
{
// we explicitly want to re-init elements even if already this is done before
dom_list
=
$
(
"
div[data-gadget-connection]
"
);
}
else
{
// XXX: improve and save 'bound' on javascript representation of a gadget not DOM
dom_list
=
$
(
"
div[data-gadget-connection]
"
)
.
filter
(
function
()
{
return
$
(
this
).
data
(
"
bound
"
)
!==
true
;
})
.
data
(
'
bound
'
,
true
);
}
dom_list
.
each
(
function
(
index
,
element
)
{
RenderJs
.
InteractionGadget
.
bind
(
$
(
element
));});
},
var
gadget_id
,
gadget_connection_list
,
createMethodInteraction
=
function
(
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
)
);
}
});
}
};
}()),
bind
:
function
(
gadget_dom
)
{
/*
* Bind event between gadgets.
*/
var
gadget_id
,
gadget_connection_list
,
createMethodInteraction
=
function
(
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
()
{
/*
* A gadget that defines possible routes (i.e. URL changes) between gadgets.
*/
var
route_list
=
[];
return
{
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
=
[];
return
{
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
);
});
},
$
(
"
div[data-gadget-route]
"
).
each
(
function
(
index
,
element
)
{
RenderJs
.
RouteGadget
.
route
(
$
(
element
));
});
},
add
:
function
(
path
,
handler_func
,
priority
)
{
/*
* Add a route between path (hashable) and a handler function (part of Gadget's API).
*/
var
body
=
$
(
"
body
"
);
body
.
route
(
"
add
"
,
path
,
1
)
.
done
(
handler_func
);
// save locally
route_list
.
push
({
"
path
"
:
path
,
"
handler_func
"
:
handler_func
,
"
priority
"
:
priority
});
},
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
);
});
},
go
:
function
(
path
,
handler_func
,
priority
)
{
/*
* Go a route.
*/
var
body
=
$
(
"
body
"
);
body
.
route
(
"
go
"
,
path
,
priority
)
.
fail
(
handler_func
);
},
add
:
function
(
path
,
handler_func
,
priority
)
{
/*
* Add a route between path (hashable) and a handler function (part of Gadget's API).
*/
var
body
=
$
(
"
body
"
);
body
.
route
(
"
add
"
,
path
,
1
)
.
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 a route.
*/
remove
:
function
(
path
)
{
/*
* 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
()
{
/*
* Get list of all router
*/
return
route_list
;
}
};
}())
getRouteList
:
function
()
{
/*
* Get list of all router
*/
return
route_list
;
}
};
}())
};
}());
}());
// Define Gadget prototype
RenderJs
.
Gadget
.
prototype
.
getId
=
function
()
{
...
...
@@ -915,7 +937,7 @@ RenderJs.Gadget.prototype.remove = function () {
RenderJs
.
GadgetIndex
.
unregisterGadget
(
this
);
// gadget might contain sub gadgets so before remove entire
// 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
"
));
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