Bug 1517737 - handle keyboard events on fake searchbox when focused (#4643)
This commit is contained in:
Родитель
cb74c57544
Коммит
796f36c1dd
|
@ -12,6 +12,7 @@ export class _Search extends React.PureComponent {
|
|||
super(props);
|
||||
this.onSearchClick = this.onSearchClick.bind(this);
|
||||
this.onSearchHandoffClick = this.onSearchHandoffClick.bind(this);
|
||||
this.onSearchHandoffKeyDown = this.onSearchHandoffKeyDown.bind(this);
|
||||
this.onInputMount = this.onInputMount.bind(this);
|
||||
}
|
||||
|
||||
|
@ -42,6 +43,16 @@ export class _Search extends React.PureComponent {
|
|||
// TODO: Send a telemetry ping. BUG 1514732
|
||||
}
|
||||
|
||||
onSearchHandoffKeyDown(event) {
|
||||
if (event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey) {
|
||||
// We only care about key strokes that will produce a character.
|
||||
const text = event.key;
|
||||
this.props.dispatch(ac.OnlyToMain({type: at.HANDOFF_SEARCH_TO_AWESOMEBAR, data: {text}}));
|
||||
|
||||
// TODO: Send a telemetry ping. BUG 1514732
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
delete window.gContentSearchController;
|
||||
}
|
||||
|
@ -119,6 +130,7 @@ export class _Search extends React.PureComponent {
|
|||
<button
|
||||
className="search-handoff-button"
|
||||
onClick={this.onSearchHandoffClick}
|
||||
onKeyDown={this.onSearchHandoffKeyDown}
|
||||
title={this.props.intl.formatMessage({id: "search_web_placeholder"})}>
|
||||
<div className="fake-textbox">{this.props.intl.formatMessage({id: "search_web_placeholder"})}</div>
|
||||
<div className="fake-caret" />
|
||||
|
|
|
@ -164,6 +164,10 @@ $glyph-forward: url('chrome://browser/skin/forward.svg');
|
|||
.search-active & {
|
||||
border: $input-border-active;
|
||||
box-shadow: var(--newtab-textbox-focus-boxshadow);
|
||||
|
||||
.fake-caret {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.search-hidden & {
|
||||
|
@ -191,10 +195,6 @@ $glyph-forward: url('chrome://browser/skin/forward.svg');
|
|||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.search-active & {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -286,15 +286,22 @@ class PlacesFeed {
|
|||
handoffSearchToAwesomebar({_target, data, meta}) {
|
||||
const urlBar = _target.browser.ownerGlobal.gURLBar;
|
||||
|
||||
if (!data.hiddenFocus) {
|
||||
if (!data.hiddenFocus && !data.text) {
|
||||
// Do a normal focus of awesomebar and reset the in content search (remove fake focus styles).
|
||||
urlBar.focus();
|
||||
this.store.dispatch(ac.OnlyToOneContent({type: at.SHOW_SEARCH}, meta.fromTarget));
|
||||
// We are done here. return early.
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus the awesomebar without the style changes.
|
||||
urlBar.hiddenFocus();
|
||||
if (data.text) {
|
||||
// Pass the provided text to the awesomebar.
|
||||
urlBar.search(data.text);
|
||||
} else {
|
||||
// Focus the awesomebar without the style changes.
|
||||
urlBar.hiddenFocus();
|
||||
}
|
||||
|
||||
const onKeydown = () => {
|
||||
// Once the user starts typing, we want to hide the in content search box
|
||||
// and show the focus styles on the awesomebar.
|
||||
|
|
|
@ -83,7 +83,7 @@ describe("<Search>", () => {
|
|||
it("should hand-off search when button is clicked with mouse", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.instance().onSearchHandoffClick({clientX: 101, clientY: 102});
|
||||
wrapper.find(".search-handoff-button").simulate("click", {clientX: 101, clientY: 102});
|
||||
assert.calledWith(dispatch, {
|
||||
data: {hiddenFocus: true},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
|
@ -94,7 +94,7 @@ describe("<Search>", () => {
|
|||
it("should hand-off search when button is clicked with keyboard", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.instance().onSearchHandoffClick({clientX: 0, clientY: 0});
|
||||
wrapper.find(".search-handoff-button").simulate("click", {clientX: 0, clientY: 0});
|
||||
assert.calledWith(dispatch, {
|
||||
data: {hiddenFocus: false},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
|
@ -102,5 +102,33 @@ describe("<Search>", () => {
|
|||
});
|
||||
assert.calledWith(dispatch, {type: "FOCUS_SEARCH"});
|
||||
});
|
||||
it("should hand-off search when user types", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f"});
|
||||
assert.calledWith(dispatch, {
|
||||
data: {text: "f"},
|
||||
meta: {from: "ActivityStream:Content", skipLocal: true, to: "ActivityStream:Main"},
|
||||
type: "HANDOFF_SEARCH_TO_AWESOMEBAR",
|
||||
});
|
||||
});
|
||||
it("should NOT hand-off search when user types with with ctrl pressed", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f", ctrlKey: true});
|
||||
assert.notCalled(dispatch);
|
||||
});
|
||||
it("should NOT hand-off search when user types with with alt pressed", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f", altKey: true});
|
||||
assert.notCalled(dispatch);
|
||||
});
|
||||
it("should NOT hand-off search when user types with with meta pressed", () => {
|
||||
const dispatch = sinon.spy();
|
||||
const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} handoffEnabled={true} dispatch={dispatch} />);
|
||||
wrapper.find(".search-handoff-button").simulate("keydown", {key: "f", metaKey: true});
|
||||
assert.notCalled(dispatch);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -326,6 +326,7 @@ describe("PlacesFeed", () => {
|
|||
beforeEach(() => {
|
||||
fakeUrlBar = {
|
||||
focus: sinon.spy(),
|
||||
search: sinon.spy(),
|
||||
hiddenFocus: sinon.spy(),
|
||||
removeHiddenFocus: sinon.spy(),
|
||||
addEventListener: (ev, cb) => {
|
||||
|
@ -395,6 +396,18 @@ describe("PlacesFeed", () => {
|
|||
type: "SHOW_SEARCH",
|
||||
});
|
||||
});
|
||||
it("should properly handle text data passed in", () => {
|
||||
feed.handoffSearchToAwesomebar({
|
||||
_target: {browser: {ownerGlobal: {gURLBar: fakeUrlBar}}},
|
||||
data: {text: "f"},
|
||||
meta: {fromTarget: {}},
|
||||
});
|
||||
assert.calledOnce(fakeUrlBar.search);
|
||||
assert.calledWith(fakeUrlBar.search, "f");
|
||||
assert.notCalled(fakeUrlBar.hiddenFocus);
|
||||
assert.notCalled(fakeUrlBar.focus);
|
||||
assert.notCalled(feed.store.dispatch);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#observe", () => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче