blob: 2e9771b50f7228a32e7871714cb7ffdf3417d6f5 [file] [log] [blame]
// Copyright 2014 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 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'image_provider.dart' as image_provider;
import 'image_stream.dart';
/// The dart:html implementation of [image_provider.NetworkImage].
/// NetworkImage on the web does not support decoding to a specified size.
class NetworkImage
extends image_provider.ImageProvider<image_provider.NetworkImage>
implements image_provider.NetworkImage {
/// Creates an object that fetches the image at the given URL.
/// The arguments [url] and [scale] must not be null.
const NetworkImage(this.url, {this.scale = 1.0, this.headers})
: assert(url != null),
assert(scale != null);
final String url;
final double scale;
final Map<String, String> headers;
Future<NetworkImage> obtainKey(
image_provider.ImageConfiguration configuration) {
return SynchronousFuture<NetworkImage>(this);
ImageStreamCompleter load(
image_provider.NetworkImage key, image_provider.DecoderCallback decode) {
// Ownership of this controller is handed off to [_loadAsync]; it is that
// method's responsibility to close the controller's stream when the image
// has been loaded or an error is thrown.
final StreamController<ImageChunkEvent> chunkEvents =
return MultiFrameImageStreamCompleter(
codec: _loadAsync(key as NetworkImage, decode, chunkEvents),
scale: key.scale,
informationCollector: _imageStreamInformationCollector(key));
InformationCollector _imageStreamInformationCollector(
image_provider.NetworkImage key) {
InformationCollector collector;
assert(() {
collector = () {
return <DiagnosticsNode>[
'Image provider', this),
DiagnosticsProperty<NetworkImage>('Image key', key as NetworkImage),
return true;
return collector;
// TODO(garyq): We should eventually support custom decoding of network images on Web as
// well, see
// Web does not support decoding network images to a specified size. The decode parameter
// here is ignored and the web-only `ui.webOnlyInstantiateImageCodecFromUrl` will be used
// directly in place of the typical `instantiateImageCodec` method.
Future<ui.Codec> _loadAsync(
NetworkImage key,
image_provider.DecoderCallback decode,
StreamController<ImageChunkEvent> chunkEvents) {
assert(key == this);
final Uri resolved = Uri.base.resolve(key.url);
// This API only exists in the web engine implementation and is not
// contained in the analyzer summary for Flutter.
return ui.webOnlyInstantiateImageCodecFromUrl(resolved, // ignore: undefined_function
chunkCallback: (int bytes, int total) {
cumulativeBytesLoaded: bytes, expectedTotalBytes: total));
}) as Future<ui.Codec>; // ignore: undefined_function
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
return other is NetworkImage && other.url == url && other.scale == scale;
int get hashCode => ui.hashValues(url, scale);
String toString() =>
'${objectRuntimeType(this, 'NetworkImage')}("$url", scale: $scale)';