Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(606)

Side by Side Diff: chrome/browser/ui/views/accessibility/accessibility_event_router_views.cc

Issue 22922003: Remove notifications from Accessibility API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clean up Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/accessibility/accessibility_event_router_views .h" 5 #include "chrome/browser/ui/views/accessibility/accessibility_event_router_views .h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 30 matching lines...) Expand all
41 return Singleton<AccessibilityEventRouterViews>::get(); 41 return Singleton<AccessibilityEventRouterViews>::get();
42 } 42 }
43 43
44 void AccessibilityEventRouterViews::HandleAccessibilityEvent( 44 void AccessibilityEventRouterViews::HandleAccessibilityEvent(
45 views::View* view, ui::AccessibilityTypes::Event event_type) { 45 views::View* view, ui::AccessibilityTypes::Event event_type) {
46 if (!ExtensionAccessibilityEventRouter::GetInstance()-> 46 if (!ExtensionAccessibilityEventRouter::GetInstance()->
47 IsAccessibilityEnabled()) { 47 IsAccessibilityEnabled()) {
48 return; 48 return;
49 } 49 }
50 50
51 chrome::NotificationType notification_type; 51 if (event_type == ui::AccessibilityTypes::EVENT_TEXT_CHANGED ||
52 switch (event_type) { 52 event_type == ui::AccessibilityTypes::EVENT_SELECTION_CHANGED) {
53 case ui::AccessibilityTypes::EVENT_FOCUS: 53 // These two events should only be sent for views that have focus. This
54 notification_type = chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED; 54 // enforces the invariant that we fire events triggered by user action and
55 break; 55 // not by programmatic logic. For example, the location bar can be updated
56 case ui::AccessibilityTypes::EVENT_MENUSTART: 56 // by javascript while the user focus is within some other part of the
57 case ui::AccessibilityTypes::EVENT_MENUPOPUPSTART: 57 // user interface. In contrast, the other supported events here do not
58 notification_type = chrome::NOTIFICATION_ACCESSIBILITY_MENU_OPENED; 58 // depend on focus. For example, a menu within a menubar can open or close
59 break; 59 // while focus is within the location bar or anywhere else as a result of
60 case ui::AccessibilityTypes::EVENT_MENUEND: 60 // user action. Note that the below logic can at some point be removed if
61 case ui::AccessibilityTypes::EVENT_MENUPOPUPEND: 61 // we pass more information along to the listener such as focused state.
62 notification_type = chrome::NOTIFICATION_ACCESSIBILITY_MENU_CLOSED; 62 if (!view->GetFocusManager() ||
63 break; 63 view->GetFocusManager()->GetFocusedView() != view)
64 case ui::AccessibilityTypes::EVENT_TEXT_CHANGED:
65 case ui::AccessibilityTypes::EVENT_SELECTION_CHANGED:
66 // These two events should only be sent for views that have focus. This
67 // enforces the invariant that we fire events triggered by user action and
68 // not by programmatic logic. For example, the location bar can be updated
69 // by javascript while the user focus is within some other part of the
70 // user interface. In contrast, the other supported events here do not
71 // depend on focus. For example, a menu within a menubar can open or close
72 // while focus is within the location bar or anywhere else as a result of
73 // user action. Note that the below logic can at some point be removed if
74 // we pass more information along to the listener such as focused state.
75 if (!view->GetFocusManager() ||
76 view->GetFocusManager()->GetFocusedView() != view)
77 return;
78 notification_type = chrome::NOTIFICATION_ACCESSIBILITY_TEXT_CHANGED;
79 break;
80 case ui::AccessibilityTypes::EVENT_VALUE_CHANGED:
81 notification_type = chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_ACTION;
82 break;
83 case ui::AccessibilityTypes::EVENT_ALERT:
84 notification_type = chrome::NOTIFICATION_ACCESSIBILITY_WINDOW_OPENED;
85 break;
86 case ui::AccessibilityTypes::EVENT_NAME_CHANGED:
87 default:
88 NOTIMPLEMENTED();
89 return; 64 return;
90 } 65 }
91 66
92 // Don't dispatch the accessibility event until the next time through the 67 // Don't dispatch the accessibility event until the next time through the
93 // event loop, to handle cases where the view's state changes after 68 // event loop, to handle cases where the view's state changes after
94 // the call to post the event. It's safe to use base::Unretained(this) 69 // the call to post the event. It's safe to use base::Unretained(this)
95 // because AccessibilityEventRouterViews is a singleton. 70 // because AccessibilityEventRouterViews is a singleton.
96 views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); 71 views::ViewStorage* view_storage = views::ViewStorage::GetInstance();
97 int view_storage_id = view_storage->CreateStorageID(); 72 int view_storage_id = view_storage->CreateStorageID();
98 view_storage->StoreView(view_storage_id, view); 73 view_storage->StoreView(view_storage_id, view);
99 base::MessageLoop::current()->PostTask( 74 base::MessageLoop::current()->PostTask(
100 FROM_HERE, 75 FROM_HERE,
101 base::Bind( 76 base::Bind(
102 &AccessibilityEventRouterViews::DispatchNotificationOnViewStorageId, 77 &AccessibilityEventRouterViews::DispatchNotificationOnViewStorageId,
103 view_storage_id, 78 view_storage_id,
104 notification_type)); 79 event_type));
105 } 80 }
106 81
107 void AccessibilityEventRouterViews::HandleMenuItemFocused( 82 void AccessibilityEventRouterViews::HandleMenuItemFocused(
108 const string16& menu_name, 83 const string16& menu_name,
109 const string16& menu_item_name, 84 const string16& menu_item_name,
110 int item_index, 85 int item_index,
111 int item_count, 86 int item_count,
112 bool has_submenu) { 87 bool has_submenu) {
113 if (!ExtensionAccessibilityEventRouter::GetInstance()-> 88 if (!ExtensionAccessibilityEventRouter::GetInstance()->
114 IsAccessibilityEnabled()) { 89 IsAccessibilityEnabled()) {
115 return; 90 return;
116 } 91 }
117 92
118 if (!most_recent_profile_) 93 if (!most_recent_profile_)
119 return; 94 return;
120 95
121 AccessibilityMenuItemInfo info(most_recent_profile_, 96 AccessibilityMenuItemInfo info(most_recent_profile_,
122 UTF16ToUTF8(menu_item_name), 97 UTF16ToUTF8(menu_item_name),
123 UTF16ToUTF8(menu_name), 98 UTF16ToUTF8(menu_name),
124 has_submenu, 99 has_submenu,
125 item_index, 100 item_index,
126 item_count); 101 item_count);
127 SendAccessibilityNotification( 102 SendControlAccessibilityNotification(
128 chrome::NOTIFICATION_ACCESSIBILITY_CONTROL_FOCUSED, &info); 103 ui::AccessibilityTypes::EVENT_FOCUS, &info);
129 } 104 }
130 105
131 void AccessibilityEventRouterViews::Observe( 106 void AccessibilityEventRouterViews::Observe(
132 int type, 107 int type,
133 const content::NotificationSource& source, 108 const content::NotificationSource& source,
134 const content::NotificationDetails& details) { 109 const content::NotificationDetails& details) {
135 DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_DESTROYED); 110 DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_DESTROYED);
136 Profile* profile = content::Source<Profile>(source).ptr(); 111 Profile* profile = content::Source<Profile>(source).ptr();
137 if (profile == most_recent_profile_) 112 if (profile == most_recent_profile_)
138 most_recent_profile_ = NULL; 113 most_recent_profile_ = NULL;
139 } 114 }
140 115
141 // 116 //
142 // Private methods 117 // Private methods
143 // 118 //
144 119
145 void AccessibilityEventRouterViews::DispatchNotificationOnViewStorageId( 120 void AccessibilityEventRouterViews::DispatchNotificationOnViewStorageId(
146 int view_storage_id, 121 int view_storage_id,
147 chrome::NotificationType type) { 122 ui::AccessibilityTypes::Event type) {
148 views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); 123 views::ViewStorage* view_storage = views::ViewStorage::GetInstance();
149 views::View* view = view_storage->RetrieveView(view_storage_id); 124 views::View* view = view_storage->RetrieveView(view_storage_id);
150 view_storage->RemoveView(view_storage_id); 125 view_storage->RemoveView(view_storage_id);
151 if (!view) 126 if (!view)
152 return; 127 return;
153 128
154 AccessibilityEventRouterViews* instance = 129 AccessibilityEventRouterViews* instance =
155 AccessibilityEventRouterViews::GetInstance(); 130 AccessibilityEventRouterViews::GetInstance();
156 instance->DispatchAccessibilityNotification(view, type); 131 instance->DispatchAccessibilityNotification(view, type);
157 } 132 }
158 133
159 void AccessibilityEventRouterViews::DispatchAccessibilityNotification( 134 void AccessibilityEventRouterViews::DispatchAccessibilityNotification(
160 views::View* view, chrome::NotificationType type) { 135 views::View* view, ui::AccessibilityTypes::Event type) {
161 // Get the profile associated with this view. If it's not found, use 136 // Get the profile associated with this view. If it's not found, use
162 // the most recent profile where accessibility events were sent, or 137 // the most recent profile where accessibility events were sent, or
163 // the default profile. 138 // the default profile.
164 Profile* profile = NULL; 139 Profile* profile = NULL;
165 views::Widget* widget = view->GetWidget(); 140 views::Widget* widget = view->GetWidget();
166 if (widget) { 141 if (widget) {
167 profile = reinterpret_cast<Profile*>( 142 profile = reinterpret_cast<Profile*>(
168 widget->GetNativeWindowProperty(Profile::kProfileKey)); 143 widget->GetNativeWindowProperty(Profile::kProfileKey));
169 } 144 }
170 if (!profile) 145 if (!profile)
171 profile = most_recent_profile_; 146 profile = most_recent_profile_;
172 if (!profile) { 147 if (!profile) {
173 if (g_browser_process->profile_manager()) 148 if (g_browser_process->profile_manager())
174 profile = g_browser_process->profile_manager()->GetLastUsedProfile(); 149 profile = g_browser_process->profile_manager()->GetLastUsedProfile();
175 } 150 }
176 if (!profile) { 151 if (!profile) {
177 LOG(WARNING) << "Accessibility notification but no profile"; 152 LOG(WARNING) << "Accessibility notification but no profile";
178 return; 153 return;
179 } 154 }
180 155
181 most_recent_profile_ = profile; 156 most_recent_profile_ = profile;
182 157
183 if (type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_OPENED || 158 if (type == ui::AccessibilityTypes::EVENT_MENUSTART ||
184 type == chrome::NOTIFICATION_ACCESSIBILITY_MENU_CLOSED) { 159 type == ui::AccessibilityTypes::EVENT_MENUPOPUPSTART ||
160 type == ui::AccessibilityTypes::EVENT_MENUEND ||
161 type == ui::AccessibilityTypes::EVENT_MENUPOPUPEND) {
185 SendMenuNotification(view, type, profile); 162 SendMenuNotification(view, type, profile);
186 return; 163 return;
187 } 164 }
188 165
189 ui::AccessibleViewState state; 166 ui::AccessibleViewState state;
190 view->GetAccessibleState(&state); 167 view->GetAccessibleState(&state);
191 168
192 switch (state.role) { 169 switch (state.role) {
193 case ui::AccessibilityTypes::ROLE_ALERT: 170 case ui::AccessibilityTypes::ROLE_ALERT:
194 case ui::AccessibilityTypes::ROLE_WINDOW: 171 case ui::AccessibilityTypes::ROLE_WINDOW:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 default: 204 default:
228 // If this is encountered, please file a bug with the role that wasn't 205 // If this is encountered, please file a bug with the role that wasn't
229 // caught so we can add accessibility extension API support. 206 // caught so we can add accessibility extension API support.
230 NOTREACHED(); 207 NOTREACHED();
231 } 208 }
232 } 209 }
233 210
234 // static 211 // static
235 void AccessibilityEventRouterViews::SendButtonNotification( 212 void AccessibilityEventRouterViews::SendButtonNotification(
236 views::View* view, 213 views::View* view,
237 int type, 214 ui::AccessibilityTypes::Event type,
238 Profile* profile) { 215 Profile* profile) {
239 AccessibilityButtonInfo info( 216 AccessibilityButtonInfo info(
240 profile, GetViewName(view), GetViewContext(view)); 217 profile, GetViewName(view), GetViewContext(view));
241 SendAccessibilityNotification(type, &info); 218 SendControlAccessibilityNotification(type, &info);
242 } 219 }
243 220
244 // static 221 // static
245 void AccessibilityEventRouterViews::SendLinkNotification( 222 void AccessibilityEventRouterViews::SendLinkNotification(
246 views::View* view, 223 views::View* view,
247 int type, 224 ui::AccessibilityTypes::Event type,
248 Profile* profile) { 225 Profile* profile) {
249 AccessibilityLinkInfo info(profile, GetViewName(view), GetViewContext(view)); 226 AccessibilityLinkInfo info(profile, GetViewName(view), GetViewContext(view));
250 SendAccessibilityNotification(type, &info); 227 SendControlAccessibilityNotification(type, &info);
251 } 228 }
252 229
253 // static 230 // static
254 void AccessibilityEventRouterViews::SendMenuNotification( 231 void AccessibilityEventRouterViews::SendMenuNotification(
255 views::View* view, 232 views::View* view,
256 int type, 233 ui::AccessibilityTypes::Event type,
257 Profile* profile) { 234 Profile* profile) {
258 AccessibilityMenuInfo info(profile, GetViewName(view)); 235 AccessibilityMenuInfo info(profile, GetViewName(view));
259 SendAccessibilityNotification(type, &info); 236 SendMenuAccessibilityNotification(type, &info);
260 } 237 }
261 238
262 // static 239 // static
263 void AccessibilityEventRouterViews::SendMenuItemNotification( 240 void AccessibilityEventRouterViews::SendMenuItemNotification(
264 views::View* view, 241 views::View* view,
265 int type, 242 ui::AccessibilityTypes::Event type,
266 Profile* profile) { 243 Profile* profile) {
267 std::string name = GetViewName(view); 244 std::string name = GetViewName(view);
268 std::string context = GetViewContext(view); 245 std::string context = GetViewContext(view);
269 246
270 bool has_submenu = false; 247 bool has_submenu = false;
271 int index = -1; 248 int index = -1;
272 int count = -1; 249 int count = -1;
273 250
274 if (!strcmp(view->GetClassName(), views::MenuItemView::kViewClassName)) 251 if (!strcmp(view->GetClassName(), views::MenuItemView::kViewClassName))
275 has_submenu = static_cast<views::MenuItemView*>(view)->HasSubmenu(); 252 has_submenu = static_cast<views::MenuItemView*>(view)->HasSubmenu();
276 253
277 views::View* parent_menu = view->parent(); 254 views::View* parent_menu = view->parent();
278 while (parent_menu != NULL && strcmp(parent_menu->GetClassName(), 255 while (parent_menu != NULL && strcmp(parent_menu->GetClassName(),
279 views::SubmenuView::kViewClassName)) { 256 views::SubmenuView::kViewClassName)) {
280 parent_menu = parent_menu->parent(); 257 parent_menu = parent_menu->parent();
281 } 258 }
282 if (parent_menu) { 259 if (parent_menu) {
283 count = 0; 260 count = 0;
284 RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count); 261 RecursiveGetMenuItemIndexAndCount(parent_menu, view, &index, &count);
285 } 262 }
286 263
287 AccessibilityMenuItemInfo info( 264 AccessibilityMenuItemInfo info(
288 profile, name, context, has_submenu, index, count); 265 profile, name, context, has_submenu, index, count);
289 SendAccessibilityNotification(type, &info); 266 SendControlAccessibilityNotification(type, &info);
290 } 267 }
291 268
292 // static 269 // static
293 void AccessibilityEventRouterViews::SendTextfieldNotification( 270 void AccessibilityEventRouterViews::SendTextfieldNotification(
294 views::View* view, 271 views::View* view,
295 int type, 272 ui::AccessibilityTypes::Event type,
296 Profile* profile) { 273 Profile* profile) {
297 ui::AccessibleViewState state; 274 ui::AccessibleViewState state;
298 view->GetAccessibleState(&state); 275 view->GetAccessibleState(&state);
299 std::string name = UTF16ToUTF8(state.name); 276 std::string name = UTF16ToUTF8(state.name);
300 std::string context = GetViewContext(view); 277 std::string context = GetViewContext(view);
301 bool password = 278 bool password =
302 (state.state & ui::AccessibilityTypes::STATE_PROTECTED) != 0; 279 (state.state & ui::AccessibilityTypes::STATE_PROTECTED) != 0;
303 AccessibilityTextBoxInfo info(profile, name, context, password); 280 AccessibilityTextBoxInfo info(profile, name, context, password);
304 std::string value = UTF16ToUTF8(state.value); 281 std::string value = UTF16ToUTF8(state.value);
305 info.SetValue(value, state.selection_start, state.selection_end); 282 info.SetValue(value, state.selection_start, state.selection_end);
306 SendAccessibilityNotification(type, &info); 283 SendControlAccessibilityNotification(type, &info);
307 } 284 }
308 285
309 // static 286 // static
310 void AccessibilityEventRouterViews::SendComboboxNotification( 287 void AccessibilityEventRouterViews::SendComboboxNotification(
311 views::View* view, 288 views::View* view,
312 int type, 289 ui::AccessibilityTypes::Event type,
313 Profile* profile) { 290 Profile* profile) {
314 ui::AccessibleViewState state; 291 ui::AccessibleViewState state;
315 view->GetAccessibleState(&state); 292 view->GetAccessibleState(&state);
316 std::string name = UTF16ToUTF8(state.name); 293 std::string name = UTF16ToUTF8(state.name);
317 std::string value = UTF16ToUTF8(state.value); 294 std::string value = UTF16ToUTF8(state.value);
318 std::string context = GetViewContext(view); 295 std::string context = GetViewContext(view);
319 AccessibilityComboBoxInfo info( 296 AccessibilityComboBoxInfo info(
320 profile, name, context, value, state.index, state.count); 297 profile, name, context, value, state.index, state.count);
321 SendAccessibilityNotification(type, &info); 298 SendControlAccessibilityNotification(type, &info);
322 } 299 }
323 300
324 // static 301 // static
325 void AccessibilityEventRouterViews::SendCheckboxNotification( 302 void AccessibilityEventRouterViews::SendCheckboxNotification(
326 views::View* view, 303 views::View* view,
327 int type, 304 ui::AccessibilityTypes::Event type,
328 Profile* profile) { 305 Profile* profile) {
329 ui::AccessibleViewState state; 306 ui::AccessibleViewState state;
330 view->GetAccessibleState(&state); 307 view->GetAccessibleState(&state);
331 std::string name = UTF16ToUTF8(state.name); 308 std::string name = UTF16ToUTF8(state.name);
332 std::string value = UTF16ToUTF8(state.value); 309 std::string value = UTF16ToUTF8(state.value);
333 std::string context = GetViewContext(view); 310 std::string context = GetViewContext(view);
334 AccessibilityCheckboxInfo info( 311 AccessibilityCheckboxInfo info(
335 profile, 312 profile,
336 name, 313 name,
337 context, 314 context,
338 state.state == ui::AccessibilityTypes::STATE_CHECKED); 315 state.state == ui::AccessibilityTypes::STATE_CHECKED);
339 SendAccessibilityNotification(type, &info); 316 SendControlAccessibilityNotification(type, &info);
340 } 317 }
341 318
342 // static 319 // static
343 void AccessibilityEventRouterViews::SendWindowNotification( 320 void AccessibilityEventRouterViews::SendWindowNotification(
344 views::View* view, 321 views::View* view,
345 int type, 322 ui::AccessibilityTypes::Event type,
346 Profile* profile) { 323 Profile* profile) {
347 ui::AccessibleViewState state; 324 ui::AccessibleViewState state;
348 view->GetAccessibleState(&state); 325 view->GetAccessibleState(&state);
349 std::string window_text; 326 std::string window_text;
350 327
351 // If it's an alert, try to get the text from the contents of the 328 // If it's an alert, try to get the text from the contents of the
352 // static text, not the window title. 329 // static text, not the window title.
353 if (state.role == ui::AccessibilityTypes::ROLE_ALERT) 330 if (state.role == ui::AccessibilityTypes::ROLE_ALERT)
354 window_text = RecursiveGetStaticText(view); 331 window_text = RecursiveGetStaticText(view);
355 332
356 // Otherwise get it from the window's accessible name. 333 // Otherwise get it from the window's accessible name.
357 if (window_text.empty()) 334 if (window_text.empty())
358 window_text = UTF16ToUTF8(state.name); 335 window_text = UTF16ToUTF8(state.name);
359 336
360 AccessibilityWindowInfo info(profile, window_text); 337 AccessibilityWindowInfo info(profile, window_text);
361 SendAccessibilityNotification(type, &info); 338 SendWindowAccessibilityNotification(type, &info);
362 } 339 }
363 340
364 // static 341 // static
365 void AccessibilityEventRouterViews::SendSliderNotification( 342 void AccessibilityEventRouterViews::SendSliderNotification(
366 views::View* view, 343 views::View* view,
367 int type, 344 ui::AccessibilityTypes::Event type,
368 Profile* profile) { 345 Profile* profile) {
369 ui::AccessibleViewState state; 346 ui::AccessibleViewState state;
370 view->GetAccessibleState(&state); 347 view->GetAccessibleState(&state);
371 348
372 std::string name = UTF16ToUTF8(state.name); 349 std::string name = UTF16ToUTF8(state.name);
373 std::string value = UTF16ToUTF8(state.value); 350 std::string value = UTF16ToUTF8(state.value);
374 std::string context = GetViewContext(view); 351 std::string context = GetViewContext(view);
375 AccessibilitySliderInfo info( 352 AccessibilitySliderInfo info(
376 profile, 353 profile,
377 name, 354 name,
378 context, 355 context,
379 value); 356 value);
380 SendAccessibilityNotification(type, &info); 357 SendControlAccessibilityNotification(type, &info);
381 } 358 }
382 359
383 // static 360 // static
384 std::string AccessibilityEventRouterViews::GetViewName(views::View* view) { 361 std::string AccessibilityEventRouterViews::GetViewName(views::View* view) {
385 ui::AccessibleViewState state; 362 ui::AccessibleViewState state;
386 view->GetAccessibleState(&state); 363 view->GetAccessibleState(&state);
387 return UTF16ToUTF8(state.name); 364 return UTF16ToUTF8(state.name);
388 } 365 }
389 366
390 // static 367 // static
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 return UTF16ToUTF8(state.name); 476 return UTF16ToUTF8(state.name);
500 477
501 for (int i = 0; i < view->child_count(); ++i) { 478 for (int i = 0; i < view->child_count(); ++i) {
502 views::View* child = view->child_at(i); 479 views::View* child = view->child_at(i);
503 std::string result = RecursiveGetStaticText(child); 480 std::string result = RecursiveGetStaticText(child);
504 if (!result.empty()) 481 if (!result.empty())
505 return result; 482 return result;
506 } 483 }
507 return std::string(); 484 return std::string();
508 } 485 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698