ericmiraglia.com

termextractor 

Yahoo! UI Library > termextractor > termextractor.js (source view)
Search:
 
Filters
(function() {

//shortcuts:
var Y  = YAHOO,
	YU = Y.util,
	YUIL = YU.YUILoader,
	YL = Y.lang,
	D  = YU.Dom,
	E  = YU.Event,
	CE = YU.CustomEvent,
	API = YAHOO.namespace("api");
	


/**
 * The TermExtractor module facilitates the use of YUI in conjunction with
 * the Yahoo Search Term Extraction API.  This module REQUIRES a server-
 * side proxy to proxy POST requests to the API; see the docs for a sample
 * proxy file written in PHP.  Use of the API also requires a valid appid,
 * which is freely available via the Yahoo Developer Network. See the
 * documentation for this module (http://developer.yahoo.com/yui/termextractor )
 * and the documentation for the API itself 
 * (http://developer.yahoo.com/search/content/V1/termExtraction.html ) for
 * more details.
 * @module termextractor
 * @requires yahoo, dom, event, yuiloader
 *
 */
/**
 * A utility to retrieve related terms via the Yahoo Term Extractor API.
 * @namespace YAHOO.api
 * @class TermExtractor
 * @constructor
 * @param {o} object
 * 		An object containing the configuration attributes for
 * 		term extraction. Members of this configuration object include:
 * 			<ul><li><strong>el | str ID contextEl:</strong> The element from whose value 
 * 				or innerText property terms will be extracted.</li>
 *    		<li><strong>str proxy:</strong> Path to the server-side post proxy 
 *    			that will relay the request and post arguments to the webservice</li>
 *  		<li><strong>str appid:</strong> The <a href="https://developer.yahoo.com/wsregapp/">Yahoo 
 *  			Developer App ID</a> to use in making the request. (Optional:
 *  		    if this is not provided, the appid must be supplied in your server-
 *   		    side proxy as an additional post variable.</li></ul>
 */
API.TermExtractor = function(o) {
	
	//Validate context element:
	if (!YL.isUndefined(o) && !YL.isUndefined(o.contextEl) && D.get(o.contextEl) ) {
		
		/**
		 * The element from whose content terms will be extracted.  If an input
		 * or textarea, content will be extracted from the element's value; if
		 * other, the element's innerText/textContent will be used.
		 * @property contextEl
		 * @type HTMLElement | string ID
		 * @public
		 */
		this.contextEl = D.get(o.contextEl);
		
	} else {
		
		YAHOO.log("ERROR: Unable to locate contextElement.", "error", "TermExtractor");

		return false;
		
	}

	//Validate proxy string presence:
	if (!YL.isUndefined(o.proxy) && YL.isString(o.proxy)) {

		/**
		 * The path to the server-side proxy that will proxy the post request
		 * to the API.  Path should be relative to the current HTML page and 
		 * must obey the strict same origin policy enforced by XMLHttpRequest.
		 * @property proxy
		 * @type string
		 * @public
		 */		
		this.proxy = o.proxy;
		
	} else {
		
		YAHOO.log("ERROR: Proxy was not provided to TermExtractor constructor.", "error", "TermExtractor");
		
	}

	//Validate appid:
	if (!YL.isUndefined(o.appid) && YL.isString(o.appid)) {

		/**
		 * The appid issued by the Yahoo Developer Network for your use.  You may choose
		 * to omit this property in your JavaScript so as to avoid exposing your
		 * appid to prying eyes; in that case, append the appid as a post variable
		 * in your server-side proxy.
		 * @property appid
		 * @type string
		 * @public
		 */
		this.appid = o.appid;
		
	} else {
		
		YAHOO.log("WARNING: Appid was not provided to TermExtractor constructor; be sure to append the appid as an additional post variable in your server-side proxy.", "warn", "TermExtractor");
		
		this.appid = false;
		
	}
	
	/**
	 * Fired when a term extraction request is complete, whether
	 * successful or not. This event uses a FLAT Custom Event signature,
	 * meaning that the subscriber gets a single argument -- an object --
	 * which contains all relevant information, including the following
	 * members:
	 * 
	 * 	<ul><li><strong>array terms:</strong> An array with all terms returned 
	 * 		by the API.</li>
	 *  <li><strong>string message:</strong> Any message coming back from TermExtractor
	 *  	indicating the disposition of the request -- if it failed,
	 *  	the message may give you some indication as to what went
	 *  	wrong.</li></ul>
	 *
	 * @event onComplete
	 */
	this.onComplete = new CE("onComplete", this, false, CE.FLAT);
	
	return this;
};

var proto = API.TermExtractor.prototype;

/**
 * Provides a readable name for the TermExtractor instance.
 * @method toString
 * @return String
 * @private
 */
proto.toString = function() {
    return "TermExtractor " + (this.contextEl.id || this.contextEl.nodeName);
};

/**
 * Kicks off a term extraction request.  Invoke this method when your
 * context element is populated with the content from which you want to
 * extract key terms -- for example, on the blur event of a text area.
 * There is no return value for this method, as the process is
 * asynchronous; subscribe to your TermExtractor instance's onComplete
 * event to process the results of your extraction request.
 * @method extract
 * @return void
 * @public
 */
proto.extract = function() {

	YAHOO.log("Term extraction initiated.", "info", "TermExtractor");

	if (!YL.isUndefined(YU.Connect) && !YL.isUndefined(YL.JSON)) {
		
		YAHOO.log("All YUI dependencies in place.", "info", "TermExtractor");

		this._onDependenciesLoaded();
	
	} else {
		
		YAHOO.log("Handing off to YUI Loader to bring in additional dependencies.", "info", "TermExtractor");
		
		//Load additional dependencies:
		this._loadDependencies();
		
	}
	
};

/**
 * Once TermExtractor has verified that all YUI dependencies are present,
 * or has loaded missing dependencies via YUI Loader, this function
 * creates the Ajax request to the API.
 * @method _onDependenciesLoaded
 * @return void
 * @private
 */
proto._onDependenciesLoaded = function() {
	
	var s,
		o,
		postBody;
	
	YAHOO.log("YUI dependencies loaded.", "info", "TermExtractor");
	
	s = this._getContextContent();
	
	if (!YL.isUndefined(s) && !YL.isUndefined(s.length) && s.length > 0) {
		
		YAHOO.log("Context content:" + s, "info", "TermExtractor");
		
		//postBody for form post to proxy handler:
		postBody = [
				
				"context=" + encodeURIComponent(s),
				"output=json"
				
			].join("&");
		
		if (this.appid) {
			postBody += "&appid=" + encodeURIComponent(this.appid);
		}
		
		//set up connection object:
		o = {
			
			success: 	this._onResponseSuccess,
			scope: 		this,
			failure: 	this._onResponseError,
			timeout:	30000
			
		};
		
		this._lastConnection = YU.Connect.asyncRequest(
			"post", 
			this.proxy, 
			o, 
			postBody);
		
		YAHOO.log("Request made to Term Extraction API.", "info", "TermExtractor");
		
	} else {
		
		YAHOO.log("Context content is undefined or empty.", "info", "TermExtractor");
		
		this.onComplete.fire({
			
			terms: [],
			message: "Context element had no content."
			
		});
		
	}
	
};

/**
 * Handles the error case if there is a transport error in contacting
 * the API via Ajax.
 * @method _onResponseError
 * @return void
 * @private
 */
proto._onResponseError = function(o) {
	
	YAHOO.log("ERROR: Ajax request failed.", "error", "TermExtractor");
	
};


/**
 * Handles Ajax succcess (does not assume that that the request
 * was successful, merely that it id not have a transport error).
 * Most errors will result in an XML response from the API, which 
 * will throw an error in parseJSON.  In that case, the error is
 * caught and the XML text is logged.
 * @method _onResponseSuccess
 * @return void
 * @private
 */
proto._onResponseSuccess = function(o) {
	
	var json,
		result;
		
	YAHOO.log("Ajax request succeeded.", "info","TermExtractor");
	
	try {
		json = YL.JSON.parse(o.responseText);
		
		if(!YL.isUndefined(json) && !YL.isUndefined(json.ResultSet) && !YL.isUndefined(json.ResultSet.Result)) {
			
			result = json.ResultSet.Result;
			
			YAHOO.log("Term extraction succeeded; terms: " + result, "info", "TermExtractor");
			
		} else {
			
			result = [];
			
			YAHOO.log("TermExtractor did not locate any terms.", "warn", "TermExtractor");
			
		}
		
		this.onComplete.fire({
			
			terms: result,
			message: "Response retrieved from Yahoo Search Term Extractor API."
			
		});
		
	} catch (e) {
		
		YAHOO.log("TermExtractor received an error message from the API service.  XML message: " + o.responseText, "error", "TermExtractor");
		
	}
	
};

/**
 * Handles Ajax succcess (does not assume that that the request
 * was successful, merely that it id not have a transport error).
 * Most errors will result in an XML response from the API, which 
 * will throw an error in parseJSON.  In that case, the error is
 * caught and the XML text is logged.
 * @method _getContextContent
 * @return void
 * @private
 */
proto._getContextContent = function() {
	
	YAHOO.log("Getting context content.", "info", "TermExtractor");

	var el = this.contextEl;
	
	if((el.nodeName.toLowerCase() === "input") || (el.nodeName.toLowerCase() === "textarea")) {
		YAHOO.log("elvalue");
		return el.value;
	} else {
		return (YL.isUndefined(el.innerText)) ? el.textContent : el.innerText;
	} 
	
	return false;
	
};

/**
 * Loads dependencies for YAHOO.api.TermExtractor using
 * YUILoader.
 * @method _loadDependencies
 * @private
 * @return void
 */
proto._loadDependencies = function() {
	
    var loader = new YAHOO.util.YUILoader({
	    require: 	["connection","dom","event","json"], 
	    combine: 	true, 
	    allowRollup: false, 
	    onSuccess: 	this._onDependenciesLoaded,
		scope:		this
    }); 
	loader.insert();
	
};

})();

Copyright © 2008 ericmiraglia.com