2 Dervied from the OpenStreetBugs client, which is available
3 under the following license.
5 This OpenStreetBugs client is free software: you can redistribute it
6 and/or modify it under the terms of the GNU Affero General Public License
7 as published by the Free Software Foundation, either version 3 of the
8 License, or (at your option) any later version.
10 This file is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
13 License <http://www.gnu.org/licenses/> for more details.
16 OpenLayers.Layer.Notes = new OpenLayers.Class(OpenLayers.Layer.Markers, {
18 * The URL of the OpenStreetMap API.
22 serverURL : "/api/0.6/",
25 * Associative array (index: note ID) that is filled with the notes
26 * loaded in this layer.
33 * The username to be used to change or create notes on OpenStreetMap.
40 * The icon to be used for an open note.
42 * @var OpenLayers.Icon
44 iconOpen : new OpenLayers.Icon("/images/open_note_marker.png", new OpenLayers.Size(22, 22), new OpenLayers.Pixel(-11, -11)),
47 * The icon to be used for a closed note.
49 * @var OpenLayers.Icon
51 iconClosed : new OpenLayers.Icon("/images/closed_note_marker.png", new OpenLayers.Size(22, 22), new OpenLayers.Pixel(-11, -11)),
54 * The projection of the coordinates sent by the OpenStreetMap API.
56 * @var OpenLayers.Projection
58 apiProjection : new OpenLayers.Projection("EPSG:4326"),
61 * If this is set to true, the user may not commit comments or close notes.
68 * When the layer is hidden, all open popups are stored in this
69 * array in order to be re-opened again when the layer is made
75 * The user name will be saved in a cookie if this isn’t set to false.
82 * The lifetime of the user name cookie in days.
86 cookieLifetime : 1000,
89 * The path where the cookie will be available on this server.
96 * A URL to append lon=123&lat=123&zoom=123 for the Permalinks.
100 permalinkURL : "http://www.openstreetmap.org/",
103 * A CSS file to be included. Set to null if you don’t need this.
107 theme : "/stylesheets/notes.css",
112 initialize : function(name, options)
114 OpenLayers.Layer.Markers.prototype.initialize.apply(this, [ name, OpenLayers.Util.extend({ opacity: 0.7, projection: new OpenLayers.Projection("EPSG:4326") }, options) ]);
115 putAJAXMarker.layers.push(this);
116 this.events.addEventType("markerAdded");
118 this.events.register("visibilitychanged", this, this.updatePopupVisibility);
119 this.events.register("visibilitychanged", this, this.loadNotes);
121 var cookies = document.cookie.split(/;\s*/);
122 for(var i=0; i<cookies.length; i++)
124 var cookie = cookies[i].split("=");
125 if(cookie[0] == "osbUsername")
127 this.username = decodeURIComponent(cookie[1]);
132 /* Copied from OpenLayers.Map */
134 // check existing links for equivalent url
136 var nodes = document.getElementsByTagName('link');
137 for(var i=0, len=nodes.length; i<len; ++i) {
138 if(OpenLayers.Util.isEquivalentUrl(nodes.item(i).href,
144 // only add a new node if one with an equivalent url hasn't already
147 var cssNode = document.createElement('link');
148 cssNode.setAttribute('rel', 'stylesheet');
149 cssNode.setAttribute('type', 'text/css');
150 cssNode.setAttribute('href', this.theme);
151 document.getElementsByTagName('head')[0].appendChild(cssNode);
157 * Is automatically called when the layer is added to an
158 * OpenLayers.Map. Initialises the automatic note loading in the
159 * visible bounding box.
161 afterAdd : function()
163 var ret = OpenLayers.Layer.Markers.prototype.afterAdd.apply(this, arguments);
165 this.map.events.register("moveend", this, this.loadNotes);
172 * At the moment the OpenStreetMap API responses to requests using
173 * JavaScript code. This way the Same Origin Policy can be worked
174 * around. Unfortunately, this makes communicating with the API a
175 * bit too asynchronous, at the moment there is no way to tell to
176 * which request the API actually responses.
178 * This method creates a new script HTML element that imports the
179 * API request URL. The API JavaScript response then executes the
180 * global functions provided below.
182 * @param String url The URL this.serverURL + url is requested.
184 apiRequest : function(url) {
185 var script = document.createElement("script");
186 script.type = "text/javascript";
187 script.src = this.serverURL + url + "&nocache="+(new Date()).getTime();
188 document.body.appendChild(script);
192 * Is automatically called when the visibility of the layer
193 * changes. When the layer is hidden, all visible popups are
194 * closed and their visibility is saved. When the layer is made
195 * visible again, these popups are re-opened.
197 updatePopupVisibility : function()
199 if(this.getVisibility())
201 for(var i=0; i<this.reopenPopups.length; i++)
202 this.reopenPopups[i].show();
203 this.reopenPopups = [ ];
207 for(var i=0; i<this.markers.length; i++)
209 if(this.markers[i].feature.popup && this.markers[i].feature.popup.visible())
211 this.markers[i].feature.popup.hide();
212 this.reopenPopups.push(this.markers[i].feature.popup);
219 * Sets the user name to be used for interactions with OpenStreetMap.
221 setUserName : function(username)
223 if(this.username == username)
226 this.username = username;
230 var cookie = "osbUsername="+encodeURIComponent(username);
231 if(this.cookieLifetime)
232 cookie += ";expires="+(new Date((new Date()).getTime() + this.cookieLifetime*86400000)).toGMTString();
234 cookie += ";path="+this.cookiePath;
235 document.cookie = cookie;
238 for(var i=0; i<this.markers.length; i++)
240 if(!this.markers[i].feature.popup) continue;
241 var els = this.markers[i].feature.popup.contentDom.getElementsByTagName("input");
242 for(var j=0; j<els.length; j++)
244 if(els[j].className != "osbUsername") continue;
245 els[j].value = username;
251 * Returns the currently set username or “NoName” if none is set.
253 getUserName : function()
256 return this.username;
262 * Loads the notes in the current bounding box. Is automatically
263 * called by an event handler ("moveend" event) that is created in
264 * the afterAdd() method.
266 loadNotes : function()
268 if(!this.getVisibility())
271 var bounds = this.map.getExtent();
272 if(!bounds) return false;
273 bounds.transform(this.map.getProjectionObject(), this.apiProjection);
275 this.apiRequest("notes"
276 + "?bbox="+this.round(bounds.left, 5)
277 + ","+this.round(bounds.bottom, 5)
278 + ","+this.round(bounds.right, 5)
279 + ","+this.round(bounds.top, 5));
283 * Rounds the given number to the given number of digits after the
286 * @param Number number
287 * @param Number digits
290 round : function(number, digits)
292 var factor = Math.pow(10, digits);
293 return Math.round(number*factor)/factor;
297 * Adds an OpenLayers.Marker representing a note to the map. Is
298 * usually called by loadNotes().
300 * @param Number id The note ID
302 createMarker: function(id)
306 if(this.notes[id].popup && !this.notes[id].popup.visible())
307 this.setPopupContent(id);
308 if(this.notes[id].closed != putAJAXMarker.notes[id][2])
309 this.notes[id].destroy();
314 var lonlat = putAJAXMarker.notes[id][0].clone().transform(this.apiProjection, this.map.getProjectionObject());
315 var comments = putAJAXMarker.notes[id][1];
316 var closed = putAJAXMarker.notes[id][2];
317 var feature = new OpenLayers.Feature(this, lonlat, { icon: (closed ? this.iconClosed : this.iconOpen).clone(), autoSize: true });
318 feature.popupClass = OpenLayers.Popup.FramedCloud.Notes;
320 feature.closed = closed;
322 var marker = feature.createMarker();
323 marker.feature = feature;
324 marker.events.register("click", feature, this.markerClick);
325 //marker.events.register("mouseover", feature, this.markerMouseOver);
326 //marker.events.register("mouseout", feature, this.markerMouseOut);
327 this.addMarker(marker);
329 this.notes[id] = feature;
330 this.events.triggerEvent("markerAdded");
334 * Recreates the content of the popup of a marker.
336 * @param Number id The note ID
338 setPopupContent: function(id) {
339 if(!this.notes[id].popup)
345 var newContent = document.createElement("div");
347 el1 = document.createElement("h3");
348 el1.appendChild(document.createTextNode(putAJAXMarker.notes[id][2] ? i18n("javascripts.note.closed") : i18n("javascripts.note.open")));
350 el1.appendChild(document.createTextNode(" ["));
351 el2 = document.createElement("a");
352 el2.href = "/browse/note/" + id;
353 el2.onclick = function(){ layer.map.setCenter(putAJAXMarker.notes[id][0].clone().transform(layer.apiProjection, layer.map.getProjectionObject()), 15); };
354 el2.appendChild(document.createTextNode(i18n("javascripts.note.details")));
355 el1.appendChild(el2);
356 el1.appendChild(document.createTextNode("]"));
358 if(this.permalinkURL)
360 el1.appendChild(document.createTextNode(" ["));
361 el2 = document.createElement("a");
362 el2.href = this.permalinkURL + (this.permalinkURL.indexOf("?") == -1 ? "?" : "&") + "lon="+putAJAXMarker.notes[id][0].lon+"&lat="+putAJAXMarker.notes[id][0].lat+"&zoom=15";
363 el2.appendChild(document.createTextNode(i18n("javascripts.note.permalink")));
364 el1.appendChild(el2);
365 el1.appendChild(document.createTextNode("]"));
367 newContent.appendChild(el1);
369 var containerDescription = document.createElement("div");
370 newContent.appendChild(containerDescription);
372 var containerChange = document.createElement("div");
373 newContent.appendChild(containerChange);
375 var displayDescription = function(){
376 containerDescription.style.display = "block";
377 containerChange.style.display = "none";
378 layer.notes[id].popup.updateSize();
380 var displayChange = function(){
381 containerDescription.style.display = "none";
382 containerChange.style.display = "block";
383 layer.notes[id].popup.updateSize();
385 displayDescription();
387 el1 = document.createElement("dl");
388 for(var i=0; i<putAJAXMarker.notes[id][1].length; i++)
390 el2 = document.createElement("dt");
391 el2.className = (i == 0 ? "note-description" : "note-comment");
392 el2.appendChild(document.createTextNode(i == 0 ? i18n("javascripts.note.description") : i18n("javascripts.note.comment")));
393 el1.appendChild(el2);
394 el2 = document.createElement("dd");
395 el2.className = (i == 0 ? "note-description" : "note-comment");
396 el2.appendChild(document.createTextNode(putAJAXMarker.notes[id][1][i]));
397 el1.appendChild(el2);
398 if (i == 0) { el2 = document.createElement("br"); el1.appendChild(el2);};
400 containerDescription.appendChild(el1);
402 if(putAJAXMarker.notes[id][2])
404 el1 = document.createElement("p");
405 el1.className = "note-fixed";
406 el2 = document.createElement("em");
407 el2.appendChild(document.createTextNode(i18n("javascripts.note.render_warning")));
408 el1.appendChild(el2);
409 containerDescription.appendChild(el1);
411 else if(!this.readonly)
413 el1 = document.createElement("div");
414 el2 = document.createElement("input");
415 el2.setAttribute("type", "button");
416 el2.onclick = function(){ displayChange(); };
417 el2.value = i18n("javascripts.note.update");
418 el1.appendChild(el2);
419 containerDescription.appendChild(el1);
421 var el_form = document.createElement("form");
422 el_form.onsubmit = function(){ if(inputComment.value.match(/^\s*$/)) return false; layer.submitComment(id, inputComment.value); layer.hidePopup(id); return false; };
424 el1 = document.createElement("dl");
425 el2 = document.createElement("dt");
426 el2.appendChild(document.createTextNode(i18n("javascripts.note.nickname")));
427 el1.appendChild(el2);
428 el2 = document.createElement("dd");
429 var inputUsername = document.createElement("input");
430 var inputUsername = document.createElement("input");;
431 if (typeof loginName === 'undefined') {
432 inputUsername.value = this.username;
434 inputUsername.value = loginName;
435 inputUsername.setAttribute('disabled','true');
437 inputUsername.className = "osbUsername";
438 inputUsername.onkeyup = function(){ layer.setUserName(inputUsername.value); };
439 el2.appendChild(inputUsername);
440 el3 = document.createElement("a");
441 el3.setAttribute("href","login");
442 el3.className = "hide_if_logged_in";
443 el3.appendChild(document.createTextNode(i18n("javascripts.note.login")));
445 el1.appendChild(el2);
447 el2 = document.createElement("dt");
448 el2.appendChild(document.createTextNode(i18n("javascripts.note.comment")));
449 el1.appendChild(el2);
450 el2 = document.createElement("dd");
451 var inputComment = document.createElement("textarea");
452 inputComment.setAttribute("cols",40);
453 inputComment.setAttribute("rows",3);
455 el2.appendChild(inputComment);
456 el1.appendChild(el2);
458 el_form.appendChild(el1);
460 el1 = document.createElement("ul");
461 el1.className = "buttons";
462 el2 = document.createElement("li");
463 el3 = document.createElement("input");
464 el3.setAttribute("type", "button");
465 el3.onclick = function(){ this.form.onsubmit(); return false; };
466 el3.value = i18n("javascripts.note.add_comment");
467 el2.appendChild(el3);
468 el1.appendChild(el2);
470 el2 = document.createElement("li");
471 el3 = document.createElement("input");
472 el3.setAttribute("type", "button");
473 el3.onclick = function(){ this.form.onsubmit(); layer.closeNote(id); layer.notes[id].popup.hide(); return false; };
474 el3.value = i18n("javascripts.note.close");
475 el2.appendChild(el3);
476 el1.appendChild(el2);
477 el_form.appendChild(el1);
478 containerChange.appendChild(el_form);
480 el1 = document.createElement("div");
481 el2 = document.createElement("input");
482 el2.setAttribute("type", "button");
483 el2.onclick = function(){ displayDescription(); };
484 el2.value = i18n("javascripts.note.cancel");
485 el1.appendChild(el2);
486 containerChange.appendChild(el1);
489 this.notes[id].popup.setContentHTML(newContent);
493 * Creates a new note.
495 * @param OpenLayers.LonLat lonlat The coordinates in the API projection.
496 * @param String description
498 createNote: function(lonlat, description) {
499 this.apiRequest("note/create"
500 + "?lat="+encodeURIComponent(lonlat.lat)
501 + "&lon="+encodeURIComponent(lonlat.lon)
502 + "&text="+encodeURIComponent(description)
503 + "&name="+encodeURIComponent(this.getUserName())
509 * Adds a comment to a note.
512 * @param String comment
514 submitComment: function(id, comment) {
515 this.apiRequest("note/"+encodeURIComponent(id)+"/comment"
516 + "?text="+encodeURIComponent(comment)
517 + "&name="+encodeURIComponent(this.getUserName())
523 * Marks a note as fixed.
527 closeNote: function(id) {
528 this.apiRequest("note/"+encodeURIComponent(id)+"/close"
534 * Removes the content of a marker popup (to reduce the amount of
539 resetPopupContent: function(id) {
540 if(!this.notes[id].popup)
543 this.notes[id].popup.setContentHTML(document.createElement("div"));
547 * Makes the popup of the given marker visible. Makes sure that
548 * the popup content is created if it does not exist yet.
552 showPopup: function(id) {
554 if(!this.notes[id].popup)
556 add = this.notes[id].createPopup(true);
557 add.events.register("close", this, function(){ this.resetPopupContent(id); if(this.notes[id].noteClicked) this.notes[id].noteClicked = false; });
559 else if(this.notes[id].popup.visible())
562 this.setPopupContent(id);
564 this.map.addPopup(add);
565 this.notes[id].popup.show();
566 this.notes[id].popup.updateSize();
570 * Hides the popup of the given marker.
574 hidePopup: function(id) {
575 if(!this.notes[id].popup || !this.notes[id].popup.visible())
578 this.notes[id].popup.hide();
579 this.notes[id].popup.events.triggerEvent("close");
583 * Is run on the “click” event of a marker in the context of its
584 * OpenLayers.Feature. Toggles the visibility of the popup.
586 markerClick: function(e) {
587 var feature = this; // Context is the feature
589 feature.noteClicked = !feature.noteClicked;
590 if(feature.noteClicked)
591 feature.layer.showPopup(feature.noteId);
593 feature.layer.hidePopup(feature.noteId);
594 OpenLayers.Event.stop(e);
598 * Is run on the “mouseover” event of a marker in the context of
599 * its OpenLayers.Feature. Makes the popup visible.
601 markerMouseOver: function(e) {
602 var feature = this; // Context is the feature
604 feature.layer.showPopup(feature.noteId);
605 OpenLayers.Event.stop(e);
609 * Is run on the “mouseout” event of a marker in the context of
610 * its OpenLayers.Feature. Hides the popup (if it has not been
613 markerMouseOut: function(e) {
614 var feature = this; // Context is the feature
616 if(!feature.noteClicked)
617 feature.layer.hidePopup(feature.noteId);
618 OpenLayers.Event.stop(e);
621 CLASS_NAME: "OpenLayers.Layer.Notes"
625 * An OpenLayers control to create new notes on mouse clicks on the
626 * map. Add an instance of this to your map using the
627 * OpenLayers.Map.addControl() method and activate() it.
629 OpenLayers.Control.Notes = new OpenLayers.Class(OpenLayers.Control, {
630 title : null, // See below because of translation call
633 * The icon to be used for the temporary markers that the “create
634 * note” popup belongs to..
636 * @var OpenLayers.Icon
638 icon : new OpenLayers.Icon("/images/icon_note_add.png", new OpenLayers.Size(22, 22), new OpenLayers.Pixel(-11, -11)),
641 * An instance of the Notes layer that this control shall be
642 * connected to. Is set in the constructor.
644 * @var OpenLayers.Layer.Notes
649 * @param OpenLayers.Layer.Notes noteLayer The Notes layer that this control will be connected to.
651 initialize: function(noteLayer, options) {
652 this.noteLayer = noteLayer;
654 this.title = i18n("javascripts.note.create");
656 OpenLayers.Control.prototype.initialize.apply(this, [ options ]);
658 this.events.register("activate", this, function() {
659 if(!this.noteLayer.getVisibility())
660 this.noteLayer.setVisibility(true);
663 this.noteLayer.events.register("visibilitychanged", this, function() {
664 if(this.active && !this.noteLayer.getVisibility())
665 this.noteLayer.setVisibility(true);
669 destroy: function() {
671 this.handler.destroy();
674 OpenLayers.Control.prototype.destroy.apply(this, arguments);
678 this.handler = new OpenLayers.Handler.Click(this, {'click': this.click}, { 'single': true, 'double': false, 'pixelTolerance': 0, 'stopSingle': false, 'stopDouble': false });
682 * Map clicking event handler. Adds a temporary marker with a
683 * popup to the map, the popup contains the form to add a note.
686 var lonlat = this.map.getLonLatFromViewPortPx(e.xy);
687 this.addTemporaryMarker(lonlat);
690 addTemporaryMarker: function(lonlat) {
691 if(!this.map) return true;
694 var lonlatApi = lonlat.clone().transform(this.map.getProjectionObject(), this.noteLayer.apiProjection);
695 var feature = new OpenLayers.Feature(this.noteLayer, lonlat, { icon: this.icon.clone(), autoSize: true });
696 feature.popupClass = OpenLayers.Popup.FramedCloud.Notes;
697 var marker = feature.createMarker();
698 marker.feature = feature;
699 this.noteLayer.addMarker(marker);
702 /** Implement a drag and drop for markers */
703 /* TODO: veryfy that the scoping of variables works correctly everywhere */
704 var dragging = false;
705 var dragFunction = function(e) {
706 map.events.unregister("mouseup",map,dragFunction);
707 lonlat = map.getLonLatFromViewPortPx(e.xy);
708 lonlatApi = lonlat.clone().transform(map.getProjectionObject(), map.noteLayer.apiProjection);
709 marker.moveTo(map.getLayerPxFromViewPortPx(e.xy));
710 marker.popup.moveTo(map.getLayerPxFromViewPortPx(e.xy));
711 marker.popup.updateRelativePosition();
716 marker.events.register("mouseover", this, function() {
717 control.map.viewPortDiv.style.cursor = "move";
719 marker.events.register("mouseout", this, function() {
721 control.map.viewPortDiv.style.cursor = "default";
723 marker.events.register("mousedown", this, function() {
725 control.map.events.register("mouseup", control.map, dragFunction);
729 var newContent = document.createElement("div");
731 el1 = document.createElement("h3");
732 el1.appendChild(document.createTextNode(i18n("javascripts.note.create_title")));
733 newContent.appendChild(el1);
734 newContent.appendChild(document.createTextNode(i18n("javascripts.note.create_help1")));
735 newContent.appendChild(document.createElement("br"));
736 newContent.appendChild(document.createTextNode(i18n("javascripts.note.create_help2")));
737 newContent.appendChild(document.createElement("br"));
738 newContent.appendChild(document.createElement("br"));
740 var el_form = document.createElement("form");
742 el1 = document.createElement("dl");
743 el2 = document.createElement("dt");
744 el2.appendChild(document.createTextNode(i18n("javascripts.note.nickname")));
745 el1.appendChild(el2);
746 el2 = document.createElement("dd");
747 var inputUsername = document.createElement("input");;
748 if (typeof loginName === 'undefined') {
749 inputUsername.value = this.noteLayer.username;
751 inputUsername.value = loginName;
752 inputUsername.setAttribute('disabled','true');
754 inputUsername.className = "osbUsername";
756 inputUsername.onkeyup = function(){ control.noteLayer.setUserName(inputUsername.value); };
757 el2.appendChild(inputUsername);
758 el3 = document.createElement("a");
759 el3.setAttribute("href","login");
760 el3.className = "hide_if_logged_in";
761 el3.appendChild(document.createTextNode(i18n("javascripts.note.login")));
762 el2.appendChild(el3);
763 el1.appendChild(el2);
764 el2 = document.createElement("br");
765 el1.appendChild(el2);
767 el2 = document.createElement("dt");
768 el2.appendChild(document.createTextNode(i18n("javascripts.note.description")));
769 el1.appendChild(el2);
770 el2 = document.createElement("dd");
771 var inputDescription = document.createElement("textarea");
772 inputDescription.setAttribute("cols",40);
773 inputDescription.setAttribute("rows",3);
774 el2.appendChild(inputDescription);
775 el1.appendChild(el2);
776 el_form.appendChild(el1);
778 el1 = document.createElement("div");
779 el2 = document.createElement("input");
780 el2.setAttribute("type", "button");
781 el2.value = i18n("javascripts.note.report");
782 el2.onclick = function() { control.noteLayer.createNote(lonlatApi, inputDescription.value); marker.feature = null; feature.destroy(); return false; };
783 el1.appendChild(el2);
784 el2 = document.createElement("input");
785 el2.setAttribute("type", "button");
786 el2.value = i18n("javascripts.note.cancel");
787 el2.onclick = function(){ feature.destroy(); };
788 el1.appendChild(el2);
789 el_form.appendChild(el1);
790 newContent.appendChild(el_form);
792 el2 = document.createElement("hr");
793 el1.appendChild(el2);
794 el2 = document.createElement("a");
795 el2.setAttribute("href","edit");
796 el2.appendChild(document.createTextNode(i18n("javascripts.note.edityourself")));
797 el1.appendChild(el2);
799 feature.data.popupContentHTML = newContent;
800 var popup = feature.createPopup(true);
801 popup.events.register("close", this, function(){ feature.destroy(); });
802 this.map.addPopup(popup);
804 marker.popup = popup;
807 CLASS_NAME: "OpenLayers.Control.Notes"
812 * This class changes the usual OpenLayers.Popup.FramedCloud class by
813 * using a DOM element instead of an innerHTML string as content for
814 * the popup. This is necessary for creating valid onclick handlers
815 * that still work with multiple Notes layer objects.
817 OpenLayers.Popup.FramedCloud.Notes = new OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
822 * See OpenLayers.Popup.FramedCloud.initialize() for
823 * parameters. As fourth parameter, pass a DOM node instead of a
826 initialize: function() {
827 this.displayClass = this.displayClass + " " + this.CLASS_NAME.replace("OpenLayers.", "ol").replace(/\./g, "");
829 var args = new Array(arguments.length);
830 for(var i=0; i<arguments.length; i++)
831 args[i] = arguments[i];
833 // Unset original contentHTML parameter
836 var closeCallback = arguments[6];
838 // Add close event trigger to the closeBoxCallback parameter
839 args[6] = function(e){ if(closeCallback) closeCallback(); else this.hide(); OpenLayers.Event.stop(e); this.events.triggerEvent("close"); };
841 OpenLayers.Popup.FramedCloud.prototype.initialize.apply(this, args);
843 this.events.addEventType("close");
845 this.setContentHTML(arguments[3]);
849 * Like OpenLayers.Popup.FramedCloud.setContentHTML(), but takes a
850 * DOM element as parameter.
852 setContentHTML: function(contentDom) {
853 if(contentDom != null)
854 this.contentDom = contentDom;
856 if(this.contentDiv == null || this.contentDom == null || this.contentDom == this.contentDiv.firstChild)
859 while(this.contentDiv.firstChild)
860 this.contentDiv.removeChild(this.contentDiv.firstChild);
862 this.contentDiv.appendChild(this.contentDom);
864 // Copied from OpenLayers.Popup.setContentHTML():
867 this.registerImageListeners();
872 destroy: function() {
873 this.contentDom = null;
874 OpenLayers.Popup.FramedCloud.prototype.destroy.apply(this, arguments);
877 CLASS_NAME: "OpenLayers.Popup.FramedCloud.Notes"
882 * This global function is executed by the OpenStreetMap API getBugs script.
884 * Each Notes layer adds itself to the putAJAXMarker.layer array. The
885 * putAJAXMarker() function executes the createMarker() method on each
886 * layer in that array each time it is called. This has the
887 * side-effect that notes displayed in one map on a page are already
888 * loaded on the other map as well.
890 function putAJAXMarker(id, lon, lat, text, closed)
892 var comments = text.split(/<hr \/>/);
893 for(var i=0; i<comments.length; i++)
894 comments[i] = comments[i].replace(/"/g, "\"").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
895 putAJAXMarker.notes[id] = [
896 new OpenLayers.LonLat(lon, lat),
900 for(var i=0; i<putAJAXMarker.layers.length; i++)
901 putAJAXMarker.layers[i].createMarker(id);
905 * This global function is executed by the OpenStreetMap API. The
906 * “create note”, “comment” and “close note” scripts execute it to give
907 * information about their success.
909 * In case of success, this function is called without a parameter, in
910 * case of an error, the error message is passed. This is lousy
911 * workaround to make it any functional at all, the OSB API is likely
912 * to be extended later (then it will provide additional information
913 * such as the ID of a created note and similar).
915 function osbResponse(error)
918 alert("Error: "+error);
920 for(var i=0; i<putAJAXMarker.layers.length; i++)
921 putAJAXMarker.layers[i].loadNotes();
924 putAJAXMarker.layers = [ ];
925 putAJAXMarker.notes = { };