From 8acdb0c82f2e05cadd695d7a5fad2a4b28b9509c Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 15:26:28 +0530 Subject: [PATCH 01/35] migrate to package:web --- .../image_picker_for_web/CHANGELOG.md | 5 +- .../image_picker_for_web_test.dart | 102 ++++++++++-------- .../integration_test/image_resizer_test.dart | 41 +++---- .../image_picker_for_web/example/pubspec.yaml | 5 +- .../lib/image_picker_for_web.dart | 80 +++++++------- .../lib/src/image_resizer.dart | 59 +++++----- .../image_picker_for_web/pubspec.yaml | 7 +- 7 files changed, 165 insertions(+), 134 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index 6b01e90c0e0..edc6b47fdb2 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 3.0.2 -* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. +* Migrates package and tests to `platform:web`. +* Updates minimum supported SDK version to Flutter 3.16.0/Dart 3.2.0. ## 3.0.1 diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 5a3af7eab57..13c631369d5 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -3,25 +3,26 @@ // found in the LICENSE file. import 'dart:convert'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/image_picker_for_web.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); -final Map options = { - 'type': 'text/plain', - 'lastModified': DateTime.utc(2017, 12, 13).millisecondsSinceEpoch, -}; -final html.File textFile = html.File([bytes], 'hello.txt', options); -final html.File secondTextFile = - html.File([otherBytes], 'secondFile.txt'); +final web.FilePropertyBag options = web.FilePropertyBag( + lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch +)..type = 'text/plain'; + +final web.File textFile = web.File(bytes.toJS as JSArray, 'hello.txt', options); +final web.File secondTextFile = + web.File(otherBytes.toJS as JSArray, 'secondFile.txt'); void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -36,12 +37,13 @@ void main() { testWidgets('getImageFromSource can select a file', ( WidgetTester _, ) async { - final html.FileUploadInputElement mockInput = html.FileUploadInputElement(); - + final web.HTMLInputElement mockInput = (web.document.createElement('input') + as web.HTMLInputElement) + ..type = 'file'; final ImagePickerPluginTestOverrides overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) - ..getMultipleFilesFromInput = ((_) => [textFile]); + ..getMultipleFilesFromInput = ((_) => [textFile]); final ImagePickerPlugin plugin = ImagePickerPlugin(overrides: overrides); @@ -51,7 +53,7 @@ void main() { ); // Mock the browser behavior of selecting a file... - mockInput.dispatchEvent(html.Event('change')); + mockInput.dispatchEvent(web.Event('change')); // Now the file should be available expect(image, completes); @@ -66,20 +68,22 @@ void main() { expect( file.lastModified(), completion( - DateTime.fromMillisecondsSinceEpoch(textFile.lastModified!), + DateTime.fromMillisecondsSinceEpoch(textFile.lastModified), )); }); testWidgets('getMultiImageWithOptions can select multiple files', ( WidgetTester _, ) async { - final html.FileUploadInputElement mockInput = html.FileUploadInputElement(); + final web.HTMLInputElement mockInput = (web.document.createElement('input') + as web.HTMLInputElement) + ..type = 'file'; final ImagePickerPluginTestOverrides overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) ..getMultipleFilesFromInput = - ((_) => [textFile, secondTextFile]); + ((_) => [textFile, secondTextFile]); final ImagePickerPlugin plugin = ImagePickerPlugin(overrides: overrides); @@ -87,7 +91,7 @@ void main() { final Future> files = plugin.getMultiImageWithOptions(); // Mock the browser behavior of selecting a file... - mockInput.dispatchEvent(html.Event('change')); + mockInput.dispatchEvent(web.Event('change')); // Now the file should be available expect(files, completes); @@ -103,13 +107,15 @@ void main() { }); testWidgets('getMedia can select multiple files', (WidgetTester _) async { - final html.FileUploadInputElement mockInput = html.FileUploadInputElement(); + final web.HTMLInputElement mockInput = (web.document.createElement('input') + as web.HTMLInputElement) + ..type = 'file'; final ImagePickerPluginTestOverrides overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) ..getMultipleFilesFromInput = - ((_) => [textFile, secondTextFile]); + ((_) => [textFile, secondTextFile]); final ImagePickerPlugin plugin = ImagePickerPlugin(overrides: overrides); @@ -118,7 +124,7 @@ void main() { plugin.getMedia(options: const MediaOptions(allowMultiple: true)); // Mock the browser behavior of selecting a file... - mockInput.dispatchEvent(html.Event('change')); + mockInput.dispatchEvent(web.Event('change')); // Now the file should be available expect(files, completes); @@ -134,20 +140,22 @@ void main() { }); group('cancel event', () { - late html.FileUploadInputElement mockInput; + late web.HTMLInputElement mockInput; late ImagePickerPluginTestOverrides overrides; late ImagePickerPlugin plugin; setUp(() { - mockInput = html.FileUploadInputElement(); + mockInput = (web.document.createElement('input') + as web.HTMLInputElement) + ..type = 'file'; overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) - ..getMultipleFilesFromInput = ((_) => [textFile]); + ..getMultipleFilesFromInput = ((_) => [textFile]); plugin = ImagePickerPlugin(overrides: overrides); }); void mockCancel() { - mockInput.dispatchEvent(html.Event('cancel')); + mockInput.dispatchEvent(web.Event('cancel')); } testWidgets('getFiles - returns empty list', (WidgetTester _) async { @@ -221,61 +229,63 @@ void main() { group('createInputElement', () { testWidgets('accept: any, capture: null', (WidgetTester tester) async { - final html.Element input = plugin.createInputElement('any', null); + final web.Element input = plugin.createInputElement('any', null); - expect(input.attributes, containsPair('accept', 'any')); - expect(input.attributes, isNot(contains('capture'))); - expect(input.attributes, isNot(contains('multiple'))); + expect(input.getAttribute('accept'), 'any'); + expect(input.hasAttribute('capture'), false); + expect(input.hasAttribute('multiple'), false); }); testWidgets('accept: any, capture: something', (WidgetTester tester) async { - final html.Element input = plugin.createInputElement('any', 'something'); + final web.Element input = plugin.createInputElement('any', 'something'); - expect(input.attributes, containsPair('accept', 'any')); - expect(input.attributes, containsPair('capture', 'something')); - expect(input.attributes, isNot(contains('multiple'))); + expect(input.getAttribute('accept'), 'any'); + expect(input.getAttribute('capture'), 'something'); + expect(input.hasAttribute('multiple'), false); }); testWidgets('accept: any, capture: null, multi: true', (WidgetTester tester) async { - final html.Element input = + final web.Element input = plugin.createInputElement('any', null, multiple: true); - expect(input.attributes, containsPair('accept', 'any')); - expect(input.attributes, isNot(contains('capture'))); - expect(input.attributes, contains('multiple')); + expect(input.getAttribute('accept'), 'any'); + expect(input.hasAttribute('capture'), false); + expect(input.hasAttribute('multiple'), true); }); testWidgets('accept: any, capture: something, multi: true', (WidgetTester tester) async { - final html.Element input = + final web.Element input = plugin.createInputElement('any', 'something', multiple: true); - expect(input.attributes, containsPair('accept', 'any')); - expect(input.attributes, containsPair('capture', 'something')); - expect(input.attributes, contains('multiple')); + expect(input.getAttribute('accept'), 'any'); + expect(input.getAttribute('capture'), 'somethinng'); + expect(input.hasAttribute('multiple'), false); }); }); group('Deprecated methods', () { - late html.FileUploadInputElement mockInput; + late web.HTMLInputElement mockInput; late ImagePickerPluginTestOverrides overrides; late ImagePickerPlugin plugin; setUp(() { - mockInput = html.FileUploadInputElement(); + mockInput = (web.document.createElement('input') + as web.HTMLInputElement) + ..type = 'file'; overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) - ..getMultipleFilesFromInput = ((_) => [textFile]); + ..getMultipleFilesFromInput = ((_) => [textFile]); plugin = ImagePickerPlugin(overrides: overrides); }); void mockCancel() { - mockInput.dispatchEvent(html.Event('cancel')); + mockInput.dispatchEvent(web.Event('cancel')); } void mockChange() { - mockInput.dispatchEvent(html.Event('change')); + mockInput.dispatchEvent(web.Event('change')); } group('getImage', () { @@ -301,7 +311,7 @@ void main() { expect( file.lastModified(), completion( - DateTime.fromMillisecondsSinceEpoch(textFile.lastModified!), + DateTime.fromMillisecondsSinceEpoch(textFile.lastModified), )); }); @@ -321,7 +331,7 @@ void main() { testWidgets('can select multiple files', (WidgetTester _) async { // Override the returned files... overrides.getMultipleFilesFromInput = - (_) => [textFile, secondTextFile]; + (_) => [textFile, secondTextFile]; // ignore: deprecated_member_use final Future> files = plugin.getMultiImage(); diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index 0ff6d238000..e4f8fab6f80 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'dart:typed_data'; import 'dart:ui'; @@ -11,6 +11,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/src/image_resizer.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; +import 'package:web/helpers.dart'; +import 'package:web/web.dart' as web; //This is a sample 10x10 png image const String pngFileBase64Contents = @@ -24,14 +26,14 @@ void main() { late XFile pngFile; setUp(() { imageResizer = ImageResizer(); - final html.File pngHtmlFile = - _base64ToFile(pngFileBase64Contents, 'pngImage.png'); - pngFile = XFile(html.Url.createObjectUrl(pngHtmlFile), - name: pngHtmlFile.name, mimeType: pngHtmlFile.type); + final web.Blob pngHtmlFile = + _base64ToBlob(pngFileBase64Contents); + pngFile = XFile(web.URL.createObjectURL(pngHtmlFile), + name: 'pngImage.png', mimeType: 'image/png'); }); testWidgets('image is loaded correctly ', (WidgetTester tester) async { - final html.ImageElement imageElement = + final web.HTMLImageElement imageElement = await imageResizer.loadImage(pngFile.path); expect(imageElement.width, 10); expect(imageElement.height, 10); @@ -40,9 +42,9 @@ void main() { testWidgets( "canvas is loaded with image's width and height when max width and max height are null", (WidgetTester widgetTester) async { - final html.ImageElement imageElement = + final web.HTMLImageElement imageElement = await imageResizer.loadImage(pngFile.path); - final html.CanvasElement canvas = + final web.HTMLCanvasElement canvas = imageResizer.resizeImageElement(imageElement, null, null); expect(canvas.width, imageElement.width); expect(canvas.height, imageElement.height); @@ -51,9 +53,9 @@ void main() { testWidgets( 'canvas size is scaled when max width and max height are not null', (WidgetTester widgetTester) async { - final html.ImageElement imageElement = + final web.HTMLImageElement imageElement = await imageResizer.loadImage(pngFile.path); - final html.CanvasElement canvas = + final web.HTMLCanvasElement canvas = imageResizer.resizeImageElement(imageElement, 8, 8); expect(canvas.width, 8); expect(canvas.height, 8); @@ -61,9 +63,9 @@ void main() { testWidgets('resized image is returned after converting canvas to file', (WidgetTester widgetTester) async { - final html.ImageElement imageElement = + final web.HTMLImageElement imageElement = await imageResizer.loadImage(pngFile.path); - final html.CanvasElement canvas = + final web.HTMLCanvasElement canvas = imageResizer.resizeImageElement(imageElement, null, null); final XFile resizedImage = await imageResizer.writeCanvasToFile(pngFile, canvas, null); @@ -112,19 +114,20 @@ void main() { Future _getImageSize(XFile file) async { final Completer completer = Completer(); - final html.ImageElement image = html.ImageElement(src: file.path); - image.onLoad.listen((html.Event event) { - completer.complete(Size(image.width!.toDouble(), image.height!.toDouble())); + final web.HTMLImageElement image = web.document.createElement('img') as web.HTMLImageElement; + image.src = file.path; + image.onLoad.listen((web.Event event) { + completer.complete(Size(image.width.toDouble(), image.height.toDouble())); }); - image.onError.listen((html.Event event) { + image.onError.listen((web.Event event) { completer.complete(Size.zero); }); return completer.future; } -html.File _base64ToFile(String data, String fileName) { +web.Blob _base64ToBlob(String data) { final List arr = data.split(','); - final String bstr = html.window.atob(arr[1]); + final String bstr = web.window.atob(arr[1]); int n = bstr.length; final Uint8List u8arr = Uint8List(n); @@ -133,5 +136,5 @@ html.File _base64ToFile(String data, String fileName) { n--; } - return html.File([u8arr], fileName); + return Blob([u8arr.toJS].toJS); } diff --git a/packages/image_picker/image_picker_for_web/example/pubspec.yaml b/packages/image_picker/image_picker_for_web/example/pubspec.yaml index e00f7ebdd26..6609fd35db8 100644 --- a/packages/image_picker/image_picker_for_web/example/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: image_picker_for_web_integration_tests publish_to: none environment: - sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.10.0" + sdk: ^3.2.0 + flutter: ">=3.16.0" dependencies: flutter: @@ -11,6 +11,7 @@ dependencies: image_picker_for_web: path: ../ image_picker_platform_interface: ^2.8.0 + web: '>=0.3.0 <0.5.0' dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index b54b68ac550..a5e17c1d8bc 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -3,12 +3,13 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'package:flutter/foundation.dart' show visibleForTesting; import 'package:flutter_web_plugins/flutter_web_plugins.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:mime/mime.dart' as mime; +import 'package:web/web.dart' as web; import 'src/image_resizer.dart'; @@ -33,7 +34,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { bool get _hasOverrides => _overrides != null; - late html.Element _target; + late web.Element _target; late ImageResizer _imageResizer; @@ -151,11 +152,11 @@ class ImagePickerPlugin extends ImagePickerPlatform { String? capture, bool multiple = false, }) { - final html.FileUploadInputElement input = createInputElement( + final web.HTMLInputElement input = createInputElement( accept, capture, multiple: multiple, - ) as html.FileUploadInputElement; + ) as web.HTMLInputElement; _injectAndActivate(input); return _getSelectedXFiles(input); @@ -226,51 +227,55 @@ class ImagePickerPlugin extends ImagePickerPlatform { return null; } - List? _getFilesFromInput(html.FileUploadInputElement input) { + List? _getFilesFromInput(web.HTMLInputElement input) { if (_hasOverrides) { return _overrides!.getMultipleFilesFromInput(input); } - return input.files; + final web.FileList? fileList = input.files; + final List files = []; + for(int i = 0; i < (fileList?.length ?? 0); i++){ + files.add(input.files!.item(i)!); + } + return files; } /// Handles the OnChange event from a FileUploadInputElement object /// Returns a list of selected files. - List? _handleOnChangeEvent(html.Event event) { - final html.FileUploadInputElement? input = - event.target as html.FileUploadInputElement?; + List? _handleOnChangeEvent(web.Event event) { + final web.HTMLInputElement? input = + event.target as web.HTMLInputElement?; return input == null ? null : _getFilesFromInput(input); } /// Monitors an and returns the selected file(s). - Future> _getSelectedXFiles(html.FileUploadInputElement input) { + Future> _getSelectedXFiles(web.HTMLInputElement input) { final Completer> completer = Completer>(); // Observe the input until we can return something - input.onChange.first.then((html.Event event) { - final List? files = _handleOnChangeEvent(event); + input.onchange = (web.Event event) { + final List? files = _handleOnChangeEvent(event); if (!completer.isCompleted && files != null) { - completer.complete(files.map((html.File file) { + completer.complete(files.map((web.File file) { return XFile( - html.Url.createObjectUrl(file), + web.URL.createObjectURL(file), name: file.name, length: file.size, lastModified: DateTime.fromMillisecondsSinceEpoch( - file.lastModified ?? DateTime.now().millisecondsSinceEpoch, + file.lastModified, ), mimeType: file.type, ); }).toList()); } - }); - - input.addEventListener('cancel', (html.Event _) { + }.toJS; + input.oncancel = (web.Event _) { completer.complete([]); - }); + }.toJS; - input.onError.first.then((html.Event event) { + input.onerror = (web.Event event) { if (!completer.isCompleted) { completer.completeError(event); } - }); + }.toJS; // Note that we don't bother detaching from these streams, since the // "input" gets re-created in the DOM every time the user needs to // pick a file. @@ -278,13 +283,12 @@ class ImagePickerPlugin extends ImagePickerPlatform { } /// Initializes a DOM container where we can host input elements. - html.Element _ensureInitialized(String id) { - html.Element? target = html.querySelector('#$id'); + web.Element _ensureInitialized(String id) { + web.Element? target = web.document.querySelector('#$id'); if (target == null) { - final html.Element targetElement = - html.Element.tag('flt-image-picker-inputs')..id = id; - - html.querySelector('body')!.children.add(targetElement); + final web.Element targetElement = + web.document.createElement('flt-image-picker-inputs')..id = id; + web.document.querySelector('body')!.append(targetElement); target = targetElement; } return target; @@ -293,7 +297,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Creates an input element that accepts certain file types, and /// allows to `capture` from the device's cameras (where supported) @visibleForTesting - html.Element createInputElement( + web.Element createInputElement( String? accept, String? capture, { bool multiple = false, @@ -302,10 +306,14 @@ class ImagePickerPlugin extends ImagePickerPlatform { return _overrides!.createInputElement(accept, capture); } - final html.Element element = html.FileUploadInputElement() - ..accept = accept + final web.HTMLInputElement element = (web.document.createElement('input') as web.HTMLInputElement) + ..type = 'file' ..multiple = multiple; + if (accept != null) { + element.accept = accept; + } + if (capture != null) { element.setAttribute('capture', capture); } @@ -314,9 +322,9 @@ class ImagePickerPlugin extends ImagePickerPlatform { } /// Injects the file input element, and clicks on it - void _injectAndActivate(html.Element element) { - _target.children.clear(); - _target.children.add(element); + void _injectAndActivate(web.HTMLElement element) { + _target.replaceChildren([].jsify()); + _target.append(element); // TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365 element.click(); } @@ -325,15 +333,15 @@ class ImagePickerPlugin extends ImagePickerPlatform { // Some tools to override behavior for unit-testing /// A function that creates a file input with the passed in `accept` and `capture` attributes. @visibleForTesting -typedef OverrideCreateInputFunction = html.Element Function( +typedef OverrideCreateInputFunction = web.Element Function( String? accept, String? capture, ); /// A function that extracts list of files from the file `input` passed in. @visibleForTesting -typedef OverrideExtractMultipleFilesFromInputFunction = List - Function(html.Element? input); +typedef OverrideExtractMultipleFilesFromInputFunction = List + Function(web.Element? input); /// Overrides for some of the functionality above. @visibleForTesting diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 7cca935c6c9..9737b92e632 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -3,11 +3,13 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:html' as html; +import 'dart:js_interop'; import 'dart:math'; import 'dart:ui'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; +import 'package:web/helpers.dart'; +import 'package:web/web.dart' as web; import 'image_resizer_utils.dart'; @@ -23,12 +25,12 @@ class ImageResizer { return file; } try { - final html.ImageElement imageElement = await loadImage(file.path); - final html.CanvasElement canvas = + final web.HTMLImageElement imageElement = await loadImage(file.path); + final web.HTMLCanvasElement canvas = resizeImageElement(imageElement, maxWidth, maxHeight); final XFile resizedImage = await writeCanvasToFile(file, canvas, imageQuality); - html.Url.revokeObjectUrl(file.path); + web.URL.revokeObjectURL(file.path); return resizedImage; } catch (e) { return file; @@ -36,39 +38,41 @@ class ImageResizer { } /// function that loads the blobUrl into an imageElement - Future loadImage(String blobUrl) { - final Completer imageLoadCompleter = - Completer(); - final html.ImageElement imageElement = html.ImageElement(); + Future loadImage(String blobUrl) { + final Completer imageLoadCompleter = + Completer(); + final web.HTMLImageElement imageElement = + web.document.createElement('img') as web.HTMLImageElement; // ignore: unsafe_html imageElement.src = blobUrl; - imageElement.onLoad.listen((html.Event event) { + imageElement.onload = (web.Event event) { imageLoadCompleter.complete(imageElement); - }); - imageElement.onError.listen((html.Event event) { + }.toJS; + imageElement.onerror = (web.Event event) { const String exception = 'Error while loading image.'; imageElement.remove(); imageLoadCompleter.completeError(exception); - }); + }.toJS; return imageLoadCompleter.future; } /// Draws image to a canvas while resizing the image to fit the [maxWidth],[maxHeight] constraints - html.CanvasElement resizeImageElement( - html.ImageElement source, double? maxWidth, double? maxHeight) { + web.HTMLCanvasElement resizeImageElement( + web.HTMLImageElement source, double? maxWidth, double? maxHeight) { final Size newImageSize = calculateSizeOfDownScaledImage( - Size(source.width!.toDouble(), source.height!.toDouble()), + Size(source.width.toDouble(), source.height.toDouble()), maxWidth, maxHeight); - final html.CanvasElement canvas = html.CanvasElement(); + final web.HTMLCanvasElement canvas = + web.document.createElement('canvas') as web.HTMLCanvasElement; canvas.width = newImageSize.width.toInt(); canvas.height = newImageSize.height.toInt(); - final html.CanvasRenderingContext2D context = canvas.context2D; + final web.CanvasRenderingContext2D context = canvas.context2D; if (maxHeight == null && maxWidth == null) { context.drawImage(source, 0, 0); } else { - context.drawImageScaled(source, 0, 0, canvas.width!, canvas.height!); + context.drawImageScaled(source, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } @@ -76,15 +80,18 @@ class ImageResizer { /// function that converts a canvas element to Xfile /// [imageQuality] is only supported for jpeg and webp images. Future writeCanvasToFile( - XFile originalFile, html.CanvasElement canvas, int? imageQuality) async { + XFile originalFile, web.HTMLCanvasElement canvas, int? imageQuality) async { final double calculatedImageQuality = (min(imageQuality ?? 100, 100)) / 100.0; - final html.Blob blob = - await canvas.toBlob(originalFile.mimeType, calculatedImageQuality); - return XFile(html.Url.createObjectUrlFromBlob(blob), - mimeType: originalFile.mimeType, - name: 'scaled_${originalFile.name}', - lastModified: DateTime.now(), - length: blob.size); + final Completer completer = Completer(); + final web.BlobCallback blobCallback = (web.Blob blob){ + completer.complete(XFile(web.URL.createObjectURL(blob), + mimeType: originalFile.mimeType, + name: 'scaled_${originalFile.name}', + lastModified: DateTime.now(), + length: blob.size)); + }.toJS; + canvas.toBlob(blobCallback, originalFile.mimeType ?? '', calculatedImageQuality.toJS); + return completer.future; } } diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index 4a1c4ea861e..431e1f46a40 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -2,11 +2,11 @@ name: image_picker_for_web description: Web platform implementation of image_picker repository: https://github.com/flutter/packages/tree/main/packages/image_picker/image_picker_for_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 3.0.1 +version: 3.0.2 environment: - sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.10.0" + sdk: ^3.2.0 + flutter: ">=3.16.0" flutter: plugin: @@ -23,6 +23,7 @@ dependencies: sdk: flutter image_picker_platform_interface: ^2.9.0 mime: ^1.0.4 + web: '>=0.3.0 <0.5.0' dev_dependencies: flutter_test: From b1d9a6f740763448673af9e825e752961617ddc6 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 15:29:15 +0530 Subject: [PATCH 02/35] dart format --- .../image_picker_for_web_test.dart | 14 ++++++-------- .../integration_test/image_resizer_test.dart | 6 +++--- .../lib/image_picker_for_web.dart | 16 ++++++++-------- .../lib/src/image_resizer.dart | 12 +++++++----- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 13c631369d5..f71172a195e 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -17,8 +17,8 @@ const String otherStringContents = 'Hello again, world!'; final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); final web.FilePropertyBag options = web.FilePropertyBag( - lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch -)..type = 'text/plain'; + lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) + ..type = 'text/plain'; final web.File textFile = web.File(bytes.toJS as JSArray, 'hello.txt', options); final web.File secondTextFile = @@ -76,7 +76,7 @@ void main() { WidgetTester _, ) async { final web.HTMLInputElement mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + as web.HTMLInputElement) ..type = 'file'; final ImagePickerPluginTestOverrides overrides = @@ -108,7 +108,7 @@ void main() { testWidgets('getMedia can select multiple files', (WidgetTester _) async { final web.HTMLInputElement mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + as web.HTMLInputElement) ..type = 'file'; final ImagePickerPluginTestOverrides overrides = @@ -145,8 +145,7 @@ void main() { late ImagePickerPlugin plugin; setUp(() { - mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + mockInput = (web.document.createElement('input') as web.HTMLInputElement) ..type = 'file'; overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) @@ -271,8 +270,7 @@ void main() { late ImagePickerPlugin plugin; setUp(() { - mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + mockInput = (web.document.createElement('input') as web.HTMLInputElement) ..type = 'file'; overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index e4f8fab6f80..bc7cc91d20c 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -26,8 +26,7 @@ void main() { late XFile pngFile; setUp(() { imageResizer = ImageResizer(); - final web.Blob pngHtmlFile = - _base64ToBlob(pngFileBase64Contents); + final web.Blob pngHtmlFile = _base64ToBlob(pngFileBase64Contents); pngFile = XFile(web.URL.createObjectURL(pngHtmlFile), name: 'pngImage.png', mimeType: 'image/png'); }); @@ -114,7 +113,8 @@ void main() { Future _getImageSize(XFile file) async { final Completer completer = Completer(); - final web.HTMLImageElement image = web.document.createElement('img') as web.HTMLImageElement; + final web.HTMLImageElement image = + web.document.createElement('img') as web.HTMLImageElement; image.src = file.path; image.onLoad.listen((web.Event event) { completer.complete(Size(image.width.toDouble(), image.height.toDouble())); diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index a5e17c1d8bc..80ef1f93d4e 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -233,7 +233,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { } final web.FileList? fileList = input.files; final List files = []; - for(int i = 0; i < (fileList?.length ?? 0); i++){ + for (int i = 0; i < (fileList?.length ?? 0); i++) { files.add(input.files!.item(i)!); } return files; @@ -242,8 +242,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Handles the OnChange event from a FileUploadInputElement object /// Returns a list of selected files. List? _handleOnChangeEvent(web.Event event) { - final web.HTMLInputElement? input = - event.target as web.HTMLInputElement?; + final web.HTMLInputElement? input = event.target as web.HTMLInputElement?; return input == null ? null : _getFilesFromInput(input); } @@ -306,9 +305,10 @@ class ImagePickerPlugin extends ImagePickerPlatform { return _overrides!.createInputElement(accept, capture); } - final web.HTMLInputElement element = (web.document.createElement('input') as web.HTMLInputElement) - ..type = 'file' - ..multiple = multiple; + final web.HTMLInputElement element = + (web.document.createElement('input') as web.HTMLInputElement) + ..type = 'file' + ..multiple = multiple; if (accept != null) { element.accept = accept; @@ -340,8 +340,8 @@ typedef OverrideCreateInputFunction = web.Element Function( /// A function that extracts list of files from the file `input` passed in. @visibleForTesting -typedef OverrideExtractMultipleFilesFromInputFunction = List - Function(web.Element? input); +typedef OverrideExtractMultipleFilesFromInputFunction = List Function( + web.Element? input); /// Overrides for some of the functionality above. @visibleForTesting diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 9737b92e632..3cc2761dc2b 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -72,26 +72,28 @@ class ImageResizer { if (maxHeight == null && maxWidth == null) { context.drawImage(source, 0, 0); } else { - context.drawImageScaled(source, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); + context.drawImageScaled( + source, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } /// function that converts a canvas element to Xfile /// [imageQuality] is only supported for jpeg and webp images. - Future writeCanvasToFile( - XFile originalFile, web.HTMLCanvasElement canvas, int? imageQuality) async { + Future writeCanvasToFile(XFile originalFile, + web.HTMLCanvasElement canvas, int? imageQuality) async { final double calculatedImageQuality = (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); - final web.BlobCallback blobCallback = (web.Blob blob){ + final web.BlobCallback blobCallback = (web.Blob blob) { completer.complete(XFile(web.URL.createObjectURL(blob), mimeType: originalFile.mimeType, name: 'scaled_${originalFile.name}', lastModified: DateTime.now(), length: blob.size)); }.toJS; - canvas.toBlob(blobCallback, originalFile.mimeType ?? '', calculatedImageQuality.toJS); + canvas.toBlob( + blobCallback, originalFile.mimeType ?? '', calculatedImageQuality.toJS); return completer.future; } } From 8591d9852c713783db827adc302a20872dc70aa6 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 15:54:04 +0530 Subject: [PATCH 03/35] dummy commit --- .../example/integration_test/image_picker_for_web_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index f71172a195e..cfc72e6bd45 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -18,7 +18,7 @@ final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) - ..type = 'text/plain'; + ..type = 'text/plaina'; final web.File textFile = web.File(bytes.toJS as JSArray, 'hello.txt', options); final web.File secondTextFile = From 7143cfea4f6b49b8c0c8fd595ee44005fef70cc5 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 15:54:15 +0530 Subject: [PATCH 04/35] dummy commit --- .../example/integration_test/image_picker_for_web_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index cfc72e6bd45..f71172a195e 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -18,7 +18,7 @@ final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) - ..type = 'text/plaina'; + ..type = 'text/plain'; final web.File textFile = web.File(bytes.toJS as JSArray, 'hello.txt', options); final web.File secondTextFile = From db4399563a19a7b8215602f54f85ae8ae61b154d Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 16:03:24 +0530 Subject: [PATCH 05/35] fix tests --- .../example/integration_test/image_picker_for_web_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index f71172a195e..1c9f9367365 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -259,7 +259,7 @@ void main() { plugin.createInputElement('any', 'something', multiple: true); expect(input.getAttribute('accept'), 'any'); - expect(input.getAttribute('capture'), 'somethinng'); + expect(input.getAttribute('capture'), 'something'); expect(input.hasAttribute('multiple'), false); }); }); From 9431bf63f2989202a9b33fd7c776d55e146e8b56 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 16:44:33 +0530 Subject: [PATCH 06/35] fix test --- .../example/integration_test/image_picker_for_web_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 1c9f9367365..513629c73f5 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -260,7 +260,7 @@ void main() { expect(input.getAttribute('accept'), 'any'); expect(input.getAttribute('capture'), 'something'); - expect(input.hasAttribute('multiple'), false); + expect(input.hasAttribute('multiple'), true); }); }); From 7adb97c5cb6495ce550dc67a326fb786672a97d6 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 16:52:22 +0530 Subject: [PATCH 07/35] fix analyze and test --- .../example/integration_test/image_resizer_test.dart | 2 +- .../image_picker_for_web/lib/image_picker_for_web.dart | 6 +++--- .../image_picker_for_web/lib/src/image_resizer.dart | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index bc7cc91d20c..081779cd34c 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -27,7 +27,7 @@ void main() { setUp(() { imageResizer = ImageResizer(); final web.Blob pngHtmlFile = _base64ToBlob(pngFileBase64Contents); - pngFile = XFile(web.URL.createObjectURL(pngHtmlFile), + pngFile = XFile(web.URL.createObjectURL(pngHtmlFile.toJSBox), name: 'pngImage.png', mimeType: 'image/png'); }); diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 80ef1f93d4e..fdd6ef91e7f 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -255,7 +255,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (!completer.isCompleted && files != null) { completer.complete(files.map((web.File file) { return XFile( - web.URL.createObjectURL(file), + web.URL.createObjectURL(file.toJSBox), name: file.name, length: file.size, lastModified: DateTime.fromMillisecondsSinceEpoch( @@ -287,7 +287,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (target == null) { final web.Element targetElement = web.document.createElement('flt-image-picker-inputs')..id = id; - web.document.querySelector('body')!.append(targetElement); + web.document.querySelector('body')!.append(targetElement.toJSBox); target = targetElement; } return target; @@ -323,7 +323,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Injects the file input element, and clicks on it void _injectAndActivate(web.HTMLElement element) { - _target.replaceChildren([].jsify()); + _target.replaceChildren([].toJS); _target.append(element); // TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365 element.click(); diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 3cc2761dc2b..4be4deb8929 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -70,10 +70,10 @@ class ImageResizer { canvas.height = newImageSize.height.toInt(); final web.CanvasRenderingContext2D context = canvas.context2D; if (maxHeight == null && maxWidth == null) { - context.drawImage(source, 0, 0); + context.drawImage(source.toJSBox, 0, 0); } else { context.drawImageScaled( - source, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); + source.toJSBox, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } @@ -86,7 +86,7 @@ class ImageResizer { (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); final web.BlobCallback blobCallback = (web.Blob blob) { - completer.complete(XFile(web.URL.createObjectURL(blob), + completer.complete(XFile(web.URL.createObjectURL(blob.toJSBox), mimeType: originalFile.mimeType, name: 'scaled_${originalFile.name}', lastModified: DateTime.now(), From b81568db81c4360a268768d2023a3c44182604f0 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 16:59:56 +0530 Subject: [PATCH 08/35] fix error --- packages/image_picker/image_picker/pubspec.yaml | 3 ++- .../image_picker_for_web/lib/image_picker_for_web.dart | 4 ++-- .../image_picker_for_web/lib/src/image_resizer.dart | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index 5095af7acab..bf53d2a89e5 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -29,7 +29,8 @@ dependencies: flutter: sdk: flutter image_picker_android: ^0.8.7 - image_picker_for_web: ">=2.2.0 <4.0.0" + image_picker_for_web: + path: ../image_picker_for_web image_picker_ios: ^0.8.8 image_picker_linux: ^0.2.1 image_picker_macos: ^0.2.1 diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index fdd6ef91e7f..b2f9ec7d9d4 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -255,7 +255,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (!completer.isCompleted && files != null) { completer.complete(files.map((web.File file) { return XFile( - web.URL.createObjectURL(file.toJSBox), + web.URL.createObjectURL(file.jsify()), name: file.name, length: file.size, lastModified: DateTime.fromMillisecondsSinceEpoch( @@ -287,7 +287,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (target == null) { final web.Element targetElement = web.document.createElement('flt-image-picker-inputs')..id = id; - web.document.querySelector('body')!.append(targetElement.toJSBox); + web.document.querySelector('body')!.append(targetElement.jsify()); target = targetElement; } return target; diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 4be4deb8929..806c43be77a 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -70,10 +70,10 @@ class ImageResizer { canvas.height = newImageSize.height.toInt(); final web.CanvasRenderingContext2D context = canvas.context2D; if (maxHeight == null && maxWidth == null) { - context.drawImage(source.toJSBox, 0, 0); + context.drawImage(source.jsify(), 0, 0); } else { context.drawImageScaled( - source.toJSBox, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); + source.jsify(), 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } @@ -86,7 +86,7 @@ class ImageResizer { (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); final web.BlobCallback blobCallback = (web.Blob blob) { - completer.complete(XFile(web.URL.createObjectURL(blob.toJSBox), + completer.complete(XFile(web.URL.createObjectURL(blob.jsify()), mimeType: originalFile.mimeType, name: 'scaled_${originalFile.name}', lastModified: DateTime.now(), From 390ee245bef191772daf90bc5524ef5dc66e1b6f Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 17:02:15 +0530 Subject: [PATCH 09/35] revert package --- packages/image_picker/image_picker/pubspec.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml index bf53d2a89e5..5095af7acab 100755 --- a/packages/image_picker/image_picker/pubspec.yaml +++ b/packages/image_picker/image_picker/pubspec.yaml @@ -29,8 +29,7 @@ dependencies: flutter: sdk: flutter image_picker_android: ^0.8.7 - image_picker_for_web: - path: ../image_picker_for_web + image_picker_for_web: ">=2.2.0 <4.0.0" image_picker_ios: ^0.8.8 image_picker_linux: ^0.2.1 image_picker_macos: ^0.2.1 From 7050c0efbbb6f53ed021eec881b084b868f6501f Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 17:17:39 +0530 Subject: [PATCH 10/35] fix analyze --- .../integration_test/image_picker_for_web_test.dart | 9 ++++----- .../image_picker_for_web/lib/image_picker_for_web.dart | 6 +++--- .../image_picker_for_web/lib/src/image_resizer.dart | 5 +++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 513629c73f5..578fe5aecd9 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -4,7 +4,6 @@ import 'dart:convert'; import 'dart:js_interop'; -import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/image_picker_for_web.dart'; @@ -14,15 +13,15 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; -final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); -final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); +final JSArray bytes = const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; +final JSArray otherBytes = const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) ..type = 'text/plain'; -final web.File textFile = web.File(bytes.toJS as JSArray, 'hello.txt', options); +final web.File textFile = web.File(bytes, 'hello.txt', options); final web.File secondTextFile = - web.File(otherBytes.toJS as JSArray, 'secondFile.txt'); + web.File(otherBytes, 'secondFile.txt'); void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index b2f9ec7d9d4..660c15f1e12 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -255,7 +255,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (!completer.isCompleted && files != null) { completer.complete(files.map((web.File file) { return XFile( - web.URL.createObjectURL(file.jsify()), + web.URL.createObjectURL(file.jsify()! as JSObject), name: file.name, length: file.size, lastModified: DateTime.fromMillisecondsSinceEpoch( @@ -287,7 +287,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (target == null) { final web.Element targetElement = web.document.createElement('flt-image-picker-inputs')..id = id; - web.document.querySelector('body')!.append(targetElement.jsify()); + web.document.querySelector('body')!.append(targetElement.jsify()!); target = targetElement; } return target; @@ -324,7 +324,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Injects the file input element, and clicks on it void _injectAndActivate(web.HTMLElement element) { _target.replaceChildren([].toJS); - _target.append(element); + _target.append(element.jsify()!); // TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365 element.click(); } diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 806c43be77a..484200c3e60 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:js'; import 'dart:js_interop'; import 'dart:math'; import 'dart:ui'; @@ -70,10 +71,10 @@ class ImageResizer { canvas.height = newImageSize.height.toInt(); final web.CanvasRenderingContext2D context = canvas.context2D; if (maxHeight == null && maxWidth == null) { - context.drawImage(source.jsify(), 0, 0); + context.drawImage(source.jsify()! as JSObject, 0, 0); } else { context.drawImageScaled( - source.jsify(), 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); + source.jsify()! as JSObject, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } From ccf7796cb264b37e1a38f5e1833e0642dbd90eed Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 17:27:13 +0530 Subject: [PATCH 11/35] fix analyze --- .../example/integration_test/image_picker_for_web_test.dart | 2 ++ .../image_picker_for_web/lib/image_picker_for_web.dart | 4 ++-- .../image_picker_for_web/lib/src/image_resizer.dart | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 578fe5aecd9..a3937dbbeea 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -13,7 +13,9 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; +// ignore: always_specify_types final JSArray bytes = const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; +// ignore: always_specify_types final JSArray otherBytes = const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 660c15f1e12..66d3f02f2dc 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -287,7 +287,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (target == null) { final web.Element targetElement = web.document.createElement('flt-image-picker-inputs')..id = id; - web.document.querySelector('body')!.append(targetElement.jsify()!); + web.document.querySelector('body')!.append(targetElement.jsify()); target = targetElement; } return target; @@ -324,7 +324,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Injects the file input element, and clicks on it void _injectAndActivate(web.HTMLElement element) { _target.replaceChildren([].toJS); - _target.append(element.jsify()!); + _target.append(element.jsify()); // TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365 element.click(); } diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 484200c3e60..ec7ceb5c7e2 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:js'; import 'dart:js_interop'; import 'dart:math'; import 'dart:ui'; @@ -87,7 +86,7 @@ class ImageResizer { (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); final web.BlobCallback blobCallback = (web.Blob blob) { - completer.complete(XFile(web.URL.createObjectURL(blob.jsify()), + completer.complete(XFile(web.URL.createObjectURL(blob.jsify()! as JSObject), mimeType: originalFile.mimeType, name: 'scaled_${originalFile.name}', lastModified: DateTime.now(), From 0a160b524163147adea8492210fa85fc6a02997e Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 17:36:39 +0530 Subject: [PATCH 12/35] fix analyze --- .../image_picker_for_web/lib/image_picker_for_web.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 66d3f02f2dc..f7de2b5de8f 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -287,7 +287,8 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (target == null) { final web.Element targetElement = web.document.createElement('flt-image-picker-inputs')..id = id; - web.document.querySelector('body')!.append(targetElement.jsify()); + final JSAny jsElement = targetElement.jsify()!; + web.document.querySelector('body')!.append(jsElement); target = targetElement; } return target; @@ -324,7 +325,8 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Injects the file input element, and clicks on it void _injectAndActivate(web.HTMLElement element) { _target.replaceChildren([].toJS); - _target.append(element.jsify()); + final JSAny jsElement = element.jsify()!; + _target.append(jsElement); // TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365 element.click(); } From 24ca0cd18bc62029bb17da18dae90c2315ec585d Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 17:42:01 +0530 Subject: [PATCH 13/35] format --- .../integration_test/image_picker_for_web_test.dart | 9 +++++---- .../image_picker_for_web/lib/src/image_resizer.dart | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index a3937dbbeea..3e9e12440ba 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -14,16 +14,17 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; // ignore: always_specify_types -final JSArray bytes = const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; +final JSArray bytes = + const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; // ignore: always_specify_types -final JSArray otherBytes = const Utf8Encoder().convert(otherStringContents).toJS as JSArray; +final JSArray otherBytes = + const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) ..type = 'text/plain'; final web.File textFile = web.File(bytes, 'hello.txt', options); -final web.File secondTextFile = - web.File(otherBytes, 'secondFile.txt'); +final web.File secondTextFile = web.File(otherBytes, 'secondFile.txt'); void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index ec7ceb5c7e2..ce15e9e044b 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -72,8 +72,8 @@ class ImageResizer { if (maxHeight == null && maxWidth == null) { context.drawImage(source.jsify()! as JSObject, 0, 0); } else { - context.drawImageScaled( - source.jsify()! as JSObject, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); + context.drawImageScaled(source.jsify()! as JSObject, 0, 0, + canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } @@ -86,7 +86,8 @@ class ImageResizer { (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); final web.BlobCallback blobCallback = (web.Blob blob) { - completer.complete(XFile(web.URL.createObjectURL(blob.jsify()! as JSObject), + completer.complete(XFile( + web.URL.createObjectURL(blob.jsify()! as JSObject), mimeType: originalFile.mimeType, name: 'scaled_${originalFile.name}', lastModified: DateTime.now(), From 0a242557ec24adc4adadef74591ebf8f40f656fe Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 18:04:02 +0530 Subject: [PATCH 14/35] analyze --- .../example/integration_test/image_picker_for_web_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 3e9e12440ba..0b93d5c119f 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -13,11 +13,11 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; -// ignore: always_specify_types final JSArray bytes = - const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; // ignore: always_specify_types + const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; final JSArray otherBytes = +// ignore: always_specify_types const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) From ac4149ceed25278df813cdc1b60dd9b2a5da752a Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 18:13:28 +0530 Subject: [PATCH 15/35] analyze --- .../example/integration_test/image_picker_for_web_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 0b93d5c119f..0bd92da0b2a 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -1,6 +1,8 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: always_specify_types + import 'dart:convert'; import 'dart:js_interop'; @@ -14,10 +16,8 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; final JSArray bytes = -// ignore: always_specify_types const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; final JSArray otherBytes = -// ignore: always_specify_types const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) From 0e29289baac7e0d4641ce5531f8e1e8e66393e7a Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 18:20:32 +0530 Subject: [PATCH 16/35] format --- .../example/integration_test/image_picker_for_web_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 0bd92da0b2a..0db21600e78 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. // ignore_for_file: always_specify_types - import 'dart:convert'; import 'dart:js_interop'; From 5f53b828618e50be3fe7e550909e6e30cabc1802 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 18:55:26 +0530 Subject: [PATCH 17/35] empty commit --- .../example/integration_test/image_picker_for_web_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 0db21600e78..9d1579b5993 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -4,7 +4,7 @@ // ignore_for_file: always_specify_types import 'dart:convert'; -import 'dart:js_interop'; +import 'dart:js_interop' ; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/image_picker_for_web.dart'; From 02c4760b54cc675b96af6e76e88140fdb14e752a Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 18:55:53 +0530 Subject: [PATCH 18/35] empty commit --- .../example/integration_test/image_picker_for_web_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 9d1579b5993..0db21600e78 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -4,7 +4,7 @@ // ignore_for_file: always_specify_types import 'dart:convert'; -import 'dart:js_interop' ; +import 'dart:js_interop'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/image_picker_for_web.dart'; From f0e1ca95c4208b9e1907779eb7922949bd70b897 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 19:11:47 +0530 Subject: [PATCH 19/35] add ignore on declaration --- .../example/integration_test/image_picker_for_web_test.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 0db21600e78..3e9e12440ba 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -1,7 +1,6 @@ // Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// ignore_for_file: always_specify_types import 'dart:convert'; import 'dart:js_interop'; @@ -14,8 +13,10 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; +// ignore: always_specify_types final JSArray bytes = const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; +// ignore: always_specify_types final JSArray otherBytes = const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( From 20bfe0e5fde11c350f37a8d748cc7da9cf135c51 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 20:09:57 +0530 Subject: [PATCH 20/35] fix analyze --- .../example/integration_test/image_picker_for_web_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 3e9e12440ba..062842da2ac 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -15,9 +15,11 @@ const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; // ignore: always_specify_types final JSArray bytes = +// ignore: always_specify_types const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; // ignore: always_specify_types final JSArray otherBytes = +// ignore: always_specify_types const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) From 6e77037958a47bcba266a061ad41824650dd2336 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 21:47:50 +0530 Subject: [PATCH 21/35] added todo --- .../example/integration_test/image_picker_for_web_test.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 062842da2ac..b943bb6cf78 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -14,11 +14,15 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; // ignore: always_specify_types +// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. final JSArray bytes = // ignore: always_specify_types +// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; // ignore: always_specify_types +// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. final JSArray otherBytes = +// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. // ignore: always_specify_types const Utf8Encoder().convert(otherStringContents).toJS as JSArray; final web.FilePropertyBag options = web.FilePropertyBag( From e58b1d2aa5aa3a74c38de9d4a676b13645ec2345 Mon Sep 17 00:00:00 2001 From: Balvinder Singh Gambhir Date: Thu, 4 Jan 2024 22:47:05 +0530 Subject: [PATCH 22/35] Update image_picker_for_web_test.dart --- .../example/integration_test/image_picker_for_web_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index b943bb6cf78..fd9b8bd62f1 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -13,14 +13,14 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; -// ignore: always_specify_types // TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. -final JSArray bytes = // ignore: always_specify_types +final JSArray bytes = // TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. - const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; // ignore: always_specify_types + const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; // TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. +// ignore: always_specify_types final JSArray otherBytes = // TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. // ignore: always_specify_types From 938c23b86331f39d3d831f33e7182d7338d709d3 Mon Sep 17 00:00:00 2001 From: Balvinder Singh Gambhir Date: Thu, 4 Jan 2024 23:26:24 +0530 Subject: [PATCH 23/35] dummy commit --- .../example/integration_test/image_resizer_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index 081779cd34c..4ffe0abd5dc 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -11,7 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/src/image_resizer.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:web/helpers.dart'; +import 'package:web/helpers.dart' ; import 'package:web/web.dart' as web; //This is a sample 10x10 png image From c70116d5386cda929a50cbd79b72d00f7b6dd7af Mon Sep 17 00:00:00 2001 From: Balvinder Singh Gambhir Date: Thu, 4 Jan 2024 23:26:54 +0530 Subject: [PATCH 24/35] dummy commit --- .../example/integration_test/image_resizer_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index 4ffe0abd5dc..b9d14dc275d 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -11,7 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/src/image_resizer.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:web/helpers.dart' ; +import 'package:web/helpers.dart'; import 'package:web/web.dart' as web; //This is a sample 10x10 png image From a270d011a6f0fde07fe6322a590e136bae8a2da4 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Thu, 4 Jan 2024 23:54:09 +0530 Subject: [PATCH 25/35] apply patch --- .../example/integration_test/image_resizer_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index b9d14dc275d..081779cd34c 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -11,7 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/src/image_resizer.dart'; import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:web/helpers.dart'; +import 'package:web/helpers.dart'; import 'package:web/web.dart' as web; //This is a sample 10x10 png image From b51fa8efc84440cb3bd5431a649dbf976b453539 Mon Sep 17 00:00:00 2001 From: balvinderz Date: Fri, 5 Jan 2024 00:35:05 +0530 Subject: [PATCH 26/35] try without jsarray --- .../image_picker_for_web_test.dart | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index fd9b8bd62f1..787cbb672f2 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'dart:js_interop'; +import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker_for_web/image_picker_for_web.dart'; @@ -13,24 +14,16 @@ import 'package:web/web.dart' as web; const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; -// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. -// ignore: always_specify_types -final JSArray bytes = -// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. -// ignore: always_specify_types - const Utf8Encoder().convert(expectedStringContents).toJS as JSArray; -// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. -// ignore: always_specify_types -final JSArray otherBytes = -// TODO(ditman): Remove once typed JSArrays (JSArray) get to `stable`. -// ignore: always_specify_types - const Utf8Encoder().convert(otherStringContents).toJS as JSArray; +final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); +final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); final web.FilePropertyBag options = web.FilePropertyBag( lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) ..type = 'text/plain'; -final web.File textFile = web.File(bytes, 'hello.txt', options); -final web.File secondTextFile = web.File(otherBytes, 'secondFile.txt'); +final web.File textFile = + web.File([bytes.toJS].toJS, 'hello.txt', options); +final web.File secondTextFile = + web.File([otherBytes.toJS].toJS, 'secondFile.txt'); void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); From c1eee82eb43978e3e91b2e873f35b9539c44131c Mon Sep 17 00:00:00 2001 From: Balvinder Singh Gambhir Date: Fri, 5 Jan 2024 19:21:20 +0530 Subject: [PATCH 27/35] Update image_resizer.dart --- .../image_picker_for_web/lib/src/image_resizer.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 5ab309a81cf..ce15e9e044b 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -7,7 +7,7 @@ import 'dart:js_interop'; import 'dart:math'; import 'dart:ui'; -import 'package:image_pickwer_platform_interface/image_picker_platform_interface.dart'; +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; import 'package:web/helpers.dart'; import 'package:web/web.dart' as web; From 9e475dfa9e3da3fe1963bde05d7fbb9c57345b1f Mon Sep 17 00:00:00 2001 From: Balvinder Singh Gambhir Date: Fri, 5 Jan 2024 20:14:11 +0530 Subject: [PATCH 28/35] Update image_picker_for_web.dart --- .../image_picker_for_web/lib/image_picker_for_web.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 60f32646e52..84b266b29ce 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -159,7 +159,9 @@ class ImagePickerPlugin extends ImagePickerPlatform { ) as web.HTMLInputElement; _injectAndActivate(input); - return _getSelectedXFiles(input).whenComplete(input.remove); + return _getSelectedXFiles(input).whenComplete(() { + input.remove(); + }); } // Deprecated methods follow... From 3eb21b736df1bd5d6ee5327ecd0cbc4946ecfd3d Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 27 Feb 2024 19:46:23 -0800 Subject: [PATCH 29/35] Update web and environment to latest stable. --- packages/image_picker/image_picker_for_web/CHANGELOG.md | 5 +++-- .../image_picker/image_picker_for_web/example/pubspec.yaml | 6 +++--- packages/image_picker/image_picker_for_web/pubspec.yaml | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index 935928abeae..b9c1adae896 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,11 +1,12 @@ ## 3.0.3 * Migrates package and tests to `platform:web`. -* Updates minimum supported SDK version to Flutter 3.16.0/Dart 3.2.0. +* Updates minimum supported SDK version to Flutter 3.19.0/Dart 3.3.0. ## 3.0.2 -* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. + * Removes input element after completion +* Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. ## 3.0.1 diff --git a/packages/image_picker/image_picker_for_web/example/pubspec.yaml b/packages/image_picker/image_picker_for_web/example/pubspec.yaml index e87de0ad186..14a12e7ae50 100644 --- a/packages/image_picker/image_picker_for_web/example/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/example/pubspec.yaml @@ -2,8 +2,8 @@ name: image_picker_for_web_integration_tests publish_to: none environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" dependencies: flutter: @@ -11,7 +11,7 @@ dependencies: image_picker_for_web: path: ../ image_picker_platform_interface: ^2.8.0 - web: '>=0.3.0 <0.5.0' + web: ^0.5.0 dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index 1d4cef10f55..e54fde03b75 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -5,8 +5,8 @@ issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+ version: 3.0.3 environment: - sdk: ^3.2.0 - flutter: ">=3.16.0" + sdk: ^3.3.0 + flutter: ">=3.19.0" flutter: plugin: @@ -23,7 +23,7 @@ dependencies: sdk: flutter image_picker_platform_interface: ^2.9.0 mime: ^1.0.4 - web: '>=0.3.0 <0.5.0' + web: ^0.5.0 dev_dependencies: flutter_test: From 5898986d2f063bb98c542f268b3d97cb3f633019 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Wed, 28 Feb 2024 17:59:13 -0800 Subject: [PATCH 30/35] Address PR comments. --- .../image_picker_for_web/CHANGELOG.md | 6 +++--- .../image_picker_for_web_test.dart | 16 ++++------------ .../integration_test/image_resizer_test.dart | 2 +- .../lib/image_picker_for_web.dart | 17 ++++++----------- .../lib/src/image_resizer.dart | 9 ++++----- .../lib/src/pkg_web_tweaks.dart | 14 ++++++++++++++ 6 files changed, 32 insertions(+), 32 deletions(-) create mode 100644 packages/image_picker/image_picker_for_web/lib/src/pkg_web_tweaks.dart diff --git a/packages/image_picker/image_picker_for_web/CHANGELOG.md b/packages/image_picker/image_picker_for_web/CHANGELOG.md index b9c1adae896..2cfa022e0b9 100644 --- a/packages/image_picker/image_picker_for_web/CHANGELOG.md +++ b/packages/image_picker/image_picker_for_web/CHANGELOG.md @@ -1,12 +1,12 @@ ## 3.0.3 -* Migrates package and tests to `platform:web`. -* Updates minimum supported SDK version to Flutter 3.19.0/Dart 3.3.0. +* Migrates package and tests to `package:web`. +* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3. ## 3.0.2 -* Removes input element after completion * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. +* Removes input element after completion ## 3.0.1 diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index b082c1381df..674b2d2cd95 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -54,12 +54,8 @@ void main() { ); expect( - web.document - .querySelector('flt-image-picker-inputs') - ?.children - .length == - 0, - isFalse); + web.document.querySelector('flt-image-picker-inputs')?.children.length, + isNonZero); // Mock the browser behavior of selecting a file... mockInput.dispatchEvent(web.Event('change')); @@ -80,12 +76,8 @@ void main() { DateTime.fromMillisecondsSinceEpoch(textFile.lastModified), )); expect( - web.document - .querySelector('flt-image-picker-inputs') - ?.children - .length == - 0, - isTrue); + web.document.querySelector('flt-image-picker-inputs')?.children.length, + isZero); }); testWidgets('getMultiImageWithOptions can select multiple files', ( diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index 081779cd34c..bc7cc91d20c 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -27,7 +27,7 @@ void main() { setUp(() { imageResizer = ImageResizer(); final web.Blob pngHtmlFile = _base64ToBlob(pngFileBase64Contents); - pngFile = XFile(web.URL.createObjectURL(pngHtmlFile.toJSBox), + pngFile = XFile(web.URL.createObjectURL(pngHtmlFile), name: 'pngImage.png', mimeType: 'image/png'); }); diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 84b266b29ce..8839c0144ec 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -12,6 +12,7 @@ import 'package:mime/mime.dart' as mime; import 'package:web/web.dart' as web; import 'src/image_resizer.dart'; +import 'src/pkg_web_tweaks.dart'; const String _kImagePickerInputsDomId = '__image_picker_web-file-input'; const String _kAcceptImageMimeType = 'image/*'; @@ -233,12 +234,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (_hasOverrides) { return _overrides!.getMultipleFilesFromInput(input); } - final web.FileList? fileList = input.files; - final List files = []; - for (int i = 0; i < (fileList?.length ?? 0); i++) { - files.add(input.files!.item(i)!); - } - return files; + return input.files?.toList; } /// Handles the OnChange event from a FileUploadInputElement object @@ -257,7 +253,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (!completer.isCompleted && files != null) { completer.complete(files.map((web.File file) { return XFile( - web.URL.createObjectURL(file.jsify()! as JSObject), + web.URL.createObjectURL(file), name: file.name, length: file.size, lastModified: DateTime.fromMillisecondsSinceEpoch( @@ -289,8 +285,8 @@ class ImagePickerPlugin extends ImagePickerPlatform { if (target == null) { final web.Element targetElement = web.document.createElement('flt-image-picker-inputs')..id = id; - final JSAny jsElement = targetElement.jsify()!; - web.document.querySelector('body')!.append(jsElement); + // TODO(ditman): Append inside the `view` of the running app. + web.document.body!.append(targetElement); target = targetElement; } return target; @@ -327,8 +323,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Injects the file input element, and clicks on it void _injectAndActivate(web.HTMLElement element) { _target.replaceChildren([].toJS); - final JSAny jsElement = element.jsify()!; - _target.append(jsElement); + _target.append(element); // TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365 element.click(); } diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index ce15e9e044b..3cc2761dc2b 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -70,10 +70,10 @@ class ImageResizer { canvas.height = newImageSize.height.toInt(); final web.CanvasRenderingContext2D context = canvas.context2D; if (maxHeight == null && maxWidth == null) { - context.drawImage(source.jsify()! as JSObject, 0, 0); + context.drawImage(source, 0, 0); } else { - context.drawImageScaled(source.jsify()! as JSObject, 0, 0, - canvas.width.toDouble(), canvas.height.toDouble()); + context.drawImageScaled( + source, 0, 0, canvas.width.toDouble(), canvas.height.toDouble()); } return canvas; } @@ -86,8 +86,7 @@ class ImageResizer { (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); final web.BlobCallback blobCallback = (web.Blob blob) { - completer.complete(XFile( - web.URL.createObjectURL(blob.jsify()! as JSObject), + completer.complete(XFile(web.URL.createObjectURL(blob), mimeType: originalFile.mimeType, name: 'scaled_${originalFile.name}', lastModified: DateTime.now(), diff --git a/packages/image_picker/image_picker_for_web/lib/src/pkg_web_tweaks.dart b/packages/image_picker/image_picker_for_web/lib/src/pkg_web_tweaks.dart new file mode 100644 index 00000000000..1152b01b2d4 --- /dev/null +++ b/packages/image_picker/image_picker_for_web/lib/src/pkg_web_tweaks.dart @@ -0,0 +1,14 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:web/web.dart' as web; + +/// Adds a `toList` method to [web.FileList] objects. +extension WebFileListToDartList on web.FileList { + /// Converts a [web.FileList] into a [List] of [web.File]. + /// + /// This method makes a copy. + List get toList => + [for (int i = 0; i < length; i++) item(i)!]; +} From 299c800a6571f3ad3a9a7183f512d779418544a2 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 5 Mar 2024 19:09:53 -0800 Subject: [PATCH 31/35] Bump web to 0.5.1 and use element constructors. --- .../image_picker_for_web_test.dart | 15 +++------ .../integration_test/image_resizer_test.dart | 18 +++++------ .../image_picker_for_web/example/pubspec.yaml | 2 +- .../lib/image_picker_for_web.dart | 7 ++-- .../lib/src/image_resizer.dart | 32 +++++++++---------- .../image_picker_for_web/pubspec.yaml | 2 +- 6 files changed, 34 insertions(+), 42 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 674b2d2cd95..4c80dd23d0c 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -38,8 +38,7 @@ void main() { testWidgets('getImageFromSource can select a file', ( WidgetTester _, ) async { - final web.HTMLInputElement mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + final web.HTMLInputElement mockInput = web.HTMLInputElement() ..type = 'file'; final ImagePickerPluginTestOverrides overrides = ImagePickerPluginTestOverrides() @@ -83,8 +82,7 @@ void main() { testWidgets('getMultiImageWithOptions can select multiple files', ( WidgetTester _, ) async { - final web.HTMLInputElement mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + final web.HTMLInputElement mockInput = web.HTMLInputElement() ..type = 'file'; final ImagePickerPluginTestOverrides overrides = @@ -115,8 +113,7 @@ void main() { }); testWidgets('getMedia can select multiple files', (WidgetTester _) async { - final web.HTMLInputElement mockInput = (web.document.createElement('input') - as web.HTMLInputElement) + final web.HTMLInputElement mockInput = web.HTMLInputElement() ..type = 'file'; final ImagePickerPluginTestOverrides overrides = @@ -153,8 +150,7 @@ void main() { late ImagePickerPlugin plugin; setUp(() { - mockInput = (web.document.createElement('input') as web.HTMLInputElement) - ..type = 'file'; + mockInput = web.HTMLInputElement()..type = 'file'; overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) ..getMultipleFilesFromInput = ((_) => [textFile]); @@ -278,8 +274,7 @@ void main() { late ImagePickerPlugin plugin; setUp(() { - mockInput = (web.document.createElement('input') as web.HTMLInputElement) - ..type = 'file'; + mockInput = web.HTMLInputElement()..type = 'file'; overrides = ImagePickerPluginTestOverrides() ..createInputElement = ((_, __) => mockInput) ..getMultipleFilesFromInput = ((_) => [textFile]); diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart index bc7cc91d20c..dc01ef6d197 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_resizer_test.dart @@ -113,15 +113,15 @@ void main() { Future _getImageSize(XFile file) async { final Completer completer = Completer(); - final web.HTMLImageElement image = - web.document.createElement('img') as web.HTMLImageElement; - image.src = file.path; - image.onLoad.listen((web.Event event) { - completer.complete(Size(image.width.toDouble(), image.height.toDouble())); - }); - image.onError.listen((web.Event event) { - completer.complete(Size.zero); - }); + final web.HTMLImageElement image = web.HTMLImageElement(); + image + ..onLoad.listen((web.Event event) { + completer.complete(Size(image.width.toDouble(), image.height.toDouble())); + }) + ..onError.listen((web.Event event) { + completer.complete(Size.zero); + }) + ..src = file.path; return completer.future; } diff --git a/packages/image_picker/image_picker_for_web/example/pubspec.yaml b/packages/image_picker/image_picker_for_web/example/pubspec.yaml index 14a12e7ae50..f4f85645c58 100644 --- a/packages/image_picker/image_picker_for_web/example/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/example/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: image_picker_for_web: path: ../ image_picker_platform_interface: ^2.8.0 - web: ^0.5.0 + web: ^0.5.1 dev_dependencies: flutter_test: diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 8839c0144ec..749b5c61c36 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -304,10 +304,9 @@ class ImagePickerPlugin extends ImagePickerPlatform { return _overrides!.createInputElement(accept, capture); } - final web.HTMLInputElement element = - (web.document.createElement('input') as web.HTMLInputElement) - ..type = 'file' - ..multiple = multiple; + final web.HTMLInputElement element = web.HTMLInputElement() + ..type = 'file' + ..multiple = multiple; if (accept != null) { element.accept = accept; diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index 3cc2761dc2b..f1a6c9a12a0 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -41,19 +41,18 @@ class ImageResizer { Future loadImage(String blobUrl) { final Completer imageLoadCompleter = Completer(); - final web.HTMLImageElement imageElement = - web.document.createElement('img') as web.HTMLImageElement; - // ignore: unsafe_html - imageElement.src = blobUrl; - - imageElement.onload = (web.Event event) { - imageLoadCompleter.complete(imageElement); - }.toJS; - imageElement.onerror = (web.Event event) { - const String exception = 'Error while loading image.'; - imageElement.remove(); - imageLoadCompleter.completeError(exception); - }.toJS; + final web.HTMLImageElement imageElement = web.HTMLImageElement(); + imageElement + // ignore: unsafe_html + ..src = blobUrl + ..onload = (web.Event event) { + imageLoadCompleter.complete(imageElement); + }.toJS + ..onerror = (web.Event event) { + const String exception = 'Error while loading image.'; + imageElement.remove(); + imageLoadCompleter.completeError(exception); + }.toJS; return imageLoadCompleter.future; } @@ -64,10 +63,9 @@ class ImageResizer { Size(source.width.toDouble(), source.height.toDouble()), maxWidth, maxHeight); - final web.HTMLCanvasElement canvas = - web.document.createElement('canvas') as web.HTMLCanvasElement; - canvas.width = newImageSize.width.toInt(); - canvas.height = newImageSize.height.toInt(); + final web.HTMLCanvasElement canvas = web.HTMLCanvasElement() + ..width = newImageSize.width.toInt() + ..height = newImageSize.height.toInt(); final web.CanvasRenderingContext2D context = canvas.context2D; if (maxHeight == null && maxWidth == null) { context.drawImage(source, 0, 0); diff --git a/packages/image_picker/image_picker_for_web/pubspec.yaml b/packages/image_picker/image_picker_for_web/pubspec.yaml index e54fde03b75..85567a58209 100644 --- a/packages/image_picker/image_picker_for_web/pubspec.yaml +++ b/packages/image_picker/image_picker_for_web/pubspec.yaml @@ -23,7 +23,7 @@ dependencies: sdk: flutter image_picker_platform_interface: ^2.9.0 mime: ^1.0.4 - web: ^0.5.0 + web: ^0.5.1 dev_dependencies: flutter_test: From a6016b0fc5d53ccfafbb39aa2384ea929139a3f2 Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 5 Mar 2024 19:16:01 -0800 Subject: [PATCH 32/35] Add web 0.6.0 note and link to PR. --- .../example/integration_test/image_picker_for_web_test.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 4c80dd23d0c..71db951a8df 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -16,8 +16,10 @@ const String expectedStringContents = 'Hello, world!'; const String otherStringContents = 'Hello again, world!'; final Uint8List bytes = const Utf8Encoder().convert(expectedStringContents); final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); +// TODO(dit): When web:0.6.0 lands, move `type` to the [web.FilePropertyBag] constructor. +// See: https://github.com/dart-lang/web/pull/197 final web.FilePropertyBag options = web.FilePropertyBag( - lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch) + lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch,) ..type = 'text/plain'; final web.File textFile = From 516f98c0a0015f4bd39d133eba2a00cbcbe33d7c Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 5 Mar 2024 19:17:53 -0800 Subject: [PATCH 33/35] dart format . --- .../example/integration_test/image_picker_for_web_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart index 71db951a8df..a467a189537 100644 --- a/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart +++ b/packages/image_picker/image_picker_for_web/example/integration_test/image_picker_for_web_test.dart @@ -19,8 +19,8 @@ final Uint8List otherBytes = const Utf8Encoder().convert(otherStringContents); // TODO(dit): When web:0.6.0 lands, move `type` to the [web.FilePropertyBag] constructor. // See: https://github.com/dart-lang/web/pull/197 final web.FilePropertyBag options = web.FilePropertyBag( - lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch,) - ..type = 'text/plain'; + lastModified: DateTime.utc(2017, 12, 13).millisecondsSinceEpoch, +)..type = 'text/plain'; final web.File textFile = web.File([bytes.toJS].toJS, 'hello.txt', options); From e569aa7a2bfd9061136a9c00d6943718229ec6aa Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 5 Mar 2024 19:45:05 -0800 Subject: [PATCH 34/35] Doc tweaks. PR comments. --- .../lib/image_picker_for_web.dart | 8 ++--- .../lib/src/image_resizer.dart | 36 ++++++++++++------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 749b5c61c36..743e5fea99e 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -157,7 +157,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { accept, capture, multiple: multiple, - ) as web.HTMLInputElement; + ); _injectAndActivate(input); return _getSelectedXFiles(input).whenComplete(() { @@ -295,7 +295,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Creates an input element that accepts certain file types, and /// allows to `capture` from the device's cameras (where supported) @visibleForTesting - web.Element createInputElement( + web.HTMLInputElement createInputElement( String? accept, String? capture, { bool multiple = false, @@ -331,7 +331,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { // Some tools to override behavior for unit-testing /// A function that creates a file input with the passed in `accept` and `capture` attributes. @visibleForTesting -typedef OverrideCreateInputFunction = web.Element Function( +typedef OverrideCreateInputFunction = web.HTMLInputElement Function( String? accept, String? capture, ); @@ -339,7 +339,7 @@ typedef OverrideCreateInputFunction = web.Element Function( /// A function that extracts list of files from the file `input` passed in. @visibleForTesting typedef OverrideExtractMultipleFilesFromInputFunction = List Function( - web.Element? input); + web.HTMLInputElement? input); /// Overrides for some of the functionality above. @visibleForTesting diff --git a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart index f1a6c9a12a0..7b32a451b67 100644 --- a/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart +++ b/packages/image_picker/image_picker_for_web/lib/src/image_resizer.dart @@ -16,9 +16,14 @@ import 'image_resizer_utils.dart'; /// Helper class that resizes images. class ImageResizer { /// Resizes the image if needed. + /// /// (Does not support gif images) - Future resizeImageIfNeeded(XFile file, double? maxWidth, - double? maxHeight, int? imageQuality) async { + Future resizeImageIfNeeded( + XFile file, + double? maxWidth, + double? maxHeight, + int? imageQuality, + ) async { if (!imageResizeNeeded(maxWidth, maxHeight, imageQuality) || file.mimeType == 'image/gif') { // Implement maxWidth and maxHeight for image/gif @@ -37,7 +42,7 @@ class ImageResizer { } } - /// function that loads the blobUrl into an imageElement + /// Loads the `blobUrl` into a [web.HTMLImageElement]. Future loadImage(String blobUrl) { final Completer imageLoadCompleter = Completer(); @@ -45,20 +50,23 @@ class ImageResizer { imageElement // ignore: unsafe_html ..src = blobUrl - ..onload = (web.Event event) { + ..onLoad.listen((web.Event event) { imageLoadCompleter.complete(imageElement); - }.toJS - ..onerror = (web.Event event) { + }) + ..onError.listen((web.Event event) { const String exception = 'Error while loading image.'; imageElement.remove(); imageLoadCompleter.completeError(exception); - }.toJS; + }); return imageLoadCompleter.future; } - /// Draws image to a canvas while resizing the image to fit the [maxWidth],[maxHeight] constraints + /// Resizing the image in a canvas to fit the [maxWidth], [maxHeight] constraints. web.HTMLCanvasElement resizeImageElement( - web.HTMLImageElement source, double? maxWidth, double? maxHeight) { + web.HTMLImageElement source, + double? maxWidth, + double? maxHeight, + ) { final Size newImageSize = calculateSizeOfDownScaledImage( Size(source.width.toDouble(), source.height.toDouble()), maxWidth, @@ -76,10 +84,14 @@ class ImageResizer { return canvas; } - /// function that converts a canvas element to Xfile + /// Converts a canvas element to [XFile]. + /// /// [imageQuality] is only supported for jpeg and webp images. - Future writeCanvasToFile(XFile originalFile, - web.HTMLCanvasElement canvas, int? imageQuality) async { + Future writeCanvasToFile( + XFile originalFile, + web.HTMLCanvasElement canvas, + int? imageQuality, + ) async { final double calculatedImageQuality = (min(imageQuality ?? 100, 100)) / 100.0; final Completer completer = Completer(); From ebe0e6a0aede7def199975aa85f9bad1ab8edb3b Mon Sep 17 00:00:00 2001 From: David Iglesias Teixeira Date: Tue, 5 Mar 2024 20:07:07 -0800 Subject: [PATCH 35/35] Link to dart-lang issue --- .../image_picker_for_web/lib/image_picker_for_web.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart index 743e5fea99e..0241e0750a7 100644 --- a/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart +++ b/packages/image_picker/image_picker_for_web/lib/image_picker_for_web.dart @@ -247,6 +247,8 @@ class ImagePickerPlugin extends ImagePickerPlatform { /// Monitors an and returns the selected file(s). Future> _getSelectedXFiles(web.HTMLInputElement input) { final Completer> completer = Completer>(); + // TODO(dit): Migrate all this to Streams (onChange, onError, onCancel) when onCancel is available. + // See: https://github.com/dart-lang/web/issues/199 // Observe the input until we can return something input.onchange = (web.Event event) { final List? files = _handleOnChangeEvent(event); @@ -264,6 +266,7 @@ class ImagePickerPlugin extends ImagePickerPlatform { }).toList()); } }.toJS; + input.oncancel = (web.Event _) { completer.complete([]); }.toJS;