fckplugin.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. /*
  2. GoogleMaps Plugin for FCKeditor
  3. Dialog plugin to handle insertion and modification of Google Maps in FCKeditor
  4. File Author:
  5. Alfonso Martinez de Lizarrondo amla70 at gmail dot com
  6. version 1.98
  7. See readme.html
  8. */
  9. // Check that the Google key is defined
  10. if ( typeof( FCKConfig.GoogleMaps_Key ) != 'string')
  11. {
  12. alert( 'Error.\r\nThe configuration doesn\'t contain the Google Maps key.\r\n' +
  13. 'Please read the Configuration section.') ;
  14. window.open(FCKPlugins.Items['googlemaps'].Path + 'docs/' + FCKLang.GMapsHelpFile + '#configure');
  15. }
  16. // If it's empty automatically remove the button from any toolbar.
  17. if ( !FCKConfig.GoogleMaps_Key || FCKConfig.GoogleMaps_Key.length === 0)
  18. {
  19. for( var name in FCKConfig.ToolbarSets )
  20. RemoveButtonFromToolbarSet( FCKConfig.ToolbarSets[name], 'googlemaps' ) ;
  21. }
  22. /**
  23. Helper function
  24. It does remove a button from an toolbarset.
  25. It's better than leaving it disabled as it will avoid questions about why some button is always disabled.
  26. */
  27. function RemoveButtonFromToolbarSet(ToolbarSet, CommandName)
  28. {
  29. if (!ToolbarSet)
  30. return;
  31. for ( var x = 0 ; x < ToolbarSet.length ; x++ )
  32. {
  33. var oToolbarItems = ToolbarSet[x] ;
  34. // If the configuration for the toolbar is missing some element or has any extra comma
  35. // this item won't be valid, so skip it and keep on processing.
  36. if ( !oToolbarItems )
  37. continue ;
  38. if ( typeof( oToolbarItems ) == 'object' )
  39. {
  40. for ( var j = 0 ; j < oToolbarItems.length ; j++ )
  41. {
  42. if ( oToolbarItems[j] == CommandName)
  43. {
  44. oToolbarItems.splice(j, 1);
  45. ToolbarSet[x] = oToolbarItems ;
  46. return;
  47. }
  48. }
  49. }
  50. }
  51. }
  52. // Toolbar button
  53. // Register the related command.
  54. FCKCommands.RegisterCommand( 'googlemaps', new FCKDialogCommand( 'googlemaps', FCKLang.DlgGMapsTitle, FCKPlugins.Items['googlemaps'].Path + 'dialog/googleMaps.html', 450, 428 ) ) ;
  55. // Create the "googlemaps" toolbar button.
  56. var oGoogleMapsButton = new FCKToolbarButton( 'googlemaps', FCKLang.GMapsBtn, FCKLang.GMapsBtnTooltip) ;
  57. oGoogleMapsButton.IconPath = FCKPlugins.Items['googlemaps'].Path + 'images/mapIcon.gif' ;
  58. FCKToolbarItems.RegisterItem( 'googlemaps', oGoogleMapsButton ) ;
  59. // Detection of existing maps
  60. /**
  61. FCKCommentsProcessor
  62. ---------------------------
  63. It's run after a document has been loaded, it detects all the protected source elements
  64. In order to use it, you add your comment parser with
  65. FCKCommentsProcessor.AddParser( function )
  66. */
  67. if (typeof FCKCommentsProcessor === 'undefined')
  68. {
  69. var FCKCommentsProcessor = FCKDocumentProcessor.AppendNew() ;
  70. FCKCommentsProcessor.ProcessDocument = function( oDoc )
  71. {
  72. if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
  73. return ;
  74. if ( !oDoc )
  75. return ;
  76. //Find all the comments: <!--{PS..0}-->
  77. //try to choose the best approach according to the browser:
  78. if ( oDoc.evaluate )
  79. this.findCommentsXPath( oDoc );
  80. else
  81. {
  82. if (oDoc.all)
  83. this.findCommentsIE( oDoc.body ) ;
  84. else
  85. this.findComments( oDoc.body ) ;
  86. }
  87. }
  88. FCKCommentsProcessor.findCommentsXPath = function(oDoc) {
  89. var nodesSnapshot = oDoc.evaluate('//body//comment()', oDoc.body, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
  90. for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
  91. {
  92. this.parseComment( nodesSnapshot.snapshotItem(i) ) ;
  93. }
  94. }
  95. FCKCommentsProcessor.findCommentsIE = function(oNode) {
  96. var aComments = oNode.getElementsByTagName( '!' );
  97. for(var i=aComments.length-1; i >=0 ; i--)
  98. {
  99. var comment = aComments[i] ;
  100. if (comment.nodeType == 8 ) // oNode.COMMENT_NODE)
  101. this.parseComment( comment ) ;
  102. }
  103. }
  104. // Fallback function, iterate all the nodes and its children searching for comments.
  105. FCKCommentsProcessor.findComments = function( oNode )
  106. {
  107. if (oNode.nodeType == 8 ) // oNode.COMMENT_NODE)
  108. {
  109. this.parseComment( oNode ) ;
  110. }
  111. else
  112. {
  113. if (oNode.hasChildNodes())
  114. {
  115. var children = oNode.childNodes ;
  116. for (var i = children.length-1; i >=0 ; i--)
  117. this.findComments( children[ i ] );
  118. }
  119. }
  120. }
  121. // We get a comment node
  122. // Check that it's one that we are interested on:
  123. FCKCommentsProcessor.parseComment = function( oNode )
  124. {
  125. var value = oNode.nodeValue ;
  126. // Difference between 2.4.3 and 2.5
  127. var prefix = ( FCKConfig.ProtectedSource._CodeTag || 'PS\\.\\.' ) ;
  128. var regex = new RegExp( "\\{" + prefix + "(\\d+)\\}", "g" ) ;
  129. if ( regex.test( value ) )
  130. {
  131. var index = RegExp.$1 ;
  132. var content = FCKTempBin.Elements[ index ] ;
  133. // Now call the registered parser handlers.
  134. var oCalls = this.ParserHandlers ;
  135. if ( oCalls )
  136. {
  137. for ( var i = 0 ; i < oCalls.length ; i++ )
  138. oCalls[ i ]( oNode, content, index ) ;
  139. }
  140. }
  141. }
  142. /**
  143. The users of the object will add a parser here, the callback function gets two parameters:
  144. oNode: it's the node in the editorDocument that holds the position of our content
  145. oContent: it's the node (removed from the document) that holds the original contents
  146. index: the reference in the FCKTempBin of our content
  147. */
  148. FCKCommentsProcessor.AddParser = function( handlerFunction )
  149. {
  150. if ( !this.ParserHandlers )
  151. this.ParserHandlers = [ handlerFunction ] ;
  152. else
  153. {
  154. // Check that the event handler isn't already registered with the same listener
  155. // It doesn't detect function pointers belonging to an object (at least in Gecko)
  156. if ( this.ParserHandlers.IndexOf( handlerFunction ) == -1 )
  157. this.ParserHandlers.push( handlerFunction ) ;
  158. }
  159. }
  160. }
  161. /**
  162. END of FCKCommentsProcessor
  163. ---------------------------
  164. */
  165. // Check if the comment it's one of our scripts:
  166. var GoogleMaps_CommentsProcessorParser = function( oNode, oContent, index)
  167. {
  168. if ( FCK.GoogleMapsHandler.detectMapScript( oContent ) )
  169. {
  170. var oMap = FCK.GoogleMapsHandler.createNew() ;
  171. oMap.parse( oContent ) ;
  172. oMap.createHtmlElement( oNode, index ) ;
  173. }
  174. else
  175. {
  176. if ( FCK.GoogleMapsHandler.detectGoogleScript( oContent ) )
  177. oNode.parentNode.removeChild( oNode );
  178. }
  179. }
  180. FCKCommentsProcessor.AddParser( GoogleMaps_CommentsProcessorParser );
  181. // Context menu
  182. FCK.ContextMenu.RegisterListener( {
  183. AddItems : function( menu, tag, tagName )
  184. {
  185. // under what circumstances do we display this option
  186. if ( tagName == 'IMG' && tag.getAttribute( 'MapNumber' ) )
  187. {
  188. // No other options:
  189. menu.RemoveAllItems() ;
  190. // the command needs the registered command name, the title for the context menu, and the icon path
  191. menu.AddItem( 'googlemaps', FCKLang.DlgGMapsTitle, oGoogleMapsButton.IconPath ) ;
  192. }
  193. }}
  194. );
  195. // Double click
  196. FCK.RegisterDoubleClickHandler( editMap, 'IMG' ) ;
  197. function editMap( oNode )
  198. {
  199. if ( !oNode.getAttribute( 'MapNumber' ))
  200. return ;
  201. FCK.Commands.GetCommand( 'googlemaps' ).Execute() ;
  202. }
  203. // Object that handles the common functions about all the maps
  204. FCK.GoogleMapsHandler = {
  205. // Object to store a reference to each map
  206. maps: {},
  207. getMap: function(id){
  208. return this.maps[id];
  209. },
  210. // Verify that the node is a script generated by this plugin.
  211. detectMapScript: function( script )
  212. {
  213. // We only know about version 1:
  214. if ( !(/FCK googlemaps v1\.(\d+)/.test(script)) )
  215. return false;
  216. return true
  217. },
  218. // Self-executed function, we want to run it once at initialization only.
  219. // Public key that will be used for the generated maps,
  220. // while we are editing we will use only FCKConfig.GoogleMaps_Key
  221. publicKey : function() {
  222. // if FCKConfig.GoogleMaps_PublicKey is set to something, then use it
  223. if ( FCKConfig.GoogleMaps_PublicKey )
  224. return FCKConfig.GoogleMaps_PublicKey ;
  225. // else we will use GoogleMaps_Key for both the public and private side.
  226. return FCKConfig.GoogleMaps_Key ;
  227. }(),
  228. // Detects both the google script as well as our ending block
  229. // both must be removed and then added later only if neccesary
  230. detectGoogleScript: function( script )
  231. {
  232. // Our final script
  233. if (/FCK googlemapsEnd v1\./.test(script) )
  234. return true ;
  235. // If it is the Google Maps script, get the public key from here:
  236. if ( !/^<script src="http:\/\/maps\.google\.com\/.*key=(.*?)("|&)/.test(script) )
  237. return false;
  238. this.publicKey = RegExp.$1 ;
  239. return ( true ) ;
  240. },
  241. GenerateGoogleScript : function()
  242. {
  243. return '\r\n<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=' + this.publicKey + '" type="text/javascript" charset="utf-8"></script>' ;
  244. },
  245. // This can be called from the dialog
  246. createNew: function()
  247. {
  248. var map = new FCKGoogleMap() ;
  249. this.maps[ map.number ] = map;
  250. return map;
  251. },
  252. BuildEndingScript: function()
  253. {
  254. var versionMarker = '// FCK googlemapsEnd v1.97';
  255. var aScript = [] ;
  256. aScript.push('\r\n<script type="text/javascript">') ;
  257. aScript.push( versionMarker ) ;
  258. aScript.push('function AddMarkers( map, aPoints )');
  259. aScript.push('{');
  260. aScript.push(' for (var i=0; i<aPoints.length ; i++)');
  261. aScript.push(' {');
  262. aScript.push(' var point = aPoints[i] ;');
  263. aScript.push(' map.addOverlay( createMarker(new GLatLng(point.lat, point.lon), point.text) );');
  264. aScript.push(' }');
  265. aScript.push('}');
  266. aScript.push('function createMarker( point, html )');
  267. aScript.push('{');
  268. aScript.push(' var marker = new GMarker(point);');
  269. aScript.push(' GEvent.addListener(marker, "click", function() {');
  270. aScript.push(' marker.openInfoWindowHtml(html, {maxWidth:200});');
  271. aScript.push(' });');
  272. aScript.push(' return marker;');
  273. aScript.push('}');
  274. var maps = this.CreatedMapsNames ;
  275. for (var i = 0; i < maps.length; i++)
  276. {
  277. // Append event listeners instead of replacing previous ones
  278. aScript.push('if (window.addEventListener) {');
  279. aScript.push(' window.addEventListener("load", CreateGMap' + maps[i] + ', false);');
  280. aScript.push('} else {');
  281. aScript.push(' window.attachEvent("onload", CreateGMap' + maps[i] + ');');
  282. aScript.push('}');
  283. }
  284. aScript.push('onunload = GUnload ;');
  285. aScript.push('</script>');
  286. return aScript.join('\r\n');
  287. },
  288. // We will use this to track the number of maps that are generated
  289. // This way we know if we must add the Google Script or not.
  290. // We store their names so they are called properly from BuildEndingScript
  291. CreatedMapsNames : [],
  292. // Function that will be injected into the normal core
  293. GetXHTMLAfter: function( node, includeNode, format, Result )
  294. {
  295. if (FCK.GoogleMapsHandler.CreatedMapsNames.length > 0)
  296. {
  297. Result += FCK.GoogleMapsHandler.BuildEndingScript() ;
  298. }
  299. // Reset the counter each time the GetXHTML function is called
  300. FCK.GoogleMapsHandler.CreatedMapsNames = [];
  301. return Result ;
  302. },
  303. // Store any previous processor so nothing breaks
  304. previousProcessor: FCKXHtml.TagProcessors[ 'img' ]
  305. }
  306. // Our object that will handle parsing of the script and creating the new one.
  307. var FCKGoogleMap = function()
  308. {
  309. var now = new Date() ;
  310. this.number = '' + now.getFullYear() + now.getMonth() + now.getDate() + now.getHours() + now.getMinutes() + now.getSeconds() ;
  311. this.width = FCKConfig.GoogleMaps_Width || 400 ;
  312. this.height = FCKConfig.GoogleMaps_Height || 240 ;
  313. this.centerLat = FCKConfig.GoogleMaps_CenterLat || 37.4419 ;
  314. this.centerLon = FCKConfig.GoogleMaps_CenterLon || -122.1419 ;
  315. this.zoom = FCKConfig.GoogleMaps_Zoom || 11 ;
  316. this.markerPoints = [] ;
  317. this.LinePoints = '' ;
  318. this.LineLevels = '' ;
  319. this.mapType = 0 ;
  320. this.WrapperClass = FCKConfig.GoogleMaps_WrapperClass || '' ;
  321. }
  322. FCKGoogleMap.prototype.createHtmlElement = function( oReplacedNode, index)
  323. {
  324. var oFakeNode = FCK.EditorDocument.createElement( 'IMG' ) ;
  325. // Are we creating a new map?
  326. if ( !oReplacedNode )
  327. {
  328. index = FCKTempBin.AddElement( this.BuildScript() ) ;
  329. var prefix = ( FCKConfig.ProtectedSource._CodeTag || 'PS..' ) ;
  330. oReplacedNode = FCK.EditorDocument.createComment( '{' + prefix + index + '}' ) ;
  331. FCK.InsertElement(oReplacedNode);
  332. }
  333. oFakeNode.contentEditable = false ;
  334. // oFakeNode.setAttribute( '_fckfakelement', 'true', 0 ) ;
  335. oFakeNode.setAttribute( '_fckrealelement', FCKTempBin.AddElement( oReplacedNode ), 0 ) ;
  336. oFakeNode.setAttribute( '_fckBinNode', index, 0 ) ;
  337. oFakeNode.src = FCKConfig.FullBasePath + 'images/spacer.gif' ;
  338. oFakeNode.style.display = 'block' ;
  339. oFakeNode.style.border = '1px solid black' ;
  340. oFakeNode.style.background = 'white center center url("' + FCKPlugins.Items['googlemaps'].Path + 'images/maps_res_logo.png' + '") no-repeat' ;
  341. oFakeNode.setAttribute("MapNumber", this.number, 0) ;
  342. oReplacedNode.parentNode.insertBefore( oFakeNode, oReplacedNode ) ;
  343. oReplacedNode.parentNode.removeChild( oReplacedNode ) ;
  344. // dimensions
  345. this.updateHTMLElement( oFakeNode );
  346. return oFakeNode ;
  347. }
  348. FCKGoogleMap.prototype.updateScript = function( oFakeNode )
  349. {
  350. this.updateDimensions( oFakeNode ) ;
  351. var index = oFakeNode.getAttribute( '_fckBinNode' );
  352. FCKTempBin.Elements[ index ] = this.BuildScript() ;
  353. }
  354. FCKGoogleMap.prototype.updateHTMLElement = function( oFakeNode )
  355. {
  356. oFakeNode.width = this.width ;
  357. oFakeNode.height = this.height ;
  358. // Static maps preview :-)
  359. oFakeNode.src = this.generateStaticMap() ;
  360. oFakeNode.style.border = 0 ;
  361. // The wrapper class is applied to the IMG not to a wrapping DIV !!!
  362. if ( this.WrapperClass !== '')
  363. oFakeNode.className = this.WrapperClass ;
  364. }
  365. FCKGoogleMap.prototype.generateStaticMap = function()
  366. {
  367. var w = Math.min(this.width, 640);
  368. var h = Math.min(this.height, 640);
  369. var staticMapTypes = ['roadmap', 'satellite', 'hybrid', 'terrain'] ;
  370. return 'http://maps.google.com/staticmap?center=' + this.centerLat + ',' + this.centerLon
  371. + '&zoom=' + this.zoom + '&size=' + w + 'x' + h
  372. + '&maptype=' + staticMapTypes[ this.mapType ]
  373. + this.generateStaticMarkers()
  374. + '&key=' + FCKConfig.GoogleMaps_Key
  375. }
  376. FCKGoogleMap.prototype.generateStaticMarkers = function()
  377. {
  378. if (this.markerPoints.length==0)
  379. return '';
  380. var aPoints = [];
  381. for (var i=0; i<this.markerPoints.length ; i++)
  382. {
  383. var point = this.markerPoints[i] ;
  384. aPoints.push(point.lat + ',' + point.lon);
  385. }
  386. return ('&markers=' + aPoints.join('|') );
  387. }
  388. // Paths: http://code.google.com/p/gmaps-api-issues/issues/detail?id=205
  389. // Read the dimensions back from the fake node (the user might have manually resized it)
  390. FCKGoogleMap.prototype.updateDimensions = function( oFakeNode )
  391. {
  392. var iWidth, iHeight ;
  393. var regexSize = /^\s*(\d+)px\s*$/i ;
  394. if ( oFakeNode.style.width )
  395. {
  396. var aMatchW = oFakeNode.style.width.match( regexSize ) ;
  397. if ( aMatchW )
  398. {
  399. iWidth = aMatchW[1] ;
  400. oFakeNode.style.width = '' ;
  401. oFakeNode.width = iWidth ;
  402. }
  403. }
  404. if ( oFakeNode.style.height )
  405. {
  406. var aMatchH = oFakeNode.style.height.match( regexSize ) ;
  407. if ( aMatchH )
  408. {
  409. iHeight = aMatchH[1] ;
  410. oFakeNode.style.height = '' ;
  411. oFakeNode.height = iHeight ;
  412. }
  413. }
  414. this.width = iWidth ? iWidth : oFakeNode.width ;
  415. this.height = iHeight ? iHeight : oFakeNode.height ;
  416. }
  417. FCKGoogleMap.prototype.decodeText = function(string)
  418. {
  419. return string.replace(/<\\\//g, "</").replace(/\\n/g, "\n").replace(/\\'/g, "'").replace(/\\\\/g, "\\");
  420. }
  421. FCKGoogleMap.prototype.encodeText = function(string)
  422. {
  423. return string.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/<\//g, "<\\/");
  424. }
  425. FCKGoogleMap.prototype.parse = function( script )
  426. {
  427. // We only know about version 1:
  428. if ( !(/FCK googlemaps v1\.(\d+)/.test(script)) )
  429. return false;
  430. var version = parseInt(RegExp.$1, 10) ;
  431. // dimensions:
  432. // document.writeln('<div id="gmap1" style="width: 544px; height: 350px;">.</div>');
  433. var regexpDimensions = /<div id="gmap(\d+)" style="width\:\s*(\d+)px; height\:\s*(\d+)px;">/ ;
  434. if (regexpDimensions.test( script ) )
  435. {
  436. delete FCK.GoogleMapsHandler.maps[this.number] ;
  437. this.number = RegExp.$1 ;
  438. FCK.GoogleMapsHandler.maps[this.number] = this ;
  439. this.width = RegExp.$2 ;
  440. this.height = RegExp.$3 ;
  441. }
  442. // map.setCenter(new GLatLng(42.4298,-8.07756), 8);
  443. var regexpPosition = /map\.setCenter\(new GLatLng\((-?\d{1,3}\.\d{1,6}),(-?\d{1,3}\.\d{1,6})\), (\d{1,2})\);/ ;
  444. if (regexpPosition.test( script ) )
  445. {
  446. this.centerLat = RegExp.$1 ;
  447. this.centerLon = RegExp.$2 ;
  448. this.zoom = RegExp.$3 ;
  449. }
  450. // v <= 1.5
  451. if ( version<=5 )
  452. {
  453. // var text = 'En O Carballino ha estado la d\'elegacion diplomatica japonesa';
  454. var markerText, markerLat=0, markerLon=0;
  455. var regexpText = /var text\s*=\s*("|')(.*)\1;\s*\n/ ;
  456. if (regexpText.test( script ) )
  457. {
  458. markerText = RegExp.$2 ;
  459. }
  460. // var point = new GLatLng(42.4298,-8.07756);
  461. var regexpMarker = /var point\s*=\s*new GLatLng\((-?\d{1,3}\.\d{1,6}),(-?\d{1,3}\.\d{1,6})\)/ ;
  462. if (regexpMarker.test( script ) )
  463. {
  464. markerLat = RegExp.$1 ;
  465. markerLon = RegExp.$2 ;
  466. }
  467. if (markerLat!=0 && markerLon!=0)
  468. this.markerPoints.push( {lat:markerLat, lon:markerLon, text:this.decodeText(markerText)} ) ;
  469. }
  470. else
  471. {
  472. // v > 1.5. multiple points.
  473. // AddMarkers( [{lat:37.45088, lon:-122.21123, text:'Write your text'}] ) ;
  474. var regexpMarkers = /\{lat\:(-?\d{1,3}\.\d{1,6}),\s*lon\:(-?\d{1,3}\.\d{1,6}),\s*text\:("|')(.*)\3}(?:,|])/ ;
  475. var point;
  476. var sampleText = script ;
  477. var startIndex = 0;
  478. var totalLength = sampleText.length;
  479. var result, pos;
  480. while (startIndex != totalLength) {
  481. result = regexpMarkers.exec(sampleText);
  482. if (result && result.length > 0) {
  483. pos = sampleText.indexOf(result[0]);
  484. startIndex += pos;
  485. this.markerPoints.push( {lat:result[1], lon:result[2], text:this.decodeText(result[4])} ) ;
  486. sampleText = sampleText.substr(pos + result[0].length);
  487. startIndex += result[0].length;
  488. } else {
  489. break;
  490. }
  491. }
  492. /*
  493. while (result = regexpMarkers.exec( script ) )
  494. {
  495. this.markerPoints.push( {lat:result[1], lon:result[2], text:result[4]} ) ;
  496. }
  497. */
  498. }
  499. // var encodedPoints = "iuowFf{kbMzH}N`IbJb@zBpYzO{dAvfF{LwDyN`_@`NzKqB|Ec@|L}BKmBbCoPjrBeEdy@uJ`Mn@zoAer@bjA~Xz{JczBa]pIps@de@tW}rCdxSwhPl`XgikCl{soA{dLdAaaF~cCyxCk_Aao@jp@kEvnCgoJ`]y[pVguKhCkUflAwrEzKk@yzCv^k@?mI";
  500. var regexpLinePoints = /var encodedPoints\s*=\s*("|')(.*)\1;\s*\n/ ;
  501. if (regexpLinePoints.test( script ) )
  502. {
  503. this.LinePoints = RegExp.$2 ;
  504. }
  505. // var encodedLevels = "B????????????????????????????????????B";
  506. var regexpLineLevels = /var encodedLevels\s*=\s*("|')(.*)\1;\s*\n/ ;
  507. if (regexpLineLevels.test( script ) )
  508. {
  509. this.LineLevels = RegExp.$2 ;
  510. }
  511. // 1.8 mapType
  512. // map.setMapType( allMapTypes[ 1 ] );
  513. var regexpMapType = /setMapType\([^\[]*\[\s*(\d+)\s*\]\s*\)/ ;
  514. if (regexpMapType.test( script ) )
  515. {
  516. this.mapType = RegExp.$1 ;
  517. }
  518. // 1.9 wrapper div with custom class
  519. if ( version >= 9 )
  520. {
  521. var regexpWrapper = /<div class=("|')(.*)\1.*\/\/wrapper/ ;
  522. if (regexpWrapper.test( script ) )
  523. this.WrapperClass = RegExp.$2 ;
  524. else
  525. this.WrapperClass = '' ;
  526. }
  527. return true;
  528. }
  529. FCKGoogleMap.prototype.BuildScript = function()
  530. {
  531. var versionMarker = '// FCK googlemaps v1.97' ;
  532. var aScript = [] ;
  533. aScript.push('\r\n<script type="text/javascript">') ;
  534. aScript.push( versionMarker ) ;
  535. if ( this.WrapperClass !== '')
  536. aScript.push('document.write(\'<div class="' + this.WrapperClass + '">\'); //wrapper');
  537. aScript.push('document.write(\'<div id="gmap' + this.number + '" style="width:' + this.width + 'px; height:' + this.height + 'px;">.<\\\/div>\');');
  538. if ( this.WrapperClass !== '')
  539. aScript.push('document.write(\'<\\\/div>\'); ');
  540. aScript.push('function CreateGMap' + this.number + '() {');
  541. aScript.push(' if(!GBrowserIsCompatible()) return;');
  542. aScript.push(' var allMapTypes = [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP] ;');
  543. aScript.push(' var map = new GMap2(document.getElementById("gmap' + this.number + '"), {mapTypes:allMapTypes});');
  544. aScript.push(' map.setCenter(new GLatLng(' + this.centerLat + ',' + this.centerLon + '), ' + this.zoom + ');');
  545. aScript.push(' map.setMapType( allMapTypes[ ' + this.mapType + ' ] );');
  546. aScript.push(' map.addControl(new GSmallMapControl());');
  547. aScript.push(' map.addControl(new GMapTypeControl());');
  548. var aPoints = [];
  549. for (var i=0; i<this.markerPoints.length ; i++)
  550. {
  551. var point = this.markerPoints[i] ;
  552. aPoints.push('{lat:' + point.lat + ', lon:' + point.lon + ', text:\'' + this.encodeText(point.text) + '\'}');
  553. }
  554. aScript.push(' AddMarkers( map, [' + aPoints.join(',\r\n') + '] ) ;') ;
  555. if ((this.LinePoints !== '') && (this.LineLevels !== '' ))
  556. {
  557. aScript.push('var encodedPoints = "' + this.LinePoints + '";');
  558. aScript.push('var encodedLevels = "' + this.LineLevels + '";');
  559. aScript.push('');
  560. aScript.push('var encodedPolyline = new GPolyline.fromEncoded({');
  561. aScript.push(' color: "#3333cc",');
  562. aScript.push(' weight: 5,');
  563. aScript.push(' points: encodedPoints,');
  564. aScript.push(' levels: encodedLevels,');
  565. aScript.push(' zoomFactor: 32,');
  566. aScript.push(' numLevels: 4');
  567. aScript.push(' });');
  568. aScript.push('map.addOverlay(encodedPolyline);');
  569. }
  570. aScript.push('}');
  571. aScript.push('</script>');
  572. return aScript.join('\r\n');
  573. }
  574. // Modifications of the core routines of FCKeditor:
  575. FCKXHtml.GetXHTML = Inject(FCKXHtml.GetXHTML, null, FCK.GoogleMapsHandler.GetXHTMLAfter ) ;
  576. FCKXHtml.TagProcessors.img = function( node, htmlNode, xmlNode )
  577. {
  578. if ( htmlNode.getAttribute( 'MapNumber' ) )
  579. {
  580. var oMap = FCK.GoogleMapsHandler.getMap( htmlNode.getAttribute( 'MapNumber' ) ) ;
  581. FCK.GoogleMapsHandler.CreatedMapsNames.push( oMap.number ) ;
  582. oMap.updateScript( htmlNode );
  583. node = FCK.GetRealElement( htmlNode ) ;
  584. if ( FCK.GoogleMapsHandler.CreatedMapsNames.length == 1 )
  585. {
  586. // If it is the first map, insert the google maps script
  587. var index = FCKTempBin.AddElement( FCK.GoogleMapsHandler.GenerateGoogleScript() ) ;
  588. var prefix = ( FCKConfig.ProtectedSource._CodeTag || 'PS..' ) ;
  589. oScriptCommentNode = xmlNode.ownerDocument.createComment( '{' + prefix + index + '}' ) ;
  590. xmlNode.appendChild( oScriptCommentNode ) ;
  591. }
  592. return xmlNode.ownerDocument.createComment( node.nodeValue ) ;
  593. }
  594. if (typeof FCK.GoogleMapsHandler.previousProcessor == 'function')
  595. node = FCK.GoogleMapsHandler.previousProcessor( node, htmlNode, xmlNode ) ;
  596. else
  597. node = FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
  598. return node ;
  599. };
  600. /**
  601. @desc inject the function
  602. @author Aimingoo&Riceball
  603. */
  604. function Inject( aOrgFunc, aBeforeExec, aAtferExec ) {
  605. return function() {
  606. if (typeof(aBeforeExec) == 'function') arguments = aBeforeExec.apply(this, arguments) || arguments;
  607. //convert arguments object to array
  608. var Result, args = [].slice.call(arguments);
  609. args.push(aOrgFunc.apply(this, args));
  610. if (typeof(aAtferExec) == 'function') Result = aAtferExec.apply(this, args);
  611. return (typeof(Result) != 'undefined')?Result:args.pop();
  612. } ;
  613. }