codesite-noreply at google.com
2009-May-26 00:21 UTC
[Mapstraction] [mapstraction commit] r5 - * Altered Invoker.go() to accept an options hash as the third argument. Property of this is ...
Author: dezfowler Date: Mon May 25 17:20:12 2009 New Revision: 5 Modified: trunk/source/mxn.core.js trunk/source/mxn.google.core.js trunk/source/mxn.js trunk/source/mxn.yahoo.core.js trunk/tests/index.htm Log: * Altered Invoker.go() to accept an options hash as the third argument. Property of this is fallback which, if set to a function, will be called in the event that a provider implementation is not found. * Fixed Yahoo polyline * Added map and marker events for google and yahoo * Added event handling for new events to tests/index.htm Modified: trunk/source/mxn.core.js =============================================================================--- trunk/source/mxn.core.js (original) +++ trunk/source/mxn.core.js Mon May 25 17:20:12 2009 @@ -8,6 +8,7 @@ */ var init = function() { this.invoker.go(''init'', [ this.currentElement, this.api ]); + this.applyOptions(); }; /** @@ -38,9 +39,17 @@ // set up our invoker for calling API methods this.invoker = new mxn.Invoker(this, ''Mapstraction'', function(){ return this.api; }); - - // TODO: Events - mxn.addEvents(this, [''load'', ''endPan'', ''markerAdded'', ''markerRemoved'', ''polylineAdded'', ''polylineRemoved'']); + + mxn.addEvents(this, [ + ''load'', // Map has loaded + ''click'', // Map is clicked {location: LatLonPoint} + ''endPan'', // Map is panned + ''changeZoom'', // Zoom is changed + ''markerAdded'', // Marker is removed {marker: Marker} + ''markerRemoved'', // Marker is removed {marker: Marker} + ''polylineAdded'', // Polyline is added {polyline: Polyline} + ''polylineRemoved'' // Polyline is removed {polyline: Polyline} + ]); // finally initialize our proper API map init.apply(this); @@ -63,7 +72,7 @@ ]); Mapstraction.prototype.setOptions = function(oOpts){ - mxn.merge(this.options, oOpts); + mxn.util.merge(this.options, oOpts); this.applyOptions(); }; @@ -304,7 +313,7 @@ this.invoker.go(''removeMarker'', arguments); marker.onmap = false; this.markers.splice(i, 1); - this.markerRemoved.fire(marker); + this.markerRemoved.fire({''marker'': marker}); break; } } @@ -388,13 +397,13 @@ if(!old) { this.polylines.push(polyline); } - this.polylineAdded.fire(polyline); + this.polylineAdded.fire({''polyline'': polyline}); }; Mapstraction.prototype.removePolylineImpl = function(polyline) { this.invoker.go(''removePolyline'', arguments); polyline.onmap = false; - this.polylineRemoved.fire(polyline); + this.polylineRemoved.fire({''polyline'': polyline}); }; /** @@ -589,7 +598,7 @@ imgElm: b }; - this.invoker.go(''addImageOverlay'', arguments, false, oContext); + this.invoker.go(''addImageOverlay'', arguments, { context: oContext }); }; Mapstraction.prototype.setImageOpacity = function(id, opacity) { @@ -627,7 +636,7 @@ pixels: { top: 0, right: 0, bottom: 0, left: 0 } }; - this.invoker.go(''setImagePosition'', arguments, false, oContext); + this.invoker.go(''setImagePosition'', arguments, { context: oContext }); imgElement.style.top = oContext.pixels.top.toString() + ''px''; imgElement.style.left = oContext.pixels.left.toString() + ''px''; @@ -1117,7 +1126,11 @@ this.attributes = []; this.pinID = "mspin-"+new Date().getTime()+''-''+(Math.floor(Math.random()*Math.pow(2,16))); this.invoker = new mxn.Invoker(this, ''Marker'', function(){return this.api;}); - mxn.addEvents(this, [ ''infoBubbleOpenned'', ''markerClicked'']); + mxn.addEvents(this, [ + ''openInfoBubble'', // Info bubble opened + ''closeInfoBubble'', // Info bubble closed + ''click'' // Marker clicked + ]); } mxn.addProxyMethods(Marker, [ @@ -1131,6 +1144,7 @@ Marker.prototype.setChild = function(some_proprietary_marker) { this.proprietary_marker = some_proprietary_marker; + some_proprietary_marker.mapstraction_marker = this; this.onmap = true; }; Modified: trunk/source/mxn.google.core.js =============================================================================--- trunk/source/mxn.google.core.js (original) +++ trunk/source/mxn.google.core.js Mon May 25 17:20:12 2009 @@ -9,20 +9,32 @@ this.maps[api] = new GMap2(element); GEvent.addListener(this.maps[api], ''click'', function(marker,location) { + + if ( marker && marker.mapstraction_marker ) { + marker.mapstraction_marker.click.fire(); + } + else if ( location ) { + me.click.fire({''location'': new mxn.LatLonPoint(location.y, location.x)}); + } + // If the user puts their own Google markers directly on the map // then there is no location and this event should not fire. if ( location ) { me.clickHandler(location.y,location.x,location,me); - } }); GEvent.addListener(this.maps[api], ''moveend'', function() { me.moveendHandler(me); - var point = me.getCenter(); - me.endPan.fire({center: point}); + me.endPan.fire(); }); + + GEvent.addListener(this.maps[api], ''zoomend'', function() { + me.changeZoom.fire(); + }); + this.loaded[api] = true; + me.load.fire(); } else { alert(''browser not compatible with Google Maps''); @@ -126,6 +138,14 @@ var map = this.maps[this.api]; var gpin = marker.toProprietary(this.api); map.addOverlay(gpin); + + GEvent.addListener(gpin, ''infowindowopen'', function() { + marker.openInfoBubble.fire(); + }); + GEvent.addListener(gpin, ''infowindowclose'', function() { + marker.closeInfoBubble.fire(); + }); + return gpin; }, @@ -398,7 +418,7 @@ options.draggable = this.draggable; } var gmarker = new GMarker( this.location.toProprietary(''google''),options); - + if(this.infoBubble){ var theInfo = this.infoBubble; var event_action; Modified: trunk/source/mxn.js =============================================================================--- trunk/source/mxn.js (original) +++ trunk/source/mxn.js Mon May 25 17:20:12 2009 @@ -3,6 +3,31 @@ // 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''; + }; + return { /** @@ -10,24 +35,8 @@ */ register: function(sApiId, oApiImpl){ if(!apis.hasOwnProperty(sApiId)) apis[sApiId] = {}; - mxn.merge(apis[sApiId], oApiImpl); - }, - - /** - * 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.merge(oRecv[sPropName], oGive[sPropName]); - } - } - }, + mxn.util.merge(apis[sApiId], oApiImpl); + }, /** * Adds a list of named proxy methods to the prototype of a @@ -40,7 +49,7 @@ 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, true);''); + 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);''); @@ -59,25 +68,6 @@ }, */ - - /** - * Calls the API specific implementation of a particular method - */ - invoke: function(sApiId, sObjName, sFnName, oScope, args){ - 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?''; - } - - if(typeof(apis[sApiId][sObjName][sFnName]) == ''undefined'') { - 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); - }, - /** * Bulk add some named events to an object. */ @@ -119,7 +109,7 @@ /** * Creates a new Invoker, a class which helps with on-the-fly - * invokation of the correct API methods. + * 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 @@ -129,32 +119,65 @@ 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 + }; /** - * Change the current api on the fly - * @param {String} sMethodName The API to swap to + * 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} bApi Optional. API ID is overridden by value in first argument. - * @param {Object} oContext Optional. Local vars can be passed from the body of the method to the API method within this object. + * @param {String} oOptions Optional. Extra options for invocation */ - this.go = function(sMethodName, args, bApi, oContext){ - var sApiId = bApi ? args[0] : fnApiIdGetter.apply(obj); - if(typeof(sApiId) == ''string''){ - if(typeof(oContext) != ''undefined''){ - // make sure args is an array - args = Array.prototype.slice.apply(args); - args.push(oContext); - } - return mxn.invoke(sApiId, sClassName, sMethodName, obj, args); + this.go = function(sMethodName, args, oOptions){ + + if(typeof(oOptions) == ''undefined''){ + oOptions = defOpts; } - else{ + + 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 @@ -310,7 +333,9 @@ */ logN: function(number, base) { return Math.log(number) / Math.log(base); - } + }, + + dummy: 0 }, Modified: trunk/source/mxn.yahoo.core.js =============================================================================--- trunk/source/mxn.yahoo.core.js (original) +++ trunk/source/mxn.yahoo.core.js Mon May 25 17:20:12 2009 @@ -9,14 +9,22 @@ YEvent.Capture(this.maps[api], EventsList.MouseClick, function(event,location) { me.clickHandler(location.Lat, location.Lon, location, me); + me.click.fire({''location'': new mxn.LatLonPoint(location.Lat, location.Lon)}); }); YEvent.Capture(this.maps[api], EventsList.changeZoom, function() { me.moveendHandler(me); + me.changeZoom.fire(); }); YEvent.Capture(this.maps[api], EventsList.endPan, function() { me.moveendHandler(me); + me.endPan.fire(); }); + YEvent.Capture(this.maps[api], EventsList.endAutoPan, function() { + me.endPan.fire(); + }); + this.loaded[api] = true; + me.load.fire(); } else { alert(api + '' map script not imported''); @@ -97,6 +105,15 @@ var map = this.maps[this.api]; var pin = marker.toProprietary(this.api); map.addOverlay(pin); + YEvent.Capture(pin, EventsList.MouseClick, function() { + marker.click.fire(); + }); + YEvent.Capture(pin, EventsList.openSmartWindow, function() { + marker.openInfoBubble.fire(); + }); + YEvent.Capture(pin, EventsList.closeSmartWindow, function() { + marker.closeInfoBubble.fire(); + }); return pin; }, @@ -341,17 +358,14 @@ Polyline: { - toProprietary: function() { - var gpoints = []; - for (var i = 0, length = this.points.length ; i< length; i++){ - gpoints.push(this.points[i].toProprietary(''google'')); - } - if (this.closed || gpoints[0].equals(gpoints[length-1])) { - var gpoly = new GPolygon(gpoints, this.color, this.width, this.opacity, this.fillColor || "#5462E3", this.opacity || "0.3"); - } else { - var gpoly = new GPolyline(gpoints, this.color, this.width, this.opacity); - } - return gpoly; + toProprietary: function() { + var ypolyline; + var ypoints = []; + for (var i = 0, length = this.points.length ; i< length; i++){ + ypoints.push(this.points[i].toProprietary(''yahoo'')); + } + ypolyline = new YPolyline(ypoints,this.color,this.width,this.opacity); + return ypolyline; }, show: function() { Modified: trunk/tests/index.htm =============================================================================--- trunk/tests/index.htm (original) +++ trunk/tests/index.htm Mon May 25 17:20:12 2009 @@ -41,13 +41,27 @@ var m = new mxn.Mapstraction(''map'', ''yahoo''); m.endPan.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ - eventsElm.innerHTML += ''Map move: '' + oEvtArgs.center.toString() + ''<br/>''; + var center = oEvtSource.getCenter(); + eventsElm.innerHTML += ''Map pan: '' + center.toString() + ''<br/>''; + }); + + m.changeZoom.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ + var zoom = oEvtSource.getZoom(); + eventsElm.innerHTML += ''Change zoom: '' + zoom.toString() + ''<br/>''; }); m.markerAdded.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ eventsElm.innerHTML += ''Marker added: '' + oEvtArgs.marker.labelText + ''<br/>''; }); + m.click.addHandler(function(sEvtName, oEvtSource, oEvtArgs){ + eventsElm.innerHTML += ''Map clicked: '' + oEvtArgs.location.toString() + ''<br/>''; + }); + + var markerEventHandler = function(sEvtName, oEvtSource, oEvtArgs){ + eventsElm.innerHTML += ''Marker event: '' + sEvtName + '' - '' + oEvtSource.labelText + ''<br/>''; + }; + var ops = [ { desc: ''Center map'', @@ -69,7 +83,6 @@ infoElm.innerHTML += ''Bounds:<br/>SW('' + bb.sw.lat.toFixed(5) + '',''+ bb.sw.lon.toFixed(5) +'')<br/>NE('' + bb.ne.lat.toFixed(5) + '',''+ bb.ne.lon.toFixed(5) +'')<br/>''; var ll = m.getCenter(); infoElm.innerHTML += ''Center: ('' + ll.lat.toFixed(5) + '',''+ ll.lon.toFixed(5) +'')<br/>''; - infoElm.innerHTML += ''Map type: '' + m.getMapType() + ''<br/>''; infoElm.innerHTML += ''Zoom: '' + m.getZoom() + ''<br/>''; } @@ -86,6 +99,9 @@ var mkr = new mxn.Marker(new mxn.LatLonPoint(37.3419, -122.0419)); mkr.setLabel(''Some random place''); mkr.setInfoBubble(''Some information about the random place''); + mkr.click.addHandler(markerEventHandler); + mkr.openInfoBubble.addHandler(markerEventHandler); + mkr.closeInfoBubble.addHandler(markerEventHandler); m.addMarker(mkr); } },