提交 ebc96835 编写于 作者: K Kamran Ahmed

Refactor and animation fixes

上级 f6384059
......@@ -14,10 +14,10 @@ img.emoji {
background: white;
padding: 10px 30px;
border-radius: 5px;
color: #333333;
color: #1f1f1f;
a, a:visited, a:focus {
color: #333333;
color: #1f1f1f;
text-decoration: underline;
}
......
......@@ -11,17 +11,27 @@ export default class Element {
* @param {Node|HTMLElement} node
* @param {Object} options
* @param {Popover} popover
* @param {Stage} stage
* @param {Overlay} overlay
* @param {Window} window
* @param {Document} document
*/
constructor(node, options, popover, overlay, window, document) {
constructor({
node,
options,
popover,
stage,
overlay,
window,
document,
} = {}) {
this.node = node;
this.document = document;
this.window = window;
this.options = options;
this.overlay = overlay;
this.popover = popover;
this.stage = stage;
this.animationTimeout = null;
......@@ -139,9 +149,13 @@ export default class Element {
* Is called when element is about to be deselected
* i.e. when moving the focus to next element of closing
*/
onDeselected() {
onDeselected(hideStage = false) {
this.hidePopover();
if (hideStage) {
this.hideStage();
}
this.node.classList.remove(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
// If there was any animation in progress, cancel that
......@@ -154,6 +168,19 @@ export default class Element {
}
}
/**
* Checks if the given element is same as the current element
* @param {Element} element
* @returns {boolean}
*/
isSame(element) {
if (!element || !element.node) {
return false;
}
return element.node === this.node;
}
/**
* Is called when the element is about to be highlighted
* i.e. either if overlay has started moving the highlight towards
......@@ -174,29 +201,21 @@ export default class Element {
*/
onHighlighted() {
this.showPopover();
this.showStage();
this.node.classList.add(CLASS_DRIVER_HIGHLIGHTED_ELEMENT);
this.highlightFinished = true;
const highlightedElement = this;
const highlightedNode = this.node;
const popoverElement = this.popover;
const lastHighlightedElement = this.overlay.getLastHighlightedElement();
const lastHighlightedNode = lastHighlightedElement && lastHighlightedElement.node;
// If this element is not already highlighted (because this call could
// be from the resize or scroll) and is not in view
if (highlightedNode !== lastHighlightedNode) {
const popoverElement = this.popover;
if (popoverElement && !popoverElement.isInView()) {
popoverElement.bringInView();
}
if (popoverElement && !popoverElement.isInView()) {
popoverElement.bringInView();
}
if (!highlightedElement.isInView()) {
highlightedElement.bringInView();
}
if (!highlightedElement.isInView()) {
highlightedElement.bringInView();
}
if (this.options.onHighlighted) {
......@@ -204,6 +223,13 @@ export default class Element {
}
}
/**
* Shows the stage behind the element
*/
showStage() {
this.stage.show(this.getCalculatedPosition());
}
/**
* Gets the DOM Element behind this element
* @returns {Node|HTMLElement|*}
......@@ -212,6 +238,10 @@ export default class Element {
return this.node;
}
hideStage() {
this.stage.hide();
}
hidePopover() {
if (!this.popover) {
return;
......
......@@ -10,10 +10,9 @@ export default class Overlay {
/**
* @param {Object} options
* @param {Window} window
* @param {Stage} stage
* @param {Document} document
*/
constructor(options, stage, window, document) {
constructor(options, window, document) {
this.options = options;
this.positionToHighlight = new Position({}); // position at which layover is to be patched at
......@@ -23,7 +22,6 @@ export default class Overlay {
this.window = window;
this.document = document;
this.stage = stage;
this.makeNode();
}
......@@ -52,6 +50,11 @@ export default class Overlay {
return;
}
// If highlighted element is not changed from last time
if (this.highlightedElement && this.highlightedElement.isSame(this.lastHighlightedElement)) {
return;
}
// There might be hide timer from last time
// which might be getting triggered
this.window.clearTimeout(this.hideTimer);
......@@ -60,7 +63,7 @@ export default class Overlay {
element.onHighlightStarted();
// Old element has been deselected
if (this.highlightedElement) {
if (this.highlightedElement && !this.highlightedElement.isSame(this.lastHighlightedElement)) {
this.highlightedElement.onDeselected();
}
......@@ -76,9 +79,6 @@ export default class Overlay {
this.showOverlay();
// Show the stage
this.stage.show(this.positionToHighlight);
// Element has been highlighted
this.highlightedElement.onHighlighted();
}
......@@ -126,14 +126,13 @@ export default class Overlay {
clear() {
this.positionToHighlight = new Position();
if (this.highlightedElement) {
this.highlightedElement.onDeselected();
this.highlightedElement.onDeselected(true);
}
this.highlightedElement = null;
this.lastHighlightedElement = null;
this.hideOverlay();
this.stage.hide();
}
/**
......@@ -141,12 +140,13 @@ export default class Overlay {
* And moves the highlight around if necessary
*/
refresh() {
// If the highlighted element was there Cancel the
// existing animation frame if any and highlight it again
// as its position might have been changed
if (this.highlightedElement) {
this.highlight(this.highlightedElement);
this.highlightedElement.onHighlighted();
// If no highlighted element, cancel the refresh
if (!this.highlightedElement) {
return;
}
// Reposition the stage and show popover
this.highlightedElement.showPopover();
this.highlightedElement.showStage();
}
}
......@@ -46,7 +46,7 @@ export default class Stage extends Element {
/**
* Makes it visible and sets the default properties
*/
reset() {
setInitialStyle() {
this.node.style.display = 'block';
this.node.style.left = '0';
this.node.style.top = '0';
......@@ -55,7 +55,7 @@ export default class Stage extends Element {
}
show(position) {
this.reset();
this.setInitialStyle();
// Make it two times the padding because, half will be given on left and half on right
const requiredPadding = this.options.padding * 2;
......
......@@ -43,8 +43,7 @@ export default class Driver {
this.steps = []; // steps to be presented if any
this.currentStep = 0; // index for the currently highlighted step
const stage = new Stage(this.options, window, document);
this.overlay = new Overlay(this.options, stage, window, document);
this.overlay = new Overlay(this.options, window, document);
this.onResize = this.onResize.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
......@@ -70,8 +69,7 @@ export default class Driver {
* @param e
*/
onClick(e) {
if (!this.hasHighlightedElement() || !this.isActivated) {
// Has no highlighted element so ignore the click
if (!this.isActivated || !this.hasHighlightedElement()) {
return;
}
......@@ -188,7 +186,7 @@ export default class Driver {
}
// Refresh with animation
this.overlay.refresh(true);
this.overlay.refresh();
}
/**
......@@ -278,7 +276,17 @@ export default class Driver {
popover = new Popover(popoverOptions, this.window, this.document);
}
return new Element(domElement, elementOptions, popover, this.overlay, this.window, this.document);
const stage = new Stage(this.options, this.window, this.document);
return new Element({
node: domElement,
options: elementOptions,
popover,
stage,
overlay: this.overlay,
window: this.window,
document: this.document,
});
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册