[Libreoffice-commits] online.git: 14 commits - loleaflet/build loleaflet/README loleaflet/spec loleaflet/src

Mihai Varga mihai.varga at collabora.com
Wed Sep 2 08:09:54 PDT 2015


 loleaflet/README                              |   22 -
 loleaflet/build/deps.js                       |   18 
 loleaflet/spec/loadtest/LoadTestSpec.js       |   36 -
 loleaflet/spec/loleaflet/loleafletSpec.js     |   23 -
 loleaflet/spec/tilebench/TileBenchSpec.js     |   28 -
 loleaflet/src/control/Control.Parts.js        |    6 
 loleaflet/src/control/Control.PartsPreview.js |    8 
 loleaflet/src/control/Control.Tabs.js         |    4 
 loleaflet/src/control/Parts.js                |   44 +-
 loleaflet/src/core/Socket.js                  |   33 +
 loleaflet/src/layer/tile/CalcTileLayer.js     |  127 ++++++
 loleaflet/src/layer/tile/GridLayer.js         |   34 -
 loleaflet/src/layer/tile/ImpressTileLayer.js  |  157 ++++++++
 loleaflet/src/layer/tile/TileLayer.js         |  505 +++++++++++---------------
 loleaflet/src/layer/tile/WriterTileLayer.js   |  158 ++++++++
 15 files changed, 793 insertions(+), 410 deletions(-)

New commits:
commit 91b295fca58492122e157234c67b3971fdfc40f2
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 18:09:08 2015 +0300

    loleaflet: updated the tests to reflect the new map initialization

diff --git a/loleaflet/spec/loadtest/LoadTestSpec.js b/loleaflet/spec/loadtest/LoadTestSpec.js
index c339926..7be5091 100644
--- a/loleaflet/spec/loadtest/LoadTestSpec.js
+++ b/loleaflet/spec/loadtest/LoadTestSpec.js
@@ -15,16 +15,9 @@ describe('LoadTest', function () {
 		if (docPath === 'file:///PATH') {
 			throw new Error('Document file path not set');
 		}
-
-		map = L.map('map-test', {
-			center: [0, 0],
-			zoom: 10,
-			minZoom: 1,
-			maxZoom: 20,
-			server: 'ws://localhost:9980',
-			doubleClickZoom: false
-		});
-		map.on('docsize', function (e) { x = e.x; y = e.y; }, this);
+		else if (docPath[docPath.length - 1] !== '/') {
+			docPath += '/';
+		}
 	});
 
 	var docPath = 'file:///PATH';
@@ -39,28 +32,23 @@ describe('LoadTest', function () {
 			});
 
 			after(function () {
-				map.removeLayer(docLayer);
+				map.remove();
 			});
 
 			it('Load the document', function (done) {
-				map._initSocket();
-				map.on('statusindicator', function (e) {
-					if (e.statusType === 'alltilesloaded') {
-						done();
-					}
-				});
-
-				docLayer = new L.TileLayer('', {
+				map = L.map('map-test', {
+					server: 'ws://localhost:9980',
 					doc: docPath + testDoc,
-					useSocket : true,
 					edit: false,
 					readOnly: false
 				});
 
-				// don't pre-fetch tiles
-				docLayer._preFetchTiles = L.Util.falseFn;
-
-				map.addLayer(docLayer);
+				map.on('statusindicator', function (e) {
+					if (e.statusType === 'alltilesloaded') {
+						y = map.getDocSize().y;
+						done();
+					}
+				});
 			});
 
 			it('Scroll to the middle', function (done) {
diff --git a/loleaflet/spec/loleaflet/loleafletSpec.js b/loleaflet/spec/loleaflet/loleafletSpec.js
index 2d0edf5..fd16985 100644
--- a/loleaflet/spec/loleaflet/loleafletSpec.js
+++ b/loleaflet/spec/loleaflet/loleafletSpec.js
@@ -15,34 +15,11 @@ describe('TileBench', function () {
 	before(function () {
 		// initialize the map and load the document
 		map = L.map('map', {
-			center: [0, 0],
-			zoom: 10,
-			minZoom: 1,
-			maxZoom: 20,
 			server: 'ws://localhost:9980',
-			doubleClickZoom: false
-		});
-
-		var docLayer = new L.TileLayer('', {
 			doc: 'file:///home/mihai/Desktop/test_docs/eval.odt',
-			useSocket : true,
 			edit: false,
 			readOnly: false
 		});
-
-		docLayer.sendMessage = L.bind(function (msg, coords) {
-			var now = Date.now();
-			if (msg.startsWith('tile')) {
-				msg += ' timestamp=' + now;
-			}
-			L.Log.log(msg, L.OUTGOING, coords, now);
-			this._map.socket.send(msg);
-		}, docLayer);
-
-		// don't pre-fetch tiles
-		docLayer._preFetchTiles = L.Util.falseFn;
-
-		map.addLayer(docLayer);
 	});
 
 	afterEach(function () {
diff --git a/loleaflet/spec/tilebench/TileBenchSpec.js b/loleaflet/spec/tilebench/TileBenchSpec.js
index a15cdb1..463f2d2 100644
--- a/loleaflet/spec/tilebench/TileBenchSpec.js
+++ b/loleaflet/spec/tilebench/TileBenchSpec.js
@@ -16,36 +16,23 @@ describe('TileBench', function () {
 	before(function () {
 		// initialize the map and load the document
 		map = L.map('map', {
-			center: [0, 0],
-			zoom: 10,
-			minZoom: 1,
-			maxZoom: 20,
 			server: 'ws://localhost:9980',
-			doubleClickZoom: false
-		});
-
-		var docLayer = new L.TileLayer('', {
 			doc: 'file:///home/mihai/Desktop/test_docs/eval.odt',
-			useSocket : true,
 			edit: false,
 			readOnly: false
 		});
 
 		// add a timestamp to tile messages so we can identify
 		// the response
-		docLayer.sendMessage = L.bind(function (msg, coords) {
+		L.Socket.sendMessage = L.bind(function (msg, coords) {
 			var now = Date.now();
 			if (msg.startsWith('tile')) {
 				msg += ' timestamp=' + now;
 			}
 			L.Log.log(msg, L.OUTGOING, coords, now);
-			this._map.socket.send(msg);
-		}, docLayer);
-
-		// don't pre-fetch tiles
-		docLayer._preFetchTiles = L.Util.falseFn;
+			this.socket.send(msg);
+		}, L.Socket);
 
-		map.addLayer(docLayer);
 		map.addControl(L.control.scroll());
 	});
 
@@ -54,15 +41,14 @@ describe('TileBench', function () {
 	});
 
 	after(function () {
-		map.socket.onclose = undefined;
-		map.socket.onerror = undefined;
-		map.socket.close();
+		map.remove();
 	});
 
 	describe('Benchmarking', function () {
 		it('Load all new tiles', function (done) {
 			map.on('statusindicator', function (e) {
 				if (e.statusType === 'alltilesloaded') {
+					map.fire('requestloksession');
 					done();
 				}
 			});
@@ -90,7 +76,7 @@ describe('TileBench', function () {
 				var y = Math.floor(docLayer._docHeightTwips / docLayer._tileHeightTwips);
 				var coords = new L.Point(x, y);
 				coords.z = map.getZoom();
-				coords.part = docLayer._currentPart;
+				coords.part = docLayer._selectedPart;
 				var key = docLayer._tileCoordsToKey(coords);
 				if (docLayer._tiles[key]) {
 					// the tile is already here, the whole document is loaded
@@ -102,7 +88,7 @@ describe('TileBench', function () {
 
 			for (var i = 0; i < keyInput.length; i++) {
 				setTimeout(L.bind(function () {
-					map._docLayer.sendMessage(keyInput[this][1]);
+					L.Socket.sendMessage(keyInput[this][1]);
 				}, i), keyInput[i][0]);
 			}
 		});
commit c7672438f032b8b30b2101ca3833e31586dbf65c
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 17:23:33 2015 +0300

    loleaflet: autoupdate previews from the preview control

diff --git a/loleaflet/src/control/Control.PartsPreview.js b/loleaflet/src/control/Control.PartsPreview.js
index 1bec8a4..4112d01 100644
--- a/loleaflet/src/control/Control.PartsPreview.js
+++ b/loleaflet/src/control/Control.PartsPreview.js
@@ -3,6 +3,10 @@
  */
 
 L.Control.PartsPreview = L.Control.extend({
+	options: {
+		autoUpdate: true
+	},
+
 	onAdd: function (map) {
 		this._previewInitialized = false;
 		this._previewTiles = {};
@@ -42,7 +46,7 @@ L.Control.PartsPreview = L.Control.extend({
 					.on(img, 'click', L.DomEvent.stop)
 					.on(img, 'click', this._setPart, this)
 					.on(img, 'click', this._refocusOnMap, this);
-				this._map.getPartPreview(i, i, 180, 180);
+				this._map.getPartPreview(i, i, 180, 180, {autoUpdate: this.options.autoUpdate});
 			}
 			this._previewInitialized = true;
 		}
@@ -57,7 +61,7 @@ L.Control.PartsPreview = L.Control.extend({
 
 	_updatePart: function (e) {
 		if (e.docType === 'presentation') {
-			this._map.getPartPreview(e.part, e.part, 180, 180);
+			this._map.getPartPreview(e.part, e.part, 180, 180, {autoUpdate: this.options.autoUpdate});
 		}
 	},
 
commit dc617eb7009ef1e5ae0a27495fa0287a57a9e125
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 17:21:35 2015 +0300

    loleaflet: impress preview invalidation

diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
index 2a437ef..2acc5c3 100644
--- a/loleaflet/src/layer/tile/ImpressTileLayer.js
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -86,6 +86,10 @@ L.ImpressTileLayer = L.TileLayer.extend({
 			this._lastValidPart = command.part;
 			this._map.fire('updatepart', {part: command.part, docType: this._docType});
 		}
+
+		// 1s after the last invalidation, update the preview
+		clearTimeout(this._previewInvalidator);
+		this._previewInvalidator = setTimeout(L.bind(this._invalidatePreview, this), 1000);
 	},
 
 	_onSetPartMsg: function (textMsg) {
@@ -124,6 +128,30 @@ L.ImpressTileLayer = L.TileLayer.extend({
 				this._preFetchPart = this._selectedPart;
 				this._preFetchBorder = null;
 			}
-        }
+		}
+	},
+
+	_invalidatePreview: function () {
+		if (this._map._docPreviews) {
+			// invalidate part previews
+			for (var key in this._map._docPreviews) {
+				var preview = this._map._docPreviews[key];
+				if (preview.part === this._selectedPart ||
+					(preview.part === this._prevSelectedPart && this._prevSelectedPartNeedsUpdate)) {
+					// if the current part needs its preview updated OR
+					// the part has been changed and we need to update the previous part preview
+					if (preview.part === this._prevSelectedPart) {
+						this._prevSelectedPartNeedsUpdate = false;
+					}
+					if (preview.autoUpdate) {
+						this._map.getPartPreview(preview.id, preview.part, preview.maxWidth, preview.maxHeight,
+								{autoUpdate: true});
+					}
+					else {
+						this._map.fire('invalidatepreview', {id: preview.id});
+					}
+				}
+			}
+		}
 	}
 });
commit 5e843d23814c055a4da3b94625ecaf0d63ba23b4
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 17:21:19 2015 +0300

    loleaflet: writer preview invalidation

diff --git a/loleaflet/src/layer/tile/WriterTileLayer.js b/loleaflet/src/layer/tile/WriterTileLayer.js
index 68260a1..fe85e9d 100644
--- a/loleaflet/src/layer/tile/WriterTileLayer.js
+++ b/loleaflet/src/layer/tile/WriterTileLayer.js
@@ -79,6 +79,13 @@ L.WriterTileLayer = L.TileLayer.extend({
 				delete this._tileCache[key];
 			}
 		}
+		if (!this._previewInvalidations) {
+			this._previewInvalidations = [];
+		}
+		this._previewInvalidations.push(invalidBounds);
+		// 1s after the last invalidation, update the preview
+		clearTimeout(this._previewInvalidator);
+		this._previewInvalidator = setTimeout(L.bind(this._invalidatePreview, this), 1000);
 	},
 
 	_onSetPartMsg: function (textMsg) {
@@ -111,5 +118,41 @@ L.WriterTileLayer = L.TileLayer.extend({
 			this._resetPreFetching(true);
 			this._update();
 		}
+	},
+
+	_invalidatePreview: function () {
+		// invalidate writer page previews
+		if (this._map._docPreviews && this._previewInvalidations) {
+			var toInvalidate = {};
+			for (var i = 0; i < this._previewInvalidations.length; i++) {
+				var invalidBounds = this._previewInvalidations[i];
+				var invalidPixBounds = new L.Bounds(
+						invalidBounds.min.divideBy(this.options.tileWidthTwips).multiplyBy(this._tileSize),
+						invalidBounds.max.divideBy(this.options.tileWidthTwips).multiplyBy(this._tileSize));
+
+				for (var key in this._map._docPreviews) {
+					// find preview tiles that need to be updated and add them in a set
+					var preview = this._map._docPreviews[key];
+					var bounds = new L.Bounds(new L.Point(preview.x, preview.y),
+											  new L.Point(preview.x + preview.width, preview.y + preview.height));
+					if (invalidPixBounds.intersects(bounds)) {
+						toInvalidate[key] = true;
+					}
+				}
+
+				for (key in toInvalidate) {
+					// update invalid preview tiles
+					preview = this._map._docPreviews[key];
+					if (preview.autoUpdate) {
+						this._map.getDocPreview(preview.id, preview.maxWidth, preview.maxHeight,
+								preview.x, preview.y, preview.width, preview.height, {autoUpdate: true});
+					}
+					else {
+						this._map.fire('invalidatepreview', {id: preview.id});
+					}
+				}
+			}
+		}
+		this._previewInvalidations = [];
 	}
 });
commit 2a2eb14532b914ebcde09e5ccf9063105170d36f
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 17:12:02 2015 +0300

    loleaflet: option for automatically updating the previews

diff --git a/loleaflet/README b/loleaflet/README
index f5b3488..dbf59a7 100644
--- a/loleaflet/README
+++ b/loleaflet/README
@@ -90,10 +90,11 @@ Buttons like Bold, Italic, Strike through etc.
 Parts (like slides in presentation, or sheets in spreadsheets):
     - API:
         map.setPart('next' | 'prev' | partNumber)
-        map.getPartPreview(id, part, maxWidth, maxHeight) where:
+        map.getPartPreview(id, part, maxWidth, maxHeight, [options]) where:
             + id = the ID of the request so that the response can be identified
             + maxWidth / maxHeight are the desired dimensions of the preview, a smaller
               image might be returned in order to keep the original ratio of the document
+            + options = {autoUpdate: true} - automatically updates the previews
         map.getNumberOfParts()
         map.getCurrentPartNumber()
     - events:
@@ -102,6 +103,8 @@ Parts (like slides in presentation, or sheets in spreadsheets):
             + e.parts == the number of parts that the document has
             + e.docType == 'text' | 'spreadsheet' | 'presentation' | 'drawing' | 'other'
             + [e.partNames] if present, part names (e.g. sheet names)
+        map.on('invalidatepreview', function (e) {})
+            + e.id = the preview's id
 
 Statusindicator (when the document is loading):
     - events
@@ -161,17 +164,20 @@ Writer pages:
         map.goToPage(page)
         map.getNumberOfPages()
         map.getCurrentPageNumber()
-        map.getDocPreview(id, maxWidth, maxHeight, x, y, width, height)
+        map.getDocPreview(id, maxWidth, maxHeight, x, y, width, height, [options])
             + id = the ID of the request so that the response can be identified
             + maxWidth / maxHeight are the desired dimensions of the preview, a smaller
               image might be returned in order to keep the original ratio of the document
             + x/y = starting position, where to get the preview from
+            + options = {autoUpdate: true} - automatically updates the previews
 
     - events
         map.on('pagenumberchanged', function (e) {}) where:
             + e.currentPage = the page on which the cursor lies
             + e.pages = number of pages
             + e.docType = document type, should be 'text'
+        map.on('invalidatepreview', function (e) {})
+            + e.id = the preview's id
 
 Styles:
     - API:
diff --git a/loleaflet/src/control/Parts.js b/loleaflet/src/control/Parts.js
index 08e1c89..040d909 100644
--- a/loleaflet/src/control/Parts.js
+++ b/loleaflet/src/control/Parts.js
@@ -4,6 +4,7 @@
 L.Map.include({
 	setPart: function (part) {
 		var docLayer = this._docLayer;
+		docLayer._prevSelectedPart = docLayer._selectedPart;
 		if (part === 'prev') {
 			if (docLayer._selectedPart > 0) {
 				docLayer._selectedPart -= 1;
@@ -33,9 +34,19 @@ L.Map.include({
 		docLayer._update();
 		docLayer._pruneTiles();
 		docLayer._clearSelections();
+		docLayer._prevSelectedPartNeedsUpdate = true;
+		if (docLayer._invalidatePreview) {
+			docLayer._invalidatePreview();
+		}
 	},
 
-	getPartPreview: function (id, part, maxWidth, maxHeight) {
+	getPartPreview: function (id, part, maxWidth, maxHeight, options) {
+		if (!this._docPreviews) {
+			this._docPreviews = {};
+		}
+		var autoUpdate = options ? options.autoUpdate : false;
+		this._docPreviews[id] = {id: id, part: part, maxWidth: maxWidth, maxHeight: maxHeight, autoUpdate: autoUpdate};
+
 		var docLayer = this._docLayer;
 		var docRatio = docLayer._docWidthTwips / docLayer._docHeightTwips;
 		var imgRatio = maxWidth / maxHeight;
@@ -56,7 +67,14 @@ L.Map.include({
 							'id=' + id);
 	},
 
-	getDocPreview: function (id, maxWidth, maxHeight, x, y, width, height) {
+	getDocPreview: function (id, maxWidth, maxHeight, x, y, width, height, options) {
+		if (!this._docPreviews) {
+			this._docPreviews = {};
+		}
+		var autoUpdate = options ? options.autoUpdate : false;
+		this._docPreviews[id] = {id: id, maxWidth: maxWidth, maxHeight: maxHeight, x: x, y: y,
+			width: width, height: height, autoUpdate: autoUpdate};
+
 		var docLayer = this._docLayer;
 		var docRatio = width / height;
 		var imgRatio = maxWidth / maxHeight;
@@ -83,6 +101,12 @@ L.Map.include({
 							'id=' + id);
 	},
 
+	removePreviewUpdate: function (id) {
+		if (this._docPreviews && this._docPreviews[id]) {
+			this._docPreviews[id].autoUpdate = false;
+		}
+	},
+
 	goToPage: function (page) {
 		var docLayer = this._docLayer;
 		if (page === 'prev') {
commit f8aab94e49a5dbcfa565107e4af4f1aacf9939c4
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 15:14:00 2015 +0300

    loleaflet: setPart msg is now handled separately

diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 4a0d1fb..7550ddb 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -86,6 +86,16 @@ L.CalcTileLayer = L.TileLayer.extend({
 		}
 	},
 
+	_onSetPartMsg: function (textMsg) {
+		var part = parseInt(textMsg.match(/\d+/g)[0]);
+		if (part !== this._selectedPart) {
+			this._selectedPart = part;
+			this._update();
+			this._clearSelections();
+			this._map.fire('setpart', {selectedPart: this._selectedPart});
+		}
+	},
+
 	_onStatusMsg: function (textMsg) {
 		var command = L.Socket.parseServerCmd(textMsg);
 		if (command.width && command.height && this._documentInfo !== textMsg) {
@@ -106,6 +116,7 @@ L.CalcTileLayer = L.TileLayer.extend({
 				docType: this._docType,
 				partNames: partNames
 			});
+			this._resetPreFetching(true);
 			this._update();
 			if (this._preFetchPart !== this._selectedPart) {
 				this._preFetchPart = this._selectedPart;
diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
index d9eddf1..2a437ef 100644
--- a/loleaflet/src/layer/tile/ImpressTileLayer.js
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -88,31 +88,42 @@ L.ImpressTileLayer = L.TileLayer.extend({
 		}
 	},
 
+	_onSetPartMsg: function (textMsg) {
+		var part = parseInt(textMsg.match(/\d+/g)[0]);
+		if (part !== this._selectedPart) {
+			this._selectedPart = part;
+			this._update();
+			this._clearSelections();
+			this._map.fire('setpart', {selectedPart: this._selectedPart});
+		}
+	},
+
 	_onStatusMsg: function (textMsg) {
 		var command = L.Socket.parseServerCmd(textMsg);
 		if (command.width && command.height && this._documentInfo !== textMsg) {
 			this._docWidthTwips = command.width;
-            this._docHeightTwips = command.height;
-            this._docType = command.type;
-            this._updateMaxBounds(true);
-            this._documentInfo = textMsg;
-            this._parts = command.parts;
-            this._selectedPart = command.selectedPart;
-            L.Socket.sendMessage('setclientpart part=' + this._selectedPart);
-            var partNames = textMsg.match(/[^\r\n]+/g);
-            // only get the last matches
-            partNames = partNames.slice(partNames.length - this._parts);
-            this._map.fire('updateparts', {
-                selectedPart: this._selectedPart,
-                parts: this._parts,
-                docType: this._docType,
-                partNames: partNames
-            });
-            this._update();
-            if (this._preFetchPart !== this._selectedPart) {
-                this._preFetchPart = this._selectedPart;
-                this._preFetchBorder = null;
-            }
+			this._docHeightTwips = command.height;
+			this._docType = command.type;
+			this._updateMaxBounds(true);
+			this._documentInfo = textMsg;
+			this._parts = command.parts;
+			this._selectedPart = command.selectedPart;
+			L.Socket.sendMessage('setclientpart part=' + this._selectedPart);
+			var partNames = textMsg.match(/[^\r\n]+/g);
+			// only get the last matches
+			partNames = partNames.slice(partNames.length - this._parts);
+			this._map.fire('updateparts', {
+				selectedPart: this._selectedPart,
+				parts: this._parts,
+				docType: this._docType,
+				partNames: partNames
+			});
+			this._resetPreFetching(true);
+			this._update();
+			if (this._preFetchPart !== this._selectedPart) {
+				this._preFetchPart = this._selectedPart;
+				this._preFetchBorder = null;
+			}
         }
 	}
 });
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 2de696d..97ced2f 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -271,24 +271,6 @@ L.TileLayer = L.GridLayer.extend({
 		this._map.fire('search', {originalPhrase: originalPhrase, count: 0});
 	},
 
-	_onSetPartMsg: function (textMsg) {
-		var part = parseInt(textMsg.match(/\d+/g)[0]);
-		if (part !== this._selectedPart && this._docType !== 'text') {
-			this._selectedPart = part;
-			this._update();
-			this._clearSelections();
-			this._map.fire('setpart', {selectedPart: this._selectedPart});
-		}
-		else if (this._docType === 'text') {
-			this._currentPage = part;
-			this._map.fire('pagenumberchanged', {
-				currentPage: part,
-				pages: this._pages,
-				docType: this._docType
-			});
-		}
-	},
-
 	_onStateChangedMsg: function (textMsg) {
 		var unoMsg = textMsg.substr(14);
 		var unoCmd = unoMsg.match('.uno:(.*)=')[1];
diff --git a/loleaflet/src/layer/tile/WriterTileLayer.js b/loleaflet/src/layer/tile/WriterTileLayer.js
index 178c8e6..68260a1 100644
--- a/loleaflet/src/layer/tile/WriterTileLayer.js
+++ b/loleaflet/src/layer/tile/WriterTileLayer.js
@@ -81,9 +81,18 @@ L.WriterTileLayer = L.TileLayer.extend({
 		}
 	},
 
+	_onSetPartMsg: function (textMsg) {
+		var part = parseInt(textMsg.match(/\d+/g)[0]);
+		this._currentPage = part;
+		this._map.fire('pagenumberchanged', {
+			currentPage: part,
+			pages: this._pages,
+			docType: this._docType
+		});
+	},
+
 	_onStatusMsg: function (textMsg) {
 		var command = L.Socket.parseServerCmd(textMsg);
-		console.log(textMsg);
 		if (command.width && command.height && this._documentInfo !== textMsg) {
 			this._docWidthTwips = command.width;
 			this._docHeightTwips = command.height;
@@ -99,6 +108,7 @@ L.WriterTileLayer = L.TileLayer.extend({
 				pages: this._pages,
 				docType: this._docType
 			});
+			this._resetPreFetching(true);
 			this._update();
 		}
 	}
commit 58862970c38496304292b0dfabffaadc43cc5a10
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 14:28:02 2015 +0300

    loleaflet: the status msg is handled now separately

diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 687d03a..4a0d1fb 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -84,5 +84,33 @@ L.CalcTileLayer = L.TileLayer.extend({
 				delete this._tileCache[key];
 			}
 		}
+	},
+
+	_onStatusMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.width && command.height && this._documentInfo !== textMsg) {
+			this._docWidthTwips = command.width;
+			this._docHeightTwips = command.height;
+			this._docType = command.type;
+			this._updateMaxBounds(true);
+			this._documentInfo = textMsg;
+			this._parts = command.parts;
+			this._selectedPart = command.selectedPart;
+			L.Socket.sendMessage('setclientpart part=' + this._selectedPart);
+			var partNames = textMsg.match(/[^\r\n]+/g);
+			// only get the last matches
+			partNames = partNames.slice(partNames.length - this._parts);
+			this._map.fire('updateparts', {
+				selectedPart: this._selectedPart,
+				parts: this._parts,
+				docType: this._docType,
+				partNames: partNames
+			});
+			this._update();
+			if (this._preFetchPart !== this._selectedPart) {
+				this._preFetchPart = this._selectedPart;
+				this._preFetchBorder = null;
+			}
+		}
 	}
 });
diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
index ba2f765..d9eddf1 100644
--- a/loleaflet/src/layer/tile/ImpressTileLayer.js
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -86,5 +86,33 @@ L.ImpressTileLayer = L.TileLayer.extend({
 			this._lastValidPart = command.part;
 			this._map.fire('updatepart', {part: command.part, docType: this._docType});
 		}
+	},
+
+	_onStatusMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.width && command.height && this._documentInfo !== textMsg) {
+			this._docWidthTwips = command.width;
+            this._docHeightTwips = command.height;
+            this._docType = command.type;
+            this._updateMaxBounds(true);
+            this._documentInfo = textMsg;
+            this._parts = command.parts;
+            this._selectedPart = command.selectedPart;
+            L.Socket.sendMessage('setclientpart part=' + this._selectedPart);
+            var partNames = textMsg.match(/[^\r\n]+/g);
+            // only get the last matches
+            partNames = partNames.slice(partNames.length - this._parts);
+            this._map.fire('updateparts', {
+                selectedPart: this._selectedPart,
+                parts: this._parts,
+                docType: this._docType,
+                partNames: partNames
+            });
+            this._update();
+            if (this._preFetchPart !== this._selectedPart) {
+                this._preFetchPart = this._selectedPart;
+                this._preFetchBorder = null;
+            }
+        }
 	}
 });
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 205163f..2de696d 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -298,47 +298,6 @@ L.TileLayer = L.GridLayer.extend({
 		}
 	},
 
-	_onStatusMsg: function (textMsg) {
-		var command = L.Socket.parseServerCmd(textMsg);
-		if (command.width && command.height && this._documentInfo !== textMsg) {
-			this._docWidthTwips = command.width;
-			this._docHeightTwips = command.height;
-			this._docType = command.type;
-			this._updateMaxBounds(true);
-			this._documentInfo = textMsg;
-			this._parts = command.parts;
-			this._selectedPart = command.selectedPart;
-			if (this._docType === 'text') {
-				this._selectedPart = 0;
-				this._parts = 1;
-				this._currentPage = command.selectedPart;
-				this._pages = command.parts;
-				this._map.fire('pagenumberchanged', {
-					currentPage: this._currentPage,
-					pages: this._pages,
-					docType: this._docType
-				});
-			}
-			else {
-				L.Socket.sendMessage('setclientpart part=' + this._selectedPart);
-				var partNames = textMsg.match(/[^\r\n]+/g);
-				// only get the last matches
-				partNames = partNames.slice(partNames.length - this._parts);
-				this._map.fire('updateparts', {
-					selectedPart: this._selectedPart,
-					parts: this._parts,
-					docType: this._docType,
-					partNames: partNames
-				});
-			}
-			this._update();
-			if (this._preFetchPart !== this._selectedPart) {
-				this._preFetchPart = this._selectedPart;
-				this._preFetchBorder = null;
-			}
-		}
-	},
-
 	_onStatusIndicatorMsg: function (textMsg) {
 		if (textMsg.startsWith('statusindicatorstart:')) {
 			this._map.fire('statusindicator', {statusType : 'start'});
diff --git a/loleaflet/src/layer/tile/WriterTileLayer.js b/loleaflet/src/layer/tile/WriterTileLayer.js
index e2dde74..178c8e6 100644
--- a/loleaflet/src/layer/tile/WriterTileLayer.js
+++ b/loleaflet/src/layer/tile/WriterTileLayer.js
@@ -79,5 +79,27 @@ L.WriterTileLayer = L.TileLayer.extend({
 				delete this._tileCache[key];
 			}
 		}
+	},
+
+	_onStatusMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		console.log(textMsg);
+		if (command.width && command.height && this._documentInfo !== textMsg) {
+			this._docWidthTwips = command.width;
+			this._docHeightTwips = command.height;
+			this._docType = command.type;
+			this._updateMaxBounds(true);
+			this._documentInfo = textMsg;
+			this._selectedPart = 0;
+			this._parts = 1;
+			this._currentPage = command.selectedPart;
+			this._pages = command.parts;
+			this._map.fire('pagenumberchanged', {
+				currentPage: this._currentPage,
+				pages: this._pages,
+				docType: this._docType
+			});
+			this._update();
+		}
 	}
 });
commit bbc65ebeb0f58d98fe847660c675be3867df0697
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 14:27:29 2015 +0300

    loleaflet: fixed typo

diff --git a/loleaflet/build/deps.js b/loleaflet/build/deps.js
index fc4a18d..c35d667 100644
--- a/loleaflet/build/deps.js
+++ b/loleaflet/build/deps.js
@@ -63,7 +63,7 @@ var deps = {
 		deps: ['TileLayer']
 	},
 
-	WriterTileLayer: {
+	CalcTileLayer: {
 		src: ['layer/tile/CalcTileLayer.js'],
 		desc: 'Calc tile layer.',
 		deps: ['TileLayer']
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index b25cf1c..b9bf086 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -90,13 +90,13 @@ L.Socket = {
 			// first status message, we need to create the document layer
 			var command = this.parseServerCmd(textMsg);
 			var docLayer = null;
-			if (command.style === 'text') {
+			if (command.type === 'text') {
 				docLayer = new L.WriterTileLayer('', {
 					edit: this._map.options.edit,
 					readOnly: this._map.options.readOnly
 				});
 			}
-			else if (command.style === 'spreadsheet') {
+			else if (command.type === 'spreadsheet') {
 				docLayer = new L.CalcTileLayer('', {
 					edit: this._map.options.edit,
 					readOnly: this._map.options.readOnly
commit 7d1625e93813f73ccff2ff61bbfef26409e5d260
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 13:57:34 2015 +0300

    loleaflet: tile invalidation is now handled in the 3 components

diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
index 1a1795a..687d03a 100644
--- a/loleaflet/src/layer/tile/CalcTileLayer.js
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -3,4 +3,86 @@
  */
 
 L.CalcTileLayer = L.TileLayer.extend({
+
+	_onInvalidateTilesMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.x === undefined || command.y === undefined || command.part === undefined) {
+			var strTwips = textMsg.match(/\d+/g);
+			command.x = parseInt(strTwips[0]);
+			command.y = parseInt(strTwips[1]);
+			command.width = parseInt(strTwips[2]);
+			command.height = parseInt(strTwips[3]);
+			command.part = this._currentPart;
+		}
+		if (this._docType === 'text') {
+			command.part = 0;
+		}
+		var topLeftTwips = new L.Point(command.x, command.y);
+		var offset = new L.Point(command.width, command.height);
+		var bottomRightTwips = topLeftTwips.add(offset);
+		var invalidBounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+		var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
+		var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
+		var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
+		var toRequest = [];
+
+		for (var key in this._tiles) {
+			var coords = this._tiles[key].coords;
+			var tileTopLeft = this._coordsToTwips(coords);
+			var tileBottomRight = new L.Point(this._tileWidthTwips, this._tileHeightTwips);
+			var bounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileBottomRight));
+			if (invalidBounds.intersects(bounds) && coords.part === command.part) {
+				if (this._tiles[key]._invalidCount) {
+					this._tiles[key]._invalidCount += 1;
+				}
+				else {
+					this._tiles[key]._invalidCount = 1;
+				}
+				if (visibleArea.intersects(bounds)) {
+					var msg = 'tile ' +
+							'part=' + coords.part + ' ' +
+							'width=' + this._tileSize + ' ' +
+							'height=' + this._tileSize + ' ' +
+							'tileposx=' + tileTopLeft.x + ' '    +
+							'tileposy=' + tileTopLeft.y + ' ' +
+							'tilewidth=' + this._tileWidthTwips + ' ' +
+							'tileheight=' + this._tileHeightTwips;
+					toRequest.push({msg: msg, key: key, coords: coords});
+				}
+				else {
+					// tile outside of the visible area, just remove it
+					this._preFetchBorder = null;
+					this._removeTile(key);
+				}
+			}
+		}
+
+		// Sort tiles so that we request those closer to the cursor first
+		var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
+		cursorPos = cursorPos.divideBy(this._tileSize);
+		toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
+		for (var i = 0; i < toRequest.length; i++) {
+			L.Socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+		}
+
+		for (key in this._tileCache) {
+			// compute the rectangle that each tile covers in the document based
+			// on the zoom level
+			coords = this._keyToTileCoords(key);
+			if (coords.part !== command.part) {
+				continue;
+			}
+			var scale = this._map.getZoomScale(coords.z);
+			topLeftTwips = new L.Point(
+					this.options.tileWidthTwips / scale * coords.x,
+					this.options.tileHeightTwips / scale * coords.y);
+			bottomRightTwips = topLeftTwips.add(new L.Point(
+					this.options.tileWidthTwips / scale,
+					this.options.tileHeightTwips / scale));
+			bounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+			if (invalidBounds.intersects(bounds)) {
+				delete this._tileCache[key];
+			}
+		}
+	}
 });
diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
index a2d1fbf..ba2f765 100644
--- a/loleaflet/src/layer/tile/ImpressTileLayer.js
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -2,6 +2,89 @@
  * Impress tile layer is used to display a presentation document
  */
 
-
 L.ImpressTileLayer = L.TileLayer.extend({
+
+	_onInvalidateTilesMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.x === undefined || command.y === undefined || command.part === undefined) {
+			var strTwips = textMsg.match(/\d+/g);
+			command.x = parseInt(strTwips[0]);
+			command.y = parseInt(strTwips[1]);
+			command.width = parseInt(strTwips[2]);
+			command.height = parseInt(strTwips[3]);
+			command.part = this._currentPart;
+		}
+		var topLeftTwips = new L.Point(command.x, command.y);
+		var offset = new L.Point(command.width, command.height);
+		var bottomRightTwips = topLeftTwips.add(offset);
+		var invalidBounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+		var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
+		var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
+		var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
+		var toRequest = [];
+
+		for (var key in this._tiles) {
+			var coords = this._tiles[key].coords;
+			var tileTopLeft = this._coordsToTwips(coords);
+			var tileBottomRight = new L.Point(this._tileWidthTwips, this._tileHeightTwips);
+			var bounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileBottomRight));
+			if (invalidBounds.intersects(bounds) && coords.part === command.part) {
+				if (this._tiles[key]._invalidCount) {
+					this._tiles[key]._invalidCount += 1;
+				}
+				else {
+					this._tiles[key]._invalidCount = 1;
+				}
+				if (visibleArea.intersects(bounds)) {
+					var msg = 'tile ' +
+							'part=' + coords.part + ' ' +
+							'width=' + this._tileSize + ' ' +
+							'height=' + this._tileSize + ' ' +
+							'tileposx=' + tileTopLeft.x + ' '    +
+							'tileposy=' + tileTopLeft.y + ' ' +
+							'tilewidth=' + this._tileWidthTwips + ' ' +
+							'tileheight=' + this._tileHeightTwips;
+					toRequest.push({msg: msg, key: key, coords: coords});
+				}
+				else {
+					// tile outside of the visible area, just remove it
+					this._preFetchBorder = null;
+					this._removeTile(key);
+				}
+			}
+		}
+
+		// Sort tiles so that we request those closer to the cursor first
+		var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
+		cursorPos = cursorPos.divideBy(this._tileSize);
+		toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
+		for (var i = 0; i < toRequest.length; i++) {
+			L.Socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+		}
+
+		for (key in this._tileCache) {
+			// compute the rectangle that each tile covers in the document based
+			// on the zoom level
+			coords = this._keyToTileCoords(key);
+			if (coords.part !== command.part) {
+				continue;
+			}
+			var scale = this._map.getZoomScale(coords.z);
+			topLeftTwips = new L.Point(
+					this.options.tileWidthTwips / scale * coords.x,
+					this.options.tileHeightTwips / scale * coords.y);
+			bottomRightTwips = topLeftTwips.add(new L.Point(
+					this.options.tileWidthTwips / scale,
+					this.options.tileHeightTwips / scale));
+			bounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+			if (invalidBounds.intersects(bounds)) {
+				delete this._tileCache[key];
+			}
+		}
+		if (command.part === this._currentPart &&
+			command.part !== this._lastValidPart) {
+			this._lastValidPart = command.part;
+			this._map.fire('updatepart', {part: command.part, docType: this._docType});
+		}
+	}
 });
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 6029884..205163f 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -266,94 +266,6 @@ L.TileLayer = L.GridLayer.extend({
 		this._onUpdateCursor();
 	},
 
-	_onInvalidateTilesMsg: function (textMsg) {
-		var command = L.Socket.parseServerCmd(textMsg);
-		if (command.x === undefined || command.y === undefined || command.part === undefined) {
-			var strTwips = textMsg.match(/\d+/g);
-			command.x = parseInt(strTwips[0]);
-			command.y = parseInt(strTwips[1]);
-			command.width = parseInt(strTwips[2]);
-			command.height = parseInt(strTwips[3]);
-			command.part = this._selectedPart;
-		}
-		if (this._docType === 'text') {
-			command.part = 0;
-		}
-		var topLeftTwips = new L.Point(command.x, command.y);
-		var offset = new L.Point(command.width, command.height);
-		var bottomRightTwips = topLeftTwips.add(offset);
-		var invalidBounds = new L.Bounds(topLeftTwips, bottomRightTwips);
-		var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
-		var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
-		var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
-		var toRequest = [];
-
-		for (var key in this._tiles) {
-			var coords = this._tiles[key].coords;
-			var tileTopLeft = this._coordsToTwips(coords);
-			var tileBottomRight = new L.Point(this._tileWidthTwips, this._tileHeightTwips);
-			var bounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileBottomRight));
-			if (invalidBounds.intersects(bounds) && coords.part === command.part) {
-				if (this._tiles[key]._invalidCount) {
-					this._tiles[key]._invalidCount += 1;
-				}
-				else {
-					this._tiles[key]._invalidCount = 1;
-				}
-				if (visibleArea.intersects(bounds)) {
-					var msg = 'tile ' +
-							'part=' + coords.part + ' ' +
-							'width=' + this._tileSize + ' ' +
-							'height=' + this._tileSize + ' ' +
-							'tileposx=' + tileTopLeft.x + ' '    +
-							'tileposy=' + tileTopLeft.y + ' ' +
-							'tilewidth=' + this._tileWidthTwips + ' ' +
-							'tileheight=' + this._tileHeightTwips;
-					toRequest.push({msg: msg, key: key, coords: coords});
-				}
-				else {
-					// tile outside of the visible area, just remove it
-					this._preFetchBorder = null;
-					this._removeTile(key);
-				}
-			}
-		}
-
-		// Sort tiles so that we request those closer to the cursor first
-		var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
-		cursorPos = cursorPos.divideBy(this._tileSize);
-		toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
-		for (var i = 0; i < toRequest.length; i++) {
-			L.Socket.sendMessage(toRequest[i].msg, toRequest[i].key);
-		}
-
-		for (key in this._tileCache) {
-			// compute the rectangle that each tile covers in the document based
-			// on the zoom level
-			coords = this._keyToTileCoords(key);
-			if (coords.part !== command.part) {
-				continue;
-			}
-			var scale = this._map.getZoomScale(coords.z);
-			topLeftTwips = new L.Point(
-					this.options.tileWidthTwips / scale * coords.x,
-					this.options.tileHeightTwips / scale * coords.y);
-			bottomRightTwips = topLeftTwips.add(new L.Point(
-					this.options.tileWidthTwips / scale,
-					this.options.tileHeightTwips / scale));
-			bounds = new L.Bounds(topLeftTwips, bottomRightTwips);
-			if (invalidBounds.intersects(bounds)) {
-				delete this._tileCache[key];
-			}
-		}
-		if (command.part === this._selectedPart &&
-			command.part !== this._lastValidPart) {
-			this._lastValidPart = command.part;
-			this._map.fire('updatepart', {part: command.part, docType: this._docType});
-		}
-
-	},
-
 	_onSearchNotFoundMsg: function (textMsg) {
 		var originalPhrase = textMsg.substring(16);
 		this._map.fire('search', {originalPhrase: originalPhrase, count: 0});
diff --git a/loleaflet/src/layer/tile/WriterTileLayer.js b/loleaflet/src/layer/tile/WriterTileLayer.js
index 6eb0258..e2dde74 100644
--- a/loleaflet/src/layer/tile/WriterTileLayer.js
+++ b/loleaflet/src/layer/tile/WriterTileLayer.js
@@ -3,4 +3,81 @@
  */
 
 L.WriterTileLayer = L.TileLayer.extend({
+
+	_onInvalidateTilesMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.x === undefined || command.y === undefined || command.part === undefined) {
+			var strTwips = textMsg.match(/\d+/g);
+			command.x = parseInt(strTwips[0]);
+			command.y = parseInt(strTwips[1]);
+			command.width = parseInt(strTwips[2]);
+			command.height = parseInt(strTwips[3]);
+			command.part = this._currentPart;
+		}
+		command.part = 0;
+		var topLeftTwips = new L.Point(command.x, command.y);
+		var offset = new L.Point(command.width, command.height);
+		var bottomRightTwips = topLeftTwips.add(offset);
+		var invalidBounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+		var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
+		var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
+		var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
+		var toRequest = [];
+
+		for (var key in this._tiles) {
+			var coords = this._tiles[key].coords;
+			var tileTopLeft = this._coordsToTwips(coords);
+			var tileBottomRight = new L.Point(this._tileWidthTwips, this._tileHeightTwips);
+			var bounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileBottomRight));
+			if (invalidBounds.intersects(bounds) && coords.part === command.part) {
+				if (this._tiles[key]._invalidCount) {
+					this._tiles[key]._invalidCount += 1;
+				}
+				else {
+					this._tiles[key]._invalidCount = 1;
+				}
+				if (visibleArea.intersects(bounds)) {
+					var msg = 'tile ' +
+							'part=' + coords.part + ' ' +
+							'width=' + this._tileSize + ' ' +
+							'height=' + this._tileSize + ' ' +
+							'tileposx=' + tileTopLeft.x + ' '    +
+							'tileposy=' + tileTopLeft.y + ' ' +
+							'tilewidth=' + this._tileWidthTwips + ' ' +
+							'tileheight=' + this._tileHeightTwips;
+					toRequest.push({msg: msg, key: key, coords: coords});
+				}
+				else {
+					// tile outside of the visible area, just remove it
+					this._preFetchBorder = null;
+					this._removeTile(key);
+				}
+			}
+		}
+
+		// Sort tiles so that we request those closer to the cursor first
+		var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
+		cursorPos = cursorPos.divideBy(this._tileSize);
+		toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
+		for (var i = 0; i < toRequest.length; i++) {
+			L.Socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+		}
+
+		for (key in this._tileCache) {
+			// compute the rectangle that each tile covers in the document based
+			// on the zoom level
+			coords = this._keyToTileCoords(key);
+			var scale = this._map.getZoomScale(coords.z);
+			topLeftTwips = new L.Point(
+					this.options.tileWidthTwips / scale * coords.x,
+					this.options.tileHeightTwips / scale * coords.y);
+			bottomRightTwips = topLeftTwips.add(new L.Point(
+					this.options.tileWidthTwips / scale,
+					this.options.tileHeightTwips / scale));
+			bounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+			if (invalidBounds.intersects(bounds)) {
+				delete this._tileCache[key];
+			}
+		}
+	}
 });
commit 6bf8a7dee0689e349360e158941eb18e82da9c7c
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 12:28:37 2015 +0300

    loleaflet: renamed 'currentPart' to 'selectedPart'

diff --git a/loleaflet/src/control/Control.Parts.js b/loleaflet/src/control/Control.Parts.js
index 9fc0b16..4a24e78 100644
--- a/loleaflet/src/control/Control.Parts.js
+++ b/loleaflet/src/control/Control.Parts.js
@@ -62,17 +62,17 @@ L.Control.Parts = L.Control.extend({
 	_updateDisabled: function (e) {
 		var className = 'leaflet-disabled';
 		var parts = e.parts;
-		var currentPart = e.currentPart;
+		var selectedPart = e.selectedPart;
 		var docType = e.docType;
 		if (docType === 'text') {
 			return;
 		}
-		if (currentPart === 0) {
+		if (selectedPart === 0) {
 			L.DomUtil.addClass(this._prevPartButton, className);
 		} else {
 			L.DomUtil.removeClass(this._prevPartButton, className);
 		}
-		if (currentPart === parts - 1) {
+		if (selectedPart === parts - 1) {
 			L.DomUtil.addClass(this._nextPartButton, className);
 		} else {
 			L.DomUtil.removeClass(this._nextPartButton, className);
diff --git a/loleaflet/src/control/Control.Tabs.js b/loleaflet/src/control/Control.Tabs.js
index cce0de9..b5ce57d 100644
--- a/loleaflet/src/control/Control.Tabs.js
+++ b/loleaflet/src/control/Control.Tabs.js
@@ -15,7 +15,7 @@ L.Control.Tabs = L.Control.extend({
 
 	_updateDisabled: function (e) {
 		var parts = e.parts;
-		var currentPart = e.currentPart;
+		var selectedPart = e.selectedPart;
 		var docType = e.docType;
 		var partNames = e.partNames;
 		if (docType === 'text') {
@@ -47,7 +47,7 @@ L.Control.Tabs = L.Control.extend({
 			for (var key in this._spreadsheetTabs) {
 				var part =  parseInt(key.match(/\d+/g)[0]);
 				L.DomUtil.removeClass(this._spreadsheetTabs[key], 'selected');
-				if (part === currentPart) {
+				if (part === selectedPart) {
 					L.DomUtil.addClass(this._spreadsheetTabs[key], 'selected');
 				}
 			}
diff --git a/loleaflet/src/control/Parts.js b/loleaflet/src/control/Parts.js
index 7089cfb..08e1c89 100644
--- a/loleaflet/src/control/Parts.js
+++ b/loleaflet/src/control/Parts.js
@@ -5,17 +5,17 @@ L.Map.include({
 	setPart: function (part) {
 		var docLayer = this._docLayer;
 		if (part === 'prev') {
-			if (docLayer._currentPart > 0) {
-				docLayer._currentPart -= 1;
+			if (docLayer._selectedPart > 0) {
+				docLayer._selectedPart -= 1;
 			}
 		}
 		else if (part === 'next') {
-			if (docLayer._currentPart < docLayer._parts - 1) {
-				docLayer._currentPart += 1;
+			if (docLayer._selectedPart < docLayer._parts - 1) {
+				docLayer._selectedPart += 1;
 			}
 		}
 		else if (typeof (part) === 'number' && part >= 0 && part < docLayer._parts) {
-			docLayer._currentPart = part;
+			docLayer._selectedPart = part;
 		}
 		else {
 			return;
@@ -25,11 +25,11 @@ L.Map.include({
 			L.Socket.sendMessage('resetselection');
 		}
 		this.fire('updateparts', {
-			currentPart: docLayer._currentPart,
+			selectedPart: docLayer._selectedPart,
 			parts: docLayer._parts,
 			docType: docLayer._docType
 		});
-		L.Socket.sendMessage('setclientpart part=' + docLayer._currentPart);
+		L.Socket.sendMessage('setclientpart part=' + docLayer._selectedPart);
 		docLayer._update();
 		docLayer._pruneTiles();
 		docLayer._clearSelections();
@@ -114,7 +114,7 @@ L.Map.include({
 	},
 
 	getCurrentPartNumber: function () {
-		return this._docLayer._currentPart;
+		return this._docLayer._selectedPart;
 	},
 
 	getDocSize: function () {
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index 5e49874..b25cf1c 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -160,7 +160,7 @@ L.Socket = {
 				command.parts = parseInt(tokens[i].substring(6));
 			}
 			else if (tokens[i].substring(0, 8) === 'current=') {
-				command.currentPart = parseInt(tokens[i].substring(8));
+				command.selectedPart = parseInt(tokens[i].substring(8));
 			}
 			else if (tokens[i].substring(0, 3) === 'id=') {
 				// remove newline characters
diff --git a/loleaflet/src/layer/tile/GridLayer.js b/loleaflet/src/layer/tile/GridLayer.js
index 58ea647..7df84b5 100644
--- a/loleaflet/src/layer/tile/GridLayer.js
+++ b/loleaflet/src/layer/tile/GridLayer.js
@@ -470,7 +470,7 @@ L.GridLayer = L.Layer.extend({
 
 		for (var key in this._tiles) {
 			if (this._keyToTileCoords(key).z !== zoom ||
-					this._keyToTileCoords(key).part !== this._currentPart) {
+					this._keyToTileCoords(key).part !== this._selectedPart) {
 				this._tiles[key].current = false;
 			}
 		}
@@ -482,7 +482,7 @@ L.GridLayer = L.Layer.extend({
 			for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
 				var coords = new L.Point(i, j);
 				coords.z = zoom;
-				coords.part = this._currentPart;
+				coords.part = this._selectedPart;
 
 				if (!this._isValidTile(coords)) { continue; }
 
@@ -619,7 +619,7 @@ L.GridLayer = L.Layer.extend({
 		var tilePos = this._getTilePos(coords),
 			key = this._tileCoordsToKey(coords);
 
-		if (coords.part === this._currentPart) {
+		if (coords.part === this._selectedPart) {
 			var tile = this.createTile(this._wrapCoords(coords), L.bind(this._tileReady, this, coords));
 
 			this._initTile(tile);
@@ -660,7 +660,7 @@ L.GridLayer = L.Layer.extend({
 					'tileposy=' + twips.y + ' ' +
 					'tilewidth=' + this._tileWidthTwips + ' ' +
 					'tileheight=' + this._tileHeightTwips;
-			if (coords.part !== this._currentPart) {
+			if (coords.part !== this._selectedPart) {
 				msg += ' prefetch=true';
 			}
 			L.Socket.sendMessage(msg, key);
@@ -770,7 +770,7 @@ L.GridLayer = L.Layer.extend({
 		}
 
 		if (!this._preFetchBorder) {
-			if (this._currentPart !== this._preFetchPart) {
+			if (this._selectedPart !== this._preFetchPart) {
 				// all tiles from the new part have to be pre-fetched
 				var tileBorder = this._preFetchBorder = new L.Bounds(new L.Point(0, 0), new L.Point(0, 0));
 			}
@@ -855,36 +855,36 @@ L.GridLayer = L.Layer.extend({
 					tileBorder.max.x * this._tileWidthTwips < this._docWidthTwips ||
 					 tileBorder.max.y * this._tileHeightTwips < this._docHeightTwips) &&
 					this.options.preFetchOtherParts) {
-				var diff = this._preFetchPart - this._currentPart;
-				if (diff === 0 && this._currentPart < this._parts - 1) {
+				var diff = this._preFetchPart - this._selectedPart;
+				if (diff === 0 && this._selectedPart < this._parts - 1) {
 					this._preFetchPart += 1;
 					this._preFetchBorder = null;
 				}
-				else if (diff === 0 && this._currentPart > 0) {
+				else if (diff === 0 && this._selectedPart > 0) {
 					this._preFetchPart -= 1;
 					this._preFetchBorder = null;
 				}
 				else if (diff > 0) {
-					if (this._currentPart - diff >= 0) {
+					if (this._selectedPart - diff >= 0) {
 						// lower part number
-						this._preFetchPart = this._currentPart - diff;
+						this._preFetchPart = this._selectedPart - diff;
 						this._preFetchBorder = null;
 					}
-					else if (this._currentPart + diff + 1 < this._parts) {
+					else if (this._selectedPart + diff + 1 < this._parts) {
 						// higher part number
-						this._preFetchPart = this._currentPart + diff + 1;
+						this._preFetchPart = this._selectedPart + diff + 1;
 						this._preFetchBorder = null;
 					}
 				}
 				else if (diff < 0) {
-					if (this._currentPart - diff + 1 < this._parts) {
+					if (this._selectedPart - diff + 1 < this._parts) {
 						// higher part number
-						this._preFetchPart = this._currentPart - diff + 1;
+						this._preFetchPart = this._selectedPart - diff + 1;
 						this._preFetchBorder = null;
 					}
-					else if (this._currentPart + diff - 1 >= 0) {
+					else if (this._selectedPart + diff - 1 >= 0) {
 						// lower part number
-						this._preFetchPart = this._currentPart + diff - 1;
+						this._preFetchPart = this._selectedPart + diff - 1;
 						this._preFetchBorder = null;
 					}
 				}
@@ -908,7 +908,7 @@ L.GridLayer = L.Layer.extend({
 		}
 		var interval = 750;
 		var idleTime = 5000;
-		this._preFetchPart = this._currentPart;
+		this._preFetchPart = this._selectedPart;
 		this._preFetchIdle = setTimeout(L.bind(function () {
 			this._tilesPreFetcher = setInterval(L.bind(this._preFetchTiles, this), interval);
 		}, this), idleTime);
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index a4e4ef0..6029884 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -274,7 +274,7 @@ L.TileLayer = L.GridLayer.extend({
 			command.y = parseInt(strTwips[1]);
 			command.width = parseInt(strTwips[2]);
 			command.height = parseInt(strTwips[3]);
-			command.part = this._currentPart;
+			command.part = this._selectedPart;
 		}
 		if (this._docType === 'text') {
 			command.part = 0;
@@ -346,7 +346,7 @@ L.TileLayer = L.GridLayer.extend({
 				delete this._tileCache[key];
 			}
 		}
-		if (command.part === this._currentPart &&
+		if (command.part === this._selectedPart &&
 			command.part !== this._lastValidPart) {
 			this._lastValidPart = command.part;
 			this._map.fire('updatepart', {part: command.part, docType: this._docType});
@@ -361,11 +361,11 @@ L.TileLayer = L.GridLayer.extend({
 
 	_onSetPartMsg: function (textMsg) {
 		var part = parseInt(textMsg.match(/\d+/g)[0]);
-		if (part !== this._currentPart && this._docType !== 'text') {
-			this._currentPart = part;
+		if (part !== this._selectedPart && this._docType !== 'text') {
+			this._selectedPart = part;
 			this._update();
 			this._clearSelections();
-			this._map.fire('setpart', {currentPart: this._currentPart});
+			this._map.fire('setpart', {selectedPart: this._selectedPart});
 		}
 		else if (this._docType === 'text') {
 			this._currentPage = part;
@@ -395,11 +395,11 @@ L.TileLayer = L.GridLayer.extend({
 			this._updateMaxBounds(true);
 			this._documentInfo = textMsg;
 			this._parts = command.parts;
-			this._currentPart = command.currentPart;
+			this._selectedPart = command.selectedPart;
 			if (this._docType === 'text') {
-				this._currentPart = 0;
+				this._selectedPart = 0;
 				this._parts = 1;
-				this._currentPage = command.currentPart;
+				this._currentPage = command.selectedPart;
 				this._pages = command.parts;
 				this._map.fire('pagenumberchanged', {
 					currentPage: this._currentPage,
@@ -408,20 +408,20 @@ L.TileLayer = L.GridLayer.extend({
 				});
 			}
 			else {
-				L.Socket.sendMessage('setclientpart part=' + this._currentPart);
+				L.Socket.sendMessage('setclientpart part=' + this._selectedPart);
 				var partNames = textMsg.match(/[^\r\n]+/g);
 				// only get the last matches
 				partNames = partNames.slice(partNames.length - this._parts);
 				this._map.fire('updateparts', {
-					currentPart: this._currentPart,
+					selectedPart: this._selectedPart,
 					parts: this._parts,
 					docType: this._docType,
 					partNames: partNames
 				});
 			}
 			this._update();
-			if (this._preFetchPart !== this._currentPart) {
-				this._preFetchPart = this._currentPart;
+			if (this._preFetchPart !== this._selectedPart) {
+				this._preFetchPart = this._selectedPart;
 				this._preFetchBorder = null;
 			}
 		}
commit e28da7e12ed464d5cf1122c107ab7551850a9271
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 12:04:13 2015 +0300

    loleaflet: alphabetically ordered the server commands

diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 111b610..a4e4ef0 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -178,21 +178,24 @@ L.TileLayer = L.GridLayer.extend({
 		if (textMsg.startsWith('cursorvisible:')) {
 			this._onCursorVisibleMsg(textMsg);
 		}
-		else if (textMsg.startsWith('invalidatecursor:')) {
-			this._onInvalidateCursorMsg(textMsg);
-		}
-		else if (textMsg.startsWith('textselectionstart:')) {
-			this._onTextSelectionStartMsg(textMsg);
-		}
-		else if (textMsg.startsWith('textselectionend:')) {
-			this._onTextSelectionEndMsg(textMsg);
+		else if (textMsg.startsWith('error:')) {
+			this._onErrorMsg(textMsg);
 		}
 		else if (textMsg.startsWith('graphicselection:')) {
 			this._onGraphicSelectionMsg(textMsg);
 		}
+		else if (textMsg.startsWith('invalidatecursor:')) {
+			this._onInvalidateCursorMsg(textMsg);
+		}
 		else if (textMsg.startsWith('invalidatetiles:') && !textMsg.match('EMPTY')) {
 			this._onInvalidateTilesMsg(textMsg);
 		}
+		else if (textMsg.startsWith('searchnotfound:')) {
+			this._onSearchNotFoundMsg(textMsg);
+		}
+		else if (textMsg.startsWith('setpart:')) {
+			this._onSetPartMsg(textMsg);
+		}
 		else if (textMsg.startsWith('statechanged:')) {
 			this._onStateChangedMsg(textMsg);
 		}
@@ -202,8 +205,8 @@ L.TileLayer = L.GridLayer.extend({
 		else if (textMsg.startsWith('statusindicator')) {
 			this._onStatusIndicatorMsg(textMsg);
 		}
-		else if (textMsg.startsWith('tile:')) {
-			this._onTileMsg(textMsg, imgBytes, index);
+		else if (textMsg.startsWith('styles:')) {
+			this._onStylesMsg(textMsg);
 		}
 		else if (textMsg.startsWith('textselection:')) {
 			this._onTextSelectionMsg(textMsg);
@@ -211,17 +214,14 @@ L.TileLayer = L.GridLayer.extend({
 		else if (textMsg.startsWith('textselectioncontent:')) {
 			this._onTextSelectionContentMsg(textMsg);
 		}
-		else if (textMsg.startsWith('setpart:')) {
-			this._onSetPartMsg(textMsg);
-		}
-		else if (textMsg.startsWith('searchnotfound:')) {
-			this._onSearchNotFoundMsg(textMsg);
+		else if (textMsg.startsWith('textselectionend:')) {
+			this._onTextSelectionEndMsg(textMsg);
 		}
-		else if (textMsg.startsWith('styles:')) {
-			this._onStylesMsg(textMsg);
+		else if (textMsg.startsWith('textselectionstart:')) {
+			this._onTextSelectionStartMsg(textMsg);
 		}
-		else if (textMsg.startsWith('error:')) {
-			this._onErrorMsg(textMsg);
+		else if (textMsg.startsWith('tile:')) {
+			this._onTileMsg(textMsg, imgBytes, index);
 		}
 	},
 
commit c927aec30637f94c43de7cf84bb8d2dbc046f2fb
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 11:59:38 2015 +0300

    loleaflet: modularized the onMessage method

diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index 7812936..111b610 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -176,198 +176,259 @@ L.TileLayer = L.GridLayer.extend({
 
 	_onMessage: function (textMsg, imgBytes, index) {
 		if (textMsg.startsWith('cursorvisible:')) {
-			var command = textMsg.match('cursorvisible: true');
-			this._isCursorVisible = command ? true : false;
-			this._isCursorOverlayVisible = true;
-			this._onUpdateCursor();
+			this._onCursorVisibleMsg(textMsg);
 		}
 		else if (textMsg.startsWith('invalidatecursor:')) {
-			var strTwips = textMsg.match(/\d+/g);
-			var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
-			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
-			var bottomRightTwips = topLeftTwips.add(offset);
-			this._visibleCursor = new L.LatLngBounds(
-							this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
-							this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
-			this._isCursorOverlayVisible = true;
-			this._onUpdateCursor();
+			this._onInvalidateCursorMsg(textMsg);
 		}
 		else if (textMsg.startsWith('textselectionstart:')) {
-			strTwips = textMsg.match(/\d+/g);
-			if (strTwips != null) {
-				topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
-				offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
-				bottomRightTwips = topLeftTwips.add(offset);
-				this._textSelectionStart = new L.LatLngBounds(
-							this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
-							this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
-			}
-			else {
-				this._textSelectionStart = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0));
-			}
+			this._onTextSelectionStartMsg(textMsg);
 		}
 		else if (textMsg.startsWith('textselectionend:')) {
-			strTwips = textMsg.match(/\d+/g);
-			if (strTwips != null) {
-				topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
-				offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
-				bottomRightTwips = topLeftTwips.add(offset);
-				this._textSelectionEnd = new L.LatLngBounds(
-							this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
-							this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
-			}
-			else {
-				this._textSelectionEnd = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0));
-			}
+			this._onTextSelectionEndMsg(textMsg);
 		}
 		else if (textMsg.startsWith('graphicselection:')) {
-			if (textMsg.match('EMPTY')) {
-				this._graphicSelection = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0));
-			}
-			else {
-				strTwips = textMsg.match(/\d+/g);
-				topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
-				offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
-				bottomRightTwips = topLeftTwips.add(offset);
-				this._graphicSelection = new L.LatLngBounds(
-								this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
-								this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
-			}
-
-			this._onUpdateGraphicSelection();
+			this._onGraphicSelectionMsg(textMsg);
 		}
 		else if (textMsg.startsWith('invalidatetiles:') && !textMsg.match('EMPTY')) {
-			command = L.Socket.parseServerCmd(textMsg);
-			if (command.x === undefined || command.y === undefined || command.part === undefined) {
-				strTwips = textMsg.match(/\d+/g);
-				command.x = parseInt(strTwips[0]);
-				command.y = parseInt(strTwips[1]);
-				command.width = parseInt(strTwips[2]);
-				command.height = parseInt(strTwips[3]);
-				command.part = this._currentPart;
-			}
-			if (this._docType === 'text') {
-				command.part = 0;
-			}
-			topLeftTwips = new L.Point(command.x, command.y);
-			offset = new L.Point(command.width, command.height);
-			bottomRightTwips = topLeftTwips.add(offset);
-			var invalidBounds = new L.Bounds(topLeftTwips, bottomRightTwips);
-			var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
-			var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
-			var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
-			var toRequest = [];
-
-			for (var key in this._tiles) {
-				var coords = this._tiles[key].coords;
-				var tileTopLeft = this._coordsToTwips(coords);
-				var tileBottomRight = new L.Point(this._tileWidthTwips, this._tileHeightTwips);
-				var bounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileBottomRight));
-				if (invalidBounds.intersects(bounds) && coords.part === command.part) {
-					if (this._tiles[key]._invalidCount) {
-						this._tiles[key]._invalidCount += 1;
-					}
-					else {
-						this._tiles[key]._invalidCount = 1;
-					}
-					if (visibleArea.intersects(bounds)) {
-						var msg = 'tile ' +
-								'part=' + coords.part + ' ' +
-								'width=' + this._tileSize + ' ' +
-								'height=' + this._tileSize + ' ' +
-								'tileposx=' + tileTopLeft.x + ' '    +
-								'tileposy=' + tileTopLeft.y + ' ' +
-								'tilewidth=' + this._tileWidthTwips + ' ' +
-								'tileheight=' + this._tileHeightTwips;
-						toRequest.push({msg: msg, key: key, coords: coords});
-					}
-					else {
-						// tile outside of the visible area, just remove it
-						this._preFetchBorder = null;
-						this._removeTile(key);
-					}
-				}
-			}
-			var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
-			cursorPos = cursorPos.divideBy(this._tileSize);
-			toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
-			for (var i = 0; i < toRequest.length; i++) {
-				L.Socket.sendMessage(toRequest[i].msg, toRequest[i].key);
-			}
-			for (key in this._tileCache) {
-				// compute the rectangle that each tile covers in the document based
-				// on the zoom level
-				coords = this._keyToTileCoords(key);
-				if (coords.part !== command.part) {
-					continue;
-				}
-				var scale = this._map.getZoomScale(coords.z);
-				topLeftTwips = new L.Point(
-						this.options.tileWidthTwips / scale * coords.x,
-						this.options.tileHeightTwips / scale * coords.y);
-				bottomRightTwips = topLeftTwips.add(new L.Point(
-						this.options.tileWidthTwips / scale,
-						this.options.tileHeightTwips / scale));
-				bounds = new L.Bounds(topLeftTwips, bottomRightTwips);
-				if (invalidBounds.intersects(bounds)) {
-					delete this._tileCache[key];
-				}
-			}
-			if (command.part === this._currentPart &&
-				command.part !== this._lastValidPart) {
-				this._lastValidPart = command.part;
-				this._map.fire('updatepart', {part: command.part, docType: this._docType});
-			}
+			this._onInvalidateTilesMsg(textMsg);
 		}
 		else if (textMsg.startsWith('statechanged:')) {
-			var unoMsg = textMsg.substr(14);
-			var unoCmd = unoMsg.match('.uno:(.*)=')[1];
-			var state = unoMsg.match('.*=(.*)')[1];
-			if (unoCmd && state) {
-				this._map.fire('commandstatechanged', {unoCmd : unoCmd, state : state});
-			}
+			this._onStateChangedMsg(textMsg);
 		}
 		else if (textMsg.startsWith('status:')) {
-			command = L.Socket.parseServerCmd(textMsg);
-			if (command.width && command.height && this._documentInfo !== textMsg) {
-				this._docWidthTwips = command.width;
-				this._docHeightTwips = command.height;
-				this._docType = command.type;
-				this._updateMaxBounds(true);
-				this._documentInfo = textMsg;
-				this._parts = command.parts;
-				this._currentPart = command.currentPart;
-				if (this._docType === 'text') {
-					this._currentPart = 0;
-					this._parts = 1;
-					this._currentPage = command.currentPart;
-					this._pages = command.parts;
-					this._map.fire('pagenumberchanged', {
-						currentPage: this._currentPage,
-						pages: this._pages,
-						docType: this._docType
-					});
+			this._onStatusMsg(textMsg);
+		}
+		else if (textMsg.startsWith('statusindicator')) {
+			this._onStatusIndicatorMsg(textMsg);
+		}
+		else if (textMsg.startsWith('tile:')) {
+			this._onTileMsg(textMsg, imgBytes, index);
+		}
+		else if (textMsg.startsWith('textselection:')) {
+			this._onTextSelectionMsg(textMsg);
+		}
+		else if (textMsg.startsWith('textselectioncontent:')) {
+			this._onTextSelectionContentMsg(textMsg);
+		}
+		else if (textMsg.startsWith('setpart:')) {
+			this._onSetPartMsg(textMsg);
+		}
+		else if (textMsg.startsWith('searchnotfound:')) {
+			this._onSearchNotFoundMsg(textMsg);
+		}
+		else if (textMsg.startsWith('styles:')) {
+			this._onStylesMsg(textMsg);
+		}
+		else if (textMsg.startsWith('error:')) {
+			this._onErrorMsg(textMsg);
+		}
+	},
+
+	_onCursorVisibleMsg: function(textMsg) {
+		var command = textMsg.match('cursorvisible: true');
+		this._isCursorVisible = command ? true : false;
+		this._isCursorOverlayVisible = true;
+		this._onUpdateCursor();
+	},
+
+	_onErrorMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		this._map.fire('error', {cmd: command.errorCmd, kind: command.errorKind});
+	},
+
+	_onGraphicSelectionMsg: function (textMsg) {
+		if (textMsg.match('EMPTY')) {
+			this._graphicSelection = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0));
+		}
+		else {
+			var strTwips = textMsg.match(/\d+/g);
+			var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
+			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
+			var bottomRightTwips = topLeftTwips.add(offset);
+			this._graphicSelection = new L.LatLngBounds(
+							this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
+							this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
+		}
+
+		this._onUpdateGraphicSelection();
+	},
+
+	_onInvalidateCursorMsg: function (textMsg) {
+		var strTwips = textMsg.match(/\d+/g);
+		var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
+		var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
+		var bottomRightTwips = topLeftTwips.add(offset);
+		this._visibleCursor = new L.LatLngBounds(
+						this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
+						this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
+		this._isCursorOverlayVisible = true;
+		this._onUpdateCursor();
+	},
+
+	_onInvalidateTilesMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.x === undefined || command.y === undefined || command.part === undefined) {
+			var strTwips = textMsg.match(/\d+/g);
+			command.x = parseInt(strTwips[0]);
+			command.y = parseInt(strTwips[1]);
+			command.width = parseInt(strTwips[2]);
+			command.height = parseInt(strTwips[3]);
+			command.part = this._currentPart;
+		}
+		if (this._docType === 'text') {
+			command.part = 0;
+		}
+		var topLeftTwips = new L.Point(command.x, command.y);
+		var offset = new L.Point(command.width, command.height);
+		var bottomRightTwips = topLeftTwips.add(offset);
+		var invalidBounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+		var visibleTopLeft = this._latLngToTwips(this._map.getBounds().getNorthWest());
+		var visibleBottomRight = this._latLngToTwips(this._map.getBounds().getSouthEast());
+		var visibleArea = new L.Bounds(visibleTopLeft, visibleBottomRight);
+		var toRequest = [];
+
+		for (var key in this._tiles) {
+			var coords = this._tiles[key].coords;
+			var tileTopLeft = this._coordsToTwips(coords);
+			var tileBottomRight = new L.Point(this._tileWidthTwips, this._tileHeightTwips);
+			var bounds = new L.Bounds(tileTopLeft, tileTopLeft.add(tileBottomRight));
+			if (invalidBounds.intersects(bounds) && coords.part === command.part) {
+				if (this._tiles[key]._invalidCount) {
+					this._tiles[key]._invalidCount += 1;
 				}
 				else {
-					L.Socket.sendMessage('setclientpart part=' + this._currentPart);
-					var partNames = textMsg.match(/[^\r\n]+/g);
-					// only get the last matches
-					partNames = partNames.slice(partNames.length - this._parts);
-					this._map.fire('updateparts', {
-						currentPart: this._currentPart,
-						parts: this._parts,
-						docType: this._docType,
-						partNames: partNames
-					});
+					this._tiles[key]._invalidCount = 1;
+				}
+				if (visibleArea.intersects(bounds)) {
+					var msg = 'tile ' +
+							'part=' + coords.part + ' ' +
+							'width=' + this._tileSize + ' ' +
+							'height=' + this._tileSize + ' ' +
+							'tileposx=' + tileTopLeft.x + ' '    +
+							'tileposy=' + tileTopLeft.y + ' ' +
+							'tilewidth=' + this._tileWidthTwips + ' ' +
+							'tileheight=' + this._tileHeightTwips;
+					toRequest.push({msg: msg, key: key, coords: coords});
 				}
-				this._update();
-				if (this._preFetchPart !== this._currentPart) {
-					this._preFetchPart = this._currentPart;
+				else {
+					// tile outside of the visible area, just remove it
 					this._preFetchBorder = null;
+					this._removeTile(key);
 				}
 			}
 		}
-		else if (textMsg.startsWith('statusindicatorstart:')) {
+
+		// Sort tiles so that we request those closer to the cursor first
+		var cursorPos = this._map.project(this._visibleCursor.getNorthWest());
+		cursorPos = cursorPos.divideBy(this._tileSize);
+		toRequest.sort(function(x, y) {return x.coords.distanceTo(cursorPos) - y.coords.distanceTo(cursorPos);});
+		for (var i = 0; i < toRequest.length; i++) {
+			L.Socket.sendMessage(toRequest[i].msg, toRequest[i].key);
+		}
+
+		for (key in this._tileCache) {
+			// compute the rectangle that each tile covers in the document based
+			// on the zoom level
+			coords = this._keyToTileCoords(key);
+			if (coords.part !== command.part) {
+				continue;
+			}
+			var scale = this._map.getZoomScale(coords.z);
+			topLeftTwips = new L.Point(
+					this.options.tileWidthTwips / scale * coords.x,
+					this.options.tileHeightTwips / scale * coords.y);
+			bottomRightTwips = topLeftTwips.add(new L.Point(
+					this.options.tileWidthTwips / scale,
+					this.options.tileHeightTwips / scale));
+			bounds = new L.Bounds(topLeftTwips, bottomRightTwips);
+			if (invalidBounds.intersects(bounds)) {
+				delete this._tileCache[key];
+			}
+		}
+		if (command.part === this._currentPart &&
+			command.part !== this._lastValidPart) {
+			this._lastValidPart = command.part;
+			this._map.fire('updatepart', {part: command.part, docType: this._docType});
+		}
+
+	},
+
+	_onSearchNotFoundMsg: function (textMsg) {
+		var originalPhrase = textMsg.substring(16);
+		this._map.fire('search', {originalPhrase: originalPhrase, count: 0});
+	},
+
+	_onSetPartMsg: function (textMsg) {
+		var part = parseInt(textMsg.match(/\d+/g)[0]);
+		if (part !== this._currentPart && this._docType !== 'text') {
+			this._currentPart = part;
+			this._update();
+			this._clearSelections();
+			this._map.fire('setpart', {currentPart: this._currentPart});
+		}
+		else if (this._docType === 'text') {
+			this._currentPage = part;
+			this._map.fire('pagenumberchanged', {
+				currentPage: part,
+				pages: this._pages,
+				docType: this._docType
+			});
+		}
+	},
+
+	_onStateChangedMsg: function (textMsg) {
+		var unoMsg = textMsg.substr(14);
+		var unoCmd = unoMsg.match('.uno:(.*)=')[1];
+		var state = unoMsg.match('.*=(.*)')[1];
+		if (unoCmd && state) {
+			this._map.fire('commandstatechanged', {unoCmd : unoCmd, state : state});
+		}
+	},
+
+	_onStatusMsg: function (textMsg) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		if (command.width && command.height && this._documentInfo !== textMsg) {
+			this._docWidthTwips = command.width;
+			this._docHeightTwips = command.height;
+			this._docType = command.type;
+			this._updateMaxBounds(true);
+			this._documentInfo = textMsg;
+			this._parts = command.parts;
+			this._currentPart = command.currentPart;
+			if (this._docType === 'text') {
+				this._currentPart = 0;
+				this._parts = 1;
+				this._currentPage = command.currentPart;
+				this._pages = command.parts;
+				this._map.fire('pagenumberchanged', {
+					currentPage: this._currentPage,
+					pages: this._pages,
+					docType: this._docType
+				});
+			}
+			else {
+				L.Socket.sendMessage('setclientpart part=' + this._currentPart);
+				var partNames = textMsg.match(/[^\r\n]+/g);
+				// only get the last matches
+				partNames = partNames.slice(partNames.length - this._parts);
+				this._map.fire('updateparts', {
+					currentPart: this._currentPart,
+					parts: this._parts,
+					docType: this._docType,
+					partNames: partNames
+				});
+			}
+			this._update();
+			if (this._preFetchPart !== this._currentPart) {
+				this._preFetchPart = this._currentPart;
+				this._preFetchBorder = null;
+			}
+		}
+	},
+
+	_onStatusIndicatorMsg: function (textMsg) {
+		if (textMsg.startsWith('statusindicatorstart:')) {
 			this._map.fire('statusindicator', {statusType : 'start'});
 		}
 		else if (textMsg.startsWith('statusindicatorsetvalue:')) {
@@ -377,126 +438,137 @@ L.TileLayer = L.GridLayer.extend({
 		else if (textMsg.startsWith('statusindicatorfinish:')) {
 			this._map.fire('statusindicator', {statusType : 'finish'});
 		}
-		else if (textMsg.startsWith('tile:')) {
-			command = L.Socket.parseServerCmd(textMsg);
-			coords = this._twipsToCoords(command);
-			coords.z = command.zoom;
-			coords.part = command.part;
-			var data = imgBytes.subarray(index + 1);
-
-			// read the tile data
-			var strBytes = '';
-			for (i = 0; i < data.length; i++) {
-				strBytes += String.fromCharCode(data[i]);
-			}
+	},
 
-			key = this._tileCoordsToKey(coords);
-			var tile = this._tiles[key];
-			var img = 'data:image/png;base64,' + window.btoa(strBytes);
-			if (command.id !== undefined) {
-				this._map.fire('tilepreview', {
-					tile: img,
-					id: command.id,
-					width: command.width,
-					height: command.height,
-					part: command.part,
-					docType: this._docType
-				});
+	_onStylesMsg: function (textMsg) {
+		this._docStyles = JSON.parse(textMsg.substring(8));
+		this._map.fire('updatestyles', {styles: this._docStyles});
+	},
+
+	_onTextSelectionMsg: function (textMsg) {
+		var strTwips = textMsg.match(/\d+/g);
+		this._clearSelections();
+		if (strTwips != null) {
+			var rectangles = [];
+			var selectionCenter = new L.Point(0, 0);
+			for (var i = 0; i < strTwips.length; i += 4) {
+				var topLeftTwips = new L.Point(parseInt(strTwips[i]), parseInt(strTwips[i + 1]));
+				var offset = new L.Point(parseInt(strTwips[i + 2]), parseInt(strTwips[i + 3]));
+				var topRightTwips = topLeftTwips.add(new L.Point(offset.x, 0));
+				var bottomLeftTwips = topLeftTwips.add(new L.Point(0, offset.y));
+				var bottomRightTwips = topLeftTwips.add(offset);
+				rectangles.push([bottomLeftTwips, bottomRightTwips, topLeftTwips, topRightTwips]);
+				selectionCenter = selectionCenter.add(topLeftTwips);
+				selectionCenter = selectionCenter.add(offset.divideBy(2));
 			}
-			else if (tile) {
-				if (this._tiles[key]._invalidCount > 0) {
-					this._tiles[key]._invalidCount -= 1;
-				}
-				if (!tile.loaded) {
-					this._emptyTilesCount -= 1;
-					if (this._emptyTilesCount === 0) {
-						this._map.fire('statusindicator', {statusType: 'alltilesloaded'});
-					}
-				}
-				tile.el.src = img;
+			// average of all rectangles' centers
+			selectionCenter = selectionCenter.divideBy(strTwips.length / 4);
+			selectionCenter = this._twipsToLatLng(selectionCenter);
+			if (!this._map.getBounds().contains(selectionCenter)) {
+				var center = this._map.project(selectionCenter);
+				center = center.subtract(this._map.getSize().divideBy(2));
+				center.x = Math.round(center.x < 0 ? 0 : center.x);
+				center.y = Math.round(center.y < 0 ? 0 : center.y);
+				this._map.fire('scrollto', {x: center.x, y: center.y});
 			}
-			else if (command.preFetch === 'true') {
-				this._tileCache[key] = img;
+
+			var polygons = L.PolyUtil.rectanglesToPolygons(rectangles, this);
+			for (i = 0; i < polygons.length; i++) {
+				var selection = new L.Polygon(polygons[i], {
+					pointerEvents: 'none',
+					fillColor: '#43ACE8',
+					fillOpacity: 0.25,
+					weight: 2,
+					opacity: 0.25});
+				this._selections.addLayer(selection);
 			}
-			L.Log.log(textMsg, L.INCOMING, key);
+			if (this._selectionContentRequest) {
+				clearTimeout(this._selectionContentRequest);
+			}
+			this._selectionContentRequest = setTimeout(L.bind(function () {
+				L.Socket.sendMessage('gettextselection mimetype=text/plain;charset=utf-8');}, this), 100);
 		}
-		else if (textMsg.startsWith('textselection:')) {
-			strTwips = textMsg.match(/\d+/g);
-			this._clearSelections();
-			if (strTwips != null) {
-				var rectangles = [];
-				var selectionCenter = new L.Point(0, 0);
-				for (i = 0; i < strTwips.length; i += 4) {
-					topLeftTwips = new L.Point(parseInt(strTwips[i]), parseInt(strTwips[i + 1]));
-					offset = new L.Point(parseInt(strTwips[i + 2]), parseInt(strTwips[i + 3]));
-					var topRightTwips = topLeftTwips.add(new L.Point(offset.x, 0));
-					var bottomLeftTwips = topLeftTwips.add(new L.Point(0, offset.y));
-					bottomRightTwips = topLeftTwips.add(offset);
-					rectangles.push([bottomLeftTwips, bottomRightTwips, topLeftTwips, topRightTwips]);
-					selectionCenter = selectionCenter.add(topLeftTwips);
-					selectionCenter = selectionCenter.add(offset.divideBy(2));
-				}
-				// average of all rectangles' centers
-				selectionCenter = selectionCenter.divideBy(strTwips.length / 4);
-				selectionCenter = this._twipsToLatLng(selectionCenter);
-				if (!this._map.getBounds().contains(selectionCenter)) {
-					var center = this._map.project(selectionCenter);
-					center = center.subtract(this._map.getSize().divideBy(2));
-					center.x = Math.round(center.x < 0 ? 0 : center.x);
-					center.y = Math.round(center.y < 0 ? 0 : center.y);
-					this._map.fire('scrollto', {x: center.x, y: center.y});
-				}
+		this._onUpdateTextSelection();
+	},
 
-				var polygons = L.PolyUtil.rectanglesToPolygons(rectangles, this);
-				for (i = 0; i < polygons.length; i++) {
-					var selection = new L.Polygon(polygons[i], {
-						pointerEvents: 'none',
-						fillColor: '#43ACE8',
-						fillOpacity: 0.25,
-						weight: 2,
-						opacity: 0.25});
-					this._selections.addLayer(selection);
-				}
-				if (this._selectionContentRequest) {
-					clearTimeout(this._selectionContentRequest);
-				}
-				this._selectionContentRequest = setTimeout(L.bind(function () {
-					L.Socket.sendMessage('gettextselection mimetype=text/plain;charset=utf-8');}, this), 100);
-			}
-			this._onUpdateTextSelection();
+	_onTextSelectionContentMsg: function (textMsg) {
+		this._selectionTextContent = textMsg.substr(22);
+	},
+
+	_onTextSelectionEndMsg: function (textMsg) {
+		var strTwips = textMsg.match(/\d+/g);
+		if (strTwips != null) {
+			var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
+			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
+			var bottomRightTwips = topLeftTwips.add(offset);
+			this._textSelectionEnd = new L.LatLngBounds(
+						this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
+						this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
 		}
-		else if (textMsg.startsWith('textselectioncontent:')) {
-			this._selectionTextContent = textMsg.substr(22);
+		else {
+			this._textSelectionEnd = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0));
 		}
-		else if (textMsg.startsWith('setpart:')) {
-			var part = parseInt(textMsg.match(/\d+/g)[0]);
-			if (part !== this._currentPart && this._docType !== 'text') {
-				this._currentPart = part;
-				this._update();
-				this._clearSelections();
-				this._map.fire('setpart', {currentPart: this._currentPart});
-			}
-			else if (this._docType === 'text') {
-				this._currentPage = part;
-				this._map.fire('pagenumberchanged', {
-					currentPage: part,
-					pages: this._pages,
-					docType: this._docType
-				});
-			}
+	},
+
+	_onTextSelectionStartMsg: function (textMsg) {
+		var strTwips = textMsg.match(/\d+/g);
+		if (strTwips != null) {
+			var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1]));
+			var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3]));
+			var bottomRightTwips = topLeftTwips.add(offset);
+			this._textSelectionStart = new L.LatLngBounds(
+						this._twipsToLatLng(topLeftTwips, this._map.getZoom()),
+						this._twipsToLatLng(bottomRightTwips, this._map.getZoom()));
 		}
-		else if (textMsg.startsWith('searchnotfound:')) {
-			var originalPhrase = textMsg.substring(16);
-			this._map.fire('search', {originalPhrase: originalPhrase, count: 0});
+		else {
+			this._textSelectionStart = new L.LatLngBounds(new L.LatLng(0, 0), new L.LatLng(0, 0));
 		}
-		else if (textMsg.startsWith('styles:')) {
-			this._docStyles = JSON.parse(textMsg.substring(8));
-			this._map.fire('updatestyles', {styles: this._docStyles});
+
+	},
+
+	_onTileMsg: function (textMsg, imgBytes, index) {
+		var command = L.Socket.parseServerCmd(textMsg);
+		var coords = this._twipsToCoords(command);
+		coords.z = command.zoom;
+		coords.part = command.part;
+		var data = imgBytes.subarray(index + 1);
+
+		// read the tile data
+		var strBytes = '';
+		for (var i = 0; i < data.length; i++) {
+			strBytes += String.fromCharCode(data[i]);
+		}
+
+		var key = this._tileCoordsToKey(coords);
+		var tile = this._tiles[key];
+		var img = 'data:image/png;base64,' + window.btoa(strBytes);
+		if (command.id !== undefined) {
+			this._map.fire('tilepreview', {
+				tile: img,
+				id: command.id,
+				width: command.width,
+				height: command.height,
+				part: command.part,
+				docType: this._docType
+			});
+		}
+		else if (tile) {
+			if (this._tiles[key]._invalidCount > 0) {
+				this._tiles[key]._invalidCount -= 1;
+			}
+			if (!tile.loaded) {
+				this._emptyTilesCount -= 1;
+				if (this._emptyTilesCount === 0) {
+					this._map.fire('statusindicator', {statusType: 'alltilesloaded'});
+				}
+			}
+			tile.el.src = img;
 		}
-		else if (textMsg.startsWith('error:')) {
-			command = L.Socket.parseServerCmd(textMsg);
-			this._map.fire('error', {cmd: command.errorCmd, kind: command.errorKind});
+		else if (command.preFetch === 'true') {
+			this._tileCache[key] = img;
 		}
+		L.Log.log(textMsg, L.INCOMING, key);
+
 	},
 
 	_tileOnLoad: function (done, tile) {
@@ -545,8 +617,6 @@ L.TileLayer = L.GridLayer.extend({
 				' x=' + x + ' y=' + y);
 	},
 
-
-
 	// Is rRectangle empty?
 	_isEmptyRectangle: function (aBounds) {
 		return aBounds.getSouthWest().equals(new L.LatLng(0, 0)) && aBounds.getNorthEast().equals(new L.LatLng(0, 0));
commit ad756ec2576d1b30edcdecb121b56bd5581a0d40
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Wed Sep 2 10:47:19 2015 +0300

    loleaflet: first splitting of TileLayer into 3 components

diff --git a/loleaflet/build/deps.js b/loleaflet/build/deps.js
index d806268..fc4a18d 100644
--- a/loleaflet/build/deps.js
+++ b/loleaflet/build/deps.js
@@ -51,6 +51,24 @@ var deps = {
 		deps: ['TileLayer']
 	},
 
+	WriterTileLayer: {
+		src: ['layer/tile/WriterTileLayer.js'],
+		desc: 'Writer tile layer.',
+		deps: ['TileLayer']
+	},
+
+	ImpressTileLayer: {
+		src: ['layer/tile/ImpressTileLayer.js'],
+		desc: 'Impress tile layer.',
+		deps: ['TileLayer']
+	},
+
+	WriterTileLayer: {
+		src: ['layer/tile/CalcTileLayer.js'],
+		desc: 'Calc tile layer.',
+		deps: ['TileLayer']
+	},
+
 	ImageOverlay: {
 		src: ['layer/ImageOverlay.js'],
 		desc: 'Used to display an image over a particular rectangular area of the map.'
diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js
index 78cb922..5e49874 100644
--- a/loleaflet/src/core/Socket.js
+++ b/loleaflet/src/core/Socket.js
@@ -89,13 +89,32 @@ L.Socket = {
 		if (textMsg.startsWith('status:') && !this._map._docLayer) {
 			// first status message, we need to create the document layer
 			var command = this.parseServerCmd(textMsg);
-			this._map._docLayer = new L.TileLayer('', {
-				edit: this._map.options.edit,
-				readOnly: this._map.options.readOnly
-			});
-			this._map.addLayer(this._map._docLayer);
+			var docLayer = null;
+			if (command.style === 'text') {
+				docLayer = new L.WriterTileLayer('', {
+					edit: this._map.options.edit,
+					readOnly: this._map.options.readOnly
+				});
+			}
+			else if (command.style === 'spreadsheet') {
+				docLayer = new L.CalcTileLayer('', {
+					edit: this._map.options.edit,
+					readOnly: this._map.options.readOnly
+				});
+			}
+			else {
+				docLayer = new L.ImpressTileLayer('', {
+					edit: this._map.options.edit,
+					readOnly: this._map.options.readOnly
+				});
+			}
+
+			this._map._docLayer = docLayer;
+			this._map.addLayer(docLayer);
+		}
+		if (this._map._docLayer) {
+			this._map._docLayer._onMessage(textMsg, imgBytes, index);
 		}
-		this._map._docLayer._onMessage(textMsg, imgBytes, index);
 	},
 
 	_onSocketError: function () {
diff --git a/loleaflet/src/layer/tile/CalcTileLayer.js b/loleaflet/src/layer/tile/CalcTileLayer.js
new file mode 100644
index 0000000..1a1795a
--- /dev/null
+++ b/loleaflet/src/layer/tile/CalcTileLayer.js
@@ -0,0 +1,6 @@
+/*
+ * Calc tile layer is used to display a spreadsheet document
+ */
+
+L.CalcTileLayer = L.TileLayer.extend({
+});
diff --git a/loleaflet/src/layer/tile/ImpressTileLayer.js b/loleaflet/src/layer/tile/ImpressTileLayer.js
new file mode 100644
index 0000000..a2d1fbf
--- /dev/null
+++ b/loleaflet/src/layer/tile/ImpressTileLayer.js
@@ -0,0 +1,7 @@
+/*
+ * Impress tile layer is used to display a presentation document
+ */
+
+
+L.ImpressTileLayer = L.TileLayer.extend({
+});
diff --git a/loleaflet/src/layer/tile/WriterTileLayer.js b/loleaflet/src/layer/tile/WriterTileLayer.js
new file mode 100644
index 0000000..6eb0258
--- /dev/null
+++ b/loleaflet/src/layer/tile/WriterTileLayer.js
@@ -0,0 +1,6 @@
+/*
+ * Writer tile layer is used to display a text document
+ */
+
+L.WriterTileLayer = L.TileLayer.extend({
+});
commit ccffd33a3b7fcb8bcce0992f632b03ecb86eff3b
Author: Mihai Varga <mihai.varga at collabora.com>
Date:   Tue Sep 1 18:15:43 2015 +0300

    loleaflet: README update

diff --git a/loleaflet/README b/loleaflet/README
index fcf1b09..f5b3488 100644
--- a/loleaflet/README
+++ b/loleaflet/README
@@ -213,15 +213,11 @@ Implementation details
 
 Loading a document:
     The map should have the following options:
-        - center at [0, 0] this will try to place the [0, 0] point in the middle of the
-          map, but it will be moved in the top left corner when the maxBounds are set
-        - zoom = defautl zoom value, zooming in and out will refer to this value
         - server address
-
-    The layer (actual document) should have the following options:
-        - doc = path to the document that will be loaded
-        - useSocket = tells the map the tiles will be received from a websocket
-          connection. If this parameter is false, an image will be loaded in each tile
+        - doc - path to the document that will be loaded
+        - edit = the initial permission
+        - readOnly - whether the document is read only
+        - [timestamp] - optionally provided for remote documents
 
 How zooming works:
     The zoom level goes from 1 to 20 (those limits can be changed) and the initial


More information about the Libreoffice-commits mailing list