mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # ionic/config/config.ts
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -28,3 +28,5 @@ scripts/resources/web-animations-js/**/*.md
|
|||||||
scripts/resources/web-animations-js/**/*.sh
|
scripts/resources/web-animations-js/**/*.sh
|
||||||
scripts/resources/web-animations-js/**/*.yml
|
scripts/resources/web-animations-js/**/*.yml
|
||||||
scripts/resources/web-animations-js/**/*.gz
|
scripts/resources/web-animations-js/**/*.gz
|
||||||
|
|
||||||
|
.package.tmp.json
|
||||||
|
8
circle.yml
Normal file
8
circle.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
test:
|
||||||
|
override:
|
||||||
|
- echo "Automatically marking tests as passing for now"
|
||||||
|
deployment:
|
||||||
|
tasks:
|
||||||
|
branch: master
|
||||||
|
commands:
|
||||||
|
- ./scripts/ci/deploy.sh
|
@ -2,7 +2,7 @@
|
|||||||
<img src="img/ios-statusbar.png" style="display:none" id="ios-only">
|
<img src="img/ios-statusbar.png" style="display:none" id="ios-only">
|
||||||
|
|
||||||
|
|
||||||
<ion-menu [content]="content" id="leftMenu">
|
<ion-menu [content]="content" id="leftMenu" side="left">
|
||||||
|
|
||||||
<ion-toolbar primary>
|
<ion-toolbar primary>
|
||||||
<ion-title>Menu</ion-title>
|
<ion-title>Menu</ion-title>
|
||||||
|
@ -25,16 +25,16 @@ class DemoApp {
|
|||||||
];
|
];
|
||||||
|
|
||||||
this.platform.ready().then( () => {
|
this.platform.ready().then( () => {
|
||||||
|
|
||||||
window.addEventListener('message', (e) => {
|
window.addEventListener('message', (e) => {
|
||||||
|
|
||||||
zone.run(() => {
|
zone.run(() => {
|
||||||
if (e.data) {
|
if (e.data) {
|
||||||
|
|
||||||
var data = JSON.parse(e.data);
|
var data = JSON.parse(e.data);
|
||||||
if (data.hash) {
|
if (data.hash) {
|
||||||
this.nextPage = helpers.getPageFor(data.hash.replace('#', ''));
|
this.nextPage = helpers.getPageFor(data.hash.replace('#', ''));
|
||||||
this.app.getComponent('leftMenu').enable(false);
|
if (data.hash !== 'menus') {
|
||||||
if (data.hash === 'menus') {
|
this.app.getComponent('leftMenu').enable(false);
|
||||||
this.app.getComponent('leftMenu').enable(true);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.nextPage = actionSheets.BasicPage;
|
this.nextPage = actionSheets.BasicPage;
|
||||||
@ -57,6 +57,7 @@ class DemoApp {
|
|||||||
|
|
||||||
openPage(page) {
|
openPage(page) {
|
||||||
// close the menu when clicking a link from the menu
|
// close the menu when clicking a link from the menu
|
||||||
|
// debugger;
|
||||||
this.app.getComponent('leftMenu').close();
|
this.app.getComponent('leftMenu').close();
|
||||||
|
|
||||||
// Reset the content nav to have just this page
|
// Reset the content nav to have just this page
|
||||||
|
@ -7,7 +7,9 @@ import * as helpers from '../../helpers';
|
|||||||
directives: [forwardRef(() => helpers.AndroidAttribute)]
|
directives: [forwardRef(() => helpers.AndroidAttribute)]
|
||||||
})
|
})
|
||||||
export class BasicPage{
|
export class BasicPage{
|
||||||
constructor() {
|
constructor(app: IonicApp) {
|
||||||
|
this.app = app;
|
||||||
|
this.app.getComponent('leftMenu').enable(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,14 +20,14 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
this.canDrag = true;
|
this.canDrag = true;
|
||||||
this.listen();
|
this.listen();
|
||||||
|
|
||||||
this.on('tap', ev => {
|
this.tap = (ev) => {
|
||||||
if (!isFromOptionButtons(ev.target)) {
|
if (!isFromOptionButtons(ev.target)) {
|
||||||
let didClose = this.closeOpened();
|
let didClose = this.closeOpened();
|
||||||
if (didClose) {
|
if (didClose) {
|
||||||
preventDefault(ev);
|
preventDefault(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
this.mouseOut = (ev) => {
|
this.mouseOut = (ev) => {
|
||||||
this.onDragEnd(ev);
|
this.onDragEnd(ev);
|
||||||
@ -38,14 +38,14 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
let itemContainerEle = getItemConatiner(ev.target);
|
let itemContainerEle = getItemConatiner(ev.target);
|
||||||
if (!itemContainerEle) return;
|
if (!itemContainerEle) return;
|
||||||
|
|
||||||
this.closeOpened(ev, itemContainerEle);
|
this.closeOpened(itemContainerEle);
|
||||||
|
|
||||||
let openAmout = this.getOpenAmount(itemContainerEle);
|
let openAmout = this.getOpenAmount(itemContainerEle);
|
||||||
let itemData = this.get(itemContainerEle);
|
let itemData = this.get(itemContainerEle);
|
||||||
this.preventDrag = (openAmout > 0);
|
this.preventDrag = (openAmout > 0);
|
||||||
|
|
||||||
if (this.preventDrag) {
|
if (this.preventDrag) {
|
||||||
this.closeOpened(ev);
|
this.closeOpened();
|
||||||
return preventDefault(ev);
|
return preventDefault(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,16 +57,18 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
if (ev.srcEvent.type.indexOf('mouse') > -1) {
|
if (ev.srcEvent.type.indexOf('mouse') > -1) {
|
||||||
ev.target.addEventListener('mouseout', this.mouseOut);
|
ev.target.addEventListener('mouseout', this.mouseOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.dragEnded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrag(ev) {
|
onDrag(ev) {
|
||||||
if (Math.abs(ev.deltaY) > 30) {
|
if (this.dragEnded || this.preventDrag || Math.abs(ev.deltaY) > 30) {
|
||||||
this.preventDrag = true;
|
this.preventDrag = true;
|
||||||
return this.closeOpened(ev);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let itemContainerEle = getItemConatiner(ev.target);
|
let itemContainerEle = getItemConatiner(ev.target);
|
||||||
if (!itemContainerEle || !isActive(itemContainerEle) || this.preventDrag) return;
|
if (!itemContainerEle || !isActive(itemContainerEle)) return;
|
||||||
|
|
||||||
let itemData = this.get(itemContainerEle);
|
let itemData = this.get(itemContainerEle);
|
||||||
|
|
||||||
@ -75,9 +77,6 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
if (!itemData.optsWidth) return;
|
if (!itemData.optsWidth) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
itemContainerEle.classList.add('active-slide');
|
|
||||||
itemContainerEle.classList.add('active-options');
|
|
||||||
|
|
||||||
let x = ev.center[this.direction];
|
let x = ev.center[this.direction];
|
||||||
let delta = x - itemData.startX;
|
let delta = x - itemData.startX;
|
||||||
|
|
||||||
@ -88,11 +87,18 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
newX = -Math.min(-itemData.optsWidth, -itemData.optsWidth + (((delta + itemData.optsWidth) * 0.4)));
|
newX = -Math.min(-itemData.optsWidth, -itemData.optsWidth + (((delta + itemData.optsWidth) * 0.4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.open(itemContainerEle, newX, false);
|
raf(() => {
|
||||||
|
if (!this.dragEnded && !this.preventDrag) {
|
||||||
|
isItemActive(itemContainerEle, true);
|
||||||
|
this.open(itemContainerEle, newX, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onDragEnd(ev) {
|
onDragEnd(ev) {
|
||||||
this.preventDrag = false;
|
this.preventDrag = false;
|
||||||
|
this.dragEnded = true;
|
||||||
|
|
||||||
let itemContainerEle = getItemConatiner(ev.target);
|
let itemContainerEle = getItemConatiner(ev.target);
|
||||||
if (!itemContainerEle || !isActive(itemContainerEle)) return;
|
if (!itemContainerEle || !isActive(itemContainerEle)) return;
|
||||||
|
|
||||||
@ -108,12 +114,7 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
if (this.getOpenAmount(itemContainerEle) < (restingPoint / 2)) {
|
if (this.getOpenAmount(itemContainerEle) < (restingPoint / 2)) {
|
||||||
|
|
||||||
// If we are going left but too slow, or going right, go back to resting
|
// If we are going left but too slow, or going right, go back to resting
|
||||||
if (ev.direction & Hammer.DIRECTION_RIGHT) {
|
if (ev.direction & Hammer.DIRECTION_RIGHT || Math.abs(ev.velocityX) < 0.3) {
|
||||||
// Left
|
|
||||||
restingPoint = 0;
|
|
||||||
|
|
||||||
} else if (Math.abs(ev.velocityX) < 0.3) {
|
|
||||||
// Right
|
|
||||||
restingPoint = 0;
|
restingPoint = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
closeOpened(ev, doNotCloseEle) {
|
closeOpened(doNotCloseEle) {
|
||||||
let didClose = false;
|
let didClose = false;
|
||||||
if (this.openItems) {
|
if (this.openItems) {
|
||||||
let openItemElements = this.listEle.querySelectorAll('.active-slide');
|
let openItemElements = this.listEle.querySelectorAll('.active-slide');
|
||||||
@ -153,8 +154,7 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
} else {
|
} else {
|
||||||
let timerId = setTimeout(() => {
|
let timerId = setTimeout(() => {
|
||||||
if (slidingEle.style[CSS.transform] === '') {
|
if (slidingEle.style[CSS.transform] === '') {
|
||||||
itemContainerEle.classList.remove('active-slide');
|
isItemActive(itemContainerEle, false);
|
||||||
itemContainerEle.classList.remove('active-options');
|
|
||||||
this.openItems--;
|
this.openItems--;
|
||||||
}
|
}
|
||||||
}, 400);
|
}, 400);
|
||||||
@ -165,6 +165,12 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
slidingEle.style[CSS.transform] = (openAmount ? 'translate3d(' + -openAmount + 'px,0,0)' : '');
|
slidingEle.style[CSS.transform] = (openAmount ? 'translate3d(' + -openAmount + 'px,0,0)' : '');
|
||||||
|
|
||||||
if (isFinal) {
|
if (isFinal) {
|
||||||
|
if (openAmount) {
|
||||||
|
isItemActive(itemContainerEle, true);
|
||||||
|
this.on('tap', this.tap);
|
||||||
|
} else {
|
||||||
|
this.off('tap', this.tap);
|
||||||
|
}
|
||||||
this.enableScroll(!openAmount);
|
this.enableScroll(!openAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,6 +203,11 @@ export class ItemSlidingGesture extends DragGesture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isItemActive(ele, isActive) {
|
||||||
|
ele.classList[isActive ? 'add' : 'remove']('active-slide');
|
||||||
|
ele.classList[isActive ? 'add' : 'remove']('active-options');
|
||||||
|
}
|
||||||
|
|
||||||
function preventDefault(ev) {
|
function preventDefault(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ ion-item-options {
|
|||||||
right: 0;
|
right: 0;
|
||||||
z-index: $z-index-item-options;
|
z-index: $z-index-item-options;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
opacity: 0;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
ion-item-sliding.active-slide {
|
ion-item-sliding.active-slide {
|
||||||
@ -39,7 +39,7 @@ ion-item-sliding.active-slide {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active-options ion-item-options{
|
&.active-options ion-item-options {
|
||||||
opacity: 1;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,9 +83,9 @@
|
|||||||
</ion-item-options>
|
</ion-item-options>
|
||||||
</ion-item-sliding>
|
</ion-item-sliding>
|
||||||
|
|
||||||
<ion-item-sliding *ng-for="#item of getItems()">
|
<ion-item-sliding *ng-for="#data of getItems()" #item>
|
||||||
<ion-item text-wrap detail-push>
|
<ion-item text-wrap detail-push>
|
||||||
<h3>ng-for {{item}}</h3>
|
<h3>ng-for {{data}}</h3>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item-options>
|
<ion-item-options>
|
||||||
<button primary (click)="archive($event, item)">Archive</button>
|
<button primary (click)="archive($event, item)">Archive</button>
|
||||||
|
@ -33,6 +33,7 @@ export class List extends Ion {
|
|||||||
constructor(elementRef: ElementRef, config: Config, private zone: NgZone) {
|
constructor(elementRef: ElementRef, config: Config, private zone: NgZone) {
|
||||||
super(elementRef, config);
|
super(elementRef, config);
|
||||||
this.ele = elementRef.nativeElement;
|
this.ele = elementRef.nativeElement;
|
||||||
|
this._enableSliding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,18 +77,22 @@ export class List extends Ion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enableSlidingItems(shouldEnable) {
|
enableSlidingItems(shouldEnable) {
|
||||||
this._enableSliding = shouldEnable;
|
|
||||||
|
|
||||||
if (this._init) {
|
if (this._init) {
|
||||||
if (shouldEnable) {
|
|
||||||
this.zone.runOutsideAngular(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.slidingGesture = new ItemSlidingGesture(this, this.ele);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
if (this._enableSliding !== shouldEnable) {
|
||||||
this.slidingGesture && this.slidingGesture.unlisten();
|
this._enableSliding = shouldEnable;
|
||||||
|
|
||||||
|
if (shouldEnable) {
|
||||||
|
console.debug('enableSlidingItems');
|
||||||
|
this.zone.runOutsideAngular(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.slidingGesture = new ItemSlidingGesture(this, this.ele);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.slidingGesture && this.slidingGesture.unlisten();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {Menu} from './menu';
|
import {Menu} from './menu';
|
||||||
import {SlideEdgeGesture} from 'ionic/gestures/slide-edge-gesture';
|
import {SlideEdgeGesture} from '../../gestures/slide-edge-gesture';
|
||||||
|
|
||||||
import * as util from 'ionic/util';
|
import * as util from 'ionic/util';
|
||||||
|
|
||||||
|
@ -116,16 +116,14 @@ class MenuPushType extends MenuType {
|
|||||||
let easing = 'ease';
|
let easing = 'ease';
|
||||||
let duration = 250;
|
let duration = 250;
|
||||||
|
|
||||||
let contentClosedX, contentOpenedX, menuClosedX, menuOpenedX;
|
let contentOpenedX, menuClosedX, menuOpenedX;
|
||||||
|
|
||||||
if (menu.side == 'right') {
|
if (menu.side == 'right') {
|
||||||
contentOpenedX = -menu.width() + 'px';
|
contentOpenedX = -menu.width() + 'px';
|
||||||
contentClosedX = '0px';
|
|
||||||
menuOpenedX = (menu.platform.width() - menu.width()) + 'px';
|
menuOpenedX = (menu.platform.width() - menu.width()) + 'px';
|
||||||
menuClosedX = menu.platform.width() + 'px';
|
menuClosedX = menu.platform.width() + 'px';
|
||||||
} else {
|
} else {
|
||||||
contentOpenedX = menu.width() + 'px';
|
contentOpenedX = menu.width() + 'px';
|
||||||
contentClosedX = '0px';
|
|
||||||
menuOpenedX = '0px';
|
menuOpenedX = '0px';
|
||||||
menuClosedX = -menu.width() + 'px';
|
menuClosedX = -menu.width() + 'px';
|
||||||
}
|
}
|
||||||
@ -139,7 +137,7 @@ class MenuPushType extends MenuType {
|
|||||||
this.open.add(menuOpen);
|
this.open.add(menuOpen);
|
||||||
|
|
||||||
let contentOpen = new Animation(menu.getContentElement());
|
let contentOpen = new Animation(menu.getContentElement());
|
||||||
contentOpen.fromTo(TRANSLATE_X, contentClosedX, contentOpenedX);
|
contentOpen.fromTo(TRANSLATE_X, '0px', contentOpenedX);
|
||||||
this.open.add(contentOpen);
|
this.open.add(contentOpen);
|
||||||
|
|
||||||
let menuClose = new Animation(menu.getMenuElement());
|
let menuClose = new Animation(menu.getMenuElement());
|
||||||
@ -147,7 +145,7 @@ class MenuPushType extends MenuType {
|
|||||||
this.close.add(menuClose);
|
this.close.add(menuClose);
|
||||||
|
|
||||||
let contentClose = new Animation(menu.getContentElement());
|
let contentClose = new Animation(menu.getContentElement());
|
||||||
contentClose.fromTo(TRANSLATE_X, contentOpenedX, contentClosedX);
|
contentClose.fromTo(TRANSLATE_X, contentOpenedX, '0px');
|
||||||
this.close.add(contentClose);
|
this.close.add(contentClose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,14 +147,19 @@ export class Menu extends Ion {
|
|||||||
if (!type) {
|
if (!type) {
|
||||||
type = this.config.get('menuType');
|
type = this.config.get('menuType');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._type = new menuTypes[type](this);
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.config.get('animate') === false) {
|
_getType() {
|
||||||
this._type.open.duration(33);
|
if (!this._type) {
|
||||||
this._type.close.duration(33);
|
this._type = new menuTypes[this.type](this);
|
||||||
|
|
||||||
|
if (this.config.get('animate') === false) {
|
||||||
|
this._type.open.duration(33);
|
||||||
|
this._type.close.duration(33);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return this._type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,7 +176,7 @@ export class Menu extends Ion {
|
|||||||
|
|
||||||
this._before();
|
this._before();
|
||||||
|
|
||||||
return this._type.setOpen(shouldOpen).then(() => {
|
return this._getType().setOpen(shouldOpen).then(() => {
|
||||||
this._after(shouldOpen);
|
this._after(shouldOpen);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -185,7 +190,7 @@ export class Menu extends Ion {
|
|||||||
|
|
||||||
this._before();
|
this._before();
|
||||||
|
|
||||||
this._type.setProgressStart(this.isOpen);
|
this._getType().setProgressStart(this.isOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,7 +201,7 @@ export class Menu extends Ion {
|
|||||||
if (this.isEnabled) {
|
if (this.isEnabled) {
|
||||||
this._prevent();
|
this._prevent();
|
||||||
this.app.setTransitioning(true);
|
this.app.setTransitioning(true);
|
||||||
this._type.setProgess(value);
|
this._getType().setProgess(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +213,7 @@ export class Menu extends Ion {
|
|||||||
if (this.isEnabled) {
|
if (this.isEnabled) {
|
||||||
this._prevent();
|
this._prevent();
|
||||||
this.app.setTransitioning(true);
|
this.app.setTransitioning(true);
|
||||||
this._type.setProgressEnd(shouldComplete).then(isOpen => {
|
this._getType().setProgressEnd(shouldComplete).then(isOpen => {
|
||||||
this._after(isOpen);
|
this._after(isOpen);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,7 @@ export class NavController extends Ion {
|
|||||||
return done();
|
return done();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._setZIndex(enteringView.instance, leavingView.instance, opts.direction);
|
this._setZIndex(enteringView.instance, leavingView && leavingView.instance, opts.direction);
|
||||||
|
|
||||||
this._zone.runOutsideAngular(() => {
|
this._zone.runOutsideAngular(() => {
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ export class OverlayController {
|
|||||||
this.app.setEnabled(true);
|
this.app.setEnabled(true);
|
||||||
this.app.setTransitioning(false);
|
this.app.setTransitioning(false);
|
||||||
instance.onPageDidEnter && instance.onPageDidEnter();
|
instance.onPageDidEnter && instance.onPageDidEnter();
|
||||||
resolve();
|
resolve(instance);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -119,7 +119,7 @@ export class Refresher {
|
|||||||
|
|
||||||
this.showIcon = util.isDefined(this.refreshingIcon);
|
this.showIcon = util.isDefined(this.refreshingIcon);
|
||||||
|
|
||||||
this._touchMoveListener = this._handleTouchMov.bind(this);
|
this._touchMoveListener = this._handleTouchMove.bind(this);
|
||||||
this._touchEndListener = this._handleTouchEnd.bind(this);
|
this._touchEndListener = this._handleTouchEnd.bind(this);
|
||||||
this._handleScrollListener = this._handleScroll.bind(this);
|
this._handleScrollListener = this._handleScroll.bind(this);
|
||||||
sc.addEventListener('touchmove', this._touchMoveListener);
|
sc.addEventListener('touchmove', this._touchMoveListener);
|
||||||
|
@ -31,10 +31,10 @@ import {isObject, isDefined, isFunction, isArray, extend} from '../util/util';
|
|||||||
* @App({
|
* @App({
|
||||||
* template: `<ion-nav [root]="root"></ion-nav>`
|
* template: `<ion-nav [root]="root"></ion-nav>`
|
||||||
* config: {
|
* config: {
|
||||||
* 'tabbarPlacement': 'bottom',
|
* tabbarPlacement: 'bottom',
|
||||||
* platforms: {
|
* platforms: {
|
||||||
* ios: {
|
* ios: {
|
||||||
* 'tabbarPlacement': 'top',
|
* tabbarPlacement: 'top',
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
@ -45,7 +45,7 @@ import {isObject, isDefined, isFunction, isArray, extend} from '../util/util';
|
|||||||
*
|
*
|
||||||
* ```html
|
* ```html
|
||||||
* <ion-tabs tabbar-placement="top">
|
* <ion-tabs tabbar-placement="top">
|
||||||
* <ion-tab tab-title="Dash" tab-icon="pulse" [root]="DashRoot"></ion-tab>
|
* <ion-tab tab-title="Dash" tab-icon="pulse" [root]="tabRoot"></ion-tab>
|
||||||
* </ion-tabs>
|
* </ion-tabs>
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
@ -7,7 +7,7 @@ import {IONIC_DIRECTIVES} from './directives';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* _For more information on how pages are created, see the [NavController API
|
* _For more information on how pages are created, see the [NavController API
|
||||||
* reference](../../Nav/NavController/#creating_pages)._
|
* reference](../../components/nav/NavController/#creating_pages)._
|
||||||
*
|
*
|
||||||
* The Page decorator indicates that the decorated class is an Ionic
|
* The Page decorator indicates that the decorated class is an Ionic
|
||||||
* navigation component, meaning it can be navigated to using a NavController.
|
* navigation component, meaning it can be navigated to using a NavController.
|
||||||
|
@ -35,7 +35,10 @@ export class Gesture {
|
|||||||
}
|
}
|
||||||
this.hammertime.on(type, cb);
|
this.hammertime.on(type, cb);
|
||||||
(this._callbacks[type] || (this._callbacks[type] = [])).push(cb);
|
(this._callbacks[type] || (this._callbacks[type] = [])).push(cb);
|
||||||
//this.element.addEventListener(type, cb);
|
}
|
||||||
|
|
||||||
|
off(type, cb) {
|
||||||
|
this.hammertime.off(type, this._callbacks[type] ? cb : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
listen() {
|
listen() {
|
||||||
@ -46,7 +49,6 @@ export class Gesture {
|
|||||||
if (this.hammertime) {
|
if (this.hammertime) {
|
||||||
for (let type in this._callbacks) {
|
for (let type in this._callbacks) {
|
||||||
for (let i = 0; i < this._callbacks[type].length; i++) {
|
for (let i = 0; i < this._callbacks[type].length; i++) {
|
||||||
//this.element.removeEventListener(type, this._callbacks[type][i]);
|
|
||||||
this.hammertime.off(type, this._callbacks[type]);
|
this.hammertime.off(type, this._callbacks[type]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ export class SqlStorage extends StorageEngine {
|
|||||||
query(query, ...params) {
|
query(query, ...params) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._db.transaction((tx) => {
|
this._db.transaction((tx) => {
|
||||||
ts.executeSql(query, params, (tx, res) => {
|
tx.executeSql(query, params, (tx, res) => {
|
||||||
resolve({
|
resolve({
|
||||||
tx: tx,
|
tx: tx,
|
||||||
res: res
|
res: res
|
||||||
|
@ -28,8 +28,8 @@ export class Storage {
|
|||||||
remove(key) {
|
remove(key) {
|
||||||
return this._strategy.remove(key);
|
return this._strategy.remove(key);
|
||||||
}
|
}
|
||||||
query(query) {
|
query(query, params) {
|
||||||
return this._strategy.query(key);
|
return this._strategy.query(query, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ export class StorageEngine {
|
|||||||
remove(key) {
|
remove(key) {
|
||||||
throw Error("remove() not implemented for this storage engine");
|
throw Error("remove() not implemented for this storage engine");
|
||||||
}
|
}
|
||||||
query(query) {
|
query(query, params) {
|
||||||
throw Error("query() not implemented for this storage engine");
|
throw Error("query() not implemented for this storage engine");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
scripts/ci/deploy.sh
Executable file
42
scripts/ci/deploy.sh
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "##### "
|
||||||
|
echo "##### ci/deploy.sh"
|
||||||
|
echo "#####"
|
||||||
|
|
||||||
|
function run {
|
||||||
|
cd ../..
|
||||||
|
export IONIC_DIR=$PWD
|
||||||
|
|
||||||
|
# If --verbose is set on this script, export it to all the scripts
|
||||||
|
export VERBOSE=$VERBOSE
|
||||||
|
|
||||||
|
git config --global user.name 'Ionitron'
|
||||||
|
git config --global user.email hi@ionicframework.com
|
||||||
|
|
||||||
|
git show $CIRCLE_SHA1~1:package.json > .package.tmp.json
|
||||||
|
OLD_VERSION=$(readJsonProp ".package.tmp.json" "version")
|
||||||
|
VERSION=$(readJsonProp "package.json" "version")
|
||||||
|
|
||||||
|
if [[ "$OLD_VERSION" != "$VERSION" ]]; then
|
||||||
|
# ./scripts/bump/release.sh --new-version="$VERSION"
|
||||||
|
IS_RELEASE=true
|
||||||
|
VERSION_NAME=$(readJsonProp "package.json" "version")
|
||||||
|
else
|
||||||
|
# ./scripts/bump/nightly.sh --build-number=$BUILD_NUMBER
|
||||||
|
VERSION_NAME="nightly"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install gulp globally for site deploy script.
|
||||||
|
npm install -g gulp
|
||||||
|
|
||||||
|
if [[ "$IS_RELEASE" == "true" ]]; then
|
||||||
|
echo "RELEASE DETECTED!"
|
||||||
|
# TODO bump version number, github release, changelog, CDN, docs nav update
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update docs
|
||||||
|
./scripts/docs/deploy.sh --version-name="$VERSION_NAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
source $(dirname $0)/../utils.sh.inc
|
5
scripts/config.json
Normal file
5
scripts/config.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"sitePath": "../ionic-site",
|
||||||
|
"v2DocsDir": "docs/v2",
|
||||||
|
"docsDest": "../ionic-site/docs/v2"
|
||||||
|
}
|
43
scripts/docs/deploy.sh
Executable file
43
scripts/docs/deploy.sh
Executable file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ARG_DEFS=(
|
||||||
|
"--version-name=(.*)"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "##### "
|
||||||
|
echo "##### docs/deploy.sh"
|
||||||
|
echo "#####"
|
||||||
|
|
||||||
|
function init {
|
||||||
|
cd ..
|
||||||
|
SITE_PATH=$(readJsonProp "config.json" "sitePath")
|
||||||
|
SITE_DIR=$IONIC_DIR/$SITE_PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
function run {
|
||||||
|
./git/clone.sh --repository="driftyco/ionic-site" \
|
||||||
|
--directory="$SITE_DIR" \
|
||||||
|
--branch="master"
|
||||||
|
cd ..
|
||||||
|
VERSION=$(readJsonProp "package.json" "version")
|
||||||
|
|
||||||
|
gulp docs --doc-version="$VERSION_NAME"
|
||||||
|
cd $SITE_DIR
|
||||||
|
|
||||||
|
CHANGES=$(git status --porcelain)
|
||||||
|
|
||||||
|
# if no changes, don't commit
|
||||||
|
if [[ "$CHANGES" == "" ]]; then
|
||||||
|
ls
|
||||||
|
echo "-- No changes detected in docs for $VERSION_NAME; docs not updated."
|
||||||
|
else
|
||||||
|
git add -A
|
||||||
|
git commit -am "docs: update for $VERSION"
|
||||||
|
git push origin master
|
||||||
|
|
||||||
|
echo "-- Updated docs for $VERSION_NAME succesfully!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
source $(dirname $0)/../utils.sh.inc
|
@ -8,6 +8,7 @@ var path = require('path');
|
|||||||
var semver = require('semver');
|
var semver = require('semver');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
var config = require('../config.json');
|
||||||
|
|
||||||
// Define the dgeni package for generating the docs
|
// Define the dgeni package for generating the docs
|
||||||
module.exports = function(currentVersion){
|
module.exports = function(currentVersion){
|
||||||
@ -44,7 +45,7 @@ module.exports = function(currentVersion){
|
|||||||
|
|
||||||
.config(function(renderDocsProcessor, computePathsProcessor, versionInfo) {
|
.config(function(renderDocsProcessor, computePathsProcessor, versionInfo) {
|
||||||
try {
|
try {
|
||||||
versions = fs.readdirSync(path.resolve(__dirname, '../../dist/ionic-site/docs/v2/'))
|
versions = fs.readdirSync(path.resolve(__dirname, '../../' + config.docsDest + '/'))
|
||||||
.filter(semver.valid)
|
.filter(semver.valid)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
versions = [];
|
versions = [];
|
||||||
@ -66,7 +67,7 @@ module.exports = function(currentVersion){
|
|||||||
//Latest version is in docs root
|
//Latest version is in docs root
|
||||||
var folder = version == latestVersion ? '' : version;
|
var folder = version == latestVersion ? '' : version;
|
||||||
return {
|
return {
|
||||||
href: path.join('/docs/v2', folder),
|
href: path.join('/' + config.v2DocsDir, folder),
|
||||||
folder: folder,
|
folder: folder,
|
||||||
name: version
|
name: version
|
||||||
};
|
};
|
||||||
@ -89,7 +90,7 @@ module.exports = function(currentVersion){
|
|||||||
// remove filename since we have multiple docTypes per file
|
// remove filename since we have multiple docTypes per file
|
||||||
docPath = docPath.substring(0, docPath.lastIndexOf('/') + 1);
|
docPath = docPath.substring(0, docPath.lastIndexOf('/') + 1);
|
||||||
docPath += doc.name + '/index.md';
|
docPath += doc.name + '/index.md';
|
||||||
var path = 'docs/v2/' + (versionData.current.folder || '') +
|
var path = config.v2DocsDir + '/' + (versionData.current.folder || '') +
|
||||||
'/api/' + docPath;
|
'/api/' + docPath;
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
@ -127,7 +128,7 @@ module.exports = function(currentVersion){
|
|||||||
|
|
||||||
// Configure file writing
|
// Configure file writing
|
||||||
.config(function(writeFilesProcessor) {
|
.config(function(writeFilesProcessor) {
|
||||||
writeFilesProcessor.outputFolder = 'dist/ionic-site'
|
writeFilesProcessor.outputFolder = config.sitePath;
|
||||||
})
|
})
|
||||||
|
|
||||||
// Configure rendering
|
// Configure rendering
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
var config = require('../config.json');
|
||||||
module.exports = function(gulp, flags) {
|
module.exports = function(gulp, flags) {
|
||||||
gulp.task('docs', ['docs.demos'], function() {
|
gulp.task('docs', ['docs.demos'], function() {
|
||||||
var Dgeni = require('dgeni');
|
var Dgeni = require('dgeni');
|
||||||
@ -28,7 +28,7 @@ module.exports = function(gulp, flags) {
|
|||||||
'!dist/src',
|
'!dist/src',
|
||||||
'!dist/src/**/*'
|
'!dist/src/**/*'
|
||||||
])
|
])
|
||||||
.pipe(gulp.dest('dist/ionic-site/docs/v2/dist'));
|
.pipe(gulp.dest(config.docsDest + '/dist'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('docs.index', function() {
|
gulp.task('docs.index', function() {
|
||||||
@ -56,7 +56,7 @@ module.exports = function(gulp, flags) {
|
|||||||
refId++;
|
refId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var docPath = 'dist/ionic-site/docs/v2';
|
var docPath = config.docsDest;
|
||||||
gutil.log('Reading docs from', gutil.colors.cyan(docPath));
|
gutil.log('Reading docs from', gutil.colors.cyan(docPath));
|
||||||
|
|
||||||
return gulp.src([
|
return gulp.src([
|
||||||
@ -68,7 +68,7 @@ module.exports = function(gulp, flags) {
|
|||||||
var contents = file.contents.toString(); //was buffer
|
var contents = file.contents.toString(); //was buffer
|
||||||
|
|
||||||
// Grab relative path from ionic-site root
|
// Grab relative path from ionic-site root
|
||||||
var relpath = file.path.replace(RegExp('^.*?' + docPath.replace('/docs/v2', '') + '/'), '');
|
var relpath = file.path.replace(RegExp('^.*?' + docPath.replace('/' + config.v2DocsDir, '') + '/'), '');
|
||||||
|
|
||||||
// Read out the yaml portion of the Jekyll file
|
// Read out the yaml portion of the Jekyll file
|
||||||
var yamlStartIndex = contents.indexOf('---');
|
var yamlStartIndex = contents.indexOf('---');
|
||||||
@ -179,7 +179,7 @@ module.exports = function(gulp, flags) {
|
|||||||
entities = new Entities();
|
entities = new Entities();
|
||||||
|
|
||||||
var variables = [];
|
var variables = [];
|
||||||
var outputFile = 'dist/ionic-site/docs/v2/data/sass.json';
|
var outputFile = config.docsDest + '/data/sass.json';
|
||||||
|
|
||||||
// Add the variable to the array, encode the html and remove !default from the value
|
// Add the variable to the array, encode the html and remove !default from the value
|
||||||
function addVariable(variableName, defaultValue, file) {
|
function addVariable(variableName, defaultValue, file) {
|
||||||
@ -225,7 +225,7 @@ module.exports = function(gulp, flags) {
|
|||||||
callback();
|
callback();
|
||||||
}).on('end', function() {
|
}).on('end', function() {
|
||||||
gutil.log("Writing to file at", gutil.colors.cyan("/driftyco/ionic2/" + outputFile));
|
gutil.log("Writing to file at", gutil.colors.cyan("/driftyco/ionic2/" + outputFile));
|
||||||
gutil.log("Place this file in", gutil.colors.cyan("/driftyco/ionic-site/docs/v2/theming/overriding-ionic-variables/"), "in order to update the docs");
|
gutil.log("Place this file in", gutil.colors.cyan("/driftyco/ionic-site/" + config.v2DocsDir + "/theming/overriding-ionic-variables/"), "in order to update the docs");
|
||||||
fs.writeFileSync(outputFile, JSON.stringify(variables));
|
fs.writeFileSync(outputFile, JSON.stringify(variables));
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
26
scripts/git/clone.sh
Executable file
26
scripts/git/clone.sh
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ARG_DEFS=(
|
||||||
|
"--repository=(.*)"
|
||||||
|
"--directory=(.*)"
|
||||||
|
"[--depth=(.*)]"
|
||||||
|
"[--branch=(.*)]"
|
||||||
|
)
|
||||||
|
|
||||||
|
function run {
|
||||||
|
rm -rf $DIRECTORY
|
||||||
|
mkdir -p $DIRECTORY
|
||||||
|
|
||||||
|
echo "-- Cloning $REPOSITORY#$BRANCH to $DIRECTORY..."
|
||||||
|
|
||||||
|
ARGS="--branch=${BRANCH:-master}"
|
||||||
|
if [[ "$DEPTH" != "" ]]; then
|
||||||
|
ARGS="$ARGS --depth=$DEPTH"
|
||||||
|
fi
|
||||||
|
git clone https://driftyco:$GH_TOKEN@github.com/$REPOSITORY $DIRECTORY $ARGS
|
||||||
|
cd $DIRECTORY
|
||||||
|
git fetch origin --tags
|
||||||
|
cd ../
|
||||||
|
}
|
||||||
|
|
||||||
|
source $(dirname $0)/../utils.sh.inc
|
@ -11,7 +11,7 @@ exports.config = {
|
|||||||
specs: 'dist/e2e/**/*e2e.js',
|
specs: 'dist/e2e/**/*e2e.js',
|
||||||
//specs: 'dist/e2e/searchbar/**/*e2e.js',
|
//specs: 'dist/e2e/searchbar/**/*e2e.js',
|
||||||
|
|
||||||
sleepBetweenSpecs: 300,
|
sleepBetweenSpecs: 350,
|
||||||
|
|
||||||
platformDefauls: {
|
platformDefauls: {
|
||||||
browser: 'chrome',
|
browser: 'chrome',
|
||||||
|
244
scripts/utils.sh.inc
Normal file
244
scripts/utils.sh.inc
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
# bash utils from angularjs
|
||||||
|
|
||||||
|
# This file provides:
|
||||||
|
# - a default control flow
|
||||||
|
# * initializes the environment
|
||||||
|
# * call a function in your script based on the arguments
|
||||||
|
# - named argument parsing and automatic generation of the "usage" for your script
|
||||||
|
# - utility functions
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# - define the variable ARGS_DEF (see below) with the arguments for your script
|
||||||
|
# - include this file using `source utils.inc` at the end of your script.
|
||||||
|
#
|
||||||
|
# Default control flow:
|
||||||
|
# 0. Set the current directory to the directory of the script. By this
|
||||||
|
# the script can be called from anywhere.
|
||||||
|
# 1. Parse the named arguments
|
||||||
|
# 2. [Redacted]
|
||||||
|
# 3. If the parameter "verbose" is set, the `-x` flag will be set in bash.
|
||||||
|
# 4. The function "init" will be called if it exists
|
||||||
|
# 5. If the parameter "action" is set, it will call the function with the name of that parameter.
|
||||||
|
# Otherwise the function "run" will be called.
|
||||||
|
#
|
||||||
|
# Named Argument Parsing:
|
||||||
|
# - The variable ARGS_DEF defines the valid command arguments
|
||||||
|
# * Required args syntax: --paramName=paramRegex
|
||||||
|
# * Optional args syntax: [--paramName=paramRegex]
|
||||||
|
# * e.g. ARG_DEFS=("--required_param=(.+)" "[--optional_param=(.+)]")
|
||||||
|
# - Checks that:
|
||||||
|
# * all arguments match to an entry in ARGS_DEF
|
||||||
|
# * all required arguments are present
|
||||||
|
# * all arguments match their regex
|
||||||
|
# - Afterwards, every paramter value will be stored in a variable
|
||||||
|
# with the name of the parameter in upper case (with dash converted to underscore).
|
||||||
|
#
|
||||||
|
# Special arguments that are always available:
|
||||||
|
# - "--action=.*": This parameter will be used to dispatch to a function with that name when the
|
||||||
|
# script is started
|
||||||
|
|
||||||
|
# - "--verbose=true": This will set the `-x` flag in bash so that all calls will be logged
|
||||||
|
#
|
||||||
|
# Utility functions:
|
||||||
|
# - readJsonProp
|
||||||
|
# - replaceJsonProp
|
||||||
|
# - resolveDir
|
||||||
|
# - getVar
|
||||||
|
# - serVar
|
||||||
|
# - isFunction
|
||||||
|
|
||||||
|
# always stop on errors
|
||||||
|
set -e
|
||||||
|
|
||||||
|
function usage {
|
||||||
|
echo "Usage: ${0} ${ARG_DEFS[@]}"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function parseArgs {
|
||||||
|
local REQUIRED_ARG_NAMES=()
|
||||||
|
|
||||||
|
# -- helper functions
|
||||||
|
function varName {
|
||||||
|
# everything to upper case and dash to underscore
|
||||||
|
echo ${1//-/_} | tr '[:lower:]' '[:upper:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
function readArgDefs {
|
||||||
|
local ARG_DEF
|
||||||
|
local AD_OPTIONAL
|
||||||
|
local AD_NAME
|
||||||
|
local AD_RE
|
||||||
|
|
||||||
|
# -- helper functions
|
||||||
|
function parseArgDef {
|
||||||
|
local ARG_DEF_REGEX="(\[?)--([^=]+)=(.*)"
|
||||||
|
if [[ ! $1 =~ $ARG_DEF_REGEX ]]; then
|
||||||
|
echo "Internal error: arg def has wrong format: $ARG_DEF"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
AD_OPTIONAL="${BASH_REMATCH[1]}"
|
||||||
|
AD_NAME="${BASH_REMATCH[2]}"
|
||||||
|
AD_RE="${BASH_REMATCH[3]}"
|
||||||
|
if [[ $AD_OPTIONAL ]]; then
|
||||||
|
# Remove last bracket for optional args.
|
||||||
|
# Can't put this into the ARG_DEF_REGEX somehow...
|
||||||
|
AD_RE=${AD_RE%?}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- run
|
||||||
|
for ARG_DEF in "${ARG_DEFS[@]}"
|
||||||
|
do
|
||||||
|
parseArgDef $ARG_DEF
|
||||||
|
|
||||||
|
local AD_NAME_UPPER=$(varName $AD_NAME)
|
||||||
|
setVar "${AD_NAME_UPPER}_OPTIONAL" "$AD_OPTIONAL"
|
||||||
|
setVar "${AD_NAME_UPPER}_RE" "$AD_RE"
|
||||||
|
if [[ ! $AD_OPTIONAL ]]; then
|
||||||
|
REQUIRED_ARG_NAMES+=($AD_NAME)
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function readAndValidateArgs {
|
||||||
|
local ARG_NAME
|
||||||
|
local ARG_VALUE
|
||||||
|
local ARG_NAME_UPPER
|
||||||
|
|
||||||
|
# -- helper functions
|
||||||
|
function parseArg {
|
||||||
|
local ARG_REGEX="--([^=]+)=?(.*)"
|
||||||
|
|
||||||
|
if [[ ! $1 =~ $ARG_REGEX ]]; then
|
||||||
|
echo "Can't parse argument $i"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
ARG_NAME="${BASH_REMATCH[1]}"
|
||||||
|
ARG_VALUE="${BASH_REMATCH[2]}"
|
||||||
|
ARG_NAME_UPPER=$(varName $ARG_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateArg {
|
||||||
|
local AD_RE=$(getVar ${ARG_NAME_UPPER}_RE)
|
||||||
|
|
||||||
|
if [[ ! $AD_RE ]]; then
|
||||||
|
echo "Unknown option: $ARG_NAME"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! $ARG_VALUE =~ ^${AD_RE}$ ]]; then
|
||||||
|
echo "Wrong format: $ARG_NAME"
|
||||||
|
usage;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# validate that the "action" option points to a valid function
|
||||||
|
if [[ $ARG_NAME == "action" ]] && ! isFunction $ARG_VALUE; then
|
||||||
|
echo "No action $ARG_VALUE defined in this script"
|
||||||
|
usage;
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- run
|
||||||
|
for i in "$@"
|
||||||
|
do
|
||||||
|
parseArg $i
|
||||||
|
validateArg
|
||||||
|
setVar "${ARG_NAME_UPPER}" "$ARG_VALUE"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkMissingArgs {
|
||||||
|
local ARG_NAME
|
||||||
|
for ARG_NAME in "${REQUIRED_ARG_NAMES[@]}"
|
||||||
|
do
|
||||||
|
ARG_VALUE=$(getVar $(varName $ARG_NAME))
|
||||||
|
|
||||||
|
if [[ ! $ARG_VALUE ]]; then
|
||||||
|
echo "Missing: $ARG_NAME"
|
||||||
|
usage;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- run
|
||||||
|
readArgDefs
|
||||||
|
readAndValidateArgs "$@"
|
||||||
|
checkMissingArgs
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# getVar(varName)
|
||||||
|
function getVar {
|
||||||
|
echo ${!1}
|
||||||
|
}
|
||||||
|
|
||||||
|
# setVar(varName, varValue)
|
||||||
|
function setVar {
|
||||||
|
eval "$1=\"$2\""
|
||||||
|
}
|
||||||
|
|
||||||
|
# isFunction(name)
|
||||||
|
# - to be used in an if, so return 0 if successful and 1 if not!
|
||||||
|
function isFunction {
|
||||||
|
if [[ $(type -t $1) == "function" ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# readJsonProp(jsonFile, property)
|
||||||
|
# - restriction: property needs to be on an own line!
|
||||||
|
function readJsonProp {
|
||||||
|
echo $(sed -En 's/.*"'$2'"[ ]*:[ ]*"(.*)".*/\1/p' $1)
|
||||||
|
}
|
||||||
|
|
||||||
|
# replaceJsonProp(jsonFile, property, newValue)
|
||||||
|
# - note: propertyRegex will be automatically placed into a
|
||||||
|
# capturing group! -> all other groups start at index 2!
|
||||||
|
function replaceJsonProp {
|
||||||
|
replaceInFile $1 "\"$2\": \".*?\"" "\"$2\": \"$3\""
|
||||||
|
}
|
||||||
|
|
||||||
|
# replaceInFile(file, findPattern, replacePattern)
|
||||||
|
function replaceInFile {
|
||||||
|
perl -pi -e "s/$2/$3/g;" $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# resolveDir(relativeDir)
|
||||||
|
# - resolves a directory relative to the current script
|
||||||
|
function resolveDir {
|
||||||
|
echo $(cd $SCRIPT_DIR; cd $1; pwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
function main {
|
||||||
|
# normalize the working dir to the directory of the script
|
||||||
|
cd $(dirname $0);SCRIPT_DIR=$(pwd)
|
||||||
|
|
||||||
|
ARG_DEFS+=("[--verbose=(true|false)]")
|
||||||
|
parseArgs "$@"
|
||||||
|
|
||||||
|
|
||||||
|
# --verbose argument
|
||||||
|
if [[ $VERBOSE == "true" ]]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isFunction init; then
|
||||||
|
init "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# jump to the function denoted by the --action argument,
|
||||||
|
# otherwise call the "run" function
|
||||||
|
if [[ $ACTION ]]; then
|
||||||
|
$ACTION "$@"
|
||||||
|
else
|
||||||
|
run "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main "$@"
|
Reference in New Issue
Block a user