Browse Source

Merge branch 'master' into progress

Rafal Wachol 7 years ago
parent
commit
54facef2f0

+ 1 - 0
README.md

@@ -143,6 +143,7 @@ Future<Null> launch(String url,
          String userAgent: null,
          bool withZoom: false,
          bool withLocalStorage: true,
+         bool withLocalUrl: true,
          bool scrollBar: true});
 ```
 ```dart

+ 2 - 3
android/build.gradle

@@ -8,7 +8,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.1.2'
+        classpath 'com.android.tools.build:gradle:3.2.1'
     }
 }
 
@@ -21,8 +21,7 @@ allprojects {
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 25
-    buildToolsVersion '27.0.3'
+    compileSdkVersion 27
 
     defaultConfig {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

+ 3 - 5
example/android/app/build.gradle

@@ -16,7 +16,6 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 
 android {
     compileSdkVersion 27
-    buildToolsVersion '27.0.3'
 
     lintOptions {
         disable 'InvalidPackage'
@@ -24,7 +23,6 @@ android {
 
     defaultConfig {
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-        
         // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
         applicationId "com.yourcompany.flutter_webview_plugin_example"
     }
@@ -43,7 +41,7 @@ flutter {
 }
 
 dependencies {
-    androidTestCompile 'com.android.support:support-annotations:25.0.0'
-    androidTestCompile 'com.android.support.test:runner:0.5'
-    androidTestCompile 'com.android.support.test:rules:0.5'
+    androidTestImplementation 'com.android.support:support-annotations:27.0.0'
+    androidTestImplementation 'com.android.support.test:runner:1.0.2'
+    androidTestImplementation 'com.android.support.test:rules:1.0.2'
 }

+ 0 - 2
example/android/app/src/main/AndroidManifest.xml

@@ -3,8 +3,6 @@
     android:versionCode="1"
     android:versionName="0.0.1">
 
-    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" />
-
     <!-- The INTERNET permission is required for development. Specifically,
          flutter needs it to communicate with the running application
          to allow setting breakpoints, to provide hot reload, etc.

+ 1 - 1
example/android/build.gradle

@@ -8,7 +8,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.1.1'
+        classpath 'com.android.tools.build:gradle:3.2.1'
     }
 }
 

+ 92 - 68
example/lib/main.dart

@@ -14,6 +14,8 @@ void main() {
 }
 
 class MyApp extends StatelessWidget {
+  final flutterWebviewPlugin = new FlutterWebviewPlugin();
+
   @override
   Widget build(BuildContext context) {
     return new MaterialApp(
@@ -37,6 +39,29 @@ class MyApp extends StatelessWidget {
                   child: Text('Waiting.....'),
                 ),
               ),
+              bottomNavigationBar: BottomAppBar(
+                  child: Row(
+                children: <Widget>[
+                  IconButton(
+                    icon: const Icon(Icons.arrow_back_ios),
+                    onPressed: () {
+                      flutterWebviewPlugin.goBack();
+                    },
+                  ),
+                  IconButton(
+                    icon: const Icon(Icons.arrow_forward_ios),
+                    onPressed: () {
+                      flutterWebviewPlugin.goForward();
+                    },
+                  ),
+                  IconButton(
+                    icon: const Icon(Icons.autorenew),
+                    onPressed: () {
+                      flutterWebviewPlugin.reload();
+                    },
+                  ),
+                ],
+              )),
             )
       },
     );
@@ -168,77 +193,76 @@ class _MyHomePageState extends State<MyHomePage> {
       appBar: new AppBar(
         title: const Text('Plugin example app'),
       ),
-      body: new Column(
-        mainAxisAlignment: MainAxisAlignment.center,
-        children: [
-          new Container(
-            padding: const EdgeInsets.all(24.0),
-            child: new TextField(controller: _urlCtrl),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.launch(selectedUrl,
-                  rect: new Rect.fromLTWH(
-                      0.0, 0.0, MediaQuery.of(context).size.width, 300.0),
-                  userAgent: kAndroidUserAgent);
-            },
-            child: const Text('Open Webview (rect)'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.launch(selectedUrl, hidden: true);
-            },
-            child: const Text('Open "hidden" Webview'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.launch(selectedUrl);
-            },
-            child: const Text('Open Fullscreen Webview'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              Navigator.of(context).pushNamed('/widget');
-            },
-            child: const Text('Open widget webview'),
-          ),
-          new Container(
-            padding: const EdgeInsets.all(24.0),
-            child: new TextField(controller: _codeCtrl),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              final future =
-                  flutterWebviewPlugin.evalJavascript(_codeCtrl.text);
-              future.then((String result) {
-                setState(() {
-                  _history.add('eval: $result');
+      body: SingleChildScrollView(
+        child: new Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            new Container(
+              padding: const EdgeInsets.all(24.0),
+              child: new TextField(controller: _urlCtrl),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.launch(selectedUrl,
+                    rect: new Rect.fromLTWH(0.0, 0.0, MediaQuery.of(context).size.width, 300.0), userAgent: kAndroidUserAgent);
+              },
+              child: const Text('Open Webview (rect)'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.launch(selectedUrl, hidden: true);
+              },
+              child: const Text('Open "hidden" Webview'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.launch(selectedUrl);
+              },
+              child: const Text('Open Fullscreen Webview'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                Navigator.of(context).pushNamed('/widget');
+              },
+              child: const Text('Open widget webview'),
+            ),
+            new Container(
+              padding: const EdgeInsets.all(24.0),
+              child: new TextField(controller: _codeCtrl),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                final future = flutterWebviewPlugin.evalJavascript(_codeCtrl.text);
+                future.then((String result) {
+                  setState(() {
+                    _history.add('eval: $result');
+                  });
                 });
-              });
-            },
-            child: const Text('Eval some javascript'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              setState(() {
-                _history.clear();
-              });
-              flutterWebviewPlugin.close();
-            },
-            child: const Text('Close'),
-          ),
-          new RaisedButton(
-            onPressed: () {
-              flutterWebviewPlugin.getCookies().then((m) {
+              },
+              child: const Text('Eval some javascript'),
+            ),
+            new RaisedButton(
+              onPressed: () {
                 setState(() {
-                  _history.add('cookies: $m');
+                  _history.clear();
+                });
+                flutterWebviewPlugin.close();
+              },
+              child: const Text('Close'),
+            ),
+            new RaisedButton(
+              onPressed: () {
+                flutterWebviewPlugin.getCookies().then((m) {
+                  setState(() {
+                    _history.add('cookies: $m');
+                  });
                 });
-              });
-            },
-            child: const Text('Cookies'),
-          ),
-          new Text(_history.join('\n'))
-        ],
+              },
+              child: const Text('Cookies'),
+            ),
+            new Text(_history.join('\n'))
+          ],
+        ),
       ),
     );
   }

+ 25 - 1
ios/Classes/FlutterWebviewPlugin.m

@@ -15,7 +15,7 @@ static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";
                methodChannelWithName:CHANNEL_NAME
                binaryMessenger:[registrar messenger]];
     
-    UIViewController *viewController = (UIViewController *)registrar.messenger;
+    UIViewController *viewController = [UIApplication sharedApplication].delegate.window.rootViewController;
     FlutterWebviewPlugin* instance = [[FlutterWebviewPlugin alloc] initWithViewController:viewController];
     
     [registrar addMethodCallDelegate:instance channel:channel];
@@ -58,6 +58,15 @@ static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";
     } else if ([@"stopLoading" isEqualToString:call.method]) {
         [self stopLoading];
         result(nil);
+    } else if ([@"back" isEqualToString:call.method]) {
+        [self back];
+        result(nil);
+    } else if ([@"forward" isEqualToString:call.method]) {
+        [self forward];
+        result(nil);
+    } else if ([@"reload" isEqualToString:call.method]) {
+        [self reload];
+        result(nil);
     } else {
         result(FlutterMethodNotImplemented);
     }
@@ -204,6 +213,21 @@ static NSString *const CHANNEL_NAME = @"flutter_webview_plugin";
         [self.webview stopLoading];
     }
 }
+- (void)back {
+    if (self.webview != nil) {
+        [self.webview goBack];
+    }
+}
+- (void)forward {
+    if (self.webview != nil) {
+        [self.webview goForward];
+    }
+}
+- (void)reload {
+    if (self.webview != nil) {
+        [self.webview reload];
+    }
+}
 
 #pragma mark -- WkWebView Delegate
 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction

+ 0 - 3
lib/src/base.dart

@@ -148,15 +148,12 @@ class FlutterWebviewPlugin {
   Future close() => _channel.invokeMethod('close');
 
   /// Reloads the WebView.
-  /// This is only available on Android for now.
   Future reload() => _channel.invokeMethod('reload');
 
   /// Navigates back on the Webview.
-  /// This is only available on Android for now.
   Future goBack() => _channel.invokeMethod('back');
 
   /// Navigates forward on the Webview.
-  /// This is only available on Android for now.
   Future goForward() => _channel.invokeMethod('forward');
 
   // Hides the webview

+ 86 - 49
lib/src/webview_scaffold.dart

@@ -2,6 +2,7 @@ import 'dart:async';
 
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
 
 import 'base.dart';
 
@@ -73,6 +74,7 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
   @override
   void dispose() {
     super.dispose();
+    _resizeTimer?.cancel();
     webviewReference.close();
     if (widget.hidden) {
       _onStateChanged.cancel();
@@ -82,64 +84,99 @@ class _WebviewScaffoldState extends State<WebviewScaffold> {
 
   @override
   Widget build(BuildContext context) {
-    if (_rect == null) {
-      _rect = _buildRect(context);
-      webviewReference.launch(widget.url,
-          headers: widget.headers,
-          withJavascript: widget.withJavascript,
-          clearCache: widget.clearCache,
-          clearCookies: widget.clearCookies,
-          enableAppScheme: widget.enableAppScheme,
-          userAgent: widget.userAgent,
-          rect: _rect,
-          withZoom: widget.withZoom,
-          withLocalStorage: widget.withLocalStorage,
-          withLocalUrl: widget.withLocalUrl,
-          scrollBar: widget.scrollBar,
-          hidden: widget.hidden);
-    } else {
-      final rect = _buildRect(context);
-      if (_rect != rect) {
-        _rect = rect;
-        _resizeTimer?.cancel();
-        _resizeTimer = new Timer(new Duration(milliseconds: 300), () {
-          // avoid resizing to fast when build is called multiple time
-          webviewReference.resize(_rect);
-        });
-      }
-    }
-    return new Scaffold(
-        appBar: widget.appBar,
-        persistentFooterButtons: widget.persistentFooterButtons,
-        bottomNavigationBar: widget.bottomNavigationBar,
-        body: widget.initialChild ?? const Center(child: const CircularProgressIndicator()));
+    return Scaffold(
+      appBar: widget.appBar,
+      persistentFooterButtons: widget.persistentFooterButtons,
+      bottomNavigationBar: widget.bottomNavigationBar,
+      body: _WebviewPlaceholder(
+        onRectChanged: (Rect value) {
+          if (_rect == null) {
+            _rect = value;
+            webviewReference.launch(
+              widget.url,
+              headers: widget.headers,
+              withJavascript: widget.withJavascript,
+              clearCache: widget.clearCache,
+              clearCookies: widget.clearCookies,
+              enableAppScheme: widget.enableAppScheme,
+              userAgent: widget.userAgent,
+              rect: _rect,
+              withZoom: widget.withZoom,
+              withLocalStorage: widget.withLocalStorage,
+              withLocalUrl: widget.withLocalUrl,
+              scrollBar: widget.scrollBar,
+            );
+          } else {
+            if (_rect != value) {
+              _rect = value;
+              _resizeTimer?.cancel();
+              _resizeTimer = Timer(const Duration(milliseconds: 250), () {
+                // avoid resizing to fast when build is called multiple time
+                webviewReference.resize(_rect);
+              });
+            }
+          }
+        },
+        child: widget.initialChild ?? const Center(child: const CircularProgressIndicator()),
+      ),
+    );
+  }
+}
+
+class _WebviewPlaceholder extends SingleChildRenderObjectWidget {
+  const _WebviewPlaceholder({
+    Key key,
+    @required this.onRectChanged,
+    Widget child,
+  }) : super(key: key, child: child);
+  
+  final ValueChanged<Rect> onRectChanged;
+
+  @override
+  RenderObject createRenderObject(BuildContext context) {
+    return _WebviewPlaceholderRender(
+      onRectChanged: onRectChanged,
+    );
+  }
+  
+  @override
+  void updateRenderObject(BuildContext context, _WebviewPlaceholderRender renderObject) {
+    renderObject..onRectChanged = onRectChanged;
   }
+}
 
-  Rect _buildRect(BuildContext context) {
-    final fullscreen = widget.appBar == null;
+class _WebviewPlaceholderRender extends RenderProxyBox {
+  ValueChanged<Rect> _callback;
+  Rect _rect;
 
-    final mediaQuery = MediaQuery.of(context);
-    final topPadding = widget.primary ? mediaQuery.padding.top : 0.0;
-    final top = fullscreen ? 0.0 : widget.appBar.preferredSize.height + topPadding;
+  _WebviewPlaceholderRender({
+    RenderBox child,
+    ValueChanged<Rect> onRectChanged,
+  })  : _callback = onRectChanged,
+        super(child);
 
-    var height = mediaQuery.size.height - top;
+  Rect get rect => _rect;
 
-    if (widget.bottomNavigationBar != null) {
-      height -= 56.0 +
-          mediaQuery.padding.bottom; // todo(lejard_h) find a way to determine bottomNavigationBar programmatically
+  set onRectChanged(ValueChanged<Rect> callback) {
+    if (callback != _callback) {
+      _callback = callback;
+      notifyRect();
     }
+  }
 
-    if (widget.persistentFooterButtons != null) {
-      height -= 53.0; // todo(lejard_h) find a way to determine persistentFooterButtons programmatically
-      if (widget.bottomNavigationBar == null) {
-        height -= mediaQuery.padding.bottom;
-      }
+  void notifyRect() {
+    if (_callback != null && _rect != null) {
+      _callback(_rect);
     }
+  }
 
-    if (height < 0.0) {
-      height = 0.0;
+  @override
+  void paint(PaintingContext context, Offset offset) {
+    super.paint(context, offset);
+    final rect = offset & size;
+    if (_rect != rect) {
+      _rect = rect;
+      notifyRect();
     }
-
-    return new Rect.fromLTWH(0.0, top, mediaQuery.size.width, height);
   }
 }

+ 1 - 0
pubspec.yaml

@@ -6,6 +6,7 @@ authors:
 - Pedia <kpedia@163.com>
 homepage: https://github.com/dart-flitter/flutter_webview_plugin
 version: 0.2.1+2
+maintainer: Simon Lightfoot (@slightfoot)
 
 environment:
   sdk: ">=2.0.0-dev <3.0.0"