codesite-noreply at google.com
2009-Jun-01 00:39 UTC
[Mapstraction] [mapstraction commit] r13 - * Refactored mxn.js so everything isn''t defined inside body of mxn. This allows prototype t...
Author: dezfowler Date: Sun May 31 17:34:50 2009 New Revision: 13 Modified: trunk/source/mxn.core.js trunk/source/mxn.js trunk/source/mxn.microsoft.core.js trunk/source/mxn.yahoo.core.js trunk/tests/index.htm Log: * Refactored mxn.js so everything isn''t defined inside body of mxn. This allows prototype to be used for constructor functions. Also moved auto load logic outside the main mxn definition function. * Added Color utility class for converting to and from ''#000000'' format and RGB integer values. * Fixed a Yahoo bug to do with pan control. * Styled test page up a bit better. Modified: trunk/source/mxn.core.js =============================================================================--- trunk/source/mxn.core.js (original) +++ trunk/source/mxn.core.js Sun May 31 17:34:50 2009 @@ -443,10 +443,8 @@ var lat_min = 90; var lon_max = -180; var lon_min = 180; - - for (var i=0; i<this.markers.length; i++) { - lat = this.markers[i].location.lat; - lon = this.markers[i].location.lon; + var lat, lon; + var checkMinMax = function(){ if (lat > lat_max) { lat_max = lat; } @@ -459,23 +457,17 @@ if (lon < lon_min) { lon_min = lon; } + }; + for (var i = 0; i < this.markers.length; i++) { + lat = this.markers[i].location.lat; + lon = this.markers[i].location.lon; + checkMinMax(); } - for (var i=0; i<this.polylines.length; i++) { - for (var j=0; j<this.polylines[i].points.length; j++) { + for (var i = 0; i < this.polylines.length; i++) { + for (var j = 0; j < this.polylines[i].points.length; j++) { lat = this.polylines[i].points[j].lat; lon = this.polylines[i].points[j].lon; - if (lat > lat_max) { - lat_max = lat; - } - if (lat < lat_min) { - lat_min = lat; - } - if (lon > lon_max) { - lon_max = lon; - } - if (lon < lon_min) { - lon_min = lon; - } + checkMinMax(); } } this.setBounds( new BoundingBox(lat_min, lon_min, lat_max, lon_max) ); @@ -956,11 +948,8 @@ this.lon = lon; this.lng = lon; // lets be lon/lng agnostic - // TODO: put a vlid function for returning the api id in here - this.invoker = new mxn.Invoker(this, ''LatLonPoint''); - - -} + this.invoker = new mxn.Invoker(this, ''LatLonPoint''); +}; mxn.addProxyMethods(LatLonPoint, [ ''fromProprietary'', ''toProprietary'' Modified: trunk/source/mxn.js =============================================================================--- trunk/source/mxn.js (original) +++ trunk/source/mxn.js Sun May 31 17:34:50 2009 @@ -1,43 +1,211 @@ -var mxn = (function(){ +(function(){ + +// holds all our implementing functions +var apis = {}; + +// Our special private methods +/** + * Calls the API specific implementation of a particular method. + */ +var invoke = function(sApiId, sObjName, sFnName, oScope, args){ + if(!hasImplementation(sApiId, sObjName, sFnName)) { + throw ''Method '' + sFnName + '' of object '' + sObjName + '' is not supported by API '' + sApiId + ''. Are you missing a script tag?''; + } + return apis[sApiId][sObjName][sFnName].apply(oScope, args); +}; + +/** + * Determines whether the specified API provides an implementation for the + * specified object and function name. + */ +var hasImplementation = function(sApiId, sObjName, sFnName){ + if(typeof(apis[sApiId]) == ''undefined'') { + throw ''API '' + sApiId + '' not loaded. Are you missing a script tag?''; + } + if(typeof(apis[sApiId][sObjName]) == ''undefined'') { + throw ''Object definition '' + sObjName + '' in API '' + sApiId + '' not loaded. Are you missing a script tag?''; + } + return typeof(apis[sApiId][sObjName][sFnName]) == ''function''; +}; + +var mxn = window.mxn = { + + /** + * Registers a set of provider specific implementation functions. + */ + register: function(sApiId, oApiImpl){ + if(!apis.hasOwnProperty(sApiId)) apis[sApiId] = {}; + mxn.util.merge(apis[sApiId], oApiImpl); + }, + + /** + * Adds a list of named proxy methods to the prototype of a + * specified constructor function. + * @param {Function} func Constructor function to add methods to + * @param {Array} aryMethods Array of method names to create + * @param {Boolean} bWithApiArg Optional. Whether the proxy methods will use an API argument + */ + addProxyMethods: function(func, aryMethods, bWithApiArg){ + for(var i = 0; i < aryMethods.length; i++) { + var sMethodName = aryMethods[i]; + if(bWithApiArg){ + func.prototype[sMethodName] = new Function(''return this.invoker.go(\'''' + sMethodName + ''\'', arguments, { overrideApi: true } );''); + } + else { + func.prototype[sMethodName] = new Function(''return this.invoker.go(\'''' + sMethodName + ''\'', arguments);''); + } + } + }, + + /* + checkLoad: function(funcDetails){ + if(this.loaded[this.api] === false) { + var scope = this; + this.onload[this.api].push( function() { funcDetails.callee.apply(scope, funcDetails); } ); + return true; + } + return false; + }, + */ + + /** + * Bulk add some named events to an object. + */ + addEvents: function(oEvtSrc, aEvtNames){ + for(var i = 0; i < aEvtNames.length; i++){ + var sEvtName = aEvtNames[i]; + if(sEvtName in oEvtSrc) throw ''Event or method '' + sEvtName + '' already declared.''; + oEvtSrc[sEvtName] = new mxn.Event(sEvtName, oEvtSrc); + } + } + +}; + +/** + * Event + * @constructor + */ +mxn.Event = function(sEvtName, oEvtSource){ + var handlers = []; + if(!sEvtName) throw ''Event name must be provided''; + this.addHandler = function(fn, ctx){ + handlers.push({context: ctx, handler: fn}); + }; + this.removeHandler = function(fn, ctx){ + for(var i = 0; i < handlers.length; i++){ + if(handlers[i].handler == fn && handlers[i].context == ctx){ + handlers.splice(i, 1); + } + } + }; + this.removeAllHandlers = function(){ + handlers = []; + }; + this.fire = function(oEvtArgs){ + var args = [sEvtName, oEvtSource, oEvtArgs]; + for(var i = 0; i < handlers.length; i++){ + handlers[i].handler.apply(handlers[i].context, args); + } + } +}; + +/** + * Creates a new Invoker, a class which helps with on-the-fly + * invocation of the correct API methods. + * @constructor + * @param {Object} aobj The core object whose methods will make cals to go() + * @param {String} asClassName The name of the Mapstraction class to be invoked, normally the same name as aobj''s constructor function + * @param {Function} afnApiIdGetter The function on object aobj which will return the active API ID + */ +mxn.Invoker = function(aobj, asClassName, afnApiIdGetter){ + var obj = aobj; + var sClassName = asClassName; + var fnApiIdGetter = afnApiIdGetter; + var defOpts = { + overrideApi: false, // {Boolean} API ID is overridden by value in first argument + context: null, // {Object} Local vars can be passed from the body of the method to the API method within this object + fallback: null // {Function} If an API implementation doesn''t exist this function is run instead + }; + + /** + * Invoke the API implementation of a specific method. + * @param {String} sMethodName The method name to invoke + * @param {Array} args Arguments to pass on + * @param {String} oOptions Optional. Extra options for invocation + */ + this.go = function(sMethodName, args, oOptions){ + + if(typeof(oOptions) == ''undefined''){ + oOptions = defOpts; + } + + var sApiId = oOptions.overrideApi ? args[0] : fnApiIdGetter.apply(obj); + + if(typeof(sApiId) != ''string'') + throw ''API ID not available.''; + + if(typeof(oOptions.context) != ''undefined'' && oOptions.context !== null){ + // make sure args is an array + args = Array.prototype.slice.apply(args); + args.push(oOptions.context); + } + + if(typeof(oOptions.fallback) == ''function'' && !hasImplementation(sApiId, sClassName, sMethodName)){ + // we''ve got no implementation but have got a fallback function + return oOptions.fallback.apply(obj, args); + } + else { + return invoke(sApiId, sClassName, sMethodName, obj, args); + } + + }; - // holds all our implementing functions - var apis = {}; +}; + + +mxn.util = { + + /** + * Merges properties of one object into another recursively. + * @param {Object} oRecv The object receiveing properties + * @param {Object} oGive The object donating properties + */ + merge: function(oRecv, oGive){ + for (var sPropName in oGive) if (oGive.hasOwnProperty(sPropName)) { + if(!oRecv.hasOwnProperty(sPropName)){ + oRecv[sPropName] = oGive[sPropName]; + } + else { + mxn.util.merge(oRecv[sPropName], oGive[sPropName]); + } + } + }, - // ''Constructor'' - (function() { - // Defaults - var providers = ''google,yahoo,microsoft''; - var modules = ''core''; - var scriptBase; - var scripts = document.getElementsByTagName(''script''); - - for (var i = 0; i < scripts.length; i++) { - var match = scripts[i].src.replace(/%20/g , '''').match(/^(.*?)mxn\.js(\?\(\[?(.*?)\]?\))?$/); - if (match != null) { - scriptBase = match[1]; - if (match[3]) { - var settings = match[3].split('',[''); - providers = settings[0].replace('']'' , ''''); - if (settings[1]) modules = settings[1]; - } - break; - } - } - providers = providers.replace(/ /g, '''').split('',''); - modules = modules.replace(/ /g, '''').split('',''); - for (var i = 0; i < modules.length; i++) { - loadScript(scriptBase + ''mxn.'' + modules[i] + ''.js''); - for (var j = 0; j < providers.length; j++) loadScript(scriptBase + ''mxn.'' + providers[j] + ''.'' + modules[i] + ''.js''); + /** + * $m, the dollar function, elegantising getElementById() + * @return An HTML element or array of HTML elements + */ + $m: function() { + var elements = []; + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof(element) == ''string'') { + element = document.getElementById(element); + } + if (arguments.length == 1) { + return element; + } + elements.push(element); } - })(); + return elements; + }, - // Our special private methods /** * loadScript is a JSON data fetcher * @param {String} src URL to JSON file * @param {Function} callback Callback function */ - function loadScript(src, callback) { + loadScript: function(src, callback) { var script = document.createElement(''script''); script.type = ''text/javascript''; script.src = src; @@ -50,341 +218,203 @@ } document.getElementsByTagName(''head'')[0].appendChild(script); return; - }; - + }, + /** - * Calls the API specific implementation of a particular method. + * + * @param {Object} point + * @param {Object} level */ - var invoke = function(sApiId, sObjName, sFnName, oScope, args){ - if(!hasImplementation(sApiId, sObjName, sFnName)) { - throw ''Method '' + sFnName + '' of object '' + sObjName + '' is not supported by API '' + sApiId + ''. Are you missing a script tag?''; - } - return apis[sApiId][sObjName][sFnName].apply(oScope, args); - }; - + convertLatLonXY_Yahoo: function(point, level) { //Mercator + var size = 1 << (26 - level); + var pixel_per_degree = size / 360.0; + var pixel_per_radian = size / (2 * Math.PI); + var origin = new YCoordPoint(size / 2 , size / 2); + var answer = new YCoordPoint(); + answer.x = Math.floor(origin.x + point.lon * pixel_per_degree); + var sin = Math.sin(point.lat * Math.PI / 180.0); + answer.y = Math.floor(origin.y + 0.5 * Math.log((1 + sin) / (1 - sin)) * -pixel_per_radian); + return answer; + }, + + /** + * Load a stylesheet from a remote file. + * @param {String} href URL to the CSS file + */ + loadStyle: function(href) { + var link = document.createElement(''link''); + link.type = ''text/css''; + link.rel = ''stylesheet''; + link.href = href; + document.getElementsByTagName(''head'')[0].appendChild(link); + return; + }, + /** - * Determines whether the specified API provides an implementation for the - * specified object and function name. + * getStyle provides cross-browser access to css + * @param {Object} el HTML Element + * @param {String} prop Style property name */ - var hasImplementation = function(sApiId, sObjName, sFnName){ - if(typeof(apis[sApiId]) == ''undefined'') { - throw ''API '' + sApiId + '' not loaded. Are you missing a script tag?''; + getStyle: function(el, prop) { + var y; + if (el.currentStyle) { + y = el.currentStyle[prop]; } - if(typeof(apis[sApiId][sObjName]) == ''undefined'') { - throw ''Object definition '' + sObjName + '' in API '' + sApiId + '' not loaded. Are you missing a script tag?''; + else if (window.getComputedStyle) { + y = window.getComputedStyle( el, '''').getPropertyValue(prop); } - return typeof(apis[sApiId][sObjName][sFnName]) == ''function''; - }; - - return { + return y; + }, - /** - * Registers a set of provider specific implementation functions. - */ - register: function(sApiId, oApiImpl){ - if(!apis.hasOwnProperty(sApiId)) apis[sApiId] = {}; - mxn.util.merge(apis[sApiId], oApiImpl); - }, - - /** - * Adds a list of named proxy methods to the prototype of a - * specified constructor function. - * @param {Function} func Constructor function to add methods to - * @param {Array} aryMethods Array of method names to create - * @param {Boolean} bWithApiArg Optional. Whether the proxy methods will use an API argument - */ - addProxyMethods: function(func, aryMethods, bWithApiArg){ - for(var i = 0; i < aryMethods.length; i++) { - var sMethodName = aryMethods[i]; - if(bWithApiArg){ - func.prototype[sMethodName] = new Function(''return this.invoker.go(\'''' + sMethodName + ''\'', arguments, { overrideApi: true } );''); - } - else { - func.prototype[sMethodName] = new Function(''return this.invoker.go(\'''' + sMethodName + ''\'', arguments);''); - } - } - }, - - /* - checkLoad: function(funcDetails){ - if(this.loaded[this.api] === false) { - var scope = this; - this.onload[this.api].push( function() { funcDetails.callee.apply(scope, funcDetails); } ); - return true; - } - return false; - }, - */ - - /** - * Bulk add some named events to an object. - */ - addEvents: function(oEvtSrc, aEvtNames){ - for(var i = 0; i < aEvtNames.length; i++){ - var sEvtName = aEvtNames[i]; - if(sEvtName in oEvtSrc) throw ''Event or method '' + sEvtName + '' already declared.''; - oEvtSrc[sEvtName] = new mxn.Event(sEvtName, oEvtSrc); - } - }, - - /** - * Event - * @constructor - */ - Event: function(sEvtName, oEvtSource){ - var handlers = []; - if(!sEvtName) throw ''Event name must be provided''; - this.addHandler = function(fn, ctx){ - handlers.push({context: ctx, handler: fn}); - }; - this.removeHandler = function(fn, ctx){ - for(var i = 0; i < handlers.length; i++){ - if(handlers[i].handler == fn && handlers[i].context == ctx){ - handlers.splice(i, 1); - } - } - }; - this.removeAllHandlers = function(){ - handlers = []; - }; - this.fire = function(oEvtArgs){ - var args = [sEvtName, oEvtSource, oEvtArgs]; - for(var i = 0; i < handlers.length; i++){ - handlers[i].handler.apply(handlers[i].context, args); - } - } - }, - - /** - * Creates a new Invoker, a class which helps with on-the-fly - * invocation of the correct API methods. - * @constructor - * @param {Object} aobj The core object whose methods will make cals to go() - * @param {String} asClassName The name of the Mapstraction class to be invoked, normally the same name as aobj''s constructor function - * @param {Function} afnApiIdGetter The function on object aobj which will return the active API ID - */ - Invoker: function(aobj, asClassName, afnApiIdGetter){ - var obj = aobj; - var sClassName = asClassName; - var fnApiIdGetter = afnApiIdGetter; - var defOpts = { - overrideApi: false, // {Boolean} API ID is overridden by value in first argument - context: null, // {Object} Local vars can be passed from the body of the method to the API method within this object - fallback: null // {Function} If an API implementation doesn''t exist this function is run instead - }; - - /** - * Invoke the API implementation of a specific method. - * @param {String} sMethodName The method name to invoke - * @param {Array} args Arguments to pass on - * @param {String} oOptions Optional. Extra options for invocation - */ - this.go = function(sMethodName, args, oOptions){ - - if(typeof(oOptions) == ''undefined''){ - oOptions = defOpts; - } - - var sApiId = oOptions.overrideApi ? args[0] : fnApiIdGetter.apply(obj); - - if(typeof(sApiId) != ''string'') - throw ''API ID not available.''; - - if(typeof(oOptions.context) != ''undefined'' && oOptions.context !== null){ - // make sure args is an array - args = Array.prototype.slice.apply(args); - args.push(oOptions.context); - } - - if(typeof(oOptions.fallback) == ''function'' && !hasImplementation(sApiId, sClassName, sMethodName)){ - // we''ve got no implementation but have got a fallback function - return oOptions.fallback.apply(obj, args); - } - else { - return invoke(sApiId, sClassName, sMethodName, obj, args); - } - - }; - - }, - - util: { - - /** - * Merges properties of one object into another recursively. - * @param {Object} oRecv The object receiveing properties - * @param {Object} oGive The object donating properties - */ - merge: function(oRecv, oGive){ - for (var sPropName in oGive) if (oGive.hasOwnProperty(sPropName)) { - if(!oRecv.hasOwnProperty(sPropName)){ - oRecv[sPropName] = oGive[sPropName]; - } - else { - mxn.util.merge(oRecv[sPropName], oGive[sPropName]); - } - } - }, - - /** - * $m, the dollar function, elegantising getElementById() - * @return An HTML element or array of HTML elements - */ - $m: function() { - var elements = []; - for (var i = 0; i < arguments.length; i++) { - var element = arguments[i]; - if (typeof(element) == ''string'') { - element = document.getElementById(element); - } - if (arguments.length == 1) { - return element; - } - elements.push(element); - } - return elements; - }, - - /** - * loadScript is a JSON data fetcher - * @param {String} src URL to JSON file - * @param {Function} callback Callback function - */ - loadScript: loadScript, - - /** - * - * @param {Object} point - * @param {Object} level - */ - convertLatLonXY_Yahoo: function(point, level) { //Mercator - var size = 1 << (26 - level); - var pixel_per_degree = size / 360.0; - var pixel_per_radian = size / (2 * Math.PI); - var origin = new YCoordPoint(size / 2 , size / 2); - var answer = new YCoordPoint(); - answer.x = Math.floor(origin.x + point.lon * pixel_per_degree); - var sin = Math.sin(point.lat * Math.PI / 180.0); - answer.y = Math.floor(origin.y + 0.5 * Math.log((1 + sin) / (1 - sin)) * -pixel_per_radian); - return answer; - }, - - /** - * Load a stylesheet from a remote file. - * @param {String} href URL to the CSS file - */ - loadStyle: function(href) { - var link = document.createElement(''link''); - link.type = ''text/css''; - link.rel = ''stylesheet''; - link.href = href; - document.getElementsByTagName(''head'')[0].appendChild(link); - return; - }, - - /** - * getStyle provides cross-browser access to css - * @param {Object} el HTML Element - * @param {String} prop Style property name - */ - getStyle: function(el, prop) { - var y; - if (el.currentStyle) { - y = el.currentStyle[prop]; - } - else if (window.getComputedStyle) { - y = window.getComputedStyle( el, '''').getPropertyValue(prop); - } - return y; - }, - - /** - * Convert longitude to metres - * http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.HTM - * "A degree of longitude at the equator is 111.2km... For other latitudes, - * multiply by cos(lat)" - * assumes the earth is a sphere but good enough for our purposes - * @param {Float} lon - * @param {Float} lat - */ - lonToMetres: function(lon, lat) { - return lon * (111200 * Math.cos(lat * (Math.PI / 180))); - }, - - /** - * Convert metres to longitude - * @param {Object} m - * @param {Object} lat - */ - metresToLon: function(m, lat) { - return m / (111200 * Math.cos(lat * (Math.PI / 180))); - }, - - /** - * Convert kilometres to miles - * @param {Float} km - * @returns {Float} miles - */ - KMToMiles: function(km) { - return km / 1.609344; - }, - - /** - * Convert miles to kilometres - * @param {Float} miles - * @returns {Float} km - */ - milesToKM: function(miles) { - return miles * 1.609344; - }, - - // stuff to convert google zoom levels to/from degrees - // assumes zoom 0 = 256 pixels = 360 degrees - // zoom 1 = 256 pixels = 180 degrees - // etc. - - /** - * - * @param {Object} pixels - * @param {Object} zoom - */ - getDegreesFromGoogleZoomLevel: function(pixels, zoom) { - return (360 * pixels) / (Math.pow(2, zoom + 8)); - }, - - /** - * - * @param {Object} pixels - * @param {Object} degrees - */ - getGoogleZoomLevelFromDegrees: function(pixels, degrees) { - return mxn.util.logN((360 * pixels) / degrees, 2) - 8; - }, - - /** - * - * @param {Object} number - * @param {Object} base - */ - logN: function(number, base) { - return Math.log(number) / Math.log(base); - }, + /** + * Convert longitude to metres + * http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.HTM + * "A degree of longitude at the equator is 111.2km... For other latitudes, + * multiply by cos(lat)" + * assumes the earth is a sphere but good enough for our purposes + * @param {Float} lon + * @param {Float} lat + */ + lonToMetres: function(lon, lat) { + return lon * (111200 * Math.cos(lat * (Math.PI / 180))); + }, + + /** + * Convert metres to longitude + * @param {Object} m + * @param {Object} lat + */ + metresToLon: function(m, lat) { + return m / (111200 * Math.cos(lat * (Math.PI / 180))); + }, + + /** + * Convert kilometres to miles + * @param {Float} km + * @returns {Float} miles + */ + KMToMiles: function(km) { + return km / 1.609344; + }, + + /** + * Convert miles to kilometres + * @param {Float} miles + * @returns {Float} km + */ + milesToKM: function(miles) { + return miles * 1.609344; + }, + + // stuff to convert google zoom levels to/from degrees + // assumes zoom 0 = 256 pixels = 360 degrees + // zoom 1 = 256 pixels = 180 degrees + // etc. + + /** + * + * @param {Object} pixels + * @param {Object} zoom + */ + getDegreesFromGoogleZoomLevel: function(pixels, zoom) { + return (360 * pixels) / (Math.pow(2, zoom + 8)); + }, + + /** + * + * @param {Object} pixels + * @param {Object} degrees + */ + getGoogleZoomLevelFromDegrees: function(pixels, degrees) { + return mxn.util.logN((360 * pixels) / degrees, 2) - 8; + }, + + /** + * + * @param {Object} number + * @param {Object} base + */ + logN: function(number, base) { + return Math.log(number) / Math.log(base); + }, - /** - * returns array of loaded provider apis - * @returns {Array} providers - */ - getAvailableProviders : function () { - var providers = []; - for (var propertyName in apis) providers.push(propertyName); - return providers; - }, - - dummy: 0 + /** + * Returns array of loaded provider apis + * @returns {Array} providers + */ + getAvailableProviders : function () { + var providers = []; + for (var propertyName in apis) providers.push(propertyName); + return providers; + } + +}; - }, - - dummy: 0 - }; - -})(); \ No newline at end of file +mxn.util.Color = function() { + if(arguments.length == 3) { + this.red = arguments[0]; + this.green = arguments[1]; + this.blue = arguments[2]; + } + else if(arguments.length == 1) { + this.setHexColor(arguments[0]); + } +}; + +mxn.util.Color.prototype.reHex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; + +mxn.util.Color.prototype.setHexColor = function(strHexColor) { + var match = strHexColor.match(this.reHex); + if(match) { + strHexColor = match[1]; + } + else { + throw ''Invalid HEX color format, expected #000, 000, #000000 or 000000''; + } + if(strHexColor.length == 3) { + strHexColor = strHexColor.replace(/\w/g, function(str){return str.concat(str);}); + } + this.red = parseInt(strHexColor.substr(0,2), 16); + this.green = parseInt(strHexColor.substr(2,2), 16); + this.blue = parseInt(strHexColor.substr(4,2), 16); +}; + +mxn.util.Color.prototype.getHexColor = function() { + var vals = [this.red.toString(16), this.green.toString(16), this.blue.toString(16)]; + for(var i = 0; i < vals.length; i++) { + vals[i] = (vals[i].length == 1) ? ''0'' + vals[i] : vals[i]; + vals[i] = vals[i].toUpperCase(); + } + return vals.join(''''); +}; + +})(); + + +// Auto-load scripts +(function() { + // Defaults + var providers = ''google,yahoo,microsoft''; + var modules = ''core''; + var scriptBase; + var scripts = document.getElementsByTagName(''script''); + + for (var i = 0; i < scripts.length; i++) { + var match = scripts[i].src.replace(/%20/g , '''').match(/^(.*?)mxn\.js(\?\(\[?(.*?)\]?\))?$/); + if (match != null) { + scriptBase = match[1]; + if (match[3]) { + var settings = match[3].split('',[''); + providers = settings[0].replace('']'' , ''''); + if (settings[1]) modules = settings[1]; + } + break; + } + } + providers = providers.replace(/ /g, '''').split('',''); + modules = modules.replace(/ /g, '''').split('',''); + for (var i = 0; i < modules.length; i++) { + mxn.util.loadScript(scriptBase + ''mxn.'' + modules[i] + ''.js''); + for (var j = 0; j < providers.length; j++) mxn.util.loadScript(scriptBase + ''mxn.'' + providers[j] + ''.'' + modules[i] + ''.js''); + } +})(); Modified: trunk/source/mxn.microsoft.core.js =============================================================================--- trunk/source/mxn.microsoft.core.js (original) +++ trunk/source/mxn.microsoft.core.js Sun May 31 17:34:50 2009 @@ -360,11 +360,6 @@ Polyline: { toProprietary: function() { - var to255Color = function(color){ - this.green = parseInt(color.substr(1,2), 16); - this.red = parseInt(color.substr(3,4), 16); - this.blue = parseInt(color.substr(5,6), 16); - }; var mpoints =[]; for(var i =0, length = this.points.length; i < length; i++) { @@ -372,12 +367,13 @@ } var mpolyline = new VEShape(VEShapeType.Polyline, mpoints); if(this.color){ - var vecolor = new to255Color(this.color); - mpolyline.SetLineColor(new VEColor(vecolor.red, vecolor.green, vecolor.blue, this.opacity)); + var color = new mxn.util.Color(this.color); + var opacity = (typeof(this.opacity) == ''undefined'' || this.opacity === null) ? 1.0 : this.opacity; + var vecolor = new VEColor(color.red, color.green, color.blue, opacity); + mpolyline.SetLineColor(vecolor); } - // TODO ability to change line width + // TODO ability to change line width return mpolyline; - }, show: function() { Modified: trunk/source/mxn.yahoo.core.js =============================================================================--- trunk/source/mxn.yahoo.core.js (original) +++ trunk/source/mxn.yahoo.core.js Sun May 31 17:34:50 2009 @@ -49,6 +49,9 @@ map.addPanControl(); } else { + // Yahoo doesn''t check the pan control is there before trying to remove it + // so throws an exception :( + map.addPanControl(); map.removePanControl(); } Modified: trunk/tests/index.htm =============================================================================--- trunk/tests/index.htm (original) +++ trunk/tests/index.htm Sun May 31 17:34:50 2009 @@ -40,7 +40,7 @@ m.endPan.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ var center = oEvtSource.getCenter(); - eventsElm.innerHTML += ''Map pan: '' + center.toString() + ''<br/>''; + eventsElm.innerHTML += ''Map pan: ('' + center.lat.toFixed(5) + '',''+ center.lon.toFixed(5) +'')<br/>''; }); m.changeZoom.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ @@ -53,7 +53,7 @@ }); m.click.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ - eventsElm.innerHTML += ''Map clicked: '' + oEvtArgs.location.toString() + ''<br/>''; + eventsElm.innerHTML += ''Map clicked: ('' + oEvtArgs.location.lat.toFixed(5) + '',''+ oEvtArgs.location.lon.toFixed(5) +'')<br/>''; }); var markerEventHandler = function(sEvtName, oEvtSource, oEvtArgs){ @@ -126,13 +126,14 @@ new mxn.LatLonPoint(38.3419, -119.0419), new mxn.LatLonPoint(37.3419, -117.0419) ]); + pl.color = ''#00DD55''; m.addPolyline(pl); } }, { desc: ''Swap API'', action: function(){ - m.swap(''map'', ''microsoft''); + m.swap(''map'', ''yahoo''); } }, @@ -176,13 +177,49 @@ //]]> </script> + <style type="text/css"> + .box { + float: left; + width:300px; + margin-right: 20px; + border: 1px solid #AAA; + } + + .box h2 { + margin: 0; + padding: 5px; + font-family: Arial; + background-color: #DDD; + } + + .box div { + overflow-y: scroll; + height:300px; + } + </style> </head> <body> - <div id="map" style="float: left; width:500px;height:300px"></div> - <div id="info" style="float: left; width:300px; height:300px; margin-left: 20px; background-color: #DDD;"></div> - <ol id="actions" style="clear: left; float: left;"> - </ol> - <div id="events" style="float: left; width:300px; height:300px; overflow-y: scroll; margin-left: 20px; background-color: #DDD;"></div> + <div style="margin: 20px;"> + <div id="map" style="position: relative; width: 500px; height: 300px;"></div> + <div style="margin-top: 20px;"> + + <div class="box"> + <h2>Actions</h2> + <div> + <ol id="actions"></ol> + </div> + </div> + <div class="box"> + <h2>Info</h2> + <div id="info"></div> + </div> + <div class="box"> + <h2>Events</h2> + <div id="events"></div> + </div> + + </div> + </div> </body> </html>