mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
If an element isContentEditable, do not ignoreScrollStart incase users are using contenteditable elements to scroll. This may have originally been put in because it disabled text selection, and moving the text cursor on touch. But this doesn’t seem to be the case anymore, so it may have been put in for platform versions we no longer support. Also fix the data-prevent-scroll dataset attribute. Closes #2091
1384 lines
47 KiB
JavaScript
1384 lines
47 KiB
JavaScript
|
|
/*
|
|
|
|
Physical Device Testing Scenarios
|
|
---------------------------------
|
|
- Keyboard should show up when tapping on a text input
|
|
- Keyboard should show up when tapping on a label which surrounds a text input
|
|
- Keyboard should stay up if focused text input is tapped again
|
|
- Keyboard should go away when text input is focused, then tapped outside of input
|
|
- Keyboard should hide when tapping the virtual keyboard's "Done" or down arrow, but tapping
|
|
- Should be able to move an inputs text caret when its focused
|
|
- Should be able to move an inputs text caret when its focused, and is wrapped with a label
|
|
the input again will bring up the keyboard again
|
|
- Options dialog should show when tapping on a select
|
|
- Options dialog should show when tapping on a label which surrounds a select (not working in Android 2.3)
|
|
- Tapping a button element should fire one click
|
|
- Tapping an anchor element should fire one click
|
|
- Tapping a checkbox should fire one click
|
|
- Tapping a label which surrounds a checkbox should fire one click
|
|
- Tapping a radio button should fire one click
|
|
- Tapping a label which surrounds a radio button should fire one click
|
|
- Moving an input[range] slider should work
|
|
- Moving an input[range] slider when its in menu content of a should work
|
|
- Tapping the track on an input[range] slider should move the knob to that location (not a default in iOS)
|
|
- Tapping an input[file] should bring up the file dialog
|
|
- After tapping an input[file] and closing the input file dialog, tap a different
|
|
element and the file dialog should NOT show up
|
|
- Element which is disabled should not be clicked
|
|
- Holding a touchstart, and not moving, should fire the click no matter how long the hold
|
|
- Holding a mousedown, and not moving, should fire the click no matter how long the hold
|
|
- Holding touchstart, then moving a few pixels cancels the click
|
|
- Holding mousedown, then moving a few pixels cancels the click
|
|
- Touchstart should set and remove the activated css class
|
|
- Mousedown should set and remove the activated css class
|
|
- Holding touchstart, then moving a few pixels removes the activated css class
|
|
- Holding mousedown, then moving a few pixels removes the activated css class
|
|
- An element or one of its parents with data-tap-disabled attribute should still click, but w/ a delay
|
|
- ALL THE ABOVE, BUT NOW WITH NG-CLICK ON THE INPUT!
|
|
- Tapping a div with an click event added should fire one click
|
|
- Tapping an img with an click event added should fire one click
|
|
- Can scroll when target is a text input, but it does not have focus
|
|
- Can scroll when the target is a text input and it already has focus
|
|
- Can hold a text input and move its text caret/cursor
|
|
- Can scroll when the target is a label
|
|
- Does not change focus 300ms after when tapping an input and the keyboard shows up
|
|
- The blinking cursor says in the input 300ms after the tap
|
|
- Can hit the keyboard's "next" button to change focus to the next input
|
|
- When flicking down a page, and a target was an input, it shouldn't focus and jank scrolling
|
|
- Do not show text caret of a focused input while scrolling, no matter what the target is
|
|
- After scrolling has come to a halt, previously focused input should be focused again
|
|
- Keyboard should stay up while scrolling if an input was focused
|
|
- Keyboard should not go away after scrolling stops and it focuses back on the previous focused input
|
|
- Should not create clones for tap inputs to hide cursor, like for checkboxes, radio, range, select
|
|
- Focus on an input, flick up, let go, and during animation flick down, and clone should go away
|
|
- While inputs are actively scrolling you should not be able to change focus
|
|
- If you touchstart on a text input, then scrolland touchend, it should not bring up the keyboard
|
|
- If you touchstart on a label wrapping a text input, then scroll and touchend, it should not bring up the keyboard
|
|
- When focused in a text input, be able to get out when tapping a checkbox
|
|
- Can scroll when the target is a select element (touch events only)
|
|
- Can scroll when the target is a label which wraps select element
|
|
- Can open the select options on touch when not scrolling
|
|
- Can open the select options mouse click when target is a select
|
|
- Can open the select options when target is a label wrapping a select
|
|
|
|
Tested on:
|
|
----------------------------
|
|
- iOS 6.1 iPad 3
|
|
- iOS 7.0 iPhone 4
|
|
- iOS 7.0 iPhone 5
|
|
- iOS 7.1 iPhone 5
|
|
- iOS 7.1 Simulator
|
|
- Android 2.3 HTC Incredible
|
|
- Android 2.3 Samsung Galaxy S
|
|
- Android 4.0 HTC Incredible
|
|
- Android 4.2 Nexus 4
|
|
- Android 4.3 Samsung S3
|
|
- Android 4.4 Motorola Moto G
|
|
- Android 4.4 Nexus 5
|
|
- OSX Chrome
|
|
- OSX Chrome (emulated touch screen)
|
|
- OSX Firefox
|
|
|
|
*/
|
|
|
|
window.console.log = function(){};
|
|
|
|
describe('Ionic Tap', function() {
|
|
var deregisterTap;
|
|
|
|
beforeEach(function() {
|
|
window._setTimeout = window.setTimeout;
|
|
window.setTimeout = function(){};
|
|
_activeElement = null; // the element which has focus
|
|
|
|
deregisterTap = ionic.tap.register(document.createElement('div'));
|
|
ionic.scroll = { isScrolling: false };
|
|
});
|
|
|
|
afterEach(function(){
|
|
window.setTimeout = window._setTimeout;
|
|
deregisterTap();
|
|
});
|
|
|
|
it('Should trigger a labels child inputs click, and should not stop the labels end event so Android allows text editing', function() {
|
|
var e = {
|
|
type: 'touchstart',
|
|
target: {
|
|
tagName: 'LABEL',
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; },
|
|
control: {
|
|
tagName: 'INPUT',
|
|
dispatchEvent: function() { e.target.control.dispatchedEvent = true; },
|
|
focus: function() { e.target.control.focused = true; }
|
|
}
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
tapClick(e);
|
|
|
|
expect( e.target.dispatchedEvent ).toBeUndefined();
|
|
expect( e.target.focused ).toBeUndefined();
|
|
|
|
expect( e.target.control.dispatchedEvent ).toBeDefined();
|
|
expect( e.target.control.focused ).toBeDefined();
|
|
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should trigger a click for an element w/out a wrapping label', function() {
|
|
var e = {
|
|
type: 'touchstart',
|
|
target: {
|
|
tagName: 'INPUT',
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; }
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
tapClick(e);
|
|
|
|
expect( e.target.dispatchedEvent ).toBeDefined();
|
|
expect( e.target.focused ).toBeDefined();
|
|
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
|
|
});
|
|
|
|
it('Should not trigger a click if tapPointerMoved has moved', function() {
|
|
var e = {
|
|
type: 'touchstart',
|
|
target: {
|
|
tagName: 'INPUT',
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; }
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
tapPointerMoved = true;
|
|
expect( tapClick(e) ).toEqual(false);
|
|
|
|
});
|
|
|
|
it('Should trigger click on mouseup and when nearby mousedown happened', function() {
|
|
var e = {
|
|
type: 'mousedown',
|
|
clientX: 100, clientY: 100,
|
|
target: {
|
|
tagName: 'INPUT',
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; },
|
|
classList: { contains: function(){} }
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
expect( e.target.dispatchedEvent ).toBeUndefined();
|
|
|
|
tapMouseDown({clientX: 101, clientY: 101});
|
|
tapMouseUp(e);
|
|
|
|
expect( e.target.dispatchedEvent ).toBeDefined();
|
|
});
|
|
|
|
it('Should not trigger click on mouseup because mousedown coordinates too far away', function() {
|
|
var e = {
|
|
clientX: 100, clientY: 100,
|
|
target: {
|
|
tagName: 'INPUT',
|
|
nodeType: 1,
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; },
|
|
classList: { contains: function(){} }
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
expect( e.target.dispatchedEvent ).toBeUndefined();
|
|
|
|
tapMouseDown({clientX: 201, clientY: 101});
|
|
tapMouseUp(e);
|
|
|
|
expect( e.target.dispatchedEvent ).toBeUndefined();
|
|
});
|
|
|
|
it('Should set tapHasPointerMoved=false on tapTouchStart', function() {
|
|
tapPointerMoved = null;
|
|
tapTouchStart({ preventDefault:function(){} });
|
|
expect( tapPointerMoved ).toEqual(false);
|
|
});
|
|
|
|
it('Should not preventDefault on text input that already has focus and is iOS', function() {
|
|
// prevent the default so iOS doesn't auto scroll to the input
|
|
ionic.Platform.setPlatform('ios');
|
|
var label = document.createElement('label');
|
|
var textarea = document.createElement('textarea');
|
|
label.appendChild(textarea);
|
|
var e = {
|
|
target: label,
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
tapActiveEle = textarea;
|
|
|
|
tapTouchStart(e);
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should preventDefault on text input that does not have focus and is iOS', function() {
|
|
// prevent the default so iOS doesn't auto scroll to the input
|
|
ionic.Platform.setPlatform('ios');
|
|
var label = document.createElement('label');
|
|
var textarea = document.createElement('textarea');
|
|
label.appendChild(textarea);
|
|
var e = {
|
|
target: label,
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
tapTouchStart(e);
|
|
expect( e.preventedDefault ).toEqual(true);
|
|
});
|
|
|
|
it('Should not preventDefault on text input target thats not iOS', function() {
|
|
// do not prevent default on touchend of a text input or else you cannot move the text caret
|
|
ionic.Platform.setPlatform('android');
|
|
var label = document.createElement('label');
|
|
var textarea = document.createElement('textarea');
|
|
label.appendChild(textarea);
|
|
var e = {
|
|
target: label,
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
tapTouchStart(e);
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should set tapPointerMoved=false on tapTouchCancel', function() {
|
|
tapPointerMoved = true;
|
|
tapTouchCancel();
|
|
expect( tapPointerMoved ).toEqual(false);
|
|
});
|
|
|
|
it('Should set tapHasPointerMoved=true on tapTouchMove', function() {
|
|
tapPointerMoved = null;
|
|
tapTouchStart({ clientX: 100, clientY: 100, preventDefault:function(){} });
|
|
expect( tapPointerMoved ).toEqual(false);
|
|
tapTouchMove({ clientX: 200, clientY: 100, target: document.createElement('button') });
|
|
expect( tapPointerMoved ).toEqual(true);
|
|
});
|
|
|
|
it('Should set tapHasPointerMoved=false on tapMouseDown', function() {
|
|
tapPointerMoved = null;
|
|
tapMouseDown({});
|
|
expect( tapPointerMoved ).toEqual(false);
|
|
});
|
|
|
|
it('Should set tapPointerMoved=false on tapMouseUp', function() {
|
|
tapPointerMoved = true;
|
|
tapMouseUp({ target: {} });
|
|
expect( tapPointerMoved ).toEqual(false);
|
|
});
|
|
|
|
it('Should set tapHasPointerMoved=true on tapMouseMove', function() {
|
|
tapPointerMoved = null;
|
|
tapMouseDown({ clientX: 100, clientY: 100 });
|
|
expect( tapPointerMoved ).toEqual(false);
|
|
tapMouseMove({ clientX: 200, clientY: 100, target: document.createElement('button') });
|
|
expect( tapPointerMoved ).toEqual(true);
|
|
});
|
|
|
|
it('Should stop event on mouseup if touch is enabled', function() {
|
|
tapEnabledTouchEvents = true;
|
|
var e = {
|
|
stopPropagation: function() { this.stoppedPropagation = true; },
|
|
preventDefault: function() { this.preventedDefault = true; }
|
|
};
|
|
tapMouseUp(e);
|
|
expect( e.stoppedPropagation ).toEqual(true);
|
|
expect( e.preventedDefault ).toEqual(true);
|
|
});
|
|
|
|
it('Should not stop event on mouseup if the target was a select element', function() {
|
|
tapEnabledTouchEvents = false;
|
|
e = {
|
|
target: document.createElement('select'),
|
|
stopPropagation: function() { this.stoppedPropagation = true; },
|
|
preventDefault: function() { this.preventedDefault = true; }
|
|
};
|
|
expect( tapMouseUp(e) ).toBeFalsy();
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should not stop event on mouseup if the target was an option element', function() {
|
|
tapEnabledTouchEvents = false;
|
|
e = {
|
|
target: document.createElement('option'),
|
|
stopPropagation: function() { this.stoppedPropagation = true; },
|
|
preventDefault: function() { this.preventedDefault = true; }
|
|
};
|
|
expect( tapMouseUp(e) ).toEqual(false);
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should stop event on mouseup if the target was an ion-option-button element', function() {
|
|
tapEnabledTouchEvents = false;
|
|
e = {
|
|
target: document.createElement('ion-option-button'),
|
|
stopPropagation: function() { this.stoppedPropagation = true; },
|
|
preventDefault: function() { this.preventedDefault = true; }
|
|
};
|
|
expect( tapMouseUp(e) ).toBeUndefined();
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should not stop event on mouseup if touch is not enabled', function() {
|
|
tapEnabledTouchEvents = false;
|
|
e = {
|
|
target: document.createElement('button'),
|
|
stopPropagation: function() { this.stoppedPropagation = true; },
|
|
preventDefault: function() { this.preventedDefault = true; }
|
|
};
|
|
tapMouseUp(e);
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should trigger click on touchend and nearby touchstart happened', function() {
|
|
var e = {
|
|
type: 'touchend',
|
|
clientX: 101, clientY: 101,
|
|
target: {
|
|
tagName: 'INPUT',
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; },
|
|
classList: { contains:function(){}}
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
tapTouchStart({clientX: 100, clientY: 100, preventDefault:function(){}});
|
|
tapTouchEnd(e);
|
|
|
|
expect( e.target.dispatchedEvent ).toBeDefined();
|
|
});
|
|
|
|
it('Should not trigger click on touchend because touchstart coordinates too far away', function() {
|
|
var e = {
|
|
type: 'touchstart',
|
|
clientX: 100, clientY: 100,
|
|
target: {
|
|
tagName: 'INPUT',
|
|
nodeType: 1,
|
|
dispatchEvent: function() { e.target.dispatchedEvent = true; },
|
|
focus: function() { e.target.focused = true; },
|
|
classList: { contains:function(){}}
|
|
},
|
|
stopPropagation: function() { e.stoppedPropagation = true; },
|
|
preventDefault: function() { e.preventedDefault = true; }
|
|
};
|
|
|
|
expect( e.target.dispatchedEvent ).toBeUndefined();
|
|
|
|
tapTouchStart({clientX: 200, clientY: 100, preventDefault:function(){}});
|
|
|
|
tapTouchEnd(e);
|
|
|
|
expect( e.target.dispatchedEvent ).toBeUndefined();
|
|
});
|
|
|
|
it('Should tapEnabledTouchEvents because of touchstart', function() {
|
|
tapEnabledTouchEvents = false;
|
|
tapTouchStart({preventDefault:function(){}});
|
|
tapEnabledTouchEvents = true;
|
|
});
|
|
|
|
it('Should cancel click on touchcancel', function() {
|
|
tapTouchCancel();
|
|
expect(tapPointerMoved).toEqual(false);
|
|
});
|
|
|
|
it('Should cancel click when touchmove coordinates goes too far from touchstart coordinates', function() {
|
|
var e = { clientX: 100, clientY: 100, preventDefault:function(){} };
|
|
tapTouchStart(e);
|
|
|
|
expect( tapTouchMove({ clientX: 102, clientY: 100, target: document.createElement('button') }) ).toBeUndefined();
|
|
|
|
expect( tapTouchMove({ clientX: 105, clientY: 100, target: document.createElement('button') }) ).toBeUndefined();
|
|
|
|
expect( tapTouchMove({ clientX: 200, clientY: 100, target: document.createElement('button') }) ).toEqual(false);
|
|
});
|
|
|
|
it('Should cancel click when touchend coordinates are too far from touchstart coordinates', function() {
|
|
var e = {
|
|
clientX: 100, clientY: 100,
|
|
dispatchEvent: function(){ this.dispatchedEvent = true; },
|
|
preventDefault:function(){},
|
|
classList: { contains:function(){}}
|
|
};
|
|
tapTouchStart(e);
|
|
tapTouchEnd({ clientX: 200, clientY: 100, target: document.createElement('button') });
|
|
expect( e.dispatchedEvent ).toBeUndefined();
|
|
});
|
|
|
|
it('Should preventDefault on touchend when the target is a select', function() {
|
|
var e = {
|
|
target: document.createElement('select'),
|
|
clientX: 100, clientY: 100,
|
|
dispatchEvent: function(){ this.dispatchedEvent = true; },
|
|
preventDefault:function(){ this.preventedDefault = true; }
|
|
};
|
|
tapTouchEnd(e);
|
|
expect( e.preventedDefault ).toEqual(true);
|
|
|
|
e = {
|
|
target: document.createElement('div'),
|
|
clientX: 100, clientY: 100,
|
|
dispatchEvent: function(){ this.dispatchedEvent = true; },
|
|
preventDefault:function(){ this.preventedDefault = true; }
|
|
};
|
|
tapTouchEnd(e);
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should cancel click when mousemove coordinates goes too far from mousedown coordinates', function() {
|
|
var e = { clientX: 100, clientY: 100 };
|
|
tapMouseDown(e);
|
|
|
|
expect( tapMouseMove({ clientX: 102, clientY: 100, target: document.createElement('button') }) ).toBeUndefined();
|
|
|
|
expect( tapMouseMove({ clientX: 105, clientY: 100, target: document.createElement('button') }) ).toBeUndefined();
|
|
|
|
expect( tapMouseMove({ clientX: 200, clientY: 100, target: document.createElement('button') }) ).toEqual(false);
|
|
});
|
|
|
|
it('Should cancel click when mouseup coordinates are too far from mousedown coordinates', function() {
|
|
var e1 = {
|
|
target: document.createElement('button'),
|
|
clientX: 100, clientY: 100,
|
|
dispatchEvent: function(){ this.dispatchedEvent = true; }
|
|
};
|
|
tapMouseDown(e1);
|
|
|
|
var e2 = {
|
|
target: document.createElement('button'),
|
|
clientX: 100, clientY: 100,
|
|
dispatchEvent: function(){ this.dispatchedEvent = true; }
|
|
};
|
|
tapMouseUp(e2);
|
|
expect( e2.dispatchedEvent ).toBeUndefined();
|
|
});
|
|
|
|
it('Should do nothing if mousedown is a custom event from ionic tap', function() {
|
|
var e = {
|
|
isTapHandled: false,
|
|
isIonicTap: true
|
|
};
|
|
tapMouseDown(e);
|
|
expect( e.isTapHandled ).toEqual(false);
|
|
});
|
|
|
|
it('Should preventDefault on mousedown if touchend target is different than mousedown target', function() {
|
|
tapLastTouchTarget = null;
|
|
|
|
var touchEndEvent = {
|
|
target: document.createElement('button'),
|
|
clientX: 100, clientY: 100,
|
|
preventDefault: function(){ this.defaultedPrevented = true; }
|
|
};
|
|
tapTouchEnd(touchEndEvent);
|
|
expect( tapLastTouchTarget ).toEqual(touchEndEvent.target);
|
|
|
|
var mouseDownEvent = {
|
|
target: document.createElement('textarea'),
|
|
clientX: 100, clientY: 100,
|
|
preventDefault: function(){ this.defaultedPrevented = true; },
|
|
stopPropagation: function(){ this.stoppedPropagation = true; }
|
|
};
|
|
tapMouseDown(mouseDownEvent);
|
|
expect( mouseDownEvent.defaultedPrevented ).toEqual(true);
|
|
});
|
|
|
|
it('Should not preventDefault on mousedown if the target is a select element', function() {
|
|
tapEnabledTouchEvents = true;
|
|
var e = {
|
|
isTapHandled: false,
|
|
isIonicTap: false,
|
|
target: document.createElement('select'),
|
|
preventDefault: function(){ this.defaultedPrevented = true; },
|
|
stopPropagation: function(){ this.stoppedPropagation = true; }
|
|
};
|
|
tapMouseDown(e);
|
|
expect( e.stoppedPropagation ).toEqual(true);
|
|
expect( e.defaultedPrevented ).toBeUndefined();
|
|
|
|
e = {
|
|
isTapHandled: false,
|
|
isIonicTap: false,
|
|
target: document.createElement('option'),
|
|
preventDefault: function(){ this.defaultedPrevented = true; },
|
|
stopPropagation: function(){ this.stoppedPropagation = true; }
|
|
};
|
|
tapMouseDown(e);
|
|
expect( e.stoppedPropagation ).toEqual(true);
|
|
expect( e.defaultedPrevented ).toBeUndefined();
|
|
});
|
|
|
|
it('Should tapClick with touchend and fire immediately', function() {
|
|
var e = {
|
|
target: {
|
|
tagName: 'button',
|
|
dispatchEvent: function(){
|
|
this.dispatchedEvent = true;
|
|
}
|
|
}
|
|
};
|
|
tapClick(e);
|
|
expect(e.target.dispatchedEvent).toEqual(true);
|
|
});
|
|
|
|
it('Should tapHasPointerMoved false if are null', function() {
|
|
expect( tapHasPointerMoved(null) ).toEqual(false);
|
|
});
|
|
|
|
it('Should tapPointerStart false if are null', function() {
|
|
tapPointerStart = null;
|
|
expect( tapHasPointerMoved(null) ).toEqual(false);
|
|
});
|
|
|
|
it('Should tapPointerStart false if are null', function() {
|
|
var e = {
|
|
target: document.createElement('input')
|
|
};
|
|
tapPointerStart = {x:0, y:0};
|
|
expect( tapHasPointerMoved(e) ).toEqual(false);
|
|
});
|
|
|
|
it('Should tapHasPointerMoved true if greater than or equal to release tolerance', function() {
|
|
tapPointerStart = { x: 100, y: 100 };
|
|
|
|
var s = tapHasPointerMoved({ clientX: 111, clientY: 100, target: document.createElement('button') });
|
|
expect(s).toEqual(true);
|
|
|
|
s = tapHasPointerMoved({ clientX: 89, clientY: 100, target: document.createElement('button') });
|
|
expect(s).toEqual(true);
|
|
|
|
s = tapHasPointerMoved({ clientX: 100, clientY: 109, target: document.createElement('button') });
|
|
expect(s).toEqual(true);
|
|
|
|
s = tapHasPointerMoved({ clientX: 100, clientY: 91, target: document.createElement('button') });
|
|
expect(s).toEqual(true);
|
|
|
|
s = tapHasPointerMoved({ clientX: 100, clientY: 200, target: document.createElement('button') });
|
|
expect(s).toEqual(true);
|
|
});
|
|
|
|
it('Should tapHasPointerMoved false if less than release tolerance', function() {
|
|
tapPointerStart = { x: 100, y: 100 };
|
|
|
|
var s = tapHasPointerMoved({ clientX: 100, clientY: 100, target: document.createElement('button') });
|
|
expect(s).toEqual(false);
|
|
|
|
s = tapHasPointerMoved({ clientX: 104, clientY: 100, target: document.createElement('button') });
|
|
expect(s).toEqual(false);
|
|
|
|
s = tapHasPointerMoved({ clientX: 96, clientY: 100, target: document.createElement('button') });
|
|
expect(s).toEqual(false);
|
|
|
|
s = tapHasPointerMoved({ clientX: 100, clientY: 102, target: document.createElement('button') });
|
|
expect(s).toEqual(false);
|
|
|
|
s = tapHasPointerMoved({ clientX: 100, clientY: 98, target: document.createElement('button') });
|
|
expect(s).toEqual(false);
|
|
});
|
|
|
|
it('Should not be tapHasPointerMoved if 0 coordinates', function() {
|
|
var e = {
|
|
clientX: 0,
|
|
clientY: 0,
|
|
target: document.createElement('input')
|
|
};
|
|
var s = tapHasPointerMoved(e, { clientX: 100, clientY: 100 });
|
|
expect(s).toEqual(false);
|
|
});
|
|
|
|
it('Should get coordinates from page mouse event', function() {
|
|
var e = { pageX: 77, pageY: 77 };
|
|
var c = ionic.tap.pointerCoord(e);
|
|
expect(c).toEqual({x:77, y: 77});
|
|
});
|
|
|
|
it('Should get coordinates from client mouse event', function() {
|
|
var e = { clientX: 77, clientY: 77 };
|
|
var c = ionic.tap.pointerCoord(e);
|
|
expect(c).toEqual({x:77, y: 77});
|
|
});
|
|
|
|
it('Should get coordinates from changedTouches touches', function() {
|
|
var e = {
|
|
touches: [{ clientX: 99, clientY: 99 }],
|
|
changedTouches: [{ clientX: 88, clientY: 88 }]
|
|
};
|
|
var c = ionic.tap.pointerCoord(e);
|
|
expect(c).toEqual({x:88, y: 88});
|
|
});
|
|
|
|
it('Should get coordinates from page touches', function() {
|
|
var e = {
|
|
touches: [{ pageX: 99, pageY: 99 }]
|
|
};
|
|
var c = ionic.tap.pointerCoord(e);
|
|
expect(c).toEqual({x:99, y: 99});
|
|
});
|
|
|
|
it('Should get coordinates from client touches', function() {
|
|
var e = {
|
|
touches: [{ clientX: 99, clientY: 99 }]
|
|
};
|
|
var c = ionic.tap.pointerCoord(e);
|
|
expect(c).toEqual({x:99, y: 99});
|
|
});
|
|
|
|
it('Should get 0 coordinates', function() {
|
|
var e = {};
|
|
var c = ionic.tap.pointerCoord(e);
|
|
expect(c).toEqual({x:0, y: 0});
|
|
});
|
|
|
|
it('Should not tapClick for disabled elements', function() {
|
|
// Disabled elements should not be tapped
|
|
var targetEle = document.createElement('input');
|
|
targetEle.disabled = true;
|
|
|
|
var e = {
|
|
target: targetEle
|
|
};
|
|
|
|
expect( tapClick(e) ).toEqual(false);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for invalid element', function() {
|
|
expect( ionic.tap.requiresNativeClick( null ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for input.disabled', function() {
|
|
var ele = document.createElement('input');
|
|
ele.disabled = true;
|
|
expect( ionic.tap.requiresNativeClick( ele ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for input[range]', function() {
|
|
var ele = document.createElement('input');
|
|
ele.type = 'range';
|
|
expect( ionic.tap.requiresNativeClick( ele ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for input[file]', function() {
|
|
var ele = document.createElement('input');
|
|
ele.type = 'file';
|
|
expect( ionic.tap.requiresNativeClick( ele ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for video element', function() {
|
|
var ele = document.createElement('video');
|
|
expect( ionic.tap.requiresNativeClick( ele ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for object element', function() {
|
|
var ele = document.createElement('object');
|
|
expect( ionic.tap.requiresNativeClick( ele ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should not ionic.tap.requiresNativeClick for common inputs', function() {
|
|
var inputTypes = ['text', 'email', 'search', 'tel', 'number', 'date', 'month', 'password', null, undefined, ''];
|
|
for(var x=0; x<inputTypes.length; x++) {
|
|
var targetEle = document.createElement('input');
|
|
targetEle.type = inputTypes[x];
|
|
expect( ionic.tap.requiresNativeClick(targetEle) ).toEqual(false);
|
|
}
|
|
expect( ionic.tap.requiresNativeClick( document.createElement('img') ) ).toEqual(false);
|
|
expect( ionic.tap.requiresNativeClick( document.createElement('div') ) ).toEqual(false);
|
|
expect( ionic.tap.requiresNativeClick( document.createElement('textarea') ) ).toEqual(false);
|
|
expect( ionic.tap.requiresNativeClick( document.createElement('select') ) ).toEqual(false);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for an element with data-tap-disabled attribute', function() {
|
|
var div = document.createElement('div');
|
|
expect( ionic.tap.requiresNativeClick( div ) ).toEqual(false);
|
|
|
|
div.setAttribute('data-tap-disabled', "true");
|
|
expect( ionic.tap.requiresNativeClick( div ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for an element with one of its parents with data-tap-disabled attribute', function() {
|
|
var div1 = document.createElement('div');
|
|
var div2 = document.createElement('div');
|
|
var div3 = document.createElement('div');
|
|
var div4 = document.createElement('div');
|
|
var div5 = document.createElement('div');
|
|
|
|
div1.appendChild(div2);
|
|
div2.appendChild(div3);
|
|
div3.appendChild(div4);
|
|
div4.appendChild(div5);
|
|
|
|
div2.setAttribute('data-tap-disabled', "true");
|
|
|
|
expect( ionic.tap.requiresNativeClick( div1 ) ).toEqual(false);
|
|
expect( ionic.tap.requiresNativeClick( div2 ) ).toEqual(true);
|
|
expect( ionic.tap.requiresNativeClick( div3 ) ).toEqual(true);
|
|
expect( ionic.tap.requiresNativeClick( div4 ) ).toEqual(true);
|
|
expect( ionic.tap.requiresNativeClick( div5 ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for labels containing input[file]', function() {
|
|
var lbl = document.createElement('label');
|
|
var ele = document.createElement('input');
|
|
ele.type = 'file';
|
|
lbl.appendChild(ele);
|
|
expect( ionic.tap.requiresNativeClick( lbl ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should ionic.tap.requiresNativeClick for elements underneath labels containing input[file]', function() {
|
|
var lbl = document.createElement('label');
|
|
var txt = document.createElement('span');
|
|
var ele = document.createElement('input');
|
|
ele.type = 'file';
|
|
lbl.appendChild(ele);
|
|
lbl.appendChild(txt);
|
|
expect( ionic.tap.requiresNativeClick( txt ) ).toEqual(true);
|
|
});
|
|
|
|
it('Should not allow a click that has an textarea target but not created by tapClick', function() {
|
|
var e = {
|
|
target: document.createElement('textarea'),
|
|
stopPropagation: function(){ this.stoppedPropagation = true; },
|
|
preventDefault: function(){ this.preventedDefault = true; }
|
|
};
|
|
tapClickGateKeeper(e);
|
|
|
|
expect( e.stoppedPropagation ).toBeDefined();
|
|
expect( e.preventedDefault ).toBeDefined();
|
|
});
|
|
|
|
it('Should allow a click that is a from an "Enter" or "Go" keypress submit', function() {
|
|
var target = document.createElement('button');
|
|
target.type = 'submit';
|
|
var e = {
|
|
target: target,
|
|
detail: 0,
|
|
stopPropagation: function(){ this.stoppedPropagation = true; },
|
|
preventDefault: function(){ this.preventedDefault = true; }
|
|
};
|
|
tapClickGateKeeper(e);
|
|
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should allow a click that is a tapClick', function() {
|
|
var e = {
|
|
target: document.createElement('input'),
|
|
isIonicTap: true,
|
|
stopPropagation: function(){ this.stoppedPropagation = true; },
|
|
preventDefault: function(){ this.preventedDefault = true; }
|
|
};
|
|
tapClickGateKeeper(e);
|
|
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should allow a click that is an ignore element', function() {
|
|
var e = {
|
|
target: document.createElement('input'),
|
|
stopPropagation: function(){ this.stoppedPropagation = true; },
|
|
preventDefault: function(){ this.preventedDefault = true; }
|
|
};
|
|
e.target.type = 'range';
|
|
tapClickGateKeeper(e);
|
|
|
|
expect( e.stoppedPropagation ).toBeUndefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should stopPropagation but not preventDefault on native label click that wraps text input', function() {
|
|
// Android requires preventDefault to not be fired when a label wraps an input
|
|
// so that when the label is tapped it brings up the keyboard
|
|
var e = {
|
|
target: document.createElement('label'),
|
|
stopPropagation: function(){ this.stoppedPropagation = true; },
|
|
preventDefault: function(){ this.preventedDefault = true; }
|
|
};
|
|
|
|
var input = document.createElement('textarea');
|
|
e.target.appendChild(input);
|
|
|
|
tapClickGateKeeper(e);
|
|
|
|
expect( e.stoppedPropagation ).toBeDefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should stopPropagation but not preventDefault on native span click inside a label that wraps text input', function() {
|
|
var label = document.createElement('label');
|
|
var span = document.createElement('span');
|
|
var textarea = document.createElement('textarea');
|
|
|
|
label.appendChild(span);
|
|
label.appendChild(textarea);
|
|
|
|
var e = {
|
|
target: span,
|
|
stopPropagation: function(){ this.stoppedPropagation = true; },
|
|
preventDefault: function(){ this.preventedDefault = true; }
|
|
};
|
|
|
|
tapClickGateKeeper(e);
|
|
|
|
expect( e.stoppedPropagation ).toBeDefined();
|
|
expect( e.preventedDefault ).toBeUndefined();
|
|
});
|
|
|
|
it('Should focus input', function() {
|
|
var ele = {
|
|
tagName: 'INPUT',
|
|
focus: function(){ this.hasFocus=true; }
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasFocus ).toEqual(true);
|
|
});
|
|
|
|
it('Should focus textarea', function() {
|
|
var ele = {
|
|
tagName: 'TEXTAREA',
|
|
focus: function(){ this.hasFocus=true; }
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasFocus ).toEqual(true);
|
|
});
|
|
|
|
it('Should set tapTouchFocusedInput if touch event and text input', function() {
|
|
tapEnabledTouchEvents = true;
|
|
var ele = {
|
|
tagName: 'TEXTAREA'
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( tapTouchFocusedInput ).toEqual(ele);
|
|
});
|
|
|
|
it('Should not set tapTouchFocusedInput if mouse event and text input', function() {
|
|
tapEnabledTouchEvents = false;
|
|
var ele = {
|
|
tagName: 'TEXTAREA'
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( tapTouchFocusedInput ).toEqual(null);
|
|
});
|
|
|
|
it('Should focus select', function() {
|
|
var ele = {
|
|
tagName: 'SELECT',
|
|
focus: function(){ this.hasFocus=true; },
|
|
dispatchEvent: function(){}
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasFocus ).toEqual(true);
|
|
expect( tapTouchFocusedInput ).toEqual(null);
|
|
});
|
|
|
|
it('Should focus contenteditable div', function() {
|
|
var ele = {
|
|
tagName: 'DIV',
|
|
isContentEditable: true,
|
|
focus: function(){ this.hasFocus=true; },
|
|
dispatchEvent: function(){}
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasFocus ).toEqual(true);
|
|
expect( tapTouchFocusedInput ).toEqual(null);
|
|
});
|
|
|
|
it('Should not focus on common elements', function() {
|
|
var tags = ['div', 'span', 'i', 'body', 'section', 'article', 'aside', 'li', 'p', 'header', 'button', 'ion-content'];
|
|
function setFocus() {
|
|
this.hasFocus = true;
|
|
}
|
|
for(var x=0; x<tags.length; x++) {
|
|
var ele = {
|
|
tagName: tags[x],
|
|
focus: setFocus
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasFocus ).toBeUndefined();
|
|
}
|
|
});
|
|
|
|
it('Should not focus on an input that already has focus', function() {
|
|
var ele = {
|
|
tagName: 'INPUT',
|
|
focus: function(){ this.hasFocus=true; }
|
|
};
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasFocus ).toEqual(true);
|
|
|
|
ele.focus = function(){ this.hasSecondFocus=true; };
|
|
tapHandleFocus(ele);
|
|
expect( ele.hasSecondFocus ).toBeUndefined();
|
|
});
|
|
|
|
it('Should not focus out on common elements', function() {
|
|
var tags = ['div', 'span', 'i', 'body', 'section', 'article', 'aside', 'li', 'p', 'header', 'button', 'ion-content'];
|
|
function setBlurred() { this.hasBlurred = true; }
|
|
for(var x=0; x<tags.length; x++) {
|
|
var ele = {
|
|
tagName: tags[x],
|
|
blur: setBlurred
|
|
};
|
|
tapActiveElement(ele);
|
|
tapFocusOutActive(ele);
|
|
expect( ele.hasBlurred ).toBeUndefined();
|
|
}
|
|
});
|
|
|
|
it('Should focus out on input elements', function() {
|
|
var tags = ['input', 'textarea', 'select'];
|
|
function setBlurred() { this.hasBlurred=true; }
|
|
for(var x=0; x<tags.length; x++) {
|
|
var ele = {
|
|
tagName: tags[x],
|
|
blur: setBlurred
|
|
};
|
|
tapActiveElement(ele);
|
|
tapFocusOutActive(ele);
|
|
expect( ele.hasBlurred ).toEqual(true);
|
|
}
|
|
});
|
|
|
|
it('Should focus out on contenteditable elements', function() {
|
|
var ele = {
|
|
tagName: 'DIV',
|
|
isContentEditable: true,
|
|
blur: function() { this.hasBlurred=true; }
|
|
};
|
|
tapActiveElement(ele);
|
|
tapFocusOutActive(ele);
|
|
expect( ele.hasBlurred ).toEqual(true);
|
|
});
|
|
|
|
it('Should get containing element of label when passed a deeply nested div', function() {
|
|
var label = document.createElement('label');
|
|
var div1 = document.createElement('div');
|
|
var div2 = document.createElement('div');
|
|
var div3 = document.createElement('div');
|
|
var div4 = document.createElement('div');
|
|
var div5 = document.createElement('div');
|
|
var div6 = document.createElement('div');
|
|
div6.id = 'div6';
|
|
|
|
label.appendChild(div1);
|
|
div1.appendChild(div2);
|
|
div2.appendChild(div3);
|
|
div3.appendChild(div4);
|
|
div4.appendChild(div5);
|
|
div5.appendChild(div6);
|
|
|
|
// max depth
|
|
expect( tapContainingElement(div5).tagName ).toEqual('LABEL');
|
|
|
|
// too deep
|
|
expect( tapContainingElement(div6).id ).toEqual('div6');
|
|
});
|
|
|
|
it('Should get containing element of label when passed a label', function() {
|
|
var label = document.createElement('label');
|
|
expect( tapContainingElement(label).tagName ).toEqual('LABEL');
|
|
});
|
|
|
|
it('Should get containing element of div when passed a div and no parent label', function() {
|
|
var ele = document.createElement('div');
|
|
expect( tapContainingElement(ele).tagName ).toEqual('DIV');
|
|
});
|
|
|
|
it('Should get containing element of label when passed a labels child span', function() {
|
|
var label = document.createElement('label');
|
|
var span = document.createElement('span');
|
|
label.appendChild(span);
|
|
expect( tapContainingElement(span).tagName ).toEqual('LABEL');
|
|
});
|
|
|
|
it('Should not return itself if no parent containing label and arg allowSelf=false', function() {
|
|
var div = document.createElement('div');
|
|
var span = document.createElement('span');
|
|
div.appendChild(span);
|
|
expect( tapContainingElement(span, false) ).toBeUndefined();
|
|
});
|
|
|
|
it('Should not focus out on label element which has no child input', function() {
|
|
var label = document.createElement('label');
|
|
label.blur = function(){ this.hasBlurred=true; };
|
|
tapActiveElement(label);
|
|
tapFocusOutActive(label);
|
|
expect( label.hasBlurred ).toBeUndefined();
|
|
});
|
|
|
|
it('Should not prevent scrolling', function() {
|
|
var target = document.createElement('div');
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
|
|
});
|
|
|
|
it('Should prevent scrolling because the event has defaultedPrevented', function() {
|
|
var target = document.createElement('div');
|
|
var e = {
|
|
target: target,
|
|
defaultPrevented: true
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should prevent scrolling because the target is input[file]', function() {
|
|
var target = document.createElement('input');
|
|
target.type = 'file';
|
|
var e = {
|
|
target: target,
|
|
defaultPrevented: true
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should prevent scrolling because the target is input[range]', function() {
|
|
var target = document.createElement('input');
|
|
target.type = 'range';
|
|
var e = {
|
|
target: target,
|
|
defaultPrevented: true
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should not prevent scrolling if the target was an input or textarea', function() {
|
|
var target = document.createElement('input');
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
|
|
|
|
e.target = document.createElement('textarea');
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
|
|
|
|
e.target = document.createElement('select');
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
|
|
});
|
|
|
|
it('Should not prevent scrolling if the target was an input or textarea, and the target is the same as the active element', function() {
|
|
var target = document.createElement('input');
|
|
tapActiveElement(target);
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
|
|
});
|
|
|
|
it('Should not prevent scrolling if the target isContentEditable', function() {
|
|
var target = document.createElement('div');
|
|
target.isContentEditable = true;
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(false);
|
|
});
|
|
|
|
it('Should prevent scrolling if the target has dataset.preventScroll', function() {
|
|
var target = document.createElement('div');
|
|
target.setAttribute('data-prevent-scroll', 'true');
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
|
|
target = document.createElement('div');
|
|
target.dataset.preventScroll = true;
|
|
e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
|
|
target = document.createElement('div');
|
|
target.dataset.preventScroll = 'true';
|
|
e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should prevent scrolling if the browser doesnt support dataset but target has data-prevent-scroll attribute', function() {
|
|
var target = {
|
|
tagName: 'div',
|
|
getAttribute: function(val) {
|
|
if(val === 'data-prevent-scroll') {
|
|
return 'true';
|
|
}
|
|
}
|
|
};
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should prevent scrolling if the target is an object or embed', function() {
|
|
var target = document.createElement('object');
|
|
var e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
|
|
target = document.createElement('embed');
|
|
e = {
|
|
target: target
|
|
};
|
|
expect( ionic.tap.ignoreScrollStart(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should get target element from an element', function() {
|
|
var ele = document.createElement('div');
|
|
expect( tapTargetElement(ele).tagName ).toEqual('DIV');
|
|
});
|
|
|
|
it('Should get labels input control from label element', function() {
|
|
var label = document.createElement('label');
|
|
var input = document.createElement('input');
|
|
label.appendChild(input);
|
|
|
|
expect( tapTargetElement(label).tagName ).toEqual('INPUT');
|
|
});
|
|
|
|
it('Should get button target even if it has children from es target', function() {
|
|
var button = document.createElement('button');
|
|
var span = document.createElement('span');
|
|
button.appendChild(span);
|
|
|
|
expect( tapTargetElement(button).tagName ).toEqual('BUTTON');
|
|
});
|
|
|
|
it('Should isTextInput', function() {
|
|
expect( ionic.tap.isTextInput(null) ).toEqual(false);
|
|
|
|
var ele = document.createElement('textarea');
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(true);
|
|
|
|
ele = document.createElement('input');
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'search';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'url';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'email';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'range';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele.type = 'file';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele.type = 'submit';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele.type = 'reset';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele.type = 'radio';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele.type = 'checkbox';
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele = document.createElement('select');
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
|
|
ele = document.createElement('div');
|
|
ele.setAttribute('contenteditable', true);
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(true);
|
|
|
|
ele = document.createElement('div');
|
|
ele.setAttribute('contenteditable', false);
|
|
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
|
|
});
|
|
|
|
it('Should isDateInput', function() {
|
|
expect( ionic.tap.isDateInput(null) ).toEqual(false);
|
|
|
|
ele = document.createElement('input');
|
|
|
|
ele.type = 'date';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'datetime-local';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'month';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'week';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'time';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(true);
|
|
|
|
ele.type = 'checkbox';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(false);
|
|
|
|
ele.type = '';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(false);
|
|
|
|
ele.type = 'text';
|
|
expect( ionic.tap.isDateInput(ele) ).toEqual(false);
|
|
|
|
|
|
});
|
|
|
|
it('Should isLabelWithTextInput', function() {
|
|
var label = document.createElement('label');
|
|
expect( ionic.tap.isLabelWithTextInput(label) ).toEqual(false);
|
|
|
|
var span = document.createElement('span');
|
|
expect( ionic.tap.isLabelWithTextInput(span) ).toEqual(false);
|
|
|
|
label.appendChild(span);
|
|
expect( ionic.tap.isLabelWithTextInput(span) ).toEqual(false);
|
|
|
|
var textarea = document.createElement('textarea');
|
|
expect( ionic.tap.isLabelWithTextInput(textarea) ).toEqual(false);
|
|
|
|
label.appendChild(textarea);
|
|
expect( ionic.tap.isLabelWithTextInput(textarea) ).toEqual(true);
|
|
});
|
|
|
|
it('Should containsOrIsTextInput', function() {
|
|
var label = document.createElement('label');
|
|
expect( ionic.tap.containsOrIsTextInput(label) ).toEqual(false);
|
|
|
|
var span = document.createElement('span');
|
|
expect( ionic.tap.containsOrIsTextInput(span) ).toEqual(false);
|
|
|
|
label.appendChild(span);
|
|
expect( ionic.tap.containsOrIsTextInput(span) ).toEqual(false);
|
|
|
|
var textarea = document.createElement('textarea');
|
|
expect( ionic.tap.containsOrIsTextInput(textarea) ).toEqual(true);
|
|
|
|
label.appendChild(textarea);
|
|
expect( ionic.tap.containsOrIsTextInput(textarea) ).toEqual(true);
|
|
});
|
|
|
|
it('Should reset focus to tapTouchFocusedInput if the active element changed from mousedown', function() {
|
|
tapEnabledTouchEvents = true;
|
|
tapActiveElement(document.createElement('textarea'));
|
|
|
|
var tapFocusedEle = document.createElement('input');
|
|
tapFocusedEle.focus = function(){
|
|
this.hasFocus = true;
|
|
};
|
|
|
|
tapTouchFocusedInput = tapFocusedEle;
|
|
|
|
var e = {
|
|
target: document.createElement('input')
|
|
};
|
|
tapFocusIn(e);
|
|
|
|
expect( tapFocusedEle.hasFocus ).toEqual(true);
|
|
expect( tapTouchFocusedInput ).toEqual(null);
|
|
});
|
|
|
|
it('Should tapIgnoreEvent false', function(){
|
|
var e = {};
|
|
expect( tapIgnoreEvent(e) ).toBeUndefined();
|
|
});
|
|
|
|
it('Should tapIgnoreEvent true because e.isTapHandled', function(){
|
|
var e = {
|
|
isTapHandled: true
|
|
};
|
|
expect( tapIgnoreEvent(e) ).toEqual(true);
|
|
});
|
|
|
|
it('Should tapIgnoreEvent true because ionic.scroll.isScrolling and target is a text input', function(){
|
|
var target = document.createElement('textarea');
|
|
var e = {
|
|
target: target,
|
|
preventDefault: function(){ this.preventedDefault=true; }
|
|
};
|
|
ionic.scroll.isScrolling = true;
|
|
expect( tapIgnoreEvent(e) ).toEqual(true);
|
|
expect( e.preventedDefault ).toEqual(true);
|
|
});
|
|
|
|
it('Should tapIgnoreEvent true because ionic.scroll.isScrolling and target is span in a label containing a text input', function(){
|
|
var label = document.createElement('label');
|
|
var span = document.createElement('span');
|
|
var textarea = document.createElement('textarea');
|
|
|
|
label.appendChild(span);
|
|
label.appendChild(textarea);
|
|
|
|
var e = {
|
|
target: label,
|
|
preventDefault: function(){ this.preventedDefault=true; }
|
|
};
|
|
ionic.scroll.isScrolling = true;
|
|
expect( tapIgnoreEvent(e) ).toEqual(true);
|
|
expect( e.preventedDefault ).toEqual(true);
|
|
});
|
|
|
|
it('Should tapIgnoreEvent false because ionic.scroll.isScrolling but target is not a text input', function(){
|
|
var target = document.createElement('span');
|
|
var e = {
|
|
target: target,
|
|
preventDefault: function(){ this.preventedDefault=true; }
|
|
};
|
|
ionic.scroll.isScrolling = true;
|
|
expect( tapIgnoreEvent(e) ).toBeUndefined();
|
|
});
|
|
|
|
it('Should tapIgnoreEvent false because ionic.scroll.isScrolling but target is a input[checkbox]', function(){
|
|
var label = document.createElement('label');
|
|
var span = document.createElement('span');
|
|
var checkbox = document.createElement('input');
|
|
checkbox.type = 'checkbox';
|
|
|
|
label.appendChild(span);
|
|
label.appendChild(checkbox);
|
|
|
|
var e = {
|
|
target: span,
|
|
preventDefault: function(){ this.preventedDefault=true; }
|
|
};
|
|
ionic.scroll.isScrolling = true;
|
|
expect( tapIgnoreEvent(e) ).toBeUndefined();
|
|
});
|
|
|
|
});
|