Skip to content

Commit

Permalink
fix(prerender): local references to window/document
Browse files Browse the repository at this point in the history
  • Loading branch information
manucorporat committed Apr 19, 2018
1 parent 86a6cde commit 78bd146
Show file tree
Hide file tree
Showing 42 changed files with 174 additions and 139 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Listen, Method } from '@stencil/core';
import { Component, Listen, Method, Prop } from '@stencil/core';
import { ActionSheetOptions } from '../../index';
import { OverlayController, createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';

Expand All @@ -9,6 +9,8 @@ export class ActionSheetController implements OverlayController {

private actionSheets = new Map<number, HTMLIonActionSheetElement>();

@Prop({ context: 'document' }) doc: Document;

@Listen('body:ionActionSheetWillPresent')
protected actionSheetWillPresent(ev: any) {
this.actionSheets.set(ev.target.overlayId, ev.target);
Expand All @@ -30,7 +32,7 @@ export class ActionSheetController implements OverlayController {
*/
@Method()
create(opts?: ActionSheetOptions): Promise<HTMLIonActionSheetElement> {
return createOverlay(document.createElement('ion-action-sheet'), opts);
return createOverlay(this.doc.createElement('ion-action-sheet'), opts);
}

/*
Expand Down
6 changes: 4 additions & 2 deletions core/src/components/alert-controller/alert-controller.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Listen, Method } from '@stencil/core';
import { Component, Listen, Method, Prop } from '@stencil/core';
import { AlertOptions } from '../../index';
import { OverlayController, createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';

Expand All @@ -9,6 +9,8 @@ export class AlertController implements OverlayController {

private alerts = new Map<number, HTMLIonAlertElement>();

@Prop({ context: 'document' }) doc: Document;

@Listen('body:ionAlertWillPresent')
protected alertWillPresent(ev: any) {
this.alerts.set(ev.target.overlayId, ev.target);
Expand All @@ -30,7 +32,7 @@ export class AlertController implements OverlayController {
*/
@Method()
create(opts?: AlertOptions): Promise<HTMLIonAlertElement> {
return createOverlay(document.createElement('ion-alert'), opts);
return createOverlay(this.doc.createElement('ion-alert'), opts);
}

/*
Expand Down
4 changes: 3 additions & 1 deletion core/src/components/anchor/anchor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { openURL } from '../../utils/theme';
})
export class Anchor {

@Prop({ context: 'window' }) win: Window;

/**
* Contains a URL or a URL fragment that the hyperlink points to.
* If this property is set, an anchor tag will be rendered.
Expand All @@ -22,7 +24,7 @@ export class Anchor {
render() {
return <a
href={this.href}
onClick={(ev) => openURL(this.href, ev, this.routerDirection)}>
onClick={(ev) => openURL(this.win, this.href, ev, this.routerDirection)}>
<slot/>
</a>;
}
Expand Down
3 changes: 2 additions & 1 deletion core/src/components/back-button/back-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class BackButton {
@Element() el: HTMLElement;

@Prop({ context: 'config' }) config: Config;
@Prop({ context: 'window' }) win: Window;

/**
* The color to use from your Sass `$colors` map.
Expand Down Expand Up @@ -54,7 +55,7 @@ export class BackButton {
ev.preventDefault();
nav.pop();
} else if (this.defaultHref) {
openURL(this.defaultHref, ev, 'back');
openURL(this.win, this.defaultHref, ev, 'back');
}
}

Expand Down
14 changes: 8 additions & 6 deletions core/src/components/backdrop/backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export class Backdrop {

private lastClick = -10000;

@Prop({ context: 'document' }) doc: Document;

/**
* If true, the backdrop will be visible. Defaults to `true`.
*/
Expand All @@ -36,11 +38,11 @@ export class Backdrop {
@Event() ionBackdropTap: EventEmitter;

componentDidLoad() {
registerBackdrop(this);
registerBackdrop(this.doc, this);
}

componentDidUnload() {
unregisterBackdrop(this);
unregisterBackdrop(this.doc, this);
}

@Listen('touchstart', {passive: false, capture: true})
Expand Down Expand Up @@ -80,14 +82,14 @@ export class Backdrop {
const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
const activeBackdrops = new Set();

function registerBackdrop(backdrop: any) {
function registerBackdrop(doc: Document, backdrop: any) {
activeBackdrops.add(backdrop);
document.body.classList.add(BACKDROP_NO_SCROLL);
doc.body.classList.add(BACKDROP_NO_SCROLL);
}

function unregisterBackdrop(backdrop: any) {
function unregisterBackdrop(doc: Document, backdrop: any) {
activeBackdrops.delete(backdrop);
if (activeBackdrops.size === 0) {
document.body.classList.remove(BACKDROP_NO_SCROLL);
doc.body.classList.remove(BACKDROP_NO_SCROLL);
}
}
5 changes: 4 additions & 1 deletion core/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import { getButtonClassMap, getElementClassMap, openURL } from '../../utils/them
}
})
export class Button {

@Element() private el: HTMLElement;

@Prop({ context: 'window' }) win: Window;

@State() keyFocus: boolean;

/**
Expand Down Expand Up @@ -145,7 +148,7 @@ export class Button {
onFocus={this.onFocus.bind(this)}
onKeyUp={this.onKeyUp.bind(this)}
onBlur={this.onBlur.bind(this)}
onClick={(ev) => openURL(this.href, ev, this.routerDirection)}>
onClick={(ev) => openURL(this.win, this.href, ev, this.routerDirection)}>
<span class='button-inner'>
<slot name='icon-only'></slot>
<slot name='start'></slot>
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/fab/fab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class Fab {
*/
@Prop() edge = false;

@Prop({mutable: true}) activated = false;
@Prop({ mutable: true }) activated = false;
@Watch('activated')
activatedChanged() {
const activated = this.activated;
Expand Down
2 changes: 1 addition & 1 deletion core/src/components/hide-when/hide-when.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class HideWhen implements DisplayWhen {

@Element() element: HTMLElement;
@Prop({ context: 'config' }) config: Config;
@Prop({ context: 'window'}) win: Window;
@Prop({ context: 'window' }) win: Window;

@Prop() orientation: string;
@Prop() mediaQuery: string;
Expand Down
10 changes: 6 additions & 4 deletions core/src/components/input-shims/hacks/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export function relocateInput(
// before it receives the actual focus event
// We hide the focused input (with the visible caret) invisiable by making it scale(0),
cloneInputComponent(componentEl, inputEl);
const tx = document.dir === 'rtl' ? 9999 : -9999;
const doc = componentEl.ownerDocument;
const tx = doc.dir === 'rtl' ? 9999 : -9999;
inputEl.style.transform = `translate3d(${tx}px,${inputRelativeY}px,0)`;
// TODO
// inputEle.style.opacity = '0';
Expand All @@ -33,7 +34,7 @@ export function relocateInput(


export function isFocused(input: HTMLInputElement): boolean {
return input === document.activeElement;
return input === input.ownerDocument.activeElement;
}

function removeClone(componentEl: HTMLElement, inputEl: HTMLElement) {
Expand All @@ -56,6 +57,7 @@ function cloneInputComponent(componentEl: HTMLElement, inputEl: HTMLInputElement
// find its parent wrapping component like <ion-input> or <ion-textarea>
// then clone the entire component
const parentElement = componentEl.parentElement;
const doc = componentEl.ownerDocument;
if (componentEl && parentElement) {
// DOM READ
const srcTop = componentEl.offsetTop;
Expand All @@ -65,7 +67,7 @@ function cloneInputComponent(componentEl: HTMLElement, inputEl: HTMLInputElement

// DOM WRITE
// not using deep clone so we don't pull in unnecessary nodes
const clonedComponentEle = document.createElement('div');
const clonedComponentEle = doc.createElement('div');
const clonedStyle = clonedComponentEle.style;
clonedComponentEle.classList.add(...Array.from(componentEl.classList));
clonedComponentEle.classList.add('cloned-input');
Expand All @@ -77,7 +79,7 @@ function cloneInputComponent(componentEl: HTMLElement, inputEl: HTMLInputElement
clonedStyle.width = srcWidth + 'px';
clonedStyle.height = srcHeight + 'px';

const clonedInputEl = document.createElement('input');
const clonedInputEl = doc.createElement('input');
clonedInputEl.classList.add(...Array.from(inputEl.classList));
clonedInputEl.value = inputEl.value;
clonedInputEl.type = inputEl.type;
Expand Down
16 changes: 8 additions & 8 deletions core/src/components/input-shims/hacks/input-blurring.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

const SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA'];

export default function enableInputBlurring() {
export default function enableInputBlurring(doc: Document) {
console.debug('Input: enableInputBlurring');

let focused = true;
Expand All @@ -21,7 +21,7 @@ export default function enableInputBlurring() {
didScroll = false;
return;
}
const active = document.activeElement as HTMLElement;
const active = doc.activeElement as HTMLElement;
if (!active) {
return;
}
Expand Down Expand Up @@ -53,13 +53,13 @@ export default function enableInputBlurring() {
}, 50);
}

document.addEventListener('ionScrollStart', onScroll);
document.addEventListener('focusin', onFocusin, true);
document.addEventListener('touchend', onTouchend, false);
doc.addEventListener('ionScrollStart', onScroll);
doc.addEventListener('focusin', onFocusin, true);
doc.addEventListener('touchend', onTouchend, false);

return () => {
document.removeEventListener('ionScrollStart', onScroll, true);
document.removeEventListener('focusin', onFocusin, true);
document.removeEventListener('touchend', onTouchend, false);
doc.removeEventListener('ionScrollStart', onScroll, true);
doc.removeEventListener('focusin', onFocusin, true);
doc.removeEventListener('touchend', onTouchend, false);
};
}
10 changes: 5 additions & 5 deletions core/src/components/input-shims/hacks/scroll-padding.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const PADDING_TIMER_KEY = '$ionPaddingTimer';

export default function enableScrollPadding(keyboardHeight: number) {
export default function enableScrollPadding(doc: Document, keyboardHeight: number) {
console.debug('Input: enableScrollPadding');

function onFocusin(ev: any) {
Expand All @@ -10,12 +10,12 @@ export default function enableScrollPadding(keyboardHeight: number) {
setScrollPadding(ev.target, 0);
}

document.addEventListener('focusin', onFocusin);
document.addEventListener('focusout', onFocusout);
doc.addEventListener('focusin', onFocusin);
doc.addEventListener('focusout', onFocusout);

return () => {
document.removeEventListener('focusin', onFocusin);
document.removeEventListener('focusout', onFocusout);
doc.removeEventListener('focusin', onFocusin);
doc.removeEventListener('focusout', onFocusout);
};
}

Expand Down
9 changes: 5 additions & 4 deletions core/src/components/input-shims/input-shims.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export class InputShims {
private hideCaretMap = new WeakMap<HTMLElement, Function>();
private scrollAssistMap = new WeakMap<HTMLElement, Function>();

@Prop({context: 'config'}) config: Config;
@Prop({ context: 'config' }) config: Config;
@Prop({ context: 'document' }) doc: Document;

componentDidLoad() {
this.keyboardHeight = this.config.getNumber('keyboardHeight', 290);
Expand All @@ -32,18 +33,18 @@ export class InputShims {

const inputBlurring = this.config.getBoolean('inputBlurring', true);
if (inputBlurring && INPUT_BLURRING) {
enableInputBlurring();
enableInputBlurring(this.doc);
}

const scrollPadding = this.config.getBoolean('scrollPadding', true);
if (scrollPadding && SCROLL_PADDING) {
enableScrollPadding(this.keyboardHeight);
enableScrollPadding(this.doc, this.keyboardHeight);
}

// Input might be already loaded in the DOM before ion-device-hacks did.
// At this point we need to look for all the ion-inputs not registered yet
// and register them.
const inputs = Array.from(document.querySelectorAll('ion-input'));
const inputs = Array.from(this.doc.querySelectorAll('ion-input'));
for (const input of inputs) {
this.registerInput(input);
}
Expand Down
4 changes: 3 additions & 1 deletion core/src/components/item-options/item-options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { Side, isRightSide } from '../../utils/helpers';
export class ItemOptions {
@Element() private el: HTMLElement;

@Prop({ context: 'window' }) win: Window;

/**
* The side the option button should be on.
* Possible values: `"start"` and `"end"`.
Expand All @@ -27,7 +29,7 @@ export class ItemOptions {

@Method()
isRightSide() {
return isRightSide(this.side);
return isRightSide(this.win, this.side);
}

@Method()
Expand Down
4 changes: 3 additions & 1 deletion core/src/components/item/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export class Item {

@Element() private el: HTMLStencilElement;

@Prop({ context: 'window' }) win: Window;

/**
* The color to use from your Sass `$colors` map.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
Expand Down Expand Up @@ -125,7 +127,7 @@ export class Item {
<TagType
{...attrs}
class={themedClasses}
onClick={(ev) => openURL(this.href, ev, this.routerDirection)}>
onClick={(ev) => openURL(this.win, this.href, ev, this.routerDirection)}>
<slot name='start'></slot>
<div class='item-inner'>
<div class='input-wrapper'>
Expand Down
6 changes: 4 additions & 2 deletions core/src/components/loading-controller/loading-controller.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Listen, Method } from '@stencil/core';
import { Component, Listen, Method, Prop } from '@stencil/core';
import { LoadingOptions } from '../../index';
import { OverlayController, createOverlay, dismissOverlay, getTopOverlay, removeLastOverlay } from '../../utils/overlays';

Expand All @@ -10,6 +10,8 @@ export class LoadingController implements OverlayController {

private loadings = new Map<number, HTMLIonLoadingElement>();

@Prop({ context: 'document' }) doc: Document;

@Listen('body:ionLoadingWillPresent')
protected loadingWillPresent(ev: any) {
this.loadings.set(ev.target.overlayId, ev.target);
Expand All @@ -31,7 +33,7 @@ export class LoadingController implements OverlayController {
*/
@Method()
create(opts?: LoadingOptions): Promise<HTMLIonLoadingElement> {
return createOverlay(document.createElement('ion-loading'), opts);
return createOverlay(this.doc.createElement('ion-loading'), opts);
}

/*
Expand Down
Loading

0 comments on commit 78bd146

Please sign in to comment.