Skip to content

Commit

Permalink
Move client to typescript 3 (DevExpress#1929)
Browse files Browse the repository at this point in the history
* move client to typescript 3

* small refactoring

* fix watch

* simplify server scripts building

* fix

* remove cookie/index.js

* remove unsed files

* removed unnecessary files

* fixes

* remove unnecessary files

* remove unnecessary files

* small changes

* fix

* fix
  • Loading branch information
miherlosev authored and LavrovArtem committed Feb 11, 2019
1 parent 12fff1a commit bfcdb5a
Show file tree
Hide file tree
Showing 73 changed files with 846 additions and 299 deletions.
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package-lock.json

# Temporary (TypeScript migration)
**/*.js
!src/client/**/*.js
!src/processing/script/tools/**/*.js
!src/test
!./src/client/**/*.js
!./src/test
!src/Gulpfile.js
21 changes: 4 additions & 17 deletions Gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,9 @@ gulp.step('client-scripts', gulp.series('client-scripts-transpile', 'client-scri

gulp.step('server-scripts', () => {
const tsConfig = gulpTypeScript.createProject('tsconfig.json');
const tsFiles = gulp.src(['./src/**/*.ts']).pipe(tsConfig());
const jsTools = gulp.src(['./src/**/*.js', '!./src/client/**/*.js']);

return mergeStreams(tsFiles, jsTools)
return gulp.src(['./src/**/*.ts'])
.pipe(tsConfig())
.pipe(gulpBabel())
.pipe(gulp.dest('lib/'));
});
Expand Down Expand Up @@ -234,24 +233,12 @@ gulp.step('templates', () => {
});

gulp.step('lint-js', () => {
// NOTE: remove this after migration will be completed
const migratedToTypeScriptClientFiles = [
'!./src/client/transport.js',
'!./src/client/page-navigation-watch.js',
'!./src/client/settings.js',
'!./src/client/sandbox/ie-debug.js',
'!./src/client/sandbox/event/**/*.js',
'!./src/client/sandbox/cookie/*.js',
'!./src/client/utils/dom.js'
];

return gulp
.src([
'./src/client/**/*.js',
'./test/server/*.js',
'./test/client/fixtures/**/*.js',
'Gulpfile.js'
].concat(migratedToTypeScriptClientFiles))
])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
Expand Down Expand Up @@ -292,7 +279,7 @@ gulp.step('mocha', () => {
gulp.task('test-server', gulp.series('build', 'mocha'));

gulp.step('qunit', () => {
gulp.watch('./src/**', gulp.series('build'));
gulp.watch('./src/**/*.ts', gulp.series('build'));

return gulp
.src('./test/client/fixtures/**/*-test.js')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,31 @@ import { sameOriginCheck } from '../utils/destination-location';
import { getProxyUrl } from '../utils/url';
import * as domUtils from '../utils/dom';
import fastApply from '../utils/fast-apply';
import { hasUnclosedElementFlag } from '../sandbox/node/document/writer';
import DocumentWriter from '../sandbox/node/document/writer';
import { findByName } from '../sandbox/windows-storage';

export default class ClientDomAdapter extends BaseDomAdapter {
removeAttr (el, attr) {
removeAttr (el: HTMLElement, attr: string) {
return nativeMethods.removeAttribute.call(el, attr);
}

getAttr (el, attr) {
getAttr (el: HTMLElement, attr: string) {
return nativeMethods.getAttribute.call(el, attr);
}

hasAttr (el, attr) {
hasAttr (el: HTMLElement, attr: string): boolean {
return el.hasAttribute(attr);
}

isSVGElement (el) {
isSVGElement (el: HTMLElement): boolean {
return domUtils.isSVGElement(el);
}

getClassName (el) {
getClassName (el: HTMLElement) {
return el.className;
}

hasEventHandler (el) {
hasEventHandler (el: HTMLElement): boolean {
const attributes = nativeMethods.elementAttributesGetter.call(el);

for (const attr of attributes) {
Expand All @@ -42,39 +42,39 @@ export default class ClientDomAdapter extends BaseDomAdapter {
return false;
}

getTagName (el) {
getTagName (el): string {
return domUtils.getTagName(el);
}

setAttr (el, attr, value) {
setAttr (el: HTMLElement, attr: string, value: string): void {
return nativeMethods.setAttribute.call(el, attr, value);
}

setScriptContent (script, content) {
setScriptContent (script: HTMLElement, content: string): void {
nativeMethods.scriptTextSetter.call(script, content);
}

getScriptContent (script) {
getScriptContent (script: HTMLElement) {
return nativeMethods.scriptTextGetter.call(script);
}

getStyleContent (style) {
getStyleContent (style: HTMLElement) {
return nativeMethods.elementInnerHTMLGetter.call(style);
}

setStyleContent (style, content) {
setStyleContent (style: HTMLElement, content: string) {
nativeMethods.elementInnerHTMLSetter.call(style, content);
}

needToProcessContent (el) {
return !hasUnclosedElementFlag(el);
needToProcessContent (el: HTMLElement): boolean {
return !DocumentWriter.hasUnclosedElementFlag(el);
}

needToProcessUrl () {
needToProcessUrl (): boolean {
return true;
}

hasIframeParent (el) {
hasIframeParent (el: HTMLElement): boolean {
try {
if (el[INTERNAL_PROPS.processedContext])
return window.top !== el[INTERNAL_PROPS.processedContext];
Expand All @@ -86,33 +86,33 @@ export default class ClientDomAdapter extends BaseDomAdapter {
}
}

attachEventEmitter (domProcessor) {
attachEventEmitter (domProcessor): void {
const eventEmitter = new EventEmitter();

domProcessor.on = (evt, listener) => eventEmitter.on(evt, listener);
domProcessor.off = (evt, listener) => eventEmitter.off(evt, listener);
domProcessor.emit = (...args) => fastApply(eventEmitter, 'emit', args);
}

getCrossDomainPort () {
getCrossDomainPort (): string {
return settings.get().crossDomainProxyPort;
}

getProxyUrl () {
getProxyUrl (): string {
return getProxyUrl.apply(null, arguments);
}

isTopParentIframe (el) {
isTopParentIframe (el: HTMLElement): boolean {
const elWindow = el[INTERNAL_PROPS.processedContext];

return elWindow && window.top === elWindow.parent;
}

sameOriginCheck (location, checkedUrl) {
sameOriginCheck (location: string, checkedUrl: string) {
return sameOriginCheck(location, checkedUrl);
}

isExistingTarget (target) {
isExistingTarget (target: string) {
return !!findByName(target);
}
}
File renamed without changes.
27 changes: 23 additions & 4 deletions src/client/index.js → src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,32 @@ import {
SCRIPT_PROCESSING_END_HEADER_COMMENT,
SCRIPT_PROCESSING_END_COMMENT
} from '../processing/script/header';
import { STYLESHEET_PROCESSING_START_COMMENT, STYLESHEET_PROCESSING_END_COMMENT } from '../processing/style';
import StyleProcessor from '../processing/style';
import extend from './utils/extend';
import INTERNAL_PROPS from '../processing/dom/internal-properties';
import PageNavigationWatch from './page-navigation-watch';
import domProcessor from './dom-processor';

class Hammerhead {
win: Window;
sandbox: Sandbox;
pageNavigationWatch: PageNavigationWatch;
EVENTS: any;
PROCESSING_COMMENTS: any;
EventEmitter: any;
doUpload: any;
createNativeXHR: any;
processScript: any;
get: any;
Promise: any;
json: any;
transport: any;
nativeMethods: any;
shadowUI: any;
storages: any;
eventSandbox: any;
utils: any;

constructor () {
this.win = null;
this.sandbox = new Sandbox();
Expand Down Expand Up @@ -57,8 +76,8 @@ class Hammerhead {
};

this.PROCESSING_COMMENTS = {
stylesheetStart: STYLESHEET_PROCESSING_START_COMMENT,
stylesheetEnd: STYLESHEET_PROCESSING_END_COMMENT,
stylesheetStart: StyleProcessor.STYLESHEET_PROCESSING_START_COMMENT,
stylesheetEnd: StyleProcessor.STYLESHEET_PROCESSING_END_COMMENT,
scriptStart: SCRIPT_PROCESSING_START_COMMENT,
scriptEndHeader: SCRIPT_PROCESSING_END_HEADER_COMMENT,
scriptEnd: SCRIPT_PROCESSING_END_COMMENT
Expand Down Expand Up @@ -206,7 +225,7 @@ const hammerhead = new Hammerhead();

// NOTE: The 'load' event is raised after calling document.close for a same-domain iframe
// So, we need to define the '%hammerhead%' variable as 'configurable' so that it can be redefined.
nativeMethods.objectDefineProperty.call(window.Object, window, INTERNAL_PROPS.hammerhead, {
nativeMethods.objectDefineProperty(window, INTERNAL_PROPS.hammerhead, {
value: hammerhead,
configurable: true
});
Expand Down
File renamed without changes.
9 changes: 7 additions & 2 deletions src/client/sandbox/base.js → src/client/sandbox/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ import { findDocument, isElementInDocument, getFrameElement } from '../utils/dom
import INTERNAL_PROPS from '../../processing/dom/internal-properties';

export default class SandboxBase extends EventEmitter {
window: Window;
nativeMethods: any;
document: Document;

constructor () {
super();

this.window = null;
this.document = null;
this.nativeMethods = nativeMethods;
}

// NOTE: The sandbox is deactivated when its window is removed from the DOM.
isDeactivated () {
isDeactivated (): boolean {
try {
// NOTE: In IE11, a situation when the document is not active may occur.
// eslint-disable-next-line no-unused-expressions
Expand All @@ -31,7 +36,7 @@ export default class SandboxBase extends EventEmitter {
return true;
}

attach (window, document) {
attach (window: Window, document?: Document) {
this.window = window;
this.document = document || window.document;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import nativeMethods from '../../sandbox/native-methods';
import { processHtml } from '../../utils/html';

export default class CodeInstrumentation extends SandboxBase {
methodCallInstrumentation: any;
locationAccessorsInstrumentation: any;
propertyAccessorsInstrumentation: any;
elementPropertyAccessors: any;

constructor (eventSandbox, windowSandbox, messageSandbox) {
super();

Expand All @@ -26,7 +31,7 @@ export default class CodeInstrumentation extends SandboxBase {
// NOTE: In Google Chrome, iframes whose src contains html code raise the 'load' event twice.
// So, we need to define code instrumentation functions as 'configurable' so that they can be redefined.
// NOTE: GH-260
nativeMethods.objectDefineProperty.call(window.Object, window, INSTRUCTION.getEval, {
nativeMethods.objectDefineProperty(window, INSTRUCTION.getEval, {
value: evalFn => {
if (evalFn !== window.eval)
return evalFn;
Expand All @@ -41,7 +46,7 @@ export default class CodeInstrumentation extends SandboxBase {
configurable: true
});

nativeMethods.objectDefineProperty.call(window.Object, window, INSTRUCTION.processScript, {
nativeMethods.objectDefineProperty(window, INSTRUCTION.processScript, {
value: (script, isApply) => {
if (isApply) {
if (script && script.length && typeof script[0] === 'string') {
Expand All @@ -64,7 +69,7 @@ export default class CodeInstrumentation extends SandboxBase {
configurable: true
});

nativeMethods.objectDefineProperty.call(window.Object, window, INSTRUCTION.processHtml, {
nativeMethods.objectDefineProperty(window, INSTRUCTION.processHtml, {
value: (win, html) => {
if (typeof html === 'string')
html = processHtml(`<html><body>${html}</body></html>`, { processedContext: win });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createOverriddenDescriptor } from '../../../utils/property-overriding';

const lengthWeakMap = new WeakMap();

export default function DOMStringListWrapper (window, getCrossDomainOrigin) {
export default function DOMStringListWrapper (window: Window, getCrossDomainOrigin) {
const nativeOrigins = window.location.ancestorOrigins;
const length = nativeOrigins.length;
let parentWindow = window.parent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import nativeMethods from '../../native-methods';
const LOCATION_WRAPPER = 'hammerhead|location-wrapper';

export default class LocationAccessorsInstrumentation extends SandboxBase {
LOCATION_CHANGED_EVENT: string = 'hammerhead|event|location-changed';

messageSandbox: any;
locationChangedEventCallback: any;

constructor (messageSandbox) {
super();

this.LOCATION_CHANGED_EVENT = 'hammerhead|event|location-changed';

this.messageSandbox = messageSandbox;

this.locationChangedEventCallback = e => this.emit(this.LOCATION_CHANGED_EVENT, e);
Expand Down Expand Up @@ -50,8 +53,8 @@ export default class LocationAccessorsInstrumentation extends SandboxBase {
nativeMethods.objectDefineProperty(window, INSTRUCTION.setLocation, {
value: (location, value) => {
if (isLocation(location) && typeof value === 'string') {
// eslint-disable-next-line no-restricted-properties
locationWrapper.href = value;
// @ts-ignore
locationWrapper.href = value;// eslint-disable-line no-restricted-properties

return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '../../../../utils/url';
import nativeMethods from '../../native-methods';
import urlResolver from '../../../utils/url-resolver';
import { processJsAttrValue, isJsProtocol } from '../../../../processing/dom/index';
import DomProcessor from '../../../../processing/dom/index';
import DOMStringListWrapper from './ancestor-origins-wrapper';
import createIntegerIdGenerator from '../../../utils/integer-id-generator';
import { createOverriddenDescriptor } from '../../../utils/property-overriding';
Expand All @@ -34,15 +34,15 @@ function getLocationUrl (window) {
}

export default class LocationWrapper {
constructor (window, messageSandbox, onChanged) {
constructor (window, messageSandbox?, onChanged?) {
const parsedLocation = parseProxyUrl(getLocationUrl(window));
const locationResourceType = parsedLocation ? parsedLocation.resourceType : '';
const parsedResourceType = parseResourceType(locationResourceType);
const isLocationPropsInProto = nativeMethods.objectHasOwnProperty.call(window.Location.prototype, 'href');
const locationPropsOwner = isLocationPropsInProto ? window.Location.prototype : window.location;
const locationProps = {};
const locationProps: any = {};

parsedResourceType.isIframe |= window !== window.top;
parsedResourceType.isIframe = parsedResourceType.isIframe || window !== window.top;

const resourceType = getResourceTypeString({
isIframe: parsedResourceType.isIframe,
Expand All @@ -68,8 +68,8 @@ export default class LocationWrapper {

href = prepareUrl(href);

if (isJsProtocol(href))
return processJsAttrValue(href, { isJsProtocol: true, isEventAttr: false });
if (DomProcessor.isJsProtocol(href))
return DomProcessor.processJsAttrValue(href, { isJsProtocol: true, isEventAttr: false });

const locationUrl = getLocationUrl(window);

Expand Down Expand Up @@ -153,8 +153,8 @@ export default class LocationWrapper {

messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, ({ message, source }) => {
if (message.cmd === GET_ORIGIN_CMD) {
// eslint-disable-next-line no-restricted-properties
messageSandbox.sendServiceMsg({ id: message.id, cmd: ORIGIN_RECEIVED_CMD, origin: this.origin }, source);
// @ts-ignore
messageSandbox.sendServiceMsg({ id: message.id, cmd: ORIGIN_RECEIVED_CMD, origin: this.origin }, source);// eslint-disable-line no-restricted-properties
}
else if (message.cmd === ORIGIN_RECEIVED_CMD) {
const callback = callbacks[message.id];
Expand Down
Loading

0 comments on commit bfcdb5a

Please sign in to comment.