diff options
-rw-r--r-- | remoting/webapp/base/js/application.js | 1 | ||||
-rw-r--r-- | remoting/webapp/crd/js/client_plugin.js | 10 | ||||
-rw-r--r-- | remoting/webapp/crd/js/client_plugin_impl.js | 34 | ||||
-rw-r--r-- | remoting/webapp/crd/js/client_session.js | 12 | ||||
-rw-r--r-- | remoting/webapp/crd/js/clipboard.js | 146 | ||||
-rw-r--r-- | remoting/webapp/crd/js/connected_view.js | 13 | ||||
-rw-r--r-- | remoting/webapp/crd/js/remoting.js | 33 |
7 files changed, 114 insertions, 135 deletions
diff --git a/remoting/webapp/base/js/application.js b/remoting/webapp/base/js/application.js index 4881380..4679ab8 100644 --- a/remoting/webapp/base/js/application.js +++ b/remoting/webapp/base/js/application.js @@ -159,7 +159,6 @@ remoting.Application.prototype.initSession_ = function(connectionInfo) { this.onSessionFinished_.bind(this)), new base.RepeatingTimer(this.updateStatistics_.bind(this), 1000) ); - remoting.clipboard.startSession(); }; /** diff --git a/remoting/webapp/crd/js/client_plugin.js b/remoting/webapp/crd/js/client_plugin.js index e8b3f8d..31bb60e 100644 --- a/remoting/webapp/crd/js/client_plugin.js +++ b/remoting/webapp/crd/js/client_plugin.js @@ -157,8 +157,14 @@ remoting.ClientPlugin.prototype.setConnectionEventHandler = * URL encoding the mouse cursor; the second and third parameters are * the cursor hotspot's x- and y-coordinates, respectively. */ -remoting.ClientPlugin.prototype.setMouseCursorHandler = - function(handler) {}; +remoting.ClientPlugin.prototype.setMouseCursorHandler = function(handler) {}; + +/** + * @param {function(string, string):void} handler Callback for processing + * clipboard data injected from the host. The first parameter is the mime + * type and the second parameter is the actual data. + */ +remoting.ClientPlugin.prototype.setClipboardHandler = function(handler) {}; /** * @param {function({rects:Array<Array<number>>}):void|null} handler Callback diff --git a/remoting/webapp/crd/js/client_plugin_impl.js b/remoting/webapp/crd/js/client_plugin_impl.js index c3808b4..0e0f916 100644 --- a/remoting/webapp/crd/js/client_plugin_impl.js +++ b/remoting/webapp/crd/js/client_plugin_impl.js @@ -44,23 +44,12 @@ remoting.ClientPluginImpl = function(container, /** @private {remoting.ClientPlugin.ConnectionEventHandler} */ this.connectionEventHandler_ = null; - /** - * @param {string} data Remote gnubbyd data. - * @private - */ - this.onGnubbyAuthHandler_ = function(data) {}; - /** - * @param {string} url - * @param {number} hotspotX - * @param {number} hotspotY - * @private - */ - this.updateMouseCursorImage_ = function(url, hotspotX, hotspotY) {}; - /** - * @param {string} data Remote cast extension message. - * @private - */ - this.onCastExtensionHandler_ = function(data) {}; + /** @private {?function(string, number, number)} */ + this.updateMouseCursorImage_ = base.doNothing; + /** @private {?function(string, string)} */ + this.updateClipboardData_ = base.doNothing; + /** @private {?function(string)} */ + this.onCastExtensionHandler_ = base.doNothing; /** @private {?function({rects:Array<Array<number>>}):void} */ this.debugRegionHandler_ = null; @@ -168,6 +157,13 @@ remoting.ClientPluginImpl.prototype.setMouseCursorHandler = function(handler) { }; /** + * @param {function(string, string):void} handler + */ +remoting.ClientPluginImpl.prototype.setClipboardHandler = function(handler) { + this.updateClipboardData_ = handler; +}; + +/** * @param {?function({rects:Array<Array<number>>}):void} handler */ remoting.ClientPluginImpl.prototype.setDebugDirtyRegionHandler = @@ -310,9 +306,7 @@ remoting.ClientPluginImpl.prototype.handleMessageMethod_ = function(message) { } else if (message.method == 'injectClipboardItem') { var mimetype = base.getStringAttr(message.data, 'mimeType'); var item = base.getStringAttr(message.data, 'item'); - if (remoting.clipboard) { - remoting.clipboard.fromHost(mimetype, item); - } + this.updateClipboardData_(mimetype, item); } else if (message.method == 'onFirstFrameReceived') { if (remoting.clientSession) { diff --git a/remoting/webapp/crd/js/client_session.js b/remoting/webapp/crd/js/client_session.js index 0328535..05a8a99 100644 --- a/remoting/webapp/crd/js/client_session.js +++ b/remoting/webapp/crd/js/client_session.js @@ -567,18 +567,6 @@ remoting.ClientSession.prototype.logHostOfflineErrors = function(enable) { }; /** - * Sends a clipboard item to the host. - * - * @param {string} mimeType The MIME type of the clipboard item. - * @param {string} item The clipboard item. - */ -remoting.ClientSession.prototype.sendClipboardItem = function(mimeType, item) { - if (!this.plugin_) - return; - this.plugin_.sendClipboardItem(mimeType, item); -}; - -/** * Sends an extension message to the host. * * @param {string} type The message type. diff --git a/remoting/webapp/crd/js/clipboard.js b/remoting/webapp/crd/js/clipboard.js index 0d11677..9d2b48c 100644 --- a/remoting/webapp/crd/js/clipboard.js +++ b/remoting/webapp/crd/js/clipboard.js @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,52 +7,60 @@ * A class for moving clipboard items between the plugin and the OS. */ -'use strict'; - /** @suppress {duplicate} */ var remoting = remoting || {}; -/** - * @constructor - */ -remoting.Clipboard = function() { -}; +(function() { + +'use strict'; /** * @private * @enum {string} */ -remoting.Clipboard.prototype.ItemTypes = { +var ItemTypes = { TEXT_TYPE: 'text/plain', TEXT_UTF8_TYPE: 'text/plain; charset=UTF-8' }; -/** @private {string} */ -remoting.Clipboard.prototype.previousContent = ""; +/** + * @constructor + * @param {remoting.ClientPlugin} plugin + * @implements {base.Disposable} + */ +remoting.Clipboard = function(plugin) { + /** @private {string} */ + this.previousContent_ = ''; -/** @private {boolean} */ -remoting.Clipboard.prototype.itemFromHostTextPending = false; + /** @private {boolean} */ + this.itemFromHostTextPending_ = false; -/** @private {boolean} */ -remoting.Clipboard.prototype.blockOneClipboardSend_ = false; + /** @private {boolean} */ + this.blockOneClipboardSend_ = true; -/** - * Notifies this object that a session has started. - * - * @return {void} Nothing. - */ -remoting.Clipboard.prototype.startSession = function() { - // Clear the store of items sent and received. Those items now relate to a - // previous session. - this.previousContent = ""; - this.itemFromHostTextPending = false; + /** @private */ + this.plugin_ = plugin; + + /** @private */ + this.eventHooks_ = new base.Disposables( + new base.DomEventHook(plugin.element(), 'focus', + this.initiateToHost_.bind(this), false), + new base.DomEventHook(window, 'paste', this.onPaste_.bind(this), false), + new base.DomEventHook(window, 'copy', this.onCopy_.bind(this), false)); // Do a paste operation, but make sure the resulting clipboard data isn't sent // to the host. This stops the host seeing items that were placed on the // clipboard before the session began. The user may not have intended such // items to be sent to the host. - this.blockOneClipboardSend_ = true; - this.initiateToHost(); + this.initiateToHost_(); + this.plugin_.setClipboardHandler(this.fromHost_.bind(this)); +}; + +remoting.Clipboard.prototype.dispose = function() { + this.plugin_.setClipboardHandler(base.doNothing); + this.plugin_ = null; + base.dispose(this.eventHooks_); + this.eventHooks_ = null; }; /** @@ -63,37 +71,34 @@ remoting.Clipboard.prototype.startSession = function() { * * @param {ClipboardData} clipboardData * @return {void} Nothing. + * @private */ -remoting.Clipboard.prototype.toHost = function(clipboardData) { +remoting.Clipboard.prototype.toHost_ = function(clipboardData) { if (!clipboardData || !clipboardData.types || !clipboardData.getData) { console.log('Got invalid clipboardData.'); return; } - if (!remoting.clientSession) { - return; - } for (var i = 0; i < clipboardData.types.length; i++) { var type = clipboardData.types[i]; var item = clipboardData.getData(type); if (!item) { - item = ""; + item = ''; } console.log('Got clipboard from OS, type: ' + type + ' length: ' + item.length + ' new: ' + - (item != this.previousContent) + ' blocking-send: ' + + (item != this.previousContent_) + ' blocking-send: ' + this.blockOneClipboardSend_); // The browser presents text clipboard items as 'text/plain'. - if (type == this.ItemTypes.TEXT_TYPE) { + if (type == ItemTypes.TEXT_TYPE) { // Don't send the same item more than once. Otherwise the item may be // sent to and fro indefinitely. - if (item != this.previousContent) { + if (item != this.previousContent_) { if (!this.blockOneClipboardSend_) { // The plugin's JSON reader emits UTF-8. console.log('Sending clipboard to host.'); - remoting.clientSession.sendClipboardItem( - this.ItemTypes.TEXT_UTF8_TYPE, item); + this.plugin_.sendClipboardItem(ItemTypes.TEXT_UTF8_TYPE, item); } - this.previousContent = item; + this.previousContent_ = item; } } } @@ -108,21 +113,21 @@ remoting.Clipboard.prototype.toHost = function(clipboardData) { * @param {string} item The clipboard item. * @return {void} Nothing. */ -remoting.Clipboard.prototype.fromHost = function(mimeType, item) { +remoting.Clipboard.prototype.fromHost_ = function(mimeType, item) { // The plugin's JSON layer will correctly convert only UTF-8 data sent from // the host. console.log('Got clipboard from host, type: ' + mimeType + ' length: ' + item.length + ' new: ' + - (item != this.previousContent)); - if (mimeType != this.ItemTypes.TEXT_UTF8_TYPE) { + (item != this.previousContent_)); + if (mimeType != ItemTypes.TEXT_UTF8_TYPE) { return; } - if (item == this.previousContent) { + if (item == this.previousContent_) { return; } - this.previousContent = item; - this.itemFromHostTextPending = true; - this.initiateToOs(); + this.previousContent_ = item; + this.itemFromHostTextPending_ = true; + this.initiateToOs_(); }; /** @@ -131,9 +136,10 @@ remoting.Clipboard.prototype.fromHost = function(mimeType, item) { * @param {ClipboardData} clipboardData * @return {boolean} Whether any clipboard items were moved to the ClipboardData * object. + * @private */ -remoting.Clipboard.prototype.toOs = function(clipboardData) { - if (!this.itemFromHostTextPending) { +remoting.Clipboard.prototype.toOs_ = function(clipboardData) { + if (!this.itemFromHostTextPending_) { console.log('Got unexpected clipboard copy event.'); return false; } @@ -141,9 +147,9 @@ remoting.Clipboard.prototype.toOs = function(clipboardData) { // JS string encoding. The browser will convert JS strings to the correct // encoding, per OS and locale conventions, provided the data type is // 'text/plain'. - console.log('Setting OS clipboard, length: ' + this.previousContent.length); - clipboardData.setData(this.ItemTypes.TEXT_TYPE, this.previousContent); - this.itemFromHostTextPending = false; + console.log('Setting OS clipboard, length: ' + this.previousContent_.length); + clipboardData.setData(ItemTypes.TEXT_TYPE, this.previousContent_); + this.itemFromHostTextPending_ = false; return true; }; @@ -154,12 +160,13 @@ remoting.Clipboard.prototype.toOs = function(clipboardData) { * This method makes the browser fire a paste event, which provides access to * the OS clipboard. That event will be caught by a handler in the document, * which will call toHost(). + * @private */ -remoting.Clipboard.prototype.initiateToHost = function() { +remoting.Clipboard.prototype.initiateToHost_ = function() { // It would be cleaner to send a paste command to the plugin element, // but that's not supported. //console.log('Initiating clipboard paste.'); - document.execCommand("paste"); + document.execCommand('paste'); }; /** @@ -169,13 +176,40 @@ remoting.Clipboard.prototype.initiateToHost = function() { * This method makes the browser fire a copy event, which provides access to * the OS clipboard. That event will be caught by a handler in the document, * which will call toOs(). + * @private */ -remoting.Clipboard.prototype.initiateToOs = function() { +remoting.Clipboard.prototype.initiateToOs_ = function() { // It would be cleaner to send a paste command to the plugin element, // but that's not supported. console.log('Initiating clipboard copy.'); - document.execCommand("copy"); + document.execCommand('copy'); +}; + +/** + * Callback function called when the browser window gets a paste operation. + * + * @param {Event} event + * @return {void} Nothing. + * @private + */ +remoting.Clipboard.prototype.onPaste_ = function(event) { + if (event && event.clipboardData) { + this.toHost_(event.clipboardData); + } +}; + +/** + * Callback function called when the browser window gets a copy operation. + * + * @param {Event} event + * @return {void} Nothing. + * @private + */ +remoting.Clipboard.prototype.onCopy_ = function(event) { + if (event && event.clipboardData && this.toOs_(event.clipboardData)) { + // The default action may overwrite items that we added to clipboardData. + event.preventDefault(); + } }; -/** @type {remoting.Clipboard} */ -remoting.clipboard = null; +})(); diff --git a/remoting/webapp/crd/js/connected_view.js b/remoting/webapp/crd/js/connected_view.js index 73f300c..f92656c 100644 --- a/remoting/webapp/crd/js/connected_view.js +++ b/remoting/webapp/crd/js/connected_view.js @@ -42,12 +42,11 @@ remoting.ConnectedView = function(plugin, viewportElement, cursorElement) { /** private */ this.disposables_ = new base.Disposables( this.cursor_, - new base.DomEventHook(pluginElement, 'focus', - this.onPluginGotFocus_.bind(this), false), new base.DomEventHook(pluginElement, 'blur', this.onPluginLostFocus_.bind(this), false), new base.DomEventHook(document, 'visibilitychange', - this.onVisibilityChanged_.bind(this), false) + this.onVisibilityChanged_.bind(this), false), + new remoting.Clipboard(plugin) ); // TODO(wez): Only allow mouse lock if the app has the pointerLock permission. @@ -91,14 +90,6 @@ remoting.ConnectedView.prototype.onConnectionReady = function(ready) { }; /** - * Callback function called when the plugin element gets focus. - * @private - */ -remoting.ConnectedView.prototype.onPluginGotFocus_ = function() { - remoting.clipboard.initiateToHost(); -}; - -/** * Callback function called when the plugin element loses focus. * @private */ diff --git a/remoting/webapp/crd/js/remoting.js b/remoting/webapp/crd/js/remoting.js index f3deae1..34a15c7 100644 --- a/remoting/webapp/crd/js/remoting.js +++ b/remoting/webapp/crd/js/remoting.js @@ -30,16 +30,10 @@ remoting.initGlobalObjects = function() { document.getElementById('statistics')); remoting.formatIq = new remoting.FormatIq(); - remoting.clipboard = new remoting.Clipboard(); var sandbox = /** @type {HTMLIFrameElement} */ (document.getElementById('wcs-sandbox')); remoting.wcsSandbox = new remoting.WcsSandboxContainer(sandbox.contentWindow); - // The plugin's onFocus handler sends a paste command to |window|, because - // it can't send one to the plugin element itself. - window.addEventListener('paste', pluginGotPaste_, false); - window.addEventListener('copy', pluginGotCopy_, false); - remoting.initModalDialogs(); remoting.testEvents = new base.EventSourceImpl(); @@ -65,33 +59,6 @@ remoting.getExtensionInfo = function() { }; /** - * Callback function called when the browser window gets a paste operation. - * - * @param {Event} event - * @return {void} Nothing. - */ -function pluginGotPaste_(event) { - if (event && event.clipboardData) { - remoting.clipboard.toHost(event.clipboardData); - } -} - -/** - * Callback function called when the browser window gets a copy operation. - * - * @param {Event} event - * @return {void} Nothing. - */ -function pluginGotCopy_(event) { - if (event && event.clipboardData) { - if (remoting.clipboard.toOs(event.clipboardData)) { - // The default action may overwrite items that we added to clipboardData. - event.preventDefault(); - } - } -} - -/** * Return the current time as a formatted string suitable for logging. * * @return {string} The current time, formatted as [mmdd/hhmmss.xyz] |