.gitignore | 1 loleaflet/dist/loleaflet.css | 10 + loleaflet/src/control/Control.Menubar.js | 8 + loleaflet/src/layer/AnnotationManager.js | 159 +++++++++++++++++++++++-------- loleaflet/src/layer/marker/Annotation.js | 79 ++++++++++----- 5 files changed, 191 insertions(+), 66 deletions(-)
New commits: commit f9d54cd05867a065075d1f0d9bee2b4706d09802 Author: Henry Castro <hcas...@collabora.com> Date: Sat Feb 11 18:04:38 2017 -0400 loleaflet: insert annotation diff --git a/loleaflet/dist/loleaflet.css b/loleaflet/dist/loleaflet.css index 8db2068..eac27ef 100644 --- a/loleaflet/dist/loleaflet.css +++ b/loleaflet/dist/loleaflet.css @@ -121,7 +121,13 @@ body { border: 1px solid #999; } -.leaflet-annotation-content { - margin: 13px 19px; +.loleaflet-annotation-content { + margin: 3px 3px; line-height: 1.4; } + +.loleaflet-annotation-textarea { + border: 1px solid #c8c8c8; + resize: none; + background-color: #ffffc0; +} diff --git a/loleaflet/src/control/Control.Menubar.js b/loleaflet/src/control/Control.Menubar.js index 4128280..6b7261e 100644 --- a/loleaflet/src/control/Control.Menubar.js +++ b/loleaflet/src/control/Control.Menubar.js @@ -37,7 +37,7 @@ L.Control.Menubar = L.Control.extend({ }, {name: _('Insert'), type: 'menu', menu: [ {name: _('Image'), id: 'insertgraphic', type: 'action'}, - {name: _('Comment'), type: 'unocommand', uno: '.uno:InsertAnnotation'}, + {name: _('Comment...'), id: 'insertcomment', type: 'action'}, {type: 'separator'}, {name: _('Footnote'), type: 'unocommand', uno: '.uno:InsertFootnote'}, {name: _('Endnote'), type: 'unocommand', uno: '.uno:InsertEndnote'}, @@ -411,6 +411,8 @@ L.Control.Menubar = L.Control.extend({ // check if it is empty fileName = fileName === '' ? 'document' : fileName; map.downloadAs(fileName + '.' + format, format); + } else if (id === 'insertcomment') { + map.insertComment(); } else if (id === 'insertgraphic') { L.DomUtil.get('insertgraphic').click(); } else if (id === 'specialcharacter') { @@ -514,7 +516,9 @@ L.Control.Menubar = L.Control.extend({ var id = $(item).data('id'); self._executeAction(id); } - map.focus(); + + if (id !== 'insertcomment') + map.focus(); }, _createMenu: function(menu) { diff --git a/loleaflet/src/layer/AnnotationManager.js b/loleaflet/src/layer/AnnotationManager.js index f00651c..56147e9 100644 --- a/loleaflet/src/layer/AnnotationManager.js +++ b/loleaflet/src/layer/AnnotationManager.js @@ -11,93 +11,180 @@ L.AnnotationManager = L.Class.extend({ initialize: function (map) { this._map = map; - this._annotations = {}; + this._items = {}; + this._anchors = []; this._selected = {}; - this._arrow = L.polyline([], {color: 'darkblue', weight:1}); + this._arrow = L.polyline([], {color: 'darkblue', weight: 1}); + this._map.on('AnnotationCancel', this._onAnnotationCancel, this); this._map.on('AnnotationClick', this._onAnnotationClick, this); + this._map.on('AnnotationSave', this._onAnnotationSave, this); }, clear: function () { - for (var key in this._annotations) { - this._map.removeLayer(this._annotations[key]); + for (var key in this._items) { + this._map.removeLayer(this._items[key]); } this._map.removeLayer(this._arrow); - this._annotations = {}; + this._items = {}; + this._anchors = []; this._selected = {}; }, fill: function (comments) { - var docTopRight = this._map.project(this._map.options.maxBounds.getNorthEast()).add(L.point(this.options.marginX, this.options.marginY)); - var annotation, point; - + var comment; this.clear(); for (var index in comments) { - point = this._map._docLayer._twipsToPixels(L.LOUtil.stringToPoint(comments[index].anchorPos)); - point.x = docTopRight.x; - annotation = L.annotation(this._map.unproject(point), comments[index]).addTo(this._map); - this._annotations[annotation._data.id] = annotation; + comment = comments[index]; + comment.anchorPos = L.LOUtil.stringToPoint(comment.anchorPos); + this._items[comment.id] = L.annotation(this._map.options.maxBounds.getSouthEast(), comment).addTo(this._map); + this._anchors.push({anchor: comment.anchorPos, id: comment.id}); } + this._anchors.sort(function(a, b) { + return Math.abs(a.anchor.y) - Math.abs(b.anchor.y); + }); + this.layout(); + }, + unselect: function () { + this._selected.annotation = null; + this._map.removeLayer(this._arrow); this.layout(); }, select: function (id) { var topRight = this._map.project(this._map.options.maxBounds.getNorthEast()); - var annotation = this._annotations[id]; - var point0, point1, point2; + var annotation = this._items[id]; + var point0, point1, point2, point3; if (annotation) { - point0 = this._map._docLayer._twipsToPixels(L.LOUtil.stringToPoint(annotation._data.anchorPos)); + this._selected.annotation = annotation; + this.layout(); + point0 = this._map._docLayer._twipsToPixels(annotation._data.anchorPos); point1 = L.point(point0.x, point0.y - this.options.offset); point2 = L.point(topRight.x, point1.y); - this._arrow.setLatLngs([this._map.unproject(point0), this._map.unproject(point1), this._map.unproject(point2)]); + point3 = L.point(topRight.x, point2.y + this.options.offset); + this._arrow.setLatLngs([this._map.unproject(point0), this._map.unproject(point1), this._map.unproject(point2), this._map.unproject(point3)]); this._map.addLayer(this._arrow); - if (this._selected.annotation) { - this._selected.annotation.setLatLng(this._selected.latlng); - } - this._selected.annotation = annotation; - this._selected.latlng = annotation._latlng; - annotation.setLatLng(this._map.unproject(point2)); + annotation.setLatLng(this._map.unproject(point3)); } }, layout: function () { - var annotation, bounds, layoutBounds, foundBounds; - this._bounds = []; - for (var key in this._annotations) { - annotation = this._annotations[key]; + var topRight = this._map.project(this._map.options.maxBounds.getNorthEast()).add(L.point(this.options.marginX, this.options.marginY)); + var annotation, bounds, layoutBounds, foundBounds,point, latlng; + var layouts = []; + + if (this._selected.annotation) { + point = L.point(topRight.x, this._map._docLayer._twipsToPixels(this._selected.annotation._data.anchorPos).y); + this._selected.annotation.setLatLng(this._map.unproject(point)); + bounds = this._selected.annotation.getBounds(); + bounds.extend(bounds.min.subtract([0, this.options.marginY])); + bounds.extend(bounds.getBottomLeft().add([0, this.options.marginY])); + this._selected.bounds = bounds; + } + + for (var itAnchor in this._anchors) { + annotation = this._items[this._anchors[itAnchor].id]; + if (annotation === this._selected.annotation) { + continue; + } + point = L.point(topRight.x, this._map._docLayer._twipsToPixels(annotation._data.anchorPos).y); + latlng = this._map.unproject(point); + annotation.setLatLng(latlng); bounds = annotation.getBounds(); foundBounds = null; - for (var itBounds in this._bounds) { - layoutBounds = this._bounds[itBounds]; + for (var itBounds in layouts) { + layoutBounds = layouts[itBounds]; if (layoutBounds.intersects(bounds)) { - foundBounds = layoutBounds; - break; + if (foundBounds) { + foundBounds = layoutBounds.max.y > foundBounds.max.y ? layoutBounds : foundBounds; + } else { + foundBounds = layoutBounds; + } } } if (foundBounds) { - annotation.setLatLng(this._map.layerPointToLatLng(foundBounds.getBottomLeft())); + if (foundBounds.contains(bounds.getTopRight())) { + point = foundBounds.getBottomLeft().add([0, bounds.getSize().y + this.options.marginY]); + latlng = this._map.layerPointToLatLng(foundBounds.getBottomLeft()); + } else { + point = foundBounds.min.subtract([0, bounds.getSize().y + this.options.marginY]); + latlng = this._map.layerPointToLatLng(point); + } + foundBounds.extend(point); + } else { + foundBounds = L.bounds(bounds.min, bounds.max); + foundBounds.extend(L.point(bounds.min.x, bounds.min.y - this.options.marginY)); + foundBounds.extend(L.point(bounds.min.x, bounds.max.y + this.options.marginY)); + layouts.push(foundBounds); } - else { - bounds.extend(L.point(bounds.min.x, bounds.min.y + this.options.marginY)); - bounds.extend(L.point(bounds.min.x, bounds.max.y + this.options.marginY)); - this._bounds.push(bounds); + + if (this._selected.annotation && this._selected.bounds && this._selected.bounds.intersects(foundBounds)) { + foundBounds.extend(this._selected.bounds.min); + latlng = this._map.layerPointToLatLng(this._selected.bounds.getBottomLeft()); + foundBounds.extend(this._selected.bounds.getBottomLeft().add([0, bounds.getSize().y + this.options.marginY])); + this._selected.bounds = null; } + + annotation.setLatLng(latlng); annotation.show(); } }, - add: function (annotation) { + add: function (comment) { + this._items[comment.id] = L.annotation(this._map.options.maxBounds.getSouthEast(), comment).addTo(this._map).edit(); + this._anchors.push({anchor: comment.anchorPos, id: comment.id}); + this._anchors.sort(function(a, b) { + return Math.abs(a.anchor.y) - Math.abs(b.anchor.y); + }); + this.select(comment.id); + this._items[comment.id].focus(); }, remove: function (annotation) { }, + _onAnnotationCancel: function (e) { + if (e.id === -1) { + for (var index in this._anchors) { + if (this._anchors[index].id === e.id) { + this._anchors.splice(index, 1); + break; + } + } + this._map.removeLayer(this._items[e.id]); + this.unselect(); + delete this._items[e.id]; + this._map.focus(); + } + }, + _onAnnotationClick: function (e) { this.select(e.id); + }, + + _onAnnotationSave: function (e) { + this._items[e.id].updateEdit(); + this._items[e.id].show(); + this.layout(); } }); + +L.Map.include({ + insertComment: function() { + this._docLayer._annotations.add({ + text: '', + textrange: '', + author: _('You'), + dateTime: new Date().toDateString(), + id: -1, + anchorPos: this._docLayer._latLngToTwips(this._docLayer._visibleCursor.getNorthWest()) + }); + } +}); + + L.annotationManager = function (map) { return new L.AnnotationManager(map); }; diff --git a/loleaflet/src/layer/marker/Annotation.js b/loleaflet/src/layer/marker/Annotation.js index dbb3189..142c73e 100644 --- a/loleaflet/src/layer/marker/Annotation.js +++ b/loleaflet/src/layer/marker/Annotation.js @@ -30,7 +30,7 @@ L.Annotation = L.Layer.extend({ }, onRemove: function (map) { - map._panes.makerPane.removeChild(this._container); + map._panes.markerPane.removeChild(this._container); this._map = null; }, @@ -57,6 +57,23 @@ L.Annotation = L.Layer.extend({ show: function () { this._container.style.visibility = ''; + this._contentNode.style.display = ''; + this._editNode.style.display = 'none'; + }, + + edit: function () { + this._container.style.visibility = ''; + this._contentNode.style.display = 'none'; + this._editNode.style.display = ''; + return this; + }, + + updateEdit: function () { + this._contentText.innerHTML = this._editText.value; + }, + + focus: function () { + this._editText.focus(); }, _initLayout: function () { @@ -65,38 +82,48 @@ L.Annotation = L.Layer.extend({ var wrapper = this._wrapper = L.DomUtil.create('div', 'loleaflet-annotation-content-wrapper', container); + L.DomEvent.disableScrollPropagation(this._container); this._contentNode = L.DomUtil.create('div', 'loleaflet-annotation-content', wrapper); - L.DomEvent.disableScrollPropagation(this._contentNode); - - this._text = document.createElement('span'); - this._author = document.createElement('span'); - this._dateTime = document.createElement('span'); - this._contentNode.appendChild(this._text); - this._contentNode.appendChild(document.createElement('br')); - this._contentNode.appendChild(document.createElement('br')); - this._contentNode.appendChild(this._author); - this._contentNode.appendChild(document.createElement('br')); - this._contentNode.appendChild(this._dateTime); + this._editNode = L.DomUtil.create('div', 'loleaflet-annotation-content', wrapper); + + this._contentText = L.DomUtil.create('div', '', this._contentNode); + this._contentAuthor = L.DomUtil.create('div', '', this._contentNode); + this._contentDate = L.DomUtil.create('div', '', this._contentNode); + + this._editText = L.DomUtil.create('textarea', 'loleaflet-annotation-textarea', this._editNode); + this._editAuthor = L.DomUtil.create('div', '', this._editNode); + this._editDate = L.DomUtil.create('div', '', this._editNode); + + var buttons = L.DomUtil.create('div', '', this._editNode); + var button = L.DomUtil.create('input', 'loleaflet-controls', buttons); + button.type = 'button'; + button.value = _(' Save '); + L.DomEvent.on(button, 'click', this._onSaveClick, this); + button = L.DomUtil.create('input', 'loleaflet-controls', buttons); + button.type = 'button'; + button.value = _('Cancel'); + L.DomEvent.on(button, 'click', this._onCancelClick, this); + this._container.style.visibility = 'hidden'; + this._editNode.style.display = 'none'; - var events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu']; + var events = ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout', 'keydown', 'keypress', 'keyup', 'contextmenu']; L.DomEvent.on(container, 'click', this._onMouseClick, this); - for (var it = 0; it < events.length; it++) { - L.DomEvent.on(container, events[it], this._stopMouseEvent, this); + L.DomEvent.on(container, events[it], L.DomEvent.stopPropagation, this); } }, - _onMouseClick: function (e) { - this._map.fire('AnnotationClick', {id: this._data.id}); + _onCancelClick: function (e) { + this._map.fire('AnnotationCancel', {id: this._data.id}); }, - _stopMouseEvent: function (e) { - if (e.type !== 'mousedown') { - L.DomEvent.stopPropagation(e); - } else { - L.DomEvent.preventDefault(e); - } + _onSaveClick: function (e) { + this._map.fire('AnnotationSave', {id: this._data.id}); + }, + + _onMouseClick: function (e) { + this._map.fire('AnnotationClick', {id: this._data.id}); }, _updateLayout: function () { @@ -110,9 +137,9 @@ L.Annotation = L.Layer.extend({ }, _updateContent: function () { - this._text.innerHTML = this._data.text; - this._author.innerHTML = this._data.author; - this._dateTime.innerHTML = this._data.dateTime; + this._contentText.innerHTML = this._editText.innerHTML = this._data.text; + this._contentAuthor.innerHTML = this._editAuthor.innerHTML = this._data.author; + this._contentDate.innerHTML = this._editDate.innerHTML = this._data.dateTime; }, _updatePosition: function () { commit b2b1dc8dafa9cf2a0c2428ce4ae4f368f3b4cb31 Author: Henry Castro <hcas...@collabora.com> Date: Sat Feb 11 21:21:18 2017 -0400 .gitignore loolwsd_fuzzer diff --git a/.gitignore b/.gitignore index 14fcf08..8d1a320 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ loolstress loolforkit-nocaps loadtest unittest +loolwsd_fuzzer # make tags TAGS _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits