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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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.va...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits