// ========================================================================== // Project: SproutCore
- JavaScript Application Framework // Copyright: ©2006-2011 Strobe Inc. and contributors. // ©2008-2011 Apple Inc. All rights reserved. // License: Licensed under MIT license (see license.js) // ========================================================================== /*global module, test, ok, equals */ var originalTabbing;
module(“SC.View - Keyboard support with Tabbing Only Inside Document”, {
setup: function () { originalTabbing = SC.TABBING_ONLY_INSIDE_DOCUMENT; SC.TABBING_ONLY_INSIDE_DOCUMENT = YES; }, teardown: function () { SC.TABBING_ONLY_INSIDE_DOCUMENT = originalTabbing; }
});
test(“Views only attempt to call performKeyEquivalent on child views that support it”, function () {
var performKeyEquivalentCalled = 0; var view = SC.View.design({ childViews: ['unsupported', 'supported'], unsupported: SC.CoreView, supported: SC.View.design({ performKeyEquivalent: function (str) { performKeyEquivalentCalled++; return NO; } }) }); view = view.create(); view.performKeyEquivalent("ctrl_r"); ok(performKeyEquivalentCalled > 0, "performKeyEquivalent is called on the view that supports it"); view.destroy();
});
/**
nextValidKeyView tests
*/
test(“nextValidKeyView is receiver if it is the only view that acceptsFirstResponder”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: SC.View, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: SC.View, view6: SC.View }) }); pane.append(); equals(pane.view1.view4.get('nextValidKeyView'), pane.view1.view4, "nextValidKeyView is receiver"); pane.remove(); pane.destroy();
});
test(“nextValidKeyView is null if no views have acceptsFirstResponder === YES”, function () {
var pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: SC.View, view4: SC.View }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: SC.View, view6: SC.View }) }); pane.append(); ok(SC.none(pane.view1.view4.get('nextValidKeyView')), "nextValidKeyView is null"); pane.remove(); pane.destroy();
});
test(“firstKeyView and nextKeyView of parents are respected”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2', 'view7'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: testView, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: testView, view6: testView }), view7: SC.View.extend({ childViews: ['view8', 'view9'], view8: testView, view9: testView }) }); pane.append(); equals(pane.view2.view6.get('nextValidKeyView'), pane.view7.view8, "order is correct when first and next not set"); pane.set('firstKeyView', pane.view2); pane.view2.set('nextKeyView', pane.view1); pane.view1.set('nextKeyView', pane.view7); equals(pane.view2.view6.get('nextValidKeyView'), pane.view1.view3, "order is respected when first and next are set"); pane.remove(); pane.destroy();
});
test(“nextValidKeyView is chosen correctly when nextKeyView is not a sibling”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: SC.View, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: testView, view6: SC.View }) }); pane.append(); pane.view1.view4.set('nextKeyView', pane.view2.view5); pane.view2.view5.set('nextKeyView', pane.view1.view4); equals(pane.view1.view4.get('nextValidKeyView'), pane.view2.view5, "nextValidKeyView is correct"); equals(pane.view2.view5.get('nextValidKeyView'), pane.view1.view4, "nextValidKeyView is correct"); pane.remove(); pane.destroy();
});
test(“nextValidKeyView is chosen correctly when child of parent's previous sibling has nextKeyView set”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: testView, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: testView, view6: testView }) }); pane.view1.view3.set('nextKeyView', pane.view1.view4); pane.append(); equals(pane.view2.view5.get('nextValidKeyView'), pane.view2.view6, "nextValidKeyView chosen is next sibling"); pane.remove(); pane.destroy();
});
test(“nextValidKeyView checks for acceptsFirstResponder”, function () {
var pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ acceptsFirstResponder: YES }), view2: SC.View.extend({ acceptsFirstResponder: NO }) }); pane.view1.set('nextKeyView', pane.view2); pane.append(); ok(pane.view1.get('nextValidKeyView') !== pane.view2, "nextValidKeyView is not nextKeyView because nextKeyView acceptsFirstResponder === NO"); pane.remove(); pane.destroy();
});
test(“nextValidKeyView prioritizes parent's lastKeyView even if nextKeyView is set”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], lastKeyView: function () { return this.view3; }.property(), view3: testView, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: testView, view6: testView }) }); pane.append(); equals(pane.view1.view3.get('nextValidKeyView'), pane.view2.view5, "lastKeyView was respected; views after lastKeyView were skipped"); pane.remove(); pane.destroy();
});
/**
previousValidKeyView tests
*/
test(“previousValidKeyView is receiver if it is the only view that acceptsFirstResponder”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: SC.View, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: SC.View, view6: SC.View }) }); pane.append(); equals(pane.view1.view4.get('previousValidKeyView'), pane.view1.view4, "previousValidKeyView is receiver"); pane.remove(); pane.destroy();
});
test(“previousValidKeyView is null if no views have acceptsFirstResponder === YES”, function () {
var pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: SC.View, view4: SC.View }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: SC.View, view6: SC.View }) }); pane.append(); ok(SC.none(pane.view1.view4.get('previousValidKeyView')), "previousValidKeyView is null"); pane.remove(); pane.destroy();
});
test(“lastKeyView and previousKeyView of parents are respected”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2', 'view7'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: testView, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: testView, view6: testView }), view7: SC.View.extend({ childViews: ['view8', 'view9'], view8: testView, view9: testView }) }); pane.append(); equals(pane.view2.view5.get('previousValidKeyView'), pane.view1.view4, "order is correct when last and previous not set"); pane.set('lastKeyView', pane.view2); pane.view2.set('previousKeyView', pane.view7); pane.view1.set('previousKeyView', pane.view1); equals(pane.view2.view5.get('previousValidKeyView'), pane.view7.view9, "order is respected when last and previous are set"); pane.remove(); pane.destroy();
});
test(“previousValidKeyView is chosen correctly when previousKeyView is not a sibling”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: SC.View, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], view5: testView, view6: SC.View }) }); pane.append(); pane.view1.view4.set('previousKeyView', pane.view2.view5); pane.view2.view5.set('previousKeyView', pane.view1.view4); equals(pane.view1.view4.get('previousValidKeyView'), pane.view2.view5, "previousValidKeyView is correct"); equals(pane.view2.view5.get('previousValidKeyView'), pane.view1.view4, "previousValidKeyView is correct"); pane.remove(); pane.destroy();
});
test(“previousValidKeyView prioritizes parent's firstKeyView even if previousKeyView is set”, function () {
var testView = SC.View.extend({acceptsFirstResponder: YES}), pane = SC.Pane.create({ childViews: ['view1', 'view2'], view1: SC.View.extend({ childViews: ['view3', 'view4'], view3: testView, view4: testView }), view2: SC.View.extend({ childViews: ['view5', 'view6'], firstKeyView: function () { return this.view6; }.property(), view5: testView, view6: testView }) }); pane.append(); equals(pane.view2.view6.get('previousValidKeyView'), pane.view1.view4, "firstKeyView was respected; views before firstKeyView were skipped"); pane.remove(); pane.destroy();
});
module(“SC.View - Keyboard support with Tabbing Outside of Document”);
test(“forward tab with no next responder moves out of document”);
test(“backwards tab with no previous responder moves out of document”);