mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
style(util): style updates
This commit is contained in:
@ -1,22 +1,74 @@
|
||||
import { ChangeDetectorRef, ElementRef, NgZone, Renderer } from '@angular/core';
|
||||
import { ChangeDetectorRef, ComponentRef, ElementRef, NgZone, Renderer, ViewContainerRef } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
|
||||
import { App, Config, Form, GestureController, Keyboard, MenuController, NavOptions, Platform, Tab, Tabs, Transition, ViewController } from '../../src';
|
||||
import { NavControllerBase } from '../../src/components/nav/nav-controller-base';
|
||||
import { AnimationOptions } from '../animations/animation';
|
||||
import { App } from '../components/app/app';
|
||||
import { IonicApp } from '../components/app/app-root';
|
||||
import { Config } from '../config/config';
|
||||
import { DeepLinker } from '../navigation/deep-linker';
|
||||
import { Form } from './form';
|
||||
import { GestureController } from '../gestures/gesture-controller';
|
||||
import { Keyboard } from './keyboard';
|
||||
import { Menu } from '../components/menu/menu';
|
||||
import { NavOptions, ViewState, DeepLinkConfig } from '../navigation/nav-util';
|
||||
import { OverlayPortal } from '../components/nav/overlay-portal';
|
||||
import { PageTransition } from '../transitions/page-transition';
|
||||
import { Platform } from '../platform/platform';
|
||||
import { QueryParams } from '../platform/query-params';
|
||||
import { Tab } from '../components/tabs/tab';
|
||||
import { Tabs } from '../components/tabs/tabs';
|
||||
import { Transition } from '../transitions/transition';
|
||||
import { TransitionController } from '../transitions/transition-controller';
|
||||
import { UrlSerializer } from '../navigation/url-serializer';
|
||||
import { ViewController } from '../navigation/view-controller';
|
||||
|
||||
import { NavControllerBase } from '../navigation/nav-controller-base';
|
||||
|
||||
export const mockConfig = function(config?: any) {
|
||||
return new Config(config);
|
||||
export const mockConfig = function(config?: any, url: string = '/', platform?: Platform) {
|
||||
const c = new Config();
|
||||
const q = mockQueryParams();
|
||||
const p = platform || mockPlatform();
|
||||
c.init(config, q, p);
|
||||
return c;
|
||||
};
|
||||
|
||||
export const mockPlatform = function(platforms?: string[]) {
|
||||
return new Platform(platforms);
|
||||
export const mockQueryParams = function(url: string = '/') {
|
||||
return new QueryParams(url);
|
||||
};
|
||||
|
||||
export const mockPlatform = function() {
|
||||
return new Platform();
|
||||
};
|
||||
|
||||
export const mockApp = function(config?: Config, platform?: Platform) {
|
||||
config = config || mockConfig();
|
||||
platform = platform || mockPlatform();
|
||||
return new App(config, platform);
|
||||
config = config || mockConfig(null, '/', platform);
|
||||
let app = new App(config, platform);
|
||||
mockIonicApp(app, config, platform);
|
||||
return app;
|
||||
};
|
||||
|
||||
export const mockIonicApp = function(app: App, config: Config, platform: Platform): IonicApp {
|
||||
let appRoot = new IonicApp(
|
||||
null, null, mockElementRef(), mockRenderer(), config, platform, null, app);
|
||||
|
||||
appRoot._loadingPortal = mockOverlayPortal(app, config, platform);
|
||||
appRoot._toastPortal = mockOverlayPortal(app, config, platform);
|
||||
appRoot._overlayPortal = mockOverlayPortal(app, config, platform);
|
||||
|
||||
return appRoot;
|
||||
};
|
||||
|
||||
export const mockTrasitionController = function() {
|
||||
let trnsCtrl = new TransitionController();
|
||||
trnsCtrl.get = (trnsId: number, enteringView: ViewController, leavingView: ViewController, opts: AnimationOptions) => {
|
||||
let trns = new PageTransition(enteringView, leavingView, opts, (callback: Function) => {
|
||||
callback();
|
||||
});
|
||||
trns.trnsId = trnsId;
|
||||
return trns;
|
||||
};
|
||||
return trnsCtrl;
|
||||
};
|
||||
|
||||
export const mockZone = function(): NgZone {
|
||||
@ -34,23 +86,108 @@ export const mockZone = function(): NgZone {
|
||||
export const mockChangeDetectorRef = function(): ChangeDetectorRef {
|
||||
let cd: any = {
|
||||
reattach: () => {},
|
||||
detach: () => {}
|
||||
detach: () => {},
|
||||
detectChanges: () => {}
|
||||
};
|
||||
return cd;
|
||||
};
|
||||
|
||||
export class MockElementRef implements ElementRef {
|
||||
nativeElement: any = new MockElement();
|
||||
}
|
||||
|
||||
export class MockElement {
|
||||
children: any[] = [];
|
||||
classList = new ClassList();
|
||||
attributes: { [name: string]: any } = {};
|
||||
style: {[property: string]: any} = {};
|
||||
|
||||
clientWidth = 0;
|
||||
clientHeight = 0;
|
||||
clientTop = 0;
|
||||
clientLeft = 0;
|
||||
offsetWidth = 0;
|
||||
offsetHeight = 0;
|
||||
offsetTop = 0;
|
||||
offsetLeft = 0;
|
||||
scrollTop = 0;
|
||||
scrollHeight = 0;
|
||||
|
||||
get className() {
|
||||
return this.classList.classes.join(' ');
|
||||
}
|
||||
set className(val: string) {
|
||||
this.classList.classes = val.split(' ');
|
||||
}
|
||||
|
||||
hasAttribute(name: string) {
|
||||
return !!this.attributes[name];
|
||||
}
|
||||
|
||||
getAttribute(name: string) {
|
||||
return this.attributes[name];
|
||||
}
|
||||
|
||||
setAttribute(name: string, val: any) {
|
||||
this.attributes[name] = val;
|
||||
}
|
||||
|
||||
removeAttribute(name: string) {
|
||||
delete this.attributes[name];
|
||||
}
|
||||
}
|
||||
|
||||
export class ClassList {
|
||||
classes: string[] = [];
|
||||
add(className: string) {
|
||||
if (!this.contains(className)) {
|
||||
this.classes.push(className);
|
||||
}
|
||||
}
|
||||
remove(className: string) {
|
||||
const index = this.classes.indexOf(className);
|
||||
if (index > -1) {
|
||||
this.classes.splice(index, 1);
|
||||
}
|
||||
}
|
||||
toggle(className: string) {
|
||||
if (this.contains(className)) {
|
||||
this.remove(className);
|
||||
} else {
|
||||
this.add(className);
|
||||
}
|
||||
}
|
||||
contains(className: string) {
|
||||
return this.classes.indexOf(className) > -1;
|
||||
}
|
||||
}
|
||||
|
||||
export const mockElementRef = function(): ElementRef {
|
||||
return {
|
||||
nativeElement: document.createElement('div')
|
||||
};
|
||||
return new MockElementRef();
|
||||
};
|
||||
|
||||
export class MockRenderer {
|
||||
setElementAttribute(renderElement: MockElement, name: string, val: any) {
|
||||
if (name === null) {
|
||||
renderElement.removeAttribute(name);
|
||||
} else {
|
||||
renderElement.setAttribute(name, val);
|
||||
}
|
||||
}
|
||||
setElementClass(renderElement: MockElement, className: string, isAdd: boolean) {
|
||||
if (isAdd) {
|
||||
renderElement.classList.add(className);
|
||||
} else {
|
||||
renderElement.classList.remove(className);
|
||||
}
|
||||
}
|
||||
setElementStyle(renderElement: MockElement, styleName: string, styleValue: string) {
|
||||
renderElement.style[styleName] = styleValue;
|
||||
}
|
||||
}
|
||||
|
||||
export const mockRenderer = function(): Renderer {
|
||||
let renderer: any = {
|
||||
setElementAttribute: () => {},
|
||||
setElementClass: () => {},
|
||||
setElementStyle: () => {}
|
||||
};
|
||||
const renderer: any = new MockRenderer();
|
||||
return renderer;
|
||||
};
|
||||
|
||||
@ -64,24 +201,41 @@ export const mockLocation = function(): Location {
|
||||
return location;
|
||||
};
|
||||
|
||||
export const mockTransition = function(playCallback: Function, duration: number) {
|
||||
return function _createTrans(enteringView: ViewController, leavingView: ViewController, transitionOpts: any): Transition {
|
||||
let transition: any = {
|
||||
play: () => {
|
||||
playCallback();
|
||||
},
|
||||
getDuration: () => { return duration; },
|
||||
onFinish: () => {}
|
||||
export const mockView = function(component?: any, data?: any) {
|
||||
if (!component) {
|
||||
component = MockView;
|
||||
}
|
||||
let view = new ViewController(component, data);
|
||||
view.init(mockComponentRef());
|
||||
return view;
|
||||
};
|
||||
return transition;
|
||||
|
||||
export const mockViews = function(nav: NavControllerBase, views: ViewController[]) {
|
||||
nav._views = views;
|
||||
views.forEach(v => v._setNav(nav));
|
||||
};
|
||||
|
||||
export const mockComponentRef = function(): ComponentRef<any> {
|
||||
let componentRef: any = {
|
||||
location: mockElementRef(),
|
||||
changeDetectorRef: mockChangeDetectorRef(),
|
||||
destroy: () => {}
|
||||
};
|
||||
return componentRef;
|
||||
};
|
||||
|
||||
export const mockDeepLinker = function(linkConfig: DeepLinkConfig = null, app?: App) {
|
||||
let serializer = new UrlSerializer(linkConfig);
|
||||
|
||||
let location = mockLocation();
|
||||
|
||||
return new DeepLinker(app || mockApp(), serializer, location);
|
||||
};
|
||||
|
||||
export const mockNavController = function(): NavControllerBase {
|
||||
let platform = mockPlatform();
|
||||
|
||||
let config = mockConfig();
|
||||
config.setPlatform(platform);
|
||||
let config = mockConfig(null, '/', platform);
|
||||
|
||||
let app = mockApp(config, platform);
|
||||
|
||||
@ -95,13 +249,15 @@ export const mockNavController = function(): NavControllerBase {
|
||||
|
||||
let renderer = mockRenderer();
|
||||
|
||||
let compiler: any = null;
|
||||
let componentFactoryResolver: any = null;
|
||||
|
||||
let gestureCtrl = new GestureController(app);
|
||||
|
||||
let location = mockLocation();
|
||||
let linker = mockDeepLinker(null, app);
|
||||
|
||||
return new NavControllerBase(
|
||||
let trnsCtrl = mockTrasitionController();
|
||||
|
||||
let nav = new NavControllerBase(
|
||||
null,
|
||||
app,
|
||||
config,
|
||||
@ -109,16 +265,69 @@ export const mockNavController = function(): NavControllerBase {
|
||||
elementRef,
|
||||
zone,
|
||||
renderer,
|
||||
compiler,
|
||||
gestureCtrl
|
||||
componentFactoryResolver,
|
||||
gestureCtrl,
|
||||
trnsCtrl,
|
||||
linker
|
||||
);
|
||||
|
||||
nav._viewInit = function(trns: Transition, enteringView: ViewController, opts: NavOptions) {
|
||||
enteringView.init(mockComponentRef());
|
||||
enteringView._state = ViewState.INITIALIZED;
|
||||
};
|
||||
|
||||
(<any>nav)._orgViewInsert = nav._viewInsert;
|
||||
|
||||
nav._viewInsert = function(view: ViewController, componentRef: ComponentRef<any>, viewport: ViewContainerRef) {
|
||||
let mockedViewport: any = {
|
||||
insert: () => { }
|
||||
};
|
||||
(<any>nav)._orgViewInsert(view, componentRef, mockedViewport);
|
||||
};
|
||||
|
||||
return nav;
|
||||
};
|
||||
|
||||
export const mockOverlayPortal = function(app: App, config: Config, platform: Platform): OverlayPortal {
|
||||
let form = new Form();
|
||||
|
||||
let zone = mockZone();
|
||||
|
||||
let keyboard = new Keyboard(config, form, zone);
|
||||
|
||||
let elementRef = mockElementRef();
|
||||
|
||||
let renderer = mockRenderer();
|
||||
|
||||
let componentFactoryResolver: any = null;
|
||||
|
||||
let gestureCtrl = new GestureController(app);
|
||||
|
||||
let serializer = new UrlSerializer(null);
|
||||
|
||||
let location = mockLocation();
|
||||
|
||||
let deepLinker = new DeepLinker(app, serializer, location);
|
||||
|
||||
return new OverlayPortal(
|
||||
app,
|
||||
config,
|
||||
keyboard,
|
||||
elementRef,
|
||||
zone,
|
||||
renderer,
|
||||
componentFactoryResolver,
|
||||
gestureCtrl,
|
||||
null,
|
||||
deepLinker,
|
||||
null
|
||||
);
|
||||
};
|
||||
|
||||
export const mockTab = function(parentTabs: Tabs): Tab {
|
||||
let platform = mockPlatform();
|
||||
|
||||
let config = mockConfig();
|
||||
config.setPlatform(platform);
|
||||
let config = mockConfig(null, '/', platform);
|
||||
|
||||
let app = (<any>parentTabs)._app || mockApp(config, platform);
|
||||
|
||||
@ -138,7 +347,7 @@ export const mockTab = function(parentTabs: Tabs): Tab {
|
||||
|
||||
let gestureCtrl = new GestureController(app);
|
||||
|
||||
let location = mockLocation();
|
||||
let linker = mockDeepLinker(null, app);
|
||||
|
||||
let tab = new Tab(
|
||||
parentTabs,
|
||||
@ -150,7 +359,9 @@ export const mockTab = function(parentTabs: Tabs): Tab {
|
||||
renderer,
|
||||
compiler,
|
||||
changeDetectorRef,
|
||||
gestureCtrl
|
||||
gestureCtrl,
|
||||
null,
|
||||
linker
|
||||
);
|
||||
|
||||
tab.load = (opts: any, cb: Function) => {
|
||||
@ -161,11 +372,37 @@ export const mockTab = function(parentTabs: Tabs): Tab {
|
||||
};
|
||||
|
||||
export const mockTabs = function(app?: App): Tabs {
|
||||
let config = mockConfig();
|
||||
let platform = mockPlatform();
|
||||
let config = mockConfig(null, '/', platform);
|
||||
app = app || mockApp(config, platform);
|
||||
let elementRef = mockElementRef();
|
||||
let renderer = mockRenderer();
|
||||
let linker: DeepLinker = mockDeepLinker();
|
||||
|
||||
return new Tabs(null, null, app, config, elementRef, platform, renderer);
|
||||
return new Tabs(null, null, app, config, elementRef, platform, renderer, linker);
|
||||
};
|
||||
|
||||
export const mockMenu = function(): Menu {
|
||||
return new Menu(null, null, null, null, null, null, null, null);
|
||||
};
|
||||
|
||||
export const mockDeepLinkConfig = function(links?: any[]): DeepLinkConfig {
|
||||
return {
|
||||
links: links || [
|
||||
{ component: MockView1, name: 'viewone' },
|
||||
{ component: MockView2, name: 'viewtwo' },
|
||||
{ component: MockView3, name: 'viewthree' },
|
||||
{ component: MockView4, name: 'viewfour' },
|
||||
{ component: MockView5, name: 'viewfive' }
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
export class MockView {}
|
||||
export class MockView1 {}
|
||||
export class MockView2 {}
|
||||
export class MockView3 {}
|
||||
export class MockView4 {}
|
||||
export class MockView5 {}
|
||||
|
||||
export function noop(): any { return 'noop'; };
|
||||
|
@ -28,7 +28,7 @@ export class ScrollView {
|
||||
this._top = top;
|
||||
|
||||
if (this._js) {
|
||||
this._el.style[CSS.transform] = `translate3d(0px,${top * -1}px,0px)`;
|
||||
(<any>this._el.style)[CSS.transform] = `translate3d(0px,${top * -1}px,0px)`;
|
||||
|
||||
} else {
|
||||
this._el.scrollTop = top;
|
||||
@ -51,8 +51,6 @@ export class ScrollView {
|
||||
let fromY = self._el.scrollTop;
|
||||
let fromX = self._el.scrollLeft;
|
||||
|
||||
let xDistance = Math.abs(x - fromX);
|
||||
let yDistance = Math.abs(y - fromY);
|
||||
let maxAttempts = (duration / 16) + 100;
|
||||
|
||||
return new Promise(resolve => {
|
||||
@ -278,7 +276,6 @@ export class ScrollView {
|
||||
|
||||
}
|
||||
|
||||
const MAX_VELOCITY = 150;
|
||||
const MIN_VELOCITY_START_DECELERATION = 4;
|
||||
const MIN_VELOCITY_CONTINUE_DECELERATION = 0.12;
|
||||
const DECELERATION_FRICTION = 0.97;
|
||||
|
@ -1,6 +1,4 @@
|
||||
import * as datetime from '../../../src/util/datetime-util';
|
||||
|
||||
export function run() {
|
||||
import * as datetime from '../datetime-util';
|
||||
|
||||
describe('convertDataToISO', () => {
|
||||
|
||||
@ -876,5 +874,3 @@ var customLocale: datetime.LocaleData = {
|
||||
'dez'
|
||||
],
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
import * as util from '../../../src/util';
|
||||
|
||||
export function run() {
|
||||
import * as util from '../util';
|
||||
|
||||
describe('isPrimitive', () => {
|
||||
|
||||
@ -264,74 +262,6 @@ export function run() {
|
||||
|
||||
});
|
||||
|
||||
describe('getQuerystring', () => {
|
||||
it('should have no entries for empty url', () => {
|
||||
expect(util.getQuerystring('')).toEqual({});
|
||||
expect(util.getQuerystring(null)).toEqual({});
|
||||
expect(util.getQuerystring(undefined)).toEqual({});
|
||||
});
|
||||
|
||||
it('should have no entries when without ?', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/')).toEqual({});
|
||||
});
|
||||
|
||||
it('should have no entries with only ?', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/?')).toEqual({});
|
||||
});
|
||||
|
||||
it('should have no entries for key with no =', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/?key')).toEqual({});
|
||||
});
|
||||
|
||||
it('should have no entries with only #?', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#?')).toEqual({});
|
||||
});
|
||||
|
||||
it('should have no entries with only #?=', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#?=')).toEqual({});
|
||||
});
|
||||
|
||||
it('should have no entries for url with no "?" character', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#key1=1&key2=2')).toEqual({});
|
||||
});
|
||||
|
||||
it('should contain key/value entries for all the parameters after "?" character', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#key1=1&key2x=2x?key3=3&key4=4')).toEqual({
|
||||
key3: '3',
|
||||
key4: '4'
|
||||
});
|
||||
});
|
||||
|
||||
it('should lowercase param keys', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#?KEY1=1&kEy2=2')).toEqual({
|
||||
key1: '1',
|
||||
key2: '2'
|
||||
});
|
||||
});
|
||||
|
||||
it('should not include any values when # comes after ?', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/?key1=1#key2=2')).toEqual({
|
||||
key1: '1'
|
||||
});
|
||||
});
|
||||
|
||||
it('should ignore empty ?& and &&', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#?&&')).toEqual({});
|
||||
|
||||
expect(util.getQuerystring('http://localhost:1234/#?&&key1=1&key2=2&&')).toEqual({
|
||||
key1: '1',
|
||||
key2: '2'
|
||||
});
|
||||
});
|
||||
|
||||
it('should get "" when key has no value', () => {
|
||||
expect(util.getQuerystring('http://localhost:1234/#?key=')).toEqual({
|
||||
key: ''
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('isTrueProperty', () => {
|
||||
|
||||
it('should be true from boolean true', () => {
|
||||
@ -430,4 +360,3 @@ export function run() {
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user