Add JS files

This commit is contained in:
2025-05-12 15:45:17 +00:00
parent 7ddd15c4fa
commit 967007b0c7
3239 changed files with 1157078 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
function Get_Cookie(name) {
var start = document.cookie.indexOf(name + '=');
var len = start + name.length + 1;
if ((!start) && (name != document.cookie.substring(0,name.length)))
return null;
if (start == -1)
return null;
var end = document.cookie.indexOf(';',len);
if (end == -1) end = document.cookie.length;
if(end == start){
return '';
}
return unescape(document.cookie.substring(len,end));
}
function Set_Cookie( name, value, expires, path, domain, secure )
{
// set time, it's in milliseconds
var today = new Date();
today.setTime( today.getTime() );
/*
if the expires variable is set, make the correct
expires time, the current script below will set
it for x number of days, to make it for hours,
delete * 24, for minutes, delete * 60 * 24
*/
if ( expires )
{
expires = expires * 1000 * 60 * 60 * 24;
}
var expires_date = new Date( today.getTime() + (expires) );
document.cookie = name + "=" +escape( value ) +
( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) +
( ( path ) ? ";path=" + path : "" ) +
( ( domain ) ? ";domain=" + domain : "" ) +
( ( secure ) ? ";secure" : "" );
}
function Delete_Cookie(name,path,domain) {
if (Get_Cookie(name))
document.cookie =
name + '=' +
( (path) ? ';path=' + path : '') +
( (domain) ? ';domain=' + domain : '') +
';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}
/*
returns an array of cookie values from a single cookie
*/
function get_sub_cookies(cookie){
var cookies = new Array();
var end ='';
if(cookie && cookie != ''){
end = cookie.indexOf('#')
while(end > -1){
var cur = cookie.substring(0, end);
cookie = cookie.substring(end + 1, cookie.length);
var name = cur.substring(0, cur.indexOf('='));
var value = cur.substring(cur.indexOf('=') + 1, cur.length);
cookies[name] = value;
end = cookie.indexOf('#')
}
}
return cookies;
}
function subs_to_cookie(cookies){
var cookie = '';
for (var i in cookies)
{
if (typeof(cookies[i]) != "function") {
cookie += i + '=' + cookies[i] + '#';
}
}
return cookie;
}

View File

@@ -0,0 +1,81 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
SUGAR.dashlets = function() {
return {
/**
* Generic javascript method to use post a form
*
* @param object theForm pointer to the form object
* @param function callback function to call after for form is sent
*
* @return bool false
*/
postForm: function(theForm, callback) {
var success = function(data) {
if(data) {
callback(data.responseText);
}
}
YAHOO.util.Connect.setForm(theForm);
var cObj = YAHOO.util.Connect.asyncRequest('POST', 'index.php', {success: success, failure: success});
return false;
},
/**
* Generic javascript method to use Dashlet methods
*
* @param string dashletId Id of the dashlet being call
* @param string methodName method to be called (function in the dashlet class)
* @param string postData data to send (eg foo=bar&foo2=bar2...)
* @param bool refreshAfter refreash the dashlet after sending data
* @param function callback function to be called after dashlet is refreshed (or not refresed)
*/
callMethod: function(dashletId, methodName, postData, refreshAfter, callback) {
ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_SAVING'));
response = function(data) {
ajaxStatus.hideStatus();
if(refreshAfter) SUGAR.mySugar.retrieveDashlet(dashletId);
if(callback) {
callback(data.responseText);
}
}
post = 'to_pdf=1&module=Home&action=CallMethodDashlet&method=' + methodName + '&id=' + dashletId + '&' + postData;
var cObj = YAHOO.util.Connect.asyncRequest('POST','index.php',
{success: response, failure: response}, post);
}
};
}();

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,223 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
//////////////////////////////////////////////////////////////////
// called on the return of a JSON-RPC async request,
// and calls the display() method on the widget registered
// in the registry at the request_id key returned by the server
//////////////////////////////////////////////////////////////////
function method_callback (request_id,rslt,e) {
if(rslt == null) {
return;
}
if(typeof (global_request_registry[request_id]) != 'undefined') {
widget = global_request_registry[request_id][0];
method_name = global_request_registry[request_id][1];
widget[method_name](rslt);
}
}
//////////////////////////////////////////////////
// class: SugarVCalClient
// async retrieval/parsing of vCal freebusy info
//
//////////////////////////////////////////////////
SugarClass.inherit("SugarVCalClient","SugarClass");
function SugarVCalClient() {
this.init();
}
SugarVCalClient.prototype.init = function(){
//this.urllib = importModule("urllib");
}
SugarVCalClient.prototype.load = function(user_id,request_id){
this.user_id = user_id;
// get content at url and declare the callback using anon function:
urllib.getURL('./vcal_server.php?type=vfb&source=outlook&user_id='+user_id,[["Content-Type", "text/plain"]], function (result) {
if (typeof GLOBAL_REGISTRY.freebusy == 'undefined')
{
GLOBAL_REGISTRY.freebusy = new Object();
}
if (typeof GLOBAL_REGISTRY.freebusy_adjusted == 'undefined')
{
GLOBAL_REGISTRY.freebusy_adjusted = new Object();
}
// parse vCal and put it in the registry using the user_id as a key:
GLOBAL_REGISTRY.freebusy[user_id] = SugarVCalClient.parseResults(result.responseText, false);
// parse for current user adjusted vCal
GLOBAL_REGISTRY.freebusy_adjusted[user_id] = SugarVCalClient.parseResults(result.responseText, true);
// now call the display() on the widget registered at request_id:
global_request_registry[request_id][0].display();
})
}
// parse vCal freebusy info and return object
SugarVCalClient.prototype.parseResults = function(textResult, adjusted){
var match = /FREEBUSY.*?\:([\w]+)\/([\w]+)/g;
// datetime = new SugarDateTime();
var result;
var timehash = new Object();
var dst_start;
var dst_end;
if(GLOBAL_REGISTRY.current_user.fields.dst_start == null)
dst_start = '19700101T000000Z';
else
dst_start = GLOBAL_REGISTRY.current_user.fields.dst_start.replace(/ /gi, 'T').replace(/:/gi,'').replace(/-/gi,'') + 'Z';
if(GLOBAL_REGISTRY.current_user.fields.dst_end == null)
dst_end = '19700101T000000Z';
else
dst_end = GLOBAL_REGISTRY.current_user.fields.dst_end.replace(/ /gi, 'T').replace(/:/gi,'').replace(/-/gi,'') + 'Z';
gmt_offset_secs = GLOBAL_REGISTRY.current_user.fields.gmt_offset * 60;
// loop thru all FREEBUSY matches
while(((result= match.exec(textResult))) != null)
{
var startdate;
var enddate;
if(adjusted) {// send back adjusted for current_user
startdate = SugarDateTime.parseAdjustedDate(result[1], dst_start, dst_end, gmt_offset_secs);
enddate = SugarDateTime.parseAdjustedDate(result[2], dst_start, dst_end, gmt_offset_secs);
}
else { // GMT
startdate = SugarDateTime.parseUTCDate(result[1]);
enddate = SugarDateTime.parseUTCDate(result[2]);
}
var startmins = startdate.getUTCMinutes();
// pick the start slot based on the minutes
if ( startmins >= 0 && startmins < 15) {
startdate.setUTCMinutes(0);
}
else if ( startmins >= 15 && startmins < 30) {
startdate.setUTCMinutes(15);
}
else if ( startmins >= 30 && startmins < 45) {
startdate.setUTCMinutes(30);
}
else {
startdate.setUTCMinutes(45);
}
// starting at startdate, create hash of each busy 15 min
// timeslot and store as a key
for(var i=0;i<100;i++)
{
if (startdate.valueOf() < enddate.valueOf())
{
var hash = SugarDateTime.getUTCHash(startdate);
if (typeof (timehash[hash]) == 'undefined')
{
timehash[hash] = 0;
}
timehash[hash] += 1;
startdate = new Date(startdate.valueOf()+(15*60*1000));
}
else
{
break;
}
}
}
return timehash;
}
SugarVCalClient.parseResults = SugarVCalClient.prototype.parseResults;
//////////////////////////////////////////////////
// class: SugarRPCClient
// wrapper around async JSON-RPC client class
//
//////////////////////////////////////////////////
SugarRPCClient.allowed_methods = ['retrieve','query','save','set_accept_status','get_objects_from_module', 'email', 'get_user_array', 'get_full_list'];
SugarClass.inherit("SugarRPCClient","SugarClass");
function SugarRPCClient() {
this.init();
}
/*
* PUT NEW METHODS IN THIS ARRAY:
*/
SugarRPCClient.prototype.allowed_methods = ['retrieve','query','save','set_accept_status', 'get_objects_from_module', 'email', 'get_user_array', 'get_full_list'];
SugarRPCClient.prototype.init = function() {
this._serviceProxy;
this._showError= function (e){
alert("ERROR CONNECTING to: ./index.php?entryPoint=json_server, ERROR:"+e);
}
this.serviceURL = './index.php?entryPoint=json_server';
this._serviceProxy = new jsonrpc.ServiceProxy(this.serviceURL,this.allowed_methods);
}
// send a 3rd argument of value 'true' to make the call synchronous.
// in synchronous mode, the return will be the result.
// in asynchronous mode, the return will be the request_id to map the call-back function to.
SugarRPCClient.prototype.call_method = function(method,args) {
var self=this;
try {
var the_result;
if(arguments.length == 3 && arguments[2] == true) {
// aha! fooled you! this function can be called synchronous!
the_result = this._serviceProxy[method](args);
} else {
// make the call asynchronous
this._serviceProxy[method](args, method_callback);
the_result = this._serviceProxy.httpConn.request_id;
}
return the_result;
} catch(e) {//error before calling server
this._showError(e);
}
}
var global_rpcClient = new SugarRPCClient();

View File

@@ -0,0 +1,774 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
// inline modules, don't do importmodule!
// from file langlite.js
langlite = Module("langlite", "0.3.7", function(mod){
mod.JSONParser=Class("JSONParser", function(publ, supr){
publ.init=function(){
this.libs = {};
}
publ.addLib = function(obj, name, exports){
if(exports == null){
this.libs[name] = obj;
}else{
for(var i=0;i<exports.length;i++){
this.libs[name + "." + exports[i]] = obj[exports[i]];
}
}
}
publ.objToJson=function(obj){
if(obj == null){
return "null";
}else{
return mod.objToJson(obj);
}
}
})
mod.parser = new mod.JSONParser();
/**
Turns JSON code into JavaScript objects.
@param src The source as a String.
*/
mod.jsonToObj=function(src){
return mod.parser.jsonToObj(src);
}
var json_types = new Object();
json_types['object'] = function(obj){
var v=[];
for(attr in obj){
if(typeof obj[attr] != "function"){
v.push('"' + attr + '": ' + mod.objToJson(obj[attr]));
}
}
return "{" + v.join(", ") + "}";
}
json_types['string'] = function(obj){
var s = '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
s = s.replace(/(\n)/g,"\\n");
return s;
}
json_types['number'] = function(obj){
return obj.toString();
}
json_types['boolean'] = function(obj){
return obj.toString();
}
json_types['date'] = function(obj){
var padd=function(s, p){
s=p+s
return s.substring(s.length - p.length)
}
var y = padd(obj.getUTCFullYear(), "0000");
var m = padd(obj.getUTCMonth() + 1, "00");
var d = padd(obj.getUTCDate(), "00");
var h = padd(obj.getUTCHours(), "00");
var min = padd(obj.getUTCMinutes(), "00");
var s = padd(obj.getUTCSeconds(), "00");
var isodate = y + m + d + "T" + h + ":" + min + ":" + s
return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
}
json_types['array'] = function(obj){
var v = [];
for(var i=0;i<obj.length;i++){
v.push(mod.objToJson(obj[i])) ;
}
return "[" + v.join(", ") + "]";
}
mod.objToJson=function(obj){
if ( typeof(obj) == 'undefined')
{
return '';
}
if ( typeof(json_types[typeof(obj)]) == 'undefined')
{
alert('class not defined for toJSON():'+typeof(obj));
}
return json_types[typeof(obj)](obj);
}
mod.test=function(){
try{
print(mod.objToJson(['sds', -12377,-1212.1212, 12, '-2312']));
}catch(e){
print(e.toTraceString());
}
}
})
// from file jsonrpclite.js
jsonrpclite = Module("jsonrpclite", "0.3.2", function(mod){
// SUGARCRM:
var lang = langlite // inline module
// var lang = importModule("langlite");
// END SUGARCRM
var tokens = lang.tokens;
var ObjectBuffer=Class("ObjectBuffer", function(publ, supr){
publ.init=function(){
this.data="";
}
publ.getObjects=function(data){
this.data += data;
var t = new lang.Tokenizer(this.data);
var brCnt= 0;
var objects = [];
var readCnt = 0
while(! t.finished()){
var n = t.next();
if(n.type != tokens.ERR){
if(n.value == "{"){
brCnt+=1;
}else if(n.value == "}"){
brCnt-=1;
if(brCnt==0){
var s = this.data.slice(readCnt, n.pos+1);
readCnt += s.length;
objects.push(s);
}
}
}else{
break;
}
}
this.data = this.data.slice(readCnt);
return objects;
}
})
var nameAllowed=function(name){
return name.match(/^[a-zA-Z]\w*$/) != null;
}
var getMethodByName=function(obj, name){
try{//to get a method by asking the service
obj = obj._getMethodByName(name)
}catch(e){
var names = name.split(".");
for(var i=0;i<names.length;i++){
name = names[i];
if(nameAllowed(name)){
obj = obj[name];
}
}
}
return obj;
}
var Response=Class("Response", function(publ, supr){
publ.init=function(id, result, error){
this.id=id;
this.result = result;
this.error = error;
}
publ._toJSON=function(){
var p = [lang.objToJson(this.id), lang.objToJson(this.result),lang.objToJson(this.error)];
return '{"id":' + p[0] + ', "result":' + p[1] + ', "error":' + p[2] + "}";
}
})
var Request=Class("Request", function(publ, supr){
publ.init=function(id, method, params){
this.id=id;
this.method = method;
this.params = params;
/*
var str = '';
for(hello in this.params)
{
str += "var:"+hello+":"+this.params[hello]+":\n";
}
alert(str);
*/
}
publ._toJSON=function(){
var p = [lang.objToJson(this.id), lang.objToJson(this.method),lang.objToJson(this.params)];
return '{"id":' + p[0] + ', "method":' + p[1] + ', "params":' + p[2] + "}";
}
})
var Notification=Class("Notification", function(publ, supr){
publ.init=function(method, params){
this.method = method;
this.params = params;
}
publ._toJSON=function(){
var p = [lang.objToJson(this.method),lang.objToJson(this.params)];
return '{"method":' + p[0] + ', "params":' + p[1] + "}";
}
})
var ResponseHandler=Class("ResponseHandler", function(publ, supr){
publ.init=function(callback){
this.callback=callback;
}
publ.handleResponse=function(resp){
this.callback(resp.result, resp.error);
}
})
var RPCLib = Class("RPCLib", function(publ, supr){
})
var BaseConnectionHandler = Class("BaseConnectionHandler", function(publ, supr){
publ.init=function(service){
this.service = service;
this.jsonParser = new lang.JSONParser();
this.jsonParser.addLib(new RPCLib(), "rpc", []);
this.respHandlers = [];
this.objBuffer = new ObjectBuffer();
}
publ.addResponseHandler=function(cb){
var id=1;
while(this.respHandlers[""+id] ){
id+=1;
}
id="" + id;
this.respHandlers[id] = new ResponseHandler(cb);
return id;
}
publ.send = function(data){
}
publ.sendNotify = function(name, args){
var n = new Notification(name, args);
n = this.jsonParser.objToJson(n);
this.send(n)
}
publ.sendRequest = function(name, args, callback){
var id = this.addResponseHandler(callback);
var r = new Request(id, name, args);
r = this.jsonParser.objToJson(r);
this.send(r);
}
publ.sendResponse = function(id, result, error){
var r = new Response(id, result, error);
r = this.jsonParser.objToJson(r);
this.send(r);
}
publ.handleRequest = function(req){
var name = req.method;
var params = req.params;
var id=req.id;
if(this.service[name]){
try{
var rslt = this.service[name].apply(this.service,params);
this.sendResponse(id, rslt, null)
}catch(e){
this.sendResponse(id, null, new ApplicationError("" + e))
}
}else{
this.sendResponse(id, null, new MethodNotFound());
}
}
publ.handleNotification = function(notif){
if(this.service[notif.method]){
try{
this.service[notif.method].apply(this.service, notif.params);
}catch(e){
}
}
}
publ.handleResponse = function(resp){
var id=resp.id;
var h = this.respHandlers[id];
h.handleResponse(resp)
delete this.respHandlers[id]
}
publ.handleData = function(data){
var objs = this.objBuffer.getObjects(data);
for(var i=0;i<objs.length;i++){
try{
var obj = this.jsonParser.jsonToObj(objs[i]);
}catch(e){
throw "Not well formed";
}
if(obj.method != null){
if(obj.id != null){
this.handleRequest(new Request(obj.id, obj.method, obj.params));
}else{
this.handleNotification(new Notification(obj.method, obj.params));
}
}else if(obj.id != null){
this.handleResponse(new Response(obj.id, obj.result, obj.error));
}else{
throw "Unknown Data";
}
}
}
})
var SocketConnectionHandler = Class("SocketConnectionHandler", BaseConnectionHandler, function(publ, supr){
publ.init=function(socket, localService){
this.socket = socket;
socket.addEventListener("connectionData", this, false);
supr(this).init( localService);
}
publ.handleEvent=function(evt){
this.handleData(evt.data);
}
publ.send=function(data){
this.socket.send(data);
}
publ.close=function(data){
this.socket.close();
}
})
var HTTPConnectionHandler = Class("HTTPConnectionHandler", BaseConnectionHandler, function(publ, supr){
var urllib;
publ.request_id = 1;
publ.init=function(url, localService){
urllib=importModule("urllib");
this.url = url;
supr(this).init( localService);
}
publ.handleData = function(data){
try{
var obj = JSON.parse(data);
}catch(e){;
throw " Not well formed\n\n" + e + "\n\nResponse from server:\n\n " + data;
}
if(obj.id != null){
return obj;
}else{
throw "Unknown Data (No id property found)";
}
}
publ.sendRequest = function(name, args, callback){
var sync = false;
if(typeof callback != "function"){//see if it is sync
args.push(callback);
sync=true;
}
var data = new Request(this.request_id++, name, args);
// cn: bug 12274 - defend against CSRF
data = JSON.stringify(data); // creates security envelope wrapped JSON object
if(sync){
var rsp = urllib.postURL(this.url, data, [["Content-Type", "text/plain"]]);
rsp = this.handleData(rsp.responseText);
if(rsp.error){
throw rsp.error;
}else{
return rsp.result;
}
}else{//async connection uses the respHandler to handle the repsonse
var self = this;
var request_id = this.request_id;
urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){
try{
rsp = self.handleData(rsp.responseText);
}catch(e){
//callback(null,e);
callback(request_id,null,e);
return;
}
callback(request_id,rsp.result, rsp.error);
//callback(this.request_id,rsp.result, rsp.error);
//callback(rsp.result, rsp.error);
});
}
}
publ.sendNotify = function(name, args){
var data = new Notification(name, args);
data = this.jsonParser.objToJson(data);
urllib.postURL(this.url, data, [["Content-Type", "text/plain"]], function(rsp){});
}
})
var PeerObject=Class("PeerObject", function(publ, supr){
publ.init=function(name, conn){
var fn=function(){
var args=[];
for(var i=0;i<arguments.length;i++){
args[i] = arguments[i];
}
var cb=args.pop();
return conn.sendRequest(name, args, cb);
}
return fn;
}
})
var PeerNotifyObject=Class("PeerNotifyObject", function(publ, supr){
publ.init=function(name, conn){
var fn=function(){
var args=[];
for(var i=0;i<arguments.length;i++){
args[i] = arguments[i];
}
conn.sendNotify(name, args);
}
return fn;
}
})
var BasePeer = Class("BasePeer", function(publ, supr){
publ.init=function(conn, methodNames){
this._conn = conn;
this.notify = new PeerObject("notify", conn);
this._add(methodNames);
}
var setupPeerMethod=function(root, methodName, conn, MethClass){
var names = methodName.split(".");
var obj = root;
for(var n=0;n<names.length-1;n++){
var name = names[n];
if(obj[name]){
obj = obj[name];
}else{
obj[name] = new Object();
obj = obj[name];
}
}
var name = names[names.length-1];
if(obj[name]){
}else{
var mth = new MethClass(methodName, conn);
obj[name] = mth;
}
}
publ._add = function(methodNames){
for(var i=0;i<methodNames.length;i++){
setupPeerMethod(this, methodNames[i], this._conn, PeerObject);
setupPeerMethod(this.notify, methodNames[i], this._conn, PeerNotifyObject);
}
}
})
mod.ServiceProxy = Class("ServiceProxy", BasePeer, function(publ, supr){
publ.init = function(url, methodNames, localService){
var n = url.match(/^jsonrpc:\/\/(.*:\d*)$/);
if(n!=null){//is it json-rpc over TCP protocoll
var hostaddr = n[1];
try{
var socket = createConnection();
}catch(e){
throw "Can't create a socket connection."
}
socket.connect(hostaddr);
supr(this).init( new SocketConnectionHandler(socket, localService), methodNames);
}else{//or is it json-rpc over http
this.httpConn = new HTTPConnectionHandler(url, localService);
supr(this).init( this.httpConn, methodNames);
}
}
})
})
jsolait.baseURL = 'include/jsolait/lib';
urllib = importModule('urllib');
var global_request_registry = new Object();
///////////////////////////////////////////////
// Class SugarClass
// superclass for all Sugar* sub-classes
//
///////////////////////////////////////////////
function SugarClass()
{
// if ( arguments.length > 0 )
this.init();
}
SugarClass.prototype.init = function() {
}
// create inheritance for a class
SugarClass.inherit = function(className,parentClassName) {
var str = className+".prototype = new "+parentClassName+"();";
str += className+".prototype.constructor = "+className+";";
str += className+".superclass = "+parentClassName+".prototype;";
try {
eval(str);
} catch (e) { }
}
var jsolait_baseURL = 'include/jsolait/lib';
var jsonrpc = jsonrpclite; //inline the module
//var jsonrpc = importModule("jsonrpclite");
// Root class of Sugar JS Application:
SugarClass.inherit("SugarContainer","SugarClass");
function SugarContainer(root_div)
{
GLOBAL_REGISTRY.container = this;
this.init(root_div);
}
SugarContainer.prototype.init = function(root_div) {
this.root_div = root_div;
SugarContainer.superclass.init.call(this);
}
SugarContainer.prototype.start = function(root_widget) {
this.root_widget = new root_widget();
this.root_widget.load(this.root_div);
}
var req_count = 0;
//////////////////////////////////////////////////
// class: SugarDateTime
// date and time utilities
//
//////////////////////////////////////////////////
SugarClass.inherit("SugarDateTime","SugarClass");
function SugarDateTime()
{
this.init(root_div);
}
SugarDateTime.prototype.init = function(root_div){
this.root_div = root_div;
}
// return the javascript Date object
// given the Sugar Meetings date_start/time_start or date_end/time_end
SugarDateTime.mysql2jsDateTime = function(mysql_date,mysql_time){
//var match = /(\d{4})-(\d{2})-(\d{2})/;
var match = new RegExp(date_reg_format);
if(((result= match.exec(mysql_date))) == null)
{
return null;
}
var match2 = new RegExp(time_reg_format);
// var match2 = /(\d{2}):(\d{2})/;
if((result2= match2.exec(mysql_time)) == null)
{
result2= [0,0,0,0];
}
var match3 = /^0(\d)/;
if((result3= match3.exec(result2[1])) != null)
{
result2[1] = result3[1];
}
if ( typeof (result2[3]) != 'undefined')
{
if ( result2[3] == 'pm' || result2[3] == 'PM')
{
if (parseInt( result2[1] ) != 12)
{
result2[1] = parseInt( result2[1] ) + 12;
}
}
else if ( result2[1] == 12 ) {
result2[1] = 0;
}
}
return new Date(result[date_reg_positions['Y']],result[date_reg_positions['m']] - 1,result[date_reg_positions['d']],result2[1],result2[2],0,0);
}
// make it a static func
// return the formatted day of the week of the date given a date object
SugarDateTime.prototype.getFormattedDate = function(date_obj) {
var returnDate = '';
var userDateFormat = GLOBAL_REGISTRY['current_user']['fields']['date_time_format']['date'];
var dow = GLOBAL_REGISTRY['calendar_strings']['dom_cal_weekdays_long'][date_obj.getDay()];
var month = date_obj.getMonth() + 1;
month = GLOBAL_REGISTRY['calendar_strings']['dom_cal_month_long'][month];
returnDate = dow;
for(i=0;i<5;i++) {
switch(userDateFormat.charAt(i)) {
case "Y":
returnDate += " " + date_obj.getFullYear();
break;
case "m":
returnDate += " " + month;
break;
case "d":
returnDate += " " + date_obj.getDate();
break;
default:
// cn: use locale's date separator? probably not.
//returnDate += " " + userDateFormat.charAt(i);
}
}
return returnDate;
//return dow+" "+date_obj.getDate()+" "+month+" "+date_obj.getFullYear();
}
SugarDateTime.getFormattedDate = SugarDateTime.prototype.getFormattedDate;
// return the formatted day of the week of the date given a date object
SugarDateTime.prototype.getFormattedDOW = function(date_obj) {
var hour = config.strings.mod_strings.Calendar.dow[date_obj.getDay()];
}
SugarDateTime.getFormattedDOW = SugarDateTime.prototype.getFormattedDOW;
// return the formatted hour of the date given a date object
SugarDateTime.getAMPM = function(date_obj) {
var hour = date_obj.getHour();
var am_pm = 'AM';
if (hour > 12)
{
hour -= 12;
am_pm = 'PM';
}
else if ( hour == 12)
{
am_pm = 'PM';
}
else if (hour == 0)
{
hour = 12;
}
return am_pm;
}
SugarDateTime.getFormattedHour = SugarDateTime.prototype.getFormattedHour;
//mod.SugarDateTime.getFormattedDate = publ.getFormattedDate;
// return the javascript Date object given a vCal UTC string
SugarDateTime.prototype.parseUTCDate = function(date_string) {
var match = /(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z/;
if(((result= match.exec(date_string))) != null)
{
var new_date = new Date(Date.UTC(result[1],result[2] - 1,result[3],result[4],result[5],parseInt(result[6])+time_offset));
return new_date;
}
}
SugarDateTime.parseUTCDate = SugarDateTime.prototype.parseUTCDate;
SugarDateTime.prototype.parseAdjustedDate = function(date_string, dst_start, dst_end, gmt_offset_secs) {
var match = /(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z/;
dst_start_parse = match.exec(dst_start);
dst_end_parse = match.exec(dst_end);
if(dst_start_parse == null || dst_end_parse == null) {
var new_date = new Date(result[1],result[2] - 1,result[3],result[4],result[5],parseInt(result[6]));
new_date = new Date(new_date.getTime() + gmt_offset_secs * 1000);
} else {
dst_start_obj = new Date(dst_start_parse[1],dst_start_parse[2] - 1,dst_start_parse[3],dst_start_parse[4],dst_start_parse[5],parseInt(dst_start_parse[6]));
dst_end_obj = new Date(dst_end_parse[1],dst_end_parse[2] - 1,dst_end_parse[3],dst_end_parse[4],dst_end_parse[5],parseInt(dst_end_parse[6]));
if(((result = match.exec(date_string))) != null)
{
var new_date = new Date(result[1],result[2] - 1,result[3],result[4],result[5],parseInt(result[6]));
var event_ts = new_date.getTime();
var dst_start_ts = dst_start_obj.getTime();
var dst_end_ts = dst_end_obj.getTime();
if(((event_ts >= dst_start_ts || event_ts < dst_end_ts) && dst_start_ts > dst_end_ts)
|| (event_ts >= dst_start_ts && event_ts < dst_end_ts)) {
new_date = new Date(new_date.getTime() + 60 * 60 * 1000);
}
new_date = new Date(new_date.getTime() + gmt_offset_secs * 1000);
}
}
return new_date;
}
SugarDateTime.parseAdjustedDate = SugarDateTime.prototype.parseAdjustedDate;
// create a hash based on a date
SugarDateTime.prototype.getUTCHash = function(startdate){
var month = ( startdate.getUTCMonth() < 10) ? "0"+startdate.getUTCMonth():""+startdate.getUTCMonth();
var day = ( startdate.getUTCDate() < 10) ? "0"+startdate.getUTCDate():""+startdate.getUTCDate();
var hours = ( startdate.getUTCHours() < 10) ? "0"+startdate.getUTCHours():""+startdate.getUTCHours();
var minutes = ( startdate.getUTCMinutes() < 10) ? "0"+startdate.getUTCMinutes():""+startdate.getUTCMinutes();
return startdate.getUTCFullYear()+month+day+hours+minutes;
return startdate.getUTCFullYear()+month+day+hours+minutes;
}
SugarDateTime.getUTCHash = SugarDateTime.prototype.getUTCHash;

View File

@@ -0,0 +1,536 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
var menuStack = new Array();
var hiddenElmStack = new Array();
var currentMenu = null;
var closeMenusDelay = null;
var openMenusDelay = null;
var delayTime = 75; // ms for menu open delay
function eraseTimeout(tId) {
//if (tId != null)
window.clearTimeout(tId);
return null;
}
function tbButtonMouseOverOrig(id){
closeMenusDelay = eraseTimeout(closeMenusDelay);
var menuName = id.replace(/Handle/i,'Menu');
var menu = getLayer(menuName);
//if (menu) menu.className = 'tbButtonMouseOverUp';
if (currentMenu){
closeAllMenus();
}
popupMenu(id, menu);
}
function tbButtonMouseOver(id,top,left,leftOffset){
closeMenusDelay = eraseTimeout(closeMenusDelay);
if (openMenusDelay == null){
openMenusDelay = window.setTimeout("showMenu('"+id+"','"+top+"','"+left+"','"+leftOffset+"')", delayTime);
}
}
function showMenu(id,top,left,leftOffset){
openMenusDelay = eraseTimeout(openMenusDelay);
var menuName = id.replace(/Handle/i,'Menu');
var menu = getLayer(menuName);
//if (menu) menu.className = 'tbButtonMouseOverUp';
if (currentMenu){
closeAllMenus();
}
popupMenu(id, menu, top,left,leftOffset);
}
function showSubMenu(id){
closeMenusDelay = eraseTimeout(closeMenusDelay);
var menuName = id.replace(/Handle/i,'Menu');
var menu = getLayer(menuName);
// if (currentMenu){
// closeMenus();
// }
// popupMenu(id, menu);
popupSubMenu(id, menu);
}
function popupMenu(handleID, menu, top, left, leftOffset){
var bw = checkBrowserWidth();
var menuName = handleID.replace(/Handle/i,'Menu');
var menuWidth = 120;
var imgWidth = document.getElementById(handleID).width;
if (menu){
var menuHandle = getLayer(handleID);
var p=menuHandle;
if (left == "") {
var left = 0;
while(p&&p.tagName.toUpperCase()!='BODY'){
left+=p.offsetLeft;
p=p.offsetParent;
}
left+=parseInt(leftOffset);
}
if (left+menuWidth>bw) {
left = left-menuWidth+imgWidth;
}
setMenuVisible(menu, left, top, false);
}
}
function popupSubMenu(handleID, menu){
if (menu){
var menuHandle = getLayer(handleID);
var p=menuHandle;
//var top = p.offsetHeight, left = 0;
var top = 0, left = p.offsetWidth;
while(p&&p.tagName.toUpperCase()!='BODY'){
top+=p.offsetTop;
left+=p.offsetLeft;
p=p.offsetParent;
}
if (is.ie && is.mac){
top -= 3;
left -= 10;
}
/*
if (menu.isSubMenu){
try{
if (blnNetscape6){
left+=(getLayer(menu.parentid).offsetWidth - 4);
}else{
left+=(getLayer(menu.parentid).clientWidth - 8);
}
}catch(e){
}
}else{
top += menuItem.offsetHeight;
}
*/
//menu.x = left;
//menu.y = top;
setMenuVisible(menu, left, top, true);
//fixWidth(paneID, menu);
}
}
function closeMenusOrig(){
if (currentMenu){
setMenuVisibility(currentMenu, false);
// currentMenu = null;
}
}
function closeSubMenus(handle){
closeMenusDelay = eraseTimeout(closeMenusDelay);
if (menuStack.length > 0){
for (var i = menuStack.length-1; i >=0; i--){
var menu = menuStack[menuStack.length-1];
if (menu.id == handle.getAttribute('parentid')){
currentMenu = menu;
break;
}else{
closeMenu(menu);
//menuStack.pop();
menuPop();
}
}
}
}
function closeMenu(menu){
setMenuVisibility(menu, false);
}
function closeMenusOrig(){
if (menuStack.length > 0){
for (var i = menuStack.length-1; i >=0; i--){
//var menu = menuStack.pop();
var menu = menuPop();
closeMenu(menu);
}
}
currentMenu = null;
}
function closeMenus(){
if (closeMenusDelay == null){
closeMenusDelay = window.setTimeout("closeAllMenus()", delayTime);
}
}
function closeAllMenus(){
closeMenusDelay = eraseTimeout(closeMenusDelay);
if (menuStack.length > 0){
for (var i = menuStack.length-1; i >=0; i--){
//var menu = menuStack.pop();
var menu = menuPop();
closeMenu(menu);
}
}
currentMenu = null;
}
function setMenuVisible(menu, x, y, isSubMenu){
/*
var id = menu.id;
var left=0;
var top=0;
var menuItem = menu.getMenuItemElm();
if (menuItem && menu){
if (menu.isTopMenu){
menuItem.className = 'tbButtonMouseDown';
}
}
*/
if (menu){
//menu.x = left;
//menu.y = top;
if (isSubMenu){
if (menu.getAttribute('parentid') == currentMenu.getAttribute('parentid')){
//menuStack.pop();
menuPop();
setMenuVisibility(currentMenu, false);
}
}else{
//menuStack.pop();
menuPop();
setMenuVisibility(currentMenu, false);
}
currentMenu = menu;
//menuStack.push(menu);
menuPush(menu);
setMenuVisibility(menu, true, x, y);
}
}
function getLayer(layerid){
/*
if (document.layers && layerid){
if (document.layers[layerid]) return document.layers[layerid];
}
if (document.links && layerid){
if (document.links[layerid]) return document.links[layerid];
}
if (document.all && layerid){
if (document.all(layerid)) return document.all(layerid);
}
*/
return document.getElementById(layerid);
}
function setMenuVisibility(menu, on, x, y){
var parent = menu;
if (menu){
/*
menu.visible = on;
setLayer(menu.id, !menu.visible, menu.x, menu.y);
setLayer(menu.id, !menu.visible, 0, 0);
menu.visible = on;
*/
setLayer(menu.id, !on, x, y);
if (is.ie){
if (!on){
if (!menu.getAttribute('parentid')){
showElement("SELECT");
}
}else{
hideElement("SELECT", x, y, menu.offsetWidth, menu.offsetHeight);
}
}
/*
setLayer(menu.id, !menu.visible, 0, 0);
var menuWidth, menuHeight;
var menuLayer = getLayer(menu.id);
if (menuLayer){
if (blnIE55){
menuWidth = menuLayer.clientWidth;
menuHeight = menuLayer.clientHeight;
}else{
menuWidth = menuLayer.offsetWidth;
menuHeight = menuLayer.offsetHeight;
}
if (menu.x+menuWidth > clientWindowWidth){
menu.x = clientWindowWidth - menuWidth - 25;
if (menu.x < 10){
menu.x = 10;
}
}
if (menu.y+menuHeight > clientWindowHeight){
menu.y = clientWindowHeight - menuHeight - 25;
if (menu.y < 10){
menu.y = 10;
}
}
setLayer(menu.id, !menu.visible, menu.x, menu.y);
}
*/
}
/*
var parentid = menu.parentid;
while (parentid){
parent = getMenu(menu.paneID, parentid);
if (parent){
parent.visible = on;
setLayer(parent.id, !parent.visible, parent.x, parent.y);
parentid = parent.parentid;
if (on == false) currentMenu = parent;
}else{
parentid = null;
}
}
}
return parent;
*/
}
function menuPop(){
if (is.ie && (is.mac || !is.ie5_5up)){
var menu = menuStack[menuStack.length-1];
var newMenuStack = new Array();
for (var i = 0; i < menuStack.length-1; i++){
newMenuStack[newMenuStack.length] = menuStack[i];
}
menuStack = newMenuStack;
return menu;
}else{
return menuStack.pop();
}
}
function menuPush(menu){
if (is.ie && (is.mac || !is.ie5_5up)){
menuStack[menuStack.length] = menu;
}else{
menuStack.push(menu);
}
}
function checkBrowserWidth(){
var windowWidth;
if (is.ie){
windowWidth = document.body.clientWidth;
}else{
// 17px for scrollbar width
windowWidth = window.innerWidth - 16;
}
if (windowWidth >= 1000){
showSB('sbContent',true,'sb');
}else{
showSB('sbContent',false,'sb');
}
return windowWidth;
}
function showSB(id, hideit, imgIdPrefix){
setLayer(id, !hideit, -1, -1);
setLayer(imgIdPrefix+'On', !hideit, -1, -1);
setLayer(imgIdPrefix+'Off', hideit, -1, -1);
}
function setLayer(id, hidden, x, y){
var layer = getLayer(id);
setLayerElm(layer, hidden, x, y);
}
function setLayerElm(layer, hideit, x, y){
if (layer && layer.style){
if (hideit){
layer.style.visibility='hidden';
//layer.style.display='none';
}else{
layer.style.display='block';
layer.style.visibility='visible';
}
if (x >=0 && x != ""){
//alert(layer.id+': '+x+', '+y+'\n'+layer.offsetLeft+', '+layer.offsetTop);
//layer.style.left=x;
//layer.style.top=y;
layer.style.left = x+'px';
}
if (y >= 0 && y != "") {
layer.style.top = y+'px';
}
}
}
function hiliteItem(menuItem,changeClass){
closeMenusDelay = eraseTimeout(closeMenusDelay);
if (changeClass=='yes') {
if (menuItem.getAttribute('avid') == 'false'){
menuItem.className = 'menuItemHiliteX';
}else{
menuItem.className = 'menuItemHilite';
}
}
}
function unhiliteItem(menuItem){
closeMenusDelay = eraseTimeout(closeMenusDelay);
if (menuItem.getAttribute('avid') == 'false'){
menuItem.className = 'menuItemX';
}else{
menuItem.className = 'menuItem';
}
}
function showElement(elmID){
for (i = 0; i < document.getElementsByTagName(elmID).length; i++) {
obj = document.getElementsByTagName(elmID)[i];
if (! obj || ! obj.offsetParent)
continue;
obj.style.visibility = "";
}
}
function showElementNew(elmID){
if (hiddenElmStack.length > 0){
for (var i = hiddenElmStack.length-1; i >=0; i--){
var obj = hiddenElmStack[hiddenElmStack.length-1];
obj.style.visibility = "";;
hiddenElmStack.pop();
}
}
}
function hideElement(elmID,x,y,w,h){
for (i = 0; i < document.getElementsByTagName(elmID).length; i++){
obj = document.getElementsByTagName(elmID)[i];
if (! obj || ! obj.offsetParent)
continue;
// Find the element's offsetTop and offsetLeft relative to the BODY tag.
objLeft = obj.offsetLeft;
objTop = obj.offsetTop;
objParent = obj.offsetParent;
while (objParent.tagName.toUpperCase() != "BODY"){
objLeft += objParent.offsetLeft;
objTop += objParent.offsetTop;
if(objParent.offsetParent == null)
break;
else
objParent = objParent.offsetParent;
}
// Adjust the element's offsetTop relative to the dropdown menu
objTop = objTop - y;
if (x > (objLeft + obj.offsetWidth) || objLeft > (x + w))
;
else if (objTop > h)
;
else if ((y + h) <= 80)
;
else {
obj.style.visibility = "hidden";
//hiddenElmStack.push(obj);
}
}
}
function Is (){
// convert all characters to lowercase to simplify testing
var agt = navigator.userAgent.toLowerCase();
// *** BROWSER VERSION ***
// Note: On IE5, these return 4, so use is.ie5up to detect IE5.
this.major = parseInt(navigator.appVersion);
this.minor = parseFloat(navigator.appVersion);
// Note: Opera and WebTV spoof Navigator. We do strict client detection.
// If you want to allow spoofing, take out the tests for opera and webtv.
this.nav = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
&& (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
&& (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
this.nav2 = (this.nav && (this.major == 2));
this.nav3 = (this.nav && (this.major == 3));
this.nav4 = (this.nav && (this.major == 4));
this.nav4up = (this.nav && (this.major >= 4));
this.navonly = (this.nav && ((agt.indexOf(";nav") != -1) ||
(agt.indexOf("; nav") != -1)) );
this.nav6 = (this.nav && (this.major == 5));
this.nav6up = (this.nav && (this.major >= 5));
this.gecko = (agt.indexOf('gecko') != -1);
this.nav7 = (this.gecko && (this.major >= 5) && (agt.indexOf('netscape/7')!=-1));
this.moz1 = false;
this.moz1up = false;
this.moz1_1 = false;
this.moz1_1up = false;
if (this.nav6up){
// if (this.nav){
myRegEx = new RegExp("rv:\\d*.\\d*.\\d*");
//myFind = myRegEx.exec("; rv:9.10.5)");
myFind = myRegEx.exec(agt);
if(myFind!=null){
var strVersion = myFind.toString();
strVersion = strVersion.replace(/rv:/,'');
var arrVersion = strVersion.split('.');
var major = parseInt(arrVersion[0]);
var minor = parseInt(arrVersion[1]);
if (arrVersion[2]) var revision = parseInt(arrVersion[2]);
this.moz1 = ((major == 1) && (minor == 0));
this.moz1up = ((major == 1) && (minor >= 0));
this.moz1_1 = ((major == 1) && (minor == 1));
this.moz1_1up = ((major == 1) && (minor >= 1));
}
}
this.ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
this.ie3 = (this.ie && (this.major < 4));
this.ie4 = (this.ie && (this.major == 4) && (agt.indexOf("msie 4")!=-1) );
this.ie4up = (this.ie && (this.major >= 4));
this.ie5 = (this.ie && (this.major == 4) && (agt.indexOf("msie 5.0")!=-1) );
this.ie5_5 = (this.ie && (this.major == 4) && (agt.indexOf("msie 5.5") !=-1));
this.ie5up = (this.ie && !this.ie3 && !this.ie4);
this.ie5_5up =(this.ie && !this.ie3 && !this.ie4 && !this.ie5);
this.ie6 = (this.ie && (this.major == 4) && (agt.indexOf("msie 6.")!=-1) );
this.ie6up = (this.ie && !this.ie3 && !this.ie4 && !this.ie5 && !this.ie5_5);
this.mac = (agt.indexOf("mac") != -1);
}
function runPageLoadItems (){
var myVar;
checkBrowserWidth();
}
var is = new Is();
if (is.ie) {
document.write('<style type="text/css">');
document.write('body {font-size: x-small;}');
document.write ('</style>');
}

View File

@@ -0,0 +1,782 @@
/*
Artistic License 2.0
Copyright (c) 2000-2006, The Perl Foundation.
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software.
You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement.
Definitions
"Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package.
"Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures.
"You" and "your" means any person who would like to copy, distribute, or modify the Package.
"Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version.
"Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization.
"Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees.
"Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder.
"Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder.
"Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future.
"Source" form means the source code, documentation source, and configuration files for the Package.
"Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form.
Permission for Use and Modification Without Distribution
(1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version.
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package.
(3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License.
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following:
(a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version.
(b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version.
(c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under
(i) the Original License or
(ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed.
Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source
(5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license.
(6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version.
Aggregating or Linking the Package
(7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation.
(8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package.
Items That are Not Considered Part of a Modified Version
(9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license.
General Provisions
(10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
(11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
(12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
(13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Do not remove or change this notice.
overlibmws.js core module - Copyright Foteos Macrides 2002-2005. All rights reserved.
Initial: August 18, 2002 - Last Revised: June 8, 2005
This module is subject to the same terms of usage as for Erik Bosrup's overLIB,
though only a minority of the code and API now correspond with Erik's version.
See the overlibmws Change History and Command Reference via:
http://www.macridesweb.com/oltest/
Published under an open source license: http://www.macridesweb.com/oltest/license.html
Give credit on sites that use overlibmws and submit changes so others can use them as well.
You can get Erik's version via: http://www.bosrup.com/web/overlib/
* The name of the Copyright Holder may not be used to endorse or promote products derived
from this software without specific prior written permission.
* THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
A PARTICULAR PURPOSE.
*/
// PRE-INIT -- Ignore these lines, configuration is below.
var OLloaded=0,pmCnt=1,pMtr=new Array(),OLcmdLine=new Array(),OLrunTime=new Array(),OLv,OLudf,
OLpct=new Array("83%","67%","83%","100%","117%","150%","200%","267%"),OLrefXY,
OLbubblePI=0,OLcrossframePI=0,OLdebugPI=0,OLdraggablePI=0,OLexclusivePI=0,OLfilterPI=0,
OLfunctionPI=0,OLhidePI=0,OLiframePI=0,OLovertwoPI=0,OLscrollPI=0,OLshadowPI=0,OLprintPI=0;
if(typeof OLgateOK=='undefined')var OLgateOK=1;
var OLp1or2c='inarray,caparray,caption,closetext,right,left,center,autostatuscap,padx,pady,'
+'below,above,vcenter,donothing',OLp1or2co='nofollow,background,offsetx,offsety,fgcolor,'
+'bgcolor,cgcolor,textcolor,capcolor,width,wrap,wrapmax,height,border,base,status,autostatus,'
+'snapx,snapy,fixx,fixy,relx,rely,midx,midy,ref,refc,refp,refx,refy,fgbackground,bgbackground,'
+'cgbackground,fullhtml,capicon,textfont,captionfont,textsize,captionsize,timeout,delay,hauto,'
+'vauto,nojustx,nojusty,fgclass,bgclass,cgclass,capbelow,textpadding,textfontclass,'
+'captionpadding,captionfontclass,sticky,noclose,mouseoff,offdelay,closecolor,closefont,'
+'closesize,closeclick,closetitle,closefontclass,decode',OLp1or2o='text,cap,close,hpos,vpos,'
+'padxl,padxr,padyt,padyb',OLp1co='label',OLp1or2=OLp1or2co+','+OLp1or2o,OLp1=OLp1co+','+'frame';
OLregCmds(OLp1or2c+','+OLp1or2co+','+OLp1co);
function OLud(v){return eval('typeof ol_'+v+'=="undefined"')?1:0;}
// DEFAULT CONFIGURATION -- See overlibConfig.txt for descriptions
if(OLud('fgcolor'))var ol_fgcolor="#ccccff";
if(OLud('bgcolor'))var ol_bgcolor="#333399";
if(OLud('cgcolor'))var ol_cgcolor="#333399";
if(OLud('textcolor'))var ol_textcolor="#000000";
if(OLud('capcolor'))var ol_capcolor="#ffffff";
if(OLud('closecolor'))var ol_closecolor="#eeeeff";
if(OLud('textfont'))var ol_textfont="Verdana,Arial,Helvetica";
if(OLud('captionfont'))var ol_captionfont="Verdana,Arial,Helvetica";
if(OLud('closefont'))var ol_closefont="Verdana,Arial,Helvetica";
if(OLud('textsize'))var ol_textsize=1;
if(OLud('captionsize'))var ol_captionsize=1;
if(OLud('closesize'))var ol_closesize=1;
if(OLud('fgclass'))var ol_fgclass="";
if(OLud('bgclass'))var ol_bgclass="";
if(OLud('cgclass'))var ol_cgclass="";
if(OLud('textpadding'))var ol_textpadding=2;
if(OLud('textfontclass'))var ol_textfontclass="";
if(OLud('captionpadding'))var ol_captionpadding=2;
if(OLud('captionfontclass'))var ol_captionfontclass="";
if(OLud('closefontclass'))var ol_closefontclass="";
if(OLud('close'))var ol_close="Close";
if(OLud('closeclick'))var ol_closeclick=0;
if(OLud('closetitle'))var ol_closetitle="Click to Close";
if(OLud('text'))var ol_text="Default Text";
if(OLud('cap'))var ol_cap="";
if(OLud('capbelow'))var ol_capbelow=0;
if(OLud('background'))var ol_background="";
if(OLud('width'))var ol_width=200;
if(OLud('wrap'))var ol_wrap=0;
if(OLud('wrapmax'))var ol_wrapmax=0;
if(OLud('height'))var ol_height= -1;
if(OLud('border'))var ol_border=1;
if(OLud('base'))var ol_base=0;
if(OLud('offsetx'))var ol_offsetx=10;
if(OLud('offsety'))var ol_offsety=10;
if(OLud('sticky'))var ol_sticky=0;
if(OLud('nofollow'))var ol_nofollow=0;
if(OLud('noclose'))var ol_noclose=0;
if(OLud('mouseoff'))var ol_mouseoff=0;
if(OLud('offdelay'))var ol_offdelay=300;
if(OLud('hpos'))var ol_hpos=RIGHT;
if(OLud('vpos'))var ol_vpos=BELOW;
if(OLud('status'))var ol_status="";
if(OLud('autostatus'))var ol_autostatus=0;
if(OLud('snapx'))var ol_snapx=0;
if(OLud('snapy'))var ol_snapy=0;
if(OLud('fixx'))var ol_fixx= -1;
if(OLud('fixy'))var ol_fixy= -1;
if(OLud('relx'))var ol_relx=null;
if(OLud('rely'))var ol_rely=null;
if(OLud('midx'))var ol_midx=null;
if(OLud('midy'))var ol_midy=null;
if(OLud('ref'))var ol_ref="";
if(OLud('refc'))var ol_refc='UL';
if(OLud('refp'))var ol_refp='UL';
if(OLud('refx'))var ol_refx=0;
if(OLud('refy'))var ol_refy=0;
if(OLud('fgbackground'))var ol_fgbackground="";
if(OLud('bgbackground'))var ol_bgbackground="";
if(OLud('cgbackground'))var ol_cgbackground="";
if(OLud('padxl'))var ol_padxl=1;
if(OLud('padxr'))var ol_padxr=1;
if(OLud('padyt'))var ol_padyt=1;
if(OLud('padyb'))var ol_padyb=1;
if(OLud('fullhtml'))var ol_fullhtml=0;
if(OLud('capicon'))var ol_capicon="";
if(OLud('frame'))var ol_frame=self;
if(OLud('timeout'))var ol_timeout=0;
if(OLud('delay'))var ol_delay=0;
if(OLud('hauto'))var ol_hauto=0;
if(OLud('vauto'))var ol_vauto=0;
if(OLud('nojustx'))var ol_nojustx=0;
if(OLud('nojusty'))var ol_nojusty=0;
if(OLud('label'))var ol_label="";
if(OLud('decode'))var ol_decode=0;
// ARRAY CONFIGURATION - See overlibConfig.txt for descriptions.
if(OLud('texts'))var ol_texts=new Array("Text 0","Text 1");
if(OLud('caps'))var ol_caps=new Array("Caption 0","Caption 1");
// END CONFIGURATION -- Don't change anything below, all configuration is above.
// INIT -- Runtime variables.
var o3_text="",o3_cap="",o3_sticky=0,o3_nofollow=0,o3_background="",o3_noclose=0,o3_mouseoff=0,
o3_offdelay=300,o3_hpos=RIGHT,o3_offsetx=10,o3_offsety=10,o3_fgcolor="",o3_bgcolor="",
o3_cgcolor="",o3_textcolor="",o3_capcolor="",o3_closecolor="",o3_width=200,o3_wrap=0,
o3_wrapmax=0,o3_height= -1,o3_border=1,o3_base=0,o3_status="",o3_autostatus=0,o3_snapx=0,
o3_snapy=0,o3_fixx= -1,o3_fixy= -1,o3_relx=null,o3_rely=null,o3_midx=null,o3_midy=null,o3_ref="",
o3_refc='UL',o3_refp='UL',o3_refx=0,o3_refy=0,o3_fgbackground="",o3_bgbackground="",
o3_cgbackground="",o3_padxl=0,o3_padxr=0,o3_padyt=0,o3_padyb=0,o3_fullhtml=0,o3_vpos=BELOW,
o3_capicon="",o3_textfont="Verdana,Arial,Helvetica",o3_captionfont="",o3_closefont="",
o3_textsize=1,o3_captionsize=1,o3_closesize=1,o3_frame=self,o3_timeout=0,o3_delay=0,o3_hauto=0,
o3_vauto=0,o3_nojustx=0,o3_nojusty=0,o3_close="",o3_closeclick=0,o3_closetitle="",o3_fgclass="",
o3_bgclass="",o3_cgclass="",o3_textpadding=2,o3_textfontclass="",o3_captionpadding=2,
o3_captionfontclass="",o3_closefontclass="",o3_capbelow=0,o3_label="",o3_decode=0,
CSSOFF=DONOTHING,CSSCLASS=DONOTHING,OLdelayid=0,OLtimerid=0,OLshowid=0,OLndt=0,over=null,
OLfnRef="",OLhover=0,OLx=0,OLy=0,OLshowingsticky=0,OLallowmove=0,OLcC=null,
OLua=navigator.userAgent.toLowerCase(),
OLns4=(navigator.appName=='Netscape'&&parseInt(navigator.appVersion)==4),
OLns6=(document.getElementById)?1:0,
OLie4=(document.all)?1:0,
OLgek=(OLv=OLua.match(/gecko\/(\d{8})/i))?parseInt(OLv[1]):0,
OLmac=(OLua.indexOf('mac')>=0)?1:0,
OLsaf=(OLua.indexOf('safari')>=0)?1:0,
OLkon=(OLua.indexOf('konqueror')>=0)?1:0,
OLkht=(OLsaf||OLkon)?1:0,
OLopr=(OLua.indexOf('opera')>=0)?1:0,
OLop7=(OLopr&&document.createTextNode)?1:0;
if(OLopr){OLns4=OLns6=0;if(!OLop7)OLie4=0;}
var OLieM=((OLie4&&OLmac)&&!(OLkht||OLopr))?1:0,
OLie5=0,OLie55=0;if(OLie4&&!OLop7){
if((OLv=OLua.match(/msie (\d\.\d+)\.*/i))&&(OLv=parseFloat(OLv[1]))>=5.0){
OLie5=1;OLns6=0;if(OLv>=5.5)OLie55=1;}if(OLns6)OLie4=0;}
if(OLns4)window.onresize=function(){location.reload();}
var OLchkMh=1,OLdw;
if(OLns4||OLie4||OLns6)OLmh();
else{overlib=nd=cClick=OLpageDefaults=no_overlib;}
/*
PUBLIC FUNCTIONS
*/
// Loads defaults then args into runtime variables.
function overlib(){
if(!(OLloaded&&OLgateOK))return;
if((OLexclusivePI)&&OLisExclusive(arguments))return true;
if(OLchkMh)OLmh();
if(OLndt&&!OLtimerid)OLndt=0;if(over)cClick();
OLload(OLp1or2);OLload(OLp1);
OLfnRef="";OLhover=0;
OLsetRunTimeVar();
OLparseTokens('o3_',arguments);
if(!(over=OLmkLyr()))return false;
if(o3_decode)OLdecode();
if(OLprintPI)OLchkPrint();
if(OLbubblePI)OLchkForBubbleEffect();
if(OLdebugPI)OLsetDebugCanShow();
if(OLshadowPI)OLinitShadow();
if(OLiframePI)OLinitIfs();
if(OLfilterPI)OLinitFilterLyr();
if(OLexclusivePI&&o3_exclusive&&o3_exclusivestatus!="")o3_status=o3_exclusivestatus;
else if(o3_autostatus==2&&o3_cap!="")o3_status=o3_cap;
else if(o3_autostatus==1&&o3_text!="")o3_status=o3_text;
if(!o3_delay){return OLmain();
}else{OLdelayid=setTimeout("OLmain()",o3_delay);
if(o3_status!=""){self.status=o3_status;return true;}
else if(!(OLop7&&event&&event.type=='mouseover'))return false;}
}
// Clears popups if appropriate
function nd(time){
if(OLloaded&&OLgateOK){if(!((OLexclusivePI)&&OLisExclusive())){
if(time&&over&&!o3_delay){if(OLtimerid>0)clearTimeout(OLtimerid);
OLtimerid=(OLhover&&o3_frame==self&&!OLcursorOff())?0:
setTimeout("cClick()",(o3_timeout=OLndt=time));}else{
if(!OLshowingsticky){OLallowmove=0;if(over)OLhideObject(over);}}}}
return false;
}
// Close function for stickies
function cClick(){
if(OLloaded&&OLgateOK){OLhover=0;if(over){
if(OLovertwoPI&&over==over2)cClick2();OLhideObject(over);OLshowingsticky=0;}}
return false;
}
// Sets page-specific defaults.
function OLpageDefaults(){
OLparseTokens('ol_',arguments);
}
// For unsupported browsers.
function no_overlib(){return false;}
/*
OVERLIB MAIN FUNCTION SET
*/
function OLmain(){
o3_delay=0;
if(o3_frame==self){if(o3_noclose)OLoptMOUSEOFF(0);else if(o3_mouseoff)OLoptMOUSEOFF(1);}
if(o3_sticky)OLshowingsticky=1;OLdoLyr();OLallowmove=0;if(o3_timeout>0){
if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("cClick()",o3_timeout);}
if(o3_ref){OLrefXY=OLgetRefXY(o3_ref);if(OLrefXY[0]==null){o3_ref="";o3_midx=0;o3_midy=0;}}
OLdisp(o3_status);if(OLdraggablePI)OLcheckDrag();
if(o3_status!="")return true;else if(!(OLop7&&event&&event.type=='mouseover'))return false;
}
// Loads o3_ variables
function OLload(c){var i,m=c.split(',');for(i=0;i<m.length;i++)eval('o3_'+m[i]+'=ol_'+m[i]);}
// Chooses LGF
function OLdoLGF(){
return (o3_background!=''||o3_fullhtml)?OLcontentBackground(o3_text,o3_background,o3_fullhtml):
(o3_cap=="")?OLcontentSimple(o3_text):
(o3_sticky)?OLcontentCaption(o3_text,o3_cap,o3_close):OLcontentCaption(o3_text,o3_cap,'');
}
// Makes Layer
function OLmkLyr(id,f,z){
id=(id||'overDiv');f=(f||o3_frame);z=(z||1000);var fd=f.document,d=OLgetRefById(id,fd);
if(!d){if(OLns4)d=fd.layers[id]=new Layer(1024,f);else if(OLie4&&!document.getElementById){
fd.body.insertAdjacentHTML('BeforeEnd','<div id="'+id+'"></div>');d=fd.all[id];
}else{d=fd.createElement('div');if(d){d.id=id;fd.body.appendChild(d);}}if(!d)return null;
if(OLns4)d.zIndex=z;else{var o=d.style;o.position='absolute';o.visibility='hidden';o.zIndex=z;}}
return d;
}
// Creates and writes layer content
function OLdoLyr(){
if(o3_background==''&&!o3_fullhtml){
if(o3_fgbackground!='')o3_fgbackground=' background="'+o3_fgbackground+'"';
if(o3_bgbackground!='')o3_bgbackground=' background="'+o3_bgbackground+'"';
if(o3_cgbackground!='')o3_cgbackground=' background="'+o3_cgbackground+'"';
if(o3_fgcolor!='')o3_fgcolor=' bgcolor="'+o3_fgcolor+'"';
if(o3_bgcolor!='')o3_bgcolor=' bgcolor="'+o3_bgcolor+'"';
if(o3_cgcolor!='')o3_cgcolor=' bgcolor="'+o3_cgcolor+'"';
if(o3_height>0)o3_height=' height="'+o3_height+'"';else o3_height='';}
if(!OLns4)OLrepositionTo(over,(OLns6?20:0),0);var lyrHtml=OLdoLGF();
if(o3_sticky&&OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}
if(o3_wrap&&!o3_fullhtml){OLlayerWrite(lyrHtml);
o3_width=(OLns4?over.clip.width:over.offsetWidth);
if(OLns4&&o3_wrapmax<1)o3_wrapmax=o3_frame.innerWidth-40;
o3_wrap=0;if(o3_wrapmax>0&&o3_width>o3_wrapmax)o3_width=o3_wrapmax;lyrHtml=OLdoLGF();}
OLlayerWrite(lyrHtml);o3_width=(OLns4?over.clip.width:over.offsetWidth);
if(OLbubblePI)OLgenerateBubble(lyrHtml);
}
/*
LAYER GENERATION FUNCTIONS
*/
// Makes simple table without caption
function OLcontentSimple(txt){
var t=OLbgLGF()+OLfgLGF(txt)+OLbaseLGF();
OLsetBackground('');return t;
}
// Makes table with caption and optional close link
function OLcontentCaption(txt,title,close){
var closing=(OLprintPI?OLprintCapLGF():''),closeevent='onmouseover',caption,t,
cC='javascript:return '+OLfnRef+(OLovertwoPI&&over==over2?'cClick2();':'cClick();');
if(o3_closeclick)closeevent=(o3_closetitle?'title="'+o3_closetitle+'" ':'')+'onclick';
if(o3_capicon!='')o3_capicon='<img src="'+o3_capicon+'" /> ';
if(close){closing+='<a href="'+cC+'" '
+closeevent+'="'+cC+'"'+(o3_closefontclass?'>':'>'+OLlgfUtil(0,'','span',o3_closecolor,o3_closefont,o3_closesize))+close
+(o3_closefontclass?'':OLlgfUtil(1,'','span'))+'</a>';}
caption='<table'+OLwd(0)+' border="0" cellpadding="'+o3_captionpadding+'" cellspacing="0"'
+(o3_cgclass?' class="'+o3_cgclass+'"':o3_cgcolor+o3_cgbackground)+'><tr><td'+OLwd(0)
+(o3_cgclass?' class="'+o3_cgclass+'">':'>')+(o3_captionfontclass?'<div class="'
+o3_captionfontclass+'">':''
+OLlgfUtil(0,'','',o3_capcolor,o3_captionfont,o3_captionsize))+o3_capicon+title
+OLlgfUtil(1,'','')+(o3_captionfontclass?'':'')+closing+'</div></td></tr></table>';
t=OLbgLGF()+(o3_capbelow?OLfgLGF(txt)+caption:caption+OLfgLGF(txt))+OLbaseLGF();
OLsetBackground('');return t;
}
// For BACKGROUND and FULLHTML commands
function OLcontentBackground(txt, image, hasfullhtml){
var t;if(hasfullhtml){t=txt;}else{t='<table'+OLwd(1)
+' border="0" cellpadding="0" cellspacing="0" '+'height="'+o3_height
+'"><tr><td colspan="3" height="'+o3_padyt+'"></td></tr><tr><td width="'
+o3_padxl+'"></td><td valign="top"'+OLwd(2)+'>'
+OLlgfUtil(0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+txt+
OLlgfUtil(1,'','div')+'</td><td width="'+o3_padxr+'"></td></tr><tr><td colspan="3" height="'
+o3_padyb+'"></td></tr></table>';}
OLsetBackground(image);return t;
}
// LGF utilities
function OLbgLGF(){
return '<table'+OLwd(1)+o3_height+' border="0" cellpadding="'+o3_border+'" cellspacing="0"'
+(o3_bgclass?' class="'+o3_bgclass+'"':o3_bgcolor+o3_bgbackground)+'><tr><td>';
}
function OLfgLGF(t){
return '<table'+OLwd(0)+o3_height+' border="0" cellpadding="'+o3_textpadding
+'" cellspacing="0"'+(o3_fgclass?' class="'+o3_fgclass+'"':o3_fgcolor+o3_fgbackground)
+'><tr><td valign="top"'+(o3_fgclass?' class="'+o3_fgclass+'"':'')+'>'
+OLlgfUtil(0,o3_textfontclass,'div',o3_textcolor,o3_textfont,o3_textsize)+t
+(OLprintPI?OLprintFgLGF():'')+OLlgfUtil(1,'','div')+'</td></tr></table>';
}
function OLlgfUtil(end,tfc,ele,col,fac,siz){
if(end)return ('</'+(OLns4?'font':ele)+'>');else return (tfc?'<div class="'+tfc+'">':
('<'+(OLns4?'font color="'+col+'" face="'+OLquoteMultiNameFonts(fac)+'" size="'+siz:ele
+' style="color:'+col+';font-family:'+OLquoteMultiNameFonts(fac)+';font-size:'+siz+';'
+(ele=='span'?'text-decoration:underline;':''))+'">'));
}
function OLquoteMultiNameFonts(f){
var i,v,pM=f.split(',');
for(i=0;i<pM.length;i++){v=pM[i];v=v.replace(/^\s+/,'').replace(/\s+$/,'');
if(/\s/.test(v) && !/['"]/.test(v)){v="\'"+v+"\'";pM[i]=v;}} //' extra quote is added for minification work around
return pM.join();
}
function OLbaseLGF(){
return ((o3_base>0&&!o3_wrap)?('<table width="100%" border="0" cellpadding="0" cellspacing="0"'
+(o3_bgclass?' class="'+o3_bgclass+'"':'')+'><tr><td height="'+o3_base
+'"></td></tr></table>'):'')+'</td></tr></table>';
}
function OLwd(a){
return(o3_wrap?'':' width="'+(!a?'100%':(a==1?o3_width:(o3_width-o3_padxl-o3_padxr)))+'"');
}
// Loads image into the div.
function OLsetBackground(i){
if(i==''){if(OLns4)over.background.src=null;
else{if(OLns6)over.style.width='';over.style.backgroundImage='none';}
}else{if(OLns4)over.background.src=i;
else{if(OLns6)over.style.width=o3_width+'px';over.style.backgroundImage='url('+i+')';}}
}
/*
HANDLING FUNCTIONS
*/
// Displays layer
function OLdisp(s){
if(!OLallowmove){if(OLshadowPI)OLdispShadow();if(OLiframePI)OLdispIfs();OLplaceLayer();
if(OLndt)OLshowObject(over);else OLshowid=setTimeout("OLshowObject(over)",1);
OLallowmove=(o3_sticky||o3_nofollow)?0:1;}OLndt=0;if(s!="")self.status=s;
}
// Decides placement of layer.
function OLplaceLayer(){
var snp,X,Y,pgLeft,pgTop,pWd=o3_width,pHt,iWd=100,iHt=100,SB=0,LM=0,CX=0,TM=0,BM=0,CY=0,
o=OLfd(),nsb=(OLgek>=20010505&&!o3_frame.scrollbars.visible)?1:0;
if(!OLkht&&o&&o.clientWidth)iWd=o.clientWidth;
else if(o3_frame.innerWidth){SB=Math.ceil(1.4*(o3_frame.outerWidth-o3_frame.innerWidth));
if(SB>20)SB=20;iWd=o3_frame.innerWidth;}
pgLeft=(OLie4)?o.scrollLeft:o3_frame.pageXOffset;
if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow)SB=CX=5;else
if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){SB+=((o3_shadowx>0)?o3_shadowx:0);
LM=((o3_shadowx<0)?Math.abs(o3_shadowx):0);CX=Math.abs(o3_shadowx);}
if(o3_ref!=""||o3_fixx> -1||o3_relx!=null||o3_midx!=null){
if(o3_ref!=""){X=OLrefXY[0];if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow){
if(o3_refp=='UR'||o3_refp=='LR')X-=5;}
else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowx){
if(o3_shadowx<0&&(o3_refp=='UL'||o3_refp=='LL'))X-=o3_shadowx;else
if(o3_shadowx>0&&(o3_refp=='UR'||o3_refp=='LR'))X-=o3_shadowx;}
}else{if(o3_midx!=null){
X=parseInt(pgLeft+((iWd-pWd-SB-LM)/2)+o3_midx);
}else{if(o3_relx!=null){
if(o3_relx>=0)X=pgLeft+o3_relx+LM;else X=pgLeft+o3_relx+iWd-pWd-SB;
}else{X=o3_fixx+LM;}}}
}else{
if(o3_hauto){
if(o3_hpos==LEFT&&OLx-pgLeft<iWd/2&&OLx-pWd-o3_offsetx<pgLeft+LM)o3_hpos=RIGHT;else
if(o3_hpos==RIGHT&&OLx-pgLeft>iWd/2&&OLx+pWd+o3_offsetx>pgLeft+iWd-SB)o3_hpos=LEFT;}
X=(o3_hpos==CENTER)?parseInt(OLx-((pWd+CX)/2)+o3_offsetx):
(o3_hpos==LEFT)?OLx-o3_offsetx-pWd:OLx+o3_offsetx;
if(o3_snapx>1){
snp=X % o3_snapx;
if(o3_hpos==LEFT){X=X-(o3_snapx+snp);}else{X=X+(o3_snapx-snp);}}}
if(!o3_nojustx&&X+pWd>pgLeft+iWd-SB)
X=iWd+pgLeft-pWd-SB;if(!o3_nojustx&&X-LM<pgLeft)X=pgLeft+LM;
pgTop=OLie4?o.scrollTop:o3_frame.pageYOffset;
if(!OLkht&&!nsb&&o&&o.clientHeight)iHt=o.clientHeight;
else if(o3_frame.innerHeight)iHt=o3_frame.innerHeight;
if(OLbubblePI&&o3_bubble)pHt=OLbubbleHt;else pHt=OLns4?over.clip.height:over.offsetHeight;
if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){TM=(o3_shadowy<0)?Math.abs(o3_shadowy):0;
if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow)BM=CY=5;else
BM=(o3_shadowy>0)?o3_shadowy:0;CY=Math.abs(o3_shadowy);}
if(o3_ref!=""||o3_fixy> -1||o3_rely!=null||o3_midy!=null){
if(o3_ref!=""){Y=OLrefXY[1];if(OLie55&&OLfilterPI&&o3_filter&&o3_filtershadow){
if(o3_refp=='LL'||o3_refp=='LR')Y-=5;}else if((OLshadowPI)&&bkdrop&&o3_shadow&&o3_shadowy){
if(o3_shadowy<0&&(o3_refp=='UL'||o3_refp=='UR'))Y-=o3_shadowy;else
if(o3_shadowy>0&&(o3_refp=='LL'||o3_refp=='LR'))Y-=o3_shadowy;}
}else{if(o3_midy!=null){
Y=parseInt(pgTop+((iHt-pHt-CY)/2)+o3_midy);
}else{if(o3_rely!=null){
if(o3_rely>=0)Y=pgTop+o3_rely+TM;else Y=pgTop+o3_rely+iHt-pHt-BM;}else{
Y=o3_fixy+TM;}}}
}else{
if(o3_vauto){
if(o3_vpos==ABOVE&&OLy-pgTop<iHt/2&&OLy-pHt-o3_offsety<pgTop)o3_vpos=BELOW;else
if(o3_vpos==BELOW&&OLy-pgTop>iHt/2&&OLy+pHt+o3_offsety+((OLns4||OLkht)?17:0)>pgTop+iHt-BM)
o3_vpos=ABOVE;}Y=(o3_vpos==VCENTER)?parseInt(OLy-((pHt+CY)/2)+o3_offsety):
(o3_vpos==ABOVE)?OLy-(pHt+o3_offsety+BM):OLy+o3_offsety+TM;
if(o3_snapy>1){
snp=Y % o3_snapy;
if(pHt>0&&o3_vpos==ABOVE){Y=Y-(o3_snapy+snp);}else{Y=Y+(o3_snapy-snp);}}}
if(!o3_nojusty&&Y+pHt+BM>pgTop+iHt)Y=pgTop+iHt-pHt-BM;if(!o3_nojusty&&Y-TM<pgTop)Y=pgTop+TM;
OLrepositionTo(over,X,Y);
if(OLshadowPI)OLrepositionShadow(X,Y);if(OLiframePI)OLrepositionIfs(X,Y);
if(OLns6&&o3_frame.innerHeight){iHt=o3_frame.innerHeight;OLrepositionTo(over,X,Y);}
if(OLscrollPI)OLchkScroll(X-pgLeft,Y-pgTop);
}
// Chooses body or documentElement
function OLfd(f){
var fd=((f)?f:o3_frame).document,fdc=fd.compatMode,fdd=fd.documentElement;
return (!OLop7&&fdc&&fdc!='BackCompat'&&fdd&&fdd.clientWidth)?fd.documentElement:fd.body;
}
// Gets location of REFerence object
function OLgetRefXY(r){
var o=OLgetRef(r),ob=o,rXY=[o3_refx,o3_refy],of;
if(!o)return [null,null];
if(OLns4){if(typeof o.length!='undefined'&&o.length>1){
ob=o[0];rXY[0]+=o[0].x+o[1].pageX;rXY[1]+=o[0].y+o[1].pageY;
}else{if((o.toString().indexOf('Image')!= -1)||(o.toString().indexOf('Anchor')!= -1)){
rXY[0]+=o.x;rXY[1]+=o.y;}else{rXY[0]+=o.pageX;rXY[1]+=o.pageY;}}
}else{rXY[0]+=OLpageLoc(o,'Left');rXY[1]+=OLpageLoc(o,'Top');}
of=OLgetRefOffsets(ob);rXY[0]+=of[0];rXY[1]+=of[1];
return rXY;
}
function OLgetRef(l){var r=OLgetRefById(l);return (r)?r:OLgetRefByName(l);}
// Seeks REFerence by id
function OLgetRefById(l,d){
var r="",j;l=(l||'overDiv');d=(d||o3_frame.document);
if(OLie4&&d.all){return d.all[l];}else if(d.getElementById){return d.getElementById(l);
}else if(d.layers&&d.layers.length>0){if(d.layers[l])return d.layers[l];
for(j=0;j<d.layers.length;j++){r=OLgetRefById(l,d.layers[j].document);if(r)return r;}}
return null;
}
// Seeks REFerence by name (for img and a)
function OLgetRefByName(l,d){
var r=null,j;d=(d||o3_frame.document);
if(typeof d.images[l]!='undefined'&&d.images[l]){return d.images[l];
}else if(typeof d.anchors[l]!='undefined'&&d.anchors[l]){return d.anchors[l];
}else if(d.layers&&d.layers.length>0){
for(j=0;j<d.layers.length;j++){r=OLgetRefByName(l,d.layers[j].document);
if(r&&r.length>0)return r;else if(r)return [r,d.layers[j]];}}
return null;
}
// Gets layer vs REFerence offsets
function OLgetRefOffsets(o){
var c=o3_refc.toUpperCase(),p=o3_refp.toUpperCase(),W=0,H=0,pW=0,pH=0,of=[0,0];
pW=(OLbubblePI&&o3_bubble)?o3_width:OLns4?over.clip.width:over.offsetWidth;
pH=(OLbubblePI&&o3_bubble)?OLbubbleHt:OLns4?over.clip.height:over.offsetHeight;
if((!OLop7)&&o.toString().indexOf('Image')!= -1){W=o.width;H=o.height;
}else if((!OLop7)&&o.toString().indexOf('Anchor')!= -1){c=o3_refc='UL';}else{
W=(OLns4)?o.clip.width:o.offsetWidth;H=(OLns4)?o.clip.height:o.offsetHeight;}
if((OLns4||(OLns6&&OLgek))&&o.border){W+=2*parseInt(o.border);H+=2*parseInt(o.border);}
if(c=='UL'){of=(p=='UR')?[-pW,0]:(p=='LL')?[0,-pH]:(p=='LR')?[-pW,-pH]:[0,0];
}else if(c=='UR'){of=(p=='UR')?[W-pW,0]:(p=='LL')?[W,-pH]:(p=='LR')?[W-pW,-pH]:[W,0];
}else if(c=='LL'){of=(p=='UR')?[-pW,H]:(p=='LL')?[0,H-pH]:(p=='LR')?[-pW,H-pH]:[0,H];
}else if(c=='LR'){of=(p=='UR')?[W-pW,H]:(p=='LL')?[W,H-pH]:(p=='LR')?[W-pW,H-pH]:
[W,H];}
return of;
}
// Gets x or y location of object
function OLpageLoc(o,t){
var l=0;while(o.offsetParent&&o.offsetParent.tagName.toLowerCase()!='html'){
l+=o['offset'+t];o=o.offsetParent;}l+=o['offset'+t];
return l;
}
// Moves layer
function OLmouseMove(e){
var e=(e||event);
OLcC=(OLovertwoPI&&over2&&over==over2?cClick2:cClick);
OLx=(e.pageX||e.clientX+OLfd().scrollLeft);OLy=(e.pageY||e.clientY+OLfd().scrollTop);
if((OLallowmove&&over)&&(o3_frame==self||over==OLgetRefById())){
OLplaceLayer();if(OLhidePI)OLhideUtil(0,1,1,0,0,0);}
if(OLhover&&over&&o3_frame==self&&OLcursorOff())if(o3_offdelay<1)OLcC();else
{if(OLtimerid>0)clearTimeout(OLtimerid);OLtimerid=setTimeout("OLcC()",o3_offdelay);}
}
// Capture mouse and chain other scripts.
function OLmh(){
var fN,f,j,k,s,mh=OLmouseMove,w=(OLns4&&window.onmousemove),re=/function[ ]*(\w*)\(/;
OLdw=document;if(document.onmousemove||w){if(w)OLdw=window;f=OLdw.onmousemove.toString();
fN=f.match(re);if(!fN||fN[1]=='anonymous'||fN[1]=='OLmouseMove'){OLchkMh=0;return;}
if(fN[1])s=fN[1]+'(e)';else{j=f.indexOf('{');k=f.lastIndexOf('}')+1;s=f.substring(j,k);}
s+=';OLmouseMove(e);';mh=new Function('e',s);}
OLdw.onmousemove=mh;if(OLns4)OLdw.captureEvents(Event.MOUSEMOVE);
}
/*
PARSING
*/
function OLparseTokens(pf,ar){
var i,v,md= -1,par=(pf!='ol_'),p=OLpar,q=OLparQuo,t=OLtoggle;OLudf=(par&&!ar.length?1:0);
for(i=0;i< ar.length;i++){if(md<0){if(typeof ar[i]=='number'){OLudf=(par?1:0);i--;}
else{switch(pf){case 'ol_':ol_text=ar[i];break;default:o3_text=ar[i];}}md=0;
}else{
if(ar[i]==INARRAY){OLudf=0;eval(pf+'text=ol_texts['+ar[++i]+']');continue;}
if(ar[i]==CAPARRAY){eval(pf+'cap=ol_caps['+ar[++i]+']');continue;}
if(ar[i]==CAPTION){q(ar[++i],pf+'cap');continue;}
if(Math.abs(ar[i])==STICKY){t(ar[i],pf+'sticky');continue;}
if(Math.abs(ar[i])==NOFOLLOW){t(ar[i],pf+'nofollow');continue;}
if(ar[i]==BACKGROUND){q(ar[++i],pf+'background');continue;}
if(Math.abs(ar[i])==NOCLOSE){t(ar[i],pf+'noclose');continue;}
if(Math.abs(ar[i])==MOUSEOFF){t(ar[i],pf+'mouseoff');continue;}
if(ar[i]==OFFDELAY){p(ar[++i],pf+'offdelay');continue;}
if(ar[i]==RIGHT||ar[i]==LEFT||ar[i]==CENTER){p(ar[i],pf+'hpos');continue;}
if(ar[i]==OFFSETX){p(ar[++i],pf+'offsetx');continue;}
if(ar[i]==OFFSETY){p(ar[++i],pf+'offsety');continue;}
if(ar[i]==FGCOLOR){q(ar[++i],pf+'fgcolor');continue;}
if(ar[i]==BGCOLOR){q(ar[++i],pf+'bgcolor');continue;}
if(ar[i]==CGCOLOR){q(ar[++i],pf+'cgcolor');continue;}
if(ar[i]==TEXTCOLOR){q(ar[++i],pf+'textcolor');continue;}
if(ar[i]==CAPCOLOR){q(ar[++i],pf+'capcolor');continue;}
if(ar[i]==CLOSECOLOR){q(ar[++i],pf+'closecolor');continue;}
if(ar[i]==WIDTH){p(ar[++i],pf+'width');continue;}
if(Math.abs(ar[i])==WRAP){t(ar[i],pf+'wrap');continue;}
if(ar[i]==WRAPMAX){p(ar[++i],pf+'wrapmax');continue;}
if(ar[i]==HEIGHT){p(ar[++i],pf+'height');continue;}
if(ar[i]==BORDER){p(ar[++i],pf+'border');continue;}
if(ar[i]==BASE){p(ar[++i],pf+'base');continue;}
if(ar[i]==STATUS){q(ar[++i],pf+'status');continue;}
if(Math.abs(ar[i])==AUTOSTATUS){v=pf+'autostatus';
eval(v+'=('+ar[i]+'<0)?('+v+'==2?2:0):('+v+'==1?0:1)');continue;}
if(Math.abs(ar[i])==AUTOSTATUSCAP){v=pf+'autostatus';
eval(v+'=('+ar[i]+'<0)?('+v+'==1?1:0):('+v+'==2?0:2)');continue;}
if(ar[i]==CLOSETEXT){q(ar[++i],pf+'close');continue;}
if(ar[i]==SNAPX){p(ar[++i],pf+'snapx');continue;}
if(ar[i]==SNAPY){p(ar[++i],pf+'snapy');continue;}
if(ar[i]==FIXX){p(ar[++i],pf+'fixx');continue;}
if(ar[i]==FIXY){p(ar[++i],pf+'fixy');continue;}
if(ar[i]==RELX){p(ar[++i],pf+'relx');continue;}
if(ar[i]==RELY){p(ar[++i],pf+'rely');continue;}
if(ar[i]==MIDX){p(ar[++i],pf+'midx');continue;}
if(ar[i]==MIDY){p(ar[++i],pf+'midy');continue;}
if(ar[i]==REF){q(ar[++i],pf+'ref');continue;}
if(ar[i]==REFC){q(ar[++i],pf+'refc');continue;}
if(ar[i]==REFP){q(ar[++i],pf+'refp');continue;}
if(ar[i]==REFX){p(ar[++i],pf+'refx');continue;}
if(ar[i]==REFY){p(ar[++i],pf+'refy');continue;}
if(ar[i]==FGBACKGROUND){q(ar[++i],pf+'fgbackground');continue;}
if(ar[i]==BGBACKGROUND){q(ar[++i],pf+'bgbackground');continue;}
if(ar[i]==CGBACKGROUND){q(ar[++i],pf+'cgbackground');continue;}
if(ar[i]==PADX){p(ar[++i],pf+'padxl');p(ar[++i],pf+'padxr');continue;}
if(ar[i]==PADY){p(ar[++i],pf+'padyt');p(ar[++i],pf+'padyb');continue;}
if(Math.abs(ar[i])==FULLHTML){t(ar[i],pf+'fullhtml');continue;}
if(ar[i]==BELOW||ar[i]==ABOVE||ar[i]==VCENTER){p(ar[i],pf+'vpos');continue;}
if(ar[i]==CAPICON){q(ar[++i],pf+'capicon');continue;}
if(ar[i]==TEXTFONT){q(ar[++i],pf+'textfont');continue;}
if(ar[i]==CAPTIONFONT){q(ar[++i],pf+'captionfont');continue;}
if(ar[i]==CLOSEFONT){q(ar[++i],pf+'closefont');continue;}
if(ar[i]==TEXTSIZE){q(ar[++i],pf+'textsize');continue;}
if(ar[i]==CAPTIONSIZE){q(ar[++i],pf+'captionsize');continue;}
if(ar[i]==CLOSESIZE){q(ar[++i],pf+'closesize');continue;}
if(ar[i]==TIMEOUT){p(ar[++i],pf+'timeout');continue;}
if(ar[i]==DELAY){p(ar[++i],pf+'delay');continue;}
if(Math.abs(ar[i])==HAUTO){t(ar[i],pf+'hauto');continue;}
if(Math.abs(ar[i])==VAUTO){t(ar[i],pf+'vauto');continue;}
if(Math.abs(ar[i])==NOJUSTX){t(ar[i],pf+'nojustx');continue;}
if(Math.abs(ar[i])==NOJUSTY){t(ar[i],pf+'nojusty');continue;}
if(Math.abs(ar[i])==CLOSECLICK){t(ar[i],pf+'closeclick');continue;}
if(ar[i]==CLOSETITLE){q(ar[++i],pf+'closetitle');continue;}
if(ar[i]==FGCLASS){q(ar[++i],pf+'fgclass');continue;}
if(ar[i]==BGCLASS){q(ar[++i],pf+'bgclass');continue;}
if(ar[i]==CGCLASS){q(ar[++i],pf+'cgclass');continue;}
if(ar[i]==TEXTPADDING){p(ar[++i],pf+'textpadding');continue;}
if(ar[i]==TEXTFONTCLASS){q(ar[++i],pf+'textfontclass');continue;}
if(ar[i]==CAPTIONPADDING){p(ar[++i],pf+'captionpadding');continue;}
if(ar[i]==CAPTIONFONTCLASS){q(ar[++i],pf+'captionfontclass');continue;}
if(ar[i]==CLOSEFONTCLASS){q(ar[++i],pf+'closefontclass');continue;}
if(Math.abs(ar[i])==CAPBELOW){t(ar[i],pf+'capbelow');continue;}
if(ar[i]==LABEL){q(ar[++i],pf+'label');continue;}
if(Math.abs(ar[i])==DECODE){t(ar[i],pf+'decode');continue;}
if(ar[i]==DONOTHING){continue;}
i=OLparseCmdLine(pf,i,ar);}}
if((OLfunctionPI)&&OLudf&&o3_function)o3_text=o3_function();
if(pf=='o3_')OLfontSize();
}
function OLpar(a,v){eval(v+'='+a);}
function OLparQuo(a,v){eval(v+"='"+OLescSglQt(a)+"'");}
function OLescSglQt(s){return s.toString().replace(/'/g,"\\'");}
function OLtoggle(a,v){eval(v+'=('+v+'==0&&'+a+'>=0)?1:0');}
function OLhasDims(s){return /[%\-a-z]+$/.test(s);}
function OLfontSize(){
var i;if(OLhasDims(o3_textsize)){if(OLns4)o3_textsize="2";}else
if(!OLns4){i=parseInt(o3_textsize);o3_textsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
if(OLhasDims(o3_captionsize)){if(OLns4)o3_captionsize="2";}else
if(!OLns4){i=parseInt(o3_captionsize);o3_captionsize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
if(OLhasDims(o3_closesize)){if(OLns4)o3_closesize="2";}else
if(!OLns4){i=parseInt(o3_closesize);o3_closesize=(i>0&&i<8)?OLpct[i]:OLpct[0];}
if(OLprintPI)OLprintDims();
}
function OLdecode(){
var re=/%[0-9A-Fa-f]{2,}/,t=o3_text,c=o3_cap,u=unescape,d=!OLns4&&(!OLgek||OLgek>=20020826)
&&typeof decodeURIComponent?decodeURIComponent:u;if(typeof(window.TypeError)=='function'){
if(re.test(t)){eval(new Array('try{','o3_text=d(t);','}catch(e){','o3_text=u(t);',
'}').join('\n'))};if(c&&re.test(c)){eval(new Array('try{','o3_cap=d(c);','}catch(e){',
'o3_cap=u(c);','}').join('\n'))}}else{if(re.test(t))o3_text=u(t);if(c&&re.test(c))o3_cap=u(c);}
}
/*
LAYER FUNCTIONS
*/
// Writes to layer
function OLlayerWrite(t){
t+="\n";
if(OLns4){over.document.write(t);over.document.close();
}else if(typeof over.innerHTML!='undefined'){if(OLieM)over.innerHTML='';over.innerHTML=t;
}else{range=o3_frame.document.createRange();range.setStartAfter(over);
domfrag=range.createContextualFragment(t);
while(over.hasChildNodes()){over.removeChild(over.lastChild);}
over.appendChild(domfrag);}
if(OLprintPI)over.print=o3_print?t:null;
}
// Makes object visible
function OLshowObject(o){
OLshowid=0;o=(OLns4)?o:o.style;
if(((OLfilterPI)&&!OLchkFilter(o))||!OLfilterPI)o.visibility="visible";
if(OLshadowPI)OLshowShadow();if(OLiframePI)OLshowIfs();if(OLhidePI)OLhideUtil(1,1,0);
}
// Hides object
function OLhideObject(o){
if(OLshowid>0){clearTimeout(OLshowid);OLshowid=0;}
if(OLtimerid>0)clearTimeout(OLtimerid);if(OLdelayid>0)clearTimeout(OLdelayid);
OLtimerid=0;OLdelayid=0;self.status="";o3_label=ol_label;
if(o3_frame!=self)o=OLgetRefById();
if(o){if(o.onmouseover)o.onmouseover=null;
if(OLscrollPI&&o==over)OLclearScroll();
if(OLdraggablePI)OLclearDrag();
if(OLfilterPI)OLcleanupFilter(o);if(OLshadowPI)OLhideShadow();
var os=(OLns4)?o:o.style;os.visibility="hidden";
if(OLhidePI&&o==over)OLhideUtil(0,0,1);if(OLiframePI)OLhideIfs(o);}
}
// Moves layer
function OLrepositionTo(o,xL,yL){
o=(OLns4)?o:o.style;
if(o.setAttribute) {
o.setAttribute('left', OLns4?xL:xL+'px');
o.setAttribute('top', OLns4?yL:yL+'px');
} else {
o.left=(OLns4?xL:xL+'px');
o.top=(OLns4?yL:yL+'px');
}
}
// Handle NOCLOSE-MOUSEOFF
function OLoptMOUSEOFF(c){
if(!c)o3_close="";
over.onmouseover=function(){OLhover=1;if(OLtimerid>0){clearTimeout(OLtimerid);OLtimerid=0;}}
}
function OLcursorOff(){
var o=(OLns4?over:over.style),pHt=OLns4?over.clip.height:over.offsetHeight,
left=parseInt(o.left),top=parseInt(o.top),
right=left+o3_width,bottom=top+((OLbubblePI&&o3_bubble)?OLbubbleHt:pHt);
if(OLx<left||OLx>right||OLy<top||OLy>bottom)return true;
return false;
}
/*
REGISTRATION
*/
function OLsetRunTimeVar(){
if(OLrunTime.length)for(var k=0;k<OLrunTime.length;k++)OLrunTime[k]();
}
function OLparseCmdLine(pf,i,ar){
if(OLcmdLine.length){for(var k=0;k<OLcmdLine.length;k++){
var j=OLcmdLine[k](pf,i,ar);if(j>-1){i=j;break;}}}
return i;
}
function OLregCmds(c){
if(typeof c!='string')return;
var pM=c.split(',');pMtr=pMtr.concat(pM);
for(var i=0;i<pM.length;i++)eval(pM[i].toUpperCase()+'='+pmCnt++);
}
function OLregRunTimeFunc(f){
if(typeof f=='object')OLrunTime=OLrunTime.concat(f);
else OLrunTime[OLrunTime.length++]=f;
}
function OLregCmdLineFunc(f){
if(typeof f=='object')OLcmdLine=OLcmdLine.concat(f);
else OLcmdLine[OLcmdLine.length++]=f;
}
OLloaded=1;

View File

@@ -0,0 +1,169 @@
/*
Artistic License 2.0
Copyright (c) 2000-2006, The Perl Foundation.
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software.
You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement.
Definitions
"Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package.
"Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures.
"You" and "your" means any person who would like to copy, distribute, or modify the Package.
"Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version.
"Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization.
"Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees.
"Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder.
"Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder.
"Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future.
"Source" form means the source code, documentation source, and configuration files for the Package.
"Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form.
Permission for Use and Modification Without Distribution
(1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version.
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package.
(3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License.
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following:
(a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version.
(b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version.
(c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under
(i) the Original License or
(ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed.
Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source
(5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license.
(6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version.
Aggregating or Linking the Package
(7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation.
(8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package.
Items That are Not Considered Part of a Modified Version
(9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license.
General Provisions
(10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
(11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
(12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
(13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
overlibmws_iframe.js plug-in module - Copyright Foteos Macrides 2003-2005
Masks system controls to prevent obscuring of popops for IE v5.5 or higher.
Initial: October 19, 2003 - Last Revised: May 15, 2005
See the Change History and Command Reference for overlibmws via:
http://www.macridesweb.com/oltest/
Published under an open source license: http://www.macridesweb.com/oltest/license.html
*/
OLloaded=0;
var OLifsP1=null,OLifsSh=null,OLifsP2=null;
// IFRAME SHIM SUPPORT FUNCTIONS
function OLinitIfs(){
if(!OLie55)return;
if((OLovertwoPI)&&over2&&over==over2){
var o=o3_frame.document.all['overIframeOvertwo'];
if(!o||OLifsP2!=o){OLifsP2=null;OLgetIfsP2Ref();}return;}
o=o3_frame.document.all['overIframe'];
if(!o||OLifsP1!=o){OLifsP1=null;OLgetIfsRef();}
if((OLshadowPI)&&o3_shadow){o=o3_frame.document.all['overIframeShadow'];
if(!o||OLifsSh!=o){OLifsSh=null;OLgetIfsShRef();}}
}
function OLsetIfsRef(o,i,z){
o.id=i;o.src='javascript:false;';o.scrolling='no';var os=o.style;
os.position='absolute';os.top=0;os.left=0;os.width=1;os.height=1;os.visibility='hidden';
os.zIndex=over.style.zIndex-z;os.filter='Alpha(style=0,opacity=0)';
}
function OLgetIfsRef(){
if(OLifsP1||!OLie55)return;
OLifsP1=o3_frame.document.createElement('iframe');
OLsetIfsRef(OLifsP1,'overIframe',2);
o3_frame.document.body.appendChild(OLifsP1);
}
function OLgetIfsShRef(){
if(OLifsSh||!OLie55)return;
OLifsSh=o3_frame.document.createElement('iframe');
OLsetIfsRef(OLifsSh,'overIframeShadow',3);
o3_frame.document.body.appendChild(OLifsSh);
}
function OLgetIfsP2Ref(){
if(OLifsP2||!OLie55)return;
OLifsP2=o3_frame.document.createElement('iframe');
OLsetIfsRef(OLifsP2,'overIframeOvertwo',1);
o3_frame.document.body.appendChild(OLifsP2);
}
function OLsetDispIfs(o,w,h){
var os=o.style;
os.width=w+'px';os.height=h+'px';os.clip='rect(0px '+w+'px '+h+'px 0px)';
o.filters.alpha.enabled=true;
}
function OLdispIfs(){
if(!OLie55)return;
var wd=over.offsetWidth,ht=over.offsetHeight;
if(OLfilterPI&&o3_filter&&o3_filtershadow){wd+=5;ht+=5;}
if((OLovertwoPI)&&over2&&over==over2){
if(!OLifsP2)return;
OLsetDispIfs(OLifsP2,wd,ht);return;}
if(!OLifsP1)return;
OLsetDispIfs(OLifsP1,wd,ht);
if((!OLshadowPI)||!o3_shadow||!OLifsSh)return;
OLsetDispIfs(OLifsSh,wd,ht);
}
function OLshowIfs(){
if(OLifsP1){OLifsP1.style.visibility="visible";
if((OLshadowPI)&&o3_shadow&&OLifsSh)OLifsSh.style.visibility="visible";}
}
function OLhideIfs(o){
if(!OLie55||o!=over)return;
if(OLifsP1)OLifsP1.style.visibility="hidden";
if((OLshadowPI)&&o3_shadow&&OLifsSh)OLifsSh.style.visibility="hidden";
}
function OLrepositionIfs(X,Y){
if(OLie55){if((OLovertwoPI)&&over2&&over==over2){
if(OLifsP2)OLrepositionTo(OLifsP2,X,Y);}
else{if(OLifsP1){OLrepositionTo(OLifsP1,X,Y);if((OLshadowPI)&&o3_shadow&&OLifsSh)
OLrepositionTo(OLifsSh,X+o3_shadowx,Y+o3_shadowy);}}}
}
OLiframePI=1;
OLloaded=1;

View File

@@ -0,0 +1,237 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
function send_back(module, id)
{
var associated_row_data = associated_javascript_data[id];
// cn: bug 12274 - stripping false-positive security envelope
eval("var temp_request_data = " + window.document.forms['popup_query_form'].request_data.value);
if(temp_request_data.jsonObject) {
var request_data = temp_request_data.jsonObject;
} else {
var request_data = temp_request_data; // passed data that is NOT incorrectly encoded via JSON.encode();
}
// cn: end bug 12274 fix
var passthru_data = Object();
if(typeof(request_data.passthru_data) != 'undefined')
{
passthru_data = request_data.passthru_data;
}
var form_name = request_data.form_name;
var field_to_name_array = request_data.field_to_name_array;
var call_back_function = eval("window.opener." + request_data.call_back_function);
var array_contents = Array();
// constructs the array of values associated to the bean that the user clicked
for(var the_key in field_to_name_array)
{
if(the_key != 'toJSON')
{
var the_name = field_to_name_array[the_key];
var the_value = '';
if(module != '' && id != '')
{
if((the_key.toUpperCase() == 'USER_NAME' || the_key.toUpperCase() == 'LAST_NAME' || the_key.toUpperCase() == 'FIRST_NAME') && typeof(is_show_fullname) != 'undefined' && is_show_fullname && form_name != 'search_form') {//if it is from searchform, it will search by assigned_user_name like 'ABC%', then it will return nothing
the_value = associated_row_data['FULL_NAME'];
}
else {
the_value = associated_row_data[the_key.toUpperCase()];
}
}
if (typeof(the_value) == 'string') {
the_value = the_value.replace(/\r\n/g, '\\n');
}
array_contents.push('"' + the_name + '":"' + the_value + '"');
}
}
eval("var name_to_value_array = {" + array_contents.join(",") + "}");
var result_data = {"form_name":form_name,"name_to_value_array":name_to_value_array,"passthru_data":passthru_data};
var close_popup = window.opener.get_close_popup();
call_back_function(result_data);
if(close_popup)
{
window.close();
}
}
function send_back_teams(module, form, field, error_message, request_data, form_team_id) {
var array_contents = Array();
if(form_team_id){
array_contents.push(form_team_id);
}else{
var j=0;
for (i = 0; i < form.elements.length; i++){
if(form.elements[i].name == field) {
if (form.elements[i].checked == true) {
array_contents.push(form.elements[i].value);
}
}
}
}
if (array_contents.length ==0 ) {
window.alert(error_message);
return;
}
var field_to_name_array = request_data.field_to_name_array;
var array_teams = new Array();
for(team_id in array_contents) {
if(typeof array_contents[team_id] == 'string') {
var team = {"team_id" : associated_javascript_data[array_contents[team_id]].ID,
"team_name" : associated_javascript_data[array_contents[team_id]].NAME};
array_teams.push(team);
}
}
var passthru_data = Object();
if(typeof request_data.call_back_function == 'undefined' && typeof request_data == 'object') {
request_data = YAHOO.lang.JSON.parse(request_data.value);
}
if(typeof(request_data.passthru_data) != 'undefined')
{
passthru_data = request_data.passthru_data;
}
var form_name = request_data.form_name;
var field_name = request_data.field_name;
var call_back_function = eval("window.opener." + request_data.call_back_function);
var result_data={"form_name":form_name,"field_name":field_name,"teams":array_teams,"passthru_data":passthru_data};
var close_popup = window.opener.get_close_popup();
call_back_function(result_data);
if(close_popup)
{
window.close();
}
}
function send_back_selected(module, form, field, error_message, request_data)
{
var array_contents = Array();
var j=0;
for (i = 0; i < form.elements.length; i++){
if(form.elements[i].name == field) {
if (form.elements[i].checked == true) {
++j;
array_contents.push('"' + "ID_" + j + '":"' + form.elements[i].value + '"');
}
}
}
if (array_contents.length ==0 ) {
window.alert(error_message);
return;
}
eval("var selection_list_array = {" + array_contents.join(",") + "}");
// cn: bug 12274 - stripping false-positive security envelope
eval("var temp_request_data = " + window.document.forms['popup_query_form'].request_data.value);
if(temp_request_data.jsonObject) {
var request_data = temp_request_data.jsonObject;
} else {
var request_data = temp_request_data; // passed data that is NOT incorrectly encoded via JSON.encode();
}
// cn: end bug 12274 fix
var passthru_data = Object();
if(typeof(request_data.passthru_data) != 'undefined')
{
passthru_data = request_data.passthru_data;
}
var form_name = request_data.form_name;
var field_to_name_array = request_data.field_to_name_array;
var call_back_function = eval("window.opener." + request_data.call_back_function);
var result_data={"form_name":form_name,"selection_list":selection_list_array ,"passthru_data":passthru_data};
var close_popup = window.opener.get_close_popup();
call_back_function(result_data);
if(close_popup)
{
window.close();
}
}
function toggleMore(spanId, img_id, module, action, params){
toggle_more_go = function() {
oReturn = function(body, caption, width, theme) {
return overlib(body, CAPTION, caption, STICKY, MOUSEOFF, 1000, WIDTH, width, CLOSETEXT, ('<img border=0 style="margin-left:2px; margin-right: 2px;" src=themes/' + theme + '/images/close.gif>'), CLOSETITLE, 'Click to Close', CLOSECLICK, FGCLASS, 'olFgClass', CGCLASS, 'olCgClass', BGCLASS, 'olBgClass', TEXTFONTCLASS, 'olFontClass', CAPTIONFONTCLASS, 'olCapFontClass', CLOSEFONTCLASS, 'olCloseFontClass', REF, spanId, REFC, 'LL', REFX, 13);
}
success = function(data) {
eval(data.responseText);
SUGAR.util.additionalDetailsCache[spanId] = new Array();
SUGAR.util.additionalDetailsCache[spanId]['body'] = result['body'];
SUGAR.util.additionalDetailsCache[spanId]['caption'] = result['caption'];
SUGAR.util.additionalDetailsCache[spanId]['width'] = result['width'];
SUGAR.util.additionalDetailsCache[spanId]['theme'] = result['theme'];
ajaxStatus.hideStatus();
return oReturn(SUGAR.util.additionalDetailsCache[spanId]['body'], SUGAR.util.additionalDetailsCache[spanId]['caption'], SUGAR.util.additionalDetailsCache[spanId]['width'], SUGAR.util.additionalDetailsCache[spanId]['theme']);
}
if(typeof SUGAR.util.additionalDetailsCache[spanId] != 'undefined')
return oReturn(SUGAR.util.additionalDetailsCache[spanId]['body'], SUGAR.util.additionalDetailsCache[spanId]['caption'], SUGAR.util.additionalDetailsCache[spanId]['width'], SUGAR.util.additionalDetailsCache[spanId]['theme']);
if(typeof SUGAR.util.additionalDetailsCalls[spanId] != 'undefined') // call already in progress
return;
ajaxStatus.showStatus(SUGAR.language.get('app_strings', 'LBL_LOADING'));
url = 'index.php?module='+module+'&action='+action+'&'+params;
SUGAR.util.additionalDetailsCalls[spanId] = YAHOO.util.Connect.asyncRequest('GET', url, {success: success, failure: success});
return false;
}
SUGAR.util.additionalDetailsRpcCall = window.setTimeout('toggle_more_go()', 250);
}

View File

@@ -0,0 +1,209 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
var popup_request_data;
var close_popup;
function get_popup_request_data()
{
return window.document.popup_request_data;
}
function get_close_popup()
{
return window.document.close_popup;
}
function open_popup(module_name, width, height, initial_filter, close_popup, hide_clear_button, popup_request_data, popup_mode, create, metadata)
{
if (typeof(popupCount) == "undefined" || popupCount == 0)
popupCount = 1;
// set the variables that the popup will pull from
window.document.popup_request_data = popup_request_data;
window.document.close_popup = close_popup;
// launch the popup
URL = 'index.php?'
+ 'module=' + module_name
+ '&action=Popup';
if(initial_filter != '')
{
URL += '&query=true' + initial_filter;
}
if(hide_clear_button)
{
URL += '&hide_clear_button=true';
}
windowName = module_name + '_popup_window' + popupCount;
popupCount++;
windowFeatures = 'width=' + width
+ ',height=' + height
+ ',resizable=1,scrollbars=1';
if (popup_mode == '' && popup_mode == 'undefined') {
popup_mode='single';
}
URL+='&mode='+popup_mode;
if (create == '' && create == 'undefined') {
create = 'false';
}
URL+='&create='+create;
if (metadata != '' && metadata != 'undefined') {
URL+='&metadata='+metadata;
}
win = window.open(URL, windowName, windowFeatures);
if(window.focus)
{
// put the focus on the popup if the browser supports the focus() method
win.focus();
}
win.popupCount = popupCount;
return win;
}
/**
* The reply data must be a JSON array structured with the following information:
* 1) form name to populate
* 2) associative array of input names to values for populating the form
*/
var from_popup_return = false;
function set_return(popup_reply_data)
{
from_popup_return = true;
var form_name = popup_reply_data.form_name;
var name_to_value_array = popup_reply_data.name_to_value_array;
for (var the_key in name_to_value_array)
{
if(the_key == 'toJSON')
{
/* just ignore */
}
else
{
var displayValue=name_to_value_array[the_key].replace(/&amp;/gi,'&').replace(/&lt;/gi,'<').replace(/&gt;/gi,'>').replace(/&#039;/gi,'\'').replace(/&quot;/gi,'"');;
if(window.document.forms[form_name] && window.document.forms[form_name].elements[the_key])
window.document.forms[form_name].elements[the_key].value = displayValue;
}
}
}
function set_return_and_save(popup_reply_data)
{
var form_name = popup_reply_data.form_name;
var name_to_value_array = popup_reply_data.name_to_value_array;
for (var the_key in name_to_value_array)
{
if(the_key == 'toJSON')
{
/* just ignore */
}
else
{
window.document.forms[form_name].elements[the_key].value = name_to_value_array[the_key];
}
}
window.document.forms[form_name].return_module.value = window.document.forms[form_name].module.value;
window.document.forms[form_name].return_action.value = 'DetailView';
window.document.forms[form_name].return_id.value = window.document.forms[form_name].record.value;
window.document.forms[form_name].action.value = 'Save';
window.document.forms[form_name].submit();
}
function set_return_and_save_targetlist(popup_reply_data)
{
var form_name = popup_reply_data.form_name;
var name_to_value_array = popup_reply_data.name_to_value_array;
var form_index = document.forms.length - 1;
sugarListView.get_checks();
var uids = document.MassUpdate.uid.value;
if (uids == '') {
return false;
}
/*
* Add the value returned from the popup to the form for submittal
*/
for (var the_key in name_to_value_array)
{
if(the_key == 'toJSON')
{
/* just ignore */
}
else
{
for ( i = form_index; i >= 0; i--)
{
if ( form_name == window.document.forms[form_index] )
{
form_index = i;
break;
}
}
window.document.forms[form_index].elements[the_key].value = name_to_value_array[the_key];
}
}
window.document.forms[form_index].return_module.value = window.document.forms[form_index].module.value;
window.document.forms[form_index].return_action.value = 'ListView';
window.document.forms[form_index].uids.value = uids;
window.document.forms[form_index].submit();
}
/**
* This is a helper function to construct the initial filter that can be
* passed into the open_popup() function. It assumes that there is an
* account_id and account_name field in the given form_name to use to
* construct the intial filter string.
*/
function get_initial_filter_by_account(form_name)
{
var account_id = window.document.forms[form_name].account_id.value;
var account_name = escape(window.document.forms[form_name].account_name.value);
var initial_filter = "&account_id=" + account_id + "&account_name=" + account_name;
return initial_filter;
}

View File

@@ -0,0 +1,290 @@
JSON = YAHOO.lang.JSON;
SUGAR.quickCompose= {};
SUGAR.quickCompose = function() {
return {
parentPanel : null,
dceMenuPanel : null,
options: null,
loadingMessgPanl : null,
frameLoaded : false,
resourcesLoaded: false,
tinyLoaded : false,
/**
* Get the required compose package in an ajax call required for
* the quick compose.
* @method initComposePackage
* @param {Array} c Options containing compose package and full return url.
* @return {} none
**/
initComposePackage: function(c)
{
//Init fix for YUI 2.7.0 datatable sort.
SUGAR.email2.addressBook.initFixForDatatableSort();
//JS resources must have been loaded if we reach this step.
SUGAR.quickCompose.resourcesLoaded = true;
var callback =
{
success: function(o)
{
var responseData = YAHOO.lang.JSON.parse(o.responseText);
//Create and insert the necessary script tag
var scriptTag = document.createElement('script');
scriptTag.id = 'quickComposeScript';
scriptTag.setAttribute('type','text/javascript');
if(YAHOO.env.ua.ie > 0) //IE hack
scriptTag.text = responseData.jsData;
else //Everybody else
scriptTag.appendChild(document.createTextNode(responseData.jsData));
document.getElementsByTagName("head")[0].appendChild(scriptTag);
//Create and insert the necessary div elements and html markup
var divTag = document.createElement("div");
divTag.innerHTML = responseData.divData;
divTag.id = 'quickCompose';
YAHOO.util.Dom.insertBefore(divTag, 'footer');
//Set the flag that we loaded the compose package.
SUGAR.quickCompose.frameLoaded = true;
//Init the UI
SUGAR.quickCompose.initUI(c.data);
}
}
if(!SUGAR.quickCompose.frameLoaded)
YAHOO.util.Connect.asyncRequest('GET', 'index.php?entryPoint=GenerateQuickComposeFrame', callback, null);
else
SUGAR.quickCompose.initUI(c.data);
},
/**
* Initalize the UI for the quick compose
* the quick compose.
* @method initComposePackage
* @param {Array} options Options containing compose package and full return url.
* @return {} none
**/
initUI: function(options)
{
var SQ = SUGAR.quickCompose;
this.options = options;
//Hide the loading div
loadingMessgPanl.hide();
dce_mode = (typeof this.dceMenuPanel != 'undefined' && this.dceMenuPanel != null) ? true : false;
//Destroy the previous quick compose panel to get a clean slate
if (SQ.parentPanel != null)
{
//First clean up the tinyMCE instance
tinyMCE.execCommand('mceRemoveControl', false, SUGAR.email2.tinyInstances.currentHtmleditor);
SUGAR.email2.tinyInstances[SUGAR.email2.tinyInstances.currentHtmleditor] = null;
SUGAR.email2.tinyInstances.currentHtmleditor = "";
SQ.parentPanel.destroy();
SQ.parentPanel = null;
}
theme = SUGAR.themes.theme_name;
//The quick compose utalizes the EmailUI compose functionality which allows for multiple compose
//tabs. Quick compose always has only one compose screen with an index of 0.
var idx = 0;
//Get template engine with template
if (!SE.composeLayout.composeTemplate)
SE.composeLayout.composeTemplate = new YAHOO.SUGAR.Template(SE.templates['compose']);
panel_modal = dce_mode ? false : true;
panel_width = '880px';
panel_constrain = dce_mode ? false : true;
panel_height = dce_mode ? '450px' : '400px';
panel_shadow = dce_mode ? false : true;
panel_draggable = dce_mode ? false : true;
panel_resize = dce_mode ? false : true;
panel_close = dce_mode ? false : true;
SQ.parentPanel = new YAHOO.widget.Panel("container1", {
modal: panel_modal,
visible: true,
constraintoviewport: panel_constrain,
width : panel_width,
height : panel_height,
shadow : panel_shadow,
draggable : panel_draggable,
resize: panel_resize,
close: panel_close
});
if(!dce_mode) {
SQ.parentPanel.setHeader( SUGAR.language.get('app_strings','LBL_EMAIL_QUICK_COMPOSE')) ;
}
SQ.parentPanel.setBody("<div class='email'><div id='htmleditordiv" + idx + "'></div></div>");
var composePanel = SE.composeLayout.getQuickComposeLayout(SQ.parentPanel,this.options);
if(!dce_mode) {
var resize = new YAHOO.util.Resize('container1', {
handles: ['br'],
autoRatio: false,
minWidth: 400,
minHeight: 350,
status: false
});
resize.on('resize', function(args) {
var panelHeight = args.height;
this.cfg.setProperty("height", panelHeight + "px");
var layout = SE.composeLayout[SE.composeLayout.currentInstanceId];
layout.set("height", panelHeight - 50);
layout.resize(true);
SE.composeLayout.resizeEditor(SE.composeLayout.currentInstanceId);
}, SQ.parentPanel, true);
}
YAHOO.util.Dom.setStyle("container1", "z-index", 1);
if (!SQ.tinyLoaded)
{
//TinyMCE bug, since we are loading the js file dynamically we need to let tiny know that the
//dom event has fired.
tinymce.dom.Event.domLoaded = true;
tinyMCE.init({
convert_urls : false,
theme_advanced_toolbar_align : tinyConfig.theme_advanced_toolbar_align,
width: tinyConfig.width,
theme: tinyConfig.theme,
theme_advanced_toolbar_location : tinyConfig.theme_advanced_toolbar_location,
theme_advanced_buttons1 : tinyConfig.theme_advanced_buttons1,
theme_advanced_buttons2 : tinyConfig.theme_advanced_buttons2,
theme_advanced_buttons3 : tinyConfig.theme_advanced_buttons3,
plugins : tinyConfig.plugins,
elements : tinyConfig.elements,
language : tinyConfig.language,
extended_valid_elements : tinyConfig.extended_valid_elements,
mode: tinyConfig.mode,
strict_loading_mode : true
});
SQ.tinyLoaded = true;
}
SQ.parentPanel.show();
//Re-declare the close function to handle appropriattely.
SUGAR.email2.composeLayout.forceCloseCompose = function(o){SUGAR.quickCompose.parentPanel.hide(); }
if(!dce_mode) {
SQ.parentPanel.center();
}
},
/**
* Display a loading pannel and start retrieving the quick compose requirements.
* @method init
* @param {Array} o Options containing compose package and full return url.
* @return {} none
**/
init: function(o) {
if(typeof o.menu_id != 'undefined') {
this.dceMenuPanel = o.menu_id;
} else {
this.dceMenuPanel = null;
}
loadingMessgPanl = new YAHOO.widget.SimpleDialog('loading', {
width: '200px',
close: true,
modal: true,
visible: true,
fixedcenter: true,
constraintoviewport: true,
draggable: false
});
loadingMessgPanl.setHeader(SUGAR.language.get('app_strings','LBL_EMAIL_PERFORMING_TASK'));
loadingMessgPanl.setBody(SUGAR.language.get('app_strings','LBL_EMAIL_ONE_MOMENT'));
loadingMessgPanl.render(document.body);
loadingMessgPanl.show();
//If JS files havn't been loaded, perform the load.
if(! SUGAR.quickCompose.resourcesLoaded )
this.loadResources(o);
else
this.initUI(o);
},
/**
* Pull in all the required js files.
* @method loadResources
* @param {Array} o Options containing compose package and full return url.
* @return {} none
**/
loadResources: function(o)
{
//IE Bug fix for TinyMCE when pulling in the js file dynamically.
window.skipTinyMCEInitPhase = true;
var require = ["layout", "element", "tabview", "menu","cookie","tinymce","securejson","sugarwidgets","sugarquickcompose","sugarquickcomposecss"];
var loader = new YAHOO.util.YUILoader({
require : require,
loadOptional: true,
skin: { base: 'blank', defaultSkin: '' },
data: o,
onSuccess: this.initComposePackage,
allowRollup: true,
base: "include/javascript/yui/build/"
});
//TiinyMCE cannot be added into the sugar_grp_quickcomp file as it breaks the build, needs to be loaded
//seperately.
loader.addModule({
name :"tinymce",
type : "js",
varName: "TinyMCE",
fullpath: "include/javascript/tiny_mce/tiny_mce.js"
});
loader.addModule({
name :"securejson",
type : "js",
varName: "JSON",
fullpath: "include/JSON.js"
});
//Load the Sugar widgets with dependancies on the yui library.
loader.addModule({
name :"sugarwidgets",
type : "js",
fullpath: "include/javascript/sugarwidgets/SugarYUIWidgets.js",
varName: "YAHOO.SUGAR",
requires: ["datatable", "dragdrop", "treeview", "tabview"]
});
//Load the main components for the quick create compose screen.
loader.addModule({
name :"sugarquickcompose",
type : "js",
varName: "SUGAR.email2.complexLayout",
requires: ["layout", "sugarwidgets", "tinymce"],
fullpath: "include/javascript/sugar_grp_quickcomp.js"
});
//Load the css needed for the quickCompose.
loader.addModule({
name :"sugarquickcomposecss",
type : "css",
fullpath: "modules/Emails/EmailUI.css"
});
loader.insert();
}
};
}();

View File

@@ -0,0 +1,248 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
/**
* browse document for quickSearch fields
* Compatible ExtJS 1.1.1 and ExtJS 2.0
* parameter : noReload - if set to true, enableQS will enable only
* the new sqsEnabled field on the page. If set to false
* it will reload all the sqsEnabled fields.
*/
function enableQS(noReload){
YAHOO.util.Event.onDOMReady(function(){
//Safety check. If sqs_objects variable is null, we really can't do anything useful
if(typeof sqs_objects == 'undefined') {
return;
}
var Dom = YAHOO.util.Dom;
//Get all the fields where sqsEnabled is an attribue, these should be the input text fields for quicksearch
var qsFields = Dom.getElementsByClassName('sqsEnabled');
//Now loop through all these fields and process them
for(qsField in qsFields){
//Safety checks to skip processing of invalid entries
if(typeof qsFields[qsField] == 'function' || typeof qsFields[qsField].id == 'undefined') {
continue;
}
//Create the index we are using to search for the sqs_objects Array
form_id = qsFields[qsField].form.getAttribute('id');
//This is a special case where there is an element with id attribute value of "id"
//In this case, we get the real_id attribute (occurs in modules/Import/tpls/step3.tpl only).
if(typeof form_id == 'object' && qsFields[qsField].form.getAttribute('real_id')) {
form_id = qsFields[qsField].form.getAttribute('real_id');
}
qs_index_id = form_id + '_' + qsFields[qsField].name;
//Another safety check, if the sqs_objects entry is not defined, we can't do anything useful
if(typeof sqs_objects[qs_index_id] == 'undefined') {
qs_index_id = qsFields[qsField].name;
if(typeof sqs_objects[qs_index_id] == 'undefined') {
continue;
}
}
//Track if this field has already been processed. The way the enableQS function is called
//is a bit problematic in that it lends itself to a lot of duplicate processing
if(QSProcessedFieldsArray[qs_index_id]) {
continue;
}
//Store sqs_objects entry as a reference for convenience
var qs_obj = sqs_objects[qs_index_id];
//The loaded variable will be used to check whether or not the quick search field should be created
var loaded = false;
if (!document.forms[qs_obj.form]) {
continue;
}
//Skip quicksearch fields that are readOnly or that are disabled since you can't search on them anyway
if (!document.forms[qs_obj.form].elements[qsFields[qsField].id].readOnly && qs_obj['disable'] != true) {
combo_id = qs_obj.form + '_' + qsFields[qsField].id;
if (Dom.get(combo_id + "_results")) {
loaded = true
}
// if loaded == false, then we do the heavy lifting to re-create the quicksearch field
if (!loaded) {
QSProcessedFieldsArray[qs_index_id] = true;
qsFields[qsField].form_id = form_id;
var sqs = sqs_objects[qs_index_id];
//Initialize the result div
var resultDiv = document.createElement('div');
resultDiv.id = combo_id + "_results";
Dom.insertAfter(resultDiv, qsFields[qsField]);
//Add the module to the fields so we can read it from the response
var fields = qs_obj.field_list.slice();
fields[fields.length] = "module";
//Create the DataSource for this QS
var ds = new YAHOO.util.DataSource("index.php?", {
responseType: YAHOO.util.XHRDataSource.TYPE_JSON,
responseSchema: {
resultsList: 'fields',
total: 'totalCount',
fields: fields,
metaNode: "fields",
metaFields: {total: 'totalCount', fields:"fields"}
},
connMethodPost: true
});
// Don't force selection for search fields
var forceSelect = !((qsFields[qsField].form && typeof(qsFields[qsField].form) == 'object' && qsFields[qsField].form.name == 'search_form')
|| qsFields[qsField].className.match('sqsNoAutofill') != null);
//Finally Declare the Autocomplete
var search = new YAHOO.widget.AutoComplete(qsFields[qsField], resultDiv, ds, {
typeAhead: forceSelect,
forceSelection : forceSelect,
fields: fields,
sqs : sqs,
animSpeed : 0.25,
qs_obj: qs_obj,
//YUI requires the data, even POST, to be URL encoded
generateRequest : function(sQuery) {
var out = SUGAR.util.paramsToUrl({
to_pdf: 'true',
module: 'Home',
action: 'quicksearchQuery',
data: encodeURIComponent(YAHOO.lang.JSON.stringify(this.sqs)),
query: sQuery
});
return out;
},
//Method to fill in form fields with the returned results.
//Should be called on select, and must be called from the AC instance scope.
setFields : function (data, filter) {
for(var i in this.fields) {
for (var key in this.qs_obj.field_list) {
//Check that the field exists and matches the filter
if (this.fields[i] == this.qs_obj.field_list[key] &&
document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]] &&
this.qs_obj.populate_list[key].match(filter)) {
document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = data[i];
}
}
}
},
clearFields : function() {
for (var key in this.qs_obj.field_list) {
if (document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]]){
document.forms[this.qs_obj.form].elements[this.qs_obj.populate_list[key]].value = "";
}
}
this.oldValue = "";
}
});
//fill in the data fields on selection
search.itemSelectEvent.subscribe(function(e, args){
var data = args[2];
var fields = this.fields;
this.setFields(data, /\S/);
//Handle special case where post_onblur_function is set
if (typeof(this.qs_obj['post_onblur_function']) != 'undefined') {
collection_extended = new Array();
for (var i in fields) {
for (var key in this.qs_obj.field_list) {
if (fields[i] == this.qs_obj.field_list[key]) {
collection_extended[this.qs_obj.field_list[key]] = data[i];
}
}
}
eval(this.qs_obj['post_onblur_function'] + '(collection_extended, this.qs_obj.id)');
}
});
// We will get the old value firstly when the field lose focus.
search.textboxFocusEvent.subscribe(function(){
this.oldValue = this.getInputEl().value;
});
//If there is no change for this qucik search field , the value of it will not be cleared.
search.selectionEnforceEvent.subscribe(function(e, args){
if (this.oldValue != args[1]) {
this.clearFields();
} else {
this.getInputEl().value = this.oldValue;
}
});
search.dataReturnEvent.subscribe(function(e, args){
//Selected the first returned value if a tab was done before results were returned
if (this.getInputEl().value.length == 0 && args[2].length > 0) {
var data = [];
for(var key in this.qs_obj.field_list) {
data[data.length] = args[2][0][this.qs_obj.field_list[key]];
}
this.getInputEl().value = data[this.key];
this.itemSelectEvent.fire(this, "", data);
}
});
if (typeof QSFieldsArray[combo_id] == 'undefined' && qsFields[qsField].id) {
QSFieldsArray[combo_id] = search;
}
}
}
}
});
}
function registerSingleSmartInputListener(input) {
if ((c = input.className) && (c.indexOf("sqsEnabled") != -1)) {
enableQS(true);
}
}
if(typeof QSFieldsArray == 'undefined') {
QSFieldsArray = new Array();
QSProcessedFieldsArray = new Array();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
SUGAR_callsInProgress = 0;
YAHOO.util.Connect.completeEvent.subscribe(function(event, data){
SUGAR_callsInProgress--;
if (SUGAR.util.isLoginPage(data[0].conn.responseText))
return false;
});
YAHOO.util.Connect.startEvent.subscribe(function(event, data)
{
SUGAR_callsInProgress++;
});

View File

@@ -0,0 +1,50 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
/**
* @author dwheeler
*/
//Load up the YUI loader and go!
SUGAR.yui = {
loader : new YAHOO.util.YUILoader()
}
SUGAR.yui.loader.addModule({
name:'sugarwidgets',
type:'js',
path:'SugarYUIWidgets.js',
requires:['yahoo', 'layout', 'dragdrop', 'treeview', 'json', 'datatable', 'container', 'button', 'tabview'],
varname: YAHOO.SUGAR
});

View File

@@ -0,0 +1,676 @@
/*********************************************************************************
* SugarCRM is a customer relationship management program developed by
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License version 3 as published by the
* Free Software Foundation with the addition of the following permission added
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License along with
* this program; if not, see http://www.gnu.org/licenses or write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU Affero General Public License version 3.
*
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "Powered by
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
* technical reasons, the Appropriate Legal Notices must display the words
* "Powered by SugarCRM".
********************************************************************************/
YAHOO.namespace("SUGAR");
(function() {
var sw = YAHOO.SUGAR,
Event = YAHOO.util.Event,
Connect = YAHOO.util.Connect,
Dom = YAHOO.util.Dom;
/**
* Message Box is a singleton widget designed to replace the browsers 'alert'
* function, as well as provide capabilities for pop-over loading bars and
* other small non-interactive pop-overs.
* TODO:Still needs configurable buttons in the footer as well as
* auto building of a loading bar.
*/
sw.MessageBox = {
progressTemplate : "{body}<br><div class='sugar-progress-wrap'><div class='sugar-progress-bar'/></div>",
promptTemplate : "{body}:<input id='sugar-message-prompt' class='sugar-message-prompt' name='sugar-message-prompt'></input>",
show: function(config) {
var myConf = sw.MessageBox.config = {
type:'message',
modal:true,
width: 240,
id:'sugarMsgWindow',
close:true,
title:"Alert",
msg: " ",
buttons: [ ]
};
if (config['type'] && config['type'] == "prompt") {
myConf['buttons'] = [{
text: SUGAR.language.get("app_strings", "LBL_EMAIL_CANCEL"), handler:YAHOO.SUGAR.MessageBox.hide
},{
text: SUGAR.language.get("app_strings", "LBL_EMAIL_OK"), handler:config['fn'] ?
function(){
var returnValue = config['fn'](YAHOO.util.Dom.get("sugar-message-prompt").value);
if (typeof(returnValue) == "undefined" || returnValue) {
YAHOO.SUGAR.MessageBox.hide();
} // if
}
: YAHOO.SUGAR.MessageBox.hide, isDefault:true
}];
} else if ((config['type'] && config['type'] == "alert")) {
myConf['buttons'] = [{
text: SUGAR.language.get("app_strings", "LBL_EMAIL_OK"),
handler: config['fn'] ?
function(){YAHOO.SUGAR.MessageBox.hide(); config['fn']();}
:
YAHOO.SUGAR.MessageBox.hide,
isDefault:true
}]
} else if((config['type'] && config['type'] == "confirm")) {
myConf['buttons'] = [{
text: SUGAR.language.get("app_strings", "LBL_EMAIL_YES"), handler:config['fn'] ?
function(){config['fn']('yes');YAHOO.SUGAR.MessageBox.hide();}
: YAHOO.SUGAR.MessageBox.hide, isDefault:true
},{
text: SUGAR.language.get("app_strings", "LBL_EMAIL_NO"), handler:config['fn'] ?
function(){config['fn']('no');YAHOO.SUGAR.MessageBox.hide();}
: YAHOO.SUGAR.MessageBox.hide
}];
}
else if((config['type'] && config['type'] == "plain")) {
myConf['buttons'] = [];
} // else if
for (var i in config) {
myConf[i] = config[i];
}
if (sw.MessageBox.panel) {
sw.MessageBox.panel.destroy();
}
sw.MessageBox.panel = new YAHOO.widget.SimpleDialog(myConf.id, {
width: myConf.width + 'px',
close: myConf.close,
modal: myConf.modal,
visible: true,
fixedcenter: true,
constraintoviewport: true,
draggable: true,
buttons: myConf.buttons
});
if (myConf.type == "progress") {
sw.MessageBox.panel.setBody(sw.MessageBox.progressTemplate.replace(/\{body\}/gi, myConf.msg));
} else if (myConf.type == "prompt") {
sw.MessageBox.panel.setBody(sw.MessageBox.promptTemplate.replace(/\{body\}/gi, myConf.msg));
} else if (myConf.type == "confirm") {
sw.MessageBox.panel.setBody(myConf.msg);
} else {
sw.MessageBox.panel.setBody(myConf.msg);
}
sw.MessageBox.panel.setHeader(myConf.title);
if (myConf.beforeShow) {
sw.MessageBox.panel.beforeShowEvent.subscribe(function() {myConf.beforeShow();});
} // if
if (myConf.beforeHide) {
sw.MessageBox.panel.beforeHideEvent.subscribe(function() {myConf.beforeHide();});
} // if
sw.MessageBox.panel.render(document.body);
sw.MessageBox.panel.show();
},
updateProgress: function(percent, message) {
if (!sw.MessageBox.config.type == "progress") return;
if (typeof message == "string") {
sw.MessageBox.panel.setBody(sw.MessageBox.progressTemplate.replace(/\{body\}/gi, message));
}
var barEl = Dom.getElementsByClassName("sugar-progress-bar", null, YAHOO.SUGAR.MessageBox.panel.element)[0];
if (percent > 100)
percent = 100;
else if (percent < 0)
percent = 0;
barEl.style.width = percent + "%";
},
hide: function() {
if (sw.MessageBox.panel)
sw.MessageBox.panel.hide();
}
};
sw.Template = function(content) {
this._setContent(content);
};
sw.Template.prototype = {
regex : /\{([\w\.]*)\}/gim,
append: function (target, args) {
var tEl = Dom.get(target);
if (tEl) tEl.innerHTML += this.exec(args);
else if (!SUGAR.isIE) console.log("Warning, unable to find target:" + target);
},
exec : function (args) {
var out = this.content;
for (var i in this.vars) {
var val = this._getValue(i, args);
var reg = new RegExp("\\{" + i + "\\}", "g");
out = out.replace(reg, val);
}
return out;
},
_setContent : function(content) {
this.content = content;
var lastIndex = -1;
var result = this.regex.exec(content);
this.vars = { };
while(result && result.index > lastIndex){
lastIndex = result.index;
this.vars[result[1]] = true;
result = this.regex.exec(content);
}
},
_getValue: function(v, scope) {
return function(e) {return eval("this." + e);}.call(scope, v);
}
};
/**
* SelectionGrid is simply a YUI Data Table with row selection already enabled.
*/
sw.SelectionGrid = function(containerEl, columns, dataSource, config){
sw.SelectionGrid.superclass.constructor.call(this, containerEl, columns, dataSource, config);
// Subscribe to events for row selection
this.subscribe("rowMouseoverEvent", this.onEventHighlightRow);
this.subscribe("rowMouseoutEvent", this.onEventUnhighlightRow);
this.subscribe("rowClickEvent", this.onEventSelectRow);
// Programmatically select the first row
this.selectRow(this.getTrEl(0));
// Programmatically bring focus to the instance so arrow selection works immediately
this.focus();
}
YAHOO.extend(sw.SelectionGrid, YAHOO.widget.ScrollingDataTable, {
//Bugfix, the default getColumn will fail if a th element is passed in. http://yuilibrary.com/projects/yui2/ticket/2528034
getColumn : function(column) {
var oColumn = this._oColumnSet.getColumn(column);
if(!oColumn) {
// Validate TD element
var elCell = this.getTdEl(column);
if(elCell && (!column.tagName || column.tagName.toUpperCase() != "TH")) {
oColumn = this._oColumnSet.getColumn(elCell.cellIndex);
}
// Validate TH element
else {
elCell = this.getThEl(column);
if(elCell) {
// Find by TH el ID
var allColumns = this._oColumnSet.flat;
for(var i=0, len=allColumns.length; i<len; i++) {
if(allColumns[i].getThEl().id === elCell.id) {
oColumn = allColumns[i];
}
}
}
}
}
if(!oColumn) {
YAHOO.log("Could not get Column for column at " + column, "info", this.toString());
}
return oColumn;
}
});
/**
* DragDropTable is a YUI Data Table with support for drag/drop row re-ordering.
*/
sw.DragDropTable = function(containerEl, columns, dataSource, config){
var DDT = sw.DragDropTable;
DDT.superclass.constructor.call(this, containerEl, columns, dataSource, config);
this.DDGroup = config.group ? config.group : "defGroup";
//Add table to the dragdrop table groups
if (typeof DDT.groups[this.DDGroup] == "undefined")
DDT.groups[this.DDGroup] = [];
DDT.groups[this.DDGroup][DDT.groups[this.DDGroup].length] = this;
this.tabledd = new YAHOO.util.DDTarget(containerEl);
}
sw.DragDropTable.groups = {
defGroup: []
}
YAHOO.extend(sw.DragDropTable, YAHOO.widget.ScrollingDataTable, {
_addTrEl : function (oRecord) {
var elTr = sw.DragDropTable.superclass._addTrEl.call(this, oRecord);
if (!this.disableEmptyRows || (
oRecord.getData()[this.getColumnSet().keys[0].key] != false
&& oRecord.getData()[this.getColumnSet().keys[0].key] != "")
) {
var _rowDD = new sw.RowDD(this, oRecord, elTr);
}
return elTr;
},
getGroup : function () {
return sw.DragDropTable.groups[this.DDGroup];
}
});
/**
* subclass of DragDrop to allow rows to be picked up and dropped between other rows.
*/
sw.RowDD = function(oDataTable, oRecord, elTr) {
if(oDataTable && oRecord && elTr) {
//sw.RowDD.superclass.constructor.call(this, elTr);
this.ddtable = oDataTable;
this.table = oDataTable.getTableEl();
this.row = oRecord;
this.rowEl = elTr;
this.newIndex = null;
this.init(elTr);
this.initFrame(); // Needed for DDProxy
this.invalidHandleTypes = {};
}
};
YAHOO.extend(sw.RowDD, YAHOO.util.DDProxy, {
// _removeIdRegex : /(<.[^\/<]*)id\s*=\s*['|"]?\w*['|"]?([^>]*>)/gim,
_removeIdRegex : new RegExp("(<.[^\\/<]*)id\\s*=\\s*['|\"]?\w*['|\"]?([^>]*>)", "gim"),
_resizeProxy: function() {
this.constructor.superclass._resizeProxy.apply(this, arguments);
var dragEl = this.getDragEl(),
el = this.getEl();
Dom.setStyle(this.pointer, 'height', (this.rowEl.offsetHeight + 5) + 'px');
Dom.setStyle(this.pointer, 'display', 'block');
var xy = Dom.getXY(el);
Dom.setXY(this.pointer, [xy[0], (xy[1] - 5)]);
Dom.setStyle(dragEl, 'height', this.rowEl.offsetHeight + "px");
Dom.setStyle(dragEl, 'width', (parseInt(Dom.getStyle(dragEl, 'width'),10) + 4) + 'px');
Dom.setXY(this.dragEl, xy);
},
startDrag: function(x, y) {
var dragEl = this.getDragEl();
var clickEl = this.getEl();
Dom.setStyle(clickEl, "opacity", "0.25");
var tableWrap = false;
if (clickEl.tagName.toUpperCase() == "TR")
tableWrap = true;
dragEl.innerHTML = "<table>" + clickEl.innerHTML.replace(this._removeIdRegex, "$1$2") + "</table>";
//Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color"));
Dom.addClass(dragEl, "yui-dt-liner");
Dom.setStyle(dragEl, "height", (clickEl.clientHeight - 2) + "px");
Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor"));
Dom.setStyle(dragEl, "border", "2px solid gray");
Dom.setStyle(dragEl, "display", "");
this.newTable = this.ddtable;
},
clickValidator: function(e) {
if (this.row.getData()[0] == " ")
return false;
var target = Event.getTarget(e);
return ( this.isValidHandleChild(target) &&
(this.id == this.handleElId || this.DDM.handleWasClicked(target, this.id)) );
},
/**
* This funciton checks that the target of the drag is a table row in this
* DDGroup and simply moves the sourceEL to that location as a preview.
*/
onDragOver: function(ev, id) {
var groupTables = this.ddtable.getGroup();
for(i in groupTables) {
var targetTable = groupTables[i];
if (!targetTable.getContainerEl)
continue;
//We got a table id
if (targetTable.getContainerEl().id == id) {
if (targetTable != this.newTable) { // Moved from one table to another
this.newIndex = targetTable.getRecordSet().getLength() - 1;
var destEl = Dom.get(targetTable.getLastTrEl());
destEl.parentNode.insertBefore(this.getEl(), destEl);
}
this.newTable = targetTable
return true;
}
}
if (this.newTable && this.newTable.getRecord(id)) { // Found the target row
var targetRow = this.newTable.getRecord(id);
var destEl = Dom.get(id);
destEl.parentNode.insertBefore(this.getEl(), destEl);
this.newIndex = this.newTable.getRecordIndex(targetRow);
}
},
endDrag: function() {
//Ensure the element is back on the home table to be cleaned up.
if (this.newTable != null && this.newIndex != null) {
this.getEl().style.display = "none";
this.table.appendChild(this.getEl());
this.newTable.addRow(this.row.getData(), this.newIndex);
this.ddtable.deleteRow(this.row);
this.ddtable.render();
}
this.newTable = this.newIndex = null
var clickEl = this.getEl();
Dom.setStyle(clickEl, "opacity", "");
}
});
/**
* A YUI panel that supports loading and re-loading it's contents from an Asynch request.
*/
sw.AsyncPanel = function (el, params) {
if (params)
sw.AsyncPanel.superclass.constructor.call(this, el, params);
else
sw.AsyncPanel.superclass.constructor.call(this, el);
}
YAHOO.extend(sw.AsyncPanel, YAHOO.widget.Panel, {
loadingText : "Loading...",
failureText : "Error loading content.",
load : function(url, method) {
method = method ? method : "GET";
this.setBody(this.loadingText);
if (Connect.url) url = Connect.url + "&" + url;
Connect.asyncRequest(method, url, {success:this._updateContent, failure:this._loadFailed, scope:this});
},
_updateContent : function (o) {
//Under safari, the width of the panel may expand for no apparent reason, and under FF it will contract
var w = this.cfg.config.width.value + "px";
this.setBody(o.responseText);
if (!SUGAR.isIE)
this.body.style.width = w
},
_loadFailed : function(o) {
this.setBody(this.failureText);
}
});
sw.ClosableTab = function(el, parent, conf) {
this.closeEvent = new YAHOO.util.CustomEvent("close", this);
if (conf)
sw.ClosableTab.superclass.constructor.call(this, el, conf);
else
sw.ClosableTab.superclass.constructor.call(this, el);
this.setAttributeConfig("TabView", {
value: parent
});
this.get("labelEl").parentNode.href = "javascript:void(0);";
}
YAHOO.extend(sw.ClosableTab, YAHOO.widget.Tab, {
close : function () {
this.closeEvent.fire();
var parent = this.get("TabView");
parent.removeTab(this);
},
initAttributes: function(attr) {
sw.ClosableTab.superclass.initAttributes.call(this, attr);
/**
* The message to display when closing the tab
* @attribute closeMsg
* @type String
*/
this.setAttributeConfig("closeMsg", {
value: attr.closeMsg || ""
});
/**
* The tab's label text (or innerHTML).
* @attribute label
* @type String
*/
this.setAttributeConfig("label", {
value: attr.label || this._getLabel(),
method: function(value) {
var labelEl = this.get("labelEl");
if (!labelEl) { // create if needed
this.set(LABEL_EL, this._createLabelEl());
}
labelEl.innerHTML = value;
var closeButton = document.createElement('a');
closeButton.href = "javascript:void(0);";
Dom.addClass(closeButton, "sugar-tab-close");
Event.addListener(closeButton, "click", function(e, tab){
if (tab.get("closeMsg") != "")
{
if (confirm(tab.get("closeMsg"))) {
tab.close();
}
}
else {
tab.close();
}
},
this
);
labelEl.appendChild(closeButton);
}
});
}
});
/**
* The sugar Tree is a YUI tree with node construction based on AJAX data built in.
*/
sw.Tree = function (parentEl, baseRequestParams, rootParams) {
this.baseRequestParams = baseRequestParams;
sw.Tree.superclass.constructor.call(this, parentEl);
if (rootParams) {
if (typeof rootParams == "string")
this.sendTreeNodeDataRequest(this.getRoot(), rootParams);
else
this.sendTreeNodeDataRequest(this.getRoot(), "");
}
}
YAHOO.extend(sw.Tree, YAHOO.widget.TreeView, {
sendTreeNodeDataRequest: function(parentNode, params){
YAHOO.util.Connect.asyncRequest('POST', 'index.php', {
success: this.handleTreeNodeDataRequest,
argument: {
parentNode: parentNode
},
scope: this
}, this.baseRequestParams + params);
},
handleTreeNodeDataRequest : function(o) {
var parentNode = o.argument.parentNode;
//parent.tree.removeChildren(parentNode);
var resp = YAHOO.lang.JSON.parse(o.responseText);
if (resp.tree_data.nodes) {
for (var i = 0; i < resp.tree_data.nodes.length; i++) {
var newChild = this.buildTreeNodeRecursive(resp.tree_data.nodes[i], parentNode);
}
}
parentNode.tree.draw();
},
buildTreeNodeRecursive : function(nodeData, parentNode) {
nodeData.label = nodeData.text;
var node = new YAHOO.widget.TextNode(nodeData, parentNode, nodeData.expanded);
if (typeof(nodeData.children) == 'object') {
for (var i = 0; i < nodeData.children.length; i++) {
this.buildTreeNodeRecursive(nodeData.children[i], node);
}
}
return node;
}
});
/**
* A 1/2 second fade-in animation.
* @class TVSlideIn
* @constructor
* @param el {HTMLElement} the element to animate
* @param callback {function} function to invoke when the animation is finished
*/
YAHOO.widget.TVSlideIn = function(el, callback) {
/**
* The element to animate
* @property el
* @type HTMLElement
*/
this.el = el;
/**
* the callback to invoke when the animation is complete
* @property callback
* @type function
*/
this.callback = callback;
this.logger = new YAHOO.widget.LogWriter(this.toString());
};
YAHOO.widget.TVSlideIn.prototype = {
/**
* Performs the animation
* @method animate
*/
animate: function() {
var tvanim = this;
var s = this.el.style;
s.height = "";
s.display = "";
s.overflow = "hidden";
var th = this.el.clientHeight;
s.height = "0px";
var dur = 0.4;
var a = new YAHOO.util.Anim(this.el, {height: {from: 0, to: th, unit:"px"}}, dur);
a.onComplete.subscribe( function() { tvanim.onComplete(); } );
a.animate();
},
/**
* Clean up and invoke callback
* @method onComplete
*/
onComplete: function() {
this.el.style.overflow = "";
this.el.style.height = "";
this.callback();
},
/**
* toString
* @method toString
* @return {string} the string representation of the instance
*/
toString: function() {
return "TVSlideIn";
}
};
/**
* A 1/2 second fade out animation.
* @class TVSlideOut
* @constructor
* @param el {HTMLElement} the element to animate
* @param callback {Function} function to invoke when the animation is finished
*/
YAHOO.widget.TVSlideOut = function(el, callback) {
/**
* The element to animate
* @property el
* @type HTMLElement
*/
this.el = el;
/**
* the callback to invoke when the animation is complete
* @property callback
* @type function
*/
this.callback = callback;
this.logger = new YAHOO.widget.LogWriter(this.toString());
};
YAHOO.widget.TVSlideOut.prototype = {
/**
* Performs the animation
* @method animate
*/
animate: function() {
var tvanim = this;
var dur = 0.4;
var th = this.el.clientHeight;
this.el.style.overflow = "hidden";
var a = new YAHOO.util.Anim(this.el, {height: {from: th, to: 0, unit:"px"}}, dur);
a.onComplete.subscribe( function() { tvanim.onComplete(); } );
a.animate();
},
/**
* Clean up and invoke callback
* @method onComplete
*/
onComplete: function() {
var s = this.el.style;
s.display = "none";
this.el.style.overflow = "";
this.el.style.height = "";
this.callback();
},
/**
* toString
* @method toString
* @return {string} the string representation of the instance
*/
toString: function() {
return "TVSlideOut";
}
};
})();

View File

@@ -0,0 +1,265 @@
/**
* SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
*
* SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*
*/
if(typeof deconcept == "undefined") var deconcept = new Object();
if(typeof deconcept.util == "undefined") deconcept.util = new Object();
if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
if (!document.getElementById) { return; }
this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
this.params = new Object();
this.variables = new Object();
this.attributes = new Array();
if(swf) { this.setAttribute('swf', swf); }
if(id) { this.setAttribute('id', id); }
if(w) { this.setAttribute('width', w); }
if(h) { this.setAttribute('height', h); }
if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
if (!window.opera && document.all && this.installedVer.major > 7) {
// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
deconcept.SWFObject.doPrepUnload = true;
}
if(c) { this.addParam('bgcolor', c); }
var q = quality ? quality : 'high';
this.addParam('quality', q);
this.setAttribute('useExpressInstall', false);
this.setAttribute('doExpressInstall', false);
var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
this.setAttribute('xiRedirectUrl', xir);
this.setAttribute('redirectUrl', '');
if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
}
deconcept.SWFObject.prototype = {
useExpressInstall: function(path) {
this.xiSWFPath = !path ? "expressinstall.swf" : path;
this.setAttribute('useExpressInstall', true);
},
setAttribute: function(name, value){
this.attributes[name] = value;
},
getAttribute: function(name){
return this.attributes[name];
},
addParam: function(name, value){
this.params[name] = value;
},
getParams: function(){
return this.params;
},
addVariable: function(name, value){
this.variables[name] = value;
},
getVariable: function(name){
return this.variables[name];
},
getVariables: function(){
return this.variables;
},
getVariablePairs: function(){
var variablePairs = new Array();
var key;
var variables = this.getVariables();
for(key in variables){
variablePairs[variablePairs.length] = key +"="+ variables[key];
}
return variablePairs;
},
getSWFHTML: function() {
var swfNode = "";
if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
if (this.getAttribute("doExpressInstall")) {
this.addVariable("MMplayerType", "PlugIn");
this.setAttribute('swf', this.xiSWFPath);
}
swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
var params = this.getParams();
for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
var pairs = this.getVariablePairs().join("&");
if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
swfNode += '/>';
} else { // PC IE
if (this.getAttribute("doExpressInstall")) {
this.addVariable("MMplayerType", "ActiveX");
this.setAttribute('swf', this.xiSWFPath);
}
swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
var params = this.getParams();
for(var key in params) {
swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
}
var pairs = this.getVariablePairs().join("&");
if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
swfNode += "</object>";
}
return swfNode;
},
write: function(elementId){
if(this.getAttribute('useExpressInstall')) {
// check to see if we need to do an express install
var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) {
this.setAttribute('doExpressInstall', true);
this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl')));
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
this.addVariable("MMdoctitle", document.title);
}
}
if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
n.innerHTML = this.getSWFHTML();
return true;
}else{
if(this.getAttribute('redirectUrl') != "") {
document.location.replace(this.getAttribute('redirectUrl'));
}
}
return false;
}
}
/* ---- detection functions ---- */
deconcept.SWFObjectUtil.getPlayerVersion = function(){
var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
if(navigator.plugins && navigator.mimeTypes.length){
var x = navigator.plugins["Shockwave Flash"];
if(x && x.description) {
PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
}
}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
var axo = 1;
var counter = 3;
while(axo) {
try {
counter++;
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
// document.write("player v: "+ counter);
PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
} catch (e) {
axo = null;
}
}
} else { // Win IE (non mobile)
// do minor version lookup in IE, but avoid fp6 crashing issues
// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
try{
var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
}catch(e){
try {
var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
} catch(e) {
if (PlayerVersion.major == 6) {
return PlayerVersion;
}
}
try {
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
} catch(e) {}
}
if (axo != null) {
PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
}
}
return PlayerVersion;
}
deconcept.PlayerVersion = function(arrVersion){
this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
}
deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
if(this.major < fv.major) return false;
if(this.major > fv.major) return true;
if(this.minor < fv.minor) return false;
if(this.minor > fv.minor) return true;
if(this.rev < fv.rev) return false;
return true;
}
/* ---- get value of query string param ---- */
deconcept.util = {
getRequestParameter: function(param) {
var q = document.location.search || document.location.hash;
if (param == null) { return q; }
if(q) {
var pairs = q.substring(1).split("&");
for (var i=0; i < pairs.length; i++) {
if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
return pairs[i].substring((pairs[i].indexOf("=")+1));
}
}
}
return "";
}
}
/* fix for video streaming bug */
deconcept.SWFObjectUtil.cleanupSWFs = function() {
var objects = document.getElementsByTagName("OBJECT");
for (var i = objects.length - 1; i >= 0; i--) {
objects[i].style.display = 'none';
for (var x in objects[i]) {
if (typeof objects[i][x] == 'function') {
objects[i][x] = function(){};
}
}
}
}
// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
if (deconcept.SWFObject.doPrepUnload) {
if (!deconcept.unloadSet) {
deconcept.SWFObjectUtil.prepUnload = function() {
__flash_unloadHandler = function(){};
__flash_savedUnloadHandler = function(){};
window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
}
window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
deconcept.unloadSet = true;
}
}
/* add document.getElementById if needed (mobile IE < 5) */
if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}
/* add some aliases for ease of use/backwards compatibility */
var getQueryParamValue = deconcept.util.getRequestParameter;
var FlashObject = deconcept.SWFObject; // for legacy support
var SWFObject = deconcept.SWFObject;
/* begin SUGARCRM customization */
function loadChartSWF(chartName, xmlFile, width, height, stylesheet, colorscheme, langFile){
if(!document.getElementById(chartName + '_div')) {
return;
}
if (width == '100%'){
width = document.getElementById(chartName + '_div').clientWidth;
}
else{
width = width.replace(/px/,'');
}
height = height.replace(/px/,'');
var home = new SWFObject("include/SugarCharts/swf/chart.swf", chartName, "100%", "100%", "7");
home.addParam("wmode","transparent");
home.addParam("menu","false");
home.addParam("quality","high");
home.addVariable( "inputFile" , xmlFile)
home.addVariable( "swfLocation" ,"include/SugarCharts/swf/");
home.addVariable( "inputColorScheme" , colorscheme);
home.addVariable( "inputStyleSheet", stylesheet);
home.addVariable( "inputLanguage", langFile);
home.addVariable( "myWidth", width);
home.addVariable( "myHeight", height);
home.write(chartName + '_div');
}
/* end SUGARCRM customization */

View File

@@ -0,0 +1,805 @@
/**
* Code Syntax Highlighter.
* Version 1.3.0
* Copyright (C) 2004 Alex Gorbatchev.
* http://www.dreamprojections.com/syntaxhighlighter/
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//
// create namespaces
//
var dp = {
sh : // dp.sh
{
Utils : {}, // dp.sh.Utils
Brushes : {}, // dp.sh.Brushes
Strings : {},
Version : '1.3.0'
}
};
dp.sh.Strings = {
AboutDialog : '<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/SyntaxHighlighter</a></p>&copy;2004-2005 Alex Gorbatchev. All right reserved.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>',
// tools
ExpandCode : '+ expand code',
ViewPlain : 'view plain',
Print : 'print',
CopyToClipboard : 'copy to clipboard',
About : '?',
CopiedToClipboard : 'The code is in your clipboard now.'
};
dp.SyntaxHighlighter = dp.sh;
//
// Dialog and toolbar functions
//
dp.sh.Utils.Expand = function(sender)
{
var table = sender;
var span = sender;
// find the span in which the text label and pipe contained so we can hide it
while(span != null && span.tagName != 'SPAN')
span = span.parentNode;
// find the table
while(table != null && table.tagName != 'TABLE')
table = table.parentNode;
// remove the 'expand code' button
span.parentNode.removeChild(span);
table.tBodies[0].className = 'show';
table.parentNode.style.height = '100%'; // containing div isn't getting updated properly when the TBODY is shown
}
// opens a new windows and puts the original unformatted source code inside.
dp.sh.Utils.ViewSource = function(sender)
{
var code = sender.parentNode.originalCode;
var wnd = window.open('', '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=1');
code = code.replace(/</g, '&lt;');
wnd.document.write('<pre>' + code + '</pre>');
wnd.document.close();
}
// copies the original source code in to the clipboard (IE only)
dp.sh.Utils.ToClipboard = function(sender)
{
var code = sender.parentNode.originalCode;
// This works only for IE. There's a way to make it work with Mozilla as well,
// but it requires security settings changed on the client, which isn't by
// default, so 99% of users won't have it working anyways.
if(window.clipboardData)
{
window.clipboardData.setData('text', code);
alert(dp.sh.Strings.CopiedToClipboard);
}
}
// creates an invisible iframe, puts the original source code inside and prints it
dp.sh.Utils.PrintSource = function(sender)
{
var td = sender.parentNode;
var code = td.processedCode;
var iframe = document.createElement('IFRAME');
var doc = null;
var wnd =
// this hides the iframe
iframe.style.cssText = 'position:absolute; width:0px; height:0px; left:-5px; top:-5px;';
td.appendChild(iframe);
doc = iframe.contentWindow.document;
code = code.replace(/</g, '&lt;');
doc.open();
doc.write('<pre>' + code + '</pre>');
doc.close();
iframe.contentWindow.focus();
iframe.contentWindow.print();
td.removeChild(iframe);
}
dp.sh.Utils.About = function()
{
var wnd = window.open('', '_blank', 'dialog,width=320,height=150,scrollbars=0');
var doc = wnd.document;
var styles = document.getElementsByTagName('style');
var links = document.getElementsByTagName('link');
doc.write(dp.sh.Strings.AboutDialog.replace('{V}', dp.sh.Version));
// copy over ALL the styles from the parent page
for(var i = 0; i < styles.length; i++)
doc.write('<style>' + styles[i].innerHTML + '</style>');
for(var i = 0; i < links.length; i++)
if(links[i].rel.toLowerCase() == 'stylesheet')
doc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
doc.close();
wnd.focus();
}
//
// Match object
//
dp.sh.Match = function(value, index, css)
{
this.value = value;
this.index = index;
this.length = value.length;
this.css = css;
}
//
// Highlighter object
//
dp.sh.Highlighter = function()
{
this.addGutter = true;
this.addControls = true;
this.collapse = false;
this.tabsToSpaces = true;
}
// static callback for the match sorting
dp.sh.Highlighter.SortCallback = function(m1, m2)
{
// sort matches by index first
if(m1.index < m2.index)
return -1;
else if(m1.index > m2.index)
return 1;
else
{
// if index is the same, sort by length
if(m1.length < m2.length)
return -1;
else if(m1.length > m2.length)
return 1;
}
return 0;
}
// gets a list of all matches for a given regular expression
dp.sh.Highlighter.prototype.GetMatches = function(regex, css)
{
var index = 0;
var match = null;
while((match = regex.exec(this.code)) != null)
{
this.matches[this.matches.length] = new dp.sh.Match(match[0], match.index, css);
}
}
dp.sh.Highlighter.prototype.AddBit = function(str, css)
{
var span = document.createElement('span');
str = str.replace(/&/g, '&amp;');
str = str.replace(/ /g, '&nbsp;');
str = str.replace(/</g, '&lt;');
str = str.replace(/\n/gm, '&nbsp;<br>');
// when adding a piece of code, check to see if it has line breaks in it
// and if it does, wrap individual line breaks with span tags
if(css != null)
{
var regex = new RegExp('<br>', 'gi');
if(regex.test(str))
{
var lines = str.split('&nbsp;<br>');
str = '';
for(var i = 0; i < lines.length; i++)
{
span = document.createElement('SPAN');
span.className = css;
span.innerHTML = lines[i];
this.div.appendChild(span);
// don't add a <BR> for the last line
if(i + 1 < lines.length)
this.div.appendChild(document.createElement('BR'));
}
}
else
{
span.className = css;
span.innerHTML = str;
this.div.appendChild(span);
}
}
else
{
span.innerHTML = str;
this.div.appendChild(span);
}
}
// checks if one match is inside any other match
dp.sh.Highlighter.prototype.IsInside = function(match)
{
if(match == null || match.length == 0)
return;
for(var i = 0; i < this.matches.length; i++)
{
var c = this.matches[i];
if(c == null)
continue;
if((match.index > c.index) && (match.index <= c.index + c.length))
return true;
}
return false;
}
dp.sh.Highlighter.prototype.ProcessRegexList = function()
{
for(var i = 0; i < this.regexList.length; i++)
this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
}
dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code)
{
var lines = code.split('\n');
var result = '';
var tabSize = 4;
var tab = '\t';
// This function inserts specified amount of spaces in the string
// where a tab is while removing that given tab.
function InsertSpaces(line, pos, count)
{
var left = line.substr(0, pos);
var right = line.substr(pos + 1, line.length); // pos + 1 will get rid of the tab
var spaces = '';
for(var i = 0; i < count; i++)
spaces += ' ';
return left + spaces + right;
}
// This function process one line for 'smart tabs'
function ProcessLine(line, tabSize)
{
if(line.indexOf(tab) == -1)
return line;
var pos = 0;
while((pos = line.indexOf(tab)) != -1)
{
// This is pretty much all there is to the 'smart tabs' logic.
// Based on the position within the line and size of a tab,
// calculate the amount of spaces we need to insert.
var spaces = tabSize - pos % tabSize;
line = InsertSpaces(line, pos, spaces);
}
return line;
}
// Go through all the lines and do the 'smart tabs' magic.
for(var i = 0; i < lines.length; i++)
result += ProcessLine(lines[i], tabSize) + '\n';
return result;
}
dp.sh.Highlighter.prototype.SwitchToTable = function()
{
// thanks to Lachlan Donald from SitePoint.com for this <br/> tag fix.
var html = this.div.innerHTML.replace(/<(br)\/?>/gi, '\n');
var lines = html.split('\n');
var row = null;
var cell = null;
var tBody = null;
var html = '';
var pipe = ' | ';
// creates an anchor to a utility
function UtilHref(util, text)
{
return '<a href="#" onclick="dp.sh.Utils.' + util + '(this); return false;">' + text + '</a>';
}
tBody = document.createElement('TBODY'); // can be created and all others go to tBodies collection.
this.table.appendChild(tBody);
if(this.addGutter == true)
{
row = tBody.insertRow(-1);
cell = row.insertCell(-1);
cell.className = 'tools-corner';
}
if(this.addControls == true)
{
var tHead = document.createElement('THEAD'); // controls will be placed in here
this.table.appendChild(tHead);
row = tHead.insertRow(-1);
// add corner if there's a gutter
if(this.addGutter == true)
{
cell = row.insertCell(-1);
cell.className = 'tools-corner';
}
cell = row.insertCell(-1);
// preserve some variables for the controls
cell.originalCode = this.originalCode;
cell.processedCode = this.code;
cell.className = 'tools';
if(this.collapse == true)
{
tBody.className = 'hide';
cell.innerHTML += '<span><b>' + UtilHref('Expand', dp.sh.Strings.ExpandCode) + '</b>' + pipe + '</span>';
}
cell.innerHTML += UtilHref('ViewSource', dp.sh.Strings.ViewPlain) + pipe + UtilHref('PrintSource', dp.sh.Strings.Print);
// IE has this clipboard object which is easy enough to use
if(window.clipboardData)
cell.innerHTML += pipe + UtilHref('ToClipboard', dp.sh.Strings.CopyToClipboard);
cell.innerHTML += pipe + UtilHref('About', dp.sh.Strings.About);
}
for(var i = 0, lineIndex = this.firstLine; i < lines.length - 1; i++, lineIndex++)
{
row = tBody.insertRow(-1);
if(this.addGutter == true)
{
cell = row.insertCell(-1);
cell.className = 'gutter';
cell.innerHTML = lineIndex;
}
cell = row.insertCell(-1);
cell.className = 'line' + (i % 2 + 1); // uses .line1 and .line2 css styles for alternating lines
cell.innerHTML = lines[i];
}
this.div.innerHTML = '';
}
dp.sh.Highlighter.prototype.Highlight = function(code)
{
function Trim(str)
{
return str.replace(/^\s*(.*?)[\s\n]*$/g, '$1');
}
function Chop(str)
{
return str.replace(/\n*$/, '').replace(/^\n*/, '');
}
function Unindent(str)
{
var lines = str.split('\n');
var indents = new Array();
var regex = new RegExp('^\\s*', 'g');
var min = 1000;
// go through every line and check for common number of indents
for(var i = 0; i < lines.length && min > 0; i++)
{
if(Trim(lines[i]).length == 0)
continue;
var matches = regex.exec(lines[i]);
if(matches != null && matches.length > 0)
min = Math.min(matches[0].length, min);
}
// trim minimum common number of white space from the begining of every line
if(min > 0)
for(var i = 0; i < lines.length; i++)
lines[i] = lines[i].substr(min);
return lines.join('\n');
}
// This function returns a portions of the string from pos1 to pos2 inclusive
function Copy(string, pos1, pos2)
{
return string.substr(pos1, pos2 - pos1);
}
var pos = 0;
this.originalCode = code;
this.code = Chop(Unindent(code));
this.div = document.createElement('DIV');
this.table = document.createElement('TABLE');
this.matches = new Array();
if(this.CssClass != null)
this.table.className = this.CssClass;
// replace tabs with spaces
if(this.tabsToSpaces == true)
this.code = this.ProcessSmartTabs(this.code);
this.table.border = 0;
this.table.cellSpacing = 0;
this.table.cellPadding = 0;
this.ProcessRegexList();
// if no matches found, add entire code as plain text
if(this.matches.length == 0)
{
this.AddBit(this.code, null);
this.SwitchToTable();
return;
}
// sort the matches
this.matches = this.matches.sort(dp.sh.Highlighter.SortCallback);
// The following loop checks to see if any of the matches are inside
// of other matches. This process would get rid of highligting strings
// inside comments, keywords inside strings and so on.
for(var i = 0; i < this.matches.length; i++)
if(this.IsInside(this.matches[i]))
this.matches[i] = null;
// Finally, go through the final list of matches and pull the all
// together adding everything in between that isn't a match.
for(var i = 0; i < this.matches.length; i++)
{
var match = this.matches[i];
if(match == null || match.length == 0)
continue;
this.AddBit(Copy(this.code, pos, match.index), null);
this.AddBit(match.value, match.css);
pos = match.index + match.length;
}
this.AddBit(this.code.substr(pos), null);
this.SwitchToTable();
}
dp.sh.Highlighter.prototype.GetKeywords = function(str)
{
return '\\b' + str.replace(/ /g, '\\b|\\b') + '\\b';
}
// highlightes all elements identified by name and gets source code from specified property
dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */, collapseAll /* optional */, firstLine /* optional */)
{
function FindValue()
{
var a = arguments;
for(var i = 0; i < a.length; i++)
{
if(a[i] == null)
continue;
if(typeof(a[i]) == 'string' && a[i] != '')
return a[i] + '';
if(typeof(a[i]) == 'object' && a[i].value != '')
return a[i].value + '';
}
return null;
}
function IsOptionSet(value, list)
{
for(var i = 0; i < list.length; i++)
if(list[i] == value)
return true;
return false;
}
function GetOptionValue(name, list, defaultValue)
{
var regex = new RegExp('^' + name + '\\[(\\w+)\\]$', 'gi');
var matches = null;
for(var i = 0; i < list.length; i++)
if((matches = regex.exec(list[i])) != null)
return matches[1];
return defaultValue;
}
var elements = document.getElementsByName(name);
var highlighter = null;
var registered = new Object();
var propertyName = 'value';
// if no code blocks found, leave
if(elements == null)
return;
// register all brushes
for(var brush in dp.sh.Brushes)
{
var aliases = dp.sh.Brushes[brush].Aliases;
if(aliases == null)
continue;
for(var i = 0; i < aliases.length; i++)
registered[aliases[i]] = brush;
}
for(var i = 0; i < elements.length; i++)
{
var element = elements[i];
var options = FindValue(
element.attributes['class'], element.className,
element.attributes['language'], element.language
);
var language = '';
if(options == null)
continue;
options = options.split(':');
language = options[0].toLowerCase();
if(registered[language] == null)
continue;
// instantiate a brush
highlighter = new dp.sh.Brushes[registered[language]]();
// hide the original element
element.style.display = 'none';
highlighter.addGutter = (showGutter == null) ? !IsOptionSet('nogutter', options) : showGutter;
highlighter.addControls = (showControls == null) ? !IsOptionSet('nocontrols', options) : showControls;
highlighter.collapse = (collapseAll == null) ? IsOptionSet('collapse', options) : collapseAll;
// first line idea comes from Andrew Collington, thanks!
highlighter.firstLine = (firstLine == null) ? parseInt(GetOptionValue('firstline', options, 1)) : firstLine;
highlighter.Highlight(element[propertyName]);
// place the result table inside a div
var div = document.createElement('DIV');
div.className = 'dp-highlighter';
div.appendChild(highlighter.table);
element.parentNode.insertBefore(div, element);
}
}
dp.sh.Brushes.Xml = function()
{
this.CssClass = 'dp-xml';
}
dp.sh.Brushes.Xml.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.Xml.Aliases = ['xml', 'xhtml', 'xslt', 'html', 'xhtml'];
dp.sh.Brushes.Xml.prototype.ProcessRegexList = function()
{
function push(array, value)
{
array[array.length] = value;
}
/* If only there was a way to get index of a group within a match, the whole XML
could be matched with the expression looking something like that:
(<!\[CDATA\[\s*.*\s*\]\]>)
| (<!--\s*.*\s*?-->)
| (<)*(\w+)*\s*(\w+)\s*=\s*(".*?"|'.*?'|\w+)(/*>)*
| (</?)(.*?)(/?>)
*/
var index = 0;
var match = null;
var regex = null;
// Match CDATA in the following format <![ ... [ ... ]]>
// <\!\[[\w\s]*?\[(.|\s)*?\]\]>
this.GetMatches(new RegExp('<\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\]>', 'gm'), 'cdata');
// Match comments
// <!--\s*.*\s*?-->
this.GetMatches(new RegExp('<!--\\s*.*\\s*?-->', 'gm'), 'comments');
// Match attributes and their values
// (\w+)\s*=\s*(".*?"|\'.*?\'|\w+)*
regex = new RegExp('([\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\w+)*', 'gm');
while((match = regex.exec(this.code)) != null)
{
push(this.matches, new dp.sh.Match(match[1], match.index, 'attribute'));
// if xml is invalid and attribute has no property value, ignore it
if(match[2] != undefined)
{
push(this.matches, new dp.sh.Match(match[2], match.index + match[0].indexOf(match[2]), 'attribute-value'));
}
}
// Match opening and closing tag brackets
// </*\?*(?!\!)|/*\?*>
this.GetMatches(new RegExp('</*\\?*(?!\\!)|/*\\?*>', 'gm'), 'tag');
// Match tag names
// </*\?*\s*(\w+)
regex = new RegExp('</*\\?*\\s*([\\w-\.]+)', 'gm');
while((match = regex.exec(this.code)) != null)
{
push(this.matches, new dp.sh.Match(match[1], match.index + match[0].indexOf(match[1]), 'tag-name'));
}
}
dp.sh.Brushes.Php = function()
{
var keywords = 'and or xor __FILE__ __LINE__ array as break case ' +
'cfunction class const continue declare default die do echo else ' +
'elseif empty enddeclare endfor endforeach endif endswitch endwhile eval exit ' +
'extends for foreach function global if include include_once isset list ' +
'new old_function print require require_once return static switch unset use ' +
'var while __FUNCTION__ __CLASS__';
this.regexList = [
{ regex: new RegExp('//.*$', 'gm'), css: 'comment' }, // one line comments
{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'), css: 'comment' }, // multiline comments
{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'), css: 'string' }, // double quoted strings
{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'), css: 'string' }, // single quoted strings
{ regex: new RegExp('\\$\\w+', 'g'), css: 'vars' }, // variables
{ regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' } // keyword
];
this.CssClass = 'dp-c';
}
dp.sh.Brushes.Php.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.Php.Aliases = ['php'];
dp.sh.Brushes.JScript = function()
{
var keywords = 'abstract boolean break byte case catch char class const continue debugger ' +
'default delete do double else enum export extends false final finally float ' +
'for function goto if implements import in instanceof int interface long native ' +
'new null package private protected public return short static super switch ' +
'synchronized this throw throws transient true try typeof var void volatile while with';
this.regexList = [
{ regex: new RegExp('//.*$', 'gm'), css: 'comment' }, // one line comments
{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'), css: 'comment' }, // multiline comments
{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'), css: 'string' }, // double quoted strings
{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'), css: 'string' }, // single quoted strings
{ regex: new RegExp('^\\s*#.*', 'gm'), css: 'preprocessor' }, // preprocessor tags like #region and #endregion
{ regex: new RegExp(this.GetKeywords(keywords), 'gm'), css: 'keyword' } // keywords
];
this.CssClass = 'dp-c';
}
dp.sh.Brushes.JScript.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.JScript.Aliases = ['js', 'jscript', 'javascript'];
dp.sh.Brushes.CSS = function() {
//Not used yet - added to values
var tags = 'abbr acronym address applet area a b base basefont bdo big blockquote body br button ' +
'caption center cite code col colgroup dd del dfn dir div dl dt em fieldset form frame frameset h1 h2 h3 h4 h5 h6 head hr html img i ' +
'iframe img input ins isindex kbd label legend li link map menu meta noframes noscript ol optgroup option p param pre q s samp script select ' +
'span strike strong style sub sup table tbody td textarea tfoot th thead title tr tt ul u';
var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
'height letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
'outline-color outline-style outline-width outline overflow-x overflow-y overflow padding-top padding-right padding-bottom padding-left padding page ' +
'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
'quotes richness right left bottom top size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
'table-layout text-align text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index zoom important after filter opacity';
var values = 'progid:DXImageTransform.Microsoft.AlphaImageLoader src sizingMethod alpha opacity ' +
'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder both bottom braille capitalize center center-left center-right circle close-quote code collapse compact condensed '+
'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
'gray green groove handheld hebrew help hidden hide high higher inline-table inline inset inside invert italic justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
'outside overline pointer portrait print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
this.regexList = [
{ regex: new RegExp('//.*$', 'gm'), css: 'comment' }, // one line comments
{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'), css: 'comment' }, // multiline comments
{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'), css: 'string' }, // double quoted strings
{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'), css: 'string' }, // single quoted strings
{ regex: new RegExp('^\\s*.*{', 'gm'), css: 'preprocessor' }, // everything before a {
{ regex: new RegExp('}', 'gm'), css: 'preprocessor' }, // The }
{ regex: new RegExp(this.GetKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords
{ regex: new RegExp(this.GetValuesCSS(values), 'gm'), css: 'value' }, // values
{ regex: new RegExp('(-?\\d+)(\.\\d+)?(px|em|pt|\:|\%|)', 'g'), css: 'value' } //Sizes
];
//Not used any more
/*
{ regex: new RegExp('(-?\\d+)(\.\\d+)', 'g'), css: 'value' }, //Plain Numbers
{ regex: new RegExp('(0(?=;))', 'g'), css: 'value' } //Number 0
{ regex: new RegExp('\([.]\)', 'gm'), css: 'string' }, // Things in parenthesis
{ regex: new RegExp('\\#[a-zA-Z0-9]{3,6}', 'g'), css: 'colors' }, // html colors
{ regex: new RegExp(this.GetKeywords(tags), 'g'), css: 'tags' }, // keywords
*/
this.CssClass = 'dp-css';
}
dp.sh.Highlighter.prototype.GetKeywordsCSS = function(str) {
//var str = '\\b' + str.replace(/ /g, '(?=:)\\b|\\b') + '\:\\b';
var str = '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
//console.log(str);
return str;
}
dp.sh.Highlighter.prototype.GetValuesCSS = function(str) {
var str = '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
//console.log(str);
return str;
}
dp.sh.Brushes.CSS.prototype = new dp.sh.Highlighter();
dp.sh.Brushes.CSS.Aliases = ['css'];

View File

@@ -0,0 +1,56 @@
if (YUI && yuiConfig) {
YUI(yuiConfig).use('node', 'event-mouseenter', 'later', function(Y) {
var items = Y.all('.yui-syntax-highlight'),
openWindow = function(node, print) {
var n = Y.one('#' + node.get('id') + '-plain'),
code = n.get('value'), win = null,
h = n.get('offsetHeight');
code = code.replace(/</g, '&lt;').replace(/>/g, '&gt;');
win = window.open('', "codeview", "status=0,scrollbars=1,width=600,height=400,menubar=0,toolbar=0,directories=0");
win.document.body.innerHTML = '<pre>' + code + '</pre>';
if (print) {
Y.later(1000, win, function() {
win.focus();
win.print();
win.focus();
});
}
},
handleClick = function(e) {
if (e.target.get('tagName').toLowerCase() == 'a') {
var type = e.target.get('innerHTML').replace(/ /g, '');
switch (type) {
case 'print':
openWindow(e.target.get('parentNode.parentNode'), true);
break;
case 'viewplain':
openWindow(e.target.get('parentNode.parentNode'));
break;
case 'togglelinenumbers':
e.target.get('parentNode.parentNode').toggleClass('yui-syntax-highlight-linenumbers');
break;
case 'copy':
break;
}
}
e.halt();
};
items.each(function(i) {
//var header = Y.Node.create('<div class="syn-header hidden"><a href="#">view plain</a> | <a href="#">print</a> | <a href="#">copy</a></div>');
var header = Y.Node.create('<div class="syn-header hidden"><a href="#">view plain</a> | <a href="#">print</a> | <a href="#">toggle line numbers</a></div>');
header.on('click', handleClick);
i.insertBefore(header, i.get('firstChild'));
i.on('mouseenter', function() {
header.removeClass('hidden');
});
i.on('mouseleave', function() {
header.addClass('hidden');
});
});
});
}

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-base",function(B){var C="running",N="startTime",L="elapsedTime",J="start",I="tween",M="end",D="node",K="paused",P="reverse",H="iterationCount",A=Number;var F={},O={},E;B.Anim=function(){B.Anim.superclass.constructor.apply(this,arguments);O[B.stamp(this)]=this;};B.Anim.NAME="anim";B.Anim.RE_DEFAULT_UNIT=/^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;B.Anim.DEFAULT_UNIT="px";B.Anim.DEFAULT_EASING=function(R,Q,T,S){return T*R/S+Q;};B.Anim.behaviors={left:{get:function(R,Q){return R._getOffset(Q);}}};B.Anim.behaviors.top=B.Anim.behaviors.left;B.Anim.DEFAULT_SETTER=function(U,R,X,W,Q,V,S,T){T=T||"";U._node.setStyle(R,S(Q,A(X),A(W)-A(X),V)+T);};B.Anim.DEFAULT_GETTER=function(Q,R){return Q._node.getComputedStyle(R);};B.Anim.ATTRS={node:{setter:function(Q){Q=B.get(Q);this._node=Q;if(!Q){}return Q;}},duration:{value:1},easing:{value:B.Anim.DEFAULT_EASING,setter:function(Q){if(typeof Q==="string"&&B.Easing){return B.Easing[Q];}}},from:{},to:{},startTime:{value:0,readOnly:true},elapsedTime:{value:0,readOnly:true},running:{getter:function(){return !!F[B.stamp(this)];},value:false,readOnly:true},iterations:{value:1},iterationCount:{value:0,readOnly:true},direction:{value:"normal"},paused:{readOnly:true,value:false},reverse:{value:false}};B.Anim.run=function(){for(var Q in O){if(O[Q].run){O[Q].run();}}};B.Anim.pause=function(){for(var Q in F){if(F[Q].pause){F[Q].pause();}}B.Anim._stopTimer();};B.Anim.stop=function(){for(var Q in F){if(F[Q].stop){F[Q].stop();}}B.Anim._stopTimer();};B.Anim._startTimer=function(){if(!E){E=setInterval(B.Anim._runFrame,1);}};B.Anim._stopTimer=function(){clearInterval(E);E=0;};B.Anim._runFrame=function(){var Q=true;for(var R in F){if(F[R]._runFrame){Q=false;F[R]._runFrame();}}if(Q){B.Anim._stopTimer();}};B.Anim.RE_UNITS=/^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;var G={run:function(){if(!this.get(C)){this._start();}else{if(this.get(K)){this._resume();}}return this;},pause:function(){if(this.get(C)){this._pause();}return this;},stop:function(Q){if(this.get(C)||this.get(K)){this._end(Q);}return this;},_added:false,_start:function(){this._set(N,new Date()-this.get(L));this._actualFrames=0;if(!this.get(K)){this._initAnimAttr();}F[B.stamp(this)]=this;B.Anim._startTimer();this.fire(J);},_pause:function(){this._set(N,null);this._set(K,true);delete F[B.stamp(this)];this.fire("pause");},_resume:function(){this._set(K,false);F[B.stamp(this)]=this;this.fire("resume");},_end:function(Q){this._set(N,null);this._set(L,0);this._set(K,false);delete F[B.stamp(this)];this.fire(M,{elapsed:this.get(L)});},_runFrame:function(){var X=this._runtimeAttr,S=B.Anim.behaviors,Y=X.easing,Z=X.duration,a=new Date()-this.get(N),W=this.get(P),U=(a>=Z),Q=Z,R,T;if(W){a=Z-a;U=(a<=0);Q=0;}for(var V in X){if(X[V].to){R=X[V];T=(V in S&&"set" in S[V])?S[V].set:B.Anim.DEFAULT_SETTER;if(!U){T(this,V,R.from,R.to,a,Z,Y,R.unit);}else{T(this,V,R.from,R.to,Q,Z,Y,R.unit);}}}this._actualFrames+=1;this._set(L,a);this.fire(I);if(U){this._lastFrame();}},_lastFrame:function(){var Q=this.get("iterations"),R=this.get(H);R+=1;if(Q==="infinite"||R<Q){if(this.get("direction")==="alternate"){this.set(P,!this.get(P));}this.fire("iteration");}else{R=0;this._end();}this._set(N,new Date());this._set(H,R);},_initAnimAttr:function(){var X=this.get("from")||{},Y=this.get("to")||{},Q=this.get("duration")*1000,T=this.get(D),W=this.get("easing")||{},V={},R=B.Anim.behaviors,Z,S,U;B.each(Y,function(d,b){if(typeof d==="function"){d=d.call(this,T);}S=X[b];if(S===undefined){S=(b in R&&"get" in R[b])?R[b].get(this,b):B.Anim.DEFAULT_GETTER(this,b);}else{if(typeof S==="function"){S=S.call(this,T);}}var a=B.Anim.RE_UNITS.exec(S);var c=B.Anim.RE_UNITS.exec(d);S=a?a[1]:S;U=c?c[1]:d;Z=c?c[2]:a?a[2]:"";if(!Z&&B.Anim.RE_DEFAULT_UNIT.test(b)){Z=B.Anim.DEFAULT_UNIT;}if(!S||!U){B.error('invalid "from" or "to" for "'+b+'"',"Anim");return;}V[b]={from:S,to:U,unit:Z};V.duration=Q;V.easing=W;},this);this._runtimeAttr=V;},_getOffset:function(R){var T=this._node,U=T.getComputedStyle(R),S=(R==="left")?"getX":"getY",V=(R==="left")?"setX":"setY";if(U==="auto"){var Q=T.getStyle("position");if(Q==="absolute"||Q==="fixed"){U=T[S]();T[V](U);}else{U=0;}}return U;}};B.extend(B.Anim,B.Base,G);},"3.0.0",{requires:["base-base","node-style"]});

View File

@@ -0,0 +1,602 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-base', function(Y) {
/**
* The Animation Utility provides an API for creating advanced transitions.
* @module anim
*/
/**
* Provides the base Anim class, for animating numeric properties.
*
* @module anim
* @submodule anim-base
*/
/**
* A class for constructing animation instances.
* @class Anim
* @for Anim
* @constructor
* @extends Base
*/
var RUNNING = 'running',
START_TIME = 'startTime',
ELAPSED_TIME = 'elapsedTime',
/**
* @for Anim
* @event start
* @description fires when an animation begins.
* @param {Event} ev The start event.
* @type Event.Custom
*/
START = 'start',
/**
* @event tween
* @description fires every frame of the animation.
* @param {Event} ev The tween event.
* @type Event.Custom
*/
TWEEN = 'tween',
/**
* @event end
* @description fires after the animation completes.
* @param {Event} ev The end event.
* @type Event.Custom
*/
END = 'end',
NODE = 'node',
PAUSED = 'paused',
REVERSE = 'reverse', // TODO: cleanup
ITERATION_COUNT = 'iterationCount',
NUM = Number;
var _running = {},
_instances = {},
_timer;
Y.Anim = function() {
Y.Anim.superclass.constructor.apply(this, arguments);
_instances[Y.stamp(this)] = this;
};
Y.Anim.NAME = 'anim';
/**
* Regex of properties that should use the default unit.
*
* @property RE_DEFAULT_UNIT
* @static
*/
Y.Anim.RE_DEFAULT_UNIT = /^width|height|top|right|bottom|left|margin.*|padding.*|border.*$/i;
/**
* The default unit to use with properties that pass the RE_DEFAULT_UNIT test.
*
* @property DEFAULT_UNIT
* @static
*/
Y.Anim.DEFAULT_UNIT = 'px';
Y.Anim.DEFAULT_EASING = function (t, b, c, d) {
return c * t / d + b; // linear easing
};
/**
* Bucket for custom getters and setters
*
* @property behaviors
* @static
*/
Y.Anim.behaviors = {
left: {
get: function(anim, attr) {
return anim._getOffset(attr);
}
}
};
Y.Anim.behaviors.top = Y.Anim.behaviors.left;
/**
* The default setter to use when setting object properties.
*
* @property DEFAULT_SETTER
* @static
*/
Y.Anim.DEFAULT_SETTER = function(anim, att, from, to, elapsed, duration, fn, unit) {
unit = unit || '';
anim._node.setStyle(att, fn(elapsed, NUM(from), NUM(to) - NUM(from), duration) + unit);
};
/**
* The default getter to use when getting object properties.
*
* @property DEFAULT_GETTER
* @static
*/
Y.Anim.DEFAULT_GETTER = function(anim, prop) {
return anim._node.getComputedStyle(prop);
};
Y.Anim.ATTRS = {
/**
* The object to be animated.
* @attribute node
* @type Node
*/
node: {
setter: function(node) {
node = Y.get(node);
this._node = node;
if (!node) {
}
return node;
}
},
/**
* The length of the animation. Defaults to "1" (second).
* @attribute duration
* @type NUM
*/
duration: {
value: 1
},
/**
* The method that will provide values to the attribute(s) during the animation.
* Defaults to "Easing.easeNone".
* @attribute easing
* @type Function
*/
easing: {
value: Y.Anim.DEFAULT_EASING,
setter: function(val) {
if (typeof val === 'string' && Y.Easing) {
return Y.Easing[val];
}
}
},
/**
* The starting values for the animated properties.
* Fields may be strings, numbers, or functions.
* If a function is used, the return value becomes the from value.
* If no from value is specified, the DEFAULT_GETTER will be used.
* @attribute from
* @type Object
*/
from: {},
/**
* The ending values for the animated properties.
* Fields may be strings, numbers, or functions.
* @attribute to
* @type Object
*/
to: {},
/**
* Date stamp for the first frame of the animation.
* @attribute startTime
* @type Int
* @default 0
* @readOnly
*/
startTime: {
value: 0,
readOnly: true
},
/**
* Current time the animation has been running.
* @attribute elapsedTime
* @type Int
* @default 0
* @readOnly
*/
elapsedTime: {
value: 0,
readOnly: true
},
/**
* Whether or not the animation is currently running.
* @attribute running
* @type Boolean
* @default false
* @readOnly
*/
running: {
getter: function() {
return !!_running[Y.stamp(this)];
},
value: false,
readOnly: true
},
/**
* The number of times the animation should run
* @attribute iterations
* @type Int
* @default 1
*/
iterations: {
value: 1
},
/**
* The number of iterations that have occurred.
* Resets when an animation ends (reaches iteration count or stop() called).
* @attribute iterationCount
* @type Int
* @default 0
* @readOnly
*/
iterationCount: {
value: 0,
readOnly: true
},
/**
* How iterations of the animation should behave.
* Possible values are "normal" and "alternate".
* Normal will repeat the animation, alternate will reverse on every other pass.
*
* @attribute direction
* @type String
* @default "normal"
*/
direction: {
value: 'normal' // | alternate (fwd on odd, rev on even per spec)
},
/**
* Whether or not the animation is currently paused.
* @attribute paused
* @type Boolean
* @default false
* @readOnly
*/
paused: {
readOnly: true,
value: false
},
/**
* If true, animation begins from last frame
* @attribute reverse
* @type Boolean
* @default false
*/
reverse: {
value: false
}
};
/**
* Runs all animation instances.
* @method run
* @static
*/
Y.Anim.run = function() {
for (var i in _instances) {
if (_instances[i].run) {
_instances[i].run();
}
}
};
/**
* Pauses all animation instances.
* @method pause
* @static
*/
Y.Anim.pause = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].pause) {
_running[i].pause();
}
}
Y.Anim._stopTimer();
};
/**
* Stops all animation instances.
* @method stop
* @static
*/
Y.Anim.stop = function() {
for (var i in _running) { // stop timer if nothing running
if (_running[i].stop) {
_running[i].stop();
}
}
Y.Anim._stopTimer();
};
Y.Anim._startTimer = function() {
if (!_timer) {
_timer = setInterval(Y.Anim._runFrame, 1);
}
};
Y.Anim._stopTimer = function() {
clearInterval(_timer);
_timer = 0;
};
/**
* Called per Interval to handle each animation frame.
* @method _runFrame
* @private
* @static
*/
Y.Anim._runFrame = function() {
var done = true;
for (var anim in _running) {
if (_running[anim]._runFrame) {
done = false;
_running[anim]._runFrame();
}
}
if (done) {
Y.Anim._stopTimer();
}
};
Y.Anim.RE_UNITS = /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/;
var proto = {
/**
* Starts or resumes an animation.
* percent start time marker.
* @method run
* @chainable
*/
run: function() {
if (!this.get(RUNNING)) {
this._start();
} else if (this.get(PAUSED)) {
this._resume();
}
return this;
},
/**
* Pauses the animation and
* freezes it in its current state and time.
* Calling run() will continue where it left off.
* @method pause
* @chainable
*/
pause: function() {
if (this.get(RUNNING)) {
this._pause();
}
return this;
},
/**
* Stops the animation and resets its time.
* @method stop
* @chainable
*/
stop: function(finish) {
if (this.get(RUNNING) || this.get(PAUSED)) {
this._end(finish);
}
return this;
},
_added: false,
_start: function() {
this._set(START_TIME, new Date() - this.get(ELAPSED_TIME));
this._actualFrames = 0;
if (!this.get(PAUSED)) {
this._initAnimAttr();
}
_running[Y.stamp(this)] = this;
Y.Anim._startTimer();
this.fire(START);
},
_pause: function() {
this._set(START_TIME, null);
this._set(PAUSED, true);
delete _running[Y.stamp(this)];
/**
* @event pause
* @description fires when an animation is paused.
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('pause');
},
_resume: function() {
this._set(PAUSED, false);
_running[Y.stamp(this)] = this;
/**
* @event resume
* @description fires when an animation is resumed (run from pause).
* @param {Event} ev The pause event.
* @type Event.Custom
*/
this.fire('resume');
},
_end: function(finish) {
this._set(START_TIME, null);
this._set(ELAPSED_TIME, 0);
this._set(PAUSED, false);
delete _running[Y.stamp(this)];
this.fire(END, {elapsed: this.get(ELAPSED_TIME)});
},
_runFrame: function() {
var attr = this._runtimeAttr,
customAttr = Y.Anim.behaviors,
easing = attr.easing,
d = attr.duration,
t = new Date() - this.get(START_TIME),
reversed = this.get(REVERSE),
done = (t >= d),
lastFrame = d,
attribute,
setter;
if (reversed) {
t = d - t;
done = (t <= 0);
lastFrame = 0;
}
for (var i in attr) {
if (attr[i].to) {
attribute = attr[i];
setter = (i in customAttr && 'set' in customAttr[i]) ?
customAttr[i].set : Y.Anim.DEFAULT_SETTER;
if (!done) {
setter(this, i, attribute.from, attribute.to, t, d, easing, attribute.unit);
} else { // ensure final frame value is set
// TODO: handle keyframes
setter(this, i, attribute.from, attribute.to, lastFrame, d, easing, attribute.unit);
}
}
}
this._actualFrames += 1;
this._set(ELAPSED_TIME, t);
this.fire(TWEEN);
if (done) {
this._lastFrame();
}
},
_lastFrame: function() {
var iter = this.get('iterations'),
iterCount = this.get(ITERATION_COUNT);
iterCount += 1;
if (iter === 'infinite' || iterCount < iter) {
if (this.get('direction') === 'alternate') {
this.set(REVERSE, !this.get(REVERSE)); // flip it
}
/**
* @event iteration
* @description fires when an animation begins an iteration.
* @param {Event} ev The iteration event.
* @type Event.Custom
*/
this.fire('iteration');
} else {
iterCount = 0;
this._end();
}
this._set(START_TIME, new Date());
this._set(ITERATION_COUNT, iterCount);
},
_initAnimAttr: function() {
var from = this.get('from') || {},
to = this.get('to') || {},
dur = this.get('duration') * 1000,
node = this.get(NODE),
easing = this.get('easing') || {},
attr = {},
customAttr = Y.Anim.behaviors,
unit, begin, end;
Y.each(to, function(val, name) {
if (typeof val === 'function') {
val = val.call(this, node);
}
begin = from[name];
if (begin === undefined) {
begin = (name in customAttr && 'get' in customAttr[name]) ?
customAttr[name].get(this, name) : Y.Anim.DEFAULT_GETTER(this, name);
} else if (typeof begin === 'function') {
begin = begin.call(this, node);
}
var mFrom = Y.Anim.RE_UNITS.exec(begin);
var mTo = Y.Anim.RE_UNITS.exec(val);
begin = mFrom ? mFrom[1] : begin;
end = mTo ? mTo[1] : val;
unit = mTo ? mTo[2] : mFrom ? mFrom[2] : ''; // one might be zero TODO: mixed units
if (!unit && Y.Anim.RE_DEFAULT_UNIT.test(name)) {
unit = Y.Anim.DEFAULT_UNIT;
}
if (!begin || !end) {
Y.error('invalid "from" or "to" for "' + name + '"', 'Anim');
return;
}
attr[name] = {
from: begin,
to: end,
unit: unit
};
attr.duration = dur;
attr.easing = easing;
}, this);
this._runtimeAttr = attr;
},
// TODO: move to computedStyle? (browsers dont agree on default computed offsets)
_getOffset: function(attr) {
var node = this._node,
val = node.getComputedStyle(attr),
get = (attr === 'left') ? 'getX': 'getY',
set = (attr === 'left') ? 'setX': 'setY';
if (val === 'auto') {
var position = node.getStyle('position');
if (position === 'absolute' || position === 'fixed') {
val = node[get]();
node[set](val);
} else {
val = 0;
}
}
return val;
}
};
Y.extend(Y.Anim, Y.Base, proto);
}, '3.0.0' ,{requires:['base-base', 'node-style']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-color",function(B){var A=Number;B.Anim.behaviors.color={set:function(F,D,I,H,C,G,E){I=B.Color.re_RGB.exec(B.Color.toRGB(I));H=B.Color.re_RGB.exec(B.Color.toRGB(H));if(!I||I.length<3||!H||H.length<3){B.error("invalid from or to passed to color behavior");}F._node.setStyle(D,"rgb("+[Math.floor(E(C,A(I[1]),A(H[1])-A(I[1]),G)),Math.floor(E(C,A(I[2]),A(H[2])-A(I[2]),G)),Math.floor(E(C,A(I[3]),A(H[3])-A(I[3]),G))].join(", ")+")");},get:function(D,C){var E=D._node.getComputedStyle(C);E=(E==="transparent")?"rgb(255, 255, 255)":E;return E;}};B.each(["backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor"],function(C,D){B.Anim.behaviors[C]=B.Anim.behaviors.color;});},"3.0.0",{requires:["anim-base"]});

View File

@@ -0,0 +1,55 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-color', function(Y) {
/**
* Adds support for color properties in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-color
*/
var NUM = Number;
Y.Anim.behaviors.color = {
set: function(anim, att, from, to, elapsed, duration, fn) {
from = Y.Color.re_RGB.exec(Y.Color.toRGB(from));
to = Y.Color.re_RGB.exec(Y.Color.toRGB(to));
if (!from || from.length < 3 || !to || to.length < 3) {
Y.error('invalid from or to passed to color behavior');
}
anim._node.setStyle(att, 'rgb(' + [
Math.floor(fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)),
Math.floor(fn(elapsed, NUM(from[2]), NUM(to[2]) - NUM(from[2]), duration)),
Math.floor(fn(elapsed, NUM(from[3]), NUM(to[3]) - NUM(from[3]), duration))
].join(', ') + ')');
},
// TODO: default bgcolor const
get: function(anim, att) {
var val = anim._node.getComputedStyle(att);
val = (val === 'transparent') ? 'rgb(255, 255, 255)' : val;
return val;
}
};
Y.each(['backgroundColor',
'borderColor',
'borderTopColor',
'borderRightColor',
'borderBottomColor',
'borderLeftColor'],
function(v, i) {
Y.Anim.behaviors[v] = Y.Anim.behaviors.color;
}
);
}, '3.0.0' ,{requires:['anim-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-curve",function(A){A.Anim.behaviors.curve={set:function(F,C,I,H,B,G,E){I=I.slice.call(I);H=H.slice.call(H);var D=E(B,0,100,G)/100;H.unshift(I);F._node.setXY(A.Anim.getBezier(H,D));},get:function(C,B){return C._node.getXY();}};A.Anim.getBezier=function(F,E){var G=F.length;var D=[];for(var C=0;C<G;++C){D[C]=[F[C][0],F[C][1]];}for(var B=1;B<G;++B){for(C=0;C<G-B;++C){D[C][0]=(1-E)*D[C][0]+E*D[parseInt(C+1,10)][0];D[C][1]=(1-E)*D[C][1]+E*D[parseInt(C+1,10)][1];}}return[D[0][0],D[0][1]];};},"3.0.0",{requires:["anim-xy"]});

View File

@@ -0,0 +1,64 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-curve', function(Y) {
/**
* Adds support for the <code>curve</code> property for the <code>to</code>
* attribute. A curve is zero or more control points and an end point.
* @module anim
* @submodule anim-curve
*/
Y.Anim.behaviors.curve = {
set: function(anim, att, from, to, elapsed, duration, fn) {
from = from.slice.call(from);
to = to.slice.call(to);
var t = fn(elapsed, 0, 100, duration) / 100;
to.unshift(from);
anim._node.setXY(Y.Anim.getBezier(to, t));
},
get: function(anim, att) {
return anim._node.getXY();
}
};
/**
* Get the current position of the animated element based on t.
* Each point is an array of "x" and "y" values (0 = x, 1 = y)
* At least 2 points are required (start and end).
* First point is start. Last point is end.
* Additional control points are optional.
* @for Anim
* @method getBezier
* @static
* @param {Array} points An array containing Bezier points
* @param {Number} t A number between 0 and 1 which is the basis for determining current position
* @return {Array} An array containing int x and y member data
*/
Y.Anim.getBezier = function(points, t) {
var n = points.length;
var tmp = [];
for (var i = 0; i < n; ++i){
tmp[i] = [points[i][0], points[i][1]]; // save input
}
for (var j = 1; j < n; ++j) {
for (i = 0; i < n - j; ++i) {
tmp[i][0] = (1 - t) * tmp[i][0] + t * tmp[parseInt(i + 1, 10)][0];
tmp[i][1] = (1 - t) * tmp[i][1] + t * tmp[parseInt(i + 1, 10)][1];
}
}
return [ tmp[0][0], tmp[0][1] ];
};
}, '3.0.0' ,{requires:['anim-xy']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-easing",function(A){A.Easing={easeNone:function(C,B,E,D){return E*C/D+B;},easeIn:function(C,B,E,D){return E*(C/=D)*C+B;},easeOut:function(C,B,E,D){return -E*(C/=D)*(C-2)+B;},easeBoth:function(C,B,E,D){if((C/=D/2)<1){return E/2*C*C+B;}return -E/2*((--C)*(C-2)-1)+B;},easeInStrong:function(C,B,E,D){return E*(C/=D)*C*C*C+B;},easeOutStrong:function(C,B,E,D){return -E*((C=C/D-1)*C*C*C-1)+B;},easeBothStrong:function(C,B,E,D){if((C/=D/2)<1){return E/2*C*C*C*C+B;}return -E/2*((C-=2)*C*C*C-2)+B;},elasticIn:function(D,B,H,G,C,F){var E;if(D===0){return B;}if((D/=G)===1){return B+H;}if(!F){F=G*0.3;}if(!C||C<Math.abs(H)){C=H;E=F/4;}else{E=F/(2*Math.PI)*Math.asin(H/C);}return -(C*Math.pow(2,10*(D-=1))*Math.sin((D*G-E)*(2*Math.PI)/F))+B;},elasticOut:function(D,B,H,G,C,F){var E;if(D===0){return B;}if((D/=G)===1){return B+H;}if(!F){F=G*0.3;}if(!C||C<Math.abs(H)){C=H;E=F/4;}else{E=F/(2*Math.PI)*Math.asin(H/C);}return C*Math.pow(2,-10*D)*Math.sin((D*G-E)*(2*Math.PI)/F)+H+B;},elasticBoth:function(D,B,H,G,C,F){var E;if(D===0){return B;}if((D/=G/2)===2){return B+H;}if(!F){F=G*(0.3*1.5);}if(!C||C<Math.abs(H)){C=H;E=F/4;}else{E=F/(2*Math.PI)*Math.asin(H/C);}if(D<1){return -0.5*(C*Math.pow(2,10*(D-=1))*Math.sin((D*G-E)*(2*Math.PI)/F))+B;}return C*Math.pow(2,-10*(D-=1))*Math.sin((D*G-E)*(2*Math.PI)/F)*0.5+H+B;},backIn:function(C,B,F,E,D){if(D===undefined){D=1.70158;}if(C===E){C-=0.001;}return F*(C/=E)*C*((D+1)*C-D)+B;},backOut:function(C,B,F,E,D){if(typeof D==="undefined"){D=1.70158;}return F*((C=C/E-1)*C*((D+1)*C+D)+1)+B;},backBoth:function(C,B,F,E,D){if(typeof D==="undefined"){D=1.70158;}if((C/=E/2)<1){return F/2*(C*C*(((D*=(1.525))+1)*C-D))+B;}return F/2*((C-=2)*C*(((D*=(1.525))+1)*C+D)+2)+B;},bounceIn:function(C,B,E,D){return E-A.Easing.bounceOut(D-C,0,E,D)+B;},bounceOut:function(C,B,E,D){if((C/=D)<(1/2.75)){return E*(7.5625*C*C)+B;}else{if(C<(2/2.75)){return E*(7.5625*(C-=(1.5/2.75))*C+0.75)+B;}else{if(C<(2.5/2.75)){return E*(7.5625*(C-=(2.25/2.75))*C+0.9375)+B;}}}return E*(7.5625*(C-=(2.625/2.75))*C+0.984375)+B;},bounceBoth:function(C,B,E,D){if(C<D/2){return A.Easing.bounceIn(C*2,0,E,D)*0.5+B;}return A.Easing.bounceOut(C*2-D,0,E,D)*0.5+E*0.5+B;}};},"3.0.0",{requires:["anim-base"]});

View File

@@ -0,0 +1,355 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-easing', function(Y) {
/*
TERMS OF USE - EASING EQUATIONS
Open source under the BSD License.
Copyright 2001 Robert Penner All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The easing module provides methods for customizing
* how an animation behaves during each run.
* @class Easing
* @module anim
* @submodule anim-easing
*/
Y.Easing = {
/**
* Uniform speed between points.
* @for Easing
* @method easeNone
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeNone: function (t, b, c, d) {
return c*t/d + b;
},
/**
* Begins slowly and accelerates towards end. (quadratic)
* @method easeIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeIn: function (t, b, c, d) {
return c*(t/=d)*t + b;
},
/**
* Begins quickly and decelerates towards end. (quadratic)
* @method easeOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeOut: function (t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
},
/**
* Begins slowly and decelerates towards end. (quadratic)
* @method easeBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeBoth: function (t, b, c, d) {
if ((t/=d/2) < 1) {
return c/2*t*t + b;
}
return -c/2 * ((--t)*(t-2) - 1) + b;
},
/**
* Begins slowly and accelerates towards end. (quartic)
* @method easeInStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeInStrong: function (t, b, c, d) {
return c*(t/=d)*t*t*t + b;
},
/**
* Begins quickly and decelerates towards end. (quartic)
* @method easeOutStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeOutStrong: function (t, b, c, d) {
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
/**
* Begins slowly and decelerates towards end. (quartic)
* @method easeBothStrong
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
easeBothStrong: function (t, b, c, d) {
if ((t/=d/2) < 1) {
return c/2*t*t*t*t + b;
}
return -c/2 * ((t-=2)*t*t*t - 2) + b;
},
/**
* Snap in elastic effect.
* @method elasticIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticIn: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d) === 1 ) {
return b+c;
}
if (!p) {
p = d* 0.3;
}
if (!a || a < Math.abs(c)) {
a = c;
s = p/4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
},
/**
* Snap out elastic effect.
* @method elasticOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticOut: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d) === 1 ) {
return b+c;
}
if (!p) {
p=d * 0.3;
}
if (!a || a < Math.abs(c)) {
a = c;
s = p / 4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
},
/**
* Snap both elastic effect.
* @method elasticBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} a Amplitude (optional)
* @param {Number} p Period (optional)
* @return {Number} The computed value for the current animation frame
*/
elasticBoth: function (t, b, c, d, a, p) {
var s;
if (t === 0) {
return b;
}
if ( (t /= d/2) === 2 ) {
return b+c;
}
if (!p) {
p = d*(0.3*1.5);
}
if ( !a || a < Math.abs(c) ) {
a = c;
s = p/4;
}
else {
s = p/(2*Math.PI) * Math.asin (c/a);
}
if (t < 1) {
return -0.5*(a*Math.pow(2,10*(t-=1)) *
Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
}
return a*Math.pow(2,-10*(t-=1)) *
Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
},
/**
* Backtracks slightly, then reverses direction and moves to end.
* @method backIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backIn: function (t, b, c, d, s) {
if (s === undefined) {
s = 1.70158;
}
if (t === d) {
t -= 0.001;
}
return c*(t/=d)*t*((s+1)*t - s) + b;
},
/**
* Overshoots end, then reverses and comes back to end.
* @method backOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backOut: function (t, b, c, d, s) {
if (typeof s === 'undefined') {
s = 1.70158;
}
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
/**
* Backtracks slightly, then reverses direction, overshoots end,
* then reverses and comes back to end.
* @method backBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @param {Number} s Overshoot (optional)
* @return {Number} The computed value for the current animation frame
*/
backBoth: function (t, b, c, d, s) {
if (typeof s === 'undefined') {
s = 1.70158;
}
if ((t /= d/2 ) < 1) {
return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
}
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
},
/**
* Bounce off of start.
* @method bounceIn
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceIn: function (t, b, c, d) {
return c - Y.Easing.bounceOut(d-t, 0, c, d) + b;
},
/**
* Bounces off end.
* @method bounceOut
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceOut: function (t, b, c, d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
}
return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
},
/**
* Bounces off start and end.
* @method bounceBoth
* @param {Number} t Time value used to compute current value
* @param {Number} b Starting value
* @param {Number} c Delta between start and end values
* @param {Number} d Total length of animation
* @return {Number} The computed value for the current animation frame
*/
bounceBoth: function (t, b, c, d) {
if (t < d/2) {
return Y.Easing.bounceIn(t * 2, 0, c, d) * 0.5 + b;
}
return Y.Easing.bounceOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
}
};
}, '3.0.0' ,{requires:['anim-base']});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-node-plugin",function(B){var A=function(C){C=(C)?B.merge(C):{};C.node=C.host;A.superclass.constructor.apply(this,arguments);};A.NAME="nodefx";A.NS="fx";B.extend(A,B.Anim);B.namespace("Plugin");B.Plugin.NodeFX=A;},"3.0.0",{requires:["node-pluginhost","anim-base"]});

View File

@@ -0,0 +1,33 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-node-plugin', function(Y) {
/**
* Binds an Anim instance to a Node instance
* @module anim
* @class Plugin.NodeFX
* @extends Base
* @submodule anim-node-plugin
*/
var NodeFX = function(config) {
config = (config) ? Y.merge(config) : {};
config.node = config.host;
NodeFX.superclass.constructor.apply(this, arguments);
};
NodeFX.NAME = "nodefx";
NodeFX.NS = "fx";
Y.extend(NodeFX, Y.Anim);
Y.namespace('Plugin');
Y.Plugin.NodeFX = NodeFX;
}, '3.0.0' ,{requires:['node-pluginhost', 'anim-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-scroll",function(B){var A=Number;B.Anim.behaviors.scroll={set:function(F,G,I,J,K,E,H){var D=F._node,C=([H(K,A(I[0]),A(J[0])-A(I[0]),E),H(K,A(I[1]),A(J[1])-A(I[1]),E)]);if(C[0]){D.set("scrollLeft",C[0]);}if(C[1]){D.set("scrollTop",C[1]);}},get:function(D){var C=D._node;return[C.get("scrollLeft"),C.get("scrollTop")];}};},"3.0.0",{requires:["anim-base"]});

View File

@@ -0,0 +1,45 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-scroll', function(Y) {
/**
* Adds support for the <code>scroll</code> property in <code>to</code>
* and <code>from</code> attributes.
* @module anim
* @submodule anim-scroll
*/
var NUM = Number;
//TODO: deprecate for scrollTop/Left properties?
Y.Anim.behaviors.scroll = {
set: function(anim, att, from, to, elapsed, duration, fn) {
var
node = anim._node,
val = ([
fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
]);
if (val[0]) {
node.set('scrollLeft', val[0]);
}
if (val[1]) {
node.set('scrollTop', val[1]);
}
},
get: function(anim) {
var node = anim._node;
return [node.get('scrollLeft'), node.get('scrollTop')];
}
};
}, '3.0.0' ,{requires:['anim-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("anim-xy",function(B){var A=Number;B.Anim.behaviors.xy={set:function(F,D,I,H,C,G,E){F._node.setXY([E(C,A(I[0]),A(H[0])-A(I[0]),G),E(C,A(I[1]),A(H[1])-A(I[1]),G)]);},get:function(C){return C._node.getXY();}};},"3.0.0",{requires:["anim-base","node-screen"]});

View File

@@ -0,0 +1,33 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('anim-xy', function(Y) {
/**
* Adds support for the <code>xy</code> property in <code>from</code> and
* <code>to</code> attributes.
* @module anim
* @submodule anim-xy
*/
var NUM = Number;
Y.Anim.behaviors.xy = {
set: function(anim, att, from, to, elapsed, duration, fn) {
anim._node.setXY([
fn(elapsed, NUM(from[0]), NUM(to[0]) - NUM(from[0]), duration),
fn(elapsed, NUM(from[1]), NUM(to[1]) - NUM(from[1]), duration)
]);
},
get: function(anim) {
return anim._node.getXY();
}
};
}, '3.0.0' ,{requires:['anim-base', 'node-screen']});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("async-queue",function(G){G.AsyncQueue=function(){this._init();this.add.apply(this,arguments);};var E=G.AsyncQueue,C="execute",B="shift",D="promote",H="remove",A=G.Lang.isObject,F=G.Lang.isFunction;E.defaults=G.mix({autoContinue:true,iterations:1,timeout:10,until:function(){this.iterations|=0;return this.iterations<=0;}},G.config.queueDefaults||{});G.extend(E,G.EventTarget,{_running:false,_init:function(){G.EventTarget.call(this,{emitFacade:true});this._q=[];this.defaults={};this._initEvents();},_initEvents:function(){this.publish("execute",{defaultFn:this._defExecFn,emitFacade:true});this.publish("shift",{defaultFn:this._defShiftFn,emitFacade:true});this.publish("add",{defaultFn:this._defAddFn,emitFacade:true});this.publish("promote",{defaultFn:this._defPromoteFn,emitFacade:true});this.publish("remove",{defaultFn:this._defRemoveFn,emitFacade:true});},next:function(){var I;while(this._q.length){I=this._q[0]=this._prepare(this._q[0]);if(I&&I.until()){this.fire(B,{callback:I});I=null;}else{break;}}return I||null;},_defShiftFn:function(I){if(this.indexOf(I.callback)===0){this._q.shift();}},_prepare:function(K){if(F(K)&&K._prepared){return K;}var I=G.merge(E.defaults,{context:this,args:[],_prepared:true},this.defaults,(F(K)?{fn:K}:K)),J=G.bind(function(){if(!J._running){J.iterations--;}if(F(J.fn)){J.fn.apply(J.context||G,G.Array(J.args));}},this);return G.mix(J,I);},run:function(){var J,I=true;for(J=this.next();I&&J&&!this.isRunning();J=this.next()){I=(J.timeout<0)?this._execute(J):this._schedule(J);}if(!J){this.fire("complete");}return this;},_execute:function(J){this._running=J._running=true;J.iterations--;this.fire(C,{callback:J});var I=this._running&&J.autoContinue;this._running=J._running=false;return I;},_schedule:function(I){this._running=G.later(I.timeout,this,function(){if(this._execute(I)){this.run();}});return false;},isRunning:function(){return !!this._running;},_defExecFn:function(I){I.callback();},add:function(){this.fire("add",{callbacks:G.Array(arguments,0,true)});return this;},_defAddFn:function(J){var K=this._q,I=[];G.Array.each(J.callbacks,function(L){if(A(L)){K.push(L);I.push(L);}});J.added=I;},pause:function(){if(A(this._running)){this._running.cancel();}this._running=false;return this;},stop:function(){this._q=[];return this.pause();},indexOf:function(L){var J=0,I=this._q.length,K;for(;J<I;++J){K=this._q[J];if(K===L||K.id===L){return J;}}return -1;},getCallback:function(J){var I=this.indexOf(J);return(I>-1)?this._q[I]:null;},promote:function(K){var J={callback:K},I;if(this.isRunning()){I=this.after(B,function(){this.fire(D,J);I.detach();},this);}else{this.fire(D,J);}return this;},_defPromoteFn:function(K){var I=this.indexOf(K.callback),J=(I>-1)?this._q.splice(I,1)[0]:null;K.promoted=J;if(J){this._q.unshift(J);}},remove:function(K){var J={callback:K},I;if(this.isRunning()){I=this.after(B,function(){this.fire(H,J);I.detach();},this);}else{this.fire(H,J);}return this;},_defRemoveFn:function(J){var I=this.indexOf(J.callback);J.removed=(I>-1)?this._q.splice(I,1)[0]:null;},size:function(){if(!this.isRunning()){this.next();}return this._q.length;}});},"3.0.0",{requires:["event-custom"]});

View File

@@ -0,0 +1,536 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('async-queue', function(Y) {
/**
* <p>AsyncQueue allows you create a chain of function callbacks executed
* via setTimeout (or synchronously) that are guaranteed to run in order.
* Items in the queue can be promoted or removed. Start or resume the
* execution chain with run(). pause() to temporarily delay execution, or
* stop() to halt and clear the queue.</p>
*
* @module async-queue
*/
/**
* <p>A specialized queue class that supports scheduling callbacks to execute
* sequentially, iteratively, even asynchronously.</p>
*
* <p>Callbacks can be function refs or objects with the following keys. Only
* the <code>fn</code> key is required.</p>
*
* <ul>
* <li><code>fn</code> -- The callback function</li>
* <li><code>context</code> -- The execution context for the callbackFn.</li>
* <li><code>args</code> -- Arguments to pass to callbackFn.</li>
* <li><code>timeout</code> -- Millisecond delay before executing callbackFn.
* (Applies to each iterative execution of callback)</li>
* <li><code>iterations</code> -- Number of times to repeat the callback.
* <li><code>until</code> -- Repeat the callback until this function returns
* true. This setting trumps iterations.</li>
* <li><code>autoContinue</code> -- Set to false to prevent the AsyncQueue from
* executing the next callback in the Queue after
* the callback completes.</li>
* <li><code>id</code> -- Name that can be used to get, promote, get the
* indexOf, or delete this callback.</li>
* </ul>
*
* @class AsyncQueue
* @extends EventTarget
* @constructor
* @param callback* {Function|Object} 0..n callbacks to seed the queue
*/
Y.AsyncQueue = function() {
this._init();
this.add.apply(this, arguments);
};
var Queue = Y.AsyncQueue,
EXECUTE = 'execute',
SHIFT = 'shift',
PROMOTE = 'promote',
REMOVE = 'remove',
isObject = Y.Lang.isObject,
isFunction = Y.Lang.isFunction;
/**
* <p>Static default values used to populate callback configuration properties.
* Preconfigured defaults include:</p>
*
* <ul>
* <li><code>autoContinue</code>: <code>true</code></li>
* <li><code>iterations</code>: 1</li>
* <li><code>timeout</code>: 10 (10ms between callbacks)</li>
* <li><code>until</code>: (function to run until iterations &lt;= 0)</li>
* </ul>
*
* @property AsyncQueue.defaults
* @type {Object}
* @static
*/
Queue.defaults = Y.mix({
autoContinue : true,
iterations : 1,
timeout : 10,
until : function () {
this.iterations |= 0;
return this.iterations <= 0;
}
}, Y.config.queueDefaults || {});
Y.extend(Queue, Y.EventTarget, {
/**
* Used to indicate the queue is currently executing a callback.
*
* @property _running
* @type {Boolean|Object} true for synchronous callback execution, the
* return handle from Y.later for async callbacks.
* Otherwise false.
* @protected
*/
_running : false,
/**
* Initializes the AsyncQueue instance properties and events.
*
* @method _init
* @protected
*/
_init : function () {
Y.EventTarget.call(this, { emitFacade: true });
this._q = [];
/**
* Callback defaults for this instance. Static defaults that are not
* overridden are also included.
*
* @property defaults
* @type {Object}
*/
this.defaults = {};
this._initEvents();
},
/**
* Initializes the instance events.
*
* @method _initEvents
* @protected
*/
_initEvents : function () {
/*
this.publish({
'execute' : { defaultFn : this._defExecFn },
'shift' : { defaultFn : this._defShiftFn },
'add' : { defaultFn : this._defAddFn },
'promote' : { defaultFn : this._defPromoteFn },
'remove' : { defaultFn : this._defRemoveFn }
});
*/
this.publish('execute' , { defaultFn : this._defExecFn, emitFacade: true });
this.publish('shift' , { defaultFn : this._defShiftFn, emitFacade: true });
this.publish('add' , { defaultFn : this._defAddFn, emitFacade: true });
this.publish('promote' , { defaultFn : this._defPromoteFn, emitFacade: true });
this.publish('remove' , { defaultFn : this._defRemoveFn, emitFacade: true });
},
/**
* Returns the next callback needing execution. If a callback is
* configured to repeat via iterations or until, it will be returned until
* the completion criteria is met.
*
* When the queue is empty, null is returned.
*
* @method next
* @return {Function} the callback to execute
*/
next : function () {
var callback;
while (this._q.length) {
callback = this._q[0] = this._prepare(this._q[0]);
if (callback && callback.until()) {
this.fire(SHIFT, { callback: callback });
callback = null;
} else {
break;
}
}
return callback || null;
},
/**
* Default functionality for the &quot;shift&quot; event. Shifts the
* callback stored in the event object's <em>callback</em> property from
* the queue if it is the first item.
*
* @method _defShiftFn
* @param e {Event} The event object
* @protected
*/
_defShiftFn : function (e) {
if (this.indexOf(e.callback) === 0) {
this._q.shift();
}
},
/**
* Creates a wrapper function to execute the callback using the aggregated
* configuration generated by combining the static AsyncQueue.defaults, the
* instance defaults, and the specified callback settings.
*
* The wrapper function is decorated with the callback configuration as
* properties for runtime modification.
*
* @method _prepare
* @param callback {Object|Function} the raw callback
* @return {Function} a decorated function wrapper to execute the callback
* @protected
*/
_prepare: function (callback) {
if (isFunction(callback) && callback._prepared) {
return callback;
}
var config = Y.merge(
Queue.defaults,
{ context : this, args: [], _prepared: true },
this.defaults,
(isFunction(callback) ? { fn: callback } : callback)),
wrapper = Y.bind(function () {
if (!wrapper._running) {
wrapper.iterations--;
}
if (isFunction(wrapper.fn)) {
wrapper.fn.apply(wrapper.context || Y,
Y.Array(wrapper.args));
}
}, this);
return Y.mix(wrapper, config);
},
/**
* Sets the queue in motion. All queued callbacks will be executed in
* order unless pause() or stop() is called or if one of the callbacks is
* configured with autoContinue: false.
*
* @method run
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
run : function () {
var callback,
cont = true;
for (callback = this.next();
cont && callback && !this.isRunning();
callback = this.next())
{
cont = (callback.timeout < 0) ?
this._execute(callback) :
this._schedule(callback);
}
if (!callback) {
/**
* Event fired after the last queued callback is executed.
* @event complete
*/
this.fire('complete');
}
return this;
},
/**
* Handles the execution of callbacks. Returns a boolean indicating
* whether it is appropriate to continue running.
*
* @method _execute
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_execute : function (callback) {
this._running = callback._running = true;
callback.iterations--;
this.fire(EXECUTE, { callback: callback });
var cont = this._running && callback.autoContinue;
this._running = callback._running = false;
return cont;
},
/**
* Schedules the execution of asynchronous callbacks.
*
* @method _schedule
* @param callback {Object} the callback object to execute
* @return {Boolean} whether the run loop should continue
* @protected
*/
_schedule : function (callback) {
this._running = Y.later(callback.timeout, this, function () {
if (this._execute(callback)) {
this.run();
}
});
return false;
},
/**
* Determines if the queue is waiting for a callback to complete execution.
*
* @method isRunning
* @return {Boolean} true if queue is waiting for a
* from any initiated transactions
*/
isRunning : function () {
return !!this._running;
},
/**
* Default functionality for the &quot;execute&quot; event. Executes the
* callback function
*
* @method _defExecFn
* @param e {Event} the event object
* @protected
*/
_defExecFn : function (e) {
e.callback();
},
/**
* Add any number of callbacks to the end of the queue. Callbacks may be
* provided as functions or objects.
*
* @method add
* @param callback* {Function|Object} 0..n callbacks
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
add : function () {
this.fire('add', { callbacks: Y.Array(arguments,0,true) });
return this;
},
/**
* Default functionality for the &quot;add&quot; event. Adds the callbacks
* in the event facade to the queue. Callbacks successfully added to the
* queue are present in the event's <code>added</code> property in the
* after phase.
*
* @method _defAddFn
* @param e {Event} the event object
* @protected
*/
_defAddFn : function(e) {
var _q = this._q,
added = [];
Y.Array.each(e.callbacks, function (c) {
if (isObject(c)) {
_q.push(c);
added.push(c);
}
});
e.added = added;
},
/**
* Pause the execution of the queue after the execution of the current
* callback completes. If called from code outside of a queued callback,
* clears the timeout for the pending callback. Paused queue can be
* restarted with q.run()
*
* @method pause
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
pause: function () {
if (isObject(this._running)) {
this._running.cancel();
}
this._running = false;
return this;
},
/**
* Stop and clear the queue after the current execution of the
* current callback completes.
*
* @method stop
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
stop : function () {
this._q = [];
return this.pause();
},
/**
* Returns the current index of a callback. Pass in either the id or
* callback function from getCallback.
*
* @method indexOf
* @param callback {String|Function} the callback or its specified id
* @return {Number} index of the callback or -1 if not found
*/
indexOf : function (callback) {
var i = 0, len = this._q.length, c;
for (; i < len; ++i) {
c = this._q[i];
if (c === callback || c.id === callback) {
return i;
}
}
return -1;
},
/**
* Retrieve a callback by its id. Useful to modify the configuration
* while the queue is running.
*
* @method getCallback
* @param id {String} the id assigned to the callback
* @return {Object} the callback object
*/
getCallback : function (id) {
var i = this.indexOf(id);
return (i > -1) ? this._q[i] : null;
},
/**
* Promotes the named callback to the top of the queue. If a callback is
* currently executing or looping (via until or iterations), the promotion
* is scheduled to occur after the current callback has completed.
*
* @method promote
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
promote : function (callback) {
var payload = { callback : callback },e;
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(PROMOTE, payload);
e.detach();
}, this);
} else {
this.fire(PROMOTE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;promote&quot; event. Promotes the
* named callback to the head of the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defPromoteFn
* @param e {Event} the custom event
* @protected
*/
_defPromoteFn : function (e) {
var i = this.indexOf(e.callback),
promoted = (i > -1) ? this._q.splice(i,1)[0] : null;
e.promoted = promoted;
if (promoted) {
this._q.unshift(promoted);
}
},
/**
* Removes the callback from the queue. If the queue is active, the
* removal is scheduled to occur after the current callback has completed.
*
* @method remove
* @param callback {String|Object} the callback object or a callback's id
* @return {AsyncQueue} the AsyncQueue instance
* @chainable
*/
remove : function (callback) {
var payload = { callback : callback },e;
// Can't return the removed callback because of the deferral until
// current callback is complete
if (this.isRunning()) {
e = this.after(SHIFT, function () {
this.fire(REMOVE, payload);
e.detach();
},this);
} else {
this.fire(REMOVE, payload);
}
return this;
},
/**
* <p>Default functionality for the &quot;remove&quot; event. Removes the
* callback from the queue.</p>
*
* <p>The event object will contain a property &quot;callback&quot;, which
* holds the id of a callback or the callback object itself.</p>
*
* @method _defRemoveFn
* @param e {Event} the custom event
* @protected
*/
_defRemoveFn : function (e) {
var i = this.indexOf(e.callback);
e.removed = (i > -1) ? this._q.splice(i,1)[0] : null;
},
/**
* Returns the number of callbacks in the queue.
*
* @method size
* @return {Number}
*/
size : function () {
// next() flushes callbacks that have met their until() criteria and
// therefore shouldn't count since they wouldn't execute anyway.
if (!this.isRunning()) {
this.next();
}
return this._q.length;
}
});
}, '3.0.0' ,{requires:['event-custom']});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("attribute-complex",function(B){var A=B.Object,C=".";B.Attribute.Complex=function(){};B.Attribute.Complex.prototype={_normAttrVals:function(G){var I={},H={},J,D,F,E;if(G){for(E in G){if(G.hasOwnProperty(E)){if(E.indexOf(C)!==-1){J=E.split(C);D=J.shift();F=H[D]=H[D]||[];F[F.length]={path:J,value:G[E]};}else{I[E]=G[E];}}}return{simple:I,complex:H};}else{return null;}},_getAttrInitVal:function(K,I,M){var E=(I.valueFn)?I.valueFn.call(this):I.value,D,F,H,G,N,L,J;if(!I.readOnly&&M){D=M.simple;if(D&&D.hasOwnProperty(K)){E=D[K];}F=M.complex;if(F&&F.hasOwnProperty(K)){J=F[K];for(H=0,G=J.length;H<G;++H){N=J[H].path;L=J[H].value;A.setValue(E,N,L);}}}return E;}};B.mix(B.Attribute,B.Attribute.Complex,true,null,1);},"3.0.0",{requires:["attribute-base"]});

View File

@@ -0,0 +1,120 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('attribute-complex', function(Y) {
/**
* Adds support for attribute providers to handle complex attributes in the constructor
*
* @module attribute
* @submodule attribute-complex
* @for Attribute
*/
var O = Y.Object,
DOT = ".";
Y.Attribute.Complex = function() {};
Y.Attribute.Complex.prototype = {
/**
* Utility method to split out simple attribute name/value pairs ("x")
* from complex attribute name/value pairs ("x.y.z"), so that complex
* attributes can be keyed by the top level attribute name.
*
* @method _normAttrVals
* @param {Object} valueHash An object with attribute name/value pairs
*
* @return {Object} An object literal with 2 properties - "simple" and "complex",
* containing simple and complex attribute values respectively keyed
* by the top level attribute name, or null, if valueHash is falsey.
*
* @private
*/
_normAttrVals : function(valueHash) {
var vals = {},
subvals = {},
path,
attr,
v, k;
if (valueHash) {
for (k in valueHash) {
if (valueHash.hasOwnProperty(k)) {
if (k.indexOf(DOT) !== -1) {
path = k.split(DOT);
attr = path.shift();
v = subvals[attr] = subvals[attr] || [];
v[v.length] = {
path : path,
value: valueHash[k]
};
} else {
vals[k] = valueHash[k];
}
}
}
return { simple:vals, complex:subvals };
} else {
return null;
}
},
/**
* Returns the initial value of the given attribute from
* either the default configuration provided, or the
* over-ridden value if it exists in the set of initValues
* provided and the attribute is not read-only.
*
* @param {String} attr The name of the attribute
* @param {Object} cfg The attribute configuration object
* @param {Object} initValues The object with simple and complex attribute name/value pairs returned from _normAttrVals
*
* @return {Any} The initial value of the attribute.
*
* @method _getAttrInitVal
* @private
*/
_getAttrInitVal : function(attr, cfg, initValues) {
var val = (cfg.valueFn) ? cfg.valueFn.call(this) : cfg.value,
simple,
complex,
i,
l,
path,
subval,
subvals;
if (!cfg.readOnly && initValues) {
// Simple Attributes
simple = initValues.simple;
if (simple && simple.hasOwnProperty(attr)) {
val = simple[attr];
}
// Complex Attributes (complex values applied, after simple, incase both are set)
complex = initValues.complex;
if (complex && complex.hasOwnProperty(attr)) {
subvals = complex[attr];
for (i = 0, l = subvals.length; i < l; ++i) {
path = subvals[i].path;
subval = subvals[i].value;
O.setValue(val, path, subval);
}
}
}
return val;
}
};
Y.mix(Y.Attribute, Y.Attribute.Complex, true, null, 1);
}, '3.0.0' ,{requires:['attribute-base']});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("base-base",function(B){var H=B.Object,J=B.Lang,I=".",F="destroy",P="init",N="initialized",G="destroyed",D="initializer",C=Object.prototype.constructor,K="deep",Q="shallow",M="destructor",A=B.Attribute;function E(){A.call(this);var L=B.Plugin&&B.Plugin.Host;if(this._initPlugins&&L){L.call(this);}if(this._lazyAddAttrs!==false){this._lazyAddAttrs=true;}this.init.apply(this,arguments);}E._ATTR_CFG=A._ATTR_CFG.concat("cloneDefaultValue");E.NAME="base";E.ATTRS={initialized:{readOnly:true,value:false},destroyed:{readOnly:true,value:false}};E.prototype={init:function(L){this._yuievt.config.prefix=this.name=this.constructor.NAME;this.publish(P,{queuable:false,defaultFn:this._defInitFn});if(L){if(L.on){this.on(L.on);}if(L.after){this.after(L.after);}}this.fire(P,{cfg:L});return this;},destroy:function(){this.publish(F,{queuable:false,defaultFn:this._defDestroyFn});this.fire(F);return this;},_defInitFn:function(L){this._initHierarchy(L.cfg);if(this._initPlugins){this._initPlugins(L.cfg);}this._set(N,true);},_defDestroyFn:function(L){this._destroyHierarchy();if(this._destroyPlugins){this._destroyPlugins();}this._set(G,true);},_getClasses:function(){if(!this._classes){this._initHierarchyData();}return this._classes;},_getAttrCfgs:function(){if(!this._attrs){this._initHierarchyData();}return this._attrs;},_filterAttrCfgs:function(T,O){var R=null,L,S=T.ATTRS;if(S){for(L in S){if(S.hasOwnProperty(L)&&O[L]){R=R||{};R[L]=O[L];delete O[L];}}}return R;},_initHierarchyData:function(){var R=this.constructor,O=[],L=[];while(R){O[O.length]=R;if(R.ATTRS){L[L.length]=R.ATTRS;}R=R.superclass?R.superclass.constructor:null;}this._classes=O;this._attrs=this._aggregateAttrs(L);},_aggregateAttrs:function(W){var T,X,S,L,Y,O,V,R=E._ATTR_CFG,U={};if(W){for(O=W.length-1;O>=0;--O){X=W[O];for(T in X){if(X.hasOwnProperty(T)){S=B.mix({},X[T],true,R);L=S.value;V=S.cloneDefaultValue;if(L){if((V===undefined&&(C===L.constructor||J.isArray(L)))||V===K||V===true){S.value=B.clone(L);}else{if(V===Q){S.value=B.merge(L);}}}Y=null;if(T.indexOf(I)!==-1){Y=T.split(I);T=Y.shift();}if(Y&&U[T]&&U[T].value){H.setValue(U[T].value,Y,L);}else{if(!Y){if(!U[T]){U[T]=S;}else{B.mix(U[T],S,true,R);}}}}}}}return U;},_initHierarchy:function(U){var R=this._lazyAddAttrs,V,W,X,S,O,T=this._getClasses(),L=this._getAttrCfgs();for(X=T.length-1;X>=0;X--){V=T[X];W=V.prototype;if(V._yuibuild&&V._yuibuild.exts&&!V._yuibuild.dynamic){for(S=0,O=V._yuibuild.exts.length;S<O;S++){V._yuibuild.exts[S].apply(this,arguments);}}this.addAttrs(this._filterAttrCfgs(V,L),U,R);if(W.hasOwnProperty(D)){W.initializer.apply(this,arguments);}}},_destroyHierarchy:function(){var T,O,S,L,R=this._getClasses();for(S=0,L=R.length;S<L;S++){T=R[S];O=T.prototype;if(O.hasOwnProperty(M)){O.destructor.apply(this,arguments);}}},toString:function(){return this.constructor.NAME+"["+B.stamp(this)+"]";}};B.mix(E,A,false,null,1);E.prototype.constructor=E;B.Base=E;E.prototype.constructor=E;},"3.0.0",{requires:["attribute-base"]});

View File

@@ -0,0 +1,531 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('base-base', function(Y) {
/**
* The base module provides the Base class, which objects requiring attribute and custom event support can extend.
* The module also provides two ways to reuse code - An augmentable Plugin.Host interface which provides plugin support
* (which is augmented to the Base class) and Base.build which provides a way to
* build custom classes using extensions.
*
* @module base
*/
/**
* The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
* and without the extension support provided by Base.build.
*
* @module base
* @submodule base-base
*/
var O = Y.Object,
L = Y.Lang,
DOT = ".",
DESTROY = "destroy",
INIT = "init",
INITIALIZED = "initialized",
DESTROYED = "destroyed",
INITIALIZER = "initializer",
OBJECT_CONSTRUCTOR = Object.prototype.constructor,
DEEP = "deep",
SHALLOW = "shallow",
DESTRUCTOR = "destructor",
Attribute = Y.Attribute;
/**
* <p>
* A base class which objects requiring attributes and custom event support can
* extend. Base also handles the chaining of initializer and destructor methods across
* the hierarchy as part of object construction and destruction. Additionally, attributes configured
* through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class
* in the hierarchy will be initialized by Base.
* </p>
*
* <p>
* The static <a href="#property_Base.NAME">NAME</a> property of each class extending
* from Base will be used as the identifier for the class, and is used by Base to prefix
* all events fired by instances of that class.
* </p>
* @class Base
* @constructor
* @uses Attribute
* @uses Plugin.Host
*
* @param {Object} config Object with configuration property name/value pairs
*/
function Base() {
Attribute.call(this);
// If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
// initial state, but don't initialize Plugins yet. That's done after initialization.
var PluginHost = Y.Plugin && Y.Plugin.Host;
if (this._initPlugins && PluginHost) {
PluginHost.call(this);
}
if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
this.init.apply(this, arguments);
}
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
*
* @property Base._ATTR_CFG
* @type Array
* @static
* @private
*/
Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
/**
* <p>
* The string to be used to identify instances of
* this class, for example in prefixing events.
* </p>
* <p>
* Classes extending Base, should define their own
* static NAME property, which should be camelCase by
* convention (e.g. MyClass.NAME = "myClass";).
* </p>
* @property Base.NAME
* @type String
* @static
*/
Base.NAME = "base";
/**
* The default set of attributes which will be available for instances of this class, and
* their configuration. In addition to the configuration properties listed by
* Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
* can also be configured with a "cloneDefaultValue" property, which defines how the statically
* defined value field should be protected ("shallow", "deep" and false are supported values).
*
* By default if the value is an object literal or an array it will be "shallow" cloned, to
* protect the default value.
*
* @property Base.ATTRS
* @type Object
* @static
*/
Base.ATTRS = {
/**
* Flag indicating whether or not this object
* has been through the init lifecycle phase.
*
* @attribute initialized
* @readonly
* @default false
* @type boolean
*/
initialized: {
readOnly:true,
value:false
},
/**
* Flag indicating whether or not this object
* has been through the destroy lifecycle phase.
*
* @attribute destroyed
* @readonly
* @default false
* @type boolean
*/
destroyed: {
readOnly:true,
value:false
}
};
Base.prototype = {
/**
* Init lifecycle method, invoked during construction.
* Fires the init event prior to setting up attributes and
* invoking initializers for the class hierarchy.
*
* @method init
* @final
* @chainable
* @param {Object} config Object with configuration property name/value pairs
* @return {Base} A reference to this object
*/
init: function(config) {
/**
* The string used to identify the class of this object.
*
* @deprecated Use this.constructor.NAME
* @property name
* @type String
*/
this._yuievt.config.prefix = this.name = this.constructor.NAME;
/**
* <p>
* Lifecycle event for the init phase, fired prior to initialization.
* Invoking the preventDefault() method on the event object provided
* to subscribers will prevent initialization from occuring.
* </p>
* <p>
* Subscribers to the "after" momemt of this event, will be notified
* after initialization of the object is complete (and therefore
* cannot prevent initialization).
* </p>
*
* @event init
* @preventable _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
*/
this.publish(INIT, {
queuable:false,
defaultFn:this._defInitFn
});
if (config) {
if (config.on) {
this.on(config.on);
}
if (config.after) {
this.after(config.after);
}
}
this.fire(INIT, {cfg: config});
return this;
},
/**
* <p>
* Destroy lifecycle method. Fires the destroy
* event, prior to invoking destructors for the
* class hierarchy.
* </p>
* <p>
* Subscribers to the destroy
* event can invoke preventDefault on the event object, to prevent destruction
* from proceeding.
* </p>
* @method destroy
* @return {Base} A reference to this object
* @final
* @chainable
*/
destroy: function() {
/**
* <p>
* Lifecycle event for the destroy phase,
* fired prior to destruction. Invoking the preventDefault
* method on the event object provided to subscribers will
* prevent destruction from proceeding.
* </p>
* <p>
* Subscribers to the "after" moment of this event, will be notified
* after destruction is complete (and as a result cannot prevent
* destruction).
* </p>
* @event destroy
* @preventable _defDestroyFn
* @param {EventFacade} e Event object
*/
this.publish(DESTROY, {
queuable:false,
defaultFn: this._defDestroyFn
});
this.fire(DESTROY);
return this;
},
/**
* Default init event handler
*
* @method _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
* @protected
*/
_defInitFn : function(e) {
this._initHierarchy(e.cfg);
if (this._initPlugins) {
// Need to initPlugins manually, to handle constructor parsing, static Plug parsing
this._initPlugins(e.cfg);
}
this._set(INITIALIZED, true);
},
/**
* Default destroy event handler
*
* @method _defDestroyFn
* @param {EventFacade} e Event object
* @protected
*/
_defDestroyFn : function(e) {
this._destroyHierarchy();
if (this._destroyPlugins) {
this._destroyPlugins();
}
this._set(DESTROYED, true);
},
/**
* Returns the class hierarchy for this object, with Base being the last class in the array.
*
* @method _getClasses
* @protected
* @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
* This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the
* cached value.
*/
_getClasses : function() {
if (!this._classes) {
this._initHierarchyData();
}
return this._classes;
},
/**
* Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
*
* @method _getAttrCfgs
* @protected
* @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
* This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
* the cached value.
*/
_getAttrCfgs : function() {
if (!this._attrs) {
this._initHierarchyData();
}
return this._attrs;
},
/**
* A helper method used when processing ATTRS across the class hierarchy during
* initialization. Returns a disposable object with the attributes defined for
* the provided class, extracted from the set of all attributes passed in .
*
* @method _filterAttrCfs
* @private
*
* @param {Function} clazz The class for which the desired attributes are required.
* @param {Object} allCfgs The set of all attribute configurations for this instance.
* Attributes will be removed from this set, if they belong to the filtered class, so
* that by the time all classes are processed, allCfgs will be empty.
*
* @return {Object} The set of attributes belonging to the class passed in, in the form
* of an object with attribute name/configuration pairs.
*/
_filterAttrCfgs : function(clazz, allCfgs) {
var cfgs = null, attr, attrs = clazz.ATTRS;
if (attrs) {
for (attr in attrs) {
if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
cfgs = cfgs || {};
cfgs[attr] = allCfgs[attr];
delete allCfgs[attr];
}
}
}
return cfgs;
},
/**
* A helper method used by _getClasses and _getAttrCfgs, which determines both
* the array of classes and aggregate set of attribute configurations
* across the class hierarchy for the instance.
*
* @method _initHierarchyData
* @private
*/
_initHierarchyData : function() {
var c = this.constructor,
classes = [],
attrs = [];
while (c) {
// Add to classes
classes[classes.length] = c;
// Add to attributes
if (c.ATTRS) {
attrs[attrs.length] = c.ATTRS;
}
c = c.superclass ? c.superclass.constructor : null;
}
this._classes = classes;
this._attrs = this._aggregateAttrs(attrs);
},
/**
* A helper method, used by _initHierarchyData to aggregate
* attribute configuration across the instances class hierarchy.
*
* The method will potect the attribute configuration value to protect the statically defined
* default value in ATTRS if required (if the value is an object literal, array or the
* attribute configuration has cloneDefaultValue set to shallow or deep).
*
* @method _aggregateAttrs
* @private
* @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy
* (subclass first, Base last)
* @return {Object} The aggregate set of ATTRS definitions for the instance
*/
_aggregateAttrs : function(allAttrs) {
var attr,
attrs,
cfg,
val,
path,
i,
clone,
cfgProps = Base._ATTR_CFG,
aggAttrs = {};
if (allAttrs) {
for (i = allAttrs.length-1; i >= 0; --i) {
attrs = allAttrs[i];
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
// Protect config passed in
cfg = Y.mix({}, attrs[attr], true, cfgProps);
val = cfg.value;
clone = cfg.cloneDefaultValue;
if (val) {
if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
cfg.value = Y.clone(val);
} else if (clone === SHALLOW) {
cfg.value = Y.merge(val);
}
// else if (clone === false), don't clone the static default value.
// It's intended to be used by reference.
}
path = null;
if (attr.indexOf(DOT) !== -1) {
path = attr.split(DOT);
attr = path.shift();
}
if (path && aggAttrs[attr] && aggAttrs[attr].value) {
O.setValue(aggAttrs[attr].value, path, val);
} else if (!path){
if (!aggAttrs[attr]) {
aggAttrs[attr] = cfg;
} else {
Y.mix(aggAttrs[attr], cfg, true, cfgProps);
}
}
}
}
}
}
return aggAttrs;
},
/**
* Initializes the class hierarchy for the instance, which includes
* initializing attributes for each class defined in the class's
* static <a href="#property_Base.ATTRS">ATTRS</a> property and
* invoking the initializer method on the prototype of each class in the hierarchy.
*
* @method _initHierarchy
* @param {Object} userVals Object with configuration property name/value pairs
* @private
*/
_initHierarchy : function(userVals) {
var lazy = this._lazyAddAttrs,
constr,
constrProto,
ci,
ei,
el,
classes = this._getClasses(),
attrCfgs = this._getAttrCfgs();
for (ci = classes.length-1; ci >= 0; ci--) {
constr = classes[ci];
constrProto = constr.prototype;
if (constr._yuibuild && constr._yuibuild.exts && !constr._yuibuild.dynamic) {
for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
constr._yuibuild.exts[ei].apply(this, arguments);
}
}
this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
if (constrProto.hasOwnProperty(INITIALIZER)) {
constrProto.initializer.apply(this, arguments);
}
}
},
/**
* Destroys the class hierarchy for this instance by invoking
* the descructor method on the prototype of each class in the hierarchy.
*
* @method _destroyHierarchy
* @private
*/
_destroyHierarchy : function() {
var constr,
constrProto,
ci, cl,
classes = this._getClasses();
for (ci = 0, cl = classes.length; ci < cl; ci++) {
constr = classes[ci];
constrProto = constr.prototype;
if (constrProto.hasOwnProperty(DESTRUCTOR)) {
constrProto.destructor.apply(this, arguments);
}
}
},
/**
* Default toString implementation. Provides the constructor NAME
* and the instance ID.
*
* @method toString
* @return {String} String representation for this object
*/
toString: function() {
return this.constructor.NAME + "[" + Y.stamp(this) + "]";
}
};
// Straightup augment, no wrapper functions
Y.mix(Base, Attribute, false, null, 1);
// Fix constructor
Base.prototype.constructor = Base;
Y.Base = Base;
// Fix constructor
Base.prototype.constructor = Base;
}, '3.0.0' ,{requires:['attribute-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("base-build",function(C){var B=C.Base,A=C.Lang;B._buildCfg={aggregates:["ATTRS","_PLUG","_UNPLUG"]};B.build=function(D,I,M,L){var O=B.build,E=O._getClass(I,L),K=O._getAggregates(I,L),G=E._yuibuild.dynamic,J,H,F,N;if(G){if(K){for(J=0,H=K.length;J<H;++J){F=K[J];if(I.hasOwnProperty(F)){E[F]=A.isArray(I[F])?[]:{};}}C.aggregate(E,I,true,K);}}for(J=0,H=M.length;J<H;J++){N=M[J];if(K){C.aggregate(E,N,true,K);}C.mix(E,N,true,null,1);E._yuibuild.exts.push(N);}E.prototype.hasImpl=O._hasImpl;if(G){E.NAME=D;E.prototype.constructor=E;}return E;};C.mix(B.build,{_template:function(D){function E(){E.superclass.constructor.apply(this,arguments);var H=E._yuibuild.exts,F=H.length,G;for(G=0;G<F;G++){H[G].apply(this,arguments);}return this;}C.extend(E,D);return E;},_hasImpl:function(G){var J=this._getClasses();for(var I=0,E=J.length;I<E;I++){var D=J[I];if(D._yuibuild){var H=D._yuibuild.exts,K=H.length,F;for(F=0;F<K;F++){if(H[F]===G){return true;}}}}return false;},_getClass:function(D,E){var F=(E&&false===E.dynamic)?false:true,G=(F)?B.build._template(D):D;G._yuibuild={id:null,exts:[],dynamic:F};return G;},_getAggregates:function(D,E){var F=[],H=(E&&E.aggregates),I=D,G;while(I&&I.prototype){G=I._buildCfg&&I._buildCfg.aggregates;if(G){F=F.concat(G);}I=I.superclass?I.superclass.constructor:null;}if(H){F=F.concat(H);}return F;}});},"3.0.0",{requires:["base-base"]});

View File

@@ -0,0 +1,201 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('base-build', function(Y) {
/**
* The base-build submodule provides Base.build functionality, which
* can be used to create custom classes, by aggregating extensions onto
* a main class.
*
* @module base
* @submodule base-build
* @for Base
*/
var Base = Y.Base,
L = Y.Lang;
/**
* The build configuration for the Base class.
*
* Defines the static fields which need to be aggregated
* when the Base class is used as the main class passed to
* the <a href="#method_Base.build">Base.build</a> method.
*
* @property Base._buildCfg
* @type Object
* @static
* @final
* @private
*/
Base._buildCfg = {
aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
};
/**
* <p>
* Builds a custom constructor function (class) from the
* main function, and array of extension functions (classes)
* provided. The NAME field for the constructor function is
* defined by the first argument passed in.
* </p>
* <p>
* The cfg object supports the following properties
* </p>
* <dl>
* <dt>dynamic &#60;boolean&#62;</dt>
* <dd>
* <p>If true (default), a completely new class
* is created which extends the main class, and acts as the
* host on which the extension classes are augmented.</p>
* <p>If false, the extensions classes are augmented directly to
* the main class, modifying the main class' prototype.</p>
* </dd>
* <dt>aggregates &#60;String[]&#62;</dt>
* <dd>An array of static property names, which will get aggregated
* on to the built class, in addition to the default properties build
* will always aggregate as defined by the main class' static _buildCfg
* property.
* </dd>
* </dl>
*
* @method Base.build
* @static
* @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
* @param {Function} main The main class on which to base the built class
* @param {Function[]} extensions The set of extension classes which will be
* augmented/aggregated to the built class.
* @param {Object} cfg Optional. Build configuration for the class (see description).
* @return {Function} A custom class, created from the provided main and extension classes
*/
Base.build = function(name, main, extensions, cfg) {
var build = Base.build,
builtClass = build._getClass(main, cfg),
aggregates = build._getAggregates(main, cfg),
dynamic = builtClass._yuibuild.dynamic,
i, l, val, extClass;
// Shallow isolate aggregates
if (dynamic) {
if (aggregates) {
for (i = 0, l = aggregates.length; i < l; ++i) {
val = aggregates[i];
if (main.hasOwnProperty(val)) {
builtClass[val] = L.isArray(main[val]) ? [] : {};
}
}
Y.aggregate(builtClass, main, true, aggregates);
}
}
// Augment/Aggregate
for (i = 0, l = extensions.length; i < l; i++) {
extClass = extensions[i];
if (aggregates) {
Y.aggregate(builtClass, extClass, true, aggregates);
}
// Old augment
Y.mix(builtClass, extClass, true, null, 1);
builtClass._yuibuild.exts.push(extClass);
}
builtClass.prototype.hasImpl = build._hasImpl;
if (dynamic) {
builtClass.NAME = name;
builtClass.prototype.constructor = builtClass;
}
return builtClass;
};
Y.mix(Base.build, {
_template: function(main) {
function BuiltClass() {
BuiltClass.superclass.constructor.apply(this, arguments);
var f = BuiltClass._yuibuild.exts,
l = f.length,
i;
for (i = 0; i < l; i++) {
f[i].apply(this, arguments);
}
return this;
}
Y.extend(BuiltClass, main);
return BuiltClass;
},
_hasImpl : function(extClass) {
var classes = this._getClasses();
for (var i = 0, l = classes.length; i < l; i++) {
var cls = classes[i];
if (cls._yuibuild) {
var exts = cls._yuibuild.exts,
ll = exts.length,
j;
for (j = 0; j < ll; j++) {
if (exts[j] === extClass) {
return true;
}
}
}
}
return false;
},
_getClass : function(main, cfg) {
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
builtClass = (dynamic) ? Base.build._template(main) : main;
builtClass._yuibuild = {
id: null,
exts : [],
dynamic : dynamic
};
return builtClass;
},
_getAggregates : function(main, cfg) {
var aggr = [],
cfgAggr = (cfg && cfg.aggregates),
c = main,
classAggr;
while (c && c.prototype) {
classAggr = c._buildCfg && c._buildCfg.aggregates;
if (classAggr) {
aggr = aggr.concat(classAggr);
}
c = c.superclass ? c.superclass.constructor : null;
}
if (cfgAggr) {
aggr = aggr.concat(cfgAggr);
}
return aggr;
}
});
}, '3.0.0' ,{requires:['base-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("base-base",function(B){var H=B.Object,J=B.Lang,I=".",F="destroy",P="init",N="initialized",G="destroyed",D="initializer",C=Object.prototype.constructor,K="deep",Q="shallow",M="destructor",A=B.Attribute;function E(){A.call(this);var L=B.Plugin&&B.Plugin.Host;if(this._initPlugins&&L){L.call(this);}if(this._lazyAddAttrs!==false){this._lazyAddAttrs=true;}this.init.apply(this,arguments);}E._ATTR_CFG=A._ATTR_CFG.concat("cloneDefaultValue");E.NAME="base";E.ATTRS={initialized:{readOnly:true,value:false},destroyed:{readOnly:true,value:false}};E.prototype={init:function(L){this._yuievt.config.prefix=this.name=this.constructor.NAME;this.publish(P,{queuable:false,defaultFn:this._defInitFn});if(L){if(L.on){this.on(L.on);}if(L.after){this.after(L.after);}}this.fire(P,{cfg:L});return this;},destroy:function(){this.publish(F,{queuable:false,defaultFn:this._defDestroyFn});this.fire(F);return this;},_defInitFn:function(L){this._initHierarchy(L.cfg);if(this._initPlugins){this._initPlugins(L.cfg);}this._set(N,true);},_defDestroyFn:function(L){this._destroyHierarchy();if(this._destroyPlugins){this._destroyPlugins();}this._set(G,true);},_getClasses:function(){if(!this._classes){this._initHierarchyData();}return this._classes;},_getAttrCfgs:function(){if(!this._attrs){this._initHierarchyData();}return this._attrs;},_filterAttrCfgs:function(T,O){var R=null,L,S=T.ATTRS;if(S){for(L in S){if(S.hasOwnProperty(L)&&O[L]){R=R||{};R[L]=O[L];delete O[L];}}}return R;},_initHierarchyData:function(){var R=this.constructor,O=[],L=[];while(R){O[O.length]=R;if(R.ATTRS){L[L.length]=R.ATTRS;}R=R.superclass?R.superclass.constructor:null;}this._classes=O;this._attrs=this._aggregateAttrs(L);},_aggregateAttrs:function(W){var T,X,S,L,Y,O,V,R=E._ATTR_CFG,U={};if(W){for(O=W.length-1;O>=0;--O){X=W[O];for(T in X){if(X.hasOwnProperty(T)){S=B.mix({},X[T],true,R);L=S.value;V=S.cloneDefaultValue;if(L){if((V===undefined&&(C===L.constructor||J.isArray(L)))||V===K||V===true){S.value=B.clone(L);}else{if(V===Q){S.value=B.merge(L);}}}Y=null;if(T.indexOf(I)!==-1){Y=T.split(I);T=Y.shift();}if(Y&&U[T]&&U[T].value){H.setValue(U[T].value,Y,L);}else{if(!Y){if(!U[T]){U[T]=S;}else{B.mix(U[T],S,true,R);}}}}}}}return U;},_initHierarchy:function(U){var R=this._lazyAddAttrs,V,W,X,S,O,T=this._getClasses(),L=this._getAttrCfgs();for(X=T.length-1;X>=0;X--){V=T[X];W=V.prototype;if(V._yuibuild&&V._yuibuild.exts&&!V._yuibuild.dynamic){for(S=0,O=V._yuibuild.exts.length;S<O;S++){V._yuibuild.exts[S].apply(this,arguments);}}this.addAttrs(this._filterAttrCfgs(V,L),U,R);if(W.hasOwnProperty(D)){W.initializer.apply(this,arguments);}}},_destroyHierarchy:function(){var T,O,S,L,R=this._getClasses();for(S=0,L=R.length;S<L;S++){T=R[S];O=T.prototype;if(O.hasOwnProperty(M)){O.destructor.apply(this,arguments);}}},toString:function(){return this.constructor.NAME+"["+B.stamp(this)+"]";}};B.mix(E,A,false,null,1);E.prototype.constructor=E;B.Base=E;E.prototype.constructor=E;},"3.0.0",{requires:["attribute-base"]});YUI.add("base-pluginhost",function(C){var A=C.Base,B=C.Plugin.Host;C.mix(A,B,false,null,1);A.plug=B.plug;A.unplug=B.unplug;},"3.0.0",{requires:["base-base","pluginhost"]});YUI.add("base-build",function(C){var B=C.Base,A=C.Lang;B._buildCfg={aggregates:["ATTRS","_PLUG","_UNPLUG"]};B.build=function(D,I,M,L){var O=B.build,E=O._getClass(I,L),K=O._getAggregates(I,L),G=E._yuibuild.dynamic,J,H,F,N;if(G){if(K){for(J=0,H=K.length;J<H;++J){F=K[J];if(I.hasOwnProperty(F)){E[F]=A.isArray(I[F])?[]:{};}}C.aggregate(E,I,true,K);}}for(J=0,H=M.length;J<H;J++){N=M[J];if(K){C.aggregate(E,N,true,K);}C.mix(E,N,true,null,1);E._yuibuild.exts.push(N);}E.prototype.hasImpl=O._hasImpl;if(G){E.NAME=D;E.prototype.constructor=E;}return E;};C.mix(B.build,{_template:function(D){function E(){E.superclass.constructor.apply(this,arguments);var H=E._yuibuild.exts,F=H.length,G;for(G=0;G<F;G++){H[G].apply(this,arguments);}return this;}C.extend(E,D);return E;},_hasImpl:function(G){var J=this._getClasses();for(var I=0,E=J.length;I<E;I++){var D=J[I];if(D._yuibuild){var H=D._yuibuild.exts,K=H.length,F;for(F=0;F<K;F++){if(H[F]===G){return true;}}}}return false;},_getClass:function(D,E){var F=(E&&false===E.dynamic)?false:true,G=(F)?B.build._template(D):D;G._yuibuild={id:null,exts:[],dynamic:F};return G;},_getAggregates:function(D,E){var F=[],H=(E&&E.aggregates),I=D,G;while(I&&I.prototype){G=I._buildCfg&&I._buildCfg.aggregates;if(G){F=F.concat(G);}I=I.superclass?I.superclass.constructor:null;}if(H){F=F.concat(H);}return F;}});},"3.0.0",{requires:["base-base"]});YUI.add("base",function(A){},"3.0.0",{use:["base-base","base-pluginhost","base-build"]});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("base-pluginhost",function(C){var A=C.Base,B=C.Plugin.Host;C.mix(A,B,false,null,1);A.plug=B.plug;A.unplug=B.unplug;},"3.0.0",{requires:["base-base","pluginhost"]});

View File

@@ -0,0 +1,43 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('base-pluginhost', function(Y) {
/**
* The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
* Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
*
* @module base
* @submodule base-pluginhost
* @for Base
*/
var Base = Y.Base,
PluginHost = Y.Plugin.Host;
Y.mix(Base, PluginHost, false, null, 1);
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
* method for argument and return value details.
*
* @method Base.plug
* @static
*/
Base.plug = PluginHost.plug;
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
* aliased method for argument and return value details.
*
* @method Base.unplug
* @static
*/
Base.unplug = PluginHost.unplug;
}, '3.0.0' ,{requires:['base-base', 'pluginhost']});

View File

@@ -0,0 +1,765 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('base-base', function(Y) {
/**
* The base module provides the Base class, which objects requiring attribute and custom event support can extend.
* The module also provides two ways to reuse code - An augmentable Plugin.Host interface which provides plugin support
* (which is augmented to the Base class) and Base.build which provides a way to
* build custom classes using extensions.
*
* @module base
*/
/**
* The base-base submodule provides the Base class without the Plugin support, provided by Plugin.Host,
* and without the extension support provided by Base.build.
*
* @module base
* @submodule base-base
*/
var O = Y.Object,
L = Y.Lang,
DOT = ".",
DESTROY = "destroy",
INIT = "init",
INITIALIZED = "initialized",
DESTROYED = "destroyed",
INITIALIZER = "initializer",
OBJECT_CONSTRUCTOR = Object.prototype.constructor,
DEEP = "deep",
SHALLOW = "shallow",
DESTRUCTOR = "destructor",
Attribute = Y.Attribute;
/**
* <p>
* A base class which objects requiring attributes and custom event support can
* extend. Base also handles the chaining of initializer and destructor methods across
* the hierarchy as part of object construction and destruction. Additionally, attributes configured
* through the static <a href="#property_Base.ATTRS">ATTRS</a> property for each class
* in the hierarchy will be initialized by Base.
* </p>
*
* <p>
* The static <a href="#property_Base.NAME">NAME</a> property of each class extending
* from Base will be used as the identifier for the class, and is used by Base to prefix
* all events fired by instances of that class.
* </p>
* @class Base
* @constructor
* @uses Attribute
* @uses Plugin.Host
*
* @param {Object} config Object with configuration property name/value pairs
*/
function Base() {
Attribute.call(this);
// If Plugin.Host has been augmented [ through base-pluginhost ], setup it's
// initial state, but don't initialize Plugins yet. That's done after initialization.
var PluginHost = Y.Plugin && Y.Plugin.Host;
if (this._initPlugins && PluginHost) {
PluginHost.call(this);
}
if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; }
this.init.apply(this, arguments);
}
/**
* The list of properties which can be configured for
* each attribute (e.g. setter, getter, writeOnce, readOnly etc.)
*
* @property Base._ATTR_CFG
* @type Array
* @static
* @private
*/
Base._ATTR_CFG = Attribute._ATTR_CFG.concat("cloneDefaultValue");
/**
* <p>
* The string to be used to identify instances of
* this class, for example in prefixing events.
* </p>
* <p>
* Classes extending Base, should define their own
* static NAME property, which should be camelCase by
* convention (e.g. MyClass.NAME = "myClass";).
* </p>
* @property Base.NAME
* @type String
* @static
*/
Base.NAME = "base";
/**
* The default set of attributes which will be available for instances of this class, and
* their configuration. In addition to the configuration properties listed by
* Attribute's <a href="Attribute.html#method_addAttr">addAttr</a> method, the attribute
* can also be configured with a "cloneDefaultValue" property, which defines how the statically
* defined value field should be protected ("shallow", "deep" and false are supported values).
*
* By default if the value is an object literal or an array it will be "shallow" cloned, to
* protect the default value.
*
* @property Base.ATTRS
* @type Object
* @static
*/
Base.ATTRS = {
/**
* Flag indicating whether or not this object
* has been through the init lifecycle phase.
*
* @attribute initialized
* @readonly
* @default false
* @type boolean
*/
initialized: {
readOnly:true,
value:false
},
/**
* Flag indicating whether or not this object
* has been through the destroy lifecycle phase.
*
* @attribute destroyed
* @readonly
* @default false
* @type boolean
*/
destroyed: {
readOnly:true,
value:false
}
};
Base.prototype = {
/**
* Init lifecycle method, invoked during construction.
* Fires the init event prior to setting up attributes and
* invoking initializers for the class hierarchy.
*
* @method init
* @final
* @chainable
* @param {Object} config Object with configuration property name/value pairs
* @return {Base} A reference to this object
*/
init: function(config) {
/**
* The string used to identify the class of this object.
*
* @deprecated Use this.constructor.NAME
* @property name
* @type String
*/
this._yuievt.config.prefix = this.name = this.constructor.NAME;
/**
* <p>
* Lifecycle event for the init phase, fired prior to initialization.
* Invoking the preventDefault() method on the event object provided
* to subscribers will prevent initialization from occuring.
* </p>
* <p>
* Subscribers to the "after" momemt of this event, will be notified
* after initialization of the object is complete (and therefore
* cannot prevent initialization).
* </p>
*
* @event init
* @preventable _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
*/
this.publish(INIT, {
queuable:false,
defaultFn:this._defInitFn
});
if (config) {
if (config.on) {
this.on(config.on);
}
if (config.after) {
this.after(config.after);
}
}
this.fire(INIT, {cfg: config});
return this;
},
/**
* <p>
* Destroy lifecycle method. Fires the destroy
* event, prior to invoking destructors for the
* class hierarchy.
* </p>
* <p>
* Subscribers to the destroy
* event can invoke preventDefault on the event object, to prevent destruction
* from proceeding.
* </p>
* @method destroy
* @return {Base} A reference to this object
* @final
* @chainable
*/
destroy: function() {
/**
* <p>
* Lifecycle event for the destroy phase,
* fired prior to destruction. Invoking the preventDefault
* method on the event object provided to subscribers will
* prevent destruction from proceeding.
* </p>
* <p>
* Subscribers to the "after" moment of this event, will be notified
* after destruction is complete (and as a result cannot prevent
* destruction).
* </p>
* @event destroy
* @preventable _defDestroyFn
* @param {EventFacade} e Event object
*/
this.publish(DESTROY, {
queuable:false,
defaultFn: this._defDestroyFn
});
this.fire(DESTROY);
return this;
},
/**
* Default init event handler
*
* @method _defInitFn
* @param {EventFacade} e Event object, with a cfg property which
* refers to the configuration object passed to the constructor.
* @protected
*/
_defInitFn : function(e) {
this._initHierarchy(e.cfg);
if (this._initPlugins) {
// Need to initPlugins manually, to handle constructor parsing, static Plug parsing
this._initPlugins(e.cfg);
}
this._set(INITIALIZED, true);
},
/**
* Default destroy event handler
*
* @method _defDestroyFn
* @param {EventFacade} e Event object
* @protected
*/
_defDestroyFn : function(e) {
this._destroyHierarchy();
if (this._destroyPlugins) {
this._destroyPlugins();
}
this._set(DESTROYED, true);
},
/**
* Returns the class hierarchy for this object, with Base being the last class in the array.
*
* @method _getClasses
* @protected
* @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object.
* This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the
* cached value.
*/
_getClasses : function() {
if (!this._classes) {
this._initHierarchyData();
}
return this._classes;
},
/**
* Returns an aggregated set of attribute configurations, by traversing the class hierarchy.
*
* @method _getAttrCfgs
* @protected
* @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy
* This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return
* the cached value.
*/
_getAttrCfgs : function() {
if (!this._attrs) {
this._initHierarchyData();
}
return this._attrs;
},
/**
* A helper method used when processing ATTRS across the class hierarchy during
* initialization. Returns a disposable object with the attributes defined for
* the provided class, extracted from the set of all attributes passed in .
*
* @method _filterAttrCfs
* @private
*
* @param {Function} clazz The class for which the desired attributes are required.
* @param {Object} allCfgs The set of all attribute configurations for this instance.
* Attributes will be removed from this set, if they belong to the filtered class, so
* that by the time all classes are processed, allCfgs will be empty.
*
* @return {Object} The set of attributes belonging to the class passed in, in the form
* of an object with attribute name/configuration pairs.
*/
_filterAttrCfgs : function(clazz, allCfgs) {
var cfgs = null, attr, attrs = clazz.ATTRS;
if (attrs) {
for (attr in attrs) {
if (attrs.hasOwnProperty(attr) && allCfgs[attr]) {
cfgs = cfgs || {};
cfgs[attr] = allCfgs[attr];
delete allCfgs[attr];
}
}
}
return cfgs;
},
/**
* A helper method used by _getClasses and _getAttrCfgs, which determines both
* the array of classes and aggregate set of attribute configurations
* across the class hierarchy for the instance.
*
* @method _initHierarchyData
* @private
*/
_initHierarchyData : function() {
var c = this.constructor,
classes = [],
attrs = [];
while (c) {
// Add to classes
classes[classes.length] = c;
// Add to attributes
if (c.ATTRS) {
attrs[attrs.length] = c.ATTRS;
}
c = c.superclass ? c.superclass.constructor : null;
}
this._classes = classes;
this._attrs = this._aggregateAttrs(attrs);
},
/**
* A helper method, used by _initHierarchyData to aggregate
* attribute configuration across the instances class hierarchy.
*
* The method will potect the attribute configuration value to protect the statically defined
* default value in ATTRS if required (if the value is an object literal, array or the
* attribute configuration has cloneDefaultValue set to shallow or deep).
*
* @method _aggregateAttrs
* @private
* @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy
* (subclass first, Base last)
* @return {Object} The aggregate set of ATTRS definitions for the instance
*/
_aggregateAttrs : function(allAttrs) {
var attr,
attrs,
cfg,
val,
path,
i,
clone,
cfgProps = Base._ATTR_CFG,
aggAttrs = {};
if (allAttrs) {
for (i = allAttrs.length-1; i >= 0; --i) {
attrs = allAttrs[i];
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
// Protect config passed in
cfg = Y.mix({}, attrs[attr], true, cfgProps);
val = cfg.value;
clone = cfg.cloneDefaultValue;
if (val) {
if ( (clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val))) || clone === DEEP || clone === true) {
cfg.value = Y.clone(val);
} else if (clone === SHALLOW) {
cfg.value = Y.merge(val);
}
// else if (clone === false), don't clone the static default value.
// It's intended to be used by reference.
}
path = null;
if (attr.indexOf(DOT) !== -1) {
path = attr.split(DOT);
attr = path.shift();
}
if (path && aggAttrs[attr] && aggAttrs[attr].value) {
O.setValue(aggAttrs[attr].value, path, val);
} else if (!path){
if (!aggAttrs[attr]) {
aggAttrs[attr] = cfg;
} else {
Y.mix(aggAttrs[attr], cfg, true, cfgProps);
}
}
}
}
}
}
return aggAttrs;
},
/**
* Initializes the class hierarchy for the instance, which includes
* initializing attributes for each class defined in the class's
* static <a href="#property_Base.ATTRS">ATTRS</a> property and
* invoking the initializer method on the prototype of each class in the hierarchy.
*
* @method _initHierarchy
* @param {Object} userVals Object with configuration property name/value pairs
* @private
*/
_initHierarchy : function(userVals) {
var lazy = this._lazyAddAttrs,
constr,
constrProto,
ci,
ei,
el,
classes = this._getClasses(),
attrCfgs = this._getAttrCfgs();
for (ci = classes.length-1; ci >= 0; ci--) {
constr = classes[ci];
constrProto = constr.prototype;
if (constr._yuibuild && constr._yuibuild.exts && !constr._yuibuild.dynamic) {
for (ei = 0, el = constr._yuibuild.exts.length; ei < el; ei++) {
constr._yuibuild.exts[ei].apply(this, arguments);
}
}
this.addAttrs(this._filterAttrCfgs(constr, attrCfgs), userVals, lazy);
if (constrProto.hasOwnProperty(INITIALIZER)) {
constrProto.initializer.apply(this, arguments);
}
}
},
/**
* Destroys the class hierarchy for this instance by invoking
* the descructor method on the prototype of each class in the hierarchy.
*
* @method _destroyHierarchy
* @private
*/
_destroyHierarchy : function() {
var constr,
constrProto,
ci, cl,
classes = this._getClasses();
for (ci = 0, cl = classes.length; ci < cl; ci++) {
constr = classes[ci];
constrProto = constr.prototype;
if (constrProto.hasOwnProperty(DESTRUCTOR)) {
constrProto.destructor.apply(this, arguments);
}
}
},
/**
* Default toString implementation. Provides the constructor NAME
* and the instance ID.
*
* @method toString
* @return {String} String representation for this object
*/
toString: function() {
return this.constructor.NAME + "[" + Y.stamp(this) + "]";
}
};
// Straightup augment, no wrapper functions
Y.mix(Base, Attribute, false, null, 1);
// Fix constructor
Base.prototype.constructor = Base;
Y.Base = Base;
// Fix constructor
Base.prototype.constructor = Base;
}, '3.0.0' ,{requires:['attribute-base']});
YUI.add('base-pluginhost', function(Y) {
/**
* The base-pluginhost submodule adds Plugin support to Base, by augmenting Base with
* Plugin.Host and setting up static (class level) Base.plug and Base.unplug methods.
*
* @module base
* @submodule base-pluginhost
* @for Base
*/
var Base = Y.Base,
PluginHost = Y.Plugin.Host;
Y.mix(Base, PluginHost, false, null, 1);
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.plug">Plugin.Host.plug</a>. See aliased
* method for argument and return value details.
*
* @method Base.plug
* @static
*/
Base.plug = PluginHost.plug;
/**
* Alias for <a href="Plugin.Host.html#method_Plugin.Host.unplug">Plugin.Host.unplug</a>. See the
* aliased method for argument and return value details.
*
* @method Base.unplug
* @static
*/
Base.unplug = PluginHost.unplug;
}, '3.0.0' ,{requires:['base-base', 'pluginhost']});
YUI.add('base-build', function(Y) {
/**
* The base-build submodule provides Base.build functionality, which
* can be used to create custom classes, by aggregating extensions onto
* a main class.
*
* @module base
* @submodule base-build
* @for Base
*/
var Base = Y.Base,
L = Y.Lang;
/**
* The build configuration for the Base class.
*
* Defines the static fields which need to be aggregated
* when the Base class is used as the main class passed to
* the <a href="#method_Base.build">Base.build</a> method.
*
* @property Base._buildCfg
* @type Object
* @static
* @final
* @private
*/
Base._buildCfg = {
aggregates : ["ATTRS", "_PLUG", "_UNPLUG"]
};
/**
* <p>
* Builds a custom constructor function (class) from the
* main function, and array of extension functions (classes)
* provided. The NAME field for the constructor function is
* defined by the first argument passed in.
* </p>
* <p>
* The cfg object supports the following properties
* </p>
* <dl>
* <dt>dynamic &#60;boolean&#62;</dt>
* <dd>
* <p>If true (default), a completely new class
* is created which extends the main class, and acts as the
* host on which the extension classes are augmented.</p>
* <p>If false, the extensions classes are augmented directly to
* the main class, modifying the main class' prototype.</p>
* </dd>
* <dt>aggregates &#60;String[]&#62;</dt>
* <dd>An array of static property names, which will get aggregated
* on to the built class, in addition to the default properties build
* will always aggregate as defined by the main class' static _buildCfg
* property.
* </dd>
* </dl>
*
* @method Base.build
* @static
* @param {Function} name The name of the new class. Used to defined the NAME property for the new class.
* @param {Function} main The main class on which to base the built class
* @param {Function[]} extensions The set of extension classes which will be
* augmented/aggregated to the built class.
* @param {Object} cfg Optional. Build configuration for the class (see description).
* @return {Function} A custom class, created from the provided main and extension classes
*/
Base.build = function(name, main, extensions, cfg) {
var build = Base.build,
builtClass = build._getClass(main, cfg),
aggregates = build._getAggregates(main, cfg),
dynamic = builtClass._yuibuild.dynamic,
i, l, val, extClass;
// Shallow isolate aggregates
if (dynamic) {
if (aggregates) {
for (i = 0, l = aggregates.length; i < l; ++i) {
val = aggregates[i];
if (main.hasOwnProperty(val)) {
builtClass[val] = L.isArray(main[val]) ? [] : {};
}
}
Y.aggregate(builtClass, main, true, aggregates);
}
}
// Augment/Aggregate
for (i = 0, l = extensions.length; i < l; i++) {
extClass = extensions[i];
if (aggregates) {
Y.aggregate(builtClass, extClass, true, aggregates);
}
// Old augment
Y.mix(builtClass, extClass, true, null, 1);
builtClass._yuibuild.exts.push(extClass);
}
builtClass.prototype.hasImpl = build._hasImpl;
if (dynamic) {
builtClass.NAME = name;
builtClass.prototype.constructor = builtClass;
}
return builtClass;
};
Y.mix(Base.build, {
_template: function(main) {
function BuiltClass() {
BuiltClass.superclass.constructor.apply(this, arguments);
var f = BuiltClass._yuibuild.exts,
l = f.length,
i;
for (i = 0; i < l; i++) {
f[i].apply(this, arguments);
}
return this;
}
Y.extend(BuiltClass, main);
return BuiltClass;
},
_hasImpl : function(extClass) {
var classes = this._getClasses();
for (var i = 0, l = classes.length; i < l; i++) {
var cls = classes[i];
if (cls._yuibuild) {
var exts = cls._yuibuild.exts,
ll = exts.length,
j;
for (j = 0; j < ll; j++) {
if (exts[j] === extClass) {
return true;
}
}
}
}
return false;
},
_getClass : function(main, cfg) {
var dynamic = (cfg && false === cfg.dynamic) ? false : true,
builtClass = (dynamic) ? Base.build._template(main) : main;
builtClass._yuibuild = {
id: null,
exts : [],
dynamic : dynamic
};
return builtClass;
},
_getAggregates : function(main, cfg) {
var aggr = [],
cfgAggr = (cfg && cfg.aggregates),
c = main,
classAggr;
while (c && c.prototype) {
classAggr = c._buildCfg && c._buildCfg.aggregates;
if (classAggr) {
aggr = aggr.concat(classAggr);
}
c = c.superclass ? c.superclass.constructor : null;
}
if (cfgAggr) {
aggr = aggr.concat(cfgAggr);
}
return aggr;
}
});
}, '3.0.0' ,{requires:['base-base']});
YUI.add('base', function(Y){}, '3.0.0' ,{use:['base-base', 'base-pluginhost', 'base-build']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("classnamemanager",function(C){var B="classNamePrefix",D="classNameDelimiter",A=C.config;A[B]=A[B]||"yui";A[D]=A[D]||"-";C.ClassNameManager=function(){var E=A[B],F=A[D];return{getClassName:C.cached(function(I,G){var H=E+F+((G)?Array.prototype.join.call(arguments,F):I);return H.replace(/\s/g,"");})};}();},"3.0.0");

View File

@@ -0,0 +1,87 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('classnamemanager', function(Y) {
/**
* Contains a singleton (ClassNameManager) that enables easy creation and caching of
* prefixed class names.
* @module classnamemanager
*/
/**
* A singleton class providing:
*
* <ul>
* <li>Easy creation of prefixed class names</li>
* <li>Caching of previously created class names for improved performance.</li>
* </ul>
*
* @class ClassNameManager
* @static
*/
// String constants
var CLASS_NAME_PREFIX = 'classNamePrefix',
CLASS_NAME_DELIMITER = 'classNameDelimiter',
CONFIG = Y.config;
// Global config
/**
* Configuration property indicating the prefix for all CSS class names in this YUI instance.
*
* @property Y.config.classNamePrefix
* @type {String}
* @default "yui"
* @static
*/
CONFIG[CLASS_NAME_PREFIX] = CONFIG[CLASS_NAME_PREFIX] || 'yui';
/**
* Configuration property indicating the delimiter used to compose all CSS class names in
* this YUI instance.
*
* @property Y.config.classNameDelimiter
* @type {String}
* @default "-"
* @static
*/
CONFIG[CLASS_NAME_DELIMITER] = CONFIG[CLASS_NAME_DELIMITER] || '-';
Y.ClassNameManager = function () {
var sPrefix = CONFIG[CLASS_NAME_PREFIX],
sDelimiter = CONFIG[CLASS_NAME_DELIMITER];
return {
/**
* Returns a class name prefixed with the the value of the
* <code>Y.config.classNamePrefix</code> attribute + the provided strings.
* Uses the <code>Y.config.classNameDelimiter</code> attribute to delimit the
* provided strings. E.g. Y.ClassNameManager.getClassName('foo','bar'); // yui-foo-bar
*
* @method getClassName
* @param {String}+ one or more classname bits to be joined and prefixed
*/
getClassName: Y.cached(function (c, x) {
var sClass = sPrefix + sDelimiter +
// ((x) ? Y.Array(arguments, 0, true).join(sDelimiter) : c);
((x) ? Array.prototype.join.call(arguments, sDelimiter) : c);
return sClass.replace(/\s/g, '');
})
};
}();
}, '3.0.0' );

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("collection",function(E){var C=E.Lang,D=Array.prototype,B=E.Array;B.lastIndexOf=(D.lastIndexOf)?function(A,F){return A.lastIndexOf(F);}:function(A,G){for(var F=A.length-1;F>=0;F=F-1){if(A[F]===G){break;}}return F;};B.unique=function(F,H){var A=F.slice(),G=0,J=-1,I=null;while(G<A.length){I=A[G];while((J=A.lastIndexOf(I))!==G){A.splice(J,1);}G+=1;}if(H){if(C.isNumber(A[0])){A.sort(B.numericSort);}else{A.sort();}}return A;};B.filter=(D.filter)?function(A,F,G){return D.filter.call(A,F,G);}:function(A,G,H){var F=[];B.each(A,function(K,J,I){if(G.call(H,K,J,I)){F.push(K);}});return F;};B.reject=function(A,F,G){return B.filter(A,function(J,I,H){return !F.call(G,J,I,H);});};B.every=(D.every)?function(A,F,G){return D.every.call(A,F,G);}:function(F,H,I){var A=F.length;for(var G=0;G<A;G=G+1){if(!H.call(I,F[G],G,F)){return false;}}return true;};B.map=(D.map)?function(A,F,G){return D.map.call(A,F,G);}:function(A,G,H){var F=[];B.each(A,function(K,J,I){F.push(G.call(H,K,J,I));});return F;};B.reduce=(D.reduce)?function(A,H,F,G){return D.reduce.call(A,function(L,K,J,I){return F.call(G,L,K,J,I);},H);}:function(A,I,G,H){var F=I;B.each(A,function(L,K,J){F=G.call(H,F,L,K,J);});return F;};B.find=function(F,H,I){var A=F.length;for(var G=0;G<A;G++){if(H.call(I,F[G],G,F)){return F[G];}}return null;};B.grep=function(A,F){return B.filter(A,function(H,G){return F.test(H);});};B.partition=function(A,G,H){var F={matches:[],rejects:[]};B.each(A,function(J,I){var K=G.call(H,J,I,A)?F.matches:F.rejects;K.push(J);});return F;};B.zip=function(F,A){var G=[];B.each(F,function(I,H){G.push([I,A[H]]);});return G;};},"3.0.0");

View File

@@ -0,0 +1,294 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('collection', function(Y) {
/**
* Collection utilities beyond what is provided in the YUI core
* @module collection
*/
var L = Y.Lang, Native = Array.prototype, A = Y.Array;
/**
* Adds the following array utilities to the YUI instance
* (Y.Array). This is in addition to the methods provided
* in the core.
* @class YUI~array~extras
*/
/**
* Returns the index of the last item in the array
* that contains the specified value, -1 if the
* value isn't found.
* method Array.lastIndexOf
* @static
* @param a {Array} the array to search
* @param val the value to search for
* @return {int} the index of hte item that contains the value or -1
*/
A.lastIndexOf = (Native.lastIndexOf) ?
function(a ,val) {
return a.lastIndexOf(val);
} :
function(a, val) {
for (var i=a.length-1; i>=0; i=i-1) {
if (a[i] === val) {
break;
}
}
return i;
};
/**
* Returns a copy of the array with the duplicate entries removed
* @method Array.unique
* @static
* @param a {Array} the array to find the subset of uniques for
* @param sort {bool} flag to denote if the array is sorted or not. Defaults to false, the more general operation
* @return {Array} a copy of the array with duplicate entries removed
*/
A.unique = function(a, sort) {
var b = a.slice(), i = 0, n = -1, item = null;
while (i < b.length) {
item = b[i];
while ((n = b.lastIndexOf(item)) !== i) {
b.splice(n, 1);
}
i += 1;
}
// Note: the sort option doesn't really belong here... I think it was added
// because there was a way to fast path the two operations together. That
// implementation was not working, so I replaced it with the following.
// Leaving it in so that the API doesn't get broken.
if (sort) {
if (L.isNumber(b[0])) {
b.sort(A.numericSort);
} else {
b.sort();
}
}
return b;
};
/**
* Executes the supplied function on each item in the array.
* Returns a new array containing the items that the supplied
* function returned true for.
* @method Array.filter
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned true. If no items matched an empty array is
* returned.
*/
A.filter = (Native.filter) ?
function(a, f, o) {
return Native.filter.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
if (f.call(o, item, i, a)) {
results.push(item);
}
});
return results;
};
/**
* The inverse of filter. Executes the supplied function on each item.
* Returns a new array containing the items that the supplied
* function returned *false* for.
* @method Array.reject
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} The items on which the supplied function
* returned false.
*/
A.reject = function(a, f, o) {
return A.filter(a, function(item, i, a) {
return !f.call(o, item, i, a);
});
};
/**
* Executes the supplied function on each item in the array.
* @method Array.every
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {boolean} true if every item in the array returns true
* from the supplied function.
*/
A.every = (Native.every) ?
function(a, f, o) {
return Native.every.call(a,f,o);
} :
function(a, f, o) {
var l = a.length;
for (var i = 0; i < l; i=i+1) {
if (!f.call(o, a[i], i, a)) {
return false;
}
}
return true;
};
/**
* Executes the supplied function on each item in the array.
* @method Array.map
* @param a {Array} the array to iterate
* @param f {Function} the function to execute on each item
* @param o Optional context object
* @static
* @return {Array} A new array containing the return value
* of the supplied function for each item in the original
* array.
*/
A.map = (Native.map) ?
function(a, f, o) {
return Native.map.call(a, f, o);
} :
function(a, f, o) {
var results = [];
A.each(a, function(item, i, a) {
results.push(f.call(o, item, i, a));
});
return results;
};
/**
* Executes the supplied function on each item in the array.
* Reduce "folds" the array into a single value.
* @method Array.reduce
* @param a {Array} the array to iterate
* @param init The initial value to start from
* @param f {Function} the function to execute on each item. It
* is responsible for returning the updated value of the
* computation.
* @param o Optional context object
* @static
* @return A value that results from iteratively applying the
* supplied function to each element in the array.
*/
A.reduce = (Native.reduce) ?
function(a, init, f, o) {
//Firefox's Array.reduce does not allow inclusion of a
// thisObject, so we need to implement it manually
return Native.reduce.call(a, function(init, item, i, a) {
return f.call(o, init, item, i, a);
}, init);
} :
function(a, init, f, o) {
var r = init;
A.each(a, function (item, i, a) {
r = f.call(o, r, item, i, a);
});
return r;
};
/**
* Executes the supplied function on each item in the array,
* searching for the first item that matches the supplied
* function.
* @method Array.find
* @param a {Array} the array to search
* @param f {Function} the function to execute on each item.
* Iteration is stopped as soon as this function returns true
* on an item.
* @param o Optional context object
* @static
* @return {object} the first item that the supplied function
* returns true for, or null if it never returns true
*/
A.find = function(a, f, o) {
var l = a.length;
for(var i=0; i < l; i++) {
if (f.call(o, a[i], i, a)) {
return a[i];
}
}
return null;
};
/**
* Iterates over an array, returning a new array of all the elements
* that match the supplied regular expression
* @method Array.grep
* @param a {Array} a collection to iterate over
* @param pattern {RegExp} The regular expression to test against
* each item
* @static
* @return {Array} All the items in the collection that
* produce a match against the supplied regular expression.
* If no items match, an empty array is returned.
*/
A.grep = function (a, pattern) {
return A.filter(a, function (item, index) {
return pattern.test(item);
});
};
/**
* Partitions an array into two new arrays, one with the items
* that match the supplied function, and one with the items that
* do not.
* @method Array.partition
* @param a {Array} a collection to iterate over
* @paran f {Function} a function that will receive each item
* in the collection and its index.
* @param o Optional execution context of f.
* @static
* @return An object with two members, 'matches' and 'rejects',
* that are arrays containing the items that were selected or
* rejected by the test function (or an empty array).
*/
A.partition = function (a, f, o) {
var results = {matches: [], rejects: []};
A.each(a, function (item, index) {
var set = f.call(o, item, index, a) ? results.matches : results.rejects;
set.push(item);
});
return results;
};
/**
* Creates an array of arrays by pairing the corresponding
* elements of two arrays together into a new array.
* @method Array.zip
* @param a {Array} a collection to iterate over
* @param a2 {Array} another collection whose members will be
* paired with members of the first parameter
* @static
* @return An array of arrays formed by pairing each element
* of the first collection with an item in the second collection
* having the corresponding index.
*/
A.zip = function (a, a2) {
var results = [];
A.each(a, function (item, index) {
results.push([item, a2[index]]);
});
return results;
};
}, '3.0.0' );

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,896 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('compat', function(Y) {
var COMPAT_ARG = '~yui|2|compat~';
if (window.YAHOO != YUI) {
// get any existing YAHOO obj props
var o = (window.YAHOO) ? YUI.merge(window.YAHOO) : null;
// Make the YUI global the YAHOO global
window.YAHOO = YUI;
// augment old YAHOO props
if (o) {
Y.mix(Y, o);
}
}
// add old namespaces
Y.namespace("util", "widget", "example");
// case/location change
Y.env = (Y.env) ? Y.mix(Y.env, Y.Env) : Y.Env;
Y.lang = (Y.lang) ? Y.mix(Y.lang, Y.Lang) : Y.Lang;
Y.env.ua = Y.UA;
// support Y.register
Y.mix(Y.env, {
modules: [],
listeners: [],
getVersion: function(name) {
return this.Env.modules[name] || null;
}
});
var L = Y.lang;
// add old lang properties
Y.mix(L, {
augmentObject: function(r, s) {
var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
return Y.mix(r, s, (wl), wl);
},
augmentProto: function(r, s) {
var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
return Y.mix(r, s, (wl), wl, 1);
},
// extend: Y.bind(Y.extend, Y),
extend: Y.extend,
// merge: Y.bind(Y.merge, Y)
merge: Y.merge
}, true);
L.augment = L.augmentProto;
L.hasOwnProperty = function(o, k) {
return (o.hasOwnProperty(k));
};
Y.augmentProto = L.augmentProto;
// add register function
Y.mix(Y, {
register: function(name, mainClass, data) {
var mods = Y.Env.modules;
if (!mods[name]) {
mods[name] = { versions:[], builds:[] };
}
var m=mods[name],v=data.version,b=data.build,ls=Y.Env.listeners;
m.name = name;
m.version = v;
m.build = b;
m.versions.push(v);
m.builds.push(b);
m.mainClass = mainClass;
// fire the module load listeners
for (var i=0;i<ls.length;i=i+1) {
ls[i](m);
}
// label the main class
if (mainClass) {
mainClass.VERSION = v;
mainClass.BUILD = b;
} else {
}
}
});
// add old load listeners
if ("undefined" !== typeof YAHOO_config) {
var l=YAHOO_config.listener,ls=Y.Env.listeners,unique=true,i;
if (l) {
// if YAHOO is loaded multiple times we need to check to see if
// this is a new config object. If it is, add the new component
// load listener to the stack
for (i=0;i<ls.length;i=i+1) {
if (ls[i]==l) {
unique=false;
break;
}
}
if (unique) {
ls.push(l);
}
}
}
// add old registration for yahoo
Y.register("yahoo", Y, {version: "3.0.0", build: "1549"});
if (Y.Event) {
var o = {
/**
* Safari detection
* @property isSafari
* @private
* @static
* @deprecated use Y.Env.UA.webkit
*/
isSafari: Y.UA.webkit,
/**
* webkit version
* @property webkit
* @type string
* @private
* @static
* @deprecated use Y.Env.UA.webkit
*/
webkit: Y.UA.webkit,
/**
* Normalized keycodes for webkit/safari
* @property webkitKeymap
* @type {int: int}
* @private
* @static
* @final
*/
webkitKeymap: {
63232: 38, // up
63233: 40, // down
63234: 37, // left
63235: 39, // right
63276: 33, // page up
63277: 34, // page down
25: 9 // SHIFT-TAB (Safari provides a different key code in
// this case, even though the shiftKey modifier is set)
},
/**
* IE detection
* @property isIE
* @private
* @static
* @deprecated use Y.Env.UA.ie
*/
isIE: Y.UA.ie,
/**
* Returns scrollLeft
* @method _getScrollLeft
* @static
* @private
*/
_getScrollLeft: function() {
return this._getScroll()[1];
},
/**
* Returns scrollTop
* @method _getScrollTop
* @static
* @private
*/
_getScrollTop: function() {
return this._getScroll()[0];
},
/**
* Returns the scrollTop and scrollLeft. Used to calculate the
* pageX and pageY in Internet Explorer
* @method _getScroll
* @static
* @private
*/
_getScroll: function() {
var d = Y.config.doc, dd = d.documentElement, db = d.body;
if (dd && (dd.scrollTop || dd.scrollLeft)) {
return [dd.scrollTop, dd.scrollLeft];
} else if (db) {
return [db.scrollTop, db.scrollLeft];
} else {
return [0, 0];
}
},
/**
* Returns the event's pageX
* @method getPageX
* @param {Event} ev the event
* @return {int} the event's pageX
* @static
*/
getPageX: function(ev) {
var x = ev.pageX;
if (!x && 0 !== x) {
x = ev.clientX || 0;
if ( Y.UA.ie ) {
x += this._getScrollLeft();
}
}
return x;
},
/**
* Returns the charcode for an event
* @method getCharCode
* @param {Event} ev the event
* @return {int} the event's charCode
* @static
*/
getCharCode: function(ev) {
var code = ev.keyCode || ev.charCode || 0;
// webkit normalization
if (Y.UA.webkit && (code in Y.Event.webkitKeymap)) {
code = Y.Event.webkitKeymap[code];
}
return code;
},
/**
* Returns the event's pageY
* @method getPageY
* @param {Event} ev the event
* @return {int} the event's pageY
* @static
*/
getPageY: function(ev) {
var y = ev.pageY;
if (!y && 0 !== y) {
y = ev.clientY || 0;
if ( Y.UA.ie ) {
y += this._getScrollTop();
}
}
return y;
},
/**
* Returns the pageX and pageY properties as an indexed array.
* @method getXY
* @param {Event} ev the event
* @return {[x, y]} the pageX and pageY properties of the event
* @static
*/
getXY: function(ev) {
return [this.getPageX(ev), this.getPageY(ev)];
},
/**
* Returns the event's related target
* @method getRelatedTarget
* @param {Event} ev the event
* @return {HTMLElement} the event's relatedTarget
* @static
*/
getRelatedTarget: function(ev) {
var t = ev.relatedTarget;
if (!t) {
if (ev.type == "mouseout") {
t = ev.toElement;
} else if (ev.type == "mouseover") {
t = ev.fromElement;
}
}
return this.resolveTextNode(t);
},
/**
* Returns the time of the event. If the time is not included, the
* event is modified using the current time.
* @method getTime
* @param {Event} ev the event
* @return {Date} the time of the event
* @static
*/
getTime: function(ev) {
if (!ev.time) {
var t = new Date().getTime();
try {
ev.time = t;
} catch(ex) {
this.lastError = ex;
return t;
}
}
return ev.time;
},
/**
* Convenience method for stopPropagation + preventDefault
* @method stopEvent
* @param {Event} ev the event
* @static
*/
stopEvent: function(ev) {
this.stopPropagation(ev);
this.preventDefault(ev);
},
/**
* Stops event propagation
* @method stopPropagation
* @param {Event} ev the event
* @static
*/
stopPropagation: function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
/**
* Prevents the default behavior of the event
* @method preventDefault
* @param {Event} ev the event
* @static
*/
preventDefault: function(ev) {
if (ev.preventDefault) {
ev.preventDefault();
} else {
ev.returnValue = false;
}
},
/**
* Returns the event's target element. Safari sometimes provides
* a text node, and this is automatically resolved to the text
* node's parent so that it behaves like other browsers.
* @method getTarget
* @param {Event} ev the event
* @param {boolean} resolveTextNode when set to true the target's
* parent will be returned if the target is a
* text node. @deprecated, the text node is
* now resolved automatically
* @return {HTMLElement} the event's target
* @static
*/
getTarget: function(ev, resolveTextNode) {
var t = ev.target || ev.srcElement;
return this.resolveTextNode(t);
},
/**
* In some cases, some browsers will return a text node inside
* the actual element that was targeted. This normalizes the
* return value for getTarget and getRelatedTarget.
* @method resolveTextNode
* @param {HTMLElement} node node to resolve
* @return {HTMLElement} the normized node
* @static
*/
resolveTextNode: function(node) {
if (node && 3 == node.nodeType) {
return node.parentNode;
} else {
return node;
}
},
/**
* We cache elements bound by id because when the unload event
* fires, we can no longer use document.getElementById
* @method getEl
* @static
* @private
* @deprecated Elements are not cached any longer
*/
getEl: function(id) {
return Y.get(id);
}
};
Y.mix(Y.Event, o);
/**
* Calls Y.Event.attach with the correct argument order
* @method removeListener
*/
Y.Event.removeListener = function(el, type, fn, data, override) {
var context, a=[type, fn, el];
if (data) {
if (override) {
context = (override === true) ? data : override;
}
a.push(context);
a.push(data);
}
a.push(COMPAT_ARG);
return Y.Event.detach.apply(Y.Event, a);
};
/**
* Calls Y.Event.detach with the correct argument order
* @method addListener
*/
Y.Event.addListener = function(el, type, fn, data, override) {
// var a = Y.Array(arguments, 0, true), el = a.shift();
// a.splice(2, 0, el);
// return Y.Event.attach.apply(Y.Event, a);
var context, a=[type, fn, el];
if (data) {
if (override) {
context = (override === true) ? data : override;
}
a.push(context);
a.push(data);
}
a.push(COMPAT_ARG);
return Y.Event.attach.apply(Y.Event, a);
};
Y.Event.on = Y.Event.addListener;
var newOnavail = Y.Event.onAvailable;
Y.Event.onAvailable = function(id, fn, p_obj, p_override) {
return newOnavail(id, fn, p_obj, p_override, false, true);
};
Y.Event.onContentReady = function(id, fn, p_obj, p_override) {
return newOnavail(id, fn, p_obj, p_override, true, true);
};
Y.Event.onDOMReady = function(fn) {
var a = Y.Array(arguments, 0, true);
a.unshift('event:ready');
return Y.on.apply(Y, a);
};
Y.util.Event = Y.Event;
var CE = function(type, oScope, silent, signature) {
//debugger;
var o = {
context: oScope,
silent: silent || false
// signature: signature || CE.LIST
};
CE.superclass.constructor.call(this, type, o);
this.signature = signature || CE.LIST;
};
Y.extend(CE, Y.CustomEvent, {
});
/**
* Subscriber listener sigature constant. The LIST type returns three
* parameters: the event type, the array of args passed to fire, and
* the optional custom object
* @property YAHOO.util.CustomEvent.LIST
* @static
* @type int
*/
CE.LIST = 0;
/**
* Subscriber listener sigature constant. The FLAT type returns two
* parameters: the first argument passed to fire and the optional
* custom object
* @property YAHOO.util.CustomEvent.FLAT
* @static
* @type int
*/
CE.FLAT = 1;
Y.util.CustomEvent = CE;
var EP = function() {
//console.log('Compat CustomEvent constructor executed: ' + this._yuid);
if (!this._yuievt) {
var sub = this.subscribe;
Y.EventTarget.apply(this, arguments);
this.subscribe = sub;
this.__yuiepinit = function() {};
}
};
Y.extend(EP, Y.EventTarget, {
createEvent: function(type, o) {
o = o || {};
o.signature = o.signature || CE.FLAT;
return this.publish(type, o);
},
subscribe: function(type, fn, obj, override) {
var ce = this._yuievt.events[type] || this.createEvent(type),
a = Y.Array(arguments);
if (override && true !== override) {
// a[2] = override;
// a[1] = obj;
}
Y.EventTarget.prototype.subscribe.apply(this, a);
},
fireEvent: function(type) {
return this.fire.apply(this, arguments);
},
hasEvent: function(type) {
return this.getEvent(type);
}
});
Y.util.EventProvider = EP;
}
Y.register("event", Y, {version: "3.0.0", build: "1549"});
var propertyCache = {};
var patterns = {
HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,
OP_SCROLL:/^(?:inline|table-row)$/i
};
var hyphenToCamel = function(property) {
if ( !patterns.HYPHEN.test(property) ) {
return property; // no hyphens
}
if (propertyCache[property]) { // already converted
return propertyCache[property];
}
var converted = property;
while( patterns.HYPHEN.exec(converted) ) {
converted = converted.replace(RegExp.$1,
RegExp.$1.substr(1).toUpperCase());
}
propertyCache[property] = converted;
return converted;
//return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
};
var Dom = {
get: function(el) {
if (el) {
if (el.nodeType || el.item) { // Node, or NodeList
return el;
}
if (typeof el === 'string') { // id
return document.getElementById(el);
}
if ('length' in el) { // array-like
var c = [];
for (var i = 0, len = el.length; i < len; ++i) {
c[c.length] = Dom.get(el[i]);
}
return c;
}
return el; // some other object, just pass it back
}
return null;
},
isAncestor: function(haystack, needle) {
return YUI.DOM.contains(Dom.get(haystack), Dom.get(needle));
},
inDocument: function(el) {
return Dom.isAncestor(Y.config.doc.documentElement, el);
},
batch: function(el, method, o, override, args) {
el = (el && (el.tagName || el.item)) ? el : Dom.get(el); // skip get() when possible
if (!el || !method) {
return false;
}
if (args) {
args = Y.Array(args);
}
var scope = (override) ? o : window;
var apply = function(el) {
if (args) {
var tmp = slice.call(args);
tmp.unshift(el);
return method.apply(scope, tmp);
} else {
return method.call(scope, el, o);
}
};
if (el.tagName || el.length === undefined) { // element or not array-like
return apply(el);
}
var collection = [];
for (var i = 0, len = el.length; i < len; ++i) {
collection[collection.length] = apply(el[i]);
}
return collection;
},
// 2.x returns false if already present
_addClass: function(el, className) {
if ( YUI.DOM.hasClass(el, className) ) {
return false;
}
YUI.DOM.addClass(el, className);
return true;
},
// 2.x returns false if not present
_removeClass: function(el, className) {
if ( !YUI.DOM.hasClass(el, className) ) {
return false;
}
YUI.DOM.removeClass(el, className);
return true;
},
// 2.x returns false if no newClass or same as oldClass
_replaceClass: function(el, oldClass, newClass) {
if (!newClass || oldClass === newClass) {
return false;
}
YUI.DOM.replaceClass(el, oldClass, newClass);
return true;
},
getElementsByClassName: function(className, tag, root) {
tag = tag || '*';
root = (root) ? Dom.get(root) : Y.config.doc;
var nodes = [];
if (root) {
nodes = Y.Selector.query(tag + '.' + className, root);
}
return nodes;
},
getElementsBy: function(method, tag, root) {
tag = tag || '*';
root = (root) ? Dom.get(root) : null || document;
var nodes = [];
if (root) {
nodes = YUI.DOM.byTag(tag, root, method);
}
return nodes;
},
getViewportWidth: YUI.DOM.winWidth,
getViewportHeight: YUI.DOM.winHeight,
getDocumentWidth: YUI.DOM.docWidth,
getDocumentHeight: YUI.DOM.docHeight,
getDocumentScrollTop: YUI.DOM.docScrollY,
getDocumentScrollLeft: YUI.DOM.docScrollX,
getDocumentHeight: YUI.DOM.docHeight,
_guid: function(el, prefix) {
prefix = prefix || 'yui-gen';
Dom._id_counter = Dom._id_counter || 0;
if (el && el.id) { // do not override existing ID
return el.id;
}
var id = prefix + Dom._id_counter++;
if (el) {
el.id = id;
}
return id;
},
_region: function(el) {
if ( (el.parentNode === null || el.offsetParent === null ||
YUI.DOM.getStyle(el, 'display') == 'none') && el != el.ownerDocument.body) {
return false;
}
return YUI.DOM.region(el);
},
_ancestorByClass: function(element, className) {
return YUI.DOM.ancestor(element, function(el) {
return YUI.DOM.hasClass(el, className);
});
},
_ancestorByTag: function(element, tag) {
tag = tag.toUpperCase();
return YUI.DOM.ancestor(element, function(el) {
return el.tagName.toUpperCase() === tag;
});
}
};
var slice = [].slice;
var wrap = function(fn, name) {
Dom[name] = function() {
var args = slice.call(arguments);
args[0] = Dom.get(args[0]);
return fn.apply(Dom, args);
};
};
var wrapped = {
getAncestorBy: YUI.DOM.ancestor,
getAncestorByClassName: Dom._ancestorByClass,
getAncestorByTagName: Dom._ancestorByTag,
getPreviousSiblingBy: YUI.DOM.previous,
getPreviousSibling: YUI.DOM.previous,
getNextSiblingBy: YUI.DOM.next,
getNextSibling: YUI.DOM.next,
getFirstChildBy: YUI.DOM.firstChild,
getFirstChild: YUI.DOM.firstChild,
getLastChildBy: YUI.DOM.lastChild,
getLastChild: YUI.DOM.lastChild,
getChildrenBy: YUI.DOM.children,
getChildren: YUI.DOM.children,
insertBefore: function(newNode, refNode) {
YUI.DOM.insertBefore(Dom.get(newNode), Dom.get(refNode));
},
insertAfter: function(newNode, refNode) {
YUI.DOM.insertAfter(Dom.get(newNode), Dom.get(refNode));
}
};
Y.each(wrapped, wrap);
var batched = {
getStyle: YUI.DOM.getStyle,
setStyle: YUI.DOM.setStyle,
getXY: YUI.DOM.getXY,
setXY: YUI.DOM.setXY,
getX: YUI.DOM.getX,
getY: YUI.DOM.getY,
setX: YUI.DOM.setX,
setY: YUI.DOM.setY,
getRegion: Dom._region,
hasClass: YUI.DOM.hasClass,
addClass: Dom._addClass,
removeClass: Dom._removeClass,
replaceClass: Dom._replaceClass,
generateId: Dom._guid
};
Y.each(batched, function(v, n) {
Dom[n] = function(el) {
var args = slice.call(arguments, 1);
return Dom.batch(el, v, null, null, args);
};
});
Y.util.Dom = Dom;
YAHOO.util.Region = function(t, r, b, l) {
this.top = t;
this[1] = t;
this.right = r;
this.bottom = b;
this.left = l;
this[0] = l;
};
YAHOO.util.Region.prototype.contains = function(region) {
return ( region.left >= this.left &&
region.right <= this.right &&
region.top >= this.top &&
region.bottom <= this.bottom );
};
YAHOO.util.Region.prototype.getArea = function() {
return ( (this.bottom - this.top) * (this.right - this.left) );
};
YAHOO.util.Region.prototype.intersect = function(region) {
var t = Math.max( this.top, region.top );
var r = Math.min( this.right, region.right );
var b = Math.min( this.bottom, region.bottom );
var l = Math.max( this.left, region.left );
if (b >= t && r >= l) {
return new YAHOO.util.Region(t, r, b, l);
} else {
return null;
}
};
YAHOO.util.Region.prototype.union = function(region) {
var t = Math.min( this.top, region.top );
var r = Math.max( this.right, region.right );
var b = Math.max( this.bottom, region.bottom );
var l = Math.min( this.left, region.left );
return new YAHOO.util.Region(t, r, b, l);
};
YAHOO.util.Region.prototype.toString = function() {
return ( "Region {" +
"top: " + this.top +
", right: " + this.right +
", bottom: " + this.bottom +
", left: " + this.left +
"}" );
};
YAHOO.util.Region.getRegion = function(el) {
return YUI.DOM.region(el);
};
YAHOO.util.Point = function(x, y) {
if (YAHOO.lang.isArray(x)) { // accept input from Dom.getXY, Event.getXY, etc.
y = x[1]; // dont blow away x yet
x = x[0];
}
this.x = this.right = this.left = this[0] = x;
this.y = this.top = this.bottom = this[1] = y;
};
YAHOO.util.Point.prototype = new YAHOO.util.Region();
}, '3.0.0' ,{requires:['dom','event']});
YUI._setup(); YUI.use('dom', 'event', 'compat');

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,710 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('console-filters', function(Y) {
/**
* <p>Provides Plugin.ConsoleFilters plugin class.</p>
*
* <p>This plugin adds the ability to control which Console entries display by filtering on category and source. Two groups of checkboxes are added to the Console footer, one for categories and the other for sources. Only those messages that match a checked category or source are displayed.</p>
*
* @module console-filters
* @namespace Plugin
* @class ConsoleFilters
*/
// Some common strings and functions
var getCN = Y.ClassNameManager.getClassName,
CONSOLE = 'console',
FILTERS = 'filters',
FILTER = 'filter',
CATEGORY = 'category',
SOURCE = 'source',
CATEGORY_DOT = 'category.',
SOURCE_DOT = 'source.',
HOST = 'host',
PARENT_NODE = 'parentNode',
CHECKED = 'checked',
DEF_VISIBILITY = 'defaultVisibility',
DOT = '.',
EMPTY = '',
C_BODY = DOT + Y.Console.CHROME_CLASSES.console_bd_class,
C_FOOT = DOT + Y.Console.CHROME_CLASSES.console_ft_class,
SEL_CHECK = 'input[type=checkbox].',
isString = Y.Lang.isString;
function ConsoleFilters() {
ConsoleFilters.superclass.constructor.apply(this,arguments);
}
Y.mix(ConsoleFilters,{
/**
* Plugin name.
*
* @property ConsoleFilters.NAME
* @type String
* @static
* @default 'consoleFilters'
*/
NAME : 'consoleFilters',
/**
* The namespace hung off the host object that this plugin will inhabit.
*
* @property ConsoleFilters.NS
* @type String
* @static
* @default 'filter'
*/
NS : FILTER,
/**
* Markup template used to create the container for the category filters.
*
* @property ConsoleFilters.CATEGORIES_TEMPLATE
* @type String
* @static
*/
CATEGORIES_TEMPLATE :
'<div class="{categories}"></div>',
/**
* Markup template used to create the container for the source filters.
*
* @property ConsoleFilters.SOURCES_TEMPLATE
* @type String
* @static
*/
SOURCES_TEMPLATE :
'<div class="{sources}"></div>',
/**
* Markup template used to create the category and source filter checkboxes.
*
* @property ConsoleFilters.FILTER_TEMPLATE
* @type String
* @static
*/
FILTER_TEMPLATE :
// IE8 and FF3 don't permit breaking _between_ nowrap elements. IE8
// doesn't understand (non spec) wbr tag, nor does it create text nodes
// for spaces in innerHTML strings. The thin-space entity suffices to
// create a breakable point.
'<label class="{filter_label}">'+
'<input type="checkbox" value="{filter_name}" '+
'class="{filter} {filter_class}"> {filter_name}'+
'</label>&#8201;',
/**
* Classnames used by the templates when creating nodes.
*
* @property ConsoleFilters.CHROME_CLASSES
* @type Object
* @static
* @protected
*/
CHROME_CLASSES : {
categories : getCN(CONSOLE,FILTERS,'categories'),
sources : getCN(CONSOLE,FILTERS,'sources'),
category : getCN(CONSOLE,FILTER,CATEGORY),
source : getCN(CONSOLE,FILTER,SOURCE),
filter : getCN(CONSOLE,FILTER),
filter_label : getCN(CONSOLE,FILTER,'label')
},
ATTRS : {
/**
* Default visibility applied to new categories and sources.
*
* @attribute defaultVisibility
* @type {Boolean}
* @default true
*/
defaultVisibility : {
value : true,
validator : Y.Lang.isBoolean
},
/**
* <p>Map of entry categories to their visibility status. Update a
* particular category's visibility by setting the subattribute to true
* (visible) or false (hidden).</p>
*
* <p>For example, yconsole.filter.set('category.info', false) to hide
* log entries with the category/logLevel of 'info'.</p>
*
* <p>Similarly, yconsole.filter.get('category.warn') will return a
* boolean indicating whether that category is currently being included
* in the UI.</p>
*
* <p>Unlike the YUI instance configuration's logInclude and logExclude
* properties, filtered entries are only hidden from the UI, but
* can be made visible again.</p>
*
* @attribute category
* @type Object
*/
category : {
value : {},
validator : function (v,k) {
return this._validateCategory(k,v);
}
},
/**
* <p>Map of entry sources to their visibility status. Update a
* particular sources's visibility by setting the subattribute to true
* (visible) or false (hidden).</p>
*
* <p>For example, yconsole.filter.set('sources.slider', false) to hide
* log entries originating from Y.Slider.</p>
*
* @attribute source
* @type Object
*/
source : {
value : {},
validator : function (v,k) {
return this._validateSource(k,v);
}
},
/**
* Maximum number of entries to store in the message cache. Use this to
* limit the memory footprint in environments with heavy log usage.
* By default, there is no limit (Number.POSITIVE_INFINITY).
*
* @attribute cacheLimit
* @type {Number}
* @default Number.POSITIVE_INFINITY
*/
cacheLimit : {
value : Number.POSITIVE_INFINITY,
setter : function (v) {
if (Y.Lang.isNumber(v)) {
this._cacheLimit = v;
return v;
} else {
return Y.Attribute.INVALID_VALUE;
}
}
}
}
});
Y.extend(ConsoleFilters, Y.Plugin.Base, {
/**
* Collection of all log messages passed through since the plugin's
* instantiation. This holds all messages regardless of filter status.
* Used as a single source of truth for repopulating the Console body when
* filters are changed.
*
* @property _entries
* @type Array
* @protected
*/
_entries : null,
_cacheLimit : Number.POSITIVE_INFINITY,
/**
* The container node created to house the category filters.
*
* @property _categories
* @type Node
* @protected
*/
_categories : null,
/**
* The container node created to house the source filters.
*
* @property _sources
* @type Node
* @protected
*/
_sources : null,
/**
* Initialize entries collection and attach listeners to host events and
* methods.
*
* @method initializer
* @protected
*/
initializer : function () {
this._entries = [];
this.get(HOST).on("entry", this._onEntry, this);
this.doAfter("renderUI", this.renderUI);
this.doAfter("syncUI", this.syncUI);
this.doAfter("bindUI", this.bindUI);
this.doAfter("clearConsole", this._afterClearConsole);
if (this.get(HOST).get('rendered')) {
this.renderUI();
this.syncUI();
this.bindUI();
}
this.after("cacheLimitChange", this._afterCacheLimitChange);
},
/**
* Removes the plugin UI and unwires events.
*
* @method destructor
* @protected
*/
destructor : function () {
//TODO: grab last {consoleLimit} entries and update the console with
//them (no filtering)
this._entries = [];
if (this._categories) {
this._categories.get(PARENT_NODE).removeChild(this._categories);
}
if (this._sources) {
this._sources.get(PARENT_NODE).removeChild(this._sources);
}
},
/**
* Adds the category and source filter sections to the Console footer.
*
* @method renderUI
* @protected
*/
renderUI : function () {
var foot = this.get(HOST).get('contentBox').query(C_FOOT),
html;
if (foot) {
html = Y.substitute(
ConsoleFilters.CATEGORIES_TEMPLATE,
ConsoleFilters.CHROME_CLASSES);
this._categories = foot.appendChild(Y.Node.create(html));
html = Y.substitute(
ConsoleFilters.SOURCES_TEMPLATE,
ConsoleFilters.CHROME_CLASSES);
this._sources = foot.appendChild(Y.Node.create(html));
}
},
/**
* Binds to checkbox click events and internal attribute change events to
* maintain the UI state.
*
* @method bindUI
* @protected
*/
bindUI : function () {
this._categories.on('click', Y.bind(this._onCategoryCheckboxClick, this));
this._sources.on('click', Y.bind(this._onSourceCheckboxClick, this));
this.after('categoryChange',this._afterCategoryChange);
this.after('sourceChange', this._afterSourceChange);
},
/**
* Updates the UI to be in accordance with the current state of the plugin.
*
* @method syncUI
*/
syncUI : function () {
Y.each(this.get(CATEGORY), function (v, k) {
this._uiSetCheckbox(CATEGORY, k, v);
}, this);
Y.each(this.get(SOURCE), function (v, k) {
this._uiSetCheckbox(SOURCE, k, v);
}, this);
this.refreshConsole();
},
/**
* Ensures a filter is set up for any new categories or sources and
* collects the messages in _entries. If the message is stamped with a
* category or source that is currently being filtered out, the message
* will not pass to the Console's print buffer.
*
* @method _onEntry
* @param e {Event} the custom event object
* @protected
*/
_onEntry : function (e) {
this._entries.push(e.message);
var cat = CATEGORY_DOT + e.message.category,
src = SOURCE_DOT + e.message.source,
cat_filter = this.get(cat),
src_filter = this.get(src),
overLimit = this._entries.length - this._cacheLimit,
visible;
if (overLimit > 0) {
this._entries.splice(0, overLimit);
}
if (cat_filter === undefined) {
visible = this.get(DEF_VISIBILITY);
this.set(cat, visible);
cat_filter = visible;
}
if (src_filter === undefined) {
visible = this.get(DEF_VISIBILITY);
this.set(src, visible);
src_filter = visible;
}
if (!cat_filter || !src_filter) {
e.preventDefault();
}
},
/**
* Flushes the cached entries after a call to the Console's clearConsole().
*
* @method _afterClearConsole
* @protected
*/
_afterClearConsole : function () {
this._entries = [];
},
/**
* Triggers the Console to update if a known category filter
* changes value (e.g. visible => hidden). Updates the appropriate
* checkbox's checked state if necessary.
*
* @method _afterCategoryChange
* @param e {Event} the attribute change event object
* @protected
*/
_afterCategoryChange : function (e) {
var cat = e.subAttrName.replace(/category\./, EMPTY),
before = e.prevVal,
after = e.newVal;
// Don't update the console for new categories
if (!cat || before[cat] !== undefined) {
this.refreshConsole();
this._filterBuffer();
}
if (cat && !e.fromUI) {
this._uiSetCheckbox(CATEGORY, cat, after[cat]);
}
},
/**
* Triggers the Console to update if a known source filter
* changes value (e.g. visible => hidden). Updates the appropriate
* checkbox's checked state if necessary.
*
* @method _afterSourceChange
* @param e {Event} the attribute change event object
* @protected
*/
_afterSourceChange : function (e) {
var src = e.subAttrName.replace(/source\./, EMPTY),
before = e.prevVal,
after = e.newVal;
// Don't update the console for new sources
if (!src || before[src] !== undefined) {
this.refreshConsole();
this._filterBuffer();
}
if (src && !e.fromUI) {
this._uiSetCheckbox(SOURCE, src, after[src]);
}
},
/**
* Flushes the Console's print buffer of any entries that have a category
* or source that is currently being excluded.
*
* @method _filterBuffer
* @protected
*/
_filterBuffer : function () {
var cats = this.get(CATEGORY),
srcs = this.get(SOURCE),
buffer = this.get(HOST).buffer,
start = null,
i;
for (i = buffer.length - 1; i >= 0; --i) {
if (!cats[buffer[i].category] || !srcs[buffer[i].source]) {
start = start || i;
} else if (start) {
buffer.splice(i,(start - i));
start = null;
}
}
if (start) {
buffer.splice(0,start + 1);
}
},
/**
* Trims the cache of entries to the appropriate new length.
*
* @method _afterCacheLimitChange
* @param e {Event} the attribute change event object
* @protected
*/
_afterCacheLimitChange : function (e) {
if (isFinite(e.newVal)) {
var delta = this._entries.length - e.newVal;
if (delta > 0) {
this._entries.splice(0,delta);
}
}
},
/**
* Repopulates the Console with entries appropriate to the current filter
* settings.
*
* @method refreshConsole
*/
refreshConsole : function () {
var entries = this._entries,
host = this.get(HOST),
body = host.get('contentBox').query(C_BODY),
remaining = host.get('consoleLimit'),
cats = this.get(CATEGORY),
srcs = this.get(SOURCE),
buffer = [],
i,e;
if (body) {
host._cancelPrintLoop();
// Evaluate all entries from latest to oldest
for (i = entries.length - 1; i >= 0 && remaining >= 0; --i) {
e = entries[i];
if (cats[e.category] && srcs[e.source]) {
buffer.unshift(e);
--remaining;
}
}
body.set('innerHTML',EMPTY);
host.buffer = buffer;
host.printBuffer();
}
},
/**
* Updates the checked property of a filter checkbox of the specified type.
* If no checkbox is found for the input params, one is created.
*
* @method _uiSetCheckbox
* @param type {String} 'category' or 'source'
* @param item {String} the name of the filter (e.g. 'info', 'event')
* @param checked {Boolean} value to set the checkbox's checked property
* @protected
*/
_uiSetCheckbox : function (type, item, checked) {
if (type && item) {
var container = type === CATEGORY ?
this._categories :
this._sources,
sel = SEL_CHECK + getCN(CONSOLE,FILTER,item),
checkbox = container.query(sel),
host;
if (!checkbox) {
host = this.get(HOST);
this._createCheckbox(container, item);
checkbox = container.query(sel);
host._uiSetHeight(host.get('height'));
}
checkbox.set(CHECKED, checked);
}
},
/**
* Passes checkbox clicks on to the category attribute.
*
* @method _onCategoryCheckboxClick
* @param e {Event} the DOM event
* @protected
*/
_onCategoryCheckboxClick : function (e) {
var t = e.target, cat;
if (t.hasClass(ConsoleFilters.CHROME_CLASSES.filter)) {
cat = t.get('value');
if (cat && cat in this.get(CATEGORY)) {
this.set(CATEGORY_DOT + cat, t.get(CHECKED), { fromUI: true });
}
}
},
/**
* Passes checkbox clicks on to the source attribute.
*
* @method _onSourceCheckboxClick
* @param e {Event} the DOM event
* @protected
*/
_onSourceCheckboxClick : function (e) {
var t = e.target, src;
if (t.hasClass(ConsoleFilters.CHROME_CLASSES.filter)) {
src = t.get('value');
if (src && src in this.get(SOURCE)) {
this.set(SOURCE_DOT + src, t.get(CHECKED), { fromUI: true });
}
}
},
/**
* Hides any number of categories from the UI. Convenience method for
* myConsole.filter.set('category.foo', false); set('category.bar', false);
* and so on.
*
* @method hideCategory
* @param cat* {String} 1..n categories to filter out of the UI
*/
hideCategory : function (cat, multiple) {
if (isString(multiple)) {
Y.Array.each(arguments, arguments.callee, this);
} else {
this.set(CATEGORY_DOT + cat, false);
}
},
/**
* Shows any number of categories in the UI. Convenience method for
* myConsole.filter.set('category.foo', true); set('category.bar', true);
* and so on.
*
* @method showCategory
* @param cat* {String} 1..n categories to allow to display in the UI
*/
showCategory : function (cat, multiple) {
if (isString(multiple)) {
Y.Array.each(arguments, arguments.callee, this);
} else {
this.set(CATEGORY_DOT + cat, true);
}
},
/**
* Hides any number of sources from the UI. Convenience method for
* myConsole.filter.set('source.foo', false); set('source.bar', false);
* and so on.
*
* @method hideSource
* @param src* {String} 1..n sources to filter out of the UI
*/
hideSource : function (src, multiple) {
if (isString(multiple)) {
Y.Array.each(arguments, arguments.callee, this);
} else {
this.set(SOURCE_DOT + src, false);
}
},
/**
* Shows any number of sources in the UI. Convenience method for
* myConsole.filter.set('source.foo', true); set('source.bar', true);
* and so on.
*
* @method showSource
* @param src* {String} 1..n sources to allow to display in the UI
*/
showSource : function (src, multiple) {
if (isString(multiple)) {
Y.Array.each(arguments, arguments.callee, this);
} else {
this.set(SOURCE_DOT + src, true);
}
},
/**
* Creates a checkbox and label from the ConsoleFilters.FILTER_TEMPLATE for
* the provided type and name. The checkbox and label are appended to the
* container node passes as the first arg.
*
* @method _createCheckbox
* @param container {Node} the parentNode of the new checkbox and label
* @param name {String} the identifier of the filter
* @protected
*/
_createCheckbox : function (container, name) {
var info = Y.merge(ConsoleFilters.CHROME_CLASSES, {
filter_name : name,
filter_class : getCN(CONSOLE, FILTER, name)
}),
node = Y.Node.create(
Y.substitute(ConsoleFilters.FILTER_TEMPLATE, info));
container.appendChild(node);
},
/**
* Validates category updates are objects and the subattribute is not too
* deep.
*
* @method _validateCategory
* @param cat {String} the new category:visibility map
* @param v {String} the subattribute path updated
* @return Boolean
* @protected
*/
_validateCategory : function (cat, v) {
return Y.Lang.isObject(v,true) && cat.split(/\./).length < 3;
},
/**
* Validates source updates are objects and the subattribute is not too
* deep.
*
* @method _validateSource
* @param cat {String} the new source:visibility map
* @param v {String} the subattribute path updated
* @return Boolean
* @protected
*/
_validateSource : function (src, v) {
return Y.Lang.isObject(v,true) && src.split(/\./).length < 3;
}
});
Y.namespace('Plugin').ConsoleFilters = ConsoleFilters;
}, '3.0.0' ,{requires:['console','plugin']});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("cookie",function(C){var K=C.Lang,I=C.Object,G=null,D=K.isString,P=K.isObject,F=K.isUndefined,E=K.isFunction,H=encodeURIComponent,B=decodeURIComponent,N=C.config.doc;function J(L){throw new TypeError(L);}function M(L){if(!D(L)||L===""){J("Cookie name must be a non-empty string.");}}function A(L){if(!D(L)||L===""){J("Subcookie name must be a non-empty string.");}}C.Cookie={_createCookieString:function(Q,T,R,O){O=O||{};var V=H(Q)+"="+(R?H(T):T),L=O.expires,U=O.path,S=O.domain;if(P(O)){if(L instanceof Date){V+="; expires="+L.toUTCString();}if(D(U)&&U!==""){V+="; path="+U;}if(D(S)&&S!==""){V+="; domain="+S;}if(O.secure===true){V+="; secure";}}return V;},_createCookieHashString:function(L){if(!P(L)){J("Cookie._createCookieHashString(): Argument must be an object.");}var O=[];I.each(L,function(R,Q){if(!E(R)&&!F(R)){O.push(H(Q)+"="+H(String(R)));}});return O.join("&");},_parseCookieHash:function(S){var R=S.split("&"),T=G,Q={};if(S.length){for(var O=0,L=R.length;O<L;O++){T=R[O].split("=");Q[B(T[0])]=B(T[1]);}}return Q;},_parseCookieString:function(W,Y){var X={};if(D(W)&&W.length>0){var L=(Y===false?function(Z){return Z;}:B),U=W.split(/;\s/g),V=G,O=G,R=G;for(var Q=0,S=U.length;Q<S;Q++){R=U[Q].match(/([^=]+)=/i);if(R instanceof Array){try{V=B(R[1]);O=L(U[Q].substring(R[1].length+1));}catch(T){}}else{V=B(U[Q]);O="";}X[V]=O;}}return X;},exists:function(L){M(L);var O=this._parseCookieString(N.cookie,true);return O.hasOwnProperty(L);},get:function(O,L){M(O);var S,Q,R;if(E(L)){R=L;L={};}else{if(P(L)){R=L.converter;}else{L={};}}S=this._parseCookieString(N.cookie,!L.raw);Q=S[O];if(F(Q)){return G;}if(!E(R)){return Q;}else{return R(Q);}},getSub:function(L,Q,O){var R=this.getSubs(L);if(R!==G){A(Q);if(F(R[Q])){return G;}if(!E(O)){return R[Q];}else{return O(R[Q]);}}else{return G;}},getSubs:function(L){M(L);var O=this._parseCookieString(N.cookie,false);if(D(O[L])){return this._parseCookieHash(O[L]);}return G;},remove:function(O,L){M(O);L=C.merge(L||{},{expires:new Date(0)});return this.set(O,"",L);},removeSub:function(O,S,L){M(O);A(S);L=L||{};var R=this.getSubs(O);if(P(R)&&R.hasOwnProperty(S)){delete R[S];if(!L.removeIfEmpty){return this.setSubs(O,R,L);}else{for(var Q in R){if(R.hasOwnProperty(Q)&&!E(R[Q])&&!F(R[Q])){return this.setSubs(O,R,L);}}return this.remove(O,L);}}else{return"";}},set:function(O,Q,L){M(O);if(F(Q)){J("Cookie.set(): Value cannot be undefined.");}L=L||{};var R=this._createCookieString(O,Q,!L.raw,L);N.cookie=R;return R;},setSub:function(O,R,Q,L){M(O);A(R);if(F(Q)){J("Cookie.setSub(): Subcookie value cannot be undefined.");}var S=this.getSubs(O);if(!P(S)){S={};}S[R]=Q;return this.setSubs(O,S,L);},setSubs:function(O,Q,L){M(O);if(!P(Q)){J("Cookie.setSubs(): Cookie value must be an object.");}var R=this._createCookieString(O,this._createCookieHashString(Q),false,L);N.cookie=R;return R;}};},"3.0.0",{requires:["yui-base"]});

View File

@@ -0,0 +1,491 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('cookie', function(Y) {
/**
* Utilities for cookie management
* @module cookie
*/
//shortcuts
var L = Y.Lang,
O = Y.Object,
NULL = null,
//shortcuts to functions
isString = L.isString,
isObject = L.isObject,
isUndefined = L.isUndefined,
isFunction = L.isFunction,
encode = encodeURIComponent,
decode = decodeURIComponent,
//shortcut to document
doc = Y.config.doc;
/*
* Throws an error message.
*/
function error(message){
throw new TypeError(message);
}
/*
* Checks the validity of a cookie name.
*/
function validateCookieName(name){
if (!isString(name) || name === ""){
error("Cookie name must be a non-empty string.");
}
}
/*
* Checks the validity of a subcookie name.
*/
function validateSubcookieName(subName){
if (!isString(subName) || subName === ""){
error("Subcookie name must be a non-empty string.");
}
}
/**
* Cookie utility.
* @class Cookie
* @static
*/
Y.Cookie = {
//-------------------------------------------------------------------------
// Private Methods
//-------------------------------------------------------------------------
/**
* Creates a cookie string that can be assigned into document.cookie.
* @param {String} name The name of the cookie.
* @param {String} value The value of the cookie.
* @param {Boolean} encodeValue True to encode the value, false to leave as-is.
* @param {Object} options (Optional) Options for the cookie.
* @return {String} The formatted cookie string.
* @method _createCookieString
* @private
* @static
*/
_createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {
options = options || {};
var text /*:String*/ = encode(name) + "=" + (encodeValue ? encode(value) : value),
expires = options.expires,
path = options.path,
domain = options.domain;
if (isObject(options)){
//expiration date
if (expires instanceof Date){
text += "; expires=" + expires.toUTCString();
}
//path
if (isString(path) && path !== ""){
text += "; path=" + path;
}
//domain
if (isString(domain) && domain !== ""){
text += "; domain=" + domain;
}
//secure
if (options.secure === true){
text += "; secure";
}
}
return text;
},
/**
* Formats a cookie value for an object containing multiple values.
* @param {Object} hash An object of key-value pairs to create a string for.
* @return {String} A string suitable for use as a cookie value.
* @method _createCookieHashString
* @private
* @static
*/
_createCookieHashString : function (hash /*:Object*/) /*:String*/ {
if (!isObject(hash)){
error("Cookie._createCookieHashString(): Argument must be an object.");
}
var text /*:Array*/ = [];
O.each(hash, function(value, key){
if (!isFunction(value) && !isUndefined(value)){
text.push(encode(key) + "=" + encode(String(value)));
}
});
return text.join("&");
},
/**
* Parses a cookie hash string into an object.
* @param {String} text The cookie hash string to parse (format: n1=v1&n2=v2).
* @return {Object} An object containing entries for each cookie value.
* @method _parseCookieHash
* @private
* @static
*/
_parseCookieHash : function (text) {
var hashParts = text.split("&"),
hashPart = NULL,
hash = {};
if (text.length){
for (var i=0, len=hashParts.length; i < len; i++){
hashPart = hashParts[i].split("=");
hash[decode(hashPart[0])] = decode(hashPart[1]);
}
}
return hash;
},
/**
* Parses a cookie string into an object representing all accessible cookies.
* @param {String} text The cookie string to parse.
* @param {Boolean} shouldDecode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
* @return {Object} An object containing entries for each accessible cookie.
* @method _parseCookieString
* @private
* @static
*/
_parseCookieString : function (text /*:String*/, shouldDecode /*:Boolean*/) /*:Object*/ {
var cookies /*:Object*/ = {};
if (isString(text) && text.length > 0) {
var decodeValue = (shouldDecode === false ? function(s){return s;} : decode),
cookieParts = text.split(/;\s/g),
cookieName = NULL,
cookieValue = NULL,
cookieNameValue = NULL;
for (var i=0, len=cookieParts.length; i < len; i++){
//check for normally-formatted cookie (name-value)
cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
if (cookieNameValue instanceof Array){
try {
cookieName = decode(cookieNameValue[1]);
cookieValue = decodeValue(cookieParts[i].substring(cookieNameValue[1].length+1));
} catch (ex){
//intentionally ignore the cookie - the encoding is wrong
}
} else {
//means the cookie does not have an "=", so treat it as a boolean flag
cookieName = decode(cookieParts[i]);
cookieValue = "";
}
cookies[cookieName] = cookieValue;
}
}
return cookies;
},
//-------------------------------------------------------------------------
// Public Methods
//-------------------------------------------------------------------------
/**
* Determines if the cookie with the given name exists. This is useful for
* Boolean cookies (those that do not follow the name=value convention).
* @param {String} name The name of the cookie to check.
* @return {Boolean} True if the cookie exists, false if not.
* @method exists
* @static
*/
exists: function(name) {
validateCookieName(name); //throws error
var cookies = this._parseCookieString(doc.cookie, true);
return cookies.hasOwnProperty(name);
},
/**
* Returns the cookie value for the given name.
* @param {String} name The name of the cookie to retrieve.
* @param {Function|Object} options (Optional) An object containing one or more
* cookie options: raw (true/false) and converter (a function).
* The converter function is run on the value before returning it. The
* function is not used if the cookie doesn't exist. The function can be
* passed instead of the options object for backwards compatibility. When
* raw is set to true, the cookie value is not URI decoded.
* @return {Variant} If no converter is specified, returns a string or null if
* the cookie doesn't exist. If the converter is specified, returns the value
* returned from the converter or null if the cookie doesn't exist.
* @method get
* @static
*/
get : function (name, options) {
validateCookieName(name); //throws error
var cookies,
cookie,
converter;
//if options is a function, then it's the converter
if (isFunction(options)) {
converter = options;
options = {};
} else if (isObject(options)) {
converter = options.converter;
} else {
options = {};
}
cookies = this._parseCookieString(doc.cookie, !options.raw);
cookie = cookies[name];
//should return null, not undefined if the cookie doesn't exist
if (isUndefined(cookie)) {
return NULL;
}
if (!isFunction(converter)){
return cookie;
} else {
return converter(cookie);
}
},
/**
* Returns the value of a subcookie.
* @param {String} name The name of the cookie to retrieve.
* @param {String} subName The name of the subcookie to retrieve.
* @param {Function} converter (Optional) A function to run on the value before returning
* it. The function is not used if the cookie doesn't exist.
* @return {Variant} If the cookie doesn't exist, null is returned. If the subcookie
* doesn't exist, null if also returned. If no converter is specified and the
* subcookie exists, a string is returned. If a converter is specified and the
* subcookie exists, the value returned from the converter is returned.
* @method getSub
* @static
*/
getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/) /*:Variant*/ {
var hash /*:Variant*/ = this.getSubs(name);
if (hash !== NULL) {
validateSubcookieName(subName); //throws error
if (isUndefined(hash[subName])){
return NULL;
}
if (!isFunction(converter)){
return hash[subName];
} else {
return converter(hash[subName]);
}
} else {
return NULL;
}
},
/**
* Returns an object containing name-value pairs stored in the cookie with the given name.
* @param {String} name The name of the cookie to retrieve.
* @return {Object} An object of name-value pairs if the cookie with the given name
* exists, null if it does not.
* @method getSubs
* @static
*/
getSubs : function (name) {
validateCookieName(name); //throws error
var cookies = this._parseCookieString(doc.cookie, false);
if (isString(cookies[name])){
return this._parseCookieHash(cookies[name]);
}
return NULL;
},
/**
* Removes a cookie from the machine by setting its expiration date to
* sometime in the past.
* @param {String} name The name of the cookie to remove.
* @param {Object} options (Optional) An object containing one or more
* cookie options: path (a string), domain (a string),
* and secure (true/false). The expires option will be overwritten
* by the method.
* @return {String} The created cookie string.
* @method remove
* @static
*/
remove : function (name, options) {
validateCookieName(name); //throws error
//set options
options = Y.merge(options || {}, {
expires: new Date(0)
});
//set cookie
return this.set(name, "", options);
},
/**
* Removes a sub cookie with a given name.
* @param {String} name The name of the cookie in which the subcookie exists.
* @param {String} subName The name of the subcookie to remove.
* @param {Object} options (Optional) An object containing one or more
* cookie options: path (a string), domain (a string), expires (a Date object),
* removeIfEmpty (true/false), and secure (true/false). This must be the same
* settings as the original subcookie.
* @return {String} The created cookie string.
* @method removeSub
* @static
*/
removeSub : function(name, subName, options) {
validateCookieName(name); //throws error
validateSubcookieName(subName); //throws error
options = options || {};
//get all subcookies for this cookie
var subs = this.getSubs(name);
//delete the indicated subcookie
if (isObject(subs) && subs.hasOwnProperty(subName)){
delete subs[subName];
if (!options.removeIfEmpty) {
//reset the cookie
return this.setSubs(name, subs, options);
} else {
//reset the cookie if there are subcookies left, else remove
for (var key in subs){
if (subs.hasOwnProperty(key) && !isFunction(subs[key]) && !isUndefined(subs[key])){
return this.setSubs(name, subs, options);
}
}
return this.remove(name, options);
}
} else {
return "";
}
},
/**
* Sets a cookie with a given name and value.
* @param {String} name The name of the cookie to set.
* @param {Variant} value The value to set for the cookie.
* @param {Object} options (Optional) An object containing one or more
* cookie options: path (a string), domain (a string), expires (a Date object),
* secure (true/false), and raw (true/false). Setting raw to true indicates
* that the cookie should not be URI encoded before being set.
* @return {String} The created cookie string.
* @method set
* @static
*/
set : function (name, value, options) {
validateCookieName(name); //throws error
if (isUndefined(value)){
error("Cookie.set(): Value cannot be undefined.");
}
options = options || {};
var text = this._createCookieString(name, value, !options.raw, options);
doc.cookie = text;
return text;
},
/**
* Sets a sub cookie with a given name to a particular value.
* @param {String} name The name of the cookie to set.
* @param {String} subName The name of the subcookie to set.
* @param {Variant} value The value to set.
* @param {Object} options (Optional) An object containing one or more
* cookie options: path (a string), domain (a string), expires (a Date object),
* and secure (true/false).
* @return {String} The created cookie string.
* @method setSub
* @static
*/
setSub : function (name, subName, value, options) {
validateCookieName(name); //throws error
validateSubcookieName(subName); //throws error
if (isUndefined(value)){
error("Cookie.setSub(): Subcookie value cannot be undefined.");
}
var hash = this.getSubs(name);
if (!isObject(hash)){
hash = {};
}
hash[subName] = value;
return this.setSubs(name, hash, options);
},
/**
* Sets a cookie with a given name to contain a hash of name-value pairs.
* @param {String} name The name of the cookie to set.
* @param {Object} value An object containing name-value pairs.
* @param {Object} options (Optional) An object containing one or more
* cookie options: path (a string), domain (a string), expires (a Date object),
* and secure (true/false).
* @return {String} The created cookie string.
* @method setSubs
* @static
*/
setSubs : function (name, value, options) {
validateCookieName(name); //throws error
if (!isObject(value)){
error("Cookie.setSubs(): Cookie value must be an object.");
}
var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
doc.cookie = text;
return text;
}
};
}, '3.0.0' ,{requires:['yui-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("dataschema-array",function(C){var A=C.Lang,B={apply:function(F,G){var D=G,E={results:[],meta:{}};if(A.isArray(D)){if(A.isArray(F.resultFields)){E=B._parseResults(F.resultFields,D,E);}else{E.results=D;}}else{E.error=new Error("Array schema parse failure");}return E;},_parseResults:function(H,K,D){var G=[],O,N,I,J,M,L,F,E;for(F=K.length-1;F>-1;F--){O={};N=K[F];I=(A.isObject(N)&&!A.isFunction(N))?2:(A.isArray(N))?1:(A.isString(N))?0:-1;if(I>0){for(E=H.length-1;E>-1;E--){J=H[E];M=(!A.isUndefined(J.key))?J.key:J;L=(!A.isUndefined(N[M]))?N[M]:N[E];O[M]=C.DataSchema.Base.parse(L,J);}}else{if(I===0){O=N;}else{O=null;}}G[F]=O;}D.results=G;return D;}};C.DataSchema.Array=C.mix(B,C.DataSchema.Base);},"3.0.0",{requires:["dataschema-base"]});

View File

@@ -0,0 +1,107 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('dataschema-array', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with data stored in arrays.
*
* @module dataschema
* @submodule dataschema-array
*/
/**
* Array subclass for the DataSchema Utility.
* @class DataSchema.Array
* @extends DataSchema.Base
* @static
*/
var LANG = Y.Lang,
SchemaArray = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.Array static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Applies a given schema to given Array data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} Array data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var data_in = data,
data_out = {results:[],meta:{}};
if(LANG.isArray(data_in)) {
if(LANG.isArray(schema.resultFields)) {
// Parse results data
data_out = SchemaArray._parseResults(schema.resultFields, data_in, data_out);
}
else {
data_out.results = data_in;
}
}
else {
data_out.error = new Error("Array schema parse failure");
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param fields {Array} Schema to parse against.
* @param array_in {Array} Array to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_parseResults: function(fields, array_in, data_out) {
var results = [],
result, item, type, field, key, value, i, j;
for(i=array_in.length-1; i>-1; i--) {
result = {};
item = array_in[i];
type = (LANG.isObject(item) && !LANG.isFunction(item)) ? 2 : (LANG.isArray(item)) ? 1 : (LANG.isString(item)) ? 0 : -1;
if(type > 0) {
for(j=fields.length-1; j>-1; j--) {
field = fields[j];
key = (!LANG.isUndefined(field.key)) ? field.key : field;
value = (!LANG.isUndefined(item[key])) ? item[key] : item[j];
result[key] = Y.DataSchema.Base.parse(value, field);
}
}
else if(type === 0) {
result = item;
}
else {
//TODO: null or {}?
result = null;
}
results[i] = result;
}
data_out.results = results;
return data_out;
}
};
Y.DataSchema.Array = Y.mix(SchemaArray, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['dataschema-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("dataschema-base",function(B){var A=B.Lang,C={apply:function(D,E){return E;},parse:function(D,E){if(E.parser){var F=(A.isFunction(E.parser))?E.parser:B.Parsers[E.parser+""];if(F){D=F.call(this,D);}else{}}return D;}};B.namespace("DataSchema").Base=C;B.namespace("Parsers");},"3.0.0",{requires:["base"]});

View File

@@ -0,0 +1,73 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('dataschema-base', function(Y) {
/**
* The DataSchema utility provides a common configurable interface for widgets to
* apply a given schema to a variety of data.
*
* @module dataschema
*/
/**
* Provides the base DataSchema implementation, which can be extended to
* create DataSchemas for specific data formats, such XML, JSON, text and
* arrays.
*
* @module dataschema
* @submodule dataschema-base
*/
var LANG = Y.Lang,
/**
* Base class for the YUI DataSchema Utility.
* @class DataSchema.Base
* @static
*/
SchemaBase = {
/**
* Overridable method returns data as-is.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} Data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
return data;
},
/**
* Applies field parser, if defined
*
* @method parse
* @param value {Object} Original value.
* @param field {Object} Field.
* @return {Object} Type-converted value.
*/
parse: function(value, field) {
if(field.parser) {
var parser = (LANG.isFunction(field.parser)) ?
field.parser : Y.Parsers[field.parser+''];
if(parser) {
value = parser.call(this, value);
}
else {
}
}
return value;
}
};
Y.namespace("DataSchema").Base = SchemaBase;
Y.namespace("Parsers");
}, '3.0.0' ,{requires:['base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("dataschema-json",function(C){var A=C.Lang,B={getPath:function(D){var G=null,F=[],E=0;if(D){D=D.replace(/\[(['"])(.*?)\1\]/g,function(I,H,J){F[E]=J;return".@"+(E++);}).replace(/\[(\d+)\]/g,function(I,H){F[E]=parseInt(H,10)|0;return".@"+(E++);}).replace(/^\./,"");if(!/[^\w\.\$@]/.test(D)){G=D.split(".");for(E=G.length-1;E>=0;--E){if(G[E].charAt(0)==="@"){G[E]=F[parseInt(G[E].substr(1),10)];}}}else{}}return G;},getLocationValue:function(G,F){var E=0,D=G.length;for(;E<D;E++){if(!A.isUndefined(F[G[E]])){F=F[G[E]];}else{F=undefined;break;}}return F;},apply:function(F,G){var D=G,E={results:[],meta:{}};if(!A.isObject(G)){try{D=C.JSON.parse(G);}catch(H){E.error=H;return E;}}if(A.isObject(D)&&F){if(!A.isUndefined(F.resultListLocator)){E=B._parseResults(F,D,E);}if(!A.isUndefined(F.metaFields)){E=B._parseMeta(F.metaFields,D,E);}}else{E.error=new Error("JSON schema parse failure");}return E;},_parseResults:function(H,D,G){var F=[],I,E;if(H.resultListLocator){I=B.getPath(H.resultListLocator);if(I){F=B.getLocationValue(I,D);if(F===undefined){G.results=[];E=new Error("JSON results retrieval failure");}else{if(A.isArray(H.resultFields)&&A.isArray(F)){G=B._getFieldValues(H.resultFields,F,G);}else{G.results=[];E=new Error("JSON Schema fields retrieval failure");}}}else{E=new Error("JSON Schema results locator failure");}if(E){G.error=E;}}return G;},_getFieldValues:function(K,P,E){var G=[],M=K.length,H,F,O,Q,S,D,J=[],N=[],L=[],R,I;for(H=0;H<M;H++){O=K[H];Q=O.key||O;S=B.getPath(Q);if(S){if(S.length===1){J[J.length]={key:Q,path:S[0]};}else{N[N.length]={key:Q,path:S};}}else{}D=(A.isFunction(O.parser))?O.parser:C.Parsers[O.parser+""];if(D){L[L.length]={key:Q,parser:D};}}for(H=P.length-1;H>=0;--H){I={};R=P[H];if(R){for(F=J.length-1;F>=0;--F){I[J[F].key]=C.DataSchema.Base.parse((A.isUndefined(R[J[F].path])?R[F]:R[J[F].path]),J[F]);}for(F=N.length-1;F>=0;--F){I[N[F].key]=C.DataSchema.Base.parse((B.getLocationValue(N[F].path,R)),N[F]);}for(F=L.length-1;F>=0;--F){Q=L[F].key;I[Q]=L[F].parser(I[Q]);if(A.isUndefined(I[Q])){I[Q]=null;}}G[H]=I;}}E.results=G;return E;},_parseMeta:function(G,D,F){if(A.isObject(G)){var E,H;for(E in G){if(G.hasOwnProperty(E)){H=B.getPath(G[E]);if(H&&D){F.meta[E]=B.getLocationValue(H,D);}}}}else{F.error=new Error("JSON meta data retrieval failure");}return F;}};C.DataSchema.JSON=C.mix(B,C.DataSchema.Base);},"3.0.0",{requires:["json","dataschema-base"]});

View File

@@ -0,0 +1,294 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('dataschema-json', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with JSON data.
*
* @module dataschema
* @submodule dataschema-json
*/
/**
* JSON subclass for the DataSchema Utility.
* @class DataSchema.JSON
* @extends DataSchema.Base
* @static
*/
var LANG = Y.Lang,
SchemaJSON = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.JSON static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Utility function converts JSON locator strings into walkable paths
*
* @method DataSchema.JSON.getPath
* @param locator {String} JSON value locator.
* @return {String[]} Walkable path to data value.
* @static
*/
getPath: function(locator) {
var path = null,
keys = [],
i = 0;
if (locator) {
// Strip the ["string keys"] and [1] array indexes
locator = locator.
replace(/\[(['"])(.*?)\1\]/g,
function (x,$1,$2) {keys[i]=$2;return '.@'+(i++);}).
replace(/\[(\d+)\]/g,
function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@'+(i++);}).
replace(/^\./,''); // remove leading dot
// Validate against problematic characters.
if (!/[^\w\.\$@]/.test(locator)) {
path = locator.split('.');
for (i=path.length-1; i >= 0; --i) {
if (path[i].charAt(0) === '@') {
path[i] = keys[parseInt(path[i].substr(1),10)];
}
}
}
else {
}
}
return path;
},
/**
* Utility function to walk a path and return the value located there.
*
* @method DataSchema.JSON.getLocationValue
* @param path {String[]} Locator path.
* @param data {String} Data to traverse.
* @return {Object} Data value at location.
* @static
*/
getLocationValue: function (path, data) {
var i = 0,
len = path.length;
for (;i<len;i++) {
if(!LANG.isUndefined(data[path[i]])) {
data = data[path[i]];
}
else {
data = undefined;
break;
}
}
return data;
},
/**
* Applies a given schema to given JSON data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} JSON data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var data_in = data,
data_out = {results:[],meta:{}};
// Convert incoming JSON strings
if(!LANG.isObject(data)) {
try {
data_in = Y.JSON.parse(data);
}
catch(e) {
data_out.error = e;
return data_out;
}
}
if(LANG.isObject(data_in) && schema) {
// Parse results data
if(!LANG.isUndefined(schema.resultListLocator)) {
data_out = SchemaJSON._parseResults(schema, data_in, data_out);
}
// Parse meta data
if(!LANG.isUndefined(schema.metaFields)) {
data_out = SchemaJSON._parseMeta(schema.metaFields, data_in, data_out);
}
}
else {
data_out.error = new Error("JSON schema parse failure");
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param schema {Object} Schema to parse against.
* @param json_in {Object} JSON to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_parseResults: function(schema, json_in, data_out) {
var results = [],
path,
error;
if(schema.resultListLocator) {
path = SchemaJSON.getPath(schema.resultListLocator);
if(path) {
results = SchemaJSON.getLocationValue(path, json_in);
if (results === undefined) {
data_out.results = [];
error = new Error("JSON results retrieval failure");
}
else {
if(LANG.isArray(schema.resultFields) && LANG.isArray(results)) {
data_out = SchemaJSON._getFieldValues(schema.resultFields, results, data_out);
}
else {
data_out.results = [];
error = new Error("JSON Schema fields retrieval failure");
}
}
}
else {
error = new Error("JSON Schema results locator failure");
}
if (error) {
data_out.error = error;
}
}
return data_out;
},
/**
* Get field data values out of list of full results
*
* @method _getFieldValues
* @param fields {Array} Fields to find.
* @param array_in {Array} Results to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_getFieldValues: function(fields, array_in, data_out) {
var results = [],
len = fields.length,
i, j,
field, key, path, parser,
simplePaths = [], complexPaths = [], fieldParsers = [],
result, record;
// First collect hashes of simple paths, complex paths, and parsers
for (i=0; i<len; i++) {
field = fields[i]; // A field can be a simple string or a hash
key = field.key || field; // Find the key
// Validate and store locators for later
path = SchemaJSON.getPath(key);
if (path) {
if (path.length === 1) {
simplePaths[simplePaths.length] = {key:key, path:path[0]};
} else {
complexPaths[complexPaths.length] = {key:key, path:path};
}
} else {
}
// Validate and store parsers for later
//TODO: use Y.DataSchema.parse?
parser = (LANG.isFunction(field.parser)) ? field.parser : Y.Parsers[field.parser+''];
if (parser) {
fieldParsers[fieldParsers.length] = {key:key, parser:parser};
}
}
// Traverse list of array_in, creating records of simple fields,
// complex fields, and applying parsers as necessary
for (i=array_in.length-1; i>=0; --i) {
record = {};
result = array_in[i];
if(result) {
// Cycle through simpleLocators
for (j=simplePaths.length-1; j>=0; --j) {
// Bug 1777850: The result might be an array instead of object
record[simplePaths[j].key] = Y.DataSchema.Base.parse(
(LANG.isUndefined(result[simplePaths[j].path]) ?
result[j] : result[simplePaths[j].path]), simplePaths[j]);
}
// Cycle through complexLocators
for (j=complexPaths.length - 1; j>=0; --j) {
record[complexPaths[j].key] = Y.DataSchema.Base.parse(
(SchemaJSON.getLocationValue(complexPaths[j].path, result)), complexPaths[j] );
}
// Cycle through fieldParsers
for (j=fieldParsers.length-1; j>=0; --j) {
key = fieldParsers[j].key;
record[key] = fieldParsers[j].parser(record[key]);
// Safety net
if (LANG.isUndefined(record[key])) {
record[key] = null;
}
}
results[i] = record;
}
}
data_out.results = results;
return data_out;
},
/**
* Parses results data according to schema
*
* @method _parseMeta
* @param metaFields {Object} Metafields definitions.
* @param json_in {Object} JSON to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Schema-parsed meta data.
* @static
* @protected
*/
_parseMeta: function(metaFields, json_in, data_out) {
if(LANG.isObject(metaFields)) {
var key, path;
for(key in metaFields) {
if (metaFields.hasOwnProperty(key)) {
path = SchemaJSON.getPath(metaFields[key]);
if (path && json_in) {
data_out.meta[key] = SchemaJSON.getLocationValue(path, json_in);
}
}
}
}
else {
data_out.error = new Error("JSON meta data retrieval failure");
}
return data_out;
}
};
Y.DataSchema.JSON = Y.mix(SchemaJSON, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['json', 'dataschema-base']});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("dataschema-text",function(C){var B=C.Lang,A={apply:function(F,G){var D=G,E={results:[],meta:{}};if(B.isString(D)&&B.isString(F.resultDelimiter)){E=A._parseResults(F,D,E);}else{E.error=new Error("Text schema parse failure");}return E;},_parseResults:function(D,K,E){var I=D.resultDelimiter,H=[],L,P,S,R,J,N,Q,O,G,F,M=K.length-I.length;if(K.substr(M)==I){K=K.substr(0,M);}L=K.split(D.resultDelimiter);for(G=L.length-1;G>-1;G--){S={};R=L[G];if(B.isString(D.fieldDelimiter)){P=R.split(D.fieldDelimiter);if(B.isArray(D.resultFields)){J=D.resultFields;for(F=J.length-1;F>-1;F--){N=J[F];Q=(!B.isUndefined(N.key))?N.key:N;O=(!B.isUndefined(P[Q]))?P[Q]:P[F];S[Q]=C.DataSchema.Base.parse(O,N);}}}else{S=R;}H[G]=S;}E.results=H;return E;}};C.DataSchema.Text=C.mix(A,C.DataSchema.Base);},"3.0.0",{requires:["dataschema-base"]});

View File

@@ -0,0 +1,116 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('dataschema-text', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with delimited text data.
*
* @module dataschema
* @submodule dataschema-text
*/
/**
* Text subclass for the DataSchema Utility.
* @class DataSchema.Text
* @extends DataSchema.Base
* @static
*/
var LANG = Y.Lang,
SchemaText = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.Text static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Applies a given schema to given delimited text data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} Text data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var data_in = data,
data_out = {results:[],meta:{}};
if(LANG.isString(data_in) && LANG.isString(schema.resultDelimiter)) {
// Parse results data
data_out = SchemaText._parseResults(schema, data_in, data_out);
}
else {
data_out.error = new Error("Text schema parse failure");
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param schema {Array} Schema to parse against.
* @param text_in {String} Text to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_parseResults: function(schema, text_in, data_out) {
var resultDelim = schema.resultDelimiter,
results = [],
results_in, fields_in, result, item, fields, field, key, value, i, j,
// Delete final delimiter at end of string if there
tmpLength = text_in.length-resultDelim.length;
if(text_in.substr(tmpLength) == resultDelim) {
text_in = text_in.substr(0, tmpLength);
}
// Split into results
results_in = text_in.split(schema.resultDelimiter);
for(i=results_in.length-1; i>-1; i--) {
result = {};
item = results_in[i];
if(LANG.isString(schema.fieldDelimiter)) {
fields_in = item.split(schema.fieldDelimiter);
if(LANG.isArray(schema.resultFields)) {
fields = schema.resultFields;
for(j=fields.length-1; j>-1; j--) {
field = fields[j];
key = (!LANG.isUndefined(field.key)) ? field.key : field;
value = (!LANG.isUndefined(fields_in[key])) ? fields_in[key] : fields_in[j];
result[key] = Y.DataSchema.Base.parse(value, field);
}
}
}
else {
result = item;
}
results[i] = result;
}
data_out.results = results;
return data_out;
}
};
Y.DataSchema.Text = Y.mix(SchemaText, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['dataschema-base']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("dataschema-xml",function(C){var B=C.Lang,A={apply:function(F,G){var D=G,E={results:[],meta:{}};if(D&&D.nodeType&&(D.nodeType===9||D.nodeType===1||D.nodeType===11)&&F){E=A._parseResults(F,D,E);E=A._parseMeta(F.metaFields,D,E);}else{E.error=new Error("XML schema parse failure");}return E;},_getLocationValue:function(K,H){var F=K.locator||K.key||K,E=H.ownerDocument||H,D,G,I=null;try{if(!B.isUndefined(E.evaluate)){D=E.evaluate(F,H,E.createNSResolver(!H.ownerDocument?H.documentElement:H.ownerDocument.documentElement),0,null);while(G=D.iterateNext()){I=G.textContent;}}else{E.setProperty("SelectionLanguage","XPath");D=H.selectNodes(F)[0];I=D.value||D.text||null;}return C.DataSchema.Base.parse(I,K);}catch(J){}},_parseMeta:function(H,G,F){if(B.isObject(H)){var E,D=G.ownerDocument||G;for(E in H){if(H.hasOwnProperty(E)){F.meta[E]=A._getLocationValue(H[E],D);}}}return F;},_parseResults:function(F,K,G){if(F.resultListLocator&&B.isArray(F.resultFields)){var E=K.getElementsByTagName(F.resultListLocator),L=F.resultFields,J=[],D,M,N,I,H;if(E.length){for(I=E.length-1;I>=0;I--){N={};D=E[I];for(H=L.length-1;H>=0;H--){M=L[H];N[M.key||M]=A._getLocationValue(M,D);}J[I]=N;}G.results=J;}else{G.error=new Error("XML schema result nodes retrieval failure");}}return G;}};C.DataSchema.XML=C.mix(A,C.DataSchema.Base);},"3.0.0",{requires:["dataschema-base"]});

View File

@@ -0,0 +1,164 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('dataschema-xml', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with XML data.
*
* @module dataschema
* @submodule dataschema-xml
*/
var LANG = Y.Lang,
/**
* XML subclass for the DataSchema Utility.
* @class DataSchema.XML
* @extends DataSchema.Base
* @static
*/
SchemaXML = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.XML static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Applies a given schema to given XML data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {XMLDoc} XML document.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var xmldoc = data,
data_out = {results:[],meta:{}};
if(xmldoc && xmldoc.nodeType && (xmldoc.nodeType === 9 || xmldoc.nodeType === 1 || xmldoc.nodeType === 11) && schema) {
// Parse results data
data_out = SchemaXML._parseResults(schema, xmldoc, data_out);
// Parse meta data
data_out = SchemaXML._parseMeta(schema.metaFields, xmldoc, data_out);
}
else {
data_out.error = new Error("XML schema parse failure");
}
return data_out;
},
/**
* Get an XPath-specified value for a given field from an XML node or document.
*
* @method _getLocationValue
* @param field {String | Object} Field definition.
* @param context {Object} XML node or document to search within.
* @return {Object} Data value or null.
* @static
* @protected
*/
_getLocationValue: function(field, context) {
var locator = field.locator || field.key || field,
xmldoc = context.ownerDocument || context,
result, res, value = null;
try {
// Standards mode
if(!LANG.isUndefined(xmldoc.evaluate)) {
result = xmldoc.evaluate(locator, context, xmldoc.createNSResolver(!context.ownerDocument ? context.documentElement : context.ownerDocument.documentElement), 0, null);
while(res = result.iterateNext()) {
value = res.textContent;
}
}
// IE mode
else {
xmldoc.setProperty("SelectionLanguage", "XPath");
result = context.selectNodes(locator)[0];
value = result.value || result.text || null;
}
return Y.DataSchema.Base.parse(value, field);
}
catch(e) {
}
},
/**
* Parses results data according to schema
*
* @method _parseMeta
* @param xmldoc_in {Object} XML document parse.
* @param data_out {Object} In-progress schema-parsed data to update.
* @return {Object} Schema-parsed data.
* @static
* @protected
*/
_parseMeta: function(metaFields, xmldoc_in, data_out) {
if(LANG.isObject(metaFields)) {
var key,
xmldoc = xmldoc_in.ownerDocument || xmldoc_in;
for(key in metaFields) {
if (metaFields.hasOwnProperty(key)) {
data_out.meta[key] = SchemaXML._getLocationValue(metaFields[key], xmldoc);
}
}
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param schema {Object} Schema to parse against.
* @param xmldoc_in {Object} XML document parse.
* @param data_out {Object} In-progress schema-parsed data to update.
* @return {Object} Schema-parsed data.
* @static
* @protected
*/
_parseResults: function(schema, xmldoc_in, data_out) {
if(schema.resultListLocator && LANG.isArray(schema.resultFields)) {
var nodeList = xmldoc_in.getElementsByTagName(schema.resultListLocator),
fields = schema.resultFields,
results = [],
node, field, result, i, j;
if(nodeList.length) {
// Loop through each result node
for(i=nodeList.length-1; i>= 0; i--) {
result = {};
node = nodeList[i];
// Find each field value
for(j=fields.length-1; j>= 0; j--) {
field = fields[j];
result[field.key || field] = SchemaXML._getLocationValue(field, node);
}
results[i] = result;
}
data_out.results = results;
}
else {
data_out.error = new Error("XML schema result nodes retrieval failure");
}
}
return data_out;
}
};
Y.DataSchema.XML = Y.mix(SchemaXML, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['dataschema-base']});

View File

@@ -0,0 +1,735 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('dataschema-base', function(Y) {
/**
* The DataSchema utility provides a common configurable interface for widgets to
* apply a given schema to a variety of data.
*
* @module dataschema
*/
/**
* Provides the base DataSchema implementation, which can be extended to
* create DataSchemas for specific data formats, such XML, JSON, text and
* arrays.
*
* @module dataschema
* @submodule dataschema-base
*/
var LANG = Y.Lang,
/**
* Base class for the YUI DataSchema Utility.
* @class DataSchema.Base
* @static
*/
SchemaBase = {
/**
* Overridable method returns data as-is.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} Data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
return data;
},
/**
* Applies field parser, if defined
*
* @method parse
* @param value {Object} Original value.
* @param field {Object} Field.
* @return {Object} Type-converted value.
*/
parse: function(value, field) {
if(field.parser) {
var parser = (LANG.isFunction(field.parser)) ?
field.parser : Y.Parsers[field.parser+''];
if(parser) {
value = parser.call(this, value);
}
else {
}
}
return value;
}
};
Y.namespace("DataSchema").Base = SchemaBase;
Y.namespace("Parsers");
}, '3.0.0' ,{requires:['base']});
YUI.add('dataschema-json', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with JSON data.
*
* @module dataschema
* @submodule dataschema-json
*/
/**
* JSON subclass for the DataSchema Utility.
* @class DataSchema.JSON
* @extends DataSchema.Base
* @static
*/
var LANG = Y.Lang,
SchemaJSON = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.JSON static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Utility function converts JSON locator strings into walkable paths
*
* @method DataSchema.JSON.getPath
* @param locator {String} JSON value locator.
* @return {String[]} Walkable path to data value.
* @static
*/
getPath: function(locator) {
var path = null,
keys = [],
i = 0;
if (locator) {
// Strip the ["string keys"] and [1] array indexes
locator = locator.
replace(/\[(['"])(.*?)\1\]/g,
function (x,$1,$2) {keys[i]=$2;return '.@'+(i++);}).
replace(/\[(\d+)\]/g,
function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@'+(i++);}).
replace(/^\./,''); // remove leading dot
// Validate against problematic characters.
if (!/[^\w\.\$@]/.test(locator)) {
path = locator.split('.');
for (i=path.length-1; i >= 0; --i) {
if (path[i].charAt(0) === '@') {
path[i] = keys[parseInt(path[i].substr(1),10)];
}
}
}
else {
}
}
return path;
},
/**
* Utility function to walk a path and return the value located there.
*
* @method DataSchema.JSON.getLocationValue
* @param path {String[]} Locator path.
* @param data {String} Data to traverse.
* @return {Object} Data value at location.
* @static
*/
getLocationValue: function (path, data) {
var i = 0,
len = path.length;
for (;i<len;i++) {
if(!LANG.isUndefined(data[path[i]])) {
data = data[path[i]];
}
else {
data = undefined;
break;
}
}
return data;
},
/**
* Applies a given schema to given JSON data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} JSON data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var data_in = data,
data_out = {results:[],meta:{}};
// Convert incoming JSON strings
if(!LANG.isObject(data)) {
try {
data_in = Y.JSON.parse(data);
}
catch(e) {
data_out.error = e;
return data_out;
}
}
if(LANG.isObject(data_in) && schema) {
// Parse results data
if(!LANG.isUndefined(schema.resultListLocator)) {
data_out = SchemaJSON._parseResults(schema, data_in, data_out);
}
// Parse meta data
if(!LANG.isUndefined(schema.metaFields)) {
data_out = SchemaJSON._parseMeta(schema.metaFields, data_in, data_out);
}
}
else {
data_out.error = new Error("JSON schema parse failure");
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param schema {Object} Schema to parse against.
* @param json_in {Object} JSON to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_parseResults: function(schema, json_in, data_out) {
var results = [],
path,
error;
if(schema.resultListLocator) {
path = SchemaJSON.getPath(schema.resultListLocator);
if(path) {
results = SchemaJSON.getLocationValue(path, json_in);
if (results === undefined) {
data_out.results = [];
error = new Error("JSON results retrieval failure");
}
else {
if(LANG.isArray(schema.resultFields) && LANG.isArray(results)) {
data_out = SchemaJSON._getFieldValues(schema.resultFields, results, data_out);
}
else {
data_out.results = [];
error = new Error("JSON Schema fields retrieval failure");
}
}
}
else {
error = new Error("JSON Schema results locator failure");
}
if (error) {
data_out.error = error;
}
}
return data_out;
},
/**
* Get field data values out of list of full results
*
* @method _getFieldValues
* @param fields {Array} Fields to find.
* @param array_in {Array} Results to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_getFieldValues: function(fields, array_in, data_out) {
var results = [],
len = fields.length,
i, j,
field, key, path, parser,
simplePaths = [], complexPaths = [], fieldParsers = [],
result, record;
// First collect hashes of simple paths, complex paths, and parsers
for (i=0; i<len; i++) {
field = fields[i]; // A field can be a simple string or a hash
key = field.key || field; // Find the key
// Validate and store locators for later
path = SchemaJSON.getPath(key);
if (path) {
if (path.length === 1) {
simplePaths[simplePaths.length] = {key:key, path:path[0]};
} else {
complexPaths[complexPaths.length] = {key:key, path:path};
}
} else {
}
// Validate and store parsers for later
//TODO: use Y.DataSchema.parse?
parser = (LANG.isFunction(field.parser)) ? field.parser : Y.Parsers[field.parser+''];
if (parser) {
fieldParsers[fieldParsers.length] = {key:key, parser:parser};
}
}
// Traverse list of array_in, creating records of simple fields,
// complex fields, and applying parsers as necessary
for (i=array_in.length-1; i>=0; --i) {
record = {};
result = array_in[i];
if(result) {
// Cycle through simpleLocators
for (j=simplePaths.length-1; j>=0; --j) {
// Bug 1777850: The result might be an array instead of object
record[simplePaths[j].key] = Y.DataSchema.Base.parse(
(LANG.isUndefined(result[simplePaths[j].path]) ?
result[j] : result[simplePaths[j].path]), simplePaths[j]);
}
// Cycle through complexLocators
for (j=complexPaths.length - 1; j>=0; --j) {
record[complexPaths[j].key] = Y.DataSchema.Base.parse(
(SchemaJSON.getLocationValue(complexPaths[j].path, result)), complexPaths[j] );
}
// Cycle through fieldParsers
for (j=fieldParsers.length-1; j>=0; --j) {
key = fieldParsers[j].key;
record[key] = fieldParsers[j].parser(record[key]);
// Safety net
if (LANG.isUndefined(record[key])) {
record[key] = null;
}
}
results[i] = record;
}
}
data_out.results = results;
return data_out;
},
/**
* Parses results data according to schema
*
* @method _parseMeta
* @param metaFields {Object} Metafields definitions.
* @param json_in {Object} JSON to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Schema-parsed meta data.
* @static
* @protected
*/
_parseMeta: function(metaFields, json_in, data_out) {
if(LANG.isObject(metaFields)) {
var key, path;
for(key in metaFields) {
if (metaFields.hasOwnProperty(key)) {
path = SchemaJSON.getPath(metaFields[key]);
if (path && json_in) {
data_out.meta[key] = SchemaJSON.getLocationValue(path, json_in);
}
}
}
}
else {
data_out.error = new Error("JSON meta data retrieval failure");
}
return data_out;
}
};
Y.DataSchema.JSON = Y.mix(SchemaJSON, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['json', 'dataschema-base']});
YUI.add('dataschema-xml', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with XML data.
*
* @module dataschema
* @submodule dataschema-xml
*/
var LANG = Y.Lang,
/**
* XML subclass for the DataSchema Utility.
* @class DataSchema.XML
* @extends DataSchema.Base
* @static
*/
SchemaXML = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.XML static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Applies a given schema to given XML data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {XMLDoc} XML document.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var xmldoc = data,
data_out = {results:[],meta:{}};
if(xmldoc && xmldoc.nodeType && (xmldoc.nodeType === 9 || xmldoc.nodeType === 1 || xmldoc.nodeType === 11) && schema) {
// Parse results data
data_out = SchemaXML._parseResults(schema, xmldoc, data_out);
// Parse meta data
data_out = SchemaXML._parseMeta(schema.metaFields, xmldoc, data_out);
}
else {
data_out.error = new Error("XML schema parse failure");
}
return data_out;
},
/**
* Get an XPath-specified value for a given field from an XML node or document.
*
* @method _getLocationValue
* @param field {String | Object} Field definition.
* @param context {Object} XML node or document to search within.
* @return {Object} Data value or null.
* @static
* @protected
*/
_getLocationValue: function(field, context) {
var locator = field.locator || field.key || field,
xmldoc = context.ownerDocument || context,
result, res, value = null;
try {
// Standards mode
if(!LANG.isUndefined(xmldoc.evaluate)) {
result = xmldoc.evaluate(locator, context, xmldoc.createNSResolver(!context.ownerDocument ? context.documentElement : context.ownerDocument.documentElement), 0, null);
while(res = result.iterateNext()) {
value = res.textContent;
}
}
// IE mode
else {
xmldoc.setProperty("SelectionLanguage", "XPath");
result = context.selectNodes(locator)[0];
value = result.value || result.text || null;
}
return Y.DataSchema.Base.parse(value, field);
}
catch(e) {
}
},
/**
* Parses results data according to schema
*
* @method _parseMeta
* @param xmldoc_in {Object} XML document parse.
* @param data_out {Object} In-progress schema-parsed data to update.
* @return {Object} Schema-parsed data.
* @static
* @protected
*/
_parseMeta: function(metaFields, xmldoc_in, data_out) {
if(LANG.isObject(metaFields)) {
var key,
xmldoc = xmldoc_in.ownerDocument || xmldoc_in;
for(key in metaFields) {
if (metaFields.hasOwnProperty(key)) {
data_out.meta[key] = SchemaXML._getLocationValue(metaFields[key], xmldoc);
}
}
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param schema {Object} Schema to parse against.
* @param xmldoc_in {Object} XML document parse.
* @param data_out {Object} In-progress schema-parsed data to update.
* @return {Object} Schema-parsed data.
* @static
* @protected
*/
_parseResults: function(schema, xmldoc_in, data_out) {
if(schema.resultListLocator && LANG.isArray(schema.resultFields)) {
var nodeList = xmldoc_in.getElementsByTagName(schema.resultListLocator),
fields = schema.resultFields,
results = [],
node, field, result, i, j;
if(nodeList.length) {
// Loop through each result node
for(i=nodeList.length-1; i>= 0; i--) {
result = {};
node = nodeList[i];
// Find each field value
for(j=fields.length-1; j>= 0; j--) {
field = fields[j];
result[field.key || field] = SchemaXML._getLocationValue(field, node);
}
results[i] = result;
}
data_out.results = results;
}
else {
data_out.error = new Error("XML schema result nodes retrieval failure");
}
}
return data_out;
}
};
Y.DataSchema.XML = Y.mix(SchemaXML, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['dataschema-base']});
YUI.add('dataschema-array', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with data stored in arrays.
*
* @module dataschema
* @submodule dataschema-array
*/
/**
* Array subclass for the DataSchema Utility.
* @class DataSchema.Array
* @extends DataSchema.Base
* @static
*/
var LANG = Y.Lang,
SchemaArray = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.Array static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Applies a given schema to given Array data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} Array data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var data_in = data,
data_out = {results:[],meta:{}};
if(LANG.isArray(data_in)) {
if(LANG.isArray(schema.resultFields)) {
// Parse results data
data_out = SchemaArray._parseResults(schema.resultFields, data_in, data_out);
}
else {
data_out.results = data_in;
}
}
else {
data_out.error = new Error("Array schema parse failure");
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param fields {Array} Schema to parse against.
* @param array_in {Array} Array to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_parseResults: function(fields, array_in, data_out) {
var results = [],
result, item, type, field, key, value, i, j;
for(i=array_in.length-1; i>-1; i--) {
result = {};
item = array_in[i];
type = (LANG.isObject(item) && !LANG.isFunction(item)) ? 2 : (LANG.isArray(item)) ? 1 : (LANG.isString(item)) ? 0 : -1;
if(type > 0) {
for(j=fields.length-1; j>-1; j--) {
field = fields[j];
key = (!LANG.isUndefined(field.key)) ? field.key : field;
value = (!LANG.isUndefined(item[key])) ? item[key] : item[j];
result[key] = Y.DataSchema.Base.parse(value, field);
}
}
else if(type === 0) {
result = item;
}
else {
//TODO: null or {}?
result = null;
}
results[i] = result;
}
data_out.results = results;
return data_out;
}
};
Y.DataSchema.Array = Y.mix(SchemaArray, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['dataschema-base']});
YUI.add('dataschema-text', function(Y) {
/**
* Provides a DataSchema implementation which can be used to work with delimited text data.
*
* @module dataschema
* @submodule dataschema-text
*/
/**
* Text subclass for the DataSchema Utility.
* @class DataSchema.Text
* @extends DataSchema.Base
* @static
*/
var LANG = Y.Lang,
SchemaText = {
/////////////////////////////////////////////////////////////////////////////
//
// DataSchema.Text static methods
//
/////////////////////////////////////////////////////////////////////////////
/**
* Applies a given schema to given delimited text data.
*
* @method apply
* @param schema {Object} Schema to apply.
* @param data {Object} Text data.
* @return {Object} Schema-parsed data.
* @static
*/
apply: function(schema, data) {
var data_in = data,
data_out = {results:[],meta:{}};
if(LANG.isString(data_in) && LANG.isString(schema.resultDelimiter)) {
// Parse results data
data_out = SchemaText._parseResults(schema, data_in, data_out);
}
else {
data_out.error = new Error("Text schema parse failure");
}
return data_out;
},
/**
* Schema-parsed list of results from full data
*
* @method _parseResults
* @param schema {Array} Schema to parse against.
* @param text_in {String} Text to parse.
* @param data_out {Object} In-progress parsed data to update.
* @return {Object} Parsed data object.
* @static
* @protected
*/
_parseResults: function(schema, text_in, data_out) {
var resultDelim = schema.resultDelimiter,
results = [],
results_in, fields_in, result, item, fields, field, key, value, i, j,
// Delete final delimiter at end of string if there
tmpLength = text_in.length-resultDelim.length;
if(text_in.substr(tmpLength) == resultDelim) {
text_in = text_in.substr(0, tmpLength);
}
// Split into results
results_in = text_in.split(schema.resultDelimiter);
for(i=results_in.length-1; i>-1; i--) {
result = {};
item = results_in[i];
if(LANG.isString(schema.fieldDelimiter)) {
fields_in = item.split(schema.fieldDelimiter);
if(LANG.isArray(schema.resultFields)) {
fields = schema.resultFields;
for(j=fields.length-1; j>-1; j--) {
field = fields[j];
key = (!LANG.isUndefined(field.key)) ? field.key : field;
value = (!LANG.isUndefined(fields_in[key])) ? fields_in[key] : fields_in[j];
result[key] = Y.DataSchema.Base.parse(value, field);
}
}
}
else {
result = item;
}
results[i] = result;
}
data_out.results = results;
return data_out;
}
};
Y.DataSchema.Text = Y.mix(SchemaText, Y.DataSchema.Base);
}, '3.0.0' ,{requires:['dataschema-base']});
YUI.add('dataschema', function(Y){}, '3.0.0' ,{use:['dataschema-base','dataschema-json','dataschema-xml','dataschema-array','dataschema-text']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-arrayschema",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NS:"schema",NAME:"dataSourceArraySchema",ATTRS:{schema:{}}});B.extend(A,B.Plugin.Base,{initializer:function(C){this.doBefore("_defDataFn",this._beforeDefDataFn);},_beforeDefDataFn:function(E){var D=(B.DataSource.IO&&(this.get("host") instanceof B.DataSource.IO)&&B.Lang.isString(E.data.responseText))?E.data.responseText:E.data,C=B.DataSchema.Array.apply(this.get("schema"),D);if(!C){C={meta:{},results:D};}this.get("host").fire("response",B.mix({response:C},E));return new B.Do.Halt("DataSourceArraySchema plugin halted _defDataFn");}});B.namespace("Plugin").DataSourceArraySchema=A;},"3.0.0",{requires:["plugin","datasource-local","dataschema-array"]});

View File

@@ -0,0 +1,113 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-arrayschema', function(Y) {
/**
* Extends DataSource with schema-parsing on array data.
*
* @module datasource
* @submodule datasource-arrayschema
*/
/**
* Adds schema-parsing to the DataSource Utility.
* @class DataSourceArraySchema
* @extends Plugin.Base
*/
var DataSourceArraySchema = function() {
DataSourceArraySchema.superclass.constructor.apply(this, arguments);
};
Y.mix(DataSourceArraySchema, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "schema"
*/
NS: "schema",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceArraySchema"
*/
NAME: "dataSourceArraySchema",
/////////////////////////////////////////////////////////////////////////////
//
// DataSourceArraySchema Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
schema: {
//value: {}
}
}
});
Y.extend(DataSourceArraySchema, Y.Plugin.Base, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this.doBefore("_defDataFn", this._beforeDefDataFn);
},
/**
* Parses raw data into a normalized response.
*
* @method _beforeDefDataFn
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @protected
*/
_beforeDefDataFn: function(e) {
var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && Y.Lang.isString(e.data.responseText)) ? e.data.responseText : e.data,
response = Y.DataSchema.Array.apply(this.get("schema"), data);
// Default
if(!response) {
response = {
meta: {},
results: data
};
}
this.get("host").fire("response", Y.mix({response:response}, e));
return new Y.Do.Halt("DataSourceArraySchema plugin halted _defDataFn");
}
});
Y.namespace('Plugin').DataSourceArraySchema = DataSourceArraySchema;
}, '3.0.0' ,{requires:['plugin', 'datasource-local', 'dataschema-array']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-cache",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NS:"cache",NAME:"dataSourceCache",ATTRS:{}});B.extend(A,B.Cache,{initializer:function(C){this.doBefore("_defRequestFn",this._beforeDefRequestFn);this.doBefore("_defResponseFn",this._beforeDefResponseFn);},_beforeDefRequestFn:function(D){var C=(this.retrieve(D.request))||null;if(C&&C.response){this.get("host").fire("response",B.mix({response:C.response},D));return new B.Do.Halt("DataSourceCache plugin halted _defRequestFn");}},_beforeDefResponseFn:function(C){if(C.response&&!C.response.cached){C.response.cached=true;this.add(C.request,C.response,(C.callback&&C.callback.argument));}}});B.namespace("Plugin").DataSourceCache=A;},"3.0.0",{requires:["datasource-local","cache"]});

View File

@@ -0,0 +1,136 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-cache', function(Y) {
/**
* Extends DataSource with caching functionality.
*
* @module datasource
* @submodule datasource-cache
*/
/**
* Adds cacheability to the DataSource Utility.
* @class DataSourceCache
* @extends Cache
*/
var DataSourceCache = function() {
DataSourceCache.superclass.constructor.apply(this, arguments);
};
Y.mix(DataSourceCache, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "cache"
*/
NS: "cache",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceCache"
*/
NAME: "dataSourceCache",
/////////////////////////////////////////////////////////////////////////////
//
// DataSourceCache Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
}
});
Y.extend(DataSourceCache, Y.Cache, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this.doBefore("_defRequestFn", this._beforeDefRequestFn);
this.doBefore("_defResponseFn", this._beforeDefResponseFn);
},
/**
* First look for cached response, then send request to live data.
*
* @method _beforeDefRequestFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object.</dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @protected
*/
_beforeDefRequestFn: function(e) {
// Is response already in the Cache?
var entry = (this.retrieve(e.request)) || null;
if(entry && entry.response) {
this.get("host").fire("response", Y.mix({response: entry.response}, e));
return new Y.Do.Halt("DataSourceCache plugin halted _defRequestFn");
}
},
/**
* Adds data to cache before returning data.
*
* @method _beforeDefResponseFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
* <dl>
* <dt>cached (Object)</dt> <dd>True when response is cached.</dd>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Object)</dt> <dd>Error object.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @protected
*/
_beforeDefResponseFn: function(e) {
// Add to Cache before returning
if(e.response && !e.response.cached) {
e.response.cached = true;
this.add(e.request, e.response, (e.callback && e.callback.argument));
}
}
});
Y.namespace('Plugin').DataSourceCache = DataSourceCache;
}, '3.0.0' ,{requires:['datasource-local', 'cache']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-function",function(B){var A=B.Lang,C=function(){C.superclass.constructor.apply(this,arguments);};B.mix(C,{NAME:"dataSourceFunction",ATTRS:{source:{validator:A.isFunction}}});B.extend(C,B.DataSource.Local,{_defRequestFn:function(G){var F=this.get("source"),D;if(F){try{D=F(G.request,this,G);this.fire("data",B.mix({data:D},G));}catch(E){G.error=E;this.fire("error",G);}}else{G.error=new Error("Function data failure");this.fire("error",G);}return G.tId;}});B.DataSource.Function=C;},"3.0.0",{requires:["datasource-local"]});

View File

@@ -0,0 +1,115 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-function', function(Y) {
/**
* Provides a DataSource implementation which can be used to retrieve data from a custom function.
*
* @module datasource
* @submodule datasource-function
*/
/**
* Function subclass for the DataSource Utility.
* @class DataSource.Function
* @extends DataSource.Local
* @constructor
*/
var LANG = Y.Lang,
DSFn = function() {
DSFn.superclass.constructor.apply(this, arguments);
};
/////////////////////////////////////////////////////////////////////////////
//
// DataSource.Function static properties
//
/////////////////////////////////////////////////////////////////////////////
Y.mix(DSFn, {
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceFunction"
*/
NAME: "dataSourceFunction",
/////////////////////////////////////////////////////////////////////////////
//
// DataSource.Function Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
/**
* @attribute source
* @description Pointer to live data.
* @type MIXED
* @default null
*/
source: {
validator: LANG.isFunction
}
}
});
Y.extend(DSFn, Y.DataSource.Local, {
/**
* Passes query string to IO. Fires <code>response</code> event when
* response is received asynchronously.
*
* @method _defRequestFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @protected
*/
_defRequestFn: function(e) {
var fn = this.get("source"),
response;
if(fn) {
try {
response = fn(e.request, this, e);
this.fire("data", Y.mix({data:response}, e));
}
catch(error) {
e.error = error;
this.fire("error", e);
}
}
else {
e.error = new Error("Function data failure");
this.fire("error", e);
}
return e.tId;
}
});
Y.DataSource.Function = DSFn;
}, '3.0.0' ,{requires:['datasource-local']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-get",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NAME:"dataSourceGet",ATTRS:{get:{value:B.Get,cloneDefaultValue:false},asyncMode:{value:"allowAll"},scriptCallbackParam:{value:"callback"},generateRequestCallback:{value:function(C,D){return"&"+C.get("scriptCallbackParam")+"=YUI.Env.DataSource.callbacks["+D+"]";}}},callbacks:[],_tId:0});B.extend(A,B.DataSource.Local,{_defRequestFn:function(F){var E=this.get("source"),D=this.get("get"),G=A._tId++,C=this;YUI.Env.DataSource.callbacks[G]=B.rbind(function(H){if((C.get("asyncMode")!=="ignoreStaleResponses")||(G===A.callbacks.length-1)){C.fire("data",B.mix({data:H},F));}else{}delete A.callbacks[G];},this,G);E+=F.request+this.get("generateRequestCallback")(this,G);D.script(E,{autopurge:true,onFailure:B.bind(function(H){H.error=new Error("Script node data failure");this.fire("error",H);},this,F)});return F.tId;}});B.DataSource.Get=A;YUI.namespace("Env.DataSource.callbacks");},"3.0.0",{requires:["datasource-local","get"]});

View File

@@ -0,0 +1,226 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-get', function(Y) {
/**
* Provides a DataSource implementation which can be used to retrieve data via the Get Utility.
*
* @module datasource
* @submodule datasource-get
*/
/**
* Get Utility subclass for the DataSource Utility.
* @class DataSource.Get
* @extends DataSource.Local
* @constructor
*/
var DSGet = function() {
DSGet.superclass.constructor.apply(this, arguments);
};
/////////////////////////////////////////////////////////////////////////////
//
// DataSource.Get static properties
//
/////////////////////////////////////////////////////////////////////////////
Y.mix(DSGet, {
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceGet"
*/
NAME: "dataSourceGet",
/////////////////////////////////////////////////////////////////////////////
//
// DataSource.Get Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
/**
* Pointer to Get Utility.
*
* @attribute get
* @type Y.Get
* @default Y.Get
*/
get: {
value: Y.Get,
cloneDefaultValue: false
},
/**
* Defines request/response management in the following manner:
* <dl>
* <!--<dt>queueRequests</dt>
* <dd>If a request is already in progress, wait until response is returned before sending the next request.</dd>
* <dt>cancelStaleRequests</dt>
* <dd>If a request is already in progress, cancel it before sending the next request.</dd>-->
* <dt>ignoreStaleResponses</dt>
* <dd>Send all requests, but handle only the response for the most recently sent request.</dd>
* <dt>allowAll</dt>
* <dd>Send all requests and handle all responses.</dd>
* </dl>
*
* @attribute asyncMode
* @type String
* @default "allowAll"
*/
asyncMode: {
value: "allowAll"
},
/**
* Callback string parameter name sent to the remote script. By default,
* requests are sent to
* &#60;URI&#62;?&#60;scriptCallbackParam&#62;=callbackFunction
*
* @attribute scriptCallbackParam
* @type String
* @default "callback"
*/
scriptCallbackParam : {
value: "callback"
},
/**
* Accepts the DataSource instance and a callback ID, and returns a callback
* param/value string that gets appended to the script URI. Implementers
* can customize this string to match their server's query syntax.
*
* @attribute generateRequestCallback
* @type Function
*/
generateRequestCallback : {
value: function(self, id) {
return "&" + self.get("scriptCallbackParam") + "=YUI.Env.DataSource.callbacks["+id+"]" ;
}
}
},
/**
* Global array of callback functions, one for each request sent.
*
* @property callbacks
* @type Function[]
* @static
*/
callbacks : [],
/**
* Unique ID to track requests.
*
* @property _tId
* @type Number
* @private
* @static
*/
_tId : 0
});
Y.extend(DSGet, Y.DataSource.Local, {
/**
* Passes query string to Get Utility. Fires <code>response</code> event when
* response is received asynchronously.
*
* @method _defRequestFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @protected
*/
_defRequestFn: function(e) {
var uri = this.get("source"),
get = this.get("get"),
id = DSGet._tId++,
self = this;
// Dynamically add handler function with a closure to the callback stack
YUI.Env.DataSource.callbacks[id] = Y.rbind(function(response) {
if((self.get("asyncMode") !== "ignoreStaleResponses")||
(id === DSGet.callbacks.length-1)) { // Must ignore stale responses
self.fire("data", Y.mix({data:response}, e));
}
else {
}
delete DSGet.callbacks[id];
}, this, id);
// We are now creating a request
uri += e.request + this.get("generateRequestCallback")(this, id);
//uri = this.doBefore(sUri);
get.script(uri, {
autopurge: true,
// Works in Firefox only....
onFailure: Y.bind(function(e) {
e.error = new Error("Script node data failure");
this.fire("error", e);
}, this, e)
});
return e.tId;
}
});
Y.DataSource.Get = DSGet;
YUI.namespace("Env.DataSource.callbacks");
}, '3.0.0' ,{requires:['datasource-local', 'get']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-io",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NAME:"dataSourceIO",ATTRS:{io:{value:B.io,cloneDefaultValue:false}}});B.extend(A,B.DataSource.Local,{initializer:function(C){this._queue={interval:null,conn:null,requests:[]};},_queue:null,_defRequestFn:function(F){var E=this.get("source"),G=this.get("io"),D=F.request,C=B.mix(F.cfg,{on:{success:function(J,H,I){this.fire("data",B.mix({data:H},I));},failure:function(J,H,I){I.error=new Error("IO data failure");this.fire("error",B.mix({data:H},I));this.fire("data",B.mix({data:H},I));}},context:this,arguments:F});if(B.Lang.isString(D)){if(C.method&&(C.method.toUpperCase()==="POST")){C.data=C.data?C.data+D:D;}else{E+=D;}}G(E,C);return F.tId;}});B.DataSource.IO=A;},"3.0.0",{requires:["datasource-local","io"]});

View File

@@ -0,0 +1,154 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-io', function(Y) {
/**
* Provides a DataSource implementation which can be used to retrieve data via the IO Utility.
*
* @module datasource
* @submodule datasource-io
*/
/**
* IO subclass for the DataSource Utility.
* @class DataSource.IO
* @extends DataSource.Local
* @constructor
*/
var DSIO = function() {
DSIO.superclass.constructor.apply(this, arguments);
};
/////////////////////////////////////////////////////////////////////////////
//
// DataSource.IO static properties
//
/////////////////////////////////////////////////////////////////////////////
Y.mix(DSIO, {
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceIO"
*/
NAME: "dataSourceIO",
/////////////////////////////////////////////////////////////////////////////
//
// DataSource.IO Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
/**
* Pointer to IO Utility.
*
* @attribute io
* @type Y.io
* @default Y.io
*/
io: {
value: Y.io,
cloneDefaultValue: false
}
}
});
Y.extend(DSIO, Y.DataSource.Local, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this._queue = {interval:null, conn:null, requests:[]};
},
/**
* @property _queue
* @description Object literal to manage asynchronous request/response
* cycles enabled if queue needs to be managed (asyncMode/ioConnMode):
* <dl>
* <dt>interval {Number}</dt>
* <dd>Interval ID of in-progress queue.</dd>
* <dt>conn</dt>
* <dd>In-progress connection identifier (if applicable).</dd>
* <dt>requests {Object[]}</dt>
* <dd>Array of queued request objects: {request:request, callback:callback}.</dd>
* </dl>
* @type Object
* @default {interval:null, conn:null, requests:[]}
* @private
*/
_queue: null,
/**
* Passes query string to IO. Fires <code>response</code> event when
* response is received asynchronously.
*
* @method _defRequestFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @protected
*/
_defRequestFn: function(e) {
var uri = this.get("source"),
io = this.get("io"),
request = e.request,
cfg = Y.mix(e.cfg, {
on: {
success: function (id, response, e) {
this.fire("data", Y.mix({data:response}, e));
},
failure: function (id, response, e) {
e.error = new Error("IO data failure");
this.fire("error", Y.mix({data:response}, e));
this.fire("data", Y.mix({data:response}, e));
}
},
context: this,
arguments: e
});
// Support for POST transactions
if(Y.Lang.isString(request)) {
if(cfg.method && (cfg.method.toUpperCase() === "POST")) {
cfg.data = cfg.data ? cfg.data+request : request;
}
else {
uri += request;
}
}
io(uri, cfg);
return e.tId;
}
});
Y.DataSource.IO = DSIO;
}, '3.0.0' ,{requires:['datasource-local', 'io']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-jsonschema",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NS:"schema",NAME:"dataSourceJSONSchema",ATTRS:{schema:{}}});B.extend(A,B.Plugin.Base,{initializer:function(C){this.doBefore("_defDataFn",this._beforeDefDataFn);},_beforeDefDataFn:function(E){var D=(B.DataSource.IO&&(this.get("host") instanceof B.DataSource.IO)&&B.Lang.isString(E.data.responseText))?E.data.responseText:E.data,C=B.DataSchema.JSON.apply(this.get("schema"),D);if(!C){C={meta:{},results:D};}this.get("host").fire("response",B.mix({response:C},E));return new B.Do.Halt("DataSourceJSONSchema plugin halted _defDataFn");}});B.namespace("Plugin").DataSourceJSONSchema=A;},"3.0.0",{requires:["plugin","datasource-local","dataschema-json"]});

View File

@@ -0,0 +1,113 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-jsonschema', function(Y) {
/**
* Extends DataSource with schema-parsing on JSON data.
*
* @module datasource
* @submodule datasource-jsonschema
*/
/**
* Adds schema-parsing to the DataSource Utility.
* @class DataSourceJSONSchema
* @extends Plugin.Base
*/
var DataSourceJSONSchema = function() {
DataSourceJSONSchema.superclass.constructor.apply(this, arguments);
};
Y.mix(DataSourceJSONSchema, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "schema"
*/
NS: "schema",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceJSONSchema"
*/
NAME: "dataSourceJSONSchema",
/////////////////////////////////////////////////////////////////////////////
//
// DataSourceJSONSchema Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
schema: {
//value: {}
}
}
});
Y.extend(DataSourceJSONSchema, Y.Plugin.Base, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this.doBefore("_defDataFn", this._beforeDefDataFn);
},
/**
* Parses raw data into a normalized response.
*
* @method _beforeDefDataFn
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @protected
*/
_beforeDefDataFn: function(e) {
var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && Y.Lang.isString(e.data.responseText)) ? e.data.responseText : e.data,
response = Y.DataSchema.JSON.apply(this.get("schema"), data);
// Default
if(!response) {
response = {
meta: {},
results: data
};
}
this.get("host").fire("response", Y.mix({response:response}, e));
return new Y.Do.Halt("DataSourceJSONSchema plugin halted _defDataFn");
}
});
Y.namespace('Plugin').DataSourceJSONSchema = DataSourceJSONSchema;
}, '3.0.0' ,{requires:['plugin', 'datasource-local', 'dataschema-json']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-local",function(C){var B=C.Lang,A=function(){A.superclass.constructor.apply(this,arguments);};C.mix(A,{NAME:"dataSourceLocal",ATTRS:{source:{value:null}},_tId:0,issueCallback:function(E){if(E.callback){var D=(E.error&&E.callback.failure)||E.callback.success;if(D){D(E);}}}});C.extend(A,C.Base,{initializer:function(D){this._initEvents();},_initEvents:function(){this.publish("request",{defaultFn:C.bind("_defRequestFn",this),queuable:true});this.publish("data",{defaultFn:C.bind("_defDataFn",this),queuable:true});this.publish("response",{defaultFn:C.bind("_defResponseFn",this),queuable:true});},_defRequestFn:function(E){var D=this.get("source");if(B.isUndefined(D)){E.error=new Error("Local source undefined");}if(E.error){this.fire("error",E);}this.fire("data",C.mix({data:D},E));},_defDataFn:function(G){var E=G.data,F=G.meta,D={results:(B.isArray(E))?E:[E],meta:(F)?F:{}};this.fire("response",C.mix({response:D},G));},_defResponseFn:function(D){A.issueCallback(D);},sendRequest:function(E,G,D){var F=A._tId++;this.fire("request",{tId:F,request:E,callback:G,cfg:D||{}});return F;}});C.namespace("DataSource").Local=A;},"3.0.0",{requires:["base"]});

View File

@@ -0,0 +1,336 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-local', function(Y) {
/**
* The DataSource utility provides a common configurable interface for widgets to
* access a variety of data, from JavaScript arrays to online database servers.
*
* @module datasource
*/
/**
* Provides the base DataSource implementation, which can be extended to
* create DataSources for specific data protocols, such as the IO Utility, the
* Get Utility, or custom functions.
*
* @module datasource
* @submodule datasource-local
*/
/**
* Base class for the DataSource Utility.
* @class DataSource.Local
* @extends Base
* @constructor
*/
var LANG = Y.Lang,
DSLocal = function() {
DSLocal.superclass.constructor.apply(this, arguments);
};
/////////////////////////////////////////////////////////////////////////////
//
// DataSource static properties
//
/////////////////////////////////////////////////////////////////////////////
Y.mix(DSLocal, {
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceLocal"
*/
NAME: "dataSourceLocal",
/////////////////////////////////////////////////////////////////////////////
//
// DataSource Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
/**
* @attribute source
* @description Pointer to live data.
* @type MIXED
* @default null
*/
source: {
value: null
}
},
/**
* Global transaction counter.
*
* @property DataSource._tId
* @type Number
* @static
* @private
* @default 0
*/
_tId: 0,
/**
* Executes a given callback. The third param determines whether to execute
*
* @method DataSource.issueCallback
* @param callback {Object} The callback object.
* @param params {Array} params to be passed to the callback method
* @param error {Boolean} whether an error occurred
* @static
*/
issueCallback: function (e) {
if(e.callback) {
var callbackFunc = (e.error && e.callback.failure) || e.callback.success;
if (callbackFunc) {
callbackFunc(e);
}
}
}
});
Y.extend(DSLocal, Y.Base, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this._initEvents();
},
/**
* This method creates all the events for this module.
* @method _initEvents
* @private
*/
_initEvents: function() {
/**
* Fired when a data request is received.
*
* @event request
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object.</dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @preventable _defRequestFn
*/
this.publish("request", {defaultFn: Y.bind("_defRequestFn", this), queuable:true});
/**
* Fired when raw data is received.
*
* @event data
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @preventable _defDataFn
*/
this.publish("data", {defaultFn: Y.bind("_defDataFn", this), queuable:true});
/**
* Fired when response is returned.
*
* @event response
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
* <dl>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Boolean)</dt> <dd>Error flag.</dd>
* </dl>
* </dd>
* </dl>
* @preventable _defResponseFn
*/
this.publish("response", {defaultFn: Y.bind("_defResponseFn", this), queuable:true});
/**
* Fired when an error is encountered.
*
* @event error
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
* <dl>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Object)</dt> <dd>Error object.</dd>
* </dl>
* </dd>
* </dl>
*/
},
/**
* Manages request/response transaction. Must fire <code>response</code>
* event when response is received. This method should be implemented by
* subclasses to achieve more complex behavior such as accessing remote data.
*
* @method _defRequestFn
* @param e {Event.Facade} Event Facadewith the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* </dl>
* @protected
*/
_defRequestFn: function(e) {
var data = this.get("source");
// Problematic data
if(LANG.isUndefined(data)) {
e.error = new Error("Local source undefined");
}
if(e.error) {
this.fire("error", e);
}
this.fire("data", Y.mix({data:data}, e));
},
/**
* Normalizes raw data into a response that includes results and meta properties.
*
* @method _defDataFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @protected
*/
_defDataFn: function(e) {
var data = e.data,
meta = e.meta,
response = {
results: (LANG.isArray(data)) ? data : [data],
meta: (meta) ? meta : {}
};
this.fire("response", Y.mix({response: response}, e));
},
/**
* Sends data as a normalized response to callback.
*
* @method _defResponseFn
* @param e {Event.Facade} Event Facade with the following properties:
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>cfg (Object)</dt> <dd>Configuration object.</dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* <dt>response (Object)</dt> <dd>Normalized response object with the following properties:
* <dl>
* <dt>results (Object)</dt> <dd>Parsed results.</dd>
* <dt>meta (Object)</dt> <dd>Parsed meta data.</dd>
* <dt>error (Boolean)</dt> <dd>Error flag.</dd>
* </dl>
* </dd>
* </dl>
* @protected
*/
_defResponseFn: function(e) {
// Send the response back to the callback
DSLocal.issueCallback(e);
},
/**
* Generates a unique transaction ID and fires <code>request</code> event.
*
* @method sendRequest
* @param request {Object} Request.
* @param callback {Object} An object literal with the following properties:
* <dl>
* <dt><code>success</code></dt>
* <dd>The function to call when the data is ready.</dd>
* <dt><code>failure</code></dt>
* <dd>The function to call upon a response failure condition.</dd>
* <dt><code>argument</code></dt>
* <dd>Arbitrary data payload that will be passed back to the success and failure handlers.</dd>
* </dl>
* @param cfg {Object} Configuration object
* @return {Number} Transaction ID.
*/
sendRequest: function(request, callback, cfg) {
var tId = DSLocal._tId++;
this.fire("request", {tId:tId, request:request, callback:callback, cfg:cfg || {}});
return tId;
}
});
Y.namespace("DataSource").Local = DSLocal;
}, '3.0.0' ,{requires:['base']});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-polling",function(C){var A=C.Lang,B=function(){this._intervals={};};B.prototype={_intervals:null,setInterval:function(F,E,G){var D=C.later(F,this,this.sendRequest,[E,G],true);this._intervals[D.id]=D;return D.id;},clearInterval:function(E,D){E=D||E;if(this._intervals[E]){this._intervals[E].cancel();delete this._intervals[E];}},clearAllIntervals:function(){C.each(this._intervals,this.clearInterval,this);}};C.augment(C.DataSource.Local,B);},"3.0.0",{requires:["datasource-local"]});

View File

@@ -0,0 +1,93 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-polling', function(Y) {
/**
* Extends DataSource with polling functionality.
*
* @module datasource
* @submodule datasource-polling
*/
/**
* Adds polling to the DataSource Utility.
* @class Pollable
* @extends DataSource.Local
*/
var LANG = Y.Lang,
Pollable = function() {
this._intervals = {};
};
Pollable.prototype = {
/**
* @property _intervals
* @description Hash of polling interval IDs that have been enabled,
* stored here to be able to clear all intervals.
* @private
*/
_intervals: null,
/**
* Sets up a polling mechanism to send requests at set intervals and forward
* responses to given callback.
*
* @method setInterval
* @param msec {Number} Length of interval in milliseconds.
* @param request {Object} Request object.
* @param callback {Object} An object literal with the following properties:
* <dl>
* <dt><code>success</code></dt>
* <dd>The function to call when the data is ready.</dd>
* <dt><code>failure</code></dt>
* <dd>The function to call upon a response failure condition.</dd>
* <dt><code>argument</code></dt>
* <dd>Arbitrary data that will be passed back to the success and failure handlers.</dd>
* </dl>
* @return {Number} Interval ID.
*/
setInterval: function(msec, request, callback) {
var x = Y.later(msec, this, this.sendRequest, [request, callback], true);
this._intervals[x.id] = x;
return x.id;
},
/**
* Disables polling mechanism associated with the given interval ID.
*
* @method clearInterval
* @param id {Number} Interval ID.
*/
clearInterval: function(id, key) {
// In case of being called by clearAllIntervals()
id = key || id;
if(this._intervals[id]) {
// Clear the interval
this._intervals[id].cancel();
// Clear from tracker
delete this._intervals[id];
}
},
/**
* Clears all intervals.
*
* @method clearAllIntervals
*/
clearAllIntervals: function() {
Y.each(this._intervals, this.clearInterval, this);
}
};
Y.augment(Y.DataSource.Local, Pollable);
}, '3.0.0' ,{requires:['datasource-local']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-textschema",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NS:"schema",NAME:"dataSourceTextSchema",ATTRS:{schema:{}}});B.extend(A,B.Plugin.Base,{initializer:function(C){this.doBefore("_defDataFn",this._beforeDefDataFn);},_beforeDefDataFn:function(E){var D=(B.DataSource.IO&&(this.get("host") instanceof B.DataSource.IO)&&B.Lang.isString(E.data.responseText))?E.data.responseText:E.data,C=B.DataSchema.Text.apply(this.get("schema"),D);if(!C){C={meta:{},results:D};}this.get("host").fire("response",B.mix({response:C},E));return new B.Do.Halt("DataSourceTextSchema plugin halted _defDataFn");}});B.namespace("Plugin").DataSourceTextSchema=A;},"3.0.0",{requires:["plugin","datasource-local","dataschema-text"]});

View File

@@ -0,0 +1,113 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-textschema', function(Y) {
/**
* Extends DataSource with schema-parsing on text data.
*
* @module datasource
* @submodule datasource-textschema
*/
/**
* Adds schema-parsing to the DataSource Utility.
* @class DataSourceTextSchema
* @extends Plugin.Base
*/
var DataSourceTextSchema = function() {
DataSourceTextSchema.superclass.constructor.apply(this, arguments);
};
Y.mix(DataSourceTextSchema, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "schema"
*/
NS: "schema",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceTextSchema"
*/
NAME: "dataSourceTextSchema",
/////////////////////////////////////////////////////////////////////////////
//
// DataSourceTextSchema Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
schema: {
//value: {}
}
}
});
Y.extend(DataSourceTextSchema, Y.Plugin.Base, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this.doBefore("_defDataFn", this._beforeDefDataFn);
},
/**
* Parses raw data into a normalized response.
*
* @method _beforeDefDataFn
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @protected
*/
_beforeDefDataFn: function(e) {
var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && Y.Lang.isString(e.data.responseText)) ? e.data.responseText : e.data,
response = Y.DataSchema.Text.apply(this.get("schema"), data);
// Default
if(!response) {
response = {
meta: {},
results: data
};
}
this.get("host").fire("response", Y.mix({response:response}, e));
return new Y.Do.Halt("DataSourceTextSchema plugin halted _defDataFn");
}
});
Y.namespace('Plugin').DataSourceTextSchema = DataSourceTextSchema;
}, '3.0.0' ,{requires:['plugin', 'datasource-local', 'dataschema-text']});

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datasource-xmlschema",function(B){var A=function(){A.superclass.constructor.apply(this,arguments);};B.mix(A,{NS:"schema",NAME:"dataSourceXMLSchema",ATTRS:{schema:{}}});B.extend(A,B.Plugin.Base,{initializer:function(C){this.doBefore("_defDataFn",this._beforeDefDataFn);},_beforeDefDataFn:function(E){var D=(B.DataSource.IO&&(this.get("host") instanceof B.DataSource.IO)&&E.data.responseXML&&(E.data.responseXML.nodeType===9))?E.data.responseXML:E.data,C=B.DataSchema.XML.apply(this.get("schema"),D);if(!C){C={meta:{},results:D};}this.get("host").fire("response",B.mix({response:C},E));return new B.Do.Halt("DataSourceXMLSchema plugin halted _defDataFn");}});B.namespace("Plugin").DataSourceXMLSchema=A;},"3.0.0",{requires:["plugin","datasource-local","dataschema-xml"]});

View File

@@ -0,0 +1,113 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datasource-xmlschema', function(Y) {
/**
* Extends DataSource with schema-parsing on XML data.
*
* @module datasource
* @submodule datasource-xmlschema
*/
/**
* Adds schema-parsing to the DataSource Utility.
* @class DataSourceXMLSchema
* @extends Plugin.Base
*/
var DataSourceXMLSchema = function() {
DataSourceXMLSchema.superclass.constructor.apply(this, arguments);
};
Y.mix(DataSourceXMLSchema, {
/**
* The namespace for the plugin. This will be the property on the host which
* references the plugin instance.
*
* @property NS
* @type String
* @static
* @final
* @value "schema"
*/
NS: "schema",
/**
* Class name.
*
* @property NAME
* @type String
* @static
* @final
* @value "dataSourceXMLSchema"
*/
NAME: "dataSourceXMLSchema",
/////////////////////////////////////////////////////////////////////////////
//
// DataSourceXMLSchema Attributes
//
/////////////////////////////////////////////////////////////////////////////
ATTRS: {
schema: {
//value: {}
}
}
});
Y.extend(DataSourceXMLSchema, Y.Plugin.Base, {
/**
* Internal init() handler.
*
* @method initializer
* @param config {Object} Config object.
* @private
*/
initializer: function(config) {
this.doBefore("_defDataFn", this._beforeDefDataFn);
},
/**
* Parses raw data into a normalized response.
*
* @method _beforeDefDataFn
* <dl>
* <dt>tId (Number)</dt> <dd>Unique transaction ID.</dd>
* <dt>request (Object)</dt> <dd>The request.</dd>
* <dt>callback (Object)</dt> <dd>The callback object with the following properties:
* <dl>
* <dt>success (Function)</dt> <dd>Success handler.</dd>
* <dt>failure (Function)</dt> <dd>Failure handler.</dd>
* </dl>
* </dd>
* <dt>data (Object)</dt> <dd>Raw data.</dd>
* </dl>
* @protected
*/
_beforeDefDataFn: function(e) {
var data = (Y.DataSource.IO && (this.get("host") instanceof Y.DataSource.IO) && e.data.responseXML && (e.data.responseXML.nodeType === 9)) ? e.data.responseXML : e.data,
response = Y.DataSchema.XML.apply(this.get("schema"), data);
// Default
if(!response) {
response = {
meta: {},
results: data
};
}
this.get("host").fire("response", Y.mix({response:response}, e));
return new Y.Do.Halt("DataSourceXMLSchema plugin halted _defDataFn");
}
});
Y.namespace('Plugin').DataSourceXMLSchema = DataSourceXMLSchema;
}, '3.0.0' ,{requires:['plugin', 'datasource-local', 'dataschema-xml']});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add("datatype-date-format",function(D){var A=function(E,G,F){if(typeof F==="undefined"){F=10;}G=G.toString();for(;parseInt(E,10)<F&&F>1;F/=10){E=G+E;}return E.toString();};D.config.dateFormat=D.config.dateFormat||"%Y-%m-%d";D.config.locale=D.config.locale||"en";var C={formats:{a:function(F,E){return E.a[F.getDay()];},A:function(F,E){return E.A[F.getDay()];},b:function(F,E){return E.b[F.getMonth()];},B:function(F,E){return E.B[F.getMonth()];},C:function(E){return A(parseInt(E.getFullYear()/100,10),0);},d:["getDate","0"],e:["getDate"," "],g:function(E){return A(parseInt(C.formats.G(E)%100,10),0);},G:function(G){var H=G.getFullYear();var F=parseInt(C.formats.V(G),10);var E=parseInt(C.formats.W(G),10);if(E>F){H++;}else{if(E===0&&F>=52){H--;}}return H;},H:["getHours","0"],I:function(F){var E=F.getHours()%12;return A(E===0?12:E,0);},j:function(I){var H=new Date(""+I.getFullYear()+"/1/1 GMT");var F=new Date(""+I.getFullYear()+"/"+(I.getMonth()+1)+"/"+I.getDate()+" GMT");var E=F-H;var G=parseInt(E/60000/60/24,10)+1;return A(G,0,100);},k:["getHours"," "],l:function(F){var E=F.getHours()%12;return A(E===0?12:E," ");},m:function(E){return A(E.getMonth()+1,0);},M:["getMinutes","0"],p:function(F,E){return E.p[F.getHours()>=12?1:0];},P:function(F,E){return E.P[F.getHours()>=12?1:0];},s:function(F,E){return parseInt(F.getTime()/1000,10);},S:["getSeconds","0"],u:function(E){var F=E.getDay();return F===0?7:F;},U:function(H){var E=parseInt(C.formats.j(H),10);var G=6-H.getDay();var F=parseInt((E+G)/7,10);return A(F,0);},V:function(H){var G=parseInt(C.formats.W(H),10);var E=(new Date(""+H.getFullYear()+"/1/1")).getDay();var F=G+(E>4||E<=1?0:1);if(F===53&&(new Date(""+H.getFullYear()+"/12/31")).getDay()<4){F=1;}else{if(F===0){F=C.formats.V(new Date(""+(H.getFullYear()-1)+"/12/31"));}}return A(F,0);},w:"getDay",W:function(H){var E=parseInt(C.formats.j(H),10);var G=7-C.formats.u(H);var F=parseInt((E+G)/7,10);return A(F,0,10);},y:function(E){return A(E.getFullYear()%100,0);},Y:"getFullYear",z:function(G){var F=G.getTimezoneOffset();var E=A(parseInt(Math.abs(F/60),10),0);var I=A(Math.abs(F%60),0);return(F>0?"-":"+")+E+I;},Z:function(E){var F=E.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/,"$2").replace(/[a-z ]/g,"");if(F.length>4){F=C.formats.z(E);}return F;},"%":function(E){return"%";}},aggregates:{c:"locale",D:"%m/%d/%y",F:"%Y-%m-%d",h:"%b",n:"\n",r:"locale",R:"%H:%M",t:"\t",T:"%H:%M:%S",x:"locale",X:"locale"},format:function(N,H){H=H||{};if(!D.Lang.isDate(N)){return D.Lang.isValue(N)?N:"";}var M=H.format||D.config.dateFormat,F=H.locale||D.config.locale,L=D.DataType.Date.Locale;F=F.replace(/_/g,"-");if(!L[F]){var G=F.replace(/-[a-zA-Z]+$/,"");if(G in L){F=G;}else{if(D.config.locale in L){F=D.config.locale;}else{F="en";}}}var J=L[F];var I=function(P,O){var Q=C.aggregates[O];return(Q==="locale"?J[O]:Q);};var E=function(P,O){var Q=C.formats[O];switch(D.Lang.type(Q)){case"string":return N[Q]();case"function":return Q.call(N,N,J);case"array":if(D.Lang.type(Q[0])==="string"){return A(N[Q[0]](),Q[1]);}default:return O;}};while(M.match(/%[cDFhnrRtTxX]/)){M=M.replace(/%([cDFhnrRtTxX])/g,I);}var K=M.replace(/%([aAbBCdegGHIjklmMpPsSuUVwWyYzZ%])/g,E);I=E=undefined;return K;}};D.mix(D.namespace("DataType.Date"),C);var B={a:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],A:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],b:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],B:["January","February","March","April","May","June","July","August","September","October","November","December"],c:"%a %d %b %Y %T %Z",p:["AM","PM"],P:["am","pm"],r:"%I:%M:%S %p",x:"%d/%m/%y",X:"%T"};D.namespace("DataType.Date.Locale");D.DataType.Date.Locale["en"]=B;D.DataType.Date.Locale["en-US"]=D.merge(B,{c:"%a %d %b %Y %I:%M:%S %p %Z",x:"%m/%d/%Y",X:"%I:%M:%S %p"});D.DataType.Date.Locale["en-GB"]=D.merge(B,{r:"%l:%M:%S %P %Z"});D.DataType.Date.Locale["en-AU"]=D.merge(B);},"3.0.0");

View File

@@ -0,0 +1,443 @@
/*
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 3.0.0
build: 1549
*/
YUI.add('datatype-date-format', function(Y) {
/**
* The DataType Utility provides type-conversion and string-formatting
* convenience methods for various JavaScript object types.
*
* @module datatype
*/
/**
* Date submodule.
*
* @module datatype
* @submodule datatype-date
*/
/**
* Format date submodule implements strftime formatters for javascript based on the
* Open Group specification defined at
* http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
* This implementation does not include modified conversion specifiers (i.e., Ex and Ox)
*
* @module datatype
* @submodule datatype-date-format
*/
/**
* DataType.Date provides a set of utility functions to operate against Date objects.
*
* @class DataType.Date
* @static
*/
/**
* Pad a number with leading spaces, zeroes or something else
* @method xPad
* @param x {Number} The number to be padded
* @param pad {String} The character to pad the number with
* @param r {Number} (optional) The base of the pad, eg, 10 implies to two digits, 100 implies to 3 digits.
* @private
*/
var xPad=function (x, pad, r)
{
if(typeof r === "undefined")
{
r=10;
}
pad = pad.toString();
for( ; parseInt(x, 10)<r && r>1; r/=10) {
x = pad + x;
}
return x.toString();
};
/**
* Default date format.
*
* @for config
* @property dateFormat
* @type String
* @value "%Y-%m-%d"
*/
Y.config.dateFormat = Y.config.dateFormat || "%Y-%m-%d";
/**
* Default locale for the YUI instance.
*
* @property locale
* @type String
* @value "en"
*/
Y.config.locale = Y.config.locale || "en";
var Dt = {
formats: {
a: function (d, l) { return l.a[d.getDay()]; },
A: function (d, l) { return l.A[d.getDay()]; },
b: function (d, l) { return l.b[d.getMonth()]; },
B: function (d, l) { return l.B[d.getMonth()]; },
C: function (d) { return xPad(parseInt(d.getFullYear()/100, 10), 0); },
d: ["getDate", "0"],
e: ["getDate", " "],
g: function (d) { return xPad(parseInt(Dt.formats.G(d)%100, 10), 0); },
G: function (d) {
var y = d.getFullYear();
var V = parseInt(Dt.formats.V(d), 10);
var W = parseInt(Dt.formats.W(d), 10);
if(W > V) {
y++;
} else if(W===0 && V>=52) {
y--;
}
return y;
},
H: ["getHours", "0"],
I: function (d) { var I=d.getHours()%12; return xPad(I===0?12:I, 0); },
j: function (d) {
var gmd_1 = new Date("" + d.getFullYear() + "/1/1 GMT");
var gmdate = new Date("" + d.getFullYear() + "/" + (d.getMonth()+1) + "/" + d.getDate() + " GMT");
var ms = gmdate - gmd_1;
var doy = parseInt(ms/60000/60/24, 10)+1;
return xPad(doy, 0, 100);
},
k: ["getHours", " "],
l: function (d) { var I=d.getHours()%12; return xPad(I===0?12:I, " "); },
m: function (d) { return xPad(d.getMonth()+1, 0); },
M: ["getMinutes", "0"],
p: function (d, l) { return l.p[d.getHours() >= 12 ? 1 : 0 ]; },
P: function (d, l) { return l.P[d.getHours() >= 12 ? 1 : 0 ]; },
s: function (d, l) { return parseInt(d.getTime()/1000, 10); },
S: ["getSeconds", "0"],
u: function (d) { var dow = d.getDay(); return dow===0?7:dow; },
U: function (d) {
var doy = parseInt(Dt.formats.j(d), 10);
var rdow = 6-d.getDay();
var woy = parseInt((doy+rdow)/7, 10);
return xPad(woy, 0);
},
V: function (d) {
var woy = parseInt(Dt.formats.W(d), 10);
var dow1_1 = (new Date("" + d.getFullYear() + "/1/1")).getDay();
// First week is 01 and not 00 as in the case of %U and %W,
// so we add 1 to the final result except if day 1 of the year
// is a Monday (then %W returns 01).
// We also need to subtract 1 if the day 1 of the year is
// Friday-Sunday, so the resulting equation becomes:
var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1);
if(idow === 53 && (new Date("" + d.getFullYear() + "/12/31")).getDay() < 4)
{
idow = 1;
}
else if(idow === 0)
{
idow = Dt.formats.V(new Date("" + (d.getFullYear()-1) + "/12/31"));
}
return xPad(idow, 0);
},
w: "getDay",
W: function (d) {
var doy = parseInt(Dt.formats.j(d), 10);
var rdow = 7-Dt.formats.u(d);
var woy = parseInt((doy+rdow)/7, 10);
return xPad(woy, 0, 10);
},
y: function (d) { return xPad(d.getFullYear()%100, 0); },
Y: "getFullYear",
z: function (d) {
var o = d.getTimezoneOffset();
var H = xPad(parseInt(Math.abs(o/60), 10), 0);
var M = xPad(Math.abs(o%60), 0);
return (o>0?"-":"+") + H + M;
},
Z: function (d) {
var tz = d.toString().replace(/^.*:\d\d( GMT[+-]\d+)? \(?([A-Za-z ]+)\)?\d*$/, "$2").replace(/[a-z ]/g, "");
if(tz.length > 4) {
tz = Dt.formats.z(d);
}
return tz;
},
"%": function (d) { return "%"; }
},
aggregates: {
c: "locale",
D: "%m/%d/%y",
F: "%Y-%m-%d",
h: "%b",
n: "\n",
r: "locale",
R: "%H:%M",
t: "\t",
T: "%H:%M:%S",
x: "locale",
X: "locale"
//"+": "%a %b %e %T %Z %Y"
},
/**
* Takes a native JavaScript Date and formats it as a string for display to user.
*
* @for DataType.Date
* @method format
* @param oDate {Date} Date.
* @param oConfig {Object} (Optional) Object literal of configuration values:
* <dl>
* <dt>format {String} (Optional)</dt>
* <dd>
* <p>
* Any strftime string is supported, such as "%I:%M:%S %p". strftime has several format specifiers defined by the Open group at
* <a href="http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html">http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html</a>
* PHP added a few of its own, defined at <a href="http://www.php.net/strftime">http://www.php.net/strftime</a>
* </p>
* <p>
* This javascript implementation supports all the PHP specifiers and a few more. The full list is below.
* </p>
* <p>
* If not specified, it defaults to the ISO8601 standard date format: %Y-%m-%d. This may be overridden by changing Y.config.dateFormat
* </p>
* <dl>
* <dt>%a</dt> <dd>abbreviated weekday name according to the current locale</dd>
* <dt>%A</dt> <dd>full weekday name according to the current locale</dd>
* <dt>%b</dt> <dd>abbreviated month name according to the current locale</dd>
* <dt>%B</dt> <dd>full month name according to the current locale</dd>
* <dt>%c</dt> <dd>preferred date and time representation for the current locale</dd>
* <dt>%C</dt> <dd>century number (the year divided by 100 and truncated to an integer, range 00 to 99)</dd>
* <dt>%d</dt> <dd>day of the month as a decimal number (range 01 to 31)</dd>
* <dt>%D</dt> <dd>same as %m/%d/%y</dd>
* <dt>%e</dt> <dd>day of the month as a decimal number, a single digit is preceded by a space (range " 1" to "31")</dd>
* <dt>%F</dt> <dd>same as %Y-%m-%d (ISO 8601 date format)</dd>
* <dt>%g</dt> <dd>like %G, but without the century</dd>
* <dt>%G</dt> <dd>The 4-digit year corresponding to the ISO week number</dd>
* <dt>%h</dt> <dd>same as %b</dd>
* <dt>%H</dt> <dd>hour as a decimal number using a 24-hour clock (range 00 to 23)</dd>
* <dt>%I</dt> <dd>hour as a decimal number using a 12-hour clock (range 01 to 12)</dd>
* <dt>%j</dt> <dd>day of the year as a decimal number (range 001 to 366)</dd>
* <dt>%k</dt> <dd>hour as a decimal number using a 24-hour clock (range 0 to 23); single digits are preceded by a blank. (See also %H.)</dd>
* <dt>%l</dt> <dd>hour as a decimal number using a 12-hour clock (range 1 to 12); single digits are preceded by a blank. (See also %I.) </dd>
* <dt>%m</dt> <dd>month as a decimal number (range 01 to 12)</dd>
* <dt>%M</dt> <dd>minute as a decimal number</dd>
* <dt>%n</dt> <dd>newline character</dd>
* <dt>%p</dt> <dd>either "AM" or "PM" according to the given time value, or the corresponding strings for the current locale</dd>
* <dt>%P</dt> <dd>like %p, but lower case</dd>
* <dt>%r</dt> <dd>time in a.m. and p.m. notation equal to %I:%M:%S %p</dd>
* <dt>%R</dt> <dd>time in 24 hour notation equal to %H:%M</dd>
* <dt>%s</dt> <dd>number of seconds since the Epoch, ie, since 1970-01-01 00:00:00 UTC</dd>
* <dt>%S</dt> <dd>second as a decimal number</dd>
* <dt>%t</dt> <dd>tab character</dd>
* <dt>%T</dt> <dd>current time, equal to %H:%M:%S</dd>
* <dt>%u</dt> <dd>weekday as a decimal number [1,7], with 1 representing Monday</dd>
* <dt>%U</dt> <dd>week number of the current year as a decimal number, starting with the
* first Sunday as the first day of the first week</dd>
* <dt>%V</dt> <dd>The ISO 8601:1988 week number of the current year as a decimal number,
* range 01 to 53, where week 1 is the first week that has at least 4 days
* in the current year, and with Monday as the first day of the week.</dd>
* <dt>%w</dt> <dd>day of the week as a decimal, Sunday being 0</dd>
* <dt>%W</dt> <dd>week number of the current year as a decimal number, starting with the
* first Monday as the first day of the first week</dd>
* <dt>%x</dt> <dd>preferred date representation for the current locale without the time</dd>
* <dt>%X</dt> <dd>preferred time representation for the current locale without the date</dd>
* <dt>%y</dt> <dd>year as a decimal number without a century (range 00 to 99)</dd>
* <dt>%Y</dt> <dd>year as a decimal number including the century</dd>
* <dt>%z</dt> <dd>numerical time zone representation</dd>
* <dt>%Z</dt> <dd>time zone name or abbreviation</dd>
* <dt>%%</dt> <dd>a literal "%" character</dd>
* </dl>
* </dd>
* <dt>locale {String} (Optional)</dt>
* <dd>
* The locale to use when displaying days of week, months of the year, and other locale specific
* strings. If not specified, this defaults to "en" (though this may be overridden by changing Y.config.locale).
* The following locales are built in:
* <dl>
* <dt>en</dt>
* <dd>English</dd>
* <dt>en-US</dt>
* <dd>US English</dd>
* <dt>en-GB</dt>
* <dd>British English</dd>
* <dt>en-AU</dt>
* <dd>Australian English (identical to British English)</dd>
* </dl>
* More locales may be added by subclassing of Y.DataType.Date.Locale["en"].
* See Y.DataType.Date.Locale for more information.
* </dd>
* </dl>
* @return {String} Formatted date for display.
*/
format : function (oDate, oConfig) {
oConfig = oConfig || {};
if(!Y.Lang.isDate(oDate)) {
return Y.Lang.isValue(oDate) ? oDate : "";
}
var format = oConfig.format || Y.config.dateFormat,
sLocale = oConfig.locale || Y.config.locale,
LOCALE = Y.DataType.Date.Locale;
sLocale = sLocale.replace(/_/g, "-");
// Make sure we have a definition for the requested locale, or default to en.
if(!LOCALE[sLocale]) {
var tmpLocale = sLocale.replace(/-[a-zA-Z]+$/, "");
if(tmpLocale in LOCALE) {
sLocale = tmpLocale;
} else if(Y.config.locale in LOCALE) {
sLocale = Y.config.locale;
} else {
sLocale = "en";
}
}
var aLocale = LOCALE[sLocale];
var replace_aggs = function (m0, m1) {
var f = Dt.aggregates[m1];
return (f === "locale" ? aLocale[m1] : f);
};
var replace_formats = function (m0, m1) {
var f = Dt.formats[m1];
switch(Y.Lang.type(f)) {
case "string": // string => built in date function
return oDate[f]();
case "function": // function => our own function
return f.call(oDate, oDate, aLocale);
case "array": // built in function with padding
if(Y.Lang.type(f[0]) === "string") {
return xPad(oDate[f[0]](), f[1]);
} // no break; (fall through to default:)
default:
return m1;
}
};
// First replace aggregates (run in a loop because an agg may be made up of other aggs)
while(format.match(/%[cDFhnrRtTxX]/)) {
format = format.replace(/%([cDFhnrRtTxX])/g, replace_aggs);
}
// Now replace formats (do not run in a loop otherwise %%a will be replace with the value of %a)
var str = format.replace(/%([aAbBCdegGHIjklmMpPsSuUVwWyYzZ%])/g, replace_formats);
replace_aggs = replace_formats = undefined;
return str;
}
};
Y.mix(Y.namespace("DataType.Date"), Dt);
/**
* @module datatype
*/
/**
* The Date.Locale class is a container for all localised date strings
* used by Y.DataType.Date. It is used internally, but may be extended
* to provide new date localisations.
*
* To create your own Locale, follow these steps:
* <ol>
* <li>Find an existing locale that matches closely with your needs</li>
* <li>Use this as your base class. Use Y.DataType.Date.Locale["en"] if nothing
* matches.</li>
* <li>Create your own class as an extension of the base class using
* Y.merge, and add your own localisations where needed.</li>
* </ol>
* See the Y.DataType.Date.Locale["en-US"] and Y.DataType.Date.Locale["en-GB"]
* classes which extend Y.DataType.Date.Locale["en"].
*
* For example, to implement locales for French french and Canadian french,
* we would do the following:
* <ol>
* <li>For French french, we have no existing similar locale, so use
* Y.DataType.Date.Locale["en"] as the base, and extend it:
* <pre>
* Y.DataType.Date.Locale["fr"] = Y.merge(Y.DataType.Date.Locale, {
* a: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"],
* A: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
* b: ["jan", "f&eacute;v", "mar", "avr", "mai", "jun", "jui", "ao&ucirc;", "sep", "oct", "nov", "d&eacute;c"],
* B: ["janvier", "f&eacute;vrier", "mars", "avril", "mai", "juin", "juillet", "ao&ucirc;t", "septembre", "octobre", "novembre", "d&eacute;cembre"],
* c: "%a %d %b %Y %T %Z",
* p: ["", ""],
* P: ["", ""],
* x: "%d.%m.%Y",
* X: "%T"
* });
* </pre>
* </li>
* <li>For Canadian french, we start with French french and change the meaning of \%x:
* <pre>
* Y.DataType.Date.Locale["fr-CA"] = Y.merge(Y.DataType.Date.Locale["fr"], {
* x: "%Y-%m-%d"
* });
* </pre>
* </li>
* </ol>
*
* With that, you can use your new locales:
* <pre>
* var d = new Date("2008/04/22");
* Y.DataType.Date.format(d, { format: "%A, %d %B == %x", locale: "fr" });
* </pre>
* will return:
* <pre>
* mardi, 22 avril == 22.04.2008
* </pre>
* And
* <pre>
* Y.DataType.Date.format(d, {format: "%A, %d %B == %x", locale: "fr-CA" });
* </pre>
* Will return:
* <pre>
* mardi, 22 avril == 2008-04-22
* </pre>
* @requires oop
* @class DataType.Date.Locale
* @static
*/
var YDateEn = {
a: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
A: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
b: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
B: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
c: "%a %d %b %Y %T %Z",
p: ["AM", "PM"],
P: ["am", "pm"],
r: "%I:%M:%S %p",
x: "%d/%m/%y",
X: "%T"
};
Y.namespace("DataType.Date.Locale");
Y.DataType.Date.Locale["en"] = YDateEn;
Y.DataType.Date.Locale["en-US"] = Y.merge(YDateEn, {
c: "%a %d %b %Y %I:%M:%S %p %Z",
x: "%m/%d/%Y",
X: "%I:%M:%S %p"
});
Y.DataType.Date.Locale["en-GB"] = Y.merge(YDateEn, {
r: "%l:%M:%S %P %Z"
});
Y.DataType.Date.Locale["en-AU"] = Y.merge(YDateEn);
}, '3.0.0' );

Some files were not shown because too many files have changed in this diff Show More