add Clipboard component for ios and android

Summary:
add Clipboard component for ios and android
 ```javascript
    import Clipboard from 'react-native'

    Clipboard.get((content)=>{
          console.log('here is content in clipboard:%s',content)
    });
    var content = 'here is a string';
    Clipboard.set(content);
```
Closes https://github.com/facebook/react-native/pull/4384

Reviewed By: svcscm

Differential Revision: D2738881

Pulled By: mkonicek

fb-gh-sync-id: a06df32d1eb2824cc9ca3de9d45e4e67fd2edbc9
This commit is contained in:
tantan 2015-12-09 10:00:19 -08:00 committed by facebook-github-bot-4
parent cd4574498d
commit 90c7ad112f
12 changed files with 188 additions and 16 deletions

View File

@ -0,0 +1,60 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @flow
*/
'use strict';
var React = require('react-native');
var {
Clipboard,
View,
Text,
} = React;
var ClipboardExample = React.createClass({
getInitialState: function() {
return {
content: 'Content will appear here'
};
},
_setContentToClipboard:function(){
Clipboard.setString('Hello World');
Clipboard.getString(content => {
this.setState({content});
});
},
render() {
return (
<View>
<Text onPress={this._setContentToClipboard} style={{color: 'blue'}}>
Tap to put "Hello World" in the clipboard
</Text>
<Text style={{color: 'red', marginTop: 20}}>
{this.state.content}
</Text>
</View>
);
}
});
exports.title = 'Clipboard';
exports.description = 'Show Clipboard contents.';
exports.examples = [
{
title: 'Clipboard.setString() and getString()',
render(): ReactElement { return <ClipboardExample />; }
}
];

View File

@ -39,6 +39,7 @@ var COMPONENTS = [
var APIS = [
require('./AccessibilityAndroidExample.android'),
require('./BorderExample'),
require('./ClipboardExample'),
require('./GeolocationExample'),
require('./IntentAndroidExample.android'),
require('./LayoutEventsExample'),

View File

@ -66,6 +66,7 @@ var APIS = [
require('./AsyncStorageExample'),
require('./BorderExample'),
require('./CameraRollExample.ios'),
require('./ClipboardExample'),
require('./GeolocationExample'),
require('./LayoutExample'),
require('./NetInfoExample'),

View File

@ -54,8 +54,8 @@ var NativeModules = {
AlertManager: {
alertWithArgs: jest.genMockFunction(),
},
Pasteboard: {
setPasteboardString: jest.genMockFunction(),
Clipboard: {
setString: jest.genMockFunction(),
},
};

View File

@ -0,0 +1,13 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Clipboard
*/
'use strict';
module.exports = require('NativeModules').Clipboard;

View File

@ -58,6 +58,7 @@ var ReactNative = {
get AsyncStorage() { return require('AsyncStorage'); },
get BackAndroid() { return require('BackAndroid'); },
get CameraRoll() { return require('CameraRoll'); },
get Clipboard() { return require('Clipboard'); },
get Dimensions() { return require('Dimensions'); },
get Easing() { return require('Easing'); },
get ImagePickerIOS() { return require('ImagePickerIOS'); },

View File

@ -70,6 +70,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
AsyncStorage: require('AsyncStorage'),
BackAndroid: require('BackAndroid'),
CameraRoll: require('CameraRoll'),
Clipboard: require('Clipboard'),
Dimensions: require('Dimensions'),
Easing: require('Easing'),
ImagePickerIOS: require('ImagePickerIOS'),

View File

@ -9,6 +9,6 @@
#import "RCTBridgeModule.h"
@interface RCTPasteboard : NSObject <RCTBridgeModule>
@interface RCTClipboard : NSObject <RCTBridgeModule>
@end

View File

@ -7,11 +7,13 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTPasteboard.h"
#import "RCTClipboard.h"
#import "RCTUtils.h"
#import <UIKit/UIKit.h>
@implementation RCTPasteboard
@implementation RCTClipboard
RCT_EXPORT_MODULE()
@ -20,9 +22,16 @@ RCT_EXPORT_MODULE()
return dispatch_get_main_queue();
}
RCT_EXPORT_METHOD(setPasteboardString:(NSString *)string)
RCT_EXPORT_METHOD(getString:(RCTResponseSenderBlock)callback)
{
[[UIPasteboard generalPasteboard] setString:string];
UIPasteboard *clipboard = [UIPasteboard generalPasteboard];
callback(@[RCTNullIfNil(clipboard.string)]);
}
RCT_EXPORT_METHOD(setString:(NSString *)content)
{
UIPasteboard *clipboard = [UIPasteboard generalPasteboard];
clipboard.string = content;
}
@end

View File

@ -38,12 +38,12 @@
13B0801D1A69489C00A75B9A /* RCTNavItemManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080131A69489C00A75B9A /* RCTNavItemManager.m */; };
13B080201A69489C00A75B9A /* RCTActivityIndicatorViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080191A69489C00A75B9A /* RCTActivityIndicatorViewManager.m */; };
13B080261A694A8400A75B9A /* RCTWrapperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */; };
13BB3D021BECD54500932C10 /* RCTImageSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BB3D011BECD54500932C10 /* RCTImageSource.m */; };
13B202011BFB945300C07393 /* RCTPasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B202001BFB945300C07393 /* RCTPasteboard.m */; };
13B202041BFB948C00C07393 /* RCTMapAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B202031BFB948C00C07393 /* RCTMapAnnotation.m */; };
13BB3D021BECD54500932C10 /* RCTImageSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BB3D011BECD54500932C10 /* RCTImageSource.m */; };
13C156051AB1A2840079392D /* RCTWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13C156021AB1A2840079392D /* RCTWebView.m */; };
13C156061AB1A2840079392D /* RCTWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13C156041AB1A2840079392D /* RCTWebViewManager.m */; };
13CC8A821B17642100940AE7 /* RCTBorderDrawing.m in Sources */ = {isa = PBXBuildFile; fileRef = 13CC8A811B17642100940AE7 /* RCTBorderDrawing.m */; };
13D033631C1837FE0021DC29 /* RCTClipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D033621C1837FE0021DC29 /* RCTClipboard.m */; };
13E0674A1A70F434002CDEE1 /* RCTUIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E067491A70F434002CDEE1 /* RCTUIManager.m */; };
13E067551A70F44B002CDEE1 /* RCTShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674C1A70F44B002CDEE1 /* RCTShadowView.m */; };
13E067561A70F44B002CDEE1 /* RCTViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E0674E1A70F44B002CDEE1 /* RCTViewManager.m */; };
@ -174,12 +174,10 @@
13B080191A69489C00A75B9A /* RCTActivityIndicatorViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTActivityIndicatorViewManager.m; sourceTree = "<group>"; };
13B080231A694A8400A75B9A /* RCTWrapperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWrapperViewController.h; sourceTree = "<group>"; };
13B080241A694A8400A75B9A /* RCTWrapperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWrapperViewController.m; sourceTree = "<group>"; };
13BB3D001BECD54500932C10 /* RCTImageSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageSource.h; sourceTree = "<group>"; };
13BB3D011BECD54500932C10 /* RCTImageSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageSource.m; sourceTree = "<group>"; };
13B201FF1BFB945300C07393 /* RCTPasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPasteboard.h; sourceTree = "<group>"; };
13B202001BFB945300C07393 /* RCTPasteboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPasteboard.m; sourceTree = "<group>"; };
13B202021BFB948C00C07393 /* RCTMapAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTMapAnnotation.h; sourceTree = "<group>"; };
13B202031BFB948C00C07393 /* RCTMapAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTMapAnnotation.m; sourceTree = "<group>"; };
13BB3D001BECD54500932C10 /* RCTImageSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageSource.h; sourceTree = "<group>"; };
13BB3D011BECD54500932C10 /* RCTImageSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageSource.m; sourceTree = "<group>"; };
13C156011AB1A2840079392D /* RCTWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebView.h; sourceTree = "<group>"; };
13C156021AB1A2840079392D /* RCTWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTWebView.m; sourceTree = "<group>"; };
13C156031AB1A2840079392D /* RCTWebViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTWebViewManager.h; sourceTree = "<group>"; };
@ -189,6 +187,8 @@
13C325281AA63B6A0048765F /* RCTComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTComponent.h; sourceTree = "<group>"; };
13CC8A801B17642100940AE7 /* RCTBorderDrawing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBorderDrawing.h; sourceTree = "<group>"; };
13CC8A811B17642100940AE7 /* RCTBorderDrawing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBorderDrawing.m; sourceTree = "<group>"; };
13D033611C1837FE0021DC29 /* RCTClipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTClipboard.h; sourceTree = "<group>"; };
13D033621C1837FE0021DC29 /* RCTClipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTClipboard.m; sourceTree = "<group>"; };
13E067481A70F434002CDEE1 /* RCTUIManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUIManager.h; sourceTree = "<group>"; };
13E067491A70F434002CDEE1 /* RCTUIManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManager.m; sourceTree = "<group>"; };
13E0674B1A70F44B002CDEE1 /* RCTShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowView.h; sourceTree = "<group>"; };
@ -318,14 +318,14 @@
1372B7091AB030C200659ED6 /* RCTAppState.m */,
58114A4F1AAE93D500E7D092 /* RCTAsyncLocalStorage.h */,
58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */,
13D033611C1837FE0021DC29 /* RCTClipboard.h */,
13D033621C1837FE0021DC29 /* RCTClipboard.m */,
13A0C2851B74F71200B29F6F /* RCTDevLoadingView.h */,
13A0C2861B74F71200B29F6F /* RCTDevLoadingView.m */,
13A0C2871B74F71200B29F6F /* RCTDevMenu.h */,
13A0C2881B74F71200B29F6F /* RCTDevMenu.m */,
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */,
13B07FEA1A69327A00A75B9A /* RCTExceptionsManager.m */,
13B201FF1BFB945300C07393 /* RCTPasteboard.h */,
13B202001BFB945300C07393 /* RCTPasteboard.m */,
13F17A831B8493E5007D4C75 /* RCTRedBox.h */,
13F17A841B8493E5007D4C75 /* RCTRedBox.m */,
000E6CE91AB0E97F000CDF4D /* RCTSourceCode.h */,
@ -628,7 +628,6 @@
13723B501A82FD3C00F88898 /* RCTStatusBarManager.m in Sources */,
000E6CEB1AB0E980000CDF4D /* RCTSourceCode.m in Sources */,
133CAE8E1B8E5CFD00F6AD92 /* RCTDatePicker.m in Sources */,
13B202011BFB945300C07393 /* RCTPasteboard.m in Sources */,
14C2CA761B3AC64F00E6CBB2 /* RCTFrameUpdate.m in Sources */,
13B07FEF1A69327A00A75B9A /* RCTAlertManager.m in Sources */,
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */,
@ -669,6 +668,7 @@
14C2CA781B3ACB0400E6CBB2 /* RCTBatchedBridge.m in Sources */,
13E067591A70F44B002CDEE1 /* UIView+React.m in Sources */,
14F484561AABFCE100FDF6B9 /* RCTSliderManager.m in Sources */,
13D033631C1837FE0021DC29 /* RCTClipboard.m in Sources */,
14C2CA741B3AC64300E6CBB2 /* RCTModuleData.m in Sources */,
142014191B32094000CC17BA /* RCTPerformanceLogger.m in Sources */,
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */,

View File

@ -0,0 +1,84 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.modules.clipboard;
import android.annotation.SuppressLint;
import android.content.ClipboardManager;
import android.content.ClipData;
import android.os.Build;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.common.ReactConstants;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A module that allows JS to get/set clipboard contents.
*/
public class ClipboardModule extends ReactContextBaseJavaModule {
public ClipboardModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "Clipboard";
}
private ClipboardManager getClipboardService() {
ReactApplicationContext reactContext = getReactApplicationContext();
return (ClipboardManager) reactContext.getSystemService(reactContext.CLIPBOARD_SERVICE);
}
@ReactMethod
public void getString(Callback cb) {
try {
ClipboardManager clipboard = getClipboardService();
ClipData clipData = clipboard.getPrimaryClip();
if (clipData == null) {
cb.invoke("");
return;
}
if (clipData.getItemCount() >= 1) {
ClipData.Item firstItem = clipboard.getPrimaryClip().getItemAt(0);
String text = "" + firstItem.getText();
cb.invoke(text);
} else {
cb.invoke("");
}
} catch(Exception e) {
FLog.w(ReactConstants.TAG, "Cannot get clipboard contents: " + e.getMessage());
}
}
@SuppressLint("DeprecatedMethod")
@ReactMethod
public void setString(String text) {
ReactApplicationContext reactContext = getReactApplicationContext();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ClipData clipdata = ClipData.newPlainText(null, text);
ClipboardManager clipboard = getClipboardService();
clipboard.setPrimaryClip(clipdata);
} else {
ClipboardManager clipboard = getClipboardService();
clipboard.setText(text);
}
}
}

View File

@ -41,6 +41,7 @@ import com.facebook.react.views.toolbar.ReactToolbarManager;
import com.facebook.react.views.view.ReactViewManager;
import com.facebook.react.views.viewpager.ReactViewPagerManager;
import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager;
import com.facebook.react.modules.clipboard.ClipboardModule;
/**
* Package defining basic modules and view managers.
@ -51,6 +52,7 @@ public class MainReactPackage implements ReactPackage {
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(
new AsyncStorageModule(reactContext),
new ClipboardModule(reactContext),
new FrescoModule(reactContext),
new IntentModule(reactContext),
new LocationModule(reactContext),