mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
New build scripts
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
339
source/web/scripts/ajax/dojo/src/widget/Parse.js
Normal file
339
source/web/scripts/ajax/dojo/src/widget/Parse.js
Normal file
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
dojo.provide("dojo.widget.Parse");
|
||||
dojo.require("dojo.widget.Manager");
|
||||
dojo.require("dojo.dom");
|
||||
|
||||
//
|
||||
// dojoML parser should be moved out of 'widget', codifying the difference between a 'component'
|
||||
// and a 'widget'. A 'component' being anything that can be generated from a tag.
|
||||
//
|
||||
// a particular dojoML tag would be handled by a registered tagHandler with a hook for a default handler
|
||||
// if the widget system is loaded, a widget builder would be attach itself as the default handler
|
||||
//
|
||||
// widget tags are no longer registered themselves:
|
||||
// they are now arbitrarily namespaced, so we cannot register them all, and the non-prefixed portions
|
||||
// are no longer guaranteed unique
|
||||
//
|
||||
// therefore dojo.widget.tags should go with this parser code out of the widget module
|
||||
//
|
||||
|
||||
dojo.widget.Parse = function(/*Object*/fragment){
|
||||
this.propertySetsList = [];
|
||||
this.fragment = fragment;
|
||||
|
||||
this.createComponents = function(/*Object*/frag, /*Object*/parentComp){
|
||||
var comps = [];
|
||||
var built = false;
|
||||
// if we have items to parse/create at this level, do it!
|
||||
try{
|
||||
if(frag && frag.tagName && (frag != frag.nodeRef)){
|
||||
|
||||
// these are in fact, not ever for widgets per-se anymore,
|
||||
// but for other markup elements (aka components)
|
||||
var djTags = dojo.widget.tags;
|
||||
|
||||
// we split so that you can declare multiple
|
||||
// non-destructive components from the same ctor node
|
||||
var tna = String(frag.tagName).split(";");
|
||||
for(var x=0; x<tna.length; x++){
|
||||
var ltn = tna[x].replace(/^\s+|\s+$/g, "").toLowerCase();
|
||||
// FIXME: unsure what this does
|
||||
frag.tagName = ltn;
|
||||
var ret;
|
||||
if(djTags[ltn]){
|
||||
built = true;
|
||||
ret = djTags[ltn](frag, this, parentComp, frag.index);
|
||||
comps.push(ret);
|
||||
}else{
|
||||
// we require a namespace prefix, default to dojo:
|
||||
if(ltn.indexOf(":") == -1){
|
||||
ltn = "dojo:"+ltn;
|
||||
}
|
||||
// FIXME: handling failure condition correctly?
|
||||
// ret = djTags[ltn](frag, this, parentComp, frag.index);
|
||||
ret = dojo.widget.buildWidgetFromParseTree(ltn, frag, this, parentComp, frag.index);
|
||||
if(ret){
|
||||
built = true;
|
||||
comps.push(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
dojo.debug("dojo.widget.Parse: error:", e);
|
||||
// note, commenting out the next line is breaking several widgets for me
|
||||
// throw e;
|
||||
// IE is such a pain sometimes
|
||||
}
|
||||
// if there's a sub-frag, build widgets from that too
|
||||
if(!built){
|
||||
comps = comps.concat(this.createSubComponents(frag, parentComp));
|
||||
}
|
||||
return comps; // Array
|
||||
}
|
||||
|
||||
this.createSubComponents = function(/*Object*/fragment, /*Object*/parentComp){
|
||||
// summary: recurses over a raw JavaScript object structure,
|
||||
// and calls the corresponding handler for its normalized tagName if it exists
|
||||
|
||||
var frag, comps = [];
|
||||
for(var item in fragment){
|
||||
frag = fragment[item];
|
||||
if(frag && typeof frag == "object"
|
||||
&&(frag!=fragment.nodeRef)
|
||||
&&(frag!=fragment.tagName)
|
||||
&&(!dojo.dom.isNode(frag))){// needed in IE when we have event.connected to the domNode
|
||||
comps = comps.concat(this.createComponents(frag, parentComp));
|
||||
}
|
||||
}
|
||||
return comps; // Array
|
||||
}
|
||||
|
||||
this.parsePropertySets = function(/*Object*/fragment){
|
||||
// summary: checks the top level of a raw JavaScript object
|
||||
// structure for any propertySets. It stores an array of references to
|
||||
// propertySets that it finds.
|
||||
return [];
|
||||
/*
|
||||
var propertySets = [];
|
||||
for(var item in fragment){
|
||||
if((fragment[item]["tagName"] == "dojo:propertyset")){
|
||||
propertySets.push(fragment[item]);
|
||||
}
|
||||
}
|
||||
// FIXME: should we store these propertySets somewhere for later retrieval
|
||||
this.propertySetsList.push(propertySets);
|
||||
return propertySets;
|
||||
*/
|
||||
}
|
||||
|
||||
this.parseProperties = function(/*Object*/fragment){
|
||||
// summary: parseProperties checks a raw JavaScript object structure for
|
||||
// properties, and returns a hash of properties that it finds.
|
||||
var properties = {};
|
||||
for(var item in fragment){
|
||||
// FIXME: need to check for undefined?
|
||||
// case: its a tagName or nodeRef
|
||||
if((fragment[item] == fragment.tagName)||(fragment[item] == fragment.nodeRef)){
|
||||
// do nothing
|
||||
}else{
|
||||
var frag = fragment[item];
|
||||
if(frag.tagName && dojo.widget.tags[frag.tagName.toLowerCase()]){
|
||||
// TODO: it isn't a property or property set, it's a fragment,
|
||||
// so do something else
|
||||
// FIXME: needs to be a better/stricter check
|
||||
// TODO: handle xlink:href for external property sets
|
||||
}else if(frag[0] && frag[0].value!="" && frag[0].value!=null){
|
||||
try{
|
||||
// FIXME: need to allow more than one provider
|
||||
if(item.toLowerCase() == "dataprovider"){
|
||||
var _this = this;
|
||||
this.getDataProvider(_this, frag[0].value);
|
||||
properties.dataProvider = this.dataProvider;
|
||||
}
|
||||
properties[item] = frag[0].value;
|
||||
var nestedProperties = this.parseProperties(frag);
|
||||
// FIXME: this kind of copying is expensive and inefficient!
|
||||
for(var property in nestedProperties){
|
||||
properties[property] = nestedProperties[property];
|
||||
}
|
||||
}catch(e){ dojo.debug(e); }
|
||||
}
|
||||
switch(item.toLowerCase()){
|
||||
case "checked":
|
||||
case "disabled":
|
||||
if (typeof properties[item] != "boolean"){
|
||||
properties[item] = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties; // Object
|
||||
}
|
||||
|
||||
this.getDataProvider = function(/*Object*/objRef, /*String*/dataUrl){
|
||||
// FIXME: this is currently sync. To make this async, we made need to move
|
||||
//this step into the widget ctor, so that it is loaded when it is needed
|
||||
// to populate the widget
|
||||
dojo.io.bind({
|
||||
url: dataUrl,
|
||||
load: function(type, evaldObj){
|
||||
if(type=="load"){
|
||||
objRef.dataProvider = evaldObj;
|
||||
}
|
||||
},
|
||||
mimetype: "text/javascript",
|
||||
sync: true
|
||||
});
|
||||
}
|
||||
|
||||
this.getPropertySetById = function(propertySetId){
|
||||
// summary: returns the propertySet that matches the provided id
|
||||
for(var x = 0; x < this.propertySetsList.length; x++){
|
||||
if(propertySetId == this.propertySetsList[x]["id"][0].value){
|
||||
return this.propertySetsList[x];
|
||||
}
|
||||
}
|
||||
return ""; // String
|
||||
}
|
||||
|
||||
//FIXME: doesn't use the componentType param?
|
||||
this.getPropertySetsByType = function(componentType){
|
||||
// summary: returns the propertySet(s) that match(es) the
|
||||
// provided componentClass
|
||||
|
||||
var propertySets = [];
|
||||
for(var x=0; x < this.propertySetsList.length; x++){
|
||||
var cpl = this.propertySetsList[x];
|
||||
var cpcc = cpl.componentClass || cpl.componentType || null; //FIXME: is componentType supposed to be an indirect reference?
|
||||
var propertySetId = this.propertySetsList[x]["id"][0].value;
|
||||
if(cpcc && (propertySetId == cpcc[0].value)){
|
||||
propertySets.push(cpl);
|
||||
}
|
||||
}
|
||||
return propertySets; // Array
|
||||
}
|
||||
|
||||
this.getPropertySets = function(/*Object*/fragment){
|
||||
// summary: returns the propertySet for a given component fragment
|
||||
|
||||
var ppl = "dojo:propertyproviderlist";
|
||||
var propertySets = [];
|
||||
var tagname = fragment.tagName;
|
||||
if(fragment[ppl]){
|
||||
var propertyProviderIds = fragment[ppl].value.split(" ");
|
||||
// FIXME: should the propertyProviderList attribute contain #
|
||||
// syntax for reference to ids or not?
|
||||
// FIXME: need a better test to see if this is local or external
|
||||
// FIXME: doesn't handle nested propertySets, or propertySets that
|
||||
// just contain information about css documents, etc.
|
||||
for(var propertySetId in propertyProviderIds){
|
||||
if((propertySetId.indexOf("..")==-1)&&(propertySetId.indexOf("://")==-1)){
|
||||
// get a reference to a propertySet within the current parsed structure
|
||||
var propertySet = this.getPropertySetById(propertySetId);
|
||||
if(propertySet != ""){
|
||||
propertySets.push(propertySet);
|
||||
}
|
||||
}else{
|
||||
// FIXME: add code to parse and return a propertySet from
|
||||
// another document
|
||||
// alex: is this even necessaray? Do we care? If so, why?
|
||||
}
|
||||
}
|
||||
}
|
||||
// we put the typed ones first so that the parsed ones override when
|
||||
// iteration happens.
|
||||
return this.getPropertySetsByType(tagname).concat(propertySets); // Array
|
||||
}
|
||||
|
||||
this.createComponentFromScript = function(/*Node*/nodeRef, /*String*/componentName, /*Object*/properties, /*String?*/ns){
|
||||
// summary:
|
||||
// nodeRef: the node to be replaced... in the future, we might want to add
|
||||
// an alternative way to specify an insertion point
|
||||
// componentName: the expected dojo widget name, i.e. Button of ContextMenu
|
||||
// properties: an object of name value pairs
|
||||
// ns: the namespace of the widget. Defaults to "dojo"
|
||||
|
||||
properties.fastMixIn = true;
|
||||
// FIXME: we pulled it apart and now we put it back together ...
|
||||
var ltn = (ns || "dojo") + ":" + componentName.toLowerCase();
|
||||
if(dojo.widget.tags[ltn]){
|
||||
return [dojo.widget.tags[ltn](properties, this, null, null, properties)]; // Array
|
||||
}
|
||||
return [dojo.widget.buildWidgetFromParseTree(ltn, properties, this, null, null, properties)]; // Array
|
||||
}
|
||||
}
|
||||
|
||||
dojo.widget._parser_collection = {"dojo": new dojo.widget.Parse() };
|
||||
|
||||
dojo.widget.getParser = function(/*String?*/name){
|
||||
if(!name){ name = "dojo"; }
|
||||
if(!this._parser_collection[name]){
|
||||
this._parser_collection[name] = new dojo.widget.Parse();
|
||||
}
|
||||
return this._parser_collection[name];
|
||||
}
|
||||
|
||||
dojo.widget.createWidget = function(/*String*/name, /*String*/props, /*Node*/refNode, /*String*/position){
|
||||
// summary: Creates widget
|
||||
// name: The name of the widget to create with optional namespace prefix,
|
||||
// e.g."ns:widget", namespace defaults to "dojo".
|
||||
// props: Key-Value pairs of properties of the widget
|
||||
// refNode: If the position argument is specified, this node is used as
|
||||
// a reference for inserting this node into a DOM tree; else
|
||||
// the widget becomes the domNode
|
||||
// position: The position to insert this widget's node relative to the
|
||||
// refNode argument
|
||||
|
||||
var isNode = false;
|
||||
var isNameStr = (typeof name == "string");
|
||||
if(isNameStr){
|
||||
var pos = name.indexOf(":");
|
||||
var ns = (pos > -1) ? name.substring(0,pos) : "dojo";
|
||||
if(pos > -1){ name = name.substring(pos+1); }
|
||||
var lowerCaseName = name.toLowerCase();
|
||||
var namespacedName = ns + ":" + lowerCaseName;
|
||||
isNode = (dojo.byId(name) && !dojo.widget.tags[namespacedName]);
|
||||
}
|
||||
|
||||
if((arguments.length == 1) && (isNode || !isNameStr)){
|
||||
// we got a DOM node
|
||||
var xp = new dojo.xml.Parse();
|
||||
// FIXME: we should try to find the parent!
|
||||
var tn = isNode ? dojo.byId(name) : name;
|
||||
return dojo.widget.getParser().createComponents(xp.parseElement(tn, null, true))[0];
|
||||
}
|
||||
|
||||
function fromScript(placeKeeperNode, name, props, ns){
|
||||
props[namespacedName] = {
|
||||
dojotype: [{value: lowerCaseName}],
|
||||
nodeRef: placeKeeperNode,
|
||||
fastMixIn: true
|
||||
};
|
||||
props.ns = ns;
|
||||
return dojo.widget.getParser().createComponentFromScript(placeKeeperNode, name, props, ns);
|
||||
}
|
||||
|
||||
props = props||{};
|
||||
var notRef = false;
|
||||
var tn = null;
|
||||
var h = dojo.render.html.capable;
|
||||
if(h){
|
||||
tn = document.createElement("span");
|
||||
}
|
||||
if(!refNode){
|
||||
notRef = true;
|
||||
refNode = tn;
|
||||
if(h){
|
||||
dojo.body().appendChild(refNode);
|
||||
}
|
||||
}else if(position){
|
||||
dojo.dom.insertAtPosition(tn, refNode, position);
|
||||
}else{ // otherwise don't replace, but build in-place
|
||||
tn = refNode;
|
||||
}
|
||||
var widgetArray = fromScript(tn, name.toLowerCase(), props, ns);
|
||||
if( (!widgetArray)||(!widgetArray[0])||
|
||||
(typeof widgetArray[0].widgetType == "undefined") ){
|
||||
throw new Error("createWidget: Creation of \"" + name + "\" widget failed.");
|
||||
}
|
||||
try{
|
||||
if(notRef && widgetArray[0].domNode.parentNode){
|
||||
widgetArray[0].domNode.parentNode.removeChild(widgetArray[0].domNode);
|
||||
}
|
||||
}catch(e){
|
||||
/* squelch for Safari */
|
||||
dojo.debug(e);
|
||||
}
|
||||
return widgetArray[0]; // Widget
|
||||
}
|
Reference in New Issue
Block a user