fix(platform-browser): Update types for TypeScript nullability support

Closes #15898
This commit is contained in:
Miško Hevery 2017-03-24 09:59:41 -07:00 committed by Tobias Bosch
parent 01d93f3af8
commit 728c9d0632
52 changed files with 169 additions and 154 deletions

View File

@ -30,5 +30,7 @@ export enum SecurityContext {
* @stable
*/
export abstract class Sanitizer {
abstract sanitize(context: SecurityContext, value: string): string;
abstract sanitize(context: SecurityContext, value: null): null;
abstract sanitize(context: SecurityContext, value: {}|string): string;
abstract sanitize(context: SecurityContext, value: {}|string|null): string|null;
}

View File

@ -87,7 +87,7 @@ export function main() {
reject = rej;
});
originalJasmineIt = jasmine.getEnv().it;
jasmine.getEnv().it = (description: string, fn: any /** TODO #9100 */) => {
jasmine.getEnv().it = (description: string, fn: any /** TODO #9100 */): any => {
const done = () => { resolve(null); };
(<any>done).fail = (err: any /** TODO #9100 */) => { reject(err); };
fn(done);

View File

@ -4,6 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../dist/packages/platform-browser-dynamic",

View File

@ -28,13 +28,13 @@ export class AnimationRendererFactory implements RendererFactory2 {
}
export class AnimationRenderer implements Renderer2 {
public destroyNode: (node: any) => (void|any) = null;
private _flushPromise: Promise<any> = null;
public destroyNode: ((node: any) => any)|null = null;
private _flushPromise: Promise<any>|null = null;
constructor(
public delegate: Renderer2, private _engine: AnimationEngine, private _zone: NgZone,
private _namespaceId: string) {
this.destroyNode = this.delegate.destroyNode ? (n) => delegate.destroyNode(n) : null;
this.destroyNode = this.delegate.destroyNode ? (n) => delegate.destroyNode !(n) : null;
}
get data() { return this.delegate.data; }
@ -132,7 +132,7 @@ export class AnimationRenderer implements Renderer2 {
if (!this._flushPromise) {
this._zone.runOutsideAngular(() => {
this._flushPromise = Promise.resolve(null).then(() => {
this._flushPromise = null;
this._flushPromise = null !;
this._engine.flush();
});
});

View File

@ -12,7 +12,7 @@ import {el} from '@angular/platform-browser/testing/src/browser_util';
export function main() {
describe('NoopAnimationEngine', () => {
let captures: string[] = [];
function capture(value: string = null) { return (v: any = null) => captures.push(value || v); }
function capture(value?: string) { return (v: any = null) => captures.push(value || v); }
beforeEach(() => { captures = []; });

View File

@ -144,12 +144,12 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
return evt.defaultPrevented || evt.returnValue != null && !evt.returnValue;
}
getInnerHTML(el: HTMLElement): string { return el.innerHTML; }
getTemplateContent(el: Node): Node {
getTemplateContent(el: Node): Node|null {
return 'content' in el && el instanceof HTMLTemplateElement ? el.content : null;
}
getOuterHTML(el: HTMLElement): string { return el.outerHTML; }
nodeName(node: Node): string { return node.nodeName; }
nodeValue(node: Node): string { return node.nodeValue; }
nodeValue(node: Node): string|null { return node.nodeValue; }
type(node: HTMLInputElement): string { return node.type; }
content(node: Node): Node {
if (this.hasProperty(node, 'content')) {
@ -158,9 +158,9 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
return node;
}
}
firstChild(el: Node): Node { return el.firstChild; }
nextSibling(el: Node): Node { return el.nextSibling; }
parentElement(el: Node): Node { return el.parentNode; }
firstChild(el: Node): Node|null { return el.firstChild; }
nextSibling(el: Node): Node|null { return el.nextSibling; }
parentElement(el: Node): Node|null { return el.parentNode; }
childNodes(el: any): Node[] { return el.childNodes; }
childNodesAsList(el: Node): any[] {
const childNodes = el.childNodes;
@ -190,7 +190,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
}
insertAfter(parent: Node, ref: Node, node: any) { parent.insertBefore(node, ref.nextSibling); }
setInnerHTML(el: Element, value: string) { el.innerHTML = value; }
getText(el: Node): string { return el.textContent; }
getText(el: Node): string|null { return el.textContent; }
setText(el: Node, value: string) { el.textContent = value; }
getValue(el: any): string { return el.value; }
setValue(el: any, value: string) { el.value = value; }
@ -242,7 +242,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
element.style[stylename] = '';
}
getStyle(element: any, stylename: string): string { return element.style[stylename]; }
hasStyle(element: any, styleName: string, styleValue: string = null): boolean {
hasStyle(element: any, styleName: string, styleValue?: string|null): boolean {
const value = this.getStyle(element, styleName) || '';
return styleValue ? value == styleValue : value.length > 0;
}
@ -262,7 +262,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
hasAttributeNS(element: Element, ns: string, attribute: string): boolean {
return element.hasAttributeNS(ns, attribute);
}
getAttribute(element: Element, attribute: string): string {
getAttribute(element: Element, attribute: string): string|null {
return element.getAttribute(attribute);
}
getAttributeNS(element: Element, ns: string, name: string): string {
@ -335,7 +335,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
return _keyMap[key] || key;
}
getGlobalEventTarget(doc: Document, target: string): EventTarget {
getGlobalEventTarget(doc: Document, target: string): EventTarget|null {
if (target === 'window') {
return window;
}
@ -345,10 +345,11 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
if (target === 'body') {
return document.body;
}
return null;
}
getHistory(): History { return window.history; }
getLocation(): Location { return window.location; }
getBaseHref(doc: Document): string {
getBaseHref(doc: Document): string|null {
const href = getBaseElementHref();
return href == null ? null : relativePath(href);
}
@ -357,7 +358,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
setData(element: Element, name: string, value: string) {
this.setAttribute(element, 'data-' + name, value);
}
getData(element: Element, name: string): string {
getData(element: Element, name: string): string|null {
return this.getAttribute(element, 'data-' + name);
}
getComputedStyle(element: any): any { return getComputedStyle(element); }
@ -375,7 +376,7 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
supportsCookies(): boolean { return true; }
getCookie(name: string): string { return parseCookieValue(document.cookie, name); }
getCookie(name: string): string|null { return parseCookieValue(document.cookie, name); }
setCookie(name: string, value: string) {
// document.cookie is magical, assigning into it assigns/overrides one cookie value, but does
@ -384,10 +385,10 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
}
}
let baseElement: HTMLElement = null;
function getBaseElementHref(): string {
let baseElement: HTMLElement|null = null;
function getBaseElementHref(): string|null {
if (!baseElement) {
baseElement = document.querySelector('base');
baseElement = document.querySelector('base') !;
if (!baseElement) {
return null;
}
@ -406,7 +407,7 @@ function relativePath(url: any): string {
'/' + urlParsingNode.pathname;
}
export function parseCookieValue(cookieStr: string, name: string): string {
export function parseCookieValue(cookieStr: string, name: string): string|null {
name = encodeURIComponent(name);
for (const cookie of cookieStr.split(';')) {
const eqIndex = cookie.indexOf('=');
@ -423,7 +424,7 @@ export function setValueOnPath(global: any, path: string, value: any) {
const parts = path.split('.');
let obj: any = global;
while (parts.length > 1) {
const name = parts.shift();
const name = parts.shift() !;
if (obj.hasOwnProperty(name) && obj[name] != null) {
obj = obj[name];
} else {
@ -433,5 +434,5 @@ export function setValueOnPath(global: any, path: string, value: any) {
if (obj === undefined || obj === null) {
obj = {};
}
obj[parts.shift()] = value;
obj[parts.shift() !] = value;
}

View File

@ -17,8 +17,8 @@ import {DomAdapter} from '../dom/dom_adapter';
* can introduce XSS risks.
*/
export abstract class GenericBrowserDomAdapter extends DomAdapter {
private _animationPrefix: string = null;
private _transitionEnd: string = null;
private _animationPrefix: string|null = null;
private _transitionEnd: string|null = null;
constructor() {
super();
try {

View File

@ -40,7 +40,7 @@ export class BrowserPlatformLocation extends PlatformLocation {
get location(): Location { return this._location; }
getBaseHrefFromDOM(): string { return getDOM().getBaseHref(this._doc); }
getBaseHrefFromDOM(): string { return getDOM().getBaseHref(this._doc) !; }
onPopState(fn: LocationChangeListener): void {
getDOM().getGlobalEventTarget(this._doc, 'window').addEventListener('popstate', fn, false);

View File

@ -39,7 +39,7 @@ export class Meta {
private _dom: DomAdapter;
constructor(@Inject(DOCUMENT) private _doc: any) { this._dom = getDOM(); }
addTag(tag: MetaDefinition, forceCreation: boolean = false): HTMLMetaElement {
addTag(tag: MetaDefinition, forceCreation: boolean = false): HTMLMetaElement|null {
if (!tag) return null;
return this._getOrCreateElement(tag, forceCreation);
}
@ -54,7 +54,7 @@ export class Meta {
}, []);
}
getTag(attrSelector: string): HTMLMetaElement {
getTag(attrSelector: string): HTMLMetaElement|null {
if (!attrSelector) return null;
return this._dom.querySelector(this._doc, `meta[${attrSelector}]`);
}
@ -65,17 +65,17 @@ export class Meta {
return list ? [].slice.call(list) : [];
}
updateTag(tag: MetaDefinition, selector?: string): HTMLMetaElement {
updateTag(tag: MetaDefinition, selector?: string): HTMLMetaElement|null {
if (!tag) return null;
selector = selector || this._parseSelector(tag);
const meta: HTMLMetaElement = this.getTag(selector);
const meta: HTMLMetaElement = this.getTag(selector) !;
if (meta) {
return this._setMetaElementAttributes(tag, meta);
}
return this._getOrCreateElement(tag, true);
}
removeTag(attrSelector: string): void { this.removeTagElement(this.getTag(attrSelector)); }
removeTag(attrSelector: string): void { this.removeTagElement(this.getTag(attrSelector) !); }
removeTagElement(meta: HTMLMetaElement): void {
if (meta) {
@ -87,7 +87,7 @@ export class Meta {
HTMLMetaElement {
if (!forceCreation) {
const selector: string = this._parseSelector(meta);
const elem: HTMLMetaElement = this.getTag(selector);
const elem: HTMLMetaElement = this.getTag(selector) !;
// It's allowed to have multiple elements with the same name so it's not enough to
// just check that element with the same name already present on the page. We also need to
// check if element has tag attributes

View File

@ -49,7 +49,7 @@ export class BrowserGetTestability implements GetTestability {
}
findTestabilityInTree(registry: TestabilityRegistry, elem: any, findInAncestors: boolean):
Testability {
Testability|null {
if (elem == null) {
return null;
}

View File

@ -49,6 +49,6 @@ export class By {
* {@example platform-browser/dom/debug/ts/by/by.ts region='by_directive'}
*/
static directive(type: Type<any>): Predicate<DebugElement> {
return (debugElement) => debugElement.providerTokens.indexOf(type) !== -1;
return (debugElement) => debugElement.providerTokens !.indexOf(type) !== -1;
}
}

View File

@ -22,7 +22,7 @@ const CORE_TOKENS_GLOBAL_NAME = 'ng.coreTokens';
* null if the given native element does not have an Angular view associated
* with it.
*/
export function inspectNativeElement(element: any): core.DebugNode {
export function inspectNativeElement(element: any): core.DebugNode|null {
return core.getDebugNode(element);
}

View File

@ -8,7 +8,7 @@
import {Type} from '@angular/core';
let _DOM: DomAdapter = null;
let _DOM: DomAdapter = null !;
export function getDOM() {
return _DOM;
@ -32,7 +32,7 @@ export function setRootDomAdapter(adapter: DomAdapter) {
* can introduce XSS risks.
*/
export abstract class DomAdapter {
public resourceLoaderType: Type<any> = null;
public resourceLoaderType: Type<any> = null !;
abstract hasProperty(element: any, name: string): boolean;
abstract setProperty(el: Element, name: string, value: any): any;
abstract getProperty(el: Element, name: string): any;
@ -68,12 +68,12 @@ export abstract class DomAdapter {
abstract getTemplateContent(el: any): any;
abstract getOuterHTML(el: any): string;
abstract nodeName(node: any): string;
abstract nodeValue(node: any): string;
abstract nodeValue(node: any): string|null;
abstract type(node: any): string;
abstract content(node: any): any;
abstract firstChild(el: any): Node;
abstract nextSibling(el: any): Node;
abstract parentElement(el: any): Node;
abstract firstChild(el: any): Node|null;
abstract nextSibling(el: any): Node|null;
abstract parentElement(el: any): Node|null;
abstract childNodes(el: any): Node[];
abstract childNodesAsList(el: any): Node[];
abstract clearNodes(el: any): any;
@ -85,7 +85,7 @@ export abstract class DomAdapter {
abstract insertAllBefore(parent: any, ref: any, nodes: any): any;
abstract insertAfter(parent: any, el: any, node: any): any;
abstract setInnerHTML(el: any, value: any): any;
abstract getText(el: any): string;
abstract getText(el: any): string|null;
abstract setText(el: any, value: string): any;
abstract getValue(el: any): string;
abstract setValue(el: any, value: string): any;
@ -117,7 +117,7 @@ export abstract class DomAdapter {
abstract attributeMap(element: any): Map<string, string>;
abstract hasAttribute(element: any, attribute: string): boolean;
abstract hasAttributeNS(element: any, ns: string, attribute: string): boolean;
abstract getAttribute(element: any, attribute: string): string;
abstract getAttribute(element: any, attribute: string): string|null;
abstract getAttributeNS(element: any, ns: string, attribute: string): string;
abstract setAttribute(element: any, name: string, value: string): any;
abstract setAttributeNS(element: any, ns: string, name: string, value: string): any;
@ -145,12 +145,12 @@ export abstract class DomAdapter {
abstract getGlobalEventTarget(doc: Document, target: string): any;
abstract getHistory(): History;
abstract getLocation(): Location;
abstract getBaseHref(doc: Document): string;
abstract getBaseHref(doc: Document): string|null;
abstract resetBaseElement(): void;
abstract getUserAgent(): string;
abstract setData(element: any, name: string, value: string): any;
abstract getComputedStyle(element: any): any;
abstract getData(element: any, name: string): string;
abstract getData(element: any, name: string): string|null;
abstract setGlobalVar(name: string, value: any): any;
abstract supportsWebAnimation(): boolean;
abstract performanceNow(): number;
@ -159,6 +159,6 @@ export abstract class DomAdapter {
abstract supportsAnimation(): boolean;
abstract supportsCookies(): boolean;
abstract getCookie(name: string): string;
abstract getCookie(name: string): string|null;
abstract setCookie(name: string, value: string): any;
}

View File

@ -67,7 +67,7 @@ export class DomRendererFactory2 implements RendererFactory2 {
this.defaultRenderer = new DefaultDomRenderer2(eventManager);
};
createRenderer(element: any, type: RendererType2): Renderer2 {
createRenderer(element: any, type: RendererType2|null): Renderer2 {
if (!element || !type) {
return this.defaultRenderer;
}

View File

@ -59,8 +59,8 @@ const EVENT_NAMES = {
export const HAMMER_GESTURE_CONFIG = new InjectionToken<HammerGestureConfig>('HammerGestureConfig');
export interface HammerInstance {
on(eventName: string, callback: Function): void;
off(eventName: string, callback: Function): void;
on(eventName: string, callback?: Function): void;
off(eventName: string, callback?: Function): void;
}
/**

View File

@ -31,7 +31,7 @@ export class KeyEventsPlugin extends EventManagerPlugin {
supports(eventName: string): boolean { return KeyEventsPlugin.parseEventName(eventName) != null; }
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
const parsedEvent = KeyEventsPlugin.parseEventName(eventName);
const parsedEvent = KeyEventsPlugin.parseEventName(eventName) !;
const outsideHandler =
KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());
@ -41,7 +41,7 @@ export class KeyEventsPlugin extends EventManagerPlugin {
});
}
static parseEventName(eventName: string): {[key: string]: string} {
static parseEventName(eventName: string): {[key: string]: string}|null {
const parts: string[] = eventName.toLowerCase().split('.');
const domEventName = parts.shift();
@ -49,7 +49,7 @@ export class KeyEventsPlugin extends EventManagerPlugin {
return null;
}
const key = KeyEventsPlugin._normalizeKey(parts.pop());
const key = KeyEventsPlugin._normalizeKey(parts.pop() !);
let fullKey = '';
MODIFIER_KEYS.forEach(modifierName => {

View File

@ -100,7 +100,9 @@ export abstract class DomSanitizer implements Sanitizer {
* by replacing URLs that have an unsafe protocol part (such as `javascript:`). The implementation
* is responsible to make sure that the value can definitely be safely used in the given context.
*/
abstract sanitize(context: SecurityContext, value: any): string;
abstract sanitize(context: SecurityContext, value: null): null;
abstract sanitize(context: SecurityContext, value: SafeValue|string): string;
abstract sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
/**
* Bypass security and trust the given value to be safe HTML. Only use this when the bound HTML
@ -152,7 +154,10 @@ export abstract class DomSanitizer implements Sanitizer {
export class DomSanitizerImpl extends DomSanitizer {
constructor(@Inject(DOCUMENT) private _doc: any) { super(); }
sanitize(ctx: SecurityContext, value: any): string {
sanitize(context: SecurityContext, value: null): null;
sanitize(context: SecurityContext, value: SafeValue|string): string;
sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
sanitize(ctx: SecurityContext, value: any): string|null {
if (value == null) return null;
switch (ctx) {
case SecurityContext.NONE:

View File

@ -13,9 +13,9 @@ import {DomAdapter, getDOM} from '../dom/dom_adapter';
import {sanitizeSrcset, sanitizeUrl} from './url_sanitizer';
/** A <body> element that can be safely used to parse untrusted HTML. Lazily initialized below. */
let inertElement: HTMLElement = null;
let inertElement: HTMLElement|null = null;
/** Lazily initialized to make sure the DOM adapter gets set before use. */
let DOM: DomAdapter = null;
let DOM: DomAdapter = null !;
/** Returns an HTML element that is guaranteed to not execute code when creating elements in it. */
function getInertElement() {
@ -126,18 +126,18 @@ class SanitizingHtmlSerializer {
// This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
// However this code never accesses properties off of `document` before deleting its contents
// again, so it shouldn't be vulnerable to DOM clobbering.
let current: Node = el.firstChild;
let current: Node = el.firstChild !;
while (current) {
if (DOM.isElementNode(current)) {
this.startElement(current as Element);
} else if (DOM.isTextNode(current)) {
this.chars(DOM.nodeValue(current));
this.chars(DOM.nodeValue(current) !);
} else {
// Strip non-element, non-text nodes.
this.sanitizedSomething = true;
}
if (DOM.firstChild(current)) {
current = DOM.firstChild(current);
current = DOM.firstChild(current) !;
continue;
}
while (current) {
@ -146,14 +146,14 @@ class SanitizingHtmlSerializer {
this.endElement(current as Element);
}
let next = checkClobberedElement(current, DOM.nextSibling(current));
let next = checkClobberedElement(current, DOM.nextSibling(current) !);
if (next) {
current = next;
break;
}
current = checkClobberedElement(current, DOM.parentElement(current));
current = checkClobberedElement(current, DOM.parentElement(current) !);
}
}
return this.buf.join('');

View File

@ -29,7 +29,7 @@ export function main() {
function makeRenderer(animationTriggers: any[] = []) {
const type = <RendererType2>{
id: 'id',
encapsulation: null,
encapsulation: null !,
styles: [],
data: {'animation': animationTriggers}
};

View File

@ -28,14 +28,14 @@ export function main() {
afterEach(() => getDOM().remove(defaultMeta));
it('should return meta tag matching selector', () => {
const actual: HTMLMetaElement = metaService.getTag('property="fb:app_id"');
const actual: HTMLMetaElement = metaService.getTag('property="fb:app_id"') !;
expect(actual).not.toBeNull();
expect(getDOM().getAttribute(actual, 'content')).toEqual('123456789');
});
it('should return all meta tags matching selector', () => {
const tag1 = metaService.addTag({name: 'author', content: 'page author'});
const tag2 = metaService.addTag({name: 'author', content: 'another page author'});
const tag1 = metaService.addTag({name: 'author', content: 'page author'}) !;
const tag2 = metaService.addTag({name: 'author', content: 'another page author'}) !;
const actual: HTMLMetaElement[] = metaService.getTags('name=author');
expect(actual.length).toEqual(2);
@ -48,7 +48,7 @@ export function main() {
});
it('should return null if meta tag does not exist', () => {
const actual: HTMLMetaElement = metaService.getTag('fake=fake');
const actual: HTMLMetaElement = metaService.getTag('fake=fake') !;
expect(actual).toBeNull();
});
@ -71,7 +71,7 @@ export function main() {
metaService.addTags([{name: 'keywords', content: 'meta test'}]);
const meta = metaService.getTag(selector);
const meta = metaService.getTag(selector) !;
expect(meta).not.toBeNull();
metaService.removeTagElement(meta);
@ -102,7 +102,7 @@ export function main() {
metaService.updateTag({name: 'twitter:title', content: 'Content Title'}, selector);
const actual = metaService.getTag(selector);
const actual = metaService.getTag(selector) !;
expect(actual).not.toBeNull();
expect(getDOM().getAttribute(actual, 'content')).toEqual('Content Title');
@ -116,7 +116,7 @@ export function main() {
metaService.addTag({name: 'og:title', content: 'Content Title'});
const actual = metaService.getTag(selector);
const actual = metaService.getTag(selector) !;
expect(actual).not.toBeNull();
expect(getDOM().getAttribute(actual, 'content')).toEqual('Content Title');
@ -134,8 +134,8 @@ export function main() {
{name: 'twitter:title', content: 'Content Title'},
{property: 'og:title', content: 'Content Title'}
]);
const twitterMeta = metaService.getTag(nameSelector);
const fbMeta = metaService.getTag(propertySelector);
const twitterMeta = metaService.getTag(nameSelector) !;
const fbMeta = metaService.getTag(propertySelector) !;
expect(twitterMeta).not.toBeNull();
expect(fbMeta).not.toBeNull();
@ -158,7 +158,7 @@ export function main() {
const selector = 'property="fb:app_id"';
expect(metaService.getTags(selector).length).toEqual(1);
const meta = metaService.addTag({property: 'fb:app_id', content: '666'});
const meta = metaService.addTag({property: 'fb:app_id', content: '666'}) !;
expect(metaService.getTags(selector).length).toEqual(2);
@ -170,7 +170,7 @@ export function main() {
const selector = 'property="fb:app_id"';
expect(metaService.getTags(selector).length).toEqual(1);
const meta = metaService.addTag({property: 'fb:app_id', content: '123456789'}, true);
const meta = metaService.addTag({property: 'fb:app_id', content: '123456789'}, true) !;
expect(metaService.getTags(selector).length).toEqual(2);

View File

@ -30,7 +30,7 @@ export function main() {
});
it('should reset title to empty string if title not provided', () => {
titleService.setTitle(null);
titleService.setTitle(null !);
expect(getDOM().getTitle(doc)).toEqual('');
});
});

View File

@ -51,7 +51,7 @@ export function main() {
const element = el('<div></div>');
const plugin = new FakeEventManagerPlugin(doc, ['dblclick']);
const manager = new EventManager([plugin], new FakeNgZone());
expect(() => manager.addEventListener(element, 'click', null))
expect(() => manager.addEventListener(element, 'click', null !))
.toThrowError('No event manager plugin found for event click');
});

View File

@ -14,7 +14,7 @@ import {sanitizeHtml} from '../../src/security/html_sanitizer';
export function main() {
describe('HTML sanitizer', () => {
let defaultDoc: any;
let originalLog: (msg: any) => any = null;
let originalLog: (msg: any) => any = null !;
let logMsgs: string[];
beforeEach(() => {

View File

@ -185,7 +185,7 @@ export function main() {
it('should allow the use of fakeAsync',
fakeAsync(inject([FancyService], (service: FancyService) => {
let value: string;
let value: string = undefined !;
service.getAsyncValue().then((val) => value = val);
tick();
expect(value).toEqual('async value');
@ -449,7 +449,7 @@ export function main() {
reject = rej;
});
originalJasmineIt = jasmine.getEnv().it;
jasmine.getEnv().it = (description: string, fn: (done: DoneFn) => void) => {
jasmine.getEnv().it = (description: string, fn: (done: DoneFn) => void): any => {
const done = <DoneFn>(() => resolve(null));
done.fail = (err) => reject(err);
fn(done);
@ -497,7 +497,7 @@ export function main() {
const itPromise = patchJasmineIt();
it('should fail with an error from a promise', async(inject([], () => {
let reject: (error: any) => void;
let reject: (error: any) => void = undefined !;
const promise = new Promise((_, rej) => reject = rej);
const p = promise.then(() => expect(1).toEqual(2));

View File

@ -12,7 +12,7 @@ import {ɵgetDOM as getDOM} from '@angular/platform-browser';
export let browserDetection: BrowserDetection;
export class BrowserDetection {
private _overrideUa: string;
private _overrideUa: string|null;
private get _ua(): string {
if (typeof this._overrideUa === 'string') {
return this._overrideUa;
@ -23,7 +23,7 @@ export class BrowserDetection {
static setup() { browserDetection = new BrowserDetection(null); }
constructor(ua: string) { this._overrideUa = ua; }
constructor(ua: string|null) { this._overrideUa = ua; }
get isFirefox(): boolean { return this._ua.indexOf('Firefox') > -1; }

View File

@ -121,7 +121,7 @@ _global.beforeEach(function() {
}
};
function compareMap(actual: any, expected: any) {
function compareMap(actual: any, expected: any): boolean|undefined {
if (actual instanceof Map) {
let pass = actual.size === expected.size;
if (pass) {
@ -270,5 +270,5 @@ function elementText(n: any): string {
return elementText(getDOM().childNodesAsList(n));
}
return getDOM().getText(n);
return getDOM().getText(n) !;
}

View File

@ -4,6 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../dist/packages/platform-browser",

View File

@ -40,9 +40,9 @@ export class ZoneMacroTaskConnection implements Connection {
constructor(public request: Request, backend: XHRBackend) {
validateRequestUrl(request.url);
this.response = new Observable((observer: Observer<Response>) => {
let task: Task = null;
let task: Task = null !;
let scheduled: boolean = false;
let sub: Subscription = null;
let sub: Subscription|null = null;
let savedResult: any = null;
let savedError: any = null;

View File

@ -45,7 +45,7 @@ export class ServerPlatformLocation implements PlatformLocation {
}
}
getBaseHrefFromDOM(): string { return getDOM().getBaseHref(this._doc); }
getBaseHrefFromDOM(): string { return getDOM().getBaseHref(this._doc) !; }
onPopState(fn: LocationChangeListener): void {
// No-op: a state stack is not implemented, so

View File

@ -201,7 +201,7 @@ export class Parse5DomAdapter extends DomAdapter {
getInnerHTML(el: any): string {
return parse5.serialize(this.templateAwareRoot(el), {treeAdapter});
}
getTemplateContent(el: any): Node { return null; }
getTemplateContent(el: any): Node|null { return null; }
getOuterHTML(el: any): string {
const fragment = treeAdapter.createDocumentFragment();
this.appendChild(fragment, el);
@ -425,7 +425,7 @@ export class Parse5DomAdapter extends DomAdapter {
hasClass(element: any, className: string): boolean {
return this.classList(element).indexOf(className) > -1;
}
hasStyle(element: any, styleName: string, styleValue: string = null): boolean {
hasStyle(element: any, styleName: string, styleValue?: string): boolean {
const value = this.getStyle(element, styleName) || '';
return styleValue ? value == styleValue : value.length > 0;
}
@ -460,7 +460,7 @@ export class Parse5DomAdapter extends DomAdapter {
}
element.attribs['style'] = styleAttrValue;
}
setStyle(element: any, styleName: string, styleValue: string) {
setStyle(element: any, styleName: string, styleValue?: string|null) {
const styleMap = this._readStyleAttribute(element);
(styleMap as any)[styleName] = styleValue;
this._writeStyleAttribute(element, styleMap);
@ -594,7 +594,7 @@ export class Parse5DomAdapter extends DomAdapter {
return doc.body;
}
}
getBaseHref(doc: Document): string {
getBaseHref(doc: Document): string|null {
const base = this.querySelector(doc, 'base');
let href = '';
if (base) {

View File

@ -24,7 +24,7 @@ export class ServerRendererFactory2 implements RendererFactory2 {
this.defaultRenderer = new DefaultServerRenderer2(document, ngZone, this.schema);
};
createRenderer(element: any, type: RendererType2): Renderer2 {
createRenderer(element: any, type: RendererType2|null): Renderer2 {
if (!element || !type) {
return this.defaultRenderer;
}

View File

@ -4,6 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../dist/packages/platform-server",

View File

@ -4,6 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../dist/packages/platform-webworker-dynamic",

View File

@ -44,7 +44,8 @@ export class ClientMessageBrokerFactory_ extends ClientMessageBrokerFactory {
* @experimental WebWorker support in Angular is experimental.
*/
export abstract class ClientMessageBroker {
abstract runOnService(args: UiArguments, returnType: Type<any>|SerializerTypes): Promise<any>;
abstract runOnService(args: UiArguments, returnType: Type<any>|SerializerTypes|null):
Promise<any>|null;
}
interface PromiseCompleter {
@ -78,7 +79,7 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
return id;
}
runOnService(args: UiArguments, returnType: Type<any>|SerializerTypes): Promise<any> {
runOnService(args: UiArguments, returnType: Type<any>|SerializerTypes): Promise<any>|null {
const fnArgs: any[] = [];
if (args.args) {
args.args.forEach(argument => {
@ -90,10 +91,10 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
});
}
let promise: Promise<any>;
let id: string = null;
let promise: Promise<any>|null;
let id: string|null = null;
if (returnType != null) {
let completer: PromiseCompleter;
let completer: PromiseCompleter = undefined !;
promise = new Promise((resolve, reject) => { completer = {resolve, reject}; });
id = this._generateMessageId(args.method);
this._pending.set(id, completer);
@ -127,12 +128,12 @@ export class ClientMessageBroker_ extends ClientMessageBroker {
private _handleMessage(message: ResponseMessageData): void {
if (message.type === 'result' || message.type === 'error') {
const id = message.id;
const id = message.id !;
if (this._pending.has(id)) {
if (message.type === 'result') {
this._pending.get(id).resolve(message.value);
this._pending.get(id) !.resolve(message.value);
} else {
this._pending.get(id).reject(message.value);
this._pending.get(id) !.reject(message.value);
}
this._pending.delete(id);
}

View File

@ -34,5 +34,7 @@ export class RenderStore {
return this._lookupById.has(id) ? this._lookupById.get(id) : null;
}
serialize(obj: any): number { return obj == null ? null : this._lookupByObject.get(obj); }
serialize(obj: any): number|null|undefined {
return obj == null ? null : this._lookupByObject.get(obj);
}
}

View File

@ -33,7 +33,7 @@ export const PRIMITIVE = SerializerTypes.PRIMITIVE;
export class LocationType {
constructor(
public href: string, public protocol: string, public host: string, public hostname: string,
public port: string, public pathname: string, public search: string, public hash: string,
public port: string, public pathname: string|null, public search: string, public hash: string,
public origin: string) {}
}
@ -49,7 +49,7 @@ export class Serializer {
return obj.map(v => this.serialize(v, type));
}
if (type === SerializerTypes.RENDER_STORE_OBJECT) {
return this._renderStore.serialize(obj);
return this._renderStore.serialize(obj) !;
}
if (type === RenderComponentType) {
return this._serializeRenderComponentType(obj);

View File

@ -47,7 +47,7 @@ export class ServiceMessageBrokerFactory_ extends ServiceMessageBrokerFactory {
*/
export abstract class ServiceMessageBroker {
abstract registerMethod(
methodName: string, signature: Array<Type<any>|SerializerTypes>, method: Function,
methodName: string, signature: Array<Type<any>|SerializerTypes>|null, method: Function,
returnType?: Type<any>|SerializerTypes): void;
}
@ -83,7 +83,7 @@ export class ServiceMessageBroker_ extends ServiceMessageBroker {
private _handleMessage(message: ReceivedMessage): void {
if (this._methods.has(message.method)) {
this._methods.get(message.method)(message);
this._methods.get(message.method) !(message);
}
}

View File

@ -18,7 +18,7 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
private _broker: ClientMessageBroker;
private _popStateListeners: Array<Function> = [];
private _hashChangeListeners: Array<Function> = [];
private _location: LocationType = null;
private _location: LocationType = null !;
private _channelSource: EventEmitter<Object>;
public initialized: Promise<any>;
private initializedResolve: () => void;
@ -31,7 +31,7 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
this._channelSource.subscribe({
next: (msg: {[key: string]: any}) => {
let listeners: Array<Function> = null;
let listeners: Array<Function>|null = null;
if (msg.hasOwnProperty('event')) {
const type: string = msg['event']['type'];
if (type === 'popstate') {
@ -55,14 +55,13 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
init(): Promise<boolean> {
const args: UiArguments = new UiArguments('getLocation');
return this._broker.runOnService(args, LocationType)
.then(
(val: LocationType) => {
this._location = val;
this.initializedResolve();
return true;
},
err => { throw new Error(err); });
return this._broker.runOnService(args, LocationType) !.then(
(val: LocationType) => {
this._location = val;
this.initializedResolve();
return true;
},
err => { throw new Error(err); });
}
getBaseHrefFromDOM(): string {
@ -74,11 +73,11 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
onHashChange(fn: LocationChangeListener): void { this._hashChangeListeners.push(fn); }
get pathname(): string { return this._location ? this._location.pathname : null; }
get pathname(): string { return this._location ? this._location.pathname ! : '<unknown>'; }
get search(): string { return this._location ? this._location.search : null; }
get search(): string { return this._location ? this._location.search : '<unknown>'; }
get hash(): string { return this._location ? this._location.hash : null; }
get hash(): string { return this._location ? this._location.hash : '<unknown>'; }
set pathname(newPath: string) {
if (this._location === null) {

View File

@ -67,7 +67,7 @@ export class WebWorkerRendererFactory2 implements RendererFactory2 {
source.subscribe({next: (message: any) => this._dispatchEvent(message)});
}
createRenderer(element: any, type: RendererType2): Renderer2 {
createRenderer(element: any, type: RendererType2|null): Renderer2 {
const renderer = new WebWorkerRenderer2(this);
const id = this.renderStore.allocateId();
@ -277,9 +277,9 @@ export class WebWorkerRenderer2 implements Renderer2 {
listener: (event: any) => boolean): () => void {
const unlistenId = this._rendererFactory.allocateId();
const [targetEl, targetName, fullName]: [any, string, string] = typeof target === 'string' ?
[null, target, `${target}:${eventName}`] :
[target, null, null];
const [targetEl, targetName, fullName]: [any, string | null, string | null] =
typeof target === 'string' ? [null, target, `${target}:${eventName}`] :
[target, null, null];
if (fullName) {
this._rendererFactory.globalEvents.listen(fullName, listener);

View File

@ -44,12 +44,12 @@ export function expectBrokerCall(
broker.spy('runOnService').and.callFake((args: UiArguments, returnType: Type<any>) => {
expect(args.method).toEqual(methodName);
if (vals != null) {
expect(args.args.length).toEqual(vals.length);
vals.forEach((v, i) => { expect(v).toEqual(args.args[i].value); });
expect(args.args !.length).toEqual(vals.length);
vals.forEach((v, i) => { expect(v).toEqual(args.args ![i].value); });
}
let promise: Promise<any>|void = null;
let promise: Promise<any>|void = null !;
if (handler != null) {
const givenValues = args.args.map((arg) => arg.value);
const givenValues = args.args !.map((arg) => arg.value);
if (givenValues.length > 0) {
promise = handler(givenValues);
} else {
@ -131,6 +131,6 @@ export class MockMessageBus extends MessageBus {
}
export class MockMessageBrokerFactory extends ClientMessageBrokerFactory_ {
constructor(private _messageBroker: ClientMessageBroker) { super(null, null); }
constructor(private _messageBroker: ClientMessageBroker) { super(null !, null !); }
createMessageBroker(channel: string, runInZone = true) { return this._messageBroker; }
}

View File

@ -18,8 +18,8 @@ import {SpyMessageBroker} from './spies';
export function main() {
describe('WebWorkerPlatformLocation', () => {
let uiBus: MessageBus = null;
let workerBus: MessageBus = null;
let uiBus: MessageBus = null !;
let workerBus: MessageBus = null !;
let broker: any = null;
const TEST_LOCATION = new LocationType(
@ -35,11 +35,11 @@ export function main() {
}
});
const factory = new MockMessageBrokerFactory(broker);
return new WebWorkerPlatformLocation(factory, workerBus, null);
return new WebWorkerPlatformLocation(factory, workerBus, null !);
}
function testPushOrReplaceState(pushState: boolean) {
const platformLocation = createWebWorkerPlatformLocation(null);
const platformLocation = createWebWorkerPlatformLocation(null !);
const TITLE = 'foo';
const URL = 'http://www.example.com/foo';
expectBrokerCall(broker, pushState ? 'pushState' : 'replaceState', [null, TITLE, URL]);
@ -60,18 +60,18 @@ export function main() {
});
it('should throw if getBaseHrefFromDOM is called', () => {
const platformLocation = createWebWorkerPlatformLocation(null);
const platformLocation = createWebWorkerPlatformLocation(null !);
expect(() => platformLocation.getBaseHrefFromDOM()).toThrowError();
});
it('should get location on init', () => {
const platformLocation = createWebWorkerPlatformLocation(null);
const platformLocation = createWebWorkerPlatformLocation(null !);
expectBrokerCall(broker, 'getLocation');
platformLocation.init();
});
it('should throw if set pathname is called before init finishes', () => {
const platformLocation = createWebWorkerPlatformLocation(null);
const platformLocation = createWebWorkerPlatformLocation(null !);
platformLocation.init();
expect(() => platformLocation.pathname = 'TEST').toThrowError();
});

View File

@ -51,7 +51,7 @@ export function main() {
const domRendererFactory = uiInjector.get(RendererFactory2);
// Worker side
lastCreatedRenderer = null;
lastCreatedRenderer = null !;
wwRenderStore = new RenderStore();
@ -72,7 +72,7 @@ export function main() {
});
function getRenderElement(workerEl: any): any {
const id = wwRenderStore.serialize(workerEl);
const id = wwRenderStore.serialize(workerEl) !;
return uiRenderStore.deserialize(id);
}
@ -205,7 +205,7 @@ function createWebWorkerRendererFactory2(
}
class RenderFactory extends WebWorkerRendererFactory2 {
createRenderer(element: any, type: RendererType2): Renderer2 {
createRenderer(element: any, type: RendererType2|null): Renderer2 {
lastCreatedRenderer = super.createRenderer(element, type);
return lastCreatedRenderer;
}

View File

@ -4,6 +4,7 @@
"declaration": true,
"stripInternal": true,
"experimentalDecorators": true,
"strictNullChecks": true,
"module": "es2015",
"moduleResolution": "node",
"outDir": "../../dist/packages/platform-webworker",

View File

@ -891,7 +891,7 @@ export declare abstract class RootRenderer {
/** @stable */
export declare abstract class Sanitizer {
abstract sanitize(context: SecurityContext, value: string): string;
abstract sanitize(context: SecurityContext, value: string): string | null;
}
/** @experimental */

View File

@ -1,5 +1,5 @@
/** @stable */
export declare const platformBrowserDynamic: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformBrowserDynamic: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @experimental */
export declare const RESOURCE_CACHE_PROVIDER: Provider[];

View File

@ -3,4 +3,4 @@ export declare class BrowserDynamicTestingModule {
}
/** @stable */
export declare const platformBrowserDynamicTesting: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformBrowserDynamicTesting: (extraProviders?: Provider[] | undefined) => PlatformRef;

View File

@ -26,7 +26,7 @@ export declare abstract class DomSanitizer implements Sanitizer {
abstract bypassSecurityTrustScript(value: string): SafeScript;
abstract bypassSecurityTrustStyle(value: string): SafeStyle;
abstract bypassSecurityTrustUrl(value: string): SafeUrl;
abstract sanitize(context: SecurityContext, value: any): string;
abstract sanitize(context: SecurityContext, value: any): string | null;
}
/** @experimental */
@ -58,13 +58,13 @@ export declare class HammerGestureConfig {
/** @experimental */
export declare class Meta {
constructor(_doc: any);
addTag(tag: MetaDefinition, forceCreation?: boolean): HTMLMetaElement;
addTag(tag: MetaDefinition, forceCreation?: boolean): HTMLMetaElement | null;
addTags(tags: MetaDefinition[], forceCreation?: boolean): HTMLMetaElement[];
getTag(attrSelector: string): HTMLMetaElement;
getTag(attrSelector: string): HTMLMetaElement | null;
getTags(attrSelector: string): HTMLMetaElement[];
removeTag(attrSelector: string): void;
removeTagElement(meta: HTMLMetaElement): void;
updateTag(tag: MetaDefinition, selector?: string): HTMLMetaElement;
updateTag(tag: MetaDefinition, selector?: string): HTMLMetaElement | null;
}
/** @experimental */

View File

@ -3,4 +3,4 @@ export declare class BrowserTestingModule {
}
/** @stable */
export declare const platformBrowserTesting: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformBrowserTesting: (extraProviders?: Provider[] | undefined) => PlatformRef;

View File

@ -8,10 +8,10 @@ export interface PlatformConfig {
}
/** @experimental */
export declare const platformDynamicServer: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformDynamicServer: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @experimental */
export declare const platformServer: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformServer: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @experimental */
export declare class PlatformState {

View File

@ -1,5 +1,5 @@
/** @experimental */
export declare const platformServerTesting: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformServerTesting: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @experimental */
export declare class ServerTestingModule {

View File

@ -1,5 +1,5 @@
/** @experimental */
export declare const platformWorkerAppDynamic: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformWorkerAppDynamic: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @stable */
export declare const VERSION: Version;

View File

@ -3,7 +3,7 @@ export declare function bootstrapWorkerUi(workerScriptUri: string, customProvide
/** @experimental */
export declare abstract class ClientMessageBroker {
abstract runOnService(args: UiArguments, returnType: Type<any> | SerializerTypes): Promise<any>;
abstract runOnService(args: UiArguments, returnType: Type<any> | SerializerTypes | null): Promise<any> | null;
}
/** @experimental */
@ -41,10 +41,10 @@ export interface MessageBusSource {
}
/** @experimental */
export declare const platformWorkerApp: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformWorkerApp: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @experimental */
export declare const platformWorkerUi: (extraProviders?: Provider[]) => PlatformRef;
export declare const platformWorkerUi: (extraProviders?: Provider[] | undefined) => PlatformRef;
/** @experimental */
export declare const PRIMITIVE: SerializerTypes;
@ -66,7 +66,7 @@ export declare const enum SerializerTypes {
/** @experimental */
export declare abstract class ServiceMessageBroker {
abstract registerMethod(methodName: string, signature: Array<Type<any> | SerializerTypes>, method: Function, returnType?: Type<any> | SerializerTypes): void;
abstract registerMethod(methodName: string, signature: Array<Type<any> | SerializerTypes> | null, method: Function, returnType?: Type<any> | SerializerTypes): void;
}
/** @experimental */