@zenkit-dev/cordova-plugin-keyboard 1.2.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,296 @@
1
+ # cordova-plugin-keyboard
2
+
3
+ > This plugin provides the `Keyboard` object which has some functions to customize and control the keyboard. It also supports the __HideKeyboardFormAccessoryBar__ (boolean) and __KeyboardShrinksView__ (boolean) preferences in config.xml.
4
+
5
+ This plugin has only been tested in Cordova 3.2 or greater, and its use in previous Cordova versions is not recommended (potential conflict with keyboard customization code present in the core in previous Cordova versions).
6
+
7
+ If you do use this plugin in an older Cordova version (again, not recommended), you have to make sure the HideKeyboardFormAccessoryBar and KeyboardShrinksView preference values are *always* false, and only use the API functions to turn things on/off.
8
+
9
+ This plugin was based on this Apache [project](https://github.com/apache/cordova-plugins/tree/master/keyboard) and has a compatible API.
10
+
11
+ - [Installation](#installation)
12
+ - [Methods](#methods)
13
+ - [cordova.plugins.Keyboard.shrinkView](#cordovapluginskeyboardshrinkview)
14
+ - [cordova.plugins.Keyboard.hideFormAccessoryBar](#cordovapluginskeyboardhideformaccessorybar)
15
+ - [cordova.plugins.Keyboard.disableScrollingInShrinkView](#cordovapluginskeyboarddisablescrollinginshrinkview)
16
+ - [cordova.plugins.Keyboard.hide](#cordovapluginskeyboardhide)
17
+ - [cordova.plugins.Keyboard.show](#cordovapluginskeyboardshow)
18
+ - [Properties](#properties)
19
+ - [cordova.plugins.Keyboard.isVisible](#cordovapluginskeyboardisvisible)
20
+ - [cordova.plugins.Keyboard.automaticScrollToTopOnHiding](#cordovapluginskeyboardautomaticscrolltotoponhiding)
21
+ - [Events](#events)
22
+ - [keyboardDidShow](#keyboarddidshow)
23
+ - [keyboardDidHide](#keyboarddidhide)
24
+ - [keyboardWillShow](#keyboardwillshow)
25
+ - [keyboardWillHide](#keyboardwillhide)
26
+ - [keyboardHeightWillChange](#keyboardheightwillchange)
27
+ - [Releases](#releases)
28
+
29
+ # Installation
30
+
31
+ From [npm](https://www.npmjs.com/package/cordova-plugin-keyboard) (stable)
32
+
33
+ `cordova plugin add cordova-plugin-keyboard`
34
+
35
+ From github latest (may not be stable)
36
+
37
+ `cordova plugin add https://github.com/cjpearson/cordova-plugin-keyboard`
38
+
39
+ # Methods
40
+
41
+ ## cordova.plugins.Keyboard.shrinkView
42
+
43
+ Shrink the WebView when the keyboard comes up.
44
+
45
+ cordova.plugins.Keyboard.shrinkView(value, successCallback);
46
+
47
+ #### Description
48
+
49
+ Set to true to shrink the WebView when the keyboard comes up. The WebView shrinks instead of the viewport shrinking and the page scrollable. This applies to apps that position their elements relative to the bottom of the WebView. This is the default behaviour on Android, and makes a lot of sense when building apps as opposed to webpages.
50
+
51
+
52
+ #### Supported Platforms
53
+
54
+ - iOS
55
+
56
+ #### Quick Example
57
+
58
+ cordova.plugins.Keyboard.shrinkView(true);
59
+ cordova.plugins.Keyboard.shrinkView(false);
60
+ cordova.plugins.Keyboard.shrinkView(null, function (currentValue) { console.log(currentValue); });
61
+
62
+ ## cordova.plugins.Keyboard.hideFormAccessoryBar
63
+
64
+ Hide the keyboard toolbar.
65
+
66
+ cordova.plugins.Keyboard.hideFormAccessoryBar(value, successCallback);
67
+
68
+ #### Description
69
+
70
+ Set to true to hide the additional toolbar that is on top of the keyboard. This toolbar features the Prev, Next, and Done buttons.
71
+
72
+
73
+ #### Supported Platforms
74
+
75
+ - iOS
76
+
77
+ #### Quick Example
78
+
79
+ cordova.plugins.Keyboard.hideFormAccessoryBar(true);
80
+ cordova.plugins.Keyboard.hideFormAccessoryBar(false);
81
+ cordova.plugins.Keyboard.hideFormAccessoryBar(null, function (currentValue) { console.log(currentValue); });
82
+
83
+ ## cordova.plugins.Keyboard.disableScrollingInShrinkView
84
+
85
+ Disable scrolling when the the WebView is shrunk.
86
+
87
+ cordova.plugins.Keyboard.disableScrollingInShrinkView(value, successCallback);
88
+
89
+ #### Description
90
+
91
+ Set to true to disable scrolling when the WebView is shrunk.
92
+
93
+
94
+ #### Supported Platforms
95
+
96
+ - iOS
97
+
98
+ #### Quick Example
99
+
100
+ cordova.plugins.Keyboard.disableScrollingInShrinkView(true);
101
+ cordova.plugins.Keyboard.disableScrollingInShrinkView(false);
102
+ cordova.plugins.Keyboard.disableScrollingInShrinkView(null, function (currentValue) { console.log(currentValue); });
103
+
104
+ ## cordova.plugins.Keyboard.hide
105
+
106
+ Hide the keyboard
107
+
108
+ cordova.plugins.Keyboard.hide();
109
+
110
+ #### Description
111
+
112
+ Call this method to hide the keyboard
113
+
114
+ #### Supported Platforms
115
+
116
+ - iOS
117
+ - Android
118
+
119
+ #### Quick Example
120
+
121
+ cordova.plugins.Keyboard.hide();
122
+
123
+ ## cordova.plugins.Keyboard.show
124
+
125
+ Show the keyboard
126
+
127
+ cordova.plugins.Keyboard.show();
128
+
129
+ #### Description
130
+
131
+ Call this method to show the keyboard.
132
+
133
+
134
+ #### Supported Platforms
135
+
136
+ - Android
137
+
138
+ #### Quick Example
139
+
140
+ cordova.plugins.Keyboard.show();
141
+
142
+ # Properties
143
+
144
+ ## cordova.plugins.Keyboard.isVisible
145
+
146
+ Determine if the keyboard is visible.
147
+
148
+ if (cordova.plugins.Keyboard.isVisible) {
149
+ // do something
150
+ }
151
+
152
+ #### Description
153
+
154
+ Read this property to determine if the keyboard is visible.
155
+
156
+
157
+ #### Supported Platforms
158
+
159
+ - iOS
160
+
161
+ ## cordova.plugins.Keyboard.automaticScrollToTopOnHiding
162
+
163
+ Specifies whenether content of page would be automatically scrolled to the top of the page
164
+ when keyboard is hiding.
165
+
166
+ cordova.plugins.Keyboard.automaticScrollToTopOnHiding = true;
167
+
168
+ #### Description
169
+
170
+ Set this to true if you need that page scroll to beginning when keyboard is hiding.
171
+ This is allows to fix issue with elements declared with position: fixed,
172
+ after keyboard is hiding.
173
+
174
+
175
+ #### Supported Platforms
176
+
177
+ - iOS
178
+
179
+ # Events
180
+
181
+ ## keyboardDidShow
182
+
183
+ This event is fired when keyboard fully shown.
184
+
185
+ window.addEventListener('keyboardDidShow', function () {
186
+ // Describe your logic which will be run each time keyboard is shown.
187
+ });
188
+
189
+ #### Description
190
+
191
+ Attach handler to this event to be able to receive notification when keyboard is shown.
192
+
193
+
194
+ #### Supported Platforms
195
+
196
+ - iOS
197
+
198
+ ## keyboardDidHide
199
+
200
+ This event is fired when the keyboard is fully closed.
201
+
202
+ window.addEventListener('keyboardDidHide', function () {
203
+ // Describe your logic which will be run each time keyboard is closed.
204
+ });
205
+
206
+ #### Description
207
+
208
+ Attach handler to this event to be able to receive notification when keyboard is closed.
209
+
210
+
211
+ #### Supported Platforms
212
+
213
+ - iOS
214
+
215
+ ## keyboardWillShow
216
+
217
+ This event fires before keyboard will be shown.
218
+
219
+ window.addEventListener('keyboardWillShow', function () {
220
+ // Describe your logic which will be run each time when keyboard is about to be shown.
221
+ });
222
+
223
+ #### Description
224
+
225
+ Attach handler to this event to be able to receive notification when keyboard is about to be shown on the screen.
226
+
227
+
228
+ #### Supported Platforms
229
+
230
+ - iOS
231
+
232
+ ## keyboardWillHide
233
+
234
+ This event is fired when the keyboard is fully closed.
235
+
236
+ window.addEventListener('keyboardWillHide', function () {
237
+ // Describe your logic which will be run each time when keyboard is about to be closed.
238
+ });
239
+
240
+ #### Description
241
+
242
+ Attach handler to this event to be able to receive notification when keyboard is about to be closed.
243
+
244
+
245
+ #### Supported Platforms
246
+
247
+ - iOS
248
+
249
+ ## keyboardHeightWillChange
250
+
251
+ This event is fired when the keyboard is fully closed.
252
+
253
+ window.addEventListener('keyboardHeightWillChange', function (event) {
254
+ // Describe your logic which will be run each time when keyboard is about to be closed.
255
+ console.log(event.keyboardHeight);
256
+ });
257
+
258
+ #### Description
259
+
260
+ Attach handler to this event to be able to receive notification when keyboard is about to be closed.
261
+
262
+
263
+ #### Supported Platforms
264
+
265
+ - iOS
266
+
267
+
268
+ # Releases
269
+
270
+ - 1.0.0
271
+ - Initial NPM release
272
+ - Fix issues with external keyboards
273
+ - Support keyboard events on window
274
+ - Fix issues with split and undocked keyboards
275
+ - Add keyboardHeightWillChange event
276
+ - Fix issues with StatusBarOverlaysWebview
277
+ - 1.1.0
278
+ - Add hide/show for Android
279
+ - Support original keyboard event mechanism
280
+ - 1.1.1
281
+ - Make compatible with cordova-android 3 and 4 (See [#2](/../../issues/2))
282
+ - Add hide for iOS
283
+ - 1.1.2
284
+ - Fix issues with hiding the accessory bar (See [#3](/../../issues/3))
285
+ - 1.1.3
286
+ - Support hiding the accessory bar when using WKWebView as the engine (See [here](https://github.com/Telerik-Verified-Plugins/WKWebView/issues/85))
287
+ - 1.1.4
288
+ - Fix page scrolling (See [#14](/../../issues/14))
289
+ - Prevent possible app store rejections (See [#21](/../../issues/21))
290
+ - 1.1.5
291
+ - Fix window.innerHeight when using WKWebView (See [#32](/../../issues/32))
292
+ - 1.2.0
293
+ - Return current values of shrinkView, disableScroll and hideFormAccessoryBar in a success callback
294
+ - Fix scroller resizing bug (See [#55](/../../issues/55))
295
+ - Fix iOS 11.1.1 WKWebView ShrinksView bug (See [#64](/../../issues/64))
296
+
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@zenkit-dev/cordova-plugin-keyboard",
3
+ "version": "1.2.0-dev.0",
4
+ "description": "Cordova Keyboard Plugin",
5
+ "cordova": {
6
+ "id": "cordova-plugin-keyboard",
7
+ "platforms": [
8
+ "ios"
9
+ ]
10
+ },
11
+ "repository": "https://github.com/zenkit/cordova-plugin-keyboard.git",
12
+ "keywords": [
13
+ "cordova",
14
+ "keyboard",
15
+ "ecosystem:cordova",
16
+ "cordova-ios",
17
+ "cordova-android"
18
+ ],
19
+ "author": "Apache Software Foundation",
20
+ "license": "Apache 2.0",
21
+ "bugs": {
22
+ "url": "https://github.com/cjpearson/cordova-plugin-keyboard/issues"
23
+ },
24
+ "homepage": "https://github.com/cjpearson/cordova-plugin-keyboard#readme"
25
+ }
package/plugin.xml ADDED
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
3
+ id="cordova-plugin-keyboard" version="1.2.0">
4
+ <name>Keyboard</name>
5
+ <description>Cordova Keyboard Plugin</description>
6
+ <license>Apache 2.0</license>
7
+ <keywords>cordova,keyboard</keywords>
8
+
9
+ <engines>
10
+ <engine name="cordova" version=">=4.0.0" />
11
+ </engines>
12
+
13
+ <js-module src="www/keyboard.js" name="keyboard">
14
+ <clobbers target="window.Keyboard" />
15
+ <clobbers target="cordova.plugins.Keyboard" />
16
+ </js-module>
17
+
18
+ <platform name="ios">
19
+ <config-file target="config.xml" parent="/*">
20
+ <feature name="Keyboard">
21
+ <param name="ios-package" value="CDVKeyboard" onload="true" />
22
+ </feature>
23
+ </config-file>
24
+
25
+ <header-file src="src/ios/CDVKeyboard.h" />
26
+ <source-file src="src/ios/CDVKeyboard.m" />
27
+ </platform>
28
+
29
+ <platform name="android">
30
+ <config-file target="config.xml" parent="/*">
31
+ <feature name="Keyboard">
32
+ <param name="android-package"
33
+ value="org.apache.cordova.labs.keyboard.KeyboardPlugin" />
34
+ <param name="onload" value="true" />
35
+ </feature>
36
+ </config-file>
37
+
38
+ <source-file src="src/android/KeyboardPlugin.java"
39
+ target-dir="src/org/apache/cordova/labs/keyboard" />
40
+ </platform>
41
+ </plugin>
@@ -0,0 +1,148 @@
1
+ package org.apache.cordova.labs.keyboard;
2
+
3
+ import android.content.Context;
4
+ import android.graphics.Point;
5
+ import android.graphics.Rect;
6
+ import android.os.Build;
7
+ import android.view.Display;
8
+ import android.view.View;
9
+ import android.view.ViewTreeObserver;
10
+ import android.view.ViewTreeObserver.OnGlobalLayoutListener;
11
+ import android.view.WindowManager;
12
+ import android.view.inputmethod.InputMethodManager;
13
+ import org.apache.cordova.*;
14
+ import org.json.JSONArray;
15
+
16
+ public class KeyboardPlugin extends CordovaPlugin {
17
+ private OnGlobalLayoutListener listener;
18
+ private boolean keyboardWasVisible = false;
19
+ private double KEYBOARD_MIN_HEIGHT_RATIO = 0.15;
20
+
21
+ private InputMethodManager getInputManager() {
22
+ return (InputMethodManager) cordova.getActivity().getSystemService(
23
+ Context.INPUT_METHOD_SERVICE);
24
+ }
25
+
26
+ private View getContentView() {
27
+ return cordova.getActivity().findViewById(android.R.id.content);
28
+ }
29
+
30
+ private ViewTreeObserver getRootViewTreeObserver() {
31
+ return getContentView().getRootView().getViewTreeObserver();
32
+ }
33
+ private ViewTreeObserver getWebViewTreeObserver() {
34
+ return webView.getView().getViewTreeObserver();
35
+ }
36
+
37
+ private void fireWindowEvent(String event) {
38
+ cordova.getActivity().runOnUiThread((Runnable) () -> {
39
+ String js = "cordova.fireWindowEvent('" + event + "');";
40
+ webView.getEngine().evaluateJavascript(js, null);
41
+ });
42
+ }
43
+ private void fireWindowEventAfterWebViewLayout(String event) {
44
+ getWebViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
45
+ @Override
46
+ public void onGlobalLayout() {
47
+ fireWindowEvent(event);
48
+ getWebViewTreeObserver().removeOnGlobalLayoutListener(this);
49
+ }
50
+ });
51
+ }
52
+
53
+ private int getScreenHeight(View root) {
54
+ if (Build.VERSION.SDK_INT < 21) {
55
+ return root.getRootView().getHeight();
56
+ }
57
+
58
+ Point size = new Point();
59
+ Display display = cordova.getActivity().getWindowManager().getDefaultDisplay();
60
+ display.getSize(size);
61
+ return size.y;
62
+ }
63
+
64
+ // NOTE: Determine if keyboard is visible
65
+ // (Implementation adapted from https://github.com/yshrsmz/KeyboardVisibilityEvent)
66
+ private boolean isKeyboardVisible() {
67
+ Rect r = new Rect();
68
+ View content = getContentView();
69
+ View root = content.getRootView();
70
+ root.getWindowVisibleDisplayFrame(r);
71
+
72
+ int[] location = new int[2];
73
+ content.getLocationOnScreen(location);
74
+
75
+ int screenHeight = getScreenHeight(root);
76
+ int heightDiff = screenHeight - r.height() - location[1];
77
+
78
+ return heightDiff > screenHeight * KEYBOARD_MIN_HEIGHT_RATIO;
79
+ }
80
+
81
+ private boolean isSoftInputAdjustNothing() {
82
+ int softInputMode = cordova.getActivity().getWindow().getAttributes().softInputMode;
83
+ int softInputAdjust = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
84
+ return (softInputAdjust & WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
85
+ == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
86
+ }
87
+
88
+ @Override
89
+ protected void pluginInitialize() {
90
+ super.pluginInitialize();
91
+
92
+ // The window will not be resized in case of SOFT_INPUT_ADJUST_NOTHING
93
+ if (isSoftInputAdjustNothing()) {
94
+ return;
95
+ }
96
+
97
+ listener = () -> {
98
+ boolean keyboardIsVisible = isKeyboardVisible();
99
+ if (keyboardWasVisible != keyboardIsVisible) {
100
+ if (keyboardIsVisible) {
101
+ fireWindowEvent("keyboardWillShow");
102
+ fireWindowEventAfterWebViewLayout("keyboardDidShow");
103
+ } else {
104
+ fireWindowEvent("keyboardWillHide");
105
+ fireWindowEventAfterWebViewLayout("keyboardDidHide");
106
+ }
107
+ }
108
+ keyboardWasVisible = keyboardIsVisible;
109
+ };
110
+
111
+ getRootViewTreeObserver().addOnGlobalLayoutListener(listener);
112
+ }
113
+
114
+ @Override
115
+ public void onDestroy() {
116
+ super.onDestroy();
117
+ if (listener != null) {
118
+ getRootViewTreeObserver().removeOnGlobalLayoutListener(listener);
119
+ }
120
+ }
121
+
122
+ @Override
123
+ public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
124
+ if ("show".equals(action)) {
125
+ cordova.getThreadPool().execute((Runnable) () -> {
126
+ getInputManager().toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
127
+ callbackContext.success();
128
+ });
129
+ return true;
130
+ }
131
+ if ("hide".equals(action)) {
132
+ cordova.getThreadPool().execute((Runnable) () -> {
133
+ View view = cordova.getActivity().getCurrentFocus();
134
+
135
+ if (view == null) {
136
+ callbackContext.error("No current focus");
137
+ return;
138
+ }
139
+
140
+ getInputManager().hideSoftInputFromWindow(
141
+ view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
142
+ callbackContext.success();
143
+ });
144
+ return true;
145
+ }
146
+ return false;
147
+ }
148
+ }
@@ -0,0 +1,5 @@
1
+ #import <Cordova/CDVPlugin.h>
2
+
3
+ @interface CDVKeyboard : CDVPlugin
4
+
5
+ @end
@@ -0,0 +1,337 @@
1
+ #import "CDVKeyboard.h"
2
+ #import <Cordova/CDVAvailability.h>
3
+ #import <Cordova/NSDictionary+CordovaPreferences.h>
4
+ #import <objc/runtime.h>
5
+
6
+ @interface CDVKeyboard () <UIScrollViewDelegate>
7
+
8
+ @property(nonatomic, readwrite, assign) BOOL keyboardIsVisible;
9
+ @property(readwrite, assign, nonatomic) BOOL keyboardShrinksView;
10
+ @property(readwrite, assign, nonatomic) BOOL hideFormAccessoryBar;
11
+ @property(readwrite, assign, nonatomic) BOOL keyboardDisablesScrolling;
12
+ @property(readwrite, assign, nonatomic) UIKeyboardAppearance keyboardAppearance;
13
+
14
+ @end
15
+
16
+ @implementation CDVKeyboard
17
+
18
+ #pragma mark CordovaHelper
19
+ - (void)fireWindowEvent:(NSString *)event {
20
+ NSString *js = [NSString stringWithFormat:@"cordova.fireWindowEvent('%@')", event];
21
+ // Don't schedule the js in the run loop so the the window event handler can handle the events
22
+ // as soon as possible.
23
+ [self.commandDelegate evalJs:js scheduledOnRunLoop:false];
24
+ }
25
+
26
+ #pragma mark Initialize
27
+
28
+ NSString *WKClassString;
29
+ NSString *UITraitsClassString;
30
+
31
+ - (void)pluginInitialize {
32
+ WKClassString = @"WKContentView";
33
+ UITraitsClassString = @"UITextInputTraits";
34
+
35
+ NSDictionary *settings = self.commandDelegate.settings;
36
+
37
+ self.keyboardShrinksView = [settings cordovaBoolSettingForKey:@"KeyboardShrinksView"
38
+ defaultValue:YES];
39
+
40
+ Boolean hide = [settings cordovaBoolSettingForKey:@"HideKeyboardFormAccessoryBar"
41
+ defaultValue:YES];
42
+ [self setHideFormAccessoryBar:hide];
43
+
44
+ Boolean disabled = [settings cordovaBoolSettingForKey:@"KeyboardDisablesScrolling"
45
+ defaultValue:YES];
46
+ [self setKeyboardDisablesScrolling:disabled];
47
+
48
+ NSString *keyboardStyle = [settings cordovaSettingForKey:@"KeyboardStyle"];
49
+
50
+ if (keyboardStyle) {
51
+ [self setKeyboardAppearanceForStyle:keyboardStyle];
52
+ }
53
+
54
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
55
+
56
+ [nc addObserver:self
57
+ selector:@selector(onKeyboardWillHide:)
58
+ name:UIKeyboardWillHideNotification
59
+ object:nil];
60
+ [nc addObserver:self
61
+ selector:@selector(onKeyboardDidHide:)
62
+ name:UIKeyboardDidHideNotification
63
+ object:nil];
64
+ [nc addObserver:self
65
+ selector:@selector(onKeyboardWillShow:)
66
+ name:UIKeyboardWillShowNotification
67
+ object:nil];
68
+ [nc addObserver:self
69
+ selector:@selector(onKeyboardDidShow:)
70
+ name:UIKeyboardDidShowNotification
71
+ object:nil];
72
+ [nc addObserver:self
73
+ selector:@selector(onKeyboardWillChangeFrame:)
74
+ name:UIKeyboardWillChangeFrameNotification
75
+ object:nil];
76
+
77
+ // Prevent WKWebView to resize window
78
+ [nc removeObserver:self.webView name:UIKeyboardWillHideNotification object:nil];
79
+ [nc removeObserver:self.webView name:UIKeyboardWillShowNotification object:nil];
80
+ [nc removeObserver:self.webView name:UIKeyboardWillChangeFrameNotification object:nil];
81
+ [nc removeObserver:self.webView name:UIKeyboardDidChangeFrameNotification object:nil];
82
+ }
83
+
84
+ #pragma mark KeyboardEvents
85
+
86
+ - (void)onKeyboardWillShow:(NSNotification *)notification {
87
+ [self fireWindowEvent:@"keyboardWillShow"];
88
+ self.keyboardIsVisible = YES;
89
+ }
90
+ - (void)onKeyboardDidShow:(NSNotification *)notification {
91
+ [self fireWindowEvent:@"keyboardDidShow"];
92
+ }
93
+ - (void)onKeyboardWillHide:(NSNotification *)notification {
94
+ [self fireWindowEvent:@"keyboardWillHide"];
95
+ self.keyboardIsVisible = NO;
96
+ }
97
+ - (void)onKeyboardDidHide:(NSNotification *)notification {
98
+ [self fireWindowEvent:@"keyboardDidHide"];
99
+ }
100
+ - (void)onKeyboardWillChangeFrame:(NSNotification *)notification {
101
+ // If the view is not visible, we should do nothing. E.g. if the inappbrowser
102
+ // is open.
103
+ if (!(self.viewController.isViewLoaded && self.viewController.view.window)) {
104
+ return;
105
+ }
106
+
107
+ // Note: we check for _keyboardShrinksView at this point instead of the
108
+ // beginning of the method to handle the case where the user disabled
109
+ // shrinkView while the keyboard is showing.
110
+ if (!_keyboardShrinksView) {
111
+ return;
112
+ }
113
+
114
+ // Delay the actual resizing so the will show/hide events fire first.
115
+ [self performSelector:@selector(resizeView:) withObject:notification afterDelay:0];
116
+ }
117
+
118
+ #pragma mark KeyboardAppearance
119
+
120
+ - (void)setKeyboardAppearance:(UIKeyboardAppearance)keyboardAppearance {
121
+ if (keyboardAppearance == _keyboardAppearance) {
122
+ return;
123
+ }
124
+
125
+ IMP appearanceImpl = imp_implementationWithBlock(^(id _s) {
126
+ return keyboardAppearance;
127
+ });
128
+
129
+ for (NSString *classString in @[ WKClassString, UITraitsClassString ]) {
130
+ Class class = NSClassFromString(classString);
131
+ SEL selector = @selector(keyboardAppearance);
132
+ Method method = class_getInstanceMethod(class, selector);
133
+
134
+ if (method != NULL) {
135
+ method_setImplementation(method, appearanceImpl);
136
+ } else {
137
+ class_addMethod(class, selector, appearanceImpl, "l@:");
138
+ }
139
+ }
140
+
141
+ _keyboardAppearance = keyboardAppearance;
142
+ }
143
+
144
+ - (void)setKeyboardAppearanceForStyle:(NSString *)style {
145
+ UIKeyboardAppearance appearance = UIKeyboardAppearanceLight;
146
+ if ([[style lowercaseString] isEqualToString:@"dark"]) {
147
+ appearance = UIKeyboardAppearanceDark;
148
+ }
149
+ [self setKeyboardAppearance:appearance];
150
+ }
151
+
152
+ #pragma mark HideFormAccessoryBar
153
+
154
+ static IMP WKOriginalImp;
155
+
156
+ - (void)setHideFormAccessoryBar:(BOOL)hideFormAccessoryBar {
157
+ if (hideFormAccessoryBar == _hideFormAccessoryBar) {
158
+ return;
159
+ }
160
+
161
+ Method WKMethod =
162
+ class_getInstanceMethod(NSClassFromString(WKClassString), @selector(inputAccessoryView));
163
+
164
+ if (hideFormAccessoryBar) {
165
+ WKOriginalImp = method_getImplementation(WKMethod);
166
+
167
+ IMP hideFormAccessoryBarImpl = imp_implementationWithBlock(^(id _s) {
168
+ return nil;
169
+ });
170
+
171
+ method_setImplementation(WKMethod, hideFormAccessoryBarImpl);
172
+ } else {
173
+ method_setImplementation(WKMethod, WKOriginalImp);
174
+ }
175
+
176
+ _hideFormAccessoryBar = hideFormAccessoryBar;
177
+ }
178
+
179
+ #pragma mark KeyboardShrinksView
180
+
181
+ - (CGFloat)calculateFrameHeight:(NSNotification *)notification {
182
+ UIScreen *screen = self.webView.window.screen;
183
+ CGFloat superviewFrameHeight = self.webView.superview.frame.size.height;
184
+ CGRect keyboardEndFrame =
185
+ [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
186
+
187
+ // NOTE: Detect if the keyboard is attached or floating.
188
+ // If the keyboard is floating it's frame should not match the screen bounds.
189
+ BOOL keyboardAttached = screen.bounds.origin.x == keyboardEndFrame.origin.x &&
190
+ screen.bounds.size.width == keyboardEndFrame.size.width;
191
+
192
+ // NOTE: If the keyboard is floating (not attached) we reset the view height.
193
+ if (keyboardAttached == NO) {
194
+ return superviewFrameHeight;
195
+ }
196
+
197
+ CGPoint keyboardOrigin = [self.webView convertPoint:keyboardEndFrame.origin toView:nil];
198
+ CGPoint relativeFrameOrigin = [self.webView convertPoint:self.webView.frame.origin
199
+ toCoordinateSpace:screen.coordinateSpace];
200
+
201
+ // NOTE: We set the web view height to the y position of keyboard,
202
+ // this should prevent an error in the calculation beeing carried over.
203
+ // (e.g. the view could already be changed because we call this with a delay)
204
+ // But we need to calculate the y position relative to the view position on the screem.
205
+ // (e.g. to account for the statusbar or the "Slide Over" multitask mode on iPads)
206
+ CGFloat relativeKeyboardY = keyboardOrigin.y - relativeFrameOrigin.y;
207
+
208
+ // NOTE: We don't allow the frame height to be smaller than 0 or bigger than the superview.
209
+ // If this happened we porbably calculated something wrong,
210
+ // in that case it is porbably better to reset the height.
211
+ if (relativeKeyboardY <= 0 || relativeKeyboardY > superviewFrameHeight) {
212
+ return superviewFrameHeight;
213
+ }
214
+ return relativeKeyboardY;
215
+ }
216
+
217
+ - (void)resizeView:(NSNotification *)notification {
218
+ CGRect frame = self.webView.frame;
219
+ CGFloat frameHeight = [self calculateFrameHeight:notification];
220
+ if (frame.size.height == frameHeight) {
221
+ return;
222
+ }
223
+
224
+ double duration =
225
+ [[notification.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
226
+ UIViewAnimationCurve curve =
227
+ [[notification.userInfo valueForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
228
+
229
+ [UIView beginAnimations:nil context:nil];
230
+ [UIView setAnimationDuration:duration];
231
+ [UIView setAnimationCurve:curve];
232
+ frame.size.height = frameHeight;
233
+ self.webView.frame = frame;
234
+ [UIView commitAnimations];
235
+ }
236
+
237
+ #pragma mark KeyboardDisablesScrolling
238
+ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
239
+ [scrollView setContentOffset:CGPointZero];
240
+ }
241
+
242
+ - (void)setKeyboardDisablesScrolling:(BOOL)keyboardDisablesScrolling {
243
+ if (keyboardDisablesScrolling == _keyboardDisablesScrolling) {
244
+ return;
245
+ }
246
+
247
+ if (keyboardDisablesScrolling) {
248
+ self.webView.scrollView.scrollEnabled = NO;
249
+ self.webView.scrollView.delegate = self;
250
+ } else {
251
+ self.webView.scrollView.scrollEnabled = YES;
252
+ self.webView.scrollView.delegate = nil;
253
+ }
254
+
255
+ _keyboardDisablesScrolling = keyboardDisablesScrolling;
256
+ }
257
+
258
+ #pragma mark Plugin Interface
259
+
260
+ - (void)keyboardShrinksView:(CDVInvokedUrlCommand *)command {
261
+ if (command.arguments.count > 0) {
262
+ id value = [command.arguments objectAtIndex:0];
263
+ if (!([value isKindOfClass:[NSNumber class]])) {
264
+ value = [NSNumber numberWithBool:NO];
265
+ }
266
+
267
+ self.keyboardShrinksView = [value boolValue];
268
+ }
269
+
270
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
271
+ messageAsBool:self.keyboardShrinksView];
272
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
273
+ }
274
+
275
+ - (void)keyboardDisablesScrolling:(CDVInvokedUrlCommand *)command {
276
+ Boolean disabled = self.keyboardDisablesScrolling;
277
+ if (command.arguments.count > 0) {
278
+ id value = [command.arguments objectAtIndex:0];
279
+ if (!([value isKindOfClass:[NSNumber class]])) {
280
+ value = [NSNumber numberWithBool:NO];
281
+ }
282
+
283
+ disabled = [value boolValue];
284
+ }
285
+
286
+ [self setKeyboardDisablesScrolling:disabled];
287
+
288
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
289
+ messageAsBool:self.keyboardDisablesScrolling];
290
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
291
+ }
292
+
293
+ - (void)hideFormAccessoryBar:(CDVInvokedUrlCommand *)command {
294
+ Boolean hide = self.hideFormAccessoryBar;
295
+ if (command.arguments.count > 0) {
296
+ id value = [command.arguments objectAtIndex:0];
297
+ if (!([value isKindOfClass:[NSNumber class]])) {
298
+ value = [NSNumber numberWithBool:NO];
299
+ }
300
+
301
+ hide = [value boolValue];
302
+ }
303
+
304
+ [self setHideFormAccessoryBar:hide];
305
+
306
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
307
+ messageAsBool:self.hideFormAccessoryBar];
308
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
309
+ }
310
+
311
+ - (void)hide:(CDVInvokedUrlCommand *)command {
312
+ [self.webView endEditing:YES];
313
+
314
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
315
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
316
+ }
317
+
318
+ - (void)setKeyboardStyle:(CDVInvokedUrlCommand *)command {
319
+ NSString *style = @"light";
320
+ id value = [command.arguments objectAtIndex:0];
321
+ if ([value isKindOfClass:[NSString class]]) {
322
+ style = (NSString *)value;
323
+ }
324
+
325
+ [self setKeyboardAppearanceForStyle:style];
326
+
327
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
328
+ [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
329
+ }
330
+
331
+ #pragma mark dealloc
332
+
333
+ - (void)dealloc {
334
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
335
+ }
336
+
337
+ @end
@@ -0,0 +1,45 @@
1
+ var cordova = require('cordova');
2
+ var exec = require('cordova/exec');
3
+
4
+ var isNil = function (value) {
5
+ return value === undefined || value === null;
6
+ };
7
+
8
+ var Keyboard = { isVisible: false };
9
+
10
+ window.addEventListener('keyboardDidShow', function () {
11
+ Keyboard.isVisible = true;
12
+ });
13
+
14
+ window.addEventListener('keyboardDidHide', function () {
15
+ Keyboard.isVisible = false;
16
+ });
17
+
18
+ Keyboard.keyboardShrinksView = function (shrink, success, failure) {
19
+ var args = isNil(shrink) ? [] : [shrink];
20
+ exec(success, failure, 'Keyboard', 'keyboardShrinksView', args);
21
+ };
22
+
23
+ Keyboard.hideFormAccessoryBar = function (hide, success, failure) {
24
+ var args = isNil(hide) ? [] : [hide];
25
+ exec(success, failure, 'Keyboard', 'hideFormAccessoryBar', args);
26
+ };
27
+
28
+ Keyboard.keyboardDisablesScrolling = function (disable, success, failure) {
29
+ var args = isNil(disable) ? [] : [disable];
30
+ exec(success, failure, 'Keyboard', 'keyboardDisablesScrolling', args);
31
+ };
32
+
33
+ Keyboard.show = function (success, failure) {
34
+ exec(success, failure, 'Keyboard', 'show', []);
35
+ };
36
+
37
+ Keyboard.hide = function (success, failure) {
38
+ exec(success, failure, 'Keyboard', 'hide', []);
39
+ };
40
+
41
+ Keyboard.setKeyboardStyle = function (style) {
42
+ exec(null, null, 'Keyboard', 'setKeyboardStyle', [style]);
43
+ };
44
+
45
+ module.exports = Keyboard;