Files
react-native-devtools-frontend/front_end/components/ImagePreview.js
T
Erik Luo 76fe06cff6 DevTools: report correct image sizes in popover
Instead of showing offset, naturalW/H in image preview popover,
- Rendered size: better than 'offset', which includes unwanted
  padding, border.
- Intrinsic size: based on the natural size when loaded by DevTools
  without any density descriptor, also the original resource size.

OffsetW/H is no longer shown, but info available in the box model
and overlay highlight.

Bug: 788114, 801218
Change-Id: I6ec08c5bcd62c0cb3d8815a1d7079cccb022ef5d
Reviewed-on: https://chromium-review.googlesource.com/c/1256072
Reviewed-by: Andrey Lushnikov <lushnikov@chromium.org>
Commit-Queue: Erik Luo <luoe@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#597404}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: a73757aba48e30c90833b13576c15fba83c90f77
2018-10-06 03:42:35 +00:00

95 lines
3.6 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.
Components.ImagePreview = class {
/**
* @param {!SDK.Target} target
* @param {string} originalImageURL
* @param {boolean} showDimensions
* @param {!Object=} precomputedFeatures
* @return {!Promise<?Element>}
*/
static build(target, originalImageURL, showDimensions, precomputedFeatures) {
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);
resource.populateImageSource(imageElement);
return promise;
/**
* @param {?SDK.Resource} resource
* @return {boolean}
*/
function isImageResource(resource) {
return !!resource && resource.resourceType() === Common.resourceTypes.Image;
}
function buildContent() {
const container = createElement('table');
UI.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) {
description = ls`${renderedWidth} \xd7 ${renderedHeight} pixels`;
if (renderedHeight !== intrinsicHeight || renderedWidth !== intrinsicWidth)
description += ls` (intrinsic: ${intrinsicWidth} \xd7 ${intrinsicHeight} 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 =
String.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};
}
}
};