/*/**************************************************************************************************************** ADDTHIS FLASH API VERSION: 1.0.0 ACTIONSCRIPT VERSION: 3.0 AUTHOR: Robert Abramski WEBSITE: http://www.robertabramski.com/ EMAIL: iam@robertabramski.com LICENSE: http://www.opensource.org/licenses/simpl-2.0.html VERSION LOG: 1.0.0 12/14/09 Initial Release. ******************************************************************************************************************/ package com.robertabramski.net { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.events.Event; import flash.events.EventDispatcher; import flash.geom.Matrix; import flash.net.URLLoader; import flash.net.URLRequest; import flash.system.Capabilities; /** * Fired when all icons are loaded from AddThis. Use the init * function to get the instance to listen for the event. * * @see #init() * @eventType flash.events.Event.ICONS_LOADED * */ [Event(name="iconsLoaded", type="flash.events.Event")] /** * Fired when all service data is loaded. Use the init * function to get the instance to listen for the event. * * @see #init() * @eventType flash.events.Event.SERVICES_LOADED * */ [Event(name="servicesLoaded", type="flash.events.Event")] /** * The AddThis class contains functions for creating custom * visualizations for AddThis. As of the creation of this class there is no * official API for getting all service codes. This class loads an HTML page, * CSS file and a PNG file from AddThis and scrapes the services from those assets. * *

As this is an unofficial implementation, AddThis may change this * content at any time in a way that may break this class. Please use the contact * information in the class file to notify the author if this occurs.

* * @author robertabramski * @version 1.0.0 * */ public class AddThis extends EventDispatcher { /** * Defines the value of the type property of a services loaded event object. * * @eventType servicesLoaded * */ public static const SERVICES_LOADED:String = "servicesLoaded"; /** * Defines the value of the type property of an icons loaded event object. * * @eventType iconsLoaded * */ public static const ICONS_LOADED:String = "iconsLoaded"; private static var servicesPage:String = ""; private static var widgetCSS:String = ""; private static var widgetSprite:String = ""; private static var instance:AddThis; private static const ICON_SIZE:int = 16; private var services:Array = []; private var icons:Array = []; /** * * Loads the service codes and icons on AddThis and makes them available for * use in Flash to make custom AddThis visualizations. * *

This function handles the loading and extraction of the services from AddThis. * Due to a lack of a crossdomain.xml file on AddThis these files must be retrieved with * a server side proxy to get the data to load properly across domains.

* *

This must be run before using the function getAllServiceValues * or getIconByCode. To listen for the finish of the loading of these assets * add event listeners to the AddThis object returned.

* * @see #SERVICES_LOADED * @see #ICONS_LOADED * * @param proxy The URL where the server side proxy script is held. * @param services The services proxy of http://www.addthis.com/services/list. * @param css The CSS proxy of http://s7.addthis.com/static/r07/widget22.css. * @param sprite The PNG sprite proxy of http://s7.addthis.com/static/r07/widget10.png. * @return The AddThis instance. * */ public static function init(proxy:String, services:String, css:String, sprite:String):AddThis { servicesPage = proxy + services; widgetCSS = proxy + css; widgetSprite = proxy + sprite; if(!instance) instance = new AddThis(new Key); return instance; } /** * Returns the singleton instance of the class. * * @return The AddThis instance. * */ public static function getInstance():AddThis { return instance; } /** * @private * @param key Enforces singleton instance. * */ public function AddThis(key:Key) { var request:URLRequest = new URLRequest(servicesPage); var loader:URLLoader = new URLLoader(); loader.load(request); loader.addEventListener(Event.COMPLETE, scrapeServices); if(majorPlayerVersion >= 10) loadStyleSheet(); } private function get majorPlayerVersion():Number { var version:String = Capabilities.version.split(" ")[1]; return version.split(",")[0].valueOf(); } private function loadStyleSheet():void { var request:URLRequest = new URLRequest(widgetCSS); var loader:URLLoader = new URLLoader(); loader.load(request); loader.addEventListener(Event.COMPLETE, scrapePositions); } private function scrapePositions(event:Event):void { try { var css:String = event.target.data as String; var rules:Array = css.split(".at15t_"); rules.shift(); rules.shift(); rules.shift(); rules[rules.length - 1] = rules[rules.length - 1].split("}")[0] + "}"; for(var i:int = 0; i < rules.length; i++) { var icon:Object = new Object; icon.icon = new Bitmap(new BitmapData(ICON_SIZE, ICON_SIZE, true, 0)); icon.code = rules[i].split(" ")[0].split("{background-position:0px")[0]; icon.y = rules[i].split(" ")[1].replace("px}", "").valueOf(); rules[i] = icon; } icons = rules; var request:URLRequest = new URLRequest(widgetSprite); var loader:Loader = new Loader(); loader.load(request); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, appendBitmapData); } catch(error:Error) { throw new Error("Icon position scraping failed"); } } private function appendBitmapData(event:Event):void { var sprite:Bitmap = event.target.content as Bitmap; for(var i:int = 0; i < icons.length; i++) { var bmd:BitmapData = new BitmapData(ICON_SIZE, ICON_SIZE, true, 0); bmd.draw(sprite, new Matrix(1, 0, 0, 1, 0, icons[i].y)); icons[i].icon.bitmapData = bmd; } dispatchEvent(new Event(ICONS_LOADED)); } private function scrapeServices(event:Event):void { try { var webPage:String = event.target.data as String; var table:String = webPage.split("")[1].split("
")[0]; var tds:Array = table.split(""); var tempString:String = ""; for(var i:int = 0; i < tds.length; i++) { if(tds[i].indexOf("", ""); } tempString += (i != 0 ? "" : "") + tds[i]; } var xml:XML = new XML("" + tempString.split("")[1]); for(var j:int = 0; j < xml.tr.length(); j++) { var service:Object = new Object; service.name = service.label = xml.tr[j].td[0].a[0]; service.code = service.data = xml.tr[j].td[1]; service.category = xml.tr[j].td[2]; service.description = xml.tr[j].td[3]; service.link = xml.tr[j].td[0].a[0].@href; services.push(service); } dispatchEvent(new Event(SERVICES_LOADED)); } catch(error:Error) { throw new Error("Service scraping failed."); } } private function getIcon(code:String = ""):Bitmap { if(code == "") code = "000"; for(var i:int = 0; i < icons.length; i++) { if(icons[i].code == code) return new Bitmap(icons[i].icon.bitmapData); } return new Bitmap(new BitmapData(ICON_SIZE, ICON_SIZE, false, 0xFFFFFF)); } /** * Gets the AddThis icon based on the service code provided. Due to Flash's 2,880 pixel bitmap limit * and the AddThis sprite PNG exceeding that limit this function only works in Flash Player 10 and above. * If the assets have not loaded this function returns a white bitmap image. Icons are available once * ICONS_LOADED has fired. If no parameter is passed the function returns the AddThis icon * by default. * * @see #ICONS_LOADED * @param code The service code. * @return The 16x16 pixel icon. * */ public static function getIconByCode(code:String = ""):Bitmap { return instance.getIcon(code); } private function getBookmark(link:String, service:String = "", title:String = "", user:String = ""):String { var url:String; url = "http://www.addthis.com/bookmark.php"; url += "?url=" + escape(link); url += service != "" ? "&s=" + service : ""; url += title != "" ? "&title=" + escape(title) : ""; url += user != "" ? "&pub=" + user : ""; return url; } /** * Gets the URL string to send to the AddThis bookmarking service. Required parameter * is link. Setting only one parameter will send to the bookmark page. * Optionally, the service parameter can be added to send to a specific service. * The title parameter will add a title used for some services and user * will allow AddThis analytics to track based on the username. All this information should * be collected from the getAllServiceValues functions once SERVICES_LOADED * has fired. * * @see #getAllServiceValues() * @see #SERVICES_LOADED * * @param service The name of the service. * @param link The service code for the bookmark query string. * @param title The title of the URL to be bookmarked. * @param user The username on AddThis. * * @return The URL string for the AddThis bookmarking service. * */ public static function getBookmarkLink(link:String, service:String = "", title:String = "", user:String = ""):String { return instance.getBookmark(link, service, title, user); } private function getOExchange(link:String, service:String = "", title:String = "", user:String = ""):String { var url:String; url = "http://api.addthis.com/oexchange/0.8/forward"; url += service != "" ? ("/" + service + "/offer?") : "/offer?"; url += "url=" + escape(link); url += title != "" ? "&title=" + escape(title) : ""; url += user != "" ? "&username=" + user : ""; return url; } /** * Gets the URL string to send to the OExchange compatible bookmarking service. Required parameter * is link. Setting only one parameter will send to the bookmark page. * Optionally, the service parameter can be added to send to a specific service. * The title parameter will add a title used for some services and user * will allow AddThis analytics to track based on the username. All this information should * be collected from the getAllServiceValues functions once SERVICES_LOADED * has fired. * * @see #getAllServiceValues() * @see #SERVICES_LOADED * * @param service The name of the service. * @param link The service code for the bookmark query string. * @param title The title of the URL to be bookmarked. * @param user The username on AddThis. * * @return The URL string for the AddThis bookmarking service. * */ public static function getOExchangeLink(link:String, service:String = "", title:String = "", user:String = ""):String { return instance.getOExchange(link, service, title, user); } /** * Gets an array of objects with properties corresponding to the * Service Codes page * on AddThis. The properties are as follows: name, code, * category, description and link. * Additionally, the properties label and data alias * name and code for Flex data providers. * *

If the init function has not been run this will return an * empty array.

* * @see http://www.addthis.com/services/list * @see #init() * @return The array of all AddThis services available. * */ public static function getAllServiceValues():Array { return instance.services; } } } /** * @private * */ internal class Key {}