Subversion Repositories eFlore/Applications.moissonnage

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 delphine 1
L.OpenStreetBugs = L.FeatureGroup.extend({
2
	options : {
3
		serverURL : "http://openstreetbugs.schokokeks.org/api/0.1/",
4
		readonly : false,
5
		setCookie : true,
6
		username : "NoName",
7
		cookieLifetime : 1000,
8
		cookiePath : null,
9
		permalinkZoom : 14,
10
		permalinkUrl: null,
11
		opacity : 0.7,
12
		showOpen: true,
13
		showClosed: true,
14
		iconOpen: "http://openstreetbugs.schokokeks.org/client/open_bug_marker.png",
15
		iconClosed:"http://openstreetbugs.schokokeks.org/client/closed_bug_marker.png",
16
		iconActive: undefined,
17
		editArea: 0.01,
18
		popupOptions: {autoPan: false},
19
		dblClick: true
20
	},
21
 
22
	initialize : function(options)
23
	{
24
		var tmp = L.Util.extend({}, this.options.popupOptions, (options || {}).popupOptions)
25
		L.Util.setOptions(this, options)
26
		this.options.popupOptions = tmp;
27
 
28
		putAJAXMarker.layers.push(this);
29
 
30
		this.bugs = {};
31
		this._layers = {};
32
 
33
		var username = this.get_cookie("osbUsername");
34
		if (username)
35
			this.options.username = username;
36
 
37
		L.OpenStreetBugs.setCSS();
38
	},
39
 
40
	onAdd : function(map)
41
	{
42
		L.FeatureGroup.prototype.onAdd.apply(this, [map]);
43
 
44
		this._map.on("moveend", this.loadBugs, this);
45
		this.loadBugs();
46
		if (!this.options.readonly) {
47
		  if (this.options.dblClick) {
48
			  map.doubleClickZoom.disable();
49
			  map.on('dblclick', this.addBug, this);
50
		  }
51
		  else {
52
			  map.on('click', this.addBug, this);
53
			}
54
		}
55
		this.fire('add');
56
	},
57
 
58
	onRemove : function(map)
59
	{
60
		this._map.off("moveend", this.loadBugs, this);
61
		this._iterateLayers(map.removeLayer, map);
62
		delete this._map;
63
		if (!this.options.readonly) {
64
		  if (this.options.dblClick) {
65
			  map.doubleClickZoom.enable();
66
			  map.off('dblclick', this.addBug, this);
67
		  }
68
		  else {
69
		    map.off('click', this.addBug, this);
70
			}
71
		}
72
		this.fire('remove');
73
	},
74
 
75
	set_cookie : function(name, value)
76
	{
77
		var expires = (new Date((new Date()).getTime() + 604800000)).toGMTString(); // one week from now
78
		document.cookie = name+"="+escape(value)+";";
79
	},
80
 
81
	get_cookie : function(name)
82
	{
83
		var cookies = (document.cookie || '').split(/;\s*/);
84
		for(var i=0; i<cookies.length; i++)
85
		{
86
			var cookie = cookies[i].split("=");
87
			if(cookie[0] == name)
88
				return unescape(cookie[1]);
89
		}
90
		return null;
91
	},
92
 
93
	loadBugs : function()
94
	{
95
		//if(!this.getVisibility())
96
		//	return true;
97
 
98
		var bounds = this._map.getBounds();
99
		if(!bounds) return false;
100
		var sw = bounds.getSouthWest(), ne = bounds.getNorthEast();
101
 
102
		function round(number, digits) {
103
			var factor = Math.pow(10, digits);
104
			return Math.round(number*factor)/factor;
105
		}
106
 
107
		this.apiRequest("getBugs"
108
			+ "?t="+round(ne.lat, 5)
109
			+ "&r="+round(ne.lng, 5)
110
			+ "&b="+round(sw.lat, 5)
111
			+ "&l="+round(sw.lng, 5));
112
	},
113
 
114
	apiRequest : function(url, reload)
115
	{
116
		var script = document.createElement("script");
117
		script.type = "text/javascript";
118
		script.src = this.options.serverURL + url + "&nocache="+(new Date()).getTime();
119
		var _this = this;
120
		script.onload = function(e) {
121
			document.body.removeChild(this);
122
			if (reload) _this.loadBugs();
123
		};
124
		document.body.appendChild(script);
125
	},
126
 
127
	createMarker: function(id, force)
128
	{
129
		var bug = putAJAXMarker.bugs[id];
130
		if(this.bugs[id])
131
		{
132
			if (force || this.bugs[id].osb.closed != bug[2])
133
				this.removeLayer(this.bugs[id]);
134
			else
135
				return;
136
		}
137
 
138
		var closed = bug[2];
139
 
140
		if (closed && !this.options.showClosed) return;
141
		if (!closed && !this.options.showOpen) return;
142
 
143
		var icon_url = null;
144
		var class_popup = ' osb';
145
		if (bug[2]) {
146
			icon_url = this.options.iconClosed;
147
			class_popup += ' osbClosed';
148
		}
149
		else if (bug[1].length == 1) {
150
			icon_url = this.options.iconOpen;
151
			class_popup += ' osbOpen';
152
		}
153
		else {
154
		  if (this.options.iconActive) {
155
		    icon_url = this.options.iconActive;
156
		    class_popup += ' osbActive';
157
		  }
158
		  else {
159
		    icon_url = this.options.iconOpen;
160
		    class_popup += ' osbOpen';
161
		  }
162
		}
163
		var feature = new L.Marker(bug[0], {icon:new this.osbIcon({iconUrl: icon_url})});
164
		feature.osb = {id: id, closed: closed};
165
		this.addLayer(feature);
166
		this.bugs[id] = feature;
167
		this.setPopupContent(id);
168
		feature._popup.options.className += class_popup;
169
 
170
		if (this.options.bugid && (parseInt(this.options.bugid) == id))
171
			feature.openPopup();
172
 
173
		//this.events.triggerEvent("markerAdded");
174
	},
175
 
176
	osbIcon :  L.Icon.extend({
177
		options: {
178
			iconUrl: 'http://openstreetbugs.schokokeks.org/client/open_bug_marker.png',
179
			iconSize: new L.Point(22, 22),
180
			shadowSize: new L.Point(0, 0),
181
			iconAnchor: new L.Point(11, 11),
182
			popupAnchor: new L.Point(0, -11)
183
		}
184
	}),
185
 
186
	setPopupContent: function(id) {
187
		if(this.bugs[id]._popup_content)
188
			return;
189
 
190
		var el1,el2,el3;
191
		var layer = this;
192
 
193
		var rawbug = putAJAXMarker.bugs[id];
194
		var isclosed = rawbug[2];
195
 
196
		var newContent = L.DomUtil.create('div', 'osb-popup');
197
		var h1 = L.DomUtil.create('h1', null, newContent);
198
		if (rawbug[2])
199
			h1.textContent = L.i18n("Fixed Error");
200
		else if (rawbug[1].length == 1)
201
			h1.textContent = L.i18n("Unresolved Error");
202
		else
203
			h1.textContent = L.i18n("Active Error");
204
 
205
		var divinfo = L.DomUtil.create('div', 'osb-info', newContent);
206
		var table = L.DomUtil.create('table', 'osb-table', divinfo);
207
		for(var i=0; i<rawbug[1].length; i++)
208
		{
209
			var tr = L.DomUtil.create('tr', "osb-tr-info", table);
210
			tr.setAttribute("valign","top")
211
			var td = L.DomUtil.create('td', "osb-td-nickname", tr);
212
			td.textContent = rawbug[5][i] + ':';
213
			var td = L.DomUtil.create('td', "osb-td-datetime", tr);
214
			td.textContent = rawbug[6][i];
215
			var td = L.DomUtil.create('td', "osb-td-comment", L.DomUtil.create('tr', "osb-tr-comment", table));
216
			td.setAttribute("colspan","2");
217
			td.setAttribute("charoff","2");
218
			td.textContent = rawbug[4][i];
219
		}
220
 
221
		function create_link(ul, text) {
222
			var a = L.DomUtil.create('a', null,
223
					L.DomUtil.create('li', null, ul));
224
			a.href = '#';
225
			a.textContent = L.i18n(text);
226
			return a;
227
		};
228
 
229
		var ul = L.DomUtil.create('ul', null, newContent);
230
		var _this = this;
231
		var bug = this.bugs[id];
232
 
233
		function showComment(title, add_comment) {
234
			h1.textContent_old = h1.textContent;
235
			h1.textContent = L.i18n(title);
236
			var form = _this.createCommentForm();
237
			form.osbid.value = id;
238
			form.cancel.onclick = function (e) {
239
				h1.textContent = h1.textContent_old;
240
				newContent.removeChild(form);
241
				newContent.appendChild(ul);
242
			}
243
			form.ok.onclick = function(e) {
244
				bug.closePopup();
245
				if (!add_comment)
246
					_this.closeBug(form);
247
				else
248
					_this.submitComment(form);
249
				return false;
250
			};
251
			newContent.appendChild(form);
252
			newContent.removeChild(ul);
253
			return false;
254
		};
255
 
256
		if (!isclosed && !this.options.readonly) {
257
			var a;
258
			a = create_link(ul, "Add comment");
259
			a.onclick = function(e) { return showComment("Add comment", true); }
260
 
261
			a = create_link(ul, "Mark as Fixed");
262
			a.onclick = function(e) { return showComment("Close bug", false); }
263
		}
264
		var a = create_link(ul, "JOSM");
265
		a.onclick = function() { _this.remoteEdit(rawbug[0]); };
266
 
267
		var a = create_link(ul, "Link");
268
		var vars = {lat:rawbug[0].lat, lon:rawbug[0].lng, zoom:this.options.permalinkZoom, bugid:id}
269
		if (this.options.permalinkUrl)
270
			a.href = L.Util.template(this.options.permalinkUrl, vars)
271
		else
272
			a.href = location.protocol + '//' + location.host + location.pathname +
273
				L.Util.getParamString(vars)
274
 
275
 
276
		bug._popup_content = newContent;
277
		bug.bindPopup(newContent, this.options.popupOptions);
278
		bug._popup.options.maxWidth=410;
279
		bug._popup.options.minWidth=410;
280
		bug.on('mouseover', bug.openTempPopup, bug);
281
	},
282
 
283
	submitComment: function(form) {
284
		if (!form.osbcomment.value) return;
285
		var nickname = form.osbnickname.value || this.options.username;
286
		this.apiRequest("editPOIexec"
287
			+ "?id="+encodeURIComponent(form.osbid.value)
288
			+ "&text="+encodeURIComponent(form.osbcomment.value + " [" + nickname + "]")
289
			+ "&format=js", true
290
		);
291
		this.set_cookie("osbUsername",nickname);
292
		this.options.username=nickname;
293
	},
294
 
295
	closeBug: function(form) {
296
		var id = form.osbid.value;
297
		this.submitComment(form);
298
		this.apiRequest("closePOIexec"
299
			+ "?id="+encodeURIComponent(id)
300
			+ "&format=js", true
301
		);
302
	},
303
 
304
	createCommentForm: function(elt) {
305
		var form = L.DomUtil.create("form", 'osb-add-comment', elt);
306
		var content = '';
307
		content += '<input name="osbid" type="hidden"/>';
308
		content += '<input name="osblat" type="hidden"/>';
309
		content += '<input name="osblon" type="hidden"/>';
310
		content += '<div><span class="osb-inputlabel">'+L.i18n('Nickname')+':</span><input type="text" name="osbnickname"></div>';
311
		content += '<div><span class="osb-inputlabel">'+L.i18n('Comment')+':</span><input type="text" name="osbcomment"></div>';
312
		content += '<div class="osb-formfooter"><input type="submit" name="ok"/><input type="button" name="cancel"/></div>';
313
		form.innerHTML = content;
314
		form.ok.value = L.i18n('OK');
315
		form.cancel.value = L.i18n('Cancel');
316
		form.osbnickname.value = this.options.username;
317
		return form;
318
	},
319
 
320
	addBug: function(e) {
321
		var newContent = L.DomUtil.create('div', 'osb-popup');
322
 
323
		newContent.innerHTML += '<h1>'+L.i18n("New bug")+'</h1>';
324
		newContent.innerHTML += '<div class="osbCreateInfo">'+L.i18n("Find your bug?")+'<br />'+L.i18n("Contact details and someone will fix it.")+'</div>';
325
 
326
		var popup = new L.Popup();
327
		var _this = this;
328
		var form = this.createCommentForm(newContent);
329
		form.osblat.value = e.latlng.lat;
330
		form.osblon.value = e.latlng.lng;
331
		form.ok.value = L.i18n("Add comment");
332
		form.onsubmit = function(e) {
333
			_this._map.closePopup(popup);
334
			_this.createBug(form);
335
			return false;
336
		};
337
		form.cancel.onclick = function(e) { _this._map.closePopup(popup); }
338
 
339
		popup.setLatLng(e.latlng);
340
		popup.setContent(newContent);
341
		popup.options.maxWidth=410;
342
		popup.options.minWidth=410;
343
		popup.options.className += ' osb osbCreate'
344
 
345
		this._map.openPopup(popup);
346
	},
347
 
348
	createBug: function(form) {
349
		if (!form.osbcomment.value) return;
350
		var nickname = form.osbnickname.value || this.options.username;
351
		this.apiRequest("addPOIexec"
352
			+ "?lat="+encodeURIComponent(form.osblat.value)
353
			+ "&lon="+encodeURIComponent(form.osblon.value)
354
			+ "&text="+encodeURIComponent(form.osbcomment.value + " [" + nickname + "]")
355
			+ "&format=js", true
356
		);
357
		this.set_cookie("osbUsername",nickname);
358
		this.options.username=nickname;
359
	},
360
 
361
	remoteEdit: function(x) {
362
		var ydelta = this.options.editArea || 0.01;
363
		var xdelta = ydelta * 2;
364
		var p = [ 'left='  + (x.lng - xdelta), 'bottom=' + (x.lat - ydelta)
365
			, 'right=' + (x.lng + xdelta), 'top='    + (x.lat + ydelta)];
366
		var url = 'http://localhost:8111/load_and_zoom?' + p.join('&');
367
		var frame = L.DomUtil.create('iframe', null);
368
		frame.style.display = 'none';
369
		frame.src = url;
370
		document.body.appendChild(frame);
371
		frame.onload = function(e) { document.body.removeChild(frame); };
372
		return false;
373
	}
374
})
375
 
376
L.OpenStreetBugs.setCSS = function() {
377
	if(L.OpenStreetBugs.setCSS.done)
378
		return;
379
	else
380
		L.OpenStreetBugs.setCSS.done = true;
381
 
382
	// See http://www.hunlock.com/blogs/Totally_Pwn_CSS_with_Javascript
383
	var idx = 0;
384
	var addRule = function(selector, rules) {
385
		var s = document.styleSheets[0];
386
		var rule;
387
		if(s.addRule) // M$IE
388
			rule = s.addRule(selector, rules, idx);
389
		else
390
			rule = s.insertRule(selector + " { " + rules + " }", idx);
391
		s.style = L.Util.extend(s.style || {}, rules);
392
		idx++;
393
	};
394
 
395
	addRule(".osb-popup dl", 'margin:0; padding:0;');
396
	addRule(".osb-popup dt", 'margin:0; padding:0; font-weight:bold; float:left; clear:left;');
397
	addRule(".osb-popup dt:after", 'content: ": ";');
398
	addRule("* html .osb-popup dt", 'margin-right:1ex;');
399
	addRule(".osb-popup dd", 'margin:0; padding:0;');
400
	addRule(".osb-popup ul.buttons", 'list-style-type:none; padding:0; margin:0;');
401
	addRule(".osb-popup ul.buttons li", 'display:inline; margin:0; padding:0;');
402
	addRule(".osb-popup h3", 'font-size:1.2em; margin:.2em 0 .7em 0;');
403
};
404
 
405
function putAJAXMarker(id, lon, lat, text, closed)
406
{
407
	var comments = text.split(/<hr \/>/);
408
	var comments_only = []
409
	var nickname = [];
410
	var datetime = [];
411
	var info = null;
412
	var isplit = 0;
413
	for(var i=0; i<comments.length; i++) {
414
		info = null;
415
		isplit = 0;
416
		comments[i] = comments[i].replace(/&quot;/g, "\"").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&");
417
		isplit = comments[i].lastIndexOf("[");
418
		if (isplit > 0) {
419
		  comments_only[i] = comments[i].substr(0,isplit-1);
420
		  info = comments[i].substr(isplit+1);
421
		  nickname[i] = info.substr(0,info.lastIndexOf(","));
422
		  datetime[i] = info.substr(info.lastIndexOf(",")+2);
423
		  datetime[i] = datetime[i].substr(0,datetime[i].lastIndexOf("]"));
424
		}
425
		else {
426
		  comments_only[i] = comments[i];
427
		}
428
	}
429
	var old = putAJAXMarker.bugs[id];
430
	putAJAXMarker.bugs[id] = [
431
		new L.LatLng(lat, lon),
432
		comments,
433
		closed,
434
		text,
435
		comments_only,
436
		nickname,
437
		datetime
438
	];
439
	var force = (old && old[3]) != text;
440
	for(var i=0; i<putAJAXMarker.layers.length; i++)
441
		putAJAXMarker.layers[i].createMarker(id, force);
442
}
443
 
444
function osbResponse(error)
445
{
446
	if(error)
447
		alert("Error: "+error);
448
 
449
	return;
450
	for(var i=0; i<putAJAXMarker.layers.length; i++)
451
		putAJAXMarker.layers[i].loadBugs();
452
}
453
 
454
putAJAXMarker.layers = [ ];
455
putAJAXMarker.bugs = { };
456
 
457
L.Marker.include({
458
	openTempPopup: function() {
459
		this.openPopup();
460
		this.off('click', this.openPopup, this);
461
 
462
		function onclick() {
463
			this.off('mouseout', onout, this);
464
			this.off('click', onclick, this);
465
			this.on('click', this.openPopup, this)
466
		}
467
 
468
		function onout() {
469
			onclick.call(this);
470
			this.closePopup();
471
		};
472
		this.on("mouseout", onout, this);
473
		this.on("click", onclick, this);
474
	}
475
});
476
 
477
L.i18n = function(s) { return (L.i18n.lang[L.i18n.current] || {})[s] || s; }
478
L.i18n.current = 'ru';
479
L.i18n.lang = {};
480
L.i18n.extend = function(lang, args) {
481
	L.i18n.lang[lang] = L.Util.extend(L.i18n.lang[lang] || {}, args)
482
};
483
 
484
L.i18n.extend('ru', {
485
	"Fixed Error":"Ошибка исправлена",
486
	"Unresolved Error":"Неисправленная ошибка",
487
	"Active Error":"Ошибка уточняется",
488
	"Description":"Описание",
489
	"Comment":"Описание",
490
	"Add comment":"Дополнить",
491
	"Mark as Fixed":"Исправлено",
492
	"Link":"Ссылка",
493
	"Cancel":"Отмена",
494
	"New bug":"Я нашел ошибку",
495
	"Find your bug?":"Нашли ошибку?",
496
	"Contact details and someone will fix it.":"Напишите подробнее и кто-нибудь её исправит."
497
});