Skip to content

Commit

Permalink
PWA: migrate document-click service to ampdoc scope (ampproject#5154)
Browse files Browse the repository at this point in the history
* PWA: Migrate document-click to ampdoc scope

* minors

* fixed tests

* liter
  • Loading branch information
dvoytenko authored Sep 22, 2016
1 parent 74c40e0 commit f2e39be
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 83 deletions.
4 changes: 2 additions & 2 deletions src/amp.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import './polyfills';
import {installPerformanceService} from './service/performance-impl';
import {installPullToRefreshBlocker} from './pull-to-refresh';
import {installGlobalClickListener} from './document-click';
import {installGlobalClickListenerForDoc} from './document-click';
import {installStyles, makeBodyVisible} from './style-installer';
import {installErrorReporting} from './error';
import {installDocService} from './service/ampdoc-impl';
Expand Down Expand Up @@ -68,7 +68,7 @@ try {
stubElements(self);

installPullToRefreshBlocker(self);
installGlobalClickListener(self);
installGlobalClickListenerForDoc(ampdoc);

maybeValidate(self);
makeBodyVisible(self.document, /* waitForServices */ true);
Expand Down
91 changes: 38 additions & 53 deletions src/document-click.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

import {closestByTag} from './dom';
import {fromClass} from './service';
import {fromClassForDoc} from './service';
import {dev} from './log';
import {historyForDoc} from './history';
import {openWindowDialog} from './dom';
Expand All @@ -28,33 +28,15 @@ import {urlReplacementsFor} from './url-replacements';
/** @private @const {string} */
const ORIGINAL_HREF_ATTRIBUTE = 'data-amp-orig-href';

/**
* @param {!Window} window
*/
export function installGlobalClickListener(window) {
clickHandlerFor(window);
captureClickHandlerFor(window);
}

/**
* @param {!Window} window
* @param {!./service/ampdoc-impl.AmpDoc} ampdoc
*/
export function uninstallGlobalClickListener(window) {
clickHandlerFor(window).cleanup();
captureClickHandlerFor(window).cleanup();
export function installGlobalClickListenerForDoc(ampdoc) {
fromClassForDoc(ampdoc, 'clickhandler', ClickHandler);
fromClassForDoc(ampdoc, 'CaptureClickHandler', CaptureClickHandler);
}

/**
* @param {!Window} window
* @return {!ClickHandler} bubble document click handler.
*/
function clickHandlerFor(window) {
return fromClass(window, 'clickhandler', ClickHandler);
}

function captureClickHandlerFor(window) {
return fromClass(window, 'CaptureClickHandler', CaptureClickHandler);
}

/**
* Intercept any click on the current document and prevent any
Expand All @@ -63,31 +45,30 @@ function captureClickHandlerFor(window) {
*/
export class ClickHandler {
/**
* @param {!Window} window
* @param {!./service/ampdoc-impl.AmpDoc} ampdoc
*/
constructor(window) {
/** @const {!Window} */
this.win = window;
constructor(ampdoc) {
/** @const {!./service/ampdoc-impl.AmpDoc} */
this.ampdoc = ampdoc;

/** @private @const {!./service/viewport-impl.Viewport} */
this.viewport_ = viewportFor(this.win);
this.viewport_ = viewportFor(this.ampdoc.win);

/** @private @const {!./service/viewer-impl.Viewer} */
this.viewer_ = viewerFor(this.win);
this.viewer_ = viewerFor(this.ampdoc.win);

/** @private @const {!./service/history-impl.History} */
this.history_ = historyForDoc(this.win.document);
this.history_ = historyForDoc(this.ampdoc);

const platform = platformFor(this.win);
const platform = platformFor(this.ampdoc.win);
/** @private @const {boolean} */
this.isIosSafari_ = platform.isIos() && platform.isSafari();

// Only intercept clicks when iframed.
if (this.viewer_.isIframed() && this.viewer_.isOvertakeHistory()) {
/** @private @const {!function(!Event)|undefined} */
this.boundHandle_ = this.handle_.bind(this);
this.win.document.documentElement.addEventListener(
'click', this.boundHandle_);
this.ampdoc.getRootNode().addEventListener('click', this.boundHandle_);
}
}

Expand All @@ -96,8 +77,7 @@ export class ClickHandler {
*/
cleanup() {
if (this.boundHandle_) {
this.win.document.documentElement.removeEventListener(
'click', this.boundHandle_);
this.ampdoc.getRootNode().removeEventListener('click', this.boundHandle_);
}
}

Expand All @@ -109,39 +89,40 @@ export class ClickHandler {
*/
handle_(e) {
onDocumentElementClick_(
e, this.viewport_, this.history_, this.isIosSafari_);
e, this.ampdoc, this.viewport_, this.history_, this.isIosSafari_);
}
}


/**
* Intercept any click on the current document and prevent any
* linking to an identifier from pushing into the history stack.
* @visibleForTesting
*/
export class CaptureClickHandler {
/**
* @param {!Window} window
* @param {!./service/ampdoc-impl.AmpDoc} ampdoc
*/
constructor(window) {
/** @const {!Window} */
this.win = window;
constructor(ampdoc) {
/** @const {!./service/ampdoc-impl.AmpDoc} */
this.ampdoc = ampdoc;

/** @private @const {!./service/url-replacements-impl.UrlReplacements} */
this.urlReplacements_ = urlReplacementsFor(this.win);
this.urlReplacements_ = urlReplacementsFor(this.ampdoc.win);

/** @private {!function(!Event)} */
this.boundHandler_ = this.handle_.bind(this);

this.win.document.documentElement.addEventListener(
this.ampdoc.getRootNode().addEventListener(
'click', this.boundHandler_, true);
}

/**
* Removes all event listeners.
*/
cleanup() {
this.win.document.documentElement.removeEventListener(
'click', this.boundHandler_);
this.ampdoc.getRootNode().removeEventListener(
'click', this.boundHandler_, true);
}

/**
Expand All @@ -153,6 +134,7 @@ export class CaptureClickHandler {
}
}


/**
* Locate first element with given tag name within event path from shadowRoot.
* @param {!Event} e
Expand All @@ -171,6 +153,7 @@ export function getElementByTagNameFromEventShadowDomPath_(e, tagName) {
return null;
}


/**
* Expands target anchor href on capture click event. If within shadow DOM,
* will offset from host element.
Expand All @@ -191,6 +174,7 @@ export function onDocumentElementCapturedClick_(e, urlReplacements) {
}
}


/**
* Intercept any click on the current document and prevent any
* linking to an identifier from pushing into the history stack.
Expand All @@ -199,11 +183,13 @@ export function onDocumentElementCapturedClick_(e, urlReplacements) {
* on iOS Safari.
*
* @param {!Event} e
* @param {!./service/ampdoc-impl.AmpDoc} ampdoc
* @param {!./service/viewport-impl.Viewport} viewport
* @param {!./service/history-impl.History} history
* @param {boolean} isIosSafari
*/
export function onDocumentElementClick_(e, viewport, history, isIosSafari) {
export function onDocumentElementClick_(
e, ampdoc, viewport, history, isIosSafari) {
if (e.defaultPrevented) {
return;
}
Expand All @@ -213,10 +199,7 @@ export function onDocumentElementClick_(e, viewport, history, isIosSafari) {
return;
}

const docElement = e.currentTarget;
const doc = docElement.ownerDocument;
const win = doc.defaultView;

const win = ampdoc.win;
const tgtLoc = parseUrl(target.href);

// On Safari iOS, custom protocol links will fail to open apps when the
Expand Down Expand Up @@ -267,11 +250,11 @@ export function onDocumentElementClick_(e, viewport, history, isIosSafari) {
const hash = tgtLoc.hash.slice(1);
let elem = null;
if (hash) {
elem = doc.getElementById(hash);
elem = ampdoc.getRootNode().getElementById(hash);
if (!elem) {
// Fallback to anchor[name] if element with id is not found.
// Linking to an anchor element with name is obsolete in html5.
elem = doc.querySelector(`a[name=${hash}]`);
elem = ampdoc.getRootNode().querySelector(`a[name=${hash}]`);
}
}

Expand All @@ -295,7 +278,8 @@ export function onDocumentElementClick_(e, viewport, history, isIosSafari) {
history.push(() => {
win.location.replace(`${curLoc.hash || '#'}`);
});
};
}


/**
* Get offset location of click from event taking into account shadowRoot.
Expand All @@ -318,6 +302,7 @@ function getClickLocation_(e) {
};
}


/**
* Expand click target href synchronously using UrlReplacements service
* including CLICK_X/CLICK_Y page offsets (if within shadowRoot will reference
Expand Down Expand Up @@ -353,4 +338,4 @@ export function expandTargetHref_(e, target, urlReplacements) {
target.setAttribute('href', newHref);
}
return newHref;
};
}
Loading

0 comments on commit f2e39be

Please sign in to comment.