Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/file_selector/file_selector_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.3

* Updates minimum supported SDK version to Dart 3.2.

## 0.9.2+1

* Adds pub topics to package metadata.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html';
import 'dart:js_interop';

import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
import 'package:file_selector_web/src/dom_helper.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:web/helpers.dart';

void main() {
group('dom_helper', () {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
late DomHelper domHelper;
late FileUploadInputElement input;
late HTMLInputElement input;

FileList? createFileList(List<File> files) {
final DataTransfer dataTransfer = DataTransfer();
files.forEach(dataTransfer.items!.add);
return dataTransfer.files as FileList?;
for (final File e in files) {
// TODO(srujzs): This is necessary in order to support package:web 0.4.0.
// This was not needed with 0.3.0, hence the lint.
// ignore: unnecessary_cast
dataTransfer.items.add(e as JSAny);
}
return dataTransfer.files;
}

void setFilesAndTriggerEvent(List<File> files, Event event) {
Expand All @@ -36,12 +42,13 @@ void main() {

setUp(() {
domHelper = DomHelper();
input = FileUploadInputElement();
input = (createElementTag('input') as HTMLInputElement)..type = 'file';
});

group('getFiles', () {
final File mockFile1 = File(<Object>['123456'], 'file1.txt');
final File mockFile2 = File(<Object>[], 'file2.txt');
final File mockFile1 =
File(<Object>['123456'].jsify as JSArray, 'file1.txt');
final File mockFile2 = File(<Object>[].jsify as JSArray, 'file2.txt');

testWidgets('works', (_) async {
final Future<List<XFile>> futureFiles = domHelper.getFiles(
Expand Down Expand Up @@ -114,7 +121,7 @@ void main() {
input: input,
);

expect(input.matchesWithAncestors('body'), true);
expect(input.matches('body'), true);
expect(input.accept, accept);
expect(input.multiple, multiple);
expect(
Expand All @@ -128,7 +135,7 @@ void main() {
await futureFile;

// It should be already removed from the DOM after the file is resolved.
expect(input.parent, isNull);
expect(input.parentElement, isNull);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html';
import 'dart:typed_data';

import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
import 'package:file_selector_web/file_selector_web.dart';
import 'package:file_selector_web/src/dom_helper.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:web/helpers.dart';

void main() {
group('FileSelectorWeb', () {
Expand Down Expand Up @@ -121,7 +121,7 @@ class MockDomHelper implements DomHelper {
Future<List<XFile>> getFiles({
String accept = '',
bool multiple = false,
FileUploadInputElement? input,
HTMLInputElement? input,
}) {
expect(accept, _expectedAccept,
reason: 'Expected "accept" value does not match.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies:
path: ../
flutter:
sdk: flutter
web: '>=0.3.0 <0.5.0'

dev_dependencies:
flutter_test:
Expand Down
42 changes: 26 additions & 16 deletions packages/file_selector/file_selector_web/lib/src/dom_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,46 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:html';
import 'dart:js_interop';

import 'package:file_selector_platform_interface/file_selector_platform_interface.dart';
import 'package:flutter/foundation.dart' show visibleForTesting;
import 'package:flutter/services.dart';
import 'package:web/helpers.dart';

/// Class to manipulate the DOM with the intention of reading files from it.
class DomHelper {
/// Default constructor, initializes the container DOM element.
DomHelper() {
final Element body = querySelector('body')!;
body.children.add(_container);
body.appendChild(_container);
}

final Element _container = Element.tag('file-selector');
final Element _container = createElementTag('file-selector');

/// Sets the <input /> attributes and waits for a file to be selected.
Future<List<XFile>> getFiles({
String accept = '',
bool multiple = false,
@visibleForTesting FileUploadInputElement? input,
@visibleForTesting HTMLInputElement? input,
}) {
final Completer<List<XFile>> completer = Completer<List<XFile>>();
final FileUploadInputElement inputElement =
input ?? FileUploadInputElement();
final HTMLInputElement inputElement =
input ?? (createElementTag('input') as HTMLInputElement)
..type = 'file';

_container.children.add(
_container.appendChild(
inputElement
..accept = accept
..multiple = multiple,
);

inputElement.onChange.first.then((_) {
final List<XFile> files =
inputElement.files!.map(_convertFileToXFile).toList();
final List<XFile> files = Iterable<File>.generate(
inputElement.files!.length,
(int i) => inputElement.files!.item(i)!)
.map(_convertFileToXFile)
.toList();
inputElement.remove();
completer.complete(files);
});
Expand All @@ -52,10 +57,13 @@ class DomHelper {
completer.completeError(platformException);
});

inputElement.addEventListener('cancel', (Event event) {
inputElement.remove();
completer.complete(<XFile>[]);
});
inputElement.addEventListener(
'cancel',
(Event event) {
inputElement.remove();
completer.complete(<XFile>[]);
}.toJS,
);

// TODO(dit): Reimplement this with the showPicker() API, https://github.com/flutter/flutter/issues/130365
inputElement.click();
Expand All @@ -64,10 +72,12 @@ class DomHelper {
}

XFile _convertFileToXFile(File file) => XFile(
Url.createObjectUrl(file),
// TODO(srujzs): This is necessary in order to support package:web 0.4.0.
// This was not needed with 0.3.0, hence the lint.
// ignore: unnecessary_cast
URL.createObjectURL(file as JSObject),
name: file.name,
length: file.size,
lastModified: DateTime.fromMillisecondsSinceEpoch(
file.lastModified ?? DateTime.now().millisecondsSinceEpoch),
lastModified: DateTime.fromMillisecondsSinceEpoch(file.lastModified),
);
}
7 changes: 4 additions & 3 deletions packages/file_selector/file_selector_web/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: file_selector_web
description: Web platform implementation of file_selector
repository: https://github.com/flutter/packages/tree/main/packages/file_selector/file_selector_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+file_selector%22
version: 0.9.2+1
version: 0.9.3

environment:
sdk: ">=2.19.0 <4.0.0"
flutter: ">=3.7.0"
sdk: ^3.2.0
flutter: ">=3.16.0"

flutter:
plugin:
Expand All @@ -22,6 +22,7 @@ dependencies:
sdk: flutter
flutter_web_plugins:
sdk: flutter
web: '>=0.3.0 <0.5.0'

dev_dependencies:
flutter_test:
Expand Down
4 changes: 4 additions & 0 deletions packages/url_launcher/url_launcher_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.2.1

* Updates minimum supported SDK version to Dart 3.2.

## 2.2.0

* Implements `supportsMode` and `supportsCloseForMode`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html' as html;

import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';
import 'package:url_launcher_web/url_launcher_web.dart';
import 'package:web/web.dart' as html;

import 'url_launcher_web_test.mocks.dart';

Expand All @@ -29,7 +28,7 @@ void main() {
when(mockWindow.navigator).thenReturn(mockNavigator);

// Simulate that window.open does something.
when(mockWindow.open(any, any, any)).thenReturn(MockWindow());
when(mockWindow.open('any', 'any')).thenReturn(MockWindow());

when(mockNavigator.userAgent).thenReturn(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
Expand Down
Loading