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;
695 var lonlatApi = lonlat.clone().transform(this.map.getProjectionObject(), this.noteLayer.apiProjection);
696 var feature = new OpenLayers.Feature(this.noteLayer, lonlat, { icon: this.icon.clone(), autoSize: true });
697 feature.popupClass = OpenLayers.Popup.FramedCloud.Notes;
698 var marker = feature.createMarker();
699 marker.feature = feature;
700 this.noteLayer.addMarker(marker);
703 /** Implement a drag and drop for markers */
704 /* TODO: veryfy that the scoping of variables works correctly everywhere */
705 var dragging = false;
706 var dragFunction = function(e) {
707 map.events.unregister("mouseup",map,dragFunction);
708 lonlat = map.getLonLatFromViewPortPx(e.xy);
709 lonlatApi = lonlat.clone().transform(map.getProjectionObject(), map.noteLayer.apiProjection);
710 marker.moveTo(map.getLayerPxFromViewPortPx(e.xy));
711 marker.popup.moveTo(map.getLayerPxFromViewPortPx(e.xy));
712 marker.popup.updateRelativePosition();
717 marker.events.register("mouseover", this,
718 function(){ document.getElementById("OpenLayers.Map_18_OpenLayers_Container").style.cursor = "move"; });
719 marker.events.register("mouseout", this,
720 function(){ if (!dragging) {document.getElementById("OpenLayers.Map_18_OpenLayers_Container").style.cursor = "default"; }});
721 marker.events.register("mousedown", this,
722 function() { dragging = true; map.events.register("mouseup",map, dragFunction); return false;});
725 var newContent = document.createElement("div");
727 el1 = document.createElement("h3");
728 el1.appendChild(document.createTextNode(i18n("javascripts.note.create_title")));
729 newContent.appendChild(el1);
730 newContent.appendChild(document.createTextNode(i18n("javascripts.note.create_help1")));
731 newContent.appendChild(document.createElement("br"));
732 newContent.appendChild(document.createTextNode(i18n("javascripts.note.create_help2")));
733 newContent.appendChild(document.createElement("br"));
734 newContent.appendChild(document.createElement("br"));
736 var el_form = document.createElement("form");
738 el1 = document.createElement("dl");
739 el2 = document.createElement("dt");
740 el2.appendChild(document.createTextNode(i18n("javascripts.note.nickname")));
741 el1.appendChild(el2);
742 el2 = document.createElement("dd");
743 var inputUsername = document.createElement("input");;
744 if (typeof loginName === 'undefined') {
745 inputUsername.value = this.noteLayer.username;
747 inputUsername.value = loginName;
748 inputUsername.setAttribute('disabled','true');
750 inputUsername.className = "osbUsername";
752 inputUsername.onkeyup = function(){ control.noteLayer.setUserName(inputUsername.value); };
753 el2.appendChild(inputUsername);
754 el3 = document.createElement("a");
755 el3.setAttribute("href","login");
756 el3.className = "hide_if_logged_in";
757 el3.appendChild(document.createTextNode(i18n("javascripts.note.login")));
758 el2.appendChild(el3);
759 el1.appendChild(el2);
760 el2 = document.createElement("br");
761 el1.appendChild(el2);
763 el2 = document.createElement("dt");
764 el2.appendChild(document.createTextNode(i18n("javascripts.note.description")));
765 el1.appendChild(el2);
766 el2 = document.createElement("dd");
767 var inputDescription = document.createElement("textarea");
768 inputDescription.setAttribute("cols",40);
769 inputDescription.setAttribute("rows",3);
770 el2.appendChild(inputDescription);
771 el1.appendChild(el2);
772 el_form.appendChild(el1);
774 el1 = document.createElement("div");
775 el2 = document.createElement("input");
776 el2.setAttribute("type", "button");
777 el2.value = i18n("javascripts.note.report");
778 el2.onclick = function() { control.noteLayer.createNote(lonlatApi, inputDescription.value); marker.feature = null; feature.destroy(); return false; };
779 el1.appendChild(el2);
780 el2 = document.createElement("input");
781 el2.setAttribute("type", "button");
782 el2.value = i18n("javascripts.note.cancel");
783 el2.onclick = function(){ feature.destroy(); };
784 el1.appendChild(el2);
785 el_form.appendChild(el1);
786 newContent.appendChild(el_form);
788 el2 = document.createElement("hr");
789 el1.appendChild(el2);
790 el2 = document.createElement("a");
791 el2.setAttribute("href","edit");
792 el2.appendChild(document.createTextNode(i18n("javascripts.note.edityourself")));
793 el1.appendChild(el2);
795 feature.data.popupContentHTML = newContent;
796 var popup = feature.createPopup(true);
797 popup.events.register("close", this, function(){ feature.destroy(); });
798 this.map.addPopup(popup);
800 marker.popup = popup;
803 CLASS_NAME: "OpenLayers.Control.Notes"
808 * This class changes the usual OpenLayers.Popup.FramedCloud class by
809 * using a DOM element instead of an innerHTML string as content for
810 * the popup. This is necessary for creating valid onclick handlers
811 * that still work with multiple Notes layer objects.
813 OpenLayers.Popup.FramedCloud.Notes = new OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
818 * See OpenLayers.Popup.FramedCloud.initialize() for
819 * parameters. As fourth parameter, pass a DOM node instead of a
822 initialize: function() {
823 this.displayClass = this.displayClass + " " + this.CLASS_NAME.replace("OpenLayers.", "ol").replace(/\./g, "");
825 var args = new Array(arguments.length);
826 for(var i=0; i<arguments.length; i++)
827 args[i] = arguments[i];
829 // Unset original contentHTML parameter
832 var closeCallback = arguments[6];
834 // Add close event trigger to the closeBoxCallback parameter
835 args[6] = function(e){ if(closeCallback) closeCallback(); else this.hide(); OpenLayers.Event.stop(e); this.events.triggerEvent("close"); };
837 OpenLayers.Popup.FramedCloud.prototype.initialize.apply(this, args);
839 this.events.addEventType("close");
841 this.setContentHTML(arguments[3]);
845 * Like OpenLayers.Popup.FramedCloud.setContentHTML(), but takes a
846 * DOM element as parameter.
848 setContentHTML: function(contentDom) {
849 if(contentDom != null)
850 this.contentDom = contentDom;
852 if(this.contentDiv == null || this.contentDom == null || this.contentDom == this.contentDiv.firstChild)
855 while(this.contentDiv.firstChild)
856 this.contentDiv.removeChild(this.contentDiv.firstChild);
858 this.contentDiv.appendChild(this.contentDom);
860 // Copied from OpenLayers.Popup.setContentHTML():
863 this.registerImageListeners();
868 destroy: function() {
869 this.contentDom = null;
870 OpenLayers.Popup.FramedCloud.prototype.destroy.apply(this, arguments);
873 CLASS_NAME: "OpenLayers.Popup.FramedCloud.Notes"
878 * This global function is executed by the OpenStreetMap API getBugs script.
880 * Each Notes layer adds itself to the putAJAXMarker.layer array. The
881 * putAJAXMarker() function executes the createMarker() method on each
882 * layer in that array each time it is called. This has the
883 * side-effect that notes displayed in one map on a page are already
884 * loaded on the other map as well.
886 function putAJAXMarker(id, lon, lat, text, closed)
888 var comments = text.split(/<hr \/>/);
889 for(var i=0; i<comments.length; i++)
890 comments[i] = comments[i].replace(/"/g, "\"").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
891 putAJAXMarker.notes[id] = [
892 new OpenLayers.LonLat(lon, lat),
896 for(var i=0; i<putAJAXMarker.layers.length; i++)
897 putAJAXMarker.layers[i].createMarker(id);
901 * This global function is executed by the OpenStreetMap API. The
902 * “create note”, “comment” and “close note” scripts execute it to give
903 * information about their success.
905 * In case of success, this function is called without a parameter, in
906 * case of an error, the error message is passed. This is lousy
907 * workaround to make it any functional at all, the OSB API is likely
908 * to be extended later (then it will provide additional information
909 * such as the ID of a created note and similar).
911 function osbResponse(error)
914 alert("Error: "+error);
916 for(var i=0; i<putAJAXMarker.layers.length; i++)
917 putAJAXMarker.layers[i].loadNotes();
920 putAJAXMarker.layers = [ ];
921 putAJAXMarker.notes = { };
923 function deactivateControl() {
924 map.noteControl.deactivate();
925 document.getElementById("OpenLayers.Map_18_OpenLayers_Container").style.cursor = "default";