Navaron Bracke

lift the video element creation out of the barcode reader; add length check for children removal

... ... @@ -114,11 +114,11 @@ abstract class BarcodeReader {
/// Start the barcode reader and initialize the [videoStream].
///
/// The [options] are used to configure the barcode reader.
/// The [containerElement] will become the parent of the video output element.
/// The [videoElement] will become the video output element.
/// The [videoStream] is the input for the barcode reader and video preview element.
Future<void> start(
StartOptions options, {
required HTMLElement containerElement,
required HTMLVideoElement videoElement,
required MediaStream videoStream,
}) {
throw UnimplementedError('start() has not been implemented.');
... ...
... ... @@ -242,7 +242,7 @@ class MobileScannerWeb extends MobileScannerPlatform {
await _barcodeReader.start(
startOptions,
containerElement: _divElement!,
videoElement: videoElement,
videoStream: videoStream,
);
} catch (error, stackTrace) {
... ... @@ -321,7 +321,9 @@ class MobileScannerWeb extends MobileScannerPlatform {
try {
final HTMLCollection? divChildren = _divElement?.children;
if (divChildren != null) {
// Since the exact element is unknown, remove all children.
// In practice, there should only be one child, the single video element.
if (divChildren != null && divChildren.length > 0) {
for (int i = 0; i < divChildren.length; i++) {
final Node? child = divChildren.item(i);
... ...
... ... @@ -107,17 +107,13 @@ final class ZXingBarcodeReader extends BarcodeReader {
/// Prepare the video element for the barcode reader.
///
/// The given [videoElement] is attached to the DOM, by attaching it to the [containerElement].
/// The given [videoElement] is assumed to already be attached to the DOM at this point.
/// The camera video output is then attached to both the barcode reader (to detect barcodes),
/// and the video element (to display the camera output).
Future<void> _prepareVideoElement(
web.HTMLVideoElement videoElement, {
required web.MediaStream videoStream,
required web.HTMLElement containerElement,
}) async {
// Attach the video element to the DOM, through its parent container.
containerElement.appendChild(videoElement);
web.HTMLVideoElement videoElement,
web.MediaStream videoStream,
) async {
final JSPromise? result = _reader?.attachStreamToVideo.callAsFunction(
_reader as JSAny?,
videoStream as JSAny,
... ... @@ -216,7 +212,7 @@ final class ZXingBarcodeReader extends BarcodeReader {
@override
Future<void> start(
StartOptions options, {
required web.HTMLElement containerElement,
required web.HTMLVideoElement videoElement,
required web.MediaStream videoStream,
}) async {
final int detectionTimeoutMs = options.detectionTimeoutMs;
... ... @@ -231,14 +227,7 @@ final class ZXingBarcodeReader extends BarcodeReader {
detectionTimeoutMs.toJS,
);
final web.HTMLVideoElement videoElement =
web.document.createElement('video') as web.HTMLVideoElement;
await _prepareVideoElement(
videoElement,
videoStream: videoStream,
containerElement: containerElement,
);
await _prepareVideoElement(videoElement, videoStream);
}
@override
... ...