mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-23 14:01:20 +08:00
refactor(delegate): don't automatically append ion-page, add tests for host-element for modal and nav
This commit is contained in:
@ -38,9 +38,16 @@
|
|||||||
// create component to open
|
// create component to open
|
||||||
const element = document.createElement('ion-page');
|
const element = document.createElement('ion-page');
|
||||||
element.innerHTML = `
|
element.innerHTML = `
|
||||||
<div style="height: 500px; background-color: red">
|
<ion-header>
|
||||||
<ion-button>Close the modal</ion-button>
|
<ion-toolbar>
|
||||||
</div>
|
<ion-title>Super Modal</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<h1>Content of doom</h1>
|
||||||
|
<div>Here's some more content</div>
|
||||||
|
<ion-button>Dismiss Modal</ion-button>
|
||||||
|
</ion-content>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// listen for close event
|
// listen for close event
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Modal - Basic</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<script src="/dist/ionic.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-page>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Modal - Basic</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content padding>
|
||||||
|
<ion-modal-controller></ion-modal-controller>
|
||||||
|
<p>
|
||||||
|
<ion-button class="e2ePresentModal" onclick="presentModal()">Present modal</ion-button>
|
||||||
|
</p>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>
|
||||||
|
</ion-app>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.addEventListener("ionModalDidDismiss", function(e){console.log('DidDismiss', e)})
|
||||||
|
window.addEventListener("ionModalWillDismiss", function(e){console.log('WillDismiss', e)})
|
||||||
|
|
||||||
|
class ModalPage extends HTMLElement {
|
||||||
|
async connectedCallback() {
|
||||||
|
this.innerHTML = `
|
||||||
|
<ion-page>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Super Modal</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<h1>Content of doom</h1>
|
||||||
|
<div>Here's some more content</div>
|
||||||
|
<ion-button>Dismiss Modal</ion-button>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>`;
|
||||||
|
|
||||||
|
// listen for close event
|
||||||
|
const button = this.querySelector('ion-button');
|
||||||
|
button.addEventListener('click', async () => {
|
||||||
|
await this.querySelector('ion-modal-controller').dismiss();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function presentModal() {
|
||||||
|
|
||||||
|
// initialize controller
|
||||||
|
const modalController = document.querySelector('ion-modal-controller');
|
||||||
|
await modalController.componentOnReady();
|
||||||
|
|
||||||
|
// present the modal
|
||||||
|
const modalElement = await modalController.create({
|
||||||
|
component: 'modal-page'
|
||||||
|
});
|
||||||
|
modalElement.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('modal-page', ModalPage);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -30,7 +30,7 @@
|
|||||||
async function loadFirstPage() {
|
async function loadFirstPage() {
|
||||||
const nav = document.querySelector('ion-nav');
|
const nav = document.querySelector('ion-nav');
|
||||||
await nav.componentOnReady();
|
await nav.componentOnReady();
|
||||||
const firstPage = document.createElement('div');
|
const firstPage = document.createElement('ion-page');
|
||||||
firstPage.classList.add('first-page');
|
firstPage.classList.add('first-page');
|
||||||
firstPage.innerHTML = `
|
firstPage.innerHTML = `
|
||||||
<ion-header>
|
<ion-header>
|
||||||
@ -54,7 +54,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function goToPageTwo(nav) {
|
async function goToPageTwo(nav) {
|
||||||
const secondPage = document.createElement('div');
|
const secondPage = document.createElement('ion-page');
|
||||||
secondPage.classList.add('second-page');
|
secondPage.classList.add('second-page');
|
||||||
secondPage.innerHTML = `
|
secondPage.innerHTML = `
|
||||||
<ion-header>
|
<ion-header>
|
||||||
@ -84,7 +84,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function goToPageThree(nav) {
|
async function goToPageThree(nav) {
|
||||||
const thirdPage = document.createElement('div');
|
const thirdPage = document.createElement('ion-page');
|
||||||
thirdPage.classList.add('third-page');
|
thirdPage.classList.add('third-page');
|
||||||
thirdPage.innerHTML = `
|
thirdPage.innerHTML = `
|
||||||
<ion-header>
|
<ion-header>
|
||||||
|
52
packages/core/src/components/nav/test/host-elements/e2e.js
Normal file
52
packages/core/src/components/nav/test/host-elements/e2e.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { register, Page, platforms } = require('../../../../../scripts/e2e');
|
||||||
|
const { getElement, waitForTransition } = require('../../../../../scripts/e2e/utils');
|
||||||
|
|
||||||
|
class E2ETestPage extends Page {
|
||||||
|
constructor(driver, platform) {
|
||||||
|
super(driver, `http://localhost:3333/src/components/nav/test/host-elements?ionicplatform=${platform}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
platforms.forEach(platform => {
|
||||||
|
describe('nav/host-elements', () => {
|
||||||
|
|
||||||
|
register('should init', driver => {
|
||||||
|
const page = new E2ETestPage(driver, platform);
|
||||||
|
return page.navigate();
|
||||||
|
});
|
||||||
|
|
||||||
|
register('should go to page-one, page-two, page-three, then back to page-two, page-one', async (driver, testContext) => {
|
||||||
|
|
||||||
|
testContext.timeout(10000);
|
||||||
|
const page = new E2ETestPage(driver, platform);
|
||||||
|
|
||||||
|
// go to page two
|
||||||
|
const pageOneNextButtonSelector = 'page-one ion-button.next.hydrated';
|
||||||
|
const pageOneNextButton = await getElement(driver, pageOneNextButtonSelector);
|
||||||
|
pageOneNextButton.click();
|
||||||
|
await waitForTransition(600);
|
||||||
|
|
||||||
|
// go to page three
|
||||||
|
const pageTwoNextButtonSelector = 'page-two ion-button.next.hydrated';
|
||||||
|
const pageTwoNextButton = await getElement(driver, pageTwoNextButtonSelector);
|
||||||
|
pageTwoNextButton.click();
|
||||||
|
await waitForTransition(600);
|
||||||
|
|
||||||
|
// go back to page two
|
||||||
|
const pageThreeBackButtonSelector = 'page-three ion-button.previous.hydrated';
|
||||||
|
const pageThreeBackButton = await getElement(driver, pageThreeBackButtonSelector);
|
||||||
|
pageThreeBackButton.click();
|
||||||
|
await waitForTransition(600);
|
||||||
|
|
||||||
|
// go back to page two
|
||||||
|
const pageTwoBackButtonSelector = 'page-two ion-button.previous.hydrated';
|
||||||
|
const pageTwoBackButton = await getElement(driver, pageTwoBackButtonSelector);
|
||||||
|
pageTwoBackButton.click();
|
||||||
|
await waitForTransition(600);
|
||||||
|
|
||||||
|
// we're back on page one now
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Nav</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<script src="/dist/ionic.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-nav root="page-one"></ion-nav>
|
||||||
|
</ion-app>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
class PageOne extends HTMLElement {
|
||||||
|
async connectedCallback() {
|
||||||
|
this.innerHTML = `
|
||||||
|
<ion-page>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Page One</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content padding>
|
||||||
|
<h1>Page One</h1>
|
||||||
|
<ion-button class="next">Go to Page Two</ion-button>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>`;
|
||||||
|
|
||||||
|
const button = this.querySelector('ion-button');
|
||||||
|
button.addEventListener('click', async () => {
|
||||||
|
this.closest('ion-nav').push('page-two');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageTwo extends HTMLElement {
|
||||||
|
async connectedCallback() {
|
||||||
|
this.innerHTML = `
|
||||||
|
<ion-page>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Page Two</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content padding>
|
||||||
|
<h1>Page Two</h1>
|
||||||
|
<ion-button class="next">Go to Page Three</ion-button>
|
||||||
|
<ion-button class="previous">Go Back</ion-button>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>`;
|
||||||
|
|
||||||
|
const previousButton = this.querySelector('ion-button.previous');
|
||||||
|
previousButton.addEventListener('click', async () => {
|
||||||
|
await this.closest('ion-nav').pop();
|
||||||
|
});
|
||||||
|
|
||||||
|
const nextButton = this.querySelector('ion-button.next');
|
||||||
|
nextButton.addEventListener('click', async () => {
|
||||||
|
await this.closest('ion-nav').push('page-three');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageThree extends HTMLElement {
|
||||||
|
async connectedCallback() {
|
||||||
|
this.innerHTML = `
|
||||||
|
<ion-page>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Page Three</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content padding>
|
||||||
|
<h1>Page Three</h1>
|
||||||
|
<ion-button class="previous">Go Back</ion-button>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>`;
|
||||||
|
|
||||||
|
const previousButton = this.querySelector('ion-button.previous');
|
||||||
|
previousButton.addEventListener('click', async () => {
|
||||||
|
await this.closest('ion-nav').pop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('page-one', PageOne);
|
||||||
|
customElements.define('page-two', PageTwo);
|
||||||
|
customElements.define('page-three', PageThree);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
@ -1,5 +1,5 @@
|
|||||||
import { FrameworkDelegate, FrameworkMountingData, } from '../index';
|
import { FrameworkDelegate, FrameworkMountingData, } from '../index';
|
||||||
import { isElementModal, isElementNav, isString } from './helpers';
|
import { isString } from './helpers';
|
||||||
|
|
||||||
export class DomFrameworkDelegate implements FrameworkDelegate {
|
export class DomFrameworkDelegate implements FrameworkDelegate {
|
||||||
|
|
||||||
@ -14,11 +14,10 @@ export class DomFrameworkDelegate implements FrameworkDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const elementToAppend = shouldWrapInIonPage(parentElement) ? createIonPageAndAppendUserElement(usersElement) : usersElement;
|
parentElement.appendChild(usersElement);
|
||||||
parentElement.appendChild(elementToAppend);
|
|
||||||
|
|
||||||
resolve({
|
resolve({
|
||||||
element: elementToAppend
|
element: usersElement
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -30,13 +29,3 @@ export class DomFrameworkDelegate implements FrameworkDelegate {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldWrapInIonPage(element: HTMLElement) {
|
|
||||||
return isElementModal(element) || isElementNav(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createIonPageAndAppendUserElement(userElement: HTMLElement) {
|
|
||||||
const wrappingElement = document.createElement('ion-page');
|
|
||||||
wrappingElement.appendChild(userElement);
|
|
||||||
return wrappingElement;
|
|
||||||
}
|
|
||||||
|
@ -24,14 +24,6 @@ export function isStringOrNumber(v: any): v is (string | number) { return isStri
|
|||||||
|
|
||||||
export function isBlank(val: any): val is null { return val === undefined || val === null; }
|
export function isBlank(val: any): val is null { return val === undefined || val === null; }
|
||||||
|
|
||||||
export function isElementNav(element: HTMLElement) {
|
|
||||||
return element.tagName.toUpperCase() === 'ION-NAV';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isElementModal(element: HTMLElement) {
|
|
||||||
return element.classList.contains('modal-wrapper');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
export function isCheckedProperty(a: any, b: any): boolean {
|
export function isCheckedProperty(a: any, b: any): boolean {
|
||||||
if (a === undefined || a === null || a === '') {
|
if (a === undefined || a === null || a === '') {
|
||||||
|
Reference in New Issue
Block a user