[Libreoffice-commits] online.git: loleaflet/Makefile.am loleaflet/src

Tomaž Vajngerl (via logerrit) logerrit at kemper.freedesktop.org
Tue Jul 21 12:47:08 UTC 2020


 loleaflet/Makefile.am                           |    1 
 loleaflet/src/control/Control.Scroll.js         |    2 
 loleaflet/src/layer/AnnotationManagerBase.js    |    1 
 loleaflet/src/layer/AnnotationManagerImpress.js |  346 ++++++++++++++++++++++++
 loleaflet/src/layer/tile/ImpressTileLayer.js    |  310 +--------------------
 5 files changed, 367 insertions(+), 293 deletions(-)

New commits:
commit 3141ba240377059a7709a445bb6041e4ed18b58f
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Sat Jul 18 22:12:36 2020 +0200
Commit:     Tomaž Vajngerl <quikee at gmail.com>
CommitDate: Tue Jul 21 14:46:34 2020 +0200

    AnnotationManagerImpress to manage annotations for Impress
    
    and move thefunctionallity from ImpressTileLayer.js
    
    Change-Id: I646432b677652983384ba53197b5a7af6dd035e0
    Reviewed-on: https://gerrit.libreoffice.org/c/online/+/99019
    Tested-by: Jenkins
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>

diff --git a/loleaflet/Makefile.am b/loleaflet/Makefile.am
index f6d063a76..049a0e977 100644
--- a/loleaflet/Makefile.am
+++ b/loleaflet/Makefile.am
@@ -322,6 +322,7 @@ LOLEAFLET_JS =\
 	src/map/anim/Map.FlyTo.js \
 	src/layer/AnnotationManagerBase.js \
 	src/layer/AnnotationManager.js \
+	src/layer/AnnotationManagerImpress.js \
 	src/control/Control.Scroll.Annotation.js \
 	src/layer/marker/Annotation.js \
 	src/layer/marker/DivOverlay.js \
diff --git a/loleaflet/src/control/Control.Scroll.js b/loleaflet/src/control/Control.Scroll.js
index 0cde2b4c9..9b0936088 100644
--- a/loleaflet/src/control/Control.Scroll.js
+++ b/loleaflet/src/control/Control.Scroll.js
@@ -167,7 +167,7 @@ L.Control.Scroll = L.Control.extend({
 		// Scrolling quickly via mousewheel messes up the annotations for some reason
 		// Triggering the layouting algorithm here, though unnecessary, fixes the problem.
 		// This is just a workaround till we find the root cause of why it messes up the annotations
-		if (this._map._docLayer._annotations.layout) {
+		if (this._map._docLayer._annotations && this._map._docLayer._annotations.layout) {
 			this._map._docLayer._annotations.layout();
 		}
 	},
diff --git a/loleaflet/src/layer/AnnotationManagerBase.js b/loleaflet/src/layer/AnnotationManagerBase.js
index b9e0975d5..967aae236 100644
--- a/loleaflet/src/layer/AnnotationManagerBase.js
+++ b/loleaflet/src/layer/AnnotationManagerBase.js
@@ -8,6 +8,7 @@
 L.AnnotationManagerBase = L.Class.extend({
 	initialize: function (map, options) {
 		this._map = map;
+		this._doclayer = this._map._docLayer;
 		this._initializeSpecific(options);
 	}
 });
diff --git a/loleaflet/src/layer/AnnotationManagerImpress.js b/loleaflet/src/layer/AnnotationManagerImpress.js
new file mode 100644
index 000000000..b3ba6422c
--- /dev/null
+++ b/loleaflet/src/layer/AnnotationManagerImpress.js
@@ -0,0 +1,346 @@
+/* -*- js-indent-level: 8 -*- */
+/*
+ *  L.AnnotationManagerImpress
+ */
+
+/* global L */
+
+L.AnnotationManagerImpress = L.AnnotationManagerBase.extend({
+	options: {
+		marginX: 40,
+		marginY: 10,
+		offset: 5,
+		extraSize: L.point(290, 0)
+	},
+	_initializeSpecific: function () {
+		this._map.on('zoomend', this._onAnnotationZoom, this);
+		this._map.on('AnnotationCancel', this.onAnnotationCancel, this);
+		this._map.on('AnnotationClick', this.onAnnotationClick, this);
+		this._map.on('AnnotationSave', this.onAnnotationSave, this);
+		this._map.on('AnnotationScrollUp', this.onAnnotationScrollUp, this);
+		this._map.on('AnnotationScrollDown', this.onAnnotationScrollDown, this);
+
+		this._annotations = {};
+		this._topAnnotation = [];
+		this._topAnnotation[this.getSelectedPart()] = 0;
+		this._selectedAnnotation = undefined;
+		this._draft = null;
+	},
+	getPartHashes: function() {
+		return this._doclayer._partHashes;
+	},
+	getPartHash: function(part) {
+		return this.getPartHashes()[part];
+	},
+	getSelectedPart: function() {
+		return this._doclayer._selectedPart;
+	},
+	getSelectedPartHash: function() {
+		var part = this.getSelectedPart();
+		return this.getPartHash(part);
+	},
+	getAnnotation: function (id) {
+		var annotations = this._annotations[this.getSelectedPartHash()];
+		for (var index in annotations) {
+			if (annotations[index]._data.id === id) {
+				return annotations[index];
+			}
+		}
+		return null;
+	},
+	newAnnotation: function (comment) {
+		if (this._draft) {
+			return;
+		}
+		this.onAnnotationCancel();
+
+		if (window.mode.isMobile() || window.mode.isTablet()) {
+			this._doclayer.newAnnotationVex(comment, this.onAnnotationSave);
+		}
+		else {
+			this._draft = L.annotation(L.latLng(0, 0), comment, {noMenu: true}).addTo(this._map);
+			this._draft.edit();
+			var mapCenter = this._map.latLngToLayerPoint(this._map.getCenter());
+			var bounds = this._draft.getBounds();
+			var topLeft = mapCenter.subtract(L.point(bounds.max.x - bounds.min.x, (bounds.max.y - bounds.min.y)/2));
+			this._draft.setLatLng(this._map.layerPointToLatLng(topLeft));
+			this.layoutAnnotations();
+			this._draft.focus();
+		}
+	},
+	hideAnnotations: function (part) {
+		this._selectedAnnotation = undefined;
+		var annotations = this._annotations[this.getPartHash(part)];
+		for (var index in annotations) {
+			annotations[index].hide();
+		}
+	},
+	hasAnnotations: function (part) {
+		var annotations = this._annotations[this.getPartHash(part)];
+		return annotations && annotations.length > 0;
+	},
+	updateDocBounds: function (count, extraSize) {
+		var annotations = this._annotations[this.getSelectedPartHash()];
+		if (annotations && annotations.length === count) {
+			this._map._docLayer._updateMaxBounds(true, extraSize);
+		}
+	},
+	_onAnnotationZoom: function () {
+		this.onAnnotationCancel();
+	},
+	onAnnotationCancel: function () {
+		if (this._draft) {
+			this._map.removeLayer(this._draft);
+			this._draft = null;
+		}
+		this._map.focus();
+		this._selectedAnnotation = undefined;
+		this.layoutAnnotations();
+	},
+	onAnnotationModify: function (annotation) {
+		this.onAnnotationCancel();
+		this._selectedAnnotation = annotation._data.id;
+		if (window.mode.isMobile() || window.mode.isTablet()) {
+			this._doclayer.newAnnotationVex(annotation, this.onAnnotationSave, /* isMod */ true);
+		}
+		else {
+			annotation.edit();
+			this.scrollUntilAnnotationIsVisible(annotation);
+			annotation.focus();
+		}
+	},
+	onAnnotationReply: function (annotation) {
+		this.onAnnotationCancel();
+		this._selectedAnnotation = annotation._data.id;
+		annotation.reply();
+		this.scrollUntilAnnotationIsVisible(annotation);
+		annotation.focus();
+	},
+	onAnnotationRemove: function (id) {
+		this.onAnnotationCancel();
+		var comment = {
+			Id: {
+				type: 'string',
+				value: id
+			}
+		};
+		this._map.sendUnoCommand('.uno:DeleteAnnotation', comment);
+		this._map.focus();
+	},
+	onAnnotationClick: function (e) {
+		var comment = {
+			Id: {
+				type: 'string',
+				value: e.annotation._data.id
+			},
+			Text: {
+				type: 'string',
+				value: e.annotation._data.reply
+			}
+		};
+		this._map.sendUnoCommand('.uno:ReplyToAnnotation', comment);
+		this._selectedAnnotation = undefined;
+		this._map.focus();
+	},
+	onAnnotationSave: function (event) {
+		var comment;
+		if (this._draft) {
+			comment = {
+				Text: {
+					type: 'string',
+					value: this._draft._data.text
+				}
+			};
+			this._map.sendUnoCommand('.uno:InsertAnnotation', comment);
+			this._map.removeLayer(this._draft);
+			this._draft = null;
+		} else {
+			comment = {
+				Id: {
+					type: 'string',
+					value: event.annotation._data.id
+				},
+				Text: {
+					type: 'string',
+					value: event.annotation._data.text
+				}
+			};
+			this._map.sendUnoCommand('.uno:EditAnnotation', comment);
+			this._selectedAnnotation = undefined;
+		}
+		this._map.focus();
+	},
+	onAnnotationScrollDown: function () {
+		var part = this.getSelectedPart();
+		this._topAnnotation[part] = Math.min(this._topAnnotation[part] + 1, this._annotations[this.getPartHash(part)].length - 1);
+		var topRight = this._map.latLngToLayerPoint(this._map.options.docBounds.getNorthEast());
+		this._map.fire('scrollby', {x: topRight.x, y: 0});
+		this.onAnnotationCancel();
+	},
+	onAnnotationScrollUp: function () {
+		var part = this.getSelectedPart();
+		if (this._topAnnotation[part] === 0) {
+			this._map.fire('scrollby', {x: 0, y: -100});
+		}
+		this._topAnnotation[part] = Math.max(--this._topAnnotation[part], 0);
+		this.onAnnotationCancel();
+	},
+	onPartChange: function (previous) {
+		var part = this.getSelectedPart();
+		this.hideAnnotations(previous);
+
+		if (this.hasAnnotations(part)) {
+			this._map._docLayer._updateMaxBounds(true);
+			if (this._topAnnotation[part] === undefined) {
+				this._topAnnotation[part] = 0;
+			}
+			this.onAnnotationCancel();
+		}
+	},
+	clearAnnotations: function () {
+		var annotation;
+		var annotations;
+		for (var key in this._annotations) {
+			annotations = this._annotations[key];
+			while (annotations.length > 0) {
+				annotation = annotations.pop();
+				if (annotation) {
+					this._map.removeLayer(annotation);
+				}
+			}
+		}
+		this._annotations = {};
+	},
+	removeAnnotation: function (id) {
+		var annotations = this._annotations[this.getSelectedPartHash()];
+		for (var index in annotations) {
+			if (annotations[index]._data.id == id) {
+				this._map.removeLayer(annotations[index]);
+				annotations.splice(index, 1);
+				break;
+			}
+		}
+	},
+	scrollUntilAnnotationIsVisible: function(annotation) {
+		var bounds = annotation.getBounds();
+		var mapBounds = this._map.getBounds();
+		if (this._map.layerPointToLatLng(bounds.getTopRight()).lat > mapBounds.getNorth()) {
+			this._topAnnotation[this.getSelectedPart()] = Math.max(this._topAnnotation[this.getSelectedPart()] - 2, 0);
+		}
+		else if (this._map.layerPointToLatLng(bounds.getBottomLeft()).lat < mapBounds.getSouth()) {
+			this._topAnnotation[this.getSelectedPart()] = Math.min(this._topAnnotation[this.getSelectedPart()] + 2, this._annotations[this.getSelectedPartHash()].length - 1);
+		}
+		this.layoutAnnotations();
+	},
+	layoutAnnotations: function () {
+		var topAnnotation;
+		var annotations = this._annotations[this.getSelectedPartHash()];
+		var topRight = this._map.latLngToLayerPoint(this._map.options.docBounds.getNorthEast())
+			.add(L.point((this._selectedAnnotation ? 3 : 2) * this.options.marginX, this.options.marginY));
+		var bounds, annotation;
+		for (var index in annotations) {
+			annotation = annotations[index];
+			if (!this._topAnnotation[this.getSelectedPart()]) {
+				this._topAnnotation[this.getSelectedPart()] = 0;
+			}
+			topAnnotation = this._topAnnotation[this.getSelectedPart()];
+			if (topAnnotation > 0 && parseInt(index) === topAnnotation - 1) {
+				// if the top annotation is not the first one, show a bit of the bottom of the previous annotation
+				// so that the user gets aware that there are more annotations above.
+
+				// get annotation bounds
+				annotation.setLatLng(this._map.layerPointToLatLng(L.point(0, -100000))); // placed where it's not visible
+				annotation.show(); // if it's hidden the bounds are wrong
+				bounds = annotation.getBounds();
+				annotation.hide();
+				var topLeft = topRight.subtract(L.point(0, bounds.max.y-bounds.min.y));
+				annotation.setLatLng(this._map.layerPointToLatLng(topLeft));
+				annotation.show();
+				bounds = annotation.getBounds();
+				bounds.extend(L.point(bounds.max.x, bounds.max.y + this.options.marginY));
+
+			} else if (index >= topAnnotation) { // visible annotations
+				if (annotation._data.id === this._selectedAnnotation) {
+					if (bounds) {
+						bounds.extend(L.point(bounds.max.x, bounds.max.y + 2 * this.options.marginY));
+					}
+					var offsetX = L.point(2 * this.options.marginX, 0);
+					topLeft = (bounds ? bounds.getBottomLeft() : topRight).subtract(offsetX);
+					annotation.setLatLng(this._map.layerPointToLatLng(topLeft));
+					bounds = annotation.getBounds();
+					bounds = L.bounds(bounds.getBottomLeft().add(offsetX), bounds.getTopRight().add(offsetX));
+					bounds.extend(L.point(bounds.max.x, bounds.max.y + 3 * this.options.marginY));
+				} else {
+					topLeft = bounds ? bounds.getBottomLeft() : topRight;
+					annotation.setLatLng(this._map.layerPointToLatLng(topLeft));
+					annotation.show();
+					bounds = annotation.getBounds();
+					bounds.extend(L.point(bounds.max.x, bounds.max.y + this.options.marginY));
+				}
+			} else {
+				annotation.hide();
+			}
+		}
+		if (bounds) {
+			if (!this._scrollAnnotation) {
+				this._scrollAnnotation = L.control.scroll.annotation();
+				this._scrollAnnotation.addTo(this._map);
+			}
+		} else if (this._scrollAnnotation) {
+			this._map.removeControl(this._scrollAnnotation);
+			this._scrollAnnotation = null;
+		}
+	},
+	addCommentsFromCommandValues: function (comments) {
+		this.clearAnnotations();
+		for (var index in comments) {
+			var comment = comments[index];
+			if (!this._annotations[comment.parthash]) {
+				this._annotations[comment.parthash] = [];
+			}
+			this._annotations[comment.parthash].push(L.annotation(this._map.options.maxBounds.getSouthEast(), comment).addTo(this._map));
+		}
+		if (!this._topAnnotation) {
+			this._topAnnotation = [];
+		}
+		this._topAnnotation[this.getSelectedPart()] = 0;
+		if (this.hasAnnotations(this.getSelectedPart())) {
+			this._map._docLayer._updateMaxBounds(true);
+		}
+		this.layoutAnnotations();
+	},
+	processCommentMessage: function (comment) {
+		if (comment.action === 'Add') {
+			if (!this._annotations[comment.parthash]) {
+				this._annotations[comment.parthash] = [];
+			}
+			this._annotations[comment.parthash].push(L.annotation(this._map.options.maxBounds.getSouthEast(), comment).addTo(this._map));
+			this._topAnnotation[this.getSelectedPart()] = Math.min(this._topAnnotation[this.getSelectedPart()], this._annotations[this.getSelectedPartHash()].length - 1);
+			this.updateDocBounds(1, this.extraSize);
+			this.layoutAnnotations();
+		} else if (comment.action === 'Remove') {
+			this.removeAnnotation(comment.id);
+			this._topAnnotation[this.getSelectedPart()] = Math.min(this._topAnnotation[this.getSelectedPart()], this._annotations[this.getSelectedPartHash()].length - 1);
+			this.updateDocBounds(0);
+			this.layoutAnnotations();
+		} else if (comment.action === 'Modify') {
+			var modified = this.getAnnotation(comment.id);
+			if (modified) {
+				modified._data = comment;
+				modified.update();
+				this._selectedAnnotation = undefined;
+				this.layoutAnnotations();
+			}
+		}
+	},
+	allocateExtraSize: function() {
+		var annotations = [];
+		if (this._annotations && this.getPartHashes() && this.getSelectedPart() !== undefined)
+			annotations = this._annotations[this.getSelectedPartHash()];
+		return (annotations !== undefined && annotations.length > 0) ? this.options.extraSize : null;
+	}
+});
+
+L.annotationManagerImpress = function (map, options) {
+	return new L.AnnotationManagerImpress(map, options);
+};
diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
index af7e3f34a..67b11cd40 100644
--- a/loleaflet/src/layer/tile/ImpressTileLayer.js
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -6,12 +6,11 @@
 /* global $ L */
 
 L.ImpressTileLayer = L.TileLayer.extend({
-	extraSize: L.point(290, 0),
 
 	initialize: function (url, options) {
 		L.TileLayer.prototype.initialize.call(this, url, options);
 		this._preview = L.control.partsPreview();
-
+		this._partHashes = null;
 		if (window.mode.isMobile()) {
 			this._addButton = L.control.mobileSlide();
 			L.DomUtil.addClass(L.DomUtil.get('mobile-edit-button'), 'impress');
@@ -19,37 +18,17 @@ L.ImpressTileLayer = L.TileLayer.extend({
 	},
 
 	newAnnotation: function (comment) {
-		if (this._draft) {
-			return;
-		}
-		this.onAnnotationCancel();
-
-		if (window.mode.isMobile() || window.mode.isTablet()) {
-			this.newAnnotationVex(comment, this.onAnnotationSave);
-		} else {
-			this._draft = L.annotation(L.latLng(0, 0), comment, {noMenu: true}).addTo(this._map);
-			this._draft.edit();
-			var mapCenter = this._map.latLngToLayerPoint(this._map.getCenter());
-			var bounds = this._draft.getBounds();
-			var topLeft = mapCenter.subtract(L.point(bounds.max.x - bounds.min.x, (bounds.max.y - bounds.min.y)/2));
-			this._draft.setLatLng(this._map.layerPointToLatLng(topLeft));
-			this.layoutAnnotations();
-			this._draft.focus();
-		}
+		this._annotationManager.newAnnotation(comment);
 	},
 
 	beforeAdd: function (map) {
+		this._map = map;
 		map.addControl(this._preview);
-		map.on('zoomend', this._onAnnotationZoom, this);
 		map.on('updateparts', this.onUpdateParts, this);
 		map.on('updatepermission', this.onUpdatePermission, this);
-		map.on('AnnotationCancel', this.onAnnotationCancel, this);
-		map.on('AnnotationReply', this.onReplyClick, this);
-		map.on('AnnotationSave', this.onAnnotationSave, this);
-		map.on('AnnotationScrollUp', this.onAnnotationScrollUp, this);
-		map.on('AnnotationScrollDown', this.onAnnotationScrollDown, this);
 		map.on('resize', this.onResize, this);
 
+		this._annotationManager = L.annotationManagerImpress(map);
 		map.uiManager.initializeSpecializedUI('presentation');
 
 		if (window.mode.isMobile()) {
@@ -71,33 +50,19 @@ L.ImpressTileLayer = L.TileLayer.extend({
 	},
 
 	getAnnotation: function (id) {
-		var annotations = this._annotations[this._partHashes[this._selectedPart]];
-		for (var index in annotations) {
-			if (annotations[index]._data.id === id) {
-				return annotations[index];
-			}
-		}
-		return null;
+		return this._annotationManager.getAnnotation(id);
 	},
 
 	hideAnnotations: function (part) {
-		this._selectedAnnotation = undefined;
-		var annotations = this._annotations[this._partHashes[part]];
-		for (var index in annotations) {
-			annotations[index].hide();
-		}
+		return this._annotationManager.hideAnnotation(part);
 	},
 
 	hasAnnotations: function (part) {
-		var annotations = this._annotations[this._partHashes[part]];
-		return annotations && annotations.length > 0;
+		return this._annotationManager.hasAnnotations(part);
 	},
 
 	updateDocBounds: function (count, extraSize) {
-		var annotations = this._annotations[this._partHashes[this._selectedPart]];
-		if (annotations && annotations.length === count) {
-			this._map._docLayer._updateMaxBounds(true, extraSize);
-		}
+		return this._annotationManager.updateDocBounds(count, extraSize);
 	},
 
 	onResize: function () {
@@ -122,12 +87,6 @@ L.ImpressTileLayer = L.TileLayer.extend({
 
 	onAdd: function (map) {
 		L.TileLayer.prototype.onAdd.call(this, map);
-		this._annotations = {};
-		this._topAnnotation = [];
-		this._topAnnotation[this._selectedPart] = 0;
-		this._selectedAnnotation = undefined;
-		this._draft = null;
-
 		map.on('updatemaxbounds', this._onUpdateMaxBounds, this);
 	},
 
@@ -137,78 +96,19 @@ L.ImpressTileLayer = L.TileLayer.extend({
 	},
 
 	onAnnotationCancel: function () {
-		if (this._draft) {
-			this._map.removeLayer(this._draft);
-			this._draft = null;
-		}
-		this._map.focus();
-		this._selectedAnnotation = undefined;
-		this.layoutAnnotations();
+		this._annotationManager.onAnnotationCancel();
 	},
 
 	onAnnotationModify: function (annotation) {
-		this.onAnnotationCancel();
-		this._selectedAnnotation = annotation._data.id;
-		if (window.mode.isMobile() || window.mode.isTablet()) {
-			this.newAnnotationVex(annotation, this.onAnnotationSave, /* isMod */ true);
-		} else {
-			annotation.edit();
-			this.scrollUntilAnnotationIsVisible(annotation);
-			annotation.focus();
-		}
+		this._annotationManager.onAnnotationModify(annotation);
 	},
 
 	onAnnotationReply: function (annotation) {
-		this.onAnnotationCancel();
-		this._selectedAnnotation = annotation._data.id;
-		annotation.reply();
-		this.scrollUntilAnnotationIsVisible(annotation);
-		annotation.focus();
+		this._annotationManager.onAnnotationReply(annotation);
 	},
 
 	onAnnotationRemove: function (id) {
-		this.onAnnotationCancel();
-		var comment = {
-			Id: {
-				type: 'string',
-				value: id
-			}
-		};
-		this._map.sendUnoCommand('.uno:DeleteAnnotation', comment);
-		this._map.focus();
-	},
-
-	onAnnotationSave: function (e) {
-		var comment;
-		if (this._draft) {
-			comment = {
-				Text: {
-					type: 'string',
-					value: this._draft._data.text
-				}
-			};
-			this._map.sendUnoCommand('.uno:InsertAnnotation', comment);
-			this._map.removeLayer(this._draft);
-			this._draft = null;
-		} else {
-			comment = {
-				Id: {
-					type: 'string',
-					value: e.annotation._data.id
-				},
-				Text: {
-					type: 'string',
-					value: e.annotation._data.text
-				}
-			};
-			this._map.sendUnoCommand('.uno:EditAnnotation', comment);
-			this._selectedAnnotation = undefined;
-		}
-		this._map.focus();
-	},
-
-	_onAnnotationZoom: function () {
-		this.onAnnotationCancel();
+		this._annotationManager.onAnnotationRemove(id);
 	},
 
 	_openMobileWizard: function(data) {
@@ -216,47 +116,9 @@ L.ImpressTileLayer = L.TileLayer.extend({
 		$('mobile-slide-sorter').mCustomScrollbar('update');
 	},
 
-	onReplyClick: function (e) {
-		var comment = {
-			Id: {
-				type: 'string',
-				value: e.annotation._data.id
-			},
-			Text: {
-				type: 'string',
-				value: e.annotation._data.reply
-			}
-		};
-		this._map.sendUnoCommand('.uno:ReplyToAnnotation', comment);
-		this._selectedAnnotation = undefined;
-		this._map.focus();
-	},
-
-	onAnnotationScrollDown: function () {
-		this._topAnnotation[this._selectedPart] = Math.min(++this._topAnnotation[this._selectedPart], this._annotations[this._partHashes[this._selectedPart]].length - 1);
-		this.onAnnotationCancel();
-		var topRight = this._map.latLngToLayerPoint(this._map.options.docBounds.getNorthEast());
-		this._map.fire('scrollby', {x: topRight.x, y: 0});
-	},
-
-	onAnnotationScrollUp: function () {
-		if (this._topAnnotation[this._selectedPart] === 0) {
-			this._map.fire('scrollby', {x: 0, y: -100});
-		}
-		this._topAnnotation[this._selectedPart] = Math.max(--this._topAnnotation[this._selectedPart], 0);
-		this.onAnnotationCancel();
-	},
-
 	onUpdateParts: function () {
 		if (typeof this._prevSelectedPart === 'number') {
-			this.hideAnnotations(this._prevSelectedPart);
-			if (this.hasAnnotations(this._selectedPart)) {
-				this._map._docLayer._updateMaxBounds(true);
-				if (this._topAnnotation[this._selectedPart] === undefined) {
-					this._topAnnotation[this._selectedPart] = 0;
-				}
-				this.onAnnotationCancel();
-			}
+			this._annotationManager.onPartChange(this._prevSelectedPart);
 		}
 	},
 
@@ -271,101 +133,11 @@ L.ImpressTileLayer = L.TileLayer.extend({
 	},
 
 	clearAnnotations: function () {
-		var annotation;
-		var annotations;
-		for (var key in this._annotations) {
-			annotations = this._annotations[key];
-			while (annotations.length > 0) {
-				annotation = annotations.pop();
-				if (annotation) {
-					this._map.removeLayer(annotation);
-				}
-			}
-		}
-		this._annotations = {};
+		this._annotationManager.clearAnnotations();
 	},
 
 	removeAnnotation: function (id) {
-		var annotations = this._annotations[this._partHashes[this._selectedPart]];
-		for (var index in annotations) {
-			if (annotations[index]._data.id == id) {
-				this._map.removeLayer(annotations[index]);
-				annotations.splice(index, 1);
-				break;
-			}
-		}
-	},
-
-	scrollUntilAnnotationIsVisible: function(annotation) {
-		var bounds = annotation.getBounds();
-		var mapBounds = this._map.getBounds();
-		if (this._map.layerPointToLatLng(bounds.getTopRight()).lat > mapBounds.getNorth()) {
-			this._topAnnotation[this._selectedPart] = Math.max(this._topAnnotation[this._selectedPart] - 2, 0);
-		}
-		else if (this._map.layerPointToLatLng(bounds.getBottomLeft()).lat < mapBounds.getSouth()) {
-			this._topAnnotation[this._selectedPart] = Math.min(this._topAnnotation[this._selectedPart] + 2, this._annotations[this._partHashes[this._selectedPart]].length - 1);
-		}
-		this.layoutAnnotations();
-	},
-
-	layoutAnnotations: function () {
-		var topAnnotation;
-		var annotations = this._annotations[this._partHashes[this._selectedPart]];
-		var topRight = this._map.latLngToLayerPoint(this._map.options.docBounds.getNorthEast())
-			.add(L.point((this._selectedAnnotation ? 3 : 2) * this.options.marginX, this.options.marginY));
-		var bounds, annotation;
-		for (var index in annotations) {
-			annotation = annotations[index];
-			if (!this._topAnnotation[this._selectedPart]) {
-				this._topAnnotation[this._selectedPart] = 0;
-			}
-			topAnnotation = this._topAnnotation[this._selectedPart];
-			if (topAnnotation > 0 && parseInt(index) === topAnnotation - 1) {
-				// if the top annotation is not the first one, show a bit of the bottom of the previous annotation
-				// so that the user gets aware that there are more annotations above.
-
-				// get annotation bounds
-				annotation.setLatLng(this._map.layerPointToLatLng(L.point(0, -100000))); // placed where it's not visible
-				annotation.show(); // if it's hidden the bounds are wrong
-				bounds = annotation.getBounds();
-				annotation.hide();
-				var topLeft = topRight.subtract(L.point(0, bounds.max.y-bounds.min.y));
-				annotation.setLatLng(this._map.layerPointToLatLng(topLeft));
-				annotation.show();
-				bounds = annotation.getBounds();
-				bounds.extend(L.point(bounds.max.x, bounds.max.y + this.options.marginY));
-
-			} else if (index >= topAnnotation) { // visible annotations
-				if (annotation._data.id === this._selectedAnnotation) {
-					if (bounds) {
-						bounds.extend(L.point(bounds.max.x, bounds.max.y + 2 * this.options.marginY));
-					}
-					var offsetX = L.point(2 * this.options.marginX, 0);
-					topLeft = (bounds ? bounds.getBottomLeft() : topRight).subtract(offsetX);
-					annotation.setLatLng(this._map.layerPointToLatLng(topLeft));
-					bounds = annotation.getBounds();
-					bounds = L.bounds(bounds.getBottomLeft().add(offsetX), bounds.getTopRight().add(offsetX));
-					bounds.extend(L.point(bounds.max.x, bounds.max.y + 3 * this.options.marginY));
-				} else {
-					topLeft = bounds ? bounds.getBottomLeft() : topRight;
-					annotation.setLatLng(this._map.layerPointToLatLng(topLeft));
-					annotation.show();
-					bounds = annotation.getBounds();
-					bounds.extend(L.point(bounds.max.x, bounds.max.y + this.options.marginY));
-				}
-			} else {
-				annotation.hide();
-			}
-		}
-		if (bounds) {
-			if (!this._scrollAnnotation) {
-				this._scrollAnnotation = L.control.scroll.annotation();
-				this._scrollAnnotation.addTo(this._map);
-			}
-		} else if (this._scrollAnnotation) {
-			this._map.removeControl(this._scrollAnnotation);
-			this._scrollAnnotation = null;
-		}
+		this._annotationManager.removeAnnotation(id);
 	},
 
 	_onCommandValuesMsg: function (textMsg) {
@@ -381,65 +153,21 @@ L.ImpressTileLayer = L.TileLayer.extend({
 		}
 
 		if (values.comments) {
-			this._addCommentsFromCommandValues(values.comments);
+			this._annotationManager.addCommentsFromCommandValues(values.comments);
 		} else {
 			L.TileLayer.prototype._onCommandValuesMsg.call(this, textMsg);
 		}
 	},
 
-	_addCommentsFromCommandValues: function (comments) {
-		this.clearAnnotations();
-		for (var index in comments) {
-			var comment = comments[index];
-			if (!this._annotations[comment.parthash]) {
-				this._annotations[comment.parthash] = [];
-			}
-			this._annotations[comment.parthash].push(L.annotation(this._map.options.maxBounds.getSouthEast(), comment).addTo(this._map));
-		}
-		if (!this._topAnnotation) {
-			this._topAnnotation = [];
-		}
-		this._topAnnotation[this._selectedPart] = 0;
-		if (this.hasAnnotations(this._selectedPart)) {
-			this._map._docLayer._updateMaxBounds(true);
-		}
-		this.layoutAnnotations();
-	},
-
 	_onMessage: function (textMsg, img) {
 		if (textMsg.startsWith('comment:')) {
 			var object = JSON.parse(textMsg.substring('comment:'.length + 1));
-			this._processCommentMessage(object.comment);
+			this._annotationManager.processCommentMessage(object.comment);
 		} else {
 			L.TileLayer.prototype._onMessage.call(this, textMsg, img);
 		}
 	},
 
-	_processCommentMessage: function (comment) {
-		if (comment.action === 'Add') {
-			if (!this._annotations[comment.parthash]) {
-				this._annotations[comment.parthash] = [];
-			}
-			this._annotations[comment.parthash].push(L.annotation(this._map.options.maxBounds.getSouthEast(), comment).addTo(this._map));
-			this._topAnnotation[this._selectedPart] = Math.min(this._topAnnotation[this._selectedPart], this._annotations[this._partHashes[this._selectedPart]].length - 1);
-			this.updateDocBounds(1, this.extraSize);
-			this.layoutAnnotations();
-		} else if (comment.action === 'Remove') {
-			this.removeAnnotation(comment.id);
-			this._topAnnotation[this._selectedPart] = Math.min(this._topAnnotation[this._selectedPart], this._annotations[this._partHashes[this._selectedPart]].length - 1);
-			this.updateDocBounds(0);
-			this.layoutAnnotations();
-		} else if (comment.action === 'Modify') {
-			var modified = this.getAnnotation(comment.id);
-			if (modified) {
-				modified._data = comment;
-				modified.update();
-				this._selectedAnnotation = undefined;
-				this.layoutAnnotations();
-			}
-		}
-	},
-
 	_onInvalidateTilesMsg: function (textMsg) {
 		var command = this._map._socket.parseServerCmd(textMsg);
 		if (command.x === undefined || command.y === undefined || command.part === undefined) {
@@ -570,9 +298,7 @@ L.ImpressTileLayer = L.TileLayer.extend({
 
 	_updateMaxBounds: function (sizeChanged, extraSize) {
 		if (!extraSize) {
-			var annotations = this._annotations && this._partHashes && this._selectedPart !== undefined ?
-				this._annotations[this._partHashes[this._selectedPart]] : [];
-			extraSize = annotations && annotations.length > 0 ? this.extraSize : null;
+			extraSize = this._annotationManager.allocateExtraSize();
 		}
 		L.GridLayer.prototype._updateMaxBounds.call(this, sizeChanged, extraSize, {panInside: false});
 	},


More information about the Libreoffice-commits mailing list