mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
fix(build): update angular build process
This commit is contained in:
@ -1,15 +1,26 @@
|
|||||||
import { DIST_BUILD_ROOT, PROJECT_ROOT } from '../constants';
|
import { SRC_ROOT, DIST_BUILD_ROOT, PROJECT_ROOT } from '../constants';
|
||||||
import { task } from 'gulp';
|
import { task } from 'gulp';
|
||||||
import { accessSync } from 'fs';
|
import { accessSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
|
|
||||||
task('core', (done) => {
|
task('core', (done) => {
|
||||||
|
buildAngularBinding(false, done);
|
||||||
|
});
|
||||||
|
|
||||||
|
task('core.watch', (done) => {
|
||||||
|
buildAngularBinding(true, done);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function buildAngularBinding(skipBuildingCore: boolean, done: Function) {
|
||||||
const cwd = join(PROJECT_ROOT, '../ionic-core');
|
const cwd = join(PROJECT_ROOT, '../ionic-core');
|
||||||
const args = [
|
const args = [
|
||||||
'run',
|
'run',
|
||||||
'build.angular',
|
'build.angular',
|
||||||
DIST_BUILD_ROOT
|
SRC_ROOT,
|
||||||
|
DIST_BUILD_ROOT,
|
||||||
|
skipBuildingCore ? 'skip-core' : 'do-not-skip-core'
|
||||||
];
|
];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -33,4 +44,4 @@ task('core', (done) => {
|
|||||||
ls.on('close', (code) => {
|
ls.on('close', (code) => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { task } from 'gulp';
|
|||||||
import { ES_2015, PROJECT_ROOT } from '../constants';
|
import { ES_2015, PROJECT_ROOT } from '../constants';
|
||||||
import { createTempTsConfig, getFolderInfo, runAppScriptsServe } from '../util';
|
import { createTempTsConfig, getFolderInfo, runAppScriptsServe } from '../util';
|
||||||
|
|
||||||
task('e2e.watch', ['e2e.prepare'], (done: Function) => {
|
task('e2e.watch', ['e2e.prepare', 'core.watch'], (done: Function) => {
|
||||||
const folderInfo = getFolderInfo();
|
const folderInfo = getFolderInfo();
|
||||||
if (!folderInfo || !folderInfo.componentName || !folderInfo.componentTest) {
|
if (!folderInfo || !folderInfo.componentName || !folderInfo.componentTest) {
|
||||||
done(new Error(`Usage: gulp e2e.watch --folder nav/basic`));
|
done(new Error(`Usage: gulp e2e.watch --folder nav/basic`));
|
||||||
|
@ -15,7 +15,7 @@ import { createTempTsConfig, createTimestamp, getFolderInfo, readFileAsync, runA
|
|||||||
import * as pAll from 'p-all';
|
import * as pAll from 'p-all';
|
||||||
|
|
||||||
task('e2e.prepare', (done: Function) => {
|
task('e2e.prepare', (done: Function) => {
|
||||||
runSequence('e2e.clean', 'core', 'e2e.polyfill', 'e2e.prepareSass', (err: any) => done(err));
|
runSequence('e2e.clean', 'e2e.polyfill', 'e2e.prepareSass', (err: any) => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
task('e2e.prepareSass', (done: Function) => {
|
task('e2e.prepareSass', (done: Function) => {
|
||||||
@ -24,7 +24,7 @@ task('e2e.prepareSass', (done: Function) => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
task('e2e.prod', ['e2e.prepare'], (done: Function) => {
|
task('e2e.prod', ['e2e.prepare', 'core'], (done: Function) => {
|
||||||
// okay, first find out all of the e2e tests to run by finding all of the 'main.ts' files
|
// okay, first find out all of the e2e tests to run by finding all of the 'main.ts' files
|
||||||
filterE2eTestfiles().then((filePaths: string[]) => {
|
filterE2eTestfiles().then((filePaths: string[]) => {
|
||||||
if (filePaths && filePaths.length > 0) {
|
if (filePaths && filePaths.length > 0) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '../../index';
|
import { Component } from '../index';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
@import "../../themes/ionic.globals";
|
@import "../../themes/ionic.globals";
|
||||||
|
|
||||||
|
|
||||||
// Card
|
// Card
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
ion-card-content,
|
ion-card-content,
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
|
visibility: inherit !important;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '../../index';
|
import { Component } from '../index';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@import "../../themes/ionic.globals";
|
@import "../../themes/ionic.globals";
|
||||||
|
|
||||||
|
|
||||||
// Card Header
|
// Card Header
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ ion-card-header,
|
|||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
visibility: inherit !important;
|
||||||
|
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '../../index';
|
import { Component } from '../index';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '../../index';
|
import { Component } from '../index';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
@import "../../themes/ionic.globals.ios";
|
@import "../../themes/ionic.globals.ios";
|
||||||
|
@import "./card";
|
||||||
|
|
||||||
|
|
||||||
// iOS Card
|
// iOS Card
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
@import "../../themes/ionic.globals.md";
|
@import "../../themes/ionic.globals.md";
|
||||||
|
@import "./card";
|
||||||
|
|
||||||
|
|
||||||
// Material Design Card
|
// Material Design Card
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@import "../../themes/ionic.globals";
|
@import "../../themes/ionic.globals";
|
||||||
|
|
||||||
|
|
||||||
// Card
|
// Card
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ ion-card,
|
|||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
visibility: inherit !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-card img,
|
ion-card img,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component } from '../../index';
|
import { Component } from '../index';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
@import "../../themes/ionic.globals.wp";
|
@import "../../themes/ionic.globals.wp";
|
||||||
|
@import "./card";
|
||||||
|
|
||||||
|
|
||||||
// Windows Card
|
// Windows Card
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { applyStyles, getElementReference, pointerCoordX, pointerCoordY } from '../../util/dom';
|
import { applyStyles, getElementReference, pointerCoordX, pointerCoordY } from '../../util/dom';
|
||||||
import { Component, Listen, Ionic, Prop } from '../../index';
|
import { Component, Listen, Ionic, Prop } from '../index';
|
||||||
import { GestureCallback, GestureDetail } from '../../util/interfaces';
|
import { GestureCallback, GestureDetail } from '../../util/interfaces';
|
||||||
import { GestureController, GestureDelegate } from './gesture-controller';
|
import { GestureController, GestureDelegate } from './gesture-controller';
|
||||||
import { PanRecognizer } from './recognizers';
|
import { PanRecognizer } from './recognizers';
|
||||||
@ -20,6 +20,7 @@ export class Gesture {
|
|||||||
private hasPress = false;
|
private hasPress = false;
|
||||||
private hasStartedPan = false;
|
private hasStartedPan = false;
|
||||||
private requiresMove = false;
|
private requiresMove = false;
|
||||||
|
private isMoveQueued = false;
|
||||||
|
|
||||||
@Prop() direction: string = 'x';
|
@Prop() direction: string = 'x';
|
||||||
@Prop() gestureName: string = '';
|
@Prop() gestureName: string = '';
|
||||||
@ -153,15 +154,21 @@ export class Gesture {
|
|||||||
|
|
||||||
if (this.pan) {
|
if (this.pan) {
|
||||||
if (this.hasCapturedPan) {
|
if (this.hasCapturedPan) {
|
||||||
Ionic.dom.write(() => {
|
|
||||||
detail.type = 'pan';
|
|
||||||
|
|
||||||
if (this.onMove) {
|
if (!this.isMoveQueued) {
|
||||||
this.onMove(detail);
|
this.isMoveQueued = true;
|
||||||
} else {
|
|
||||||
Ionic.emit(this, 'ionGestureMove', this.detail);
|
Ionic.dom.write(() => {
|
||||||
}
|
this.isMoveQueued = false;
|
||||||
});
|
detail.type = 'pan';
|
||||||
|
|
||||||
|
if (this.onMove) {
|
||||||
|
this.onMove(detail);
|
||||||
|
} else {
|
||||||
|
Ionic.emit(this, 'ionGestureMove', { detail: this.detail });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} else if (this.pan.detect(detail.currentX, detail.currentY)) {
|
} else if (this.pan.detect(detail.currentX, detail.currentY)) {
|
||||||
if (this.pan.isGesture() !== 0) {
|
if (this.pan.isGesture() !== 0) {
|
||||||
@ -201,14 +208,14 @@ export class Gesture {
|
|||||||
// compute relative movement between these two points
|
// compute relative movement between these two points
|
||||||
var movedX = (positions[startPos - 2] - positions[endPos - 2]);
|
var movedX = (positions[startPos - 2] - positions[endPos - 2]);
|
||||||
var movedY = (positions[startPos - 1] - positions[endPos - 1]);
|
var movedY = (positions[startPos - 1] - positions[endPos - 1]);
|
||||||
var factor = 16 / (positions[endPos] - positions[startPos]);
|
var factor = 16.67 / (positions[endPos] - positions[startPos]);
|
||||||
|
|
||||||
// based on XXms compute the movement to apply for each render step
|
// based on XXms compute the movement to apply for each render step
|
||||||
detail.velocityX = movedX * factor;
|
detail.velocityX = movedX * factor;
|
||||||
detail.velocityY = movedY * factor;
|
detail.velocityY = movedY * factor;
|
||||||
|
|
||||||
detail.velocityDirectionX = (detail.velocityX > 0 ? 'left' : (detail.velocityX < 0 ? 'right' : null));
|
detail.velocityDirectionX = (movedX > 0 ? 'left' : (movedX < 0 ? 'right' : null));
|
||||||
detail.velocityDirectionY = (detail.velocityY > 0 ? 'up' : (detail.velocityY < 0 ? 'down' : null));
|
detail.velocityDirectionY = (movedY > 0 ? 'up' : (movedY < 0 ? 'down' : null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +229,7 @@ export class Gesture {
|
|||||||
if (this.onStart) {
|
if (this.onStart) {
|
||||||
this.onStart(this.detail);
|
this.onStart(this.detail);
|
||||||
} else {
|
} else {
|
||||||
Ionic.emit(this, 'ionGestureStart', this.detail);
|
Ionic.emit(this, 'ionGestureStart', { detail: this.detail });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hasCapturedPan = true;
|
this.hasCapturedPan = true;
|
||||||
@ -279,7 +286,7 @@ export class Gesture {
|
|||||||
if (this.onEnd) {
|
if (this.onEnd) {
|
||||||
this.onEnd(detail);
|
this.onEnd(detail);
|
||||||
} else {
|
} else {
|
||||||
Ionic.emit(this, 'ionGestureEnd', detail);
|
Ionic.emit(this, 'ionGestureEnd', { detail: detail });
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (this.hasPress) {
|
} else if (this.hasPress) {
|
||||||
@ -289,7 +296,7 @@ export class Gesture {
|
|||||||
if (this.notCaptured) {
|
if (this.notCaptured) {
|
||||||
this.notCaptured(detail);
|
this.notCaptured(detail);
|
||||||
} else {
|
} else {
|
||||||
Ionic.emit(this, 'ionGestureNotCaptured', detail);
|
Ionic.emit(this, 'ionGestureNotCaptured', { detail: detail });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +318,7 @@ export class Gesture {
|
|||||||
if (this.onPress) {
|
if (this.onPress) {
|
||||||
this.onPress(detail);
|
this.onPress(detail);
|
||||||
} else {
|
} else {
|
||||||
Ionic.emit(this, 'ionPress', detail);
|
Ionic.emit(this, 'ionPress', { detail: detail });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/components/index.ts
Normal file
15
src/components/index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
import * as interfaces from '../util/interfaces';
|
||||||
|
|
||||||
|
|
||||||
|
export declare const Component: interfaces.ComponentDecorator;
|
||||||
|
|
||||||
|
export declare const h: interfaces.Hyperscript;
|
||||||
|
|
||||||
|
export declare const Ionic: interfaces.Ionic;
|
||||||
|
|
||||||
|
export declare const Listen: interfaces.ListenDecorator;
|
||||||
|
|
||||||
|
export declare const Prop: interfaces.PropDecorator;
|
||||||
|
|
||||||
|
export declare const Watch: interfaces.WatchDecorator;
|
14
src/components/scroll/scroll-interface.ts
Normal file
14
src/components/scroll/scroll-interface.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { ScrollCallback } from '../../util/interfaces';
|
||||||
|
|
||||||
|
|
||||||
|
export interface Scroll {
|
||||||
|
enabled: boolean;
|
||||||
|
jsScroll: boolean;
|
||||||
|
|
||||||
|
ionScrollStart: ScrollCallback;
|
||||||
|
ionScroll: ScrollCallback;
|
||||||
|
ionScrollEnd: ScrollCallback;
|
||||||
|
|
||||||
|
scrollToTop: (duration: number) => Promise<void>;
|
||||||
|
scrollToBottom: (duration: number) => Promise<void>;
|
||||||
|
}
|
@ -1,34 +0,0 @@
|
|||||||
@import "../../themes/ionic.globals";
|
|
||||||
|
|
||||||
ion-scroll {
|
|
||||||
position: relative;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-scroll.scroll-x .scroll-content {
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-scroll.scroll-y .scroll-content {
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-scroll[center] .scroll-content {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
ion-scroll .scroll-content {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
overflow-y: hidden;
|
|
||||||
overflow-x: hidden;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
will-change: scroll-position;
|
|
||||||
}
|
|
@ -1,120 +1,360 @@
|
|||||||
import { ChangeDetectionStrategy, Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';
|
import { Component, Listen, Ionic, Prop } from '../index';
|
||||||
|
import { ScrollCallback, ScrollDetail } from '../../util/interfaces';
|
||||||
|
import { GestureController, GestureDelegate } from '../gesture/gesture-controller';
|
||||||
|
import { Scroll as IScroll } from './scroll-interface';
|
||||||
|
|
||||||
import { isTrueProperty, assert } from '../../util/util';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name Scroll
|
|
||||||
* @description
|
|
||||||
* Scroll is a non-flexboxed scroll area that can scroll horizontally or vertically. `ion-Scroll` Can be used in places where you may not need a full page scroller, but a highly customized one, such as image scubber or comment scroller.
|
|
||||||
* @usage
|
|
||||||
* ```html
|
|
||||||
* <ion-scroll scrollX="true">
|
|
||||||
* </ion-scroll>
|
|
||||||
*
|
|
||||||
* <ion-scroll scrollY="true">
|
|
||||||
* </ion-scroll>
|
|
||||||
*
|
|
||||||
* <ion-scroll scrollX="true" scrollY="true">
|
|
||||||
* </ion-scroll>
|
|
||||||
* ```
|
|
||||||
* @demo /docs/demos/src/scroll/
|
|
||||||
*/
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ion-scroll',
|
tag: 'ion-scroll',
|
||||||
template:
|
shadow: false
|
||||||
'<div class="scroll-content" #scrollContent>' +
|
|
||||||
'<div class="scroll-zoom-wrapper">' +
|
|
||||||
'<ng-content></ng-content>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>',
|
|
||||||
host: {
|
|
||||||
'[class.scroll-x]': 'scrollX',
|
|
||||||
'[class.scroll-y]': 'scrollY'
|
|
||||||
},
|
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
||||||
encapsulation: ViewEncapsulation.None,
|
|
||||||
})
|
})
|
||||||
export class Scroll {
|
export class Scroll implements IScroll {
|
||||||
|
private $el: HTMLElement;
|
||||||
|
private gesture: GestureDelegate;
|
||||||
|
private positions: number[] = [];
|
||||||
|
private _l: number;
|
||||||
|
private _t: number;
|
||||||
|
private tmr: any;
|
||||||
|
private queued = false;
|
||||||
|
|
||||||
|
isScrolling: boolean = false;
|
||||||
|
detail: ScrollDetail = {};
|
||||||
|
|
||||||
|
@Prop() enabled: boolean = true;
|
||||||
|
@Prop() jsScroll: boolean = false;
|
||||||
|
@Prop() ionScrollStart: ScrollCallback;
|
||||||
|
@Prop() ionScroll: ScrollCallback;
|
||||||
|
@Prop() ionScrollEnd: ScrollCallback;
|
||||||
|
|
||||||
|
|
||||||
|
ionViewDidLoad() {
|
||||||
|
Ionic.controllers.gesture = (Ionic.controllers.gesture || new GestureController());
|
||||||
|
|
||||||
|
this.gesture = (<GestureController>Ionic.controllers.gesture).createGesture('scroll', 100, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Native Scroll *************************
|
||||||
|
|
||||||
|
@Listen('scroll', { passive: true })
|
||||||
|
onNativeScroll() {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (!self.queued && self.enabled) {
|
||||||
|
self.queued = true;
|
||||||
|
|
||||||
|
Ionic.dom.read(function(timeStamp) {
|
||||||
|
self.queued = false;
|
||||||
|
self.onScroll(timeStamp || Date.now());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onScroll(timeStamp: number) {
|
||||||
|
const self = this;
|
||||||
|
const detail = self.detail;
|
||||||
|
const positions = self.positions;
|
||||||
|
|
||||||
|
detail.timeStamp = timeStamp;
|
||||||
|
|
||||||
|
// get the current scrollTop
|
||||||
|
// ******** DOM READ ****************
|
||||||
|
detail.scrollTop = self.getTop();
|
||||||
|
|
||||||
|
// get the current scrollLeft
|
||||||
|
// ******** DOM READ ****************
|
||||||
|
detail.scrollLeft = self.getLeft();
|
||||||
|
|
||||||
|
if (!self.isScrolling) {
|
||||||
|
// currently not scrolling, so this is a scroll start
|
||||||
|
self.isScrolling = true;
|
||||||
|
|
||||||
|
// remember the start positions
|
||||||
|
detail.startY = detail.scrollTop;
|
||||||
|
detail.startX = detail.scrollLeft;
|
||||||
|
|
||||||
|
// new scroll, so do some resets
|
||||||
|
detail.velocityY = detail.velocityX = detail.deltaY = detail.deltaX = positions.length = 0;
|
||||||
|
|
||||||
|
// emit only on the first scroll event
|
||||||
|
if (self.ionScrollStart) {
|
||||||
|
self.ionScrollStart(detail);
|
||||||
|
} else {
|
||||||
|
Ionic.emit(this, 'ionScrollStart', { detail: detail });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
detail.directionX = detail.velocityDirectionX = (detail.deltaX > 0 ? 'left' : (detail.deltaX < 0 ? 'right' : null));
|
||||||
|
detail.directionY = detail.velocityDirectionY = (detail.deltaY > 0 ? 'up' : (detail.deltaY < 0 ? 'down' : null));
|
||||||
|
|
||||||
|
// actively scrolling
|
||||||
|
positions.push(detail.scrollTop, detail.scrollLeft, detail.timeStamp);
|
||||||
|
|
||||||
|
if (positions.length > 3) {
|
||||||
|
// we've gotten at least 2 scroll events so far
|
||||||
|
detail.deltaY = (detail.scrollTop - detail.startY);
|
||||||
|
detail.deltaX = (detail.scrollLeft - detail.startX);
|
||||||
|
|
||||||
|
var endPos = (positions.length - 1);
|
||||||
|
var startPos = endPos;
|
||||||
|
var timeRange = (detail.timeStamp - 100);
|
||||||
|
|
||||||
|
// move pointer to position measured 100ms ago
|
||||||
|
for (var i = endPos; i > 0 && positions[i] > timeRange; i -= 3) {
|
||||||
|
startPos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startPos !== endPos) {
|
||||||
|
// compute relative movement between these two points
|
||||||
|
var movedTop = (positions[startPos - 2] - positions[endPos - 2]);
|
||||||
|
var movedLeft = (positions[startPos - 1] - positions[endPos - 1]);
|
||||||
|
var factor = 16.67 / (positions[endPos] - positions[startPos]);
|
||||||
|
|
||||||
|
// based on XXms compute the movement to apply for each render step
|
||||||
|
detail.velocityY = movedTop * factor;
|
||||||
|
detail.velocityX = movedLeft * factor;
|
||||||
|
|
||||||
|
// figure out which direction we're scrolling
|
||||||
|
detail.velocityDirectionX = (movedLeft > 0 ? 'left' : (movedLeft < 0 ? 'right' : null));
|
||||||
|
detail.velocityDirectionY = (movedTop > 0 ? 'up' : (movedTop < 0 ? 'down' : null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(self.tmr);
|
||||||
|
self.tmr = setTimeout(function() {
|
||||||
|
|
||||||
|
// haven't scrolled in a while, so it's a scrollend
|
||||||
|
self.isScrolling = false;
|
||||||
|
|
||||||
|
Ionic.dom.read(function(timeStamp) {
|
||||||
|
if (!self.isScrolling) {
|
||||||
|
self.onEnd(timeStamp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 80);
|
||||||
|
|
||||||
|
// emit on each scroll event
|
||||||
|
if (self.ionScrollStart) {
|
||||||
|
self.ionScroll(detail);
|
||||||
|
} else {
|
||||||
|
Ionic.emit(this, 'ionScroll', { detail: detail });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onEnd(timeStamp: number) {
|
||||||
|
const self = this;
|
||||||
|
const detail = self.detail;
|
||||||
|
|
||||||
|
detail.timeStamp = timeStamp || Date.now();
|
||||||
|
|
||||||
|
// emit that the scroll has ended
|
||||||
|
if (self.ionScrollEnd) {
|
||||||
|
self.ionScrollEnd(detail);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Ionic.emit(this, 'ionScrollEnd', { detail: detail });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enableJsScroll(contentTop: number, contentBottom: number) {
|
||||||
|
this.jsScroll = true;
|
||||||
|
|
||||||
|
Ionic.listener.enable(this, 'scroll', false);
|
||||||
|
|
||||||
|
Ionic.listener.enable(this, 'touchstart', true);
|
||||||
|
|
||||||
|
contentTop; contentBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Touch Scroll *************************
|
||||||
|
|
||||||
|
@Listen('touchstart', { passive: true, enabled: false })
|
||||||
|
onTouchStart() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ionic.listener.enable(this, 'touchmove', true);
|
||||||
|
Ionic.listener.enable(this, 'touchend', true);
|
||||||
|
|
||||||
|
throw 'jsScroll: TODO!';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Listen('touchmove', { passive: true, enabled: false })
|
||||||
|
onTouchMove() {
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Listen('touchend', { passive: true, enabled: false })
|
||||||
|
onTouchEnd() {
|
||||||
|
Ionic.listener.enable(this, 'touchmove', false);
|
||||||
|
Ionic.listener.enable(this, 'touchend', false);
|
||||||
|
|
||||||
|
if (!this.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_scrollX: boolean = false;
|
|
||||||
_scrollY: boolean = false;
|
|
||||||
_zoom: boolean = false;
|
|
||||||
_maxZoom: number = 1;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @input {boolean} If true, scrolling along the X axis is enabled.
|
* DOM READ
|
||||||
*/
|
*/
|
||||||
@Input()
|
getTop() {
|
||||||
get scrollX() {
|
if (this.jsScroll) {
|
||||||
return this._scrollX;
|
return this._t;
|
||||||
}
|
}
|
||||||
set scrollX(val: any) {
|
return this._t = this.$el.scrollTop;
|
||||||
this._scrollX = isTrueProperty(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @input {boolean} If true, scrolling along the Y axis is enabled; requires the following CSS declaration: ion-scroll { white-space: nowrap; }
|
* DOM READ
|
||||||
*/
|
*/
|
||||||
@Input()
|
getLeft() {
|
||||||
get scrollY() {
|
if (this.jsScroll) {
|
||||||
return this._scrollY;
|
return 0;
|
||||||
}
|
}
|
||||||
set scrollY(val: any) {
|
return this._l = this.$el.scrollLeft;
|
||||||
this._scrollY = isTrueProperty(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @input {boolean} If true, zooming is enabled.
|
* DOM WRITE
|
||||||
*/
|
*/
|
||||||
@Input()
|
setTop(top: number) {
|
||||||
get zoom() {
|
this._t = top;
|
||||||
return this._zoom;
|
|
||||||
}
|
if (this.jsScroll) {
|
||||||
set zoom(val: any) {
|
this.$el.style.transform = this.$el.style.webkitTransform = `translate3d(${this._l * -1}px,${top * -1}px,0px)`;
|
||||||
this._zoom = isTrueProperty(val);
|
|
||||||
|
} else {
|
||||||
|
this.$el.scrollTop = top;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @input {number} Set the max zoom amount.
|
* DOM WRITE
|
||||||
*/
|
*/
|
||||||
@Input()
|
setLeft(left: number) {
|
||||||
get maxZoom() {
|
this._l = left;
|
||||||
return this._maxZoom;
|
|
||||||
}
|
if (this.jsScroll) {
|
||||||
set maxZoom(val: any) {
|
this.$el.style.transform = this.$el.style.webkitTransform = `translate3d(${left * -1}px,${this._t * -1}px,0px)`;
|
||||||
this._maxZoom = val;
|
|
||||||
|
} else {
|
||||||
|
this.$el.scrollLeft = left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
scrollTo(x: number, y: number, duration: number, done?: Function): Promise<any> {
|
||||||
* @hidden
|
// scroll animation loop w/ easing
|
||||||
*/
|
// credit https://gist.github.com/dezinezync/5487119
|
||||||
maxScale: number = 3;
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
zoomDuration: number = 250;
|
|
||||||
|
|
||||||
/** @internal */
|
let promise: Promise<any>;
|
||||||
@ViewChild('scrollContent', { read: ElementRef }) _scrollContent: ElementRef;
|
if (done === undefined) {
|
||||||
|
// only create a promise if a done callback wasn't provided
|
||||||
|
// done can be a null, which avoids any functions
|
||||||
|
promise = new Promise(resolve => {
|
||||||
|
done = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor(private _elementRef: ElementRef) { }
|
const self = this;
|
||||||
|
const el = self.$el;
|
||||||
|
if (!el) {
|
||||||
|
// invalid element
|
||||||
|
done();
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
if (duration < 32) {
|
||||||
* @hidden
|
self.setTop(y);
|
||||||
* Add a scroll event handler to the scroll element if it exists.
|
self.setLeft(x);
|
||||||
* @param {Function} handler The scroll handler to add to the scroll element.
|
done();
|
||||||
* @returns {?Function} a function to remove the specified handler, otherwise
|
return promise;
|
||||||
* undefined if the scroll element doesn't exist.
|
}
|
||||||
*/
|
|
||||||
addScrollEventListener(handler: any) {
|
|
||||||
assert(this._scrollContent, 'scroll element is missing');
|
|
||||||
|
|
||||||
const ele = this._scrollContent.nativeElement;
|
const fromY = el.scrollTop;
|
||||||
ele.addEventListener('scroll', handler);
|
const fromX = el.scrollLeft;
|
||||||
|
|
||||||
return () => {
|
const maxAttempts = (duration / 16) + 100;
|
||||||
ele.removeEventListener('scroll', handler);
|
|
||||||
};
|
let startTime: number;
|
||||||
|
let attempts = 0;
|
||||||
|
let stopScroll = false;
|
||||||
|
|
||||||
|
// scroll loop
|
||||||
|
function step(timeStamp: number) {
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
if (!self.$el || stopScroll || attempts > maxAttempts) {
|
||||||
|
self.isScrolling = false;
|
||||||
|
el.style.transform = el.style.webkitTransform = '';
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let time = Math.min(1, ((timeStamp - startTime) / duration));
|
||||||
|
|
||||||
|
// where .5 would be 50% of time on a linear scale easedT gives a
|
||||||
|
// fraction based on the easing method
|
||||||
|
let easedT = (--time) * time * time + 1;
|
||||||
|
|
||||||
|
if (fromY !== y) {
|
||||||
|
self.setTop((easedT * (y - fromY)) + fromY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromX !== x) {
|
||||||
|
self.setLeft(Math.floor((easedT * (x - fromX)) + fromX));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (easedT < 1) {
|
||||||
|
// do not use DomController here
|
||||||
|
// must use nativeRaf in order to fire in the next frame
|
||||||
|
Ionic.dom.raf(step);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
stopScroll = true;
|
||||||
|
self.isScrolling = false;
|
||||||
|
el.style.transform = el.style.webkitTransform = '';
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start scroll loop
|
||||||
|
self.isScrolling = true;
|
||||||
|
|
||||||
|
// chill out for a frame first
|
||||||
|
Ionic.dom.write(() => {
|
||||||
|
Ionic.dom.write(timeStamp => {
|
||||||
|
startTime = timeStamp;
|
||||||
|
step(timeStamp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToTop(duration: number): Promise<void> {
|
||||||
|
return this.scrollTo(0, 0, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToBottom(duration: number): Promise<void> {
|
||||||
|
let y = 0;
|
||||||
|
if (this.$el) {
|
||||||
|
y = this.$el.scrollHeight - this.$el.clientHeight;
|
||||||
|
}
|
||||||
|
return this.scrollTo(0, y, duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ionViewWillUnload() {
|
||||||
|
this.gesture && this.gesture.destroy();
|
||||||
|
this.gesture = this.detail = this.detail.event = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
import { Component, NgModule } from '@angular/core';
|
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
|
||||||
import { IonicApp, IonicModule } from '../../../..';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
templateUrl: 'main.html'
|
|
||||||
})
|
|
||||||
export class AppComponent {
|
|
||||||
doRefresh() {
|
|
||||||
console.log('DOREFRESH');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [
|
|
||||||
AppComponent
|
|
||||||
],
|
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
IonicModule.forRoot(AppComponent)
|
|
||||||
],
|
|
||||||
bootstrap: [IonicApp],
|
|
||||||
entryComponents: [
|
|
||||||
AppComponent
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class AppModule {}
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
@ -1,66 +0,0 @@
|
|||||||
<ion-header>
|
|
||||||
|
|
||||||
<ion-toolbar>
|
|
||||||
<ion-title>Scroll</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
|
|
||||||
</ion-header>
|
|
||||||
|
|
||||||
|
|
||||||
<ion-content>
|
|
||||||
|
|
||||||
<h2>Horizontal</h2>
|
|
||||||
<ion-scroll scrollX="true" style="height: 200px">
|
|
||||||
<div style="height: 200px; width: 2500px;" class="pattern1"></div>
|
|
||||||
</ion-scroll>
|
|
||||||
|
|
||||||
<h2>Vertical</h2>
|
|
||||||
<ion-scroll scrollY="true" style="width: 200px; height: 500px">
|
|
||||||
<div style="height: 2500px; width: 200px;" class="pattern2"></div>
|
|
||||||
</ion-scroll>
|
|
||||||
|
|
||||||
<h2>Both</h2>
|
|
||||||
<ion-scroll scrollX scrollY style="width: 100%; height: 500px">
|
|
||||||
<div style="height: 2500px; width: 2500px;" class="pattern3"></div>
|
|
||||||
</ion-scroll>
|
|
||||||
|
|
||||||
</ion-content>
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
|
||||||
f { display: block; height: 400px; width: 100%; background-color: #387ef5; margin-bottom: 15px; }
|
|
||||||
#counter {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
padding: 20px;
|
|
||||||
background-color: rgba(0,0,0,0.4);
|
|
||||||
z-index: 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pattern1 {
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 0% 50%, rgba(96, 16, 48, 0) 9px, #613 10px, rgba(96, 16, 48, 0) 11px) 0px 10px,
|
|
||||||
radial-gradient(at 100% 100%, rgba(96, 16, 48, 0) 9px, #613 10px, rgba(96, 16, 48, 0) 11px),
|
|
||||||
#8a3;
|
|
||||||
background-size: 20px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pattern2 {
|
|
||||||
background:
|
|
||||||
linear-gradient(63deg, #999 23%, transparent 23%) 7px 0,
|
|
||||||
linear-gradient(63deg, transparent 74%, #999 78%),
|
|
||||||
linear-gradient(63deg, transparent 34%, #999 38%, #999 58%, transparent 62%),
|
|
||||||
#444;
|
|
||||||
background-size: 16px 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pattern3 {
|
|
||||||
background:
|
|
||||||
linear-gradient(135deg, #708090 22px, #d9ecff 22px, #d9ecff 24px, transparent 24px, transparent 67px, #d9ecff 67px, #d9ecff 69px, transparent 69px),
|
|
||||||
linear-gradient(225deg, #708090 22px, #d9ecff 22px, #d9ecff 24px, transparent 24px, transparent 67px, #d9ecff 67px, #d9ecff 69px, transparent 69px)0 64px;
|
|
||||||
background-color:#708090;
|
|
||||||
background-size: 64px 128px
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,5 +0,0 @@
|
|||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
|
||||||
|
|
||||||
import { AppModule } from './app.module';
|
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
|
@ -1,5 +1,5 @@
|
|||||||
import { BooleanInputComponent, GestureDetail } from '../../util/interfaces';
|
import { BooleanInputComponent, GestureDetail } from '../../util/interfaces';
|
||||||
import { Component, h, Ionic, Listen, Prop, Watch } from '../../index';
|
import { Component, h, Ionic, Listen, Prop, Watch } from '../index';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -24,7 +24,7 @@ export class Toggle implements BooleanInputComponent {
|
|||||||
|
|
||||||
@Watch('checked')
|
@Watch('checked')
|
||||||
changed(val: boolean) {
|
changed(val: boolean) {
|
||||||
Ionic.emit(this, 'ionChange', { checked: val });
|
Ionic.emit(this, 'ionChange', { detail: { checked: val } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
20
src/index.ts
20
src/index.ts
@ -164,23 +164,3 @@ export { registerModeConfigs } from './config/mode-registry';
|
|||||||
export { IonicGestureConfig } from './gestures/gesture-config';
|
export { IonicGestureConfig } from './gestures/gesture-config';
|
||||||
|
|
||||||
export { IonicModule, IonicPageModule, provideLocationStrategy } from './module';
|
export { IonicModule, IonicPageModule, provideLocationStrategy } from './module';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Core
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as interfaces from './util/interfaces';
|
|
||||||
|
|
||||||
export declare const Component: interfaces.ComponentDecorator;
|
|
||||||
|
|
||||||
export declare const h: interfaces.Hyperscript;
|
|
||||||
|
|
||||||
export declare const Ionic: interfaces.Ionic;
|
|
||||||
|
|
||||||
export declare const Listen: interfaces.ListenDecorator;
|
|
||||||
|
|
||||||
export declare const Prop: interfaces.PropDecorator;
|
|
||||||
|
|
||||||
export declare const Watch: interfaces.WatchDecorator;
|
|
||||||
|
@ -9,11 +9,20 @@ export interface Ionic {
|
|||||||
gesture?: any;
|
gesture?: any;
|
||||||
};
|
};
|
||||||
dom: DomControllerApi;
|
dom: DomControllerApi;
|
||||||
|
config: ConfigApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface EventEmit {
|
export interface EventEmit {
|
||||||
(instance: any, eventName: string, data?: any): void;
|
(instance: any, eventName: string, data?: CustomEventOptions): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface CustomEventOptions {
|
||||||
|
bubbles?: boolean;
|
||||||
|
cancelable?: boolean;
|
||||||
|
composed?: boolean;
|
||||||
|
detail?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,15 +61,54 @@ export interface GestureCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface ScrollDetail extends GestureDetail {
|
||||||
|
scrollTop?: number;
|
||||||
|
scrollLeft?: number;
|
||||||
|
scrollHeight?: number;
|
||||||
|
scrollWidth?: number;
|
||||||
|
contentHeight?: number;
|
||||||
|
contentWidth?: number;
|
||||||
|
contentTop?: number;
|
||||||
|
contentBottom?: number;
|
||||||
|
domWrite?: RequestAnimationFrame;
|
||||||
|
contentElement?: HTMLElement;
|
||||||
|
fixedElement?: HTMLElement;
|
||||||
|
scrollElement?: HTMLElement;
|
||||||
|
headerElement?: HTMLElement;
|
||||||
|
footerElement?: HTMLElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface ScrollCallback {
|
||||||
|
(detail?: ScrollDetail): boolean|void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface ContentDimensions {
|
||||||
|
contentHeight: number;
|
||||||
|
contentTop: number;
|
||||||
|
contentBottom: number;
|
||||||
|
|
||||||
|
contentWidth: number;
|
||||||
|
contentLeft: number;
|
||||||
|
|
||||||
|
scrollHeight: number;
|
||||||
|
scrollTop: number;
|
||||||
|
|
||||||
|
scrollWidth: number;
|
||||||
|
scrollLeft: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IonicGlobal {
|
export interface IonicGlobal {
|
||||||
staticDir?: string;
|
staticDir?: string;
|
||||||
components?: LoadComponents;
|
components?: LoadComponents;
|
||||||
loadComponents?: {(bundleId: string): void};
|
loadComponents?: {(bundleId: string): void};
|
||||||
config?: Object;
|
|
||||||
configCtrl?: ConfigApi;
|
|
||||||
domCtrl?: DomControllerApi;
|
|
||||||
nextTickCtrl?: NextTickApi;
|
|
||||||
eventNamePrefix?: string;
|
eventNamePrefix?: string;
|
||||||
|
config?: Object;
|
||||||
|
ConfigCtrl?: ConfigApi;
|
||||||
|
DomCtrl?: DomControllerApi;
|
||||||
|
NextTickCtrl?: NextTickApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,22 +122,12 @@ export interface NextTick {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface DomRead {
|
|
||||||
(cb: Function): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface DomWrite {
|
|
||||||
(cb: Function): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export interface DomControllerApi {
|
export interface DomControllerApi {
|
||||||
read: DomRead;
|
read: RequestAnimationFrame;
|
||||||
write: DomWrite;
|
write: RequestAnimationFrame;
|
||||||
|
raf: RequestAnimationFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface RafCallback {
|
export interface RafCallback {
|
||||||
(timeStamp?: number): void;
|
(timeStamp?: number): void;
|
||||||
}
|
}
|
||||||
@ -251,7 +289,7 @@ export interface Watchers {
|
|||||||
|
|
||||||
|
|
||||||
export interface IonicTheme {
|
export interface IonicTheme {
|
||||||
(instance: any, cssClassName: string, vnodeData: VNodeData): VNodeData;
|
(instance: any, cssClassName: string, vnodeData?: VNodeData): VNodeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -346,7 +384,7 @@ export interface ProxyElement extends HTMLElement {
|
|||||||
|
|
||||||
|
|
||||||
export interface RendererApi {
|
export interface RendererApi {
|
||||||
(oldVnode: VNode | Element, vnode: VNode): VNode;
|
(oldVnode: VNode | Element, vnode: VNode, manualSlotProjection?: boolean): VNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -394,8 +432,6 @@ export interface PlatformApi {
|
|||||||
getComponentMeta: (tag: string) => ComponentMeta;
|
getComponentMeta: (tag: string) => ComponentMeta;
|
||||||
loadComponent: (bundleId: string, cb: Function) => void;
|
loadComponent: (bundleId: string, cb: Function) => void;
|
||||||
nextTick: NextTick;
|
nextTick: NextTick;
|
||||||
domRead: DomRead;
|
|
||||||
domWrite: DomWrite;
|
|
||||||
|
|
||||||
isElement: (node: Node) => node is Element;
|
isElement: (node: Node) => node is Element;
|
||||||
isText: (node: Node) => node is Text;
|
isText: (node: Node) => node is Text;
|
||||||
@ -414,7 +450,14 @@ export interface PlatformApi {
|
|||||||
$setTextContent: (node: Node, text: string | null) => void;
|
$setTextContent: (node: Node, text: string | null) => void;
|
||||||
$getTextContent: (node: Node) => string | null;
|
$getTextContent: (node: Node) => string | null;
|
||||||
$getAttribute: (elm: Element, attrName: string) => string;
|
$getAttribute: (elm: Element, attrName: string) => string;
|
||||||
$attachShadow: (elm: Element, cmpMode: ComponentMode, cmpModeId: string) => ShadowRoot;
|
$attachComponent: (elm: Element, cmpMeta: ComponentMeta, instance: Component) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface PlatformConfig {
|
||||||
|
name: string;
|
||||||
|
isMatch?: {(url: string, userAgent: string): boolean};
|
||||||
|
settings?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user