1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h"
#include "base/logging.h"
#include "base/stl_util.h"
namespace {
const char kDefaultURLPath[] = "index.html";
const size_t kDefaultURLPathLen = arraysize(kDefaultURLPath) - 1;
namespace ime = ::chromeos::input_method;
// Selects and returns a virtual keyboard extension from |keyboards| which
// supports the |layout|.
const ime::VirtualKeyboard* SelectVirtualKeyboardInternal(
const std::list<const ime::VirtualKeyboard*>& keyboards,
const std::string& layout) {
for (std::list<const ime::VirtualKeyboard*>::const_iterator iter =
keyboards.begin(); iter != keyboards.end(); ++iter) {
const ime::VirtualKeyboard* keyboard = *iter;
if (keyboard->IsLayoutSupported(layout))
return keyboard;
}
return NULL;
}
} // namespace
namespace chromeos {
namespace input_method {
VirtualKeyboard::VirtualKeyboard(const GURL& url,
const std::string& name,
const std::set<std::string>& supported_layouts,
bool is_system)
: url_(url),
name_(name),
supported_layouts_(supported_layouts),
is_system_(is_system) {
}
VirtualKeyboard::~VirtualKeyboard() {
}
GURL VirtualKeyboard::GetURLForLayout(const std::string& layout) const {
if (layout.empty()) {
return url_;
}
url_canon::Replacements<char> replacements;
replacements.SetPath(
kDefaultURLPath, url_parse::Component(0, kDefaultURLPathLen));
// TODO(yusukes): would be better to URL-encode the |layout|?
replacements.SetRef(layout.c_str(), url_parse::Component(0, layout.length()));
return url_.ReplaceComponents(replacements);
}
bool VirtualKeyboard::IsLayoutSupported(const std::string& layout) const {
return supported_layouts_.count(layout) > 0;
}
VirtualKeyboardSelector::VirtualKeyboardSelector()
: current_(NULL) {
}
VirtualKeyboardSelector::~VirtualKeyboardSelector() {
STLDeleteElements(&keyboards_);
STLDeleteElements(&system_keyboards_);
}
bool VirtualKeyboardSelector::AddVirtualKeyboard(
const GURL& url,
const std::string& name,
const std::set<std::string>& supported_layouts,
bool is_system) {
if (url_to_keyboard_.count(url))
return false; // the URL is already in use.
const VirtualKeyboard* new_keyboard = new VirtualKeyboard(url,
name,
supported_layouts,
is_system);
if (is_system) {
system_keyboards_.push_front(new_keyboard);
} else {
keyboards_.push_front(new_keyboard);
}
url_to_keyboard_.insert(std::make_pair(url, new_keyboard));
std::set<std::string>::const_iterator layout_iter;
for (layout_iter = new_keyboard->supported_layouts().begin();
layout_iter != new_keyboard->supported_layouts().end();
++layout_iter) {
const std::string& layout = *layout_iter;
layout_to_keyboard_.insert(std::make_pair(layout, new_keyboard));
}
return true;
}
const VirtualKeyboard* VirtualKeyboardSelector::SelectVirtualKeyboard(
const std::string& layout) {
if (layout.empty()) {
LOG(ERROR) << "No layout is specified";
return NULL;
}
// First, check the user pref.
std::map<std::string, const VirtualKeyboard*>::const_iterator iter =
user_preference_.find(layout);
if (iter != user_preference_.end() &&
iter->second->IsLayoutSupported(layout)) {
current_ = iter->second;
return current_;
}
// Second, check whether the current keyboard supports the layout.
if (current_ && current_->IsLayoutSupported(layout)) {
return current_;
}
const VirtualKeyboard* keyboard =
SelectVirtualKeyboardWithoutPreferences(layout);
if (!keyboard) {
VLOG(1) << "No virtual keyboard for " << layout << " is found";
return NULL;
}
current_ = keyboard;
return keyboard;
}
bool VirtualKeyboardSelector::SetUserPreference(
const std::string& layout, const GURL& url) {
std::map<GURL, const VirtualKeyboard*>::const_iterator iter =
url_to_keyboard_.find(url);
if (iter == url_to_keyboard_.end()) {
VLOG(1) << "Can't set user preference: unknown URL";
return false;
}
const VirtualKeyboard* keyboard = iter->second;
if (!keyboard->IsLayoutSupported(layout)) {
VLOG(1) << "Requested layout is not supported by requested URL";
return false;
}
RemoveUserPreference(layout);
user_preference_.insert(std::make_pair(layout, keyboard));
return true;
}
void VirtualKeyboardSelector::RemoveUserPreference(const std::string& layout) {
user_preference_.erase(layout);
}
void VirtualKeyboardSelector::ClearAllUserPreferences() {
user_preference_.clear();
}
const VirtualKeyboard*
VirtualKeyboardSelector::SelectVirtualKeyboardWithoutPreferences(
const std::string& layout) {
const VirtualKeyboard* keyboard =
SelectVirtualKeyboardInternal(keyboards_, layout);
if (!keyboard)
keyboard = SelectVirtualKeyboardInternal(system_keyboards_, layout);
return keyboard;
}
} // namespace input_method
} // namespace chromeos
|