[Libreoffice-commits] online.git: Branch 'private/mmeeks/clipboard' - 5 commits - loleaflet/src loleaflet/test wsd/LOOLWSD.cpp

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Tue Aug 6 02:25:06 UTC 2019


 loleaflet/src/map/Clipboard.js |  100 ++++++++++++++++++----------
 loleaflet/test/copy-test.html  |  146 +++++++++++++++++++++++++++++++++++++++++
 wsd/LOOLWSD.cpp                |    2 
 3 files changed, 214 insertions(+), 34 deletions(-)

New commits:
commit d34ba83dd3dcb36c9a9c31e0f43df24ec5e26413
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed Jul 31 09:50:04 2019 +0000
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 22:24:33 2019 -0400

    Use rich paste also for IE
    
    Change-Id: I220af7fb1d2e7326e61c8ef4f9ec73980f65388b

diff --git a/loleaflet/src/map/Clipboard.js b/loleaflet/src/map/Clipboard.js
index 7768914e0..079f41e9f 100644
--- a/loleaflet/src/map/Clipboard.js
+++ b/loleaflet/src/map/Clipboard.js
@@ -657,7 +657,7 @@ L.Clipboard = L.Class.extend({
 			var active = document.activeElement;
 			// Can't get HTML until it is pasted ... so quick timeout
 			setTimeout(function() {
-				that.dataTransferToDocument(null, /* preferInternal = */ false, that._dummyDiv.innerHTML);
+				that.dataTransferToDocument(null, /* preferInternal = */ true, that._dummyDiv.innerHTML);
 				// attempt to restore focus.
 				if (active == null)
 					that._map.focus();
commit bd3c723e410f8123a3e3bd65bcbeac9e740e338e
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Mon Jul 15 12:53:06 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 22:22:50 2019 -0400

    copy/paste test - expand to paste.
    
    Change-Id: I69db38511aa70f1c2e7ff9613f49307dfe952bae

diff --git a/loleaflet/test/copy-test.html b/loleaflet/test/copy-test.html
index 761b215eb..a4165b2b2 100644
--- a/loleaflet/test/copy-test.html
+++ b/loleaflet/test/copy-test.html
@@ -23,7 +23,13 @@
       <li id="aclass" data-event="both-aclass"><a class>Both AClass (fails on iOS)</a></li>
       <li/>
       <li/>
+      <li id="paste" data-event="paste"><a href="#">Paste</a></li>
+      <li/>
+      <li/>
     </ul>
+
+    <div id="clipcontent">
+    </div>
 </body>
   <script defer>
     var serial = 42;
@@ -104,5 +110,37 @@
         doSelect();
     };
 
+    // --------- copy function ---------
+    var paste = document.getElementById('paste');
+    paste.onclick = function(ev) {
+
+        if (document.execCommand('paste'))
+            console.log('Paste succeeded');
+        else
+            console.log('Paste failed');
+    };
+
+    document.onpaste = function(ev) {
+        if (!ev.clipboardData) { // non-standard
+            console.log('No clipboard data');
+            return;
+        }
+
+        var dataTransfer = ev.clipboardData;
+        var types = dataTransfer.types;
+
+        console.log('We have ' + types.length + ' types');
+        for (var t = 0; t < types.length; ++t) {
+            var data = new Blob([dataTransfer.getData(types[t])]);
+            console.log('type ' + types[t] + ' length ' + data.size +
+			    ' -> 0x' + data.size.toString(16));
+            if (types[t].startsWith('text/'))
+                 console.log('data: ' + dataTransfer.getData(types[t]));
+        }
+
+        ev.preventDefault();
+        return false;
+    };
+
     </script>
 </body></html>
commit e774e569811f05ba095921cc48f5275c5a9f74f4
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Mon Jul 15 11:52:49 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 22:22:31 2019 -0400

    Add test bits for copy/paste.
    
    Change-Id: I7e1b0bf8c834a414d2f8a87bd16ebf8465dd324a

diff --git a/loleaflet/test/copy-test.html b/loleaflet/test/copy-test.html
new file mode 100644
index 000000000..761b215eb
--- /dev/null
+++ b/loleaflet/test/copy-test.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Copy Test</title>
+<meta charset="utf-8">
+</head>
+  <body id="body" style="user-select: none;"> <!-- text doesn't seem to matter here -->
+    <h1>Test clipboard code: none</h1>
+    <div id="area_id" contenteditable="true" style="-webkit-user-select: text; border: red; background-color: grey">dummy content</div>
+
+    <ul>
+      <li id="select" data-event="select"><a href="#" class="item-link list-button">Select All</a></li>
+      <li/>
+      <li/>
+      <li id="both" data-event="both"><a href="#" class="item-link list-button">Both TouchStart</a></li>
+      <li/>
+      <li/>
+      <li id="bothclick" data-event="both-click"><a href="#" class="item-link list-button">Both Click</a></li>
+      <li/>
+      <li/>
+      <li id="bothstopclick" data-event="both-stop-click"><a href="#" class="item-link list-button">Both StoponTouch Click</a></li>
+      <li/>
+      <li/>
+      <li id="aclass" data-event="both-aclass"><a class>Both AClass (fails on iOS)</a></li>
+      <li/>
+      <li/>
+    </ul>
+</body>
+  <script defer>
+    var serial = 42;
+
+    document.getElementById('area_id').focus();
+
+    // --------- select function ---------
+    var doSelect = function() {
+        console.log('select whole area');
+        var selection     = window.getSelection();
+        selection.removeAllRanges();
+        var rangeToSelect = document.createRange();
+        elem = document.getElementById('area_id');
+        rangeToSelect.selectNodeContents(elem);
+        selection.addRange(rangeToSelect);
+    };
+    var select = document.getElementById('select');
+    select.onclick = function(ev) {
+        doSelect();
+    };
+
+    // --------- copy function ---------
+    var doCopy = function(ev) {
+        console.log('On touch copy invoke');
+
+        try
+        {
+            console.log('exec command copy - before');
+            _ret = document.execCommand('copy');
+           console.log('exec command copy success: ' + _ret);
+        }
+        catch (err)
+        {
+           console.log('exception in copy ' + err);
+           _ret = false;
+        }
+    };
+
+    // --------- both function ---------
+    var both = document.getElementById('both');
+    both.ontouchstart = function(ev) {
+        doCopy();
+    };
+
+    var bothClick = document.getElementById('bothclick');
+    bothClick.onclick = function(ev) {
+        doCopy();
+    };
+
+    // JQuery context menu does this on touch - killing a click event
+    var bothStopClick = document.getElementById('bothstopclick');
+    bothStopClick.ontouchstart = function(ev) {
+        console.log('stop on touch!');
+        ev.preventDefault();
+        ev.stopImmediatePropagation();
+        return false;
+    };
+    bothStopClick.onclick = function(ev) {
+        doCopy();
+    };
+
+    var aclass = document.getElementById('aclass');
+    aclass.onclick = function(ev) {
+        doCopy();
+    };
+
+    // Actually put serial data in the thing ..
+    document.oncopy = function(ev) {
+        ev.preventDefault();
+        var forclip = 'serial ' + serial++ + ' ops';
+        console.log('set clip to ' + forclip);
+        ev.clipboardData.setData('text/plain', forclip);
+    };
+
+    // Do the selection
+    document.onbeforecopy = function(ev) {
+        console.log('we have to select in a before copy event [!]');
+        doSelect();
+    };
+
+    </script>
+</body></html>
commit 852e8f4b0e5f503903ab3aef545c7172bdf05004
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Fri Jul 12 21:45:52 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 22:22:21 2019 -0400

    More IE11 work, paste works again, cut/copy pending.
    
    Change-Id: I744e76c7ecb655c42ed3dfb0662c0995d2c48650

diff --git a/loleaflet/src/map/Clipboard.js b/loleaflet/src/map/Clipboard.js
index 34aee3649..7768914e0 100644
--- a/loleaflet/src/map/Clipboard.js
+++ b/loleaflet/src/map/Clipboard.js
@@ -414,13 +414,8 @@ L.Clipboard = L.Class.extend({
 			console.log('Error: collapsed selection - cannot copy/paste');
 	},
 
-	populateClipboard: function(ev) {
+	_getHtmlForClipboard: function() {
 		var text;
-
-		this._checkSelection();
-
-//		this._stopHideDownload(); - this confuses the borwser ruins copy/cut on iOS
-
 		if (this._selectionType === 'complex' ||
 		    this._map._docLayer.hasGraphicSelection()) {
 			console.log('Copy/Cut with complex/graphical selection');
@@ -444,6 +439,24 @@ L.Clipboard = L.Class.extend({
 			console.log('Copy/Cut with simple text selection');
 			text = this._selectionContent;
 		}
+		return text;
+	},
+
+	// returns whether we shold stop processing the event
+	populateClipboard: function(ev) {
+		this._checkSelection();
+
+		if (window.isInternetExplorer)
+		{
+			var that = this;
+			setTimeout(function() { that._resetDiv(); }, 0);
+			this._clipboardSerial++; // we have no way of knowing of course.
+			// We let the browser copy from our div.
+			return false;
+		}
+
+		var text = this._getHtmlForClipboard();
+//		this._stopHideDownload(); - this confuses the borwser ruins copy/cut on iOS
 
 		var plainText = this.stripHTML(text);
 		if (ev.clipboardData) { // Standard
@@ -451,11 +464,9 @@ L.Clipboard = L.Class.extend({
 			ev.clipboardData.setData('text/html', text);
 			console.log('Put "' + text + '" on the clipboard');
 			this._clipboardSerial++;
-
-		} else if (window.clipboardData) { // IE 11 - poor clipboard API
-			if (window.clipboardData.setData('Text', plainText))
-				this._clipboardSerial++;
 		}
+
+		return true; // prevent default
 	},
 
 	// only used by IE.
@@ -466,23 +477,49 @@ L.Clipboard = L.Class.extend({
 		// Now wait for the paste ...
 	},
 
+	// Does the selection of text before an event comes in
 	_beforeSelect: function(ev) {
 		console.log('Got event ' + ev.type + ' setting up selection');
 
-		this._resetDiv();
+		if (window.isInternetExplorer && ev.type != 'paste')
+			// We need populate our content into the div for
+			// the brower to copy.
+			this._dummyDiv.innerHTML = this._getHtmlForClipboard();
+		else
+			// We need some spaces in there ...
+			this._resetDiv();
 
 		var sel = document.getSelection();
 		if (!sel)
 			return;
 
-		sel.removeAllRanges();
-		var rangeToSelect = document.createRange();
-		rangeToSelect.selectNodeContents(this._dummyDiv);
-		sel.addRange(rangeToSelect);
+		var selected = false;
+		var selectRange;
+		if (window.isInternetExplorer && ev.type != 'paste')
+		{
+			this._dummyDiv.focus();
 
-		var checkSelect = document.getSelection();
-		if (checkSelect.isCollapsed)
-			console.log('Error: failed to select - cannot copy/paste');
+			if (document.body.createTextRange) // Internet Explorer
+			{
+				console.log('Legacy IE11 selection');
+				selectRange = document.body.createTextRange();
+				selectRange.moveToElementText(this._dummyDiv);
+				selectRange.select();
+				selected = true;
+			}
+		}
+
+		if (!selected)
+		{
+			sel.removeAllRanges();
+			selectRange = document.createRange();
+			selectRange.selectNodeContents(this._dummyDiv);
+			sel.addRange(selectRange);
+
+			var checkSelect = document.getSelection();
+			if (checkSelect.isCollapsed)
+				console.log('Error: failed to select - cannot copy/paste');
+		}
 
 		return false;
 	},
@@ -595,21 +632,19 @@ L.Clipboard = L.Class.extend({
 		return true;
 	},
 
-	copy: function(ev) {
-		console.log('Copy');
-		ev.preventDefault();
-		this.populateClipboard(ev);
-		this._map._socket.sendMessage('uno .uno:Copy');
-		return false;
+	_doCopyCut: function(ev, unoName) {
+		console.log(unoName);
+		var preventDefault = this.populateClipboard(ev);
+		this._map._socket.sendMessage('uno .uno:' + unoName);
+		if (preventDefault) {
+			ev.preventDefault();
+			return false;
+		}
 	},
 
-	cut: function(ev) {
-		console.log('Cut');
-		ev.preventDefault();
-		this.populateClipboard(ev);
-		this._map._socket.sendMessage('uno .uno:Cut');
-		return false;
-	},
+	cut:  function(ev) { return this._doCopyCut(ev, 'Cut'); },
+
+	copy: function(ev) { return this._doCopyCut(ev, 'Copy'); },
 
 	paste: function(ev) {
 		console.log('Paste');
@@ -622,8 +657,7 @@ L.Clipboard = L.Class.extend({
 			var active = document.activeElement;
 			// Can't get HTML until it is pasted ... so quick timeout
 			setTimeout(function() {
-				var tmpDiv = document.getElementById(that._dummyDivName);
-				that.dataTransferToDocument(null, /* preferInternal = */ false, tmpDiv.innerHTML);
+				that.dataTransferToDocument(null, /* preferInternal = */ false, that._dummyDiv.innerHTML);
 				// attempt to restore focus.
 				if (active == null)
 					that._map.focus();
commit 1c9a3db307c546fb82f56b36183a81875dab9c82
Author:     Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Wed Jul 10 17:03:09 2019 +0100
Commit:     Michael Meeks <michael.meeks at collabora.com>
CommitDate: Mon Aug 5 22:22:16 2019 -0400

    clipboard: remove inadvertent debug.
    
    Change-Id: I59833519d5f4a8b16c7925a8094c974a1e7f5c11

diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp
index 3ed895cdc..9cccc78df 100644
--- a/wsd/LOOLWSD.cpp
+++ b/wsd/LOOLWSD.cpp
@@ -2156,7 +2156,7 @@ private:
                 StringTokenizer reqPathTokens(request.getURI(), "/?", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
                 if (reqPathTokens.count() > 1 && reqPathTokens[0] == "lool" && reqPathTokens[1] == "clipboard")
                 {
-                    Util::dumpHex(std::cerr, "clipboard:\n", "", socket->getInBuffer()); // lots of data ...
+//                    Util::dumpHex(std::cerr, "clipboard:\n", "", socket->getInBuffer()); // lots of data ...
                     handleClipboardRequest(request, message, disposition);
                 }
                 else if (!(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0) &&


More information about the Libreoffice-commits mailing list