Skip to content

Commit

Permalink
[todomvc] Browser hangs on the Angular2 demo page opening (close DevE…
Browse files Browse the repository at this point in the history
  • Loading branch information
churkin authored and AlexanderMoskovkin committed Nov 14, 2016
1 parent ced5330 commit 3d567d1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
42 changes: 27 additions & 15 deletions src/client/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { isFirefox, isWebKit, isIE, version as browserVersion } from './browser'
import trim from '../../utils/string-trim';
import getNativeQuerySelectorAll from './get-native-query-selector-all';

const NATIVE_METHOD_REG_EX = /^\s*function\s[\s\S]+()\s*\{\s*\[native\scode\]\s*\}\s*$/;

// NOTE: We should avoid using native object prototype methods,
// since they can be overriden by the client code. (GH-245)
var arraySlice = Array.prototype.slice;
Expand Down Expand Up @@ -79,6 +81,13 @@ function hasClassFallback (el, className) {
return preparedElementClassName.indexOf(className) !== -1;
}

function nativeToString (obj) {
if (obj && obj.toString && typeof obj.toString === 'function' && NATIVE_METHOD_REG_EX.test(obj.toString.toString()))
return obj.toString();

return '';
}

export function getActiveElement (currentDocument) {
// NOTE: Sometimes document.activeElement returns an empty object or null (IE11).
// https://github.com/DevExpress/testcafe-hammerhead/issues/768
Expand Down Expand Up @@ -303,8 +312,7 @@ export function isDomElement (el) {
return true;

// NOTE: T184805
if (el && typeof el.toString === 'function' && el.toString.toString().indexOf('[native code]') !== -1 &&
el.constructor &&
if (el && nativeToString(el) && el.constructor &&
(el.constructor.toString().indexOf(' Element') !== -1 || el.constructor.toString().indexOf(' Node') !== -1))
return false;

Expand Down Expand Up @@ -366,9 +374,10 @@ export function isIframeWithoutSrc (iframe) {
// NOTE: In IE, after document.open is called for a same-domain iframe or an iframe with a javascript src,
// the iframe window location becomes equal to the location of the parent window with src.
var parsedIframeSrcLocation = urlUtils.isSupportedProtocol(iframeSrcLocation) ? urlUtils.parseUrl(iframeSrcLocation)
: null;
: null;

if (parsedIframeSrcLocation && parsedIframeSrcLocation.partAfterHost && iframeDocumentLocation === parentWindowLocation)
if (parsedIframeSrcLocation && parsedIframeSrcLocation.partAfterHost &&
iframeDocumentLocation === parentWindowLocation)
return false;

return iframeDocumentLocation === parentWindowLocation;
Expand Down Expand Up @@ -515,8 +524,10 @@ export function isWindow (instance) {
return true;

try {
return instance && typeof instance === 'object' && instance.top !== void 0 && instance.toString &&
(instance.toString() === '[object Window]' || instance.toString() === '[object global]');
var str = nativeToString(instance);

return instance && typeof instance === 'object' && instance.top !== void 0 &&
(str === '[object Window]' || str === '[object global]');
}
catch (e) {
// NOTE: If a cross-domain object has the 'top' field, this object is a window
Expand All @@ -530,8 +541,10 @@ export function isDocument (instance) {
return true;

try {
return instance && typeof instance === 'object' && instance.toString &&
(instance.toString() === '[object HTMLDocument]' || instance.toString() === '[object Document]');
var str = nativeToString(instance);

return instance && typeof instance === 'object' &&
(str === '[object HTMLDocument]' || str === '[object Document]');
}
catch (e) {
// NOTE: For cross-domain objects (windows, documents or locations), we return false because
Expand All @@ -542,13 +555,12 @@ export function isDocument (instance) {

export function isXMLHttpRequest (instance) {
return instance && (instance instanceof XMLHttpRequest ||
typeof instance === 'object' && instance.toString &&
instance.toString() === '[object XMLHttpRequest]');
typeof instance === 'object' && nativeToString(instance) === '[object XMLHttpRequest]');
}

export function isBlob (instance) {
return instance && typeof instance === 'object' && typeof instance.slice === 'function' &&
instance.toString && instance.toString() === '[object Blob]';
nativeToString(instance) === '[object Blob]';
}

export function isLocation (instance) {
Expand All @@ -568,8 +580,8 @@ export function isSVGElement (instance) {
if (instance instanceof nativeMethods.svgElementClass)
return true;

return instance && typeof instance === 'object' && instance.ownerSVGElement !== void 0 && instance.toString &&
instance.toString().toLowerCase() === '[object svg' + getTagName(instance) + 'element]';
return instance && typeof instance === 'object' && instance.ownerSVGElement !== void 0 &&
nativeToString(instance).toLowerCase() === '[object svg' + getTagName(instance) + 'element]';
}

export function isSVGElementOrChild (el) {
Expand All @@ -581,15 +593,15 @@ export function isFetchHeaders (instance) {
return true;

return instance && typeof instance === 'object' && instance.append !== void 0 &&
typeof instance.toString === 'function' && instance.toString() === '[object Headers]';
nativeToString(instance) === '[object Headers]';
}

export function isFetchRequest (instance) {
if (nativeMethods.Request && instance instanceof nativeMethods.Request)
return true;

return instance && typeof instance === 'object' && typeof instance.json === 'function' &&
typeof instance.toString === 'function' && instance.toString() === '[object Request]';
nativeToString(instance) === '[object Request]';
}

export function isTextEditableInput (el) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ test('document.referrer', function () {
}
};

documentMock.toString.toString = function () {
return 'function test() { [native code] }';
};

strictEqual(getProperty(documentMock, 'referrer'), url);
});

Expand All @@ -148,6 +152,10 @@ test('document.documentURI', function () {
}
};

documentMock.toString.toString = function () {
return 'function test() { [native code] }';
};

strictEqual(getProperty(documentMock, 'documentURI'), url);
});

Expand Down
6 changes: 6 additions & 0 deletions test/client/fixtures/utils/dom-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,12 @@ asyncTest('isElementFocusable', function () {

module('regression');

test('isDocument infinite recursion (GH-923)', function () {
var obj = eval(processScript('({ toString: function () { this.location = 1; } })'));

ok(!domUtils.isDocument(obj));
});

asyncTest('isDocument for a cross-domain object (GH-467)', function () {
var iframe = document.createElement('iframe');

Expand Down

0 comments on commit 3d567d1

Please sign in to comment.