Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cancel drag when no visibility #83 #396

Merged
merged 13 commits into from
Apr 11, 2018

Conversation

grady-lad
Copy link
Contributor

Fixes #83

Quick Demo

canceldemo

};

export default (cancel: Function = () => {}) : EventBinding => {
if (typeof window !== 'undefined') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When can this function be called when window is not around?

Copy link
Contributor Author

@grady-lad grady-lad Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the integration tests for SSR
Within test/unit/integration/server-side-rendering.spec.js the following tests fail

  • should render identical content when resetting context between renders
  • should support rendering to static markup
  • should support rendering to a string


const getVisibiltyEvent = () : ?{hidden:string, name:string} => {
const prefixes = ['ms', 'webkit', 'moz', 'o'];
let browserPrefix;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just use a find here (we are already using .find around the place). Also, I think we should check for the default first:

// using memoizeOne so that we do not recompute this function after initial computation
const getVisibilityEvent = memoizeOne() : ?Pair => {
 // non prefixed event is supported
 if('hidden' in document) {
   return {
    hidden: 'hidden',
    name: 'visibilitychange',
  }

  const prefix: ?string = ['ms', 'webkit', 'moz', 'o'].find((prefix: string): boolean => `${prefix}Hidden` in document);

   if(!prefix) {
      return null;
   }

   return {
     hidden: `${prefix}Hidden`,
     name: `${prefix}visibilitychange`,
   }
 }
})

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const defaultPair: Pair = {
    hidden: 'hidden',
    name: 'visibilitychange',
  }

// using memoizeOne so that we do not recompute this function after initial computation
const getVisibilityEvent = memoizeOne() : ?Pair => {
 // non prefixed event is supported
 if('hidden' in document) {
   return defaultPair;

  const prefix: ?string = ['ms', 'webkit', 'moz', 'o'].find((prefix: string): boolean => `${prefix}Hidden` in document);

   // if no prefixed event is supported - simply return the defaultPair. It will not cause any errors to bind to this event - it just won't do anything on visibility change
   if(!prefix) {
      return defaultPair;
   }

   return {
     hidden: `${prefix}Hidden`,
     name: `${prefix}visibilitychange`,
   }
 }
})

@@ -922,6 +922,23 @@ describe('drag handle', () => {
expect(event.defaultPrevented).toBe(false);
});

it('should cancel when the window is not visibile', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this test please be moved to the shared 'control' section at the bottom so that each sensor type can be tested against this functionality?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing, Which section? Is it the interactive elements section?

test/setup.js Outdated
@@ -22,8 +22,10 @@ if (typeof window !== 'undefined') {
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
document.documentElement.clientWidth = window.innerWidth;
document.documentElement.clientHeight = window.innerHeight;
// So that we can test window visibility within tests.
document.webkitvisibilitychange = () => {};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that we check 'hidden' first we should move to the non prefixed one

test/setup.js Outdated
@@ -22,8 +22,10 @@ if (typeof window !== 'undefined') {
if (typeof document !== 'undefined' && typeof window !== 'undefined') {
document.documentElement.clientWidth = window.innerWidth;
document.documentElement.clientHeight = window.innerHeight;
// So that we can test window visibility within tests.
document.webkitvisibilitychange = () => {};
document.webkitHidden = true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to have the default has

document.hidden = false;

rather than 'true'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexreardon I am a little stuck about mocking the visibility event for the unit tests.

The document object that is used for the unit tests has a property hidden but no visibilitychange function. So within test/setup.js I added the visibilitychange function to the document object and within that function tried set document.hidden = true.

I presumed that would mock the window being hidden but the function does not get called.

So I am wondering does anyone have any suggestions how to mock this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can trigger your own events manually. See user-input-util

export const dispatchWindowEvent = (eventName: string, options?: Object = {}): Event => {
  const event: Event = document.createEvent('Event');
  event.initEvent(eventName, true, true);

  // override properties on the event itself
  Object.assign(event, options);

  window.dispatchEvent(event);

  return event;
};

@alexreardon
Copy link
Collaborator

Thanks for getting into this @grady-lad !!!

@alexreardon
Copy link
Collaborator

This is looking good

@alexreardon
Copy link
Collaborator

However, it looks like a test is failing in CI. Did you need some help with it?

@grady-lad
Copy link
Contributor Author

Hey @alexreardon I just noticed.
Yeah that would be great! I am pretty new to flow and haven't seemed to figure out the error.

@alexreardon
Copy link
Collaborator

I will try to take a look early next week. Happy easter!

@alexreardon
Copy link
Collaborator

Sorry for the delay on this one. We got totally blindsided by #413. Once things settle a bit I will take another look at this

@grady-lad
Copy link
Contributor Author

@alexreardon no problems, take your time.

@alexreardon
Copy link
Collaborator

I have updated the PR @grady-lad

@grady-lad
Copy link
Contributor Author

Hey @alexreardon I just seen that changes, thanks for the help 😄. Do you need anything else from my side to close this out?

@@ -222,6 +223,11 @@ export default ({
eventName: 'scroll',
fn: callbacks.onWindowScroll,
},
// Cancel on page visibility change
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to simply the solution.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not need to know what the visibility of the page is when the even fires - we simply need to know if the event fires. If it fires while a drag is occurring we can kill the drag

@alexreardon alexreardon merged commit 5d56d2b into atlassian:master Apr 11, 2018
@alexreardon
Copy link
Collaborator

Thanks for your patience @grady-lad! Well done on your first contribution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants