Skip to content

Commit

Permalink
fix `Cannot read property 'width' of undefined, preview pictures are …
Browse files Browse the repository at this point in the history
…not displayed` (close DevExpress#1959)
  • Loading branch information
LavrovArtem committed Jul 22, 2019
1 parent 239c29a commit 77c6fca
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 32 deletions.
24 changes: 16 additions & 8 deletions src/client/sandbox/node/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { ATTRS_WITH_SPECIAL_PROXYING_LOGIC } from '../../../processing/dom/attri
import settings from '../../settings';
import { overrideDescriptor } from '../../utils/property-overriding';
import InsertPosition from '../../utils/insert-position';
import { isFirefox } from '../../utils/browser';

const KEYWORD_TARGETS = ['_blank', '_self', '_parent', '_top'];

Expand Down Expand Up @@ -83,17 +84,18 @@ export default class ElementSandbox extends SandboxBase {
}

static _setProxiedSrc (img) {
if (!img[INTERNAL_PROPS.forceProxySrcForImage]) {
const imgSrc = nativeMethods.imageSrcGetter.call(img);
const skipNextLoadEvent = !!imgSrc && img.complete;
if (img[INTERNAL_PROPS.forceProxySrcForImage])
return;

img[INTERNAL_PROPS.forceProxySrcForImage] = true;
const imgSrc = nativeMethods.imageSrcGetter.call(img);
const skipNextLoadEvent = !!imgSrc && img.complete && !img[INTERNAL_PROPS.cachedImage];

if (imgSrc)
img.setAttribute('src', imgSrc);
img[INTERNAL_PROPS.forceProxySrcForImage] = true;

img[INTERNAL_PROPS.skipNextLoadEventForImage] = skipNextLoadEvent;
}
if (imgSrc)
img.setAttribute('src', imgSrc);

img[INTERNAL_PROPS.skipNextLoadEventForImage] = skipNextLoadEvent;
}

getAttributeCore (el, args, isNs?: boolean) {
Expand Down Expand Up @@ -317,6 +319,9 @@ export default class ElementSandbox extends SandboxBase {

const result = setAttrMeth.apply(el, args);

if (tagName === 'img' && !el[INTERNAL_PROPS.forceProxySrcForImage] && el.complete && !isFirefox)
el[INTERNAL_PROPS.cachedImage] = true;

if (needToCallTargetChanged)
ElementSandbox._onTargetChanged(el);

Expand Down Expand Up @@ -894,6 +899,9 @@ export default class ElementSandbox extends SandboxBase {
case 'img':
this.eventSandbox.listeners.initElementListening(el, ['load']);
this.eventSandbox.listeners.addInternalEventListener(el, ['load'], (_e, _dispatched, preventEvent, _cancelHandlers, stopEventPropagation) => {
if (el[INTERNAL_PROPS.cachedImage])
el[INTERNAL_PROPS.cachedImage] = false;

if (!el[INTERNAL_PROPS.skipNextLoadEventForImage])
return;

Expand Down
3 changes: 2 additions & 1 deletion src/processing/dom/internal-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export default {
selection: 'hammerhead|selection',
shadowUIElement: 'hammerhead|shadow-ui-element',
forceProxySrcForImage: 'hammerhead|image|force-proxy-src-flag',
skipNextLoadEventForImage: 'hammerhead|image|skip-next-load-event-flag'
skipNextLoadEventForImage: 'hammerhead|image|skip-next-load-event-flag',
cachedImage: 'hammerhead|image|cached-image'
};
33 changes: 14 additions & 19 deletions test/client/config-qunit-server-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,26 +183,21 @@ module.exports = function (app) {
app.get('/:url', iframeLocationUrlCallback);

app.get('/image.png', function (req, res) {
var promise = null;
var image = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUA' +
'AAAJcEhZcwAADsMAAA7DAcdvqGQAAAAMSURBVBhXY9j6TBYABAwBuZFzS6sAAAAASUVORK5CYII=', 'base64');

if (req.query.timeout) {
promise = new Promise(function (resolve) {
setTimeout(resolve, req.query.timeout);
});
}
else
promise = Promise.resolve();

promise
.then(function () {
res
.set('content-type', 'image/png')
.set('cache-control', 'no-cache, no-store, must-revalidate')
.set('pragma', 'no-cache')
.send(Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0I' +
'Ars4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqG' +
'QAAAAMSURBVBhXY9j6TBYABAwBuZFzS6sAAAAASUVORK5CYII=', 'base64'));
});
setTimeout(function () {
res.set('content-type', 'image/png');

if (!req.query.expires) {
res.set('cache-control', 'no-cache, no-store, must-revalidate');
res.set('pragma', 'no-cache');
}
else
res.set('expires', req.query.expires);

res.send(image);
}, req.query.timeout || 0);
});

app.get('/destroy-connection', function (req, res) {
Expand Down
31 changes: 27 additions & 4 deletions test/client/fixtures/sandbox/node/dom-processor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ test('add element with `formaction` tag to the form', function () {

module('should create a proxy url for the img src attribute if the image has the load handler (GH-651)', function () {
module('onload property', function () {
var origin = location.origin || location.protocol + location.host;

test('attach the load handler before setting up the src', function () {
var img = document.createElement('img');
var imgUrl = window.QUnitGlobals.getResourceUrl('../../../data/node-sandbox/image.png');
Expand Down Expand Up @@ -367,7 +369,7 @@ module('should create a proxy url for the img src attribute if the image has the

destLocation.forceLocation('http://localhost/sessionId/' + location.origin);

img.src = 'http://localhost:2000/image.png?rand=' + Math.random() + '&timeout=0';
img.src = origin + '/image.png?rand=' + Math.random() + '&timeout=0';

nativeMethods.htmlElementOnloadSetter.call(img, function () {
var onloadHandlerCalled = false;
Expand Down Expand Up @@ -395,7 +397,7 @@ module('should create a proxy url for the img src attribute if the image has the

destLocation.forceLocation('http://localhost/sessionId/' + location.origin);

img.src = 'http://localhost:2000/image.png?rand=' + Math.random() + '&timeout=300';
img.src = origin + '/image.png?rand=' + Math.random() + '&timeout=300';
img.onload = function () {
ok(true);
destLocation.forceLocation(storedForcedLocation);
Expand All @@ -409,7 +411,7 @@ module('should create a proxy url for the img src attribute if the image has the

destLocation.forceLocation('http://localhost/sessionId/' + location.origin);

img.src = 'http://localhost:2000/image.png?rand=' + Math.random() + '&timeout=0';
img.src = origin + '/image.png?rand=' + Math.random() + '&timeout=0';

nativeMethods.htmlElementOnloadSetter.call(img, function () {
img.onload = function () {
Expand All @@ -419,7 +421,28 @@ module('should create a proxy url for the img src attribute if the image has the
start();
};

img.src = 'http://localhost:2000/image.png?rand=' + Math.random() + '&timeout=0';
img.src = origin + '/image.png?rand=' + Math.random() + '&timeout=0';
});
});

asyncTest('attach the load handler after setting up the cached src(image is loaded, but load event is not emitted) (GH-1959)', function () {
var img = document.createElement('img');
var imgSrc = origin + '/image.png?rand=' + Math.random() + '&timeout=0&expires=' +
new Date(Date.now() + 1e6).toUTCString();
var storedForcedLocation = destLocation.getLocation();

destLocation.forceLocation('http://localhost/sessionId/' + location.origin);

img.src = imgSrc;
nativeMethods.htmlElementOnloadSetter.call(img, function () {
var anotherImg = document.createElement('img');

anotherImg.src = imgSrc;
anotherImg.onload = function () {
ok(true);
destLocation.forceLocation(storedForcedLocation);
start();
};
});
});
});
Expand Down

0 comments on commit 77c6fca

Please sign in to comment.