Skip to content

Commit

Permalink
#188 additional cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Mrowetz committed May 4, 2017
1 parent 76488e2 commit bdb9510
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 185 deletions.
30 changes: 15 additions & 15 deletions src/ts/helpers/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ export function removeClass<T extends Element>(el: T, className: string): T {
return el;
}

/**
* Helper to recursively find parent with the `className` class
* @param base `Element` to start from
* @param className class that the parent should have
*/
export function getParentByClassName(base: Element, className: string) {
if (base.parentElement === undefined) {
return undefined;
}
if (base.parentElement.classList.contains(className)) {
return base.parentElement;
}
return getParentByClassName(base.parentElement, className);
};

/**
* Removes all child DOM nodes from `el`
* @param {Element} el
Expand Down Expand Up @@ -66,18 +81,3 @@ export function forEachNodeList<T extends Node>(list: NodeListOf<T>, fn: {(el: T
fn(list.item(i), i);
}
}

/**
* Helper to recousivly find parent with `className`
* @param base `Element` to start from
* @param className class that the parent should have
*/
export function findParentByClassName(base: Element, className: string) {
if (base.parentElement === undefined) {
return undefined;
}
if (base.parentElement.classList.contains(className)) {
return base.parentElement;
}
return findParentByClassName(base.parentElement, className);
};
2 changes: 0 additions & 2 deletions src/ts/helpers/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ export function findIndex<T>(arr: T[], predicate: {(el: T, index: number): Boole
}
i++;
}

// 7. Return undefined.
return undefined;
}

Expand Down
58 changes: 51 additions & 7 deletions src/ts/waterfall/details-overlay/overlay-manager.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,55 @@
import { forEachNodeList, removeChildren } from "../../helpers/dom";
import { find } from "../../helpers/misc";
import {
forEachNodeList,
getLastItemOfNodeList,
getParentByClassName,
removeChildren,
} from "../../helpers/dom";
import {
find,
isTabDown,
isTabUp,
} from "../../helpers/misc";
import { Context, OverlayManagerClass } from "../../typing/context";
import { OpenOverlay, OverlayChangeEvent } from "../../typing/open-overlay";
import { WaterfallEntry } from "../../typing/waterfall";
import { createRowInfoOverlay } from "./svg-details-overlay";

/** Overlay (popup) instance manager */
class OverlayManager implements OverlayManagerClass {
private static showFullName = (el: Element) => {
el.getElementsByClassName("row-fixed").item(0)
.dispatchEvent(new MouseEvent("mouseenter"));
}
/**
* Keypress Event handler for fist el in Overlay,
* to manage highlighting of the element above
*/
private static firstElKeypress = (evt: KeyboardEvent) => {
if (isTabUp(evt)) {
const par = getParentByClassName(evt.target as Element, "row-overlay-holder") as SVGGElement;
if (par && par.previousElementSibling) {
OverlayManager.showFullName(par.previousElementSibling);
}
}
}

/**
* Keypress Event handler for last el in Overlay,
* to manage highlighting of the element below
*/
private static lastElKeypress = (evt: KeyboardEvent) => {
if (isTabDown(evt)) {
const par = getParentByClassName(evt.target as Element, "row-overlay-holder") as SVGGElement;
if (par && par.nextElementSibling) {
OverlayManager.showFullName(par.nextElementSibling);
}
}
}

/** Collection of currely open overlays */
private openOverlays: OpenOverlay[] = [];

constructor(private context: Context, private rowHolder: SVGGElement) {

}

/** all open overlays height combined */
Expand Down Expand Up @@ -138,10 +176,8 @@ class OverlayManager implements OverlayManagerClass {
* @param {SVGGElement} overlayHolder
*/
private renderOverlays(detailsHeight: number) {
// removeChildren(this.rowHolder);

/** shared variable to keep track of heigth */
let currY = 0;

let updateHeight = (overlay, y, currHeight) => {
currY += currHeight;
overlay.actualY = y;
Expand All @@ -156,17 +192,25 @@ class OverlayManager implements OverlayManagerClass {
if (previewImg && !previewImg.src) {
previewImg.setAttribute("src", previewImg.attributes.getNamedItem("data-src").value);
}
infoOverlay.querySelector("a")
.addEventListener("keydown", OverlayManager.firstElKeypress);
getLastItemOfNodeList(infoOverlay.querySelectorAll("button"))
.addEventListener("keydown", OverlayManager.lastElKeypress);
overlayHolder.appendChild(infoOverlay);
updateHeight(overlay, y, infoOverlay.getBoundingClientRect().height);
};

const rowItems = this.rowHolder.getElementsByClassName("row-item") as NodeListOf<SVGAElement>;
forEachNodeList(rowItems, (rowItem, index) => {
const overlay = find(this.openOverlays, (o) => o.index === index);
let overlayEl = rowItem.nextElementSibling.firstElementChild as SVGGElement;
const overlayEl = rowItem.nextElementSibling.firstElementChild as SVGGElement;
if (overlay === undefined) {
if (overlayEl) {
// remove closed overlay
rowItem.nextElementSibling.querySelector("a")
.removeEventListener("keydown", OverlayManager.firstElKeypress);
getLastItemOfNodeList(rowItem.nextElementSibling.querySelectorAll("button"))
.removeEventListener("keydown", OverlayManager.lastElKeypress);
removeChildren(rowItem.nextElementSibling);
}
return; // not open
Expand Down
169 changes: 8 additions & 161 deletions src/ts/waterfall/row/svg-row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
} from "../../helpers/misc";
import * as svg from "../../helpers/svg";
import { Context } from "../../typing/context";
import { OpenOverlay } from "../../typing/open-overlay";
import { RectData } from "../../typing/rect-data";
import { WaterfallEntry } from "../../typing/waterfall";
import { getIndicatorIcons } from "./svg-indicators";
Expand Down Expand Up @@ -80,196 +79,44 @@ export function createRow(context: Context, index: number,

rowSubComponents.appendRequestLabels(rowName, requestNumberLabel, shortLabel, fullLabel);

// const onOpenOverlayFocusOut = (evt: KeyboardEvent) => {
// if (evt.which !== 9) {
// return; // only handle tabs
// }
// const isUpward = evt.shiftKey;
// console.log("onActiveFocusOut", isUpward);
// };

// accordeon a11y guide
// https://www.w3.org/TR/wai-aria-practices-1.1/#accordion
context.pubSub.subscribeToSpecificOverlayChanges(index, (change) => {
openOverlay = (change.type === "open") ? change.changedOverlay : undefined;
hasOpenOverlay = (change.type === "open");
});
if (index > 0) {
context.pubSub.subscribeToSpecificOverlayChanges(index - 1, (change) => {
prevOpenOverlay = (change.type === "open") ? change.changedOverlay : undefined;
hasPrevOpenOverlay = (change.type === "open");
});
}

let isPoinerClick = false;
let openOverlay: OpenOverlay;
/** Poiter to the previous open Oberlay (if exist) */
let prevOpenOverlay: OpenOverlay;
// let showDetailsTimeout: number;



// const enterOverlaySetup = (isDownwards: boolean, openOverlay: OpenOverlay) => {
// const overlayEl = context.overlayManager.getOpenOverlayDomEl(openOverlay);
// /** Top header el */
// const firstFocusEl = overlayEl.getElementsByTagName("a")[0];
// /** All focusable elements */
// const allFocusEl = overlayEl.querySelectorAll(":scope a, :scope button");
// const lastTab = getLastItemOfNodeList(allFocusEl);
// for (let i = allFocusEl.length - 1; i <= 0 i--) {
// const el = allFocusEl.item(i);
// el.setAttribute("tabindex", "0");
// }
// console.log(allFocusEl)

// const onOverlayExit = () => {
// console.log("Implement me");
// for (let i = allFocusEl.length - 1; i <= 0 i--) {
// const el = allFocusEl.item(i);
// el.setAttribute("tabindex", "-1");
// }
// lastTab.removeEventListener("keypress", onLastElKeypress);
// };

// const onLastElKeypress = (evt: KeyboardEvent) => {
// if (isTabDown(evt)) {
// evt.preventDefault();
// onOverlayExit();
// }
// };
// lastTab.addEventListener("keypress", onLastElKeypress)
// firstFocusEl.focus();
// };
let hasOpenOverlay: boolean;
let hasPrevOpenOverlay: boolean;




// triggered before click by touch and mouse devices
rowItem.addEventListener("mouseup", () => {
isPoinerClick = true;
});
rowItem.addEventListener("click", (evt: MouseEvent) => {
isPoinerClick = false;
onDetailsOverlayShow(evt);
});
rowItem.addEventListener("keydown", (evt: KeyboardEvent) => {
// on enter
if (evt.which === 32) {
evt.preventDefault();
onDetailsOverlayShow(evt);
return;
return onDetailsOverlayShow(evt);
}

// // moving down into overlay
// if (isTabDown(evt) && openOverlay) {
// console.log("moving down into overlay");
// evt.preventDefault();
// const overlayEl = context.overlayManager.getOpenOverlayDomEl(openOverlay);
// /** Top header el */
// const firstFocusEl = overlayEl.getElementsByTagName("a")[0];
// const lastTab = getLastItemOfNodeList(overlayEl.getElementsByClassName("tab-button") as
// NodeListOf<HTMLButtonElement>);

// // Move out up the the top, to the node el
// firstFocusEl.addEventListener("keydown", (inOverlayEvt: KeyboardEvent) => {
// // IE & Edge do not support `focus()` in SVG
// if (isTabUp(inOverlayEvt) && typeof (rowItem as any).focus === "function") {
// console.log("Move out up the the top, to the node el");
// inOverlayEvt.preventDefault();
// console.log("rowItem in `nextFocusEl.on keydown with tab+shift`", rowItem);
// (rowItem as any).focus();
// }
// });

// console.log("lastTab", lastTab);
// // Move out down at the end
// lastTab.addEventListener("keydown", (inOverlayEvt: KeyboardEvent) => {
// // IE & Edge do not support `focus()` in SVG
// if (isTabDown(inOverlayEvt) && typeof (rowItem as any).focus === "function") {
// console.log("Move out down at the end");
// if (rowItem.nextSibling) {
// inOverlayEvt.preventDefault();
// // not last in chart
// (rowItem.nextSibling as any).focus();
// } else {
// //last in chart
// console.log("last in chart")
// inOverlayEvt.preventDefault();
// }
// } else if (isTabDown(inOverlayEvt)) {
// console.log(">>>");
// }
// });
// firstFocusEl.focus();
// return;
// // evt.cancelBubble = true;
// }

// // moving up into overlay
// if (isTabUp(evt) && prevOpenOverlay) {
// console.log("moving up into overlay");
// evt.preventDefault();
// const prevOverlayEl = context.overlayManager.getOpenOverlayDomEl(prevOpenOverlay);
// const lastTab = getLastItemOfNodeList(prevOverlayEl.getElementsByClassName("tab-button") as
// NodeListOf<HTMLButtonElement>);
// lastTab.focus();
// return;
// }

// // tab without open overlays around
if (isTabUp(evt) && !prevOpenOverlay && index > 0) {
// tab without open overlays around
if (isTabUp(evt) && !hasPrevOpenOverlay && index > 0) {
rowItem.previousSibling.previousSibling.lastChild.lastChild.dispatchEvent(new MouseEvent("mouseenter"));
return;
}
if (isTabDown(evt) && !openOverlay) {
if (isTabDown(evt) && !hasOpenOverlay) {
if (rowItem.nextSibling && rowItem.nextSibling.nextSibling) {
rowItem.nextSibling.nextSibling.lastChild.lastChild.dispatchEvent(new MouseEvent("mouseenter"));
}
// else {
// console.log("Sort this out > tab without open overlays around");
// if (context.overlayManager.hasOpenOverlays()) {
// const lastTab = getLastItemOfNodeList(context.overlayManager.getLastOpenOverlayDomEl()
// .getElementsByClassName("tab-button") as NodeListOf<HTMLButtonElement>);
// console.log("END", lastTab);
// lastTab.focus();
// }
// // prev
// // do not prevent default, so the focus moves on
// }
return;
}
// // Not handled
// if (evt.which === 9) {
// console.log("go to next/prev thing");
// }
});

// rowItem.addEventListener("keyup", (evt: KeyboardEvent) => {
// if (evt.which === 9) {
// //document.activeElement === rowItem
// console.log("keydown");
// rowName.dispatchEvent(new MouseEvent("mouseenter"));
// window["eventsStore"]["key"].push(evt);
// }
// });


// rowItem.addEventListener("focusin", (evt: FocusEvent) => {
// console.log("in", isPoinerClick);
// // const test = new MouseEvent("mouseenter");
// rowName.dispatchEvent(new MouseEvent("mouseenter"));
// window["eventsStore"]["mouse"].push(evt);
// });


rowItem.addEventListener("focusout", () => {
rowName.dispatchEvent(new MouseEvent("mouseleave"));
});

// rowItem.addEventListener("click", (evt) => {
// console.log("click", evt);
// onDetailsOverlayShow(evt);
// });


flexScaleHolder.appendChild(rowBar);
leftFixedHolder.appendChild(clipPathElProto.cloneNode(true));
leftFixedHolder.appendChild(rowName);
Expand Down

0 comments on commit bdb9510

Please sign in to comment.