/*
* Copyright 2003-2006, 2009, 2017, United States Government, as represented by the Administrator of the
* National Aeronautics and Space Administration. All rights reserved.
*
* The NASAWorldWind/WebWorldWind platform is licensed 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.
*/
/**
* @exports OpenSearchUtils
*/
define([
'../../util/Promise'
],
function (Promise) {
'use strict';
/**
* Provides utilities for handling OpenSearch responses and requests.
* @exports OpenSearchUtils
*/
var OpenSearchUtils = {
/**
* Gets the trimmed text content of the first child node starting from a root node.
*
* @param {Node} parent The root node from which to start the search.
* @param {String} localName The local name (without the namespace) of the child node which contains the
* text content.
* @param {String|null} namespaceURI The namespace URI of the child node.
*
* @return {String} The text content of the specified child node.
*/
getChildTextContent: function (parent, localName, namespaceURI) {
var collection = this.getXmlElements(parent, localName, namespaceURI);
if (collection.length) {
return collection[0].textContent.trim();
}
return '';
},
/**
* Gets the trimmed text content of node.
*
* @param {Node} node The node from which to get the text content.
*
* @return {String} The text content of the specified node.
*/
getTextContent: function (node) {
return node.textContent.trim();
},
/**
* Finds all child nodes that match the localName and namespaceURI, starting from a root node.
*
* @param {Node} parent The root node from which to start the search.
* @param {String} localName The local name (without the namespace) of the child node.
* @param {String|null} namespaceURI The namespace URI of the child node.
*
* @return {Node[]} An array of XML nodes.
*/
getXmlElements: function (parent, localName, namespaceURI) {
var collection;
if (namespaceURI) {
collection = parent.getElementsByTagNameNS(namespaceURI, localName);
}
else {
collection = parent.getElementsByTagName(localName);
//Firefox does not return namespace nodes with getElementsByTagName
if (!collection.length) {
collection = parent.getElementsByTagNameNS('*', localName);
}
}
if (collection && collection.length) {
return [].slice.call(collection);
}
return [];
},
/**
* Gets the attributes of an XML node and stores them in an object.
*
* @param {Node} node The XML node to read from.
* @param {Object} result An object to store the attributes.
*
* @return {Object} The resulting object.
*/
getNodeAttributes: function (node, result) {
for (var i = 0, len = node.attributes.length; i < len; i++) {
var attribute = node.attributes[i];
result[attribute.name] = attribute.value;
}
return result;
},
/**
* Finds a value in an array that satisfies the provided predicate function.
*
* @param {Array} array The array to search in.
* @param {Function} predicate Function to execute on each value in the array, taking three arguments:
* element The current element being processed in the array.
* index The index of the current element being processed in the array.
* array The array find was called upon.
* @param {Object|null} context Object to use as "this" when executing the predicate function.
*
* @return {Any|undefined} The value of the first element in the array that satisfies the provided predicate
* function. Otherwise, undefined is returned.
*/
arrayFind: function (array, predicate, context) {
if (!Array.isArray(array)) {
throw (new Error('arrayFind - missing array'));
}
if (typeof predicate !== 'function') {
throw (new Error('arrayFind - missing predicate'));
}
for (var i = 0, len = array.length; i < len; i++) {
if (predicate.call(context, array[i], i, array)) {
return array[i];
}
}
},
/**
* Parses an XML string and returns its root element.
*
* @param {String} xmlString The XML string to parse.
* @return {Element} The root element of the parsed document.
*/
parseXml: function (xmlString) {
var xmlDOM = new DOMParser().parseFromString(xmlString, 'text/xml');
return xmlDOM.documentElement;
},
/**
* Provides a standard method for fetching resources.
*
* @param {OpenSearchRequest} options
* @return {Promise} A promise that resolves with the response or rejects with an error.
*/
fetch: function (options) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
return resolve(this.response);
}
return reject(new Error(this.status + ' ' + this.statusText));
};
xhr.onerror = function () {
return reject(new Error('Unable to fetch data'));
};
xhr.ontimeout = function () {
return reject(new Error('Request timed out'));
};
xhr.open(options.method, options.url, true, options.user, options.password);
xhr.withCredentials = options.withCredentials;
xhr.timeout = options.timeout;
xhr.responseType = options.responseType;
Object.keys(options.headers).forEach(function (key) {
xhr.setRequestHeader(key, options.headers[key]);
});
xhr.send(options.body);
});
}
};
return OpenSearchUtils;
});