![JAR search and dependency download from the Maven repository](/logo.png)
features.opensocial-templates.loader.js Maven / Gradle / Ivy
Go to download
Packages all the features that shindig provides into a single jar file to allow
loading from the classpath
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @fileoverview OpenSocial Template loader. Can be used to load template
* libraries via URL. Supports Javascript and CSS injection.
*
* Usage:
* os.Loader.loadUrl("/path/templatelib.xml", function() { doSomething(); });
*
* or
* os.Loader.loadContent(
* "... ");
*
* The Template Library should have the following structure:
*
*
*
* [Template Markup Here]
*
*
* function usedByAllTemplates() { ... };
*
*
* [Markup for foo:baz]
*
*
* function usedByFooBaz() { ... };
*
*
*
*
* TODO(levik): Implement dependency support - inject JS and CSS lazily.
* TODO(levik): More error handling and reporting of ill-formed XML files.
*/
os.Loader = {};
/**
* A map of URLs which were already loaded.
* @private
*/
os.Loader.loadedUrls_ = {};
/**
* Load a remote URL via XMLHttpRequest or gadgets.io.makeRequest API
* when in context of a gadget.
* @param {string} url The URL that is to be fetched.
* @param {Function} callback Function to call once loaded.
*/
os.Loader.loadUrl = function(url, callback) {
if (typeof(window['gadgets']) != 'undefined') {
os.Loader.requestUrlGadgets_(url, callback);
} else {
os.Loader.requestUrlXHR_(url, callback);
}
};
/**
* Loads a Template Library from a URL via XMLHttpRequest. Once the library is
* loaded, the callback function is called. A map is kept to prevent loading
* the same URL twice.
* @param {string} url The URL of the Template Library.
* @param {Function} callback Function to call once loaded.
* @private
*/
os.Loader.requestUrlXHR_ = function(url, callback) {
if (os.Loader.loadedUrls_[url]) {
window.setTimeout(callback, 0);
return;
}
var req = null;
if (typeof shindig != 'undefined' &&
shindig.xhrwrapper &&
shindig.xhrwrapper.createXHR) {
req = shindig.xhrwrapper.createXHR();
} else if (typeof XMLHttpRequest != 'undefined') {
req = new XMLHttpRequest();
} else {
req = new ActiveXObject('MSXML2.XMLHTTP');
}
req.open('GET', url, true);
req.onreadystatechange = function() {
if (req.readyState == 4) {
os.Loader.loadContent(req.responseText, url);
callback();
}
};
req.send(null);
};
/**
* Fetch content remotely using the gadgets.io.makeRequest API.
* @param {string} url The URL where the content is located.
* @param {Function} callback Function to call with the data from the URL
* once it is fetched.
* @private
*/
os.Loader.requestUrlGadgets_ = function(url, callback) {
var params = {};
var gadgets = window['gadgets'];
if (os.Loader.loadedUrls_[url]) {
window.setTimeout(callback, 0);
return;
}
params[gadgets.io.RequestParameters.CONTENT_TYPE] =
gadgets.io.ContentType.TEXT;
gadgets.io.makeRequest(url, function(obj) {
os.Loader.loadContent(obj.data, url);
callback();
}, params);
};
/**
* Loads a number of Template libraries, specified by an array of URLs. Once
* all the libraries have been loaded, the callback is called.
* @param {Array.} urls An array of URLs of Template Libraries to load.
* @param {Function} callback Function to call once all libraries are loaded.
*/
os.Loader.loadUrls = function(urls, callback) {
var loadOne = function() {
if (urls.length == 0) {
callback();
} else {
os.Loader.loadUrl(urls.pop(), loadOne);
}
};
loadOne();
};
/**
* Processes the XML markup of a Template Library.
*/
os.Loader.loadContent = function(xmlString, url) {
var doc = gadgets.jsondom.parse(xmlString, url);
var templatesNode = doc.firstChild;
os.Loader.processTemplatesNode(templatesNode);
os.Loader.loadedUrls_[url] = true;
};
/**
* Gets the function that should be used for processing a tag.
* @param {string} tagName Name of the tag.
* @return {?Function} The function for processing such tags.
* @private
*/
os.Loader.getProcessorFunction_ = function(tagName) {
// TODO(levik): This won't work once compiler does name mangling.
return os.Loader['process' + tagName + 'Node'] || null;
};
/**
* Processes the node.
*/
os.Loader.processTemplatesNode = function(node) {
// since the ie domparse does not return a general parent element
// we check here if firstChild is really present
if (node.firstChild) {
node = node.firstChild;
}
for (var child = node; child; child = child.nextSibling) {
if (child.nodeType == DOM_ELEMENT_NODE) {
var handler = os.Loader.getProcessorFunction_(child.tagName);
if (handler) {
handler(child);
}
}
}
};
/**
* Processes the node.
*/
os.Loader.processNamespaceNode = function(node) {
var prefix = node.getAttribute('prefix');
var url = node.getAttribute('url');
os.createNamespace(prefix, url);
};
/**
* Processes the node
*/
os.Loader.processTemplateDefNode = function(node) {
var tag = node.getAttribute('tag');
var name = node.getAttribute('name');
for (var child = node.firstChild; child; child = child.nextSibling) {
if (child.nodeType == DOM_ELEMENT_NODE) {
// TODO(levik): This won't work once compiler does name mangling.
var handler = os.Loader.getProcessorFunction_(child.tagName);
if (handler) {
handler(child, tag, name);
}
}
}
};
/**
* Processes the node
*/
os.Loader.processTemplateNode = function(node, opt_tag, opt_name) {
var tag = opt_tag || node.getAttribute('tag');
var name = opt_name || node.getAttribute('name');
if (tag) {
var tagParts = tag.split(':');
if (tagParts.length != 2) {
throw Error('Invalid tag name: ' + tag);
}
var nsObj = os.getNamespace(tagParts[0]);
if (!nsObj) {
throw Error('Namespace not registered: ' + tagParts[0] +
' while trying to define ' + tag);
}
var template = os.compileXMLNode(node);
nsObj[tagParts[1]] = os.createTemplateCustomTag(template);
} else if (name) {
var template = os.compileXMLNode(node);
template.id = name;
os.registerTemplate(template);
}
};
/**
* Processes the node
*/
os.Loader.processJavaScriptNode = function(node, opt_tag) {
for (var contentNode = node.firstChild; contentNode;
contentNode = contentNode.nextSibling) {
// TODO(levik): Skip empty text nodes (with whitespace and newlines)
os.Loader.injectJavaScript(contentNode.nodeValue);
}
};
/**
* Processes the