mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 21:54:47 +08:00
R=aerotwist@chromium.org Bug: chromium:1101738 Change-Id: Ieb5134f468e0679d5e559287469998c99a2d9818 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2317311 Commit-Queue: Simon Zünd <szuend@chromium.org> Reviewed-by: Paul Lewis <aerotwist@chromium.org>
126 lines
4.4 KiB
JavaScript
126 lines
4.4 KiB
JavaScript
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||
// Use of this source code is governed by a BSD-style license that can be
|
||
// found in the LICENSE file.
|
||
|
||
// @ts-nocheck
|
||
// TODO(crbug.com/1011811): Enable TypeScript compiler checks
|
||
|
||
import * as Common from '../common/common.js';
|
||
import * as Platform from '../platform/platform.js';
|
||
import * as UI from '../ui/ui.js';
|
||
|
||
export class ImagePreview {
|
||
/**
|
||
* @param {!SDK.Target} target
|
||
* @param {string} originalImageURL
|
||
* @param {boolean} showDimensions
|
||
* @param {!{precomputedFeatures: (!Object|undefined), imageAltText: (string|undefined)}=} options
|
||
* @return {!Promise<?Element>}
|
||
*/
|
||
static build(target, originalImageURL, showDimensions, options = {}) {
|
||
const {precomputedFeatures, imageAltText} = options;
|
||
const resourceTreeModel = target.model(SDK.ResourceTreeModel);
|
||
if (!resourceTreeModel) {
|
||
return Promise.resolve(/** @type {?Element} */ (null));
|
||
}
|
||
let resource = resourceTreeModel.resourceForURL(originalImageURL);
|
||
let imageURL = originalImageURL;
|
||
if (!isImageResource(resource) && precomputedFeatures && precomputedFeatures.currentSrc) {
|
||
imageURL = precomputedFeatures.currentSrc;
|
||
resource = resourceTreeModel.resourceForURL(imageURL);
|
||
}
|
||
if (!isImageResource(resource)) {
|
||
return Promise.resolve(/** @type {?Element} */ (null));
|
||
}
|
||
|
||
let fulfill;
|
||
const promise = new Promise(x => {
|
||
fulfill = x;
|
||
});
|
||
const imageElement = createElement('img');
|
||
imageElement.addEventListener('load', buildContent, false);
|
||
imageElement.addEventListener('error', () => fulfill(null), false);
|
||
if (imageAltText) {
|
||
imageElement.alt = imageAltText;
|
||
}
|
||
resource.populateImageSource(imageElement);
|
||
return promise;
|
||
|
||
/**
|
||
* @param {?SDK.Resource} resource
|
||
* @return {boolean}
|
||
*/
|
||
function isImageResource(resource) {
|
||
return !!resource && resource.resourceType() === Common.ResourceType.resourceTypes.Image;
|
||
}
|
||
|
||
function buildContent() {
|
||
const container = createElement('table');
|
||
UI.Utils.appendStyle(container, 'components/imagePreview.css');
|
||
container.className = 'image-preview-container';
|
||
const intrinsicWidth = imageElement.naturalWidth;
|
||
const intrinsicHeight = imageElement.naturalHeight;
|
||
const renderedWidth = precomputedFeatures ? precomputedFeatures.renderedWidth : intrinsicWidth;
|
||
const renderedHeight = precomputedFeatures ? precomputedFeatures.renderedHeight : intrinsicHeight;
|
||
let description;
|
||
if (showDimensions) {
|
||
if (renderedHeight !== intrinsicHeight || renderedWidth !== intrinsicWidth) {
|
||
description = ls`${renderedWidth} × ${renderedHeight} pixels (intrinsic: ${intrinsicWidth} × ${
|
||
intrinsicHeight} pixels)`;
|
||
} else {
|
||
description = ls`${renderedWidth} × ${renderedHeight} pixels`;
|
||
}
|
||
}
|
||
|
||
container.createChild('tr').createChild('td', 'image-container').appendChild(imageElement);
|
||
if (description) {
|
||
container.createChild('tr').createChild('td').createChild('span', 'description').textContent = description;
|
||
}
|
||
if (imageURL !== originalImageURL) {
|
||
container.createChild('tr').createChild('td').createChild('span', 'description').textContent =
|
||
Platform.StringUtilities.sprintf('currentSrc: %s', imageURL.trimMiddle(100));
|
||
}
|
||
fulfill(container);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param {!SDK.DOMNode} node
|
||
* @return {!Promise<!Object|undefined>}
|
||
*/
|
||
static async loadDimensionsForNode(node) {
|
||
if (!node.nodeName() || node.nodeName().toLowerCase() !== 'img') {
|
||
return;
|
||
}
|
||
|
||
const object = await node.resolveToObject('');
|
||
|
||
if (!object) {
|
||
return;
|
||
}
|
||
|
||
const featuresObject = object.callFunctionJSON(features, undefined);
|
||
object.release();
|
||
return featuresObject;
|
||
|
||
/**
|
||
* @return {!{renderedWidth: number, renderedHeight: number, currentSrc: (string|undefined)}}
|
||
* @suppressReceiverCheck
|
||
* @this {!Element}
|
||
*/
|
||
function features() {
|
||
return {renderedWidth: this.width, renderedHeight: this.height, currentSrc: this.currentSrc};
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @param {string} url
|
||
* @return {string}
|
||
*/
|
||
static defaultAltTextForImageURL(url) {
|
||
const parsedImageURL = new Common.ParsedURL.ParsedURL(url);
|
||
const imageSourceText = parsedImageURL.isValid ? parsedImageURL.displayName : ls`unknown source`;
|
||
return ls`Image from ${imageSourceText}`;
|
||
}
|
||
}
|