Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "WinIMEHandler.h" |
michael@0 | 7 | |
michael@0 | 8 | #include "mozilla/Preferences.h" |
michael@0 | 9 | #include "nsIMM32Handler.h" |
michael@0 | 10 | #include "nsWindowDefs.h" |
michael@0 | 11 | |
michael@0 | 12 | #ifdef NS_ENABLE_TSF |
michael@0 | 13 | #include "nsTextStore.h" |
michael@0 | 14 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 15 | |
michael@0 | 16 | #include "nsWindow.h" |
michael@0 | 17 | #include "WinUtils.h" |
michael@0 | 18 | |
michael@0 | 19 | namespace mozilla { |
michael@0 | 20 | namespace widget { |
michael@0 | 21 | |
michael@0 | 22 | /****************************************************************************** |
michael@0 | 23 | * IMEHandler |
michael@0 | 24 | ******************************************************************************/ |
michael@0 | 25 | |
michael@0 | 26 | #ifdef NS_ENABLE_TSF |
michael@0 | 27 | bool IMEHandler::sIsInTSFMode = false; |
michael@0 | 28 | bool IMEHandler::sIsIMMEnabled = true; |
michael@0 | 29 | bool IMEHandler::sPluginHasFocus = false; |
michael@0 | 30 | decltype(SetInputScopes)* IMEHandler::sSetInputScopes = nullptr; |
michael@0 | 31 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 32 | |
michael@0 | 33 | // static |
michael@0 | 34 | void |
michael@0 | 35 | IMEHandler::Initialize() |
michael@0 | 36 | { |
michael@0 | 37 | #ifdef NS_ENABLE_TSF |
michael@0 | 38 | nsTextStore::Initialize(); |
michael@0 | 39 | sIsInTSFMode = nsTextStore::IsInTSFMode(); |
michael@0 | 40 | sIsIMMEnabled = |
michael@0 | 41 | !sIsInTSFMode || Preferences::GetBool("intl.tsf.support_imm", true); |
michael@0 | 42 | if (!sIsInTSFMode) { |
michael@0 | 43 | // When full nsTextStore is not available, try to use SetInputScopes API |
michael@0 | 44 | // to enable at least InputScope. Use GET_MODULE_HANDLE_EX_FLAG_PIN to |
michael@0 | 45 | // ensure that msctf.dll will not be unloaded. |
michael@0 | 46 | HMODULE module = nullptr; |
michael@0 | 47 | if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, L"msctf.dll", |
michael@0 | 48 | &module)) { |
michael@0 | 49 | sSetInputScopes = reinterpret_cast<decltype(SetInputScopes)*>( |
michael@0 | 50 | GetProcAddress(module, "SetInputScopes")); |
michael@0 | 51 | } |
michael@0 | 52 | } |
michael@0 | 53 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 54 | |
michael@0 | 55 | nsIMM32Handler::Initialize(); |
michael@0 | 56 | } |
michael@0 | 57 | |
michael@0 | 58 | // static |
michael@0 | 59 | void |
michael@0 | 60 | IMEHandler::Terminate() |
michael@0 | 61 | { |
michael@0 | 62 | #ifdef NS_ENABLE_TSF |
michael@0 | 63 | if (sIsInTSFMode) { |
michael@0 | 64 | nsTextStore::Terminate(); |
michael@0 | 65 | sIsInTSFMode = false; |
michael@0 | 66 | } |
michael@0 | 67 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 68 | |
michael@0 | 69 | nsIMM32Handler::Terminate(); |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | // static |
michael@0 | 73 | void* |
michael@0 | 74 | IMEHandler::GetNativeData(uint32_t aDataType) |
michael@0 | 75 | { |
michael@0 | 76 | #ifdef NS_ENABLE_TSF |
michael@0 | 77 | void* result = nsTextStore::GetNativeData(aDataType); |
michael@0 | 78 | if (!result || !(*(static_cast<void**>(result)))) { |
michael@0 | 79 | return nullptr; |
michael@0 | 80 | } |
michael@0 | 81 | // XXX During the TSF module test, sIsInTSFMode must be true. After that, |
michael@0 | 82 | // the value should be restored but currently, there is no way for that. |
michael@0 | 83 | // When the TSF test is enabled again, we need to fix this. Perhaps, |
michael@0 | 84 | // sending a message can fix this. |
michael@0 | 85 | sIsInTSFMode = true; |
michael@0 | 86 | return result; |
michael@0 | 87 | #else // #ifdef NS_ENABLE_TSF |
michael@0 | 88 | return nullptr; |
michael@0 | 89 | #endif // #ifdef NS_ENABLE_TSF #else |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | // static |
michael@0 | 93 | bool |
michael@0 | 94 | IMEHandler::ProcessRawKeyMessage(const MSG& aMsg) |
michael@0 | 95 | { |
michael@0 | 96 | #ifdef NS_ENABLE_TSF |
michael@0 | 97 | if (IsTSFAvailable()) { |
michael@0 | 98 | return nsTextStore::ProcessRawKeyMessage(aMsg); |
michael@0 | 99 | } |
michael@0 | 100 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 101 | return false; // noting to do in IMM mode. |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | // static |
michael@0 | 105 | bool |
michael@0 | 106 | IMEHandler::ProcessMessage(nsWindow* aWindow, UINT aMessage, |
michael@0 | 107 | WPARAM& aWParam, LPARAM& aLParam, |
michael@0 | 108 | MSGResult& aResult) |
michael@0 | 109 | { |
michael@0 | 110 | #ifdef NS_ENABLE_TSF |
michael@0 | 111 | if (IsTSFAvailable()) { |
michael@0 | 112 | nsTextStore::ProcessMessage(aWindow, aMessage, aWParam, aLParam, aResult); |
michael@0 | 113 | if (aResult.mConsumed) { |
michael@0 | 114 | return true; |
michael@0 | 115 | } |
michael@0 | 116 | // If we don't support IMM in TSF mode, we don't use nsIMM32Handler. |
michael@0 | 117 | if (!sIsIMMEnabled) { |
michael@0 | 118 | return false; |
michael@0 | 119 | } |
michael@0 | 120 | // IME isn't implemented with IMM, nsIMM32Handler shouldn't handle any |
michael@0 | 121 | // messages. |
michael@0 | 122 | if (!nsTextStore::IsIMM_IME()) { |
michael@0 | 123 | return false; |
michael@0 | 124 | } |
michael@0 | 125 | } |
michael@0 | 126 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 127 | |
michael@0 | 128 | return nsIMM32Handler::ProcessMessage(aWindow, aMessage, aWParam, aLParam, |
michael@0 | 129 | aResult); |
michael@0 | 130 | } |
michael@0 | 131 | |
michael@0 | 132 | // static |
michael@0 | 133 | bool |
michael@0 | 134 | IMEHandler::IsComposing() |
michael@0 | 135 | { |
michael@0 | 136 | #ifdef NS_ENABLE_TSF |
michael@0 | 137 | if (IsTSFAvailable()) { |
michael@0 | 138 | return nsTextStore::IsComposing(); |
michael@0 | 139 | } |
michael@0 | 140 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 141 | |
michael@0 | 142 | return nsIMM32Handler::IsComposing(); |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | // static |
michael@0 | 146 | bool |
michael@0 | 147 | IMEHandler::IsComposingOn(nsWindow* aWindow) |
michael@0 | 148 | { |
michael@0 | 149 | #ifdef NS_ENABLE_TSF |
michael@0 | 150 | if (IsTSFAvailable()) { |
michael@0 | 151 | return nsTextStore::IsComposingOn(aWindow); |
michael@0 | 152 | } |
michael@0 | 153 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 154 | |
michael@0 | 155 | return nsIMM32Handler::IsComposingOn(aWindow); |
michael@0 | 156 | } |
michael@0 | 157 | |
michael@0 | 158 | // static |
michael@0 | 159 | nsresult |
michael@0 | 160 | IMEHandler::NotifyIME(nsWindow* aWindow, |
michael@0 | 161 | const IMENotification& aIMENotification) |
michael@0 | 162 | { |
michael@0 | 163 | #ifdef NS_ENABLE_TSF |
michael@0 | 164 | if (IsTSFAvailable()) { |
michael@0 | 165 | switch (aIMENotification.mMessage) { |
michael@0 | 166 | case NOTIFY_IME_OF_SELECTION_CHANGE: |
michael@0 | 167 | return nsTextStore::OnSelectionChange(); |
michael@0 | 168 | case NOTIFY_IME_OF_TEXT_CHANGE: |
michael@0 | 169 | return nsTextStore::OnTextChange(aIMENotification); |
michael@0 | 170 | case NOTIFY_IME_OF_FOCUS: |
michael@0 | 171 | return nsTextStore::OnFocusChange(true, aWindow, |
michael@0 | 172 | aWindow->GetInputContext().mIMEState.mEnabled); |
michael@0 | 173 | case NOTIFY_IME_OF_BLUR: |
michael@0 | 174 | return nsTextStore::OnFocusChange(false, aWindow, |
michael@0 | 175 | aWindow->GetInputContext().mIMEState.mEnabled); |
michael@0 | 176 | case REQUEST_TO_COMMIT_COMPOSITION: |
michael@0 | 177 | if (nsTextStore::IsComposingOn(aWindow)) { |
michael@0 | 178 | nsTextStore::CommitComposition(false); |
michael@0 | 179 | } |
michael@0 | 180 | return NS_OK; |
michael@0 | 181 | case REQUEST_TO_CANCEL_COMPOSITION: |
michael@0 | 182 | if (nsTextStore::IsComposingOn(aWindow)) { |
michael@0 | 183 | nsTextStore::CommitComposition(true); |
michael@0 | 184 | } |
michael@0 | 185 | return NS_OK; |
michael@0 | 186 | case NOTIFY_IME_OF_POSITION_CHANGE: |
michael@0 | 187 | return nsTextStore::OnLayoutChange(); |
michael@0 | 188 | default: |
michael@0 | 189 | return NS_ERROR_NOT_IMPLEMENTED; |
michael@0 | 190 | } |
michael@0 | 191 | } |
michael@0 | 192 | #endif //NS_ENABLE_TSF |
michael@0 | 193 | |
michael@0 | 194 | switch (aIMENotification.mMessage) { |
michael@0 | 195 | case REQUEST_TO_COMMIT_COMPOSITION: |
michael@0 | 196 | nsIMM32Handler::CommitComposition(aWindow); |
michael@0 | 197 | return NS_OK; |
michael@0 | 198 | case REQUEST_TO_CANCEL_COMPOSITION: |
michael@0 | 199 | nsIMM32Handler::CancelComposition(aWindow); |
michael@0 | 200 | return NS_OK; |
michael@0 | 201 | case NOTIFY_IME_OF_POSITION_CHANGE: |
michael@0 | 202 | case NOTIFY_IME_OF_COMPOSITION_UPDATE: |
michael@0 | 203 | nsIMM32Handler::OnUpdateComposition(aWindow); |
michael@0 | 204 | return NS_OK; |
michael@0 | 205 | #ifdef NS_ENABLE_TSF |
michael@0 | 206 | case NOTIFY_IME_OF_BLUR: |
michael@0 | 207 | // If a plugin gets focus while TSF has focus, we need to notify TSF of |
michael@0 | 208 | // the blur. |
michael@0 | 209 | if (nsTextStore::ThinksHavingFocus()) { |
michael@0 | 210 | return nsTextStore::OnFocusChange(false, aWindow, |
michael@0 | 211 | aWindow->GetInputContext().mIMEState.mEnabled); |
michael@0 | 212 | } |
michael@0 | 213 | return NS_ERROR_NOT_IMPLEMENTED; |
michael@0 | 214 | #endif //NS_ENABLE_TSF |
michael@0 | 215 | default: |
michael@0 | 216 | return NS_ERROR_NOT_IMPLEMENTED; |
michael@0 | 217 | } |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | // static |
michael@0 | 221 | nsIMEUpdatePreference |
michael@0 | 222 | IMEHandler::GetUpdatePreference() |
michael@0 | 223 | { |
michael@0 | 224 | #ifdef NS_ENABLE_TSF |
michael@0 | 225 | if (IsTSFAvailable()) { |
michael@0 | 226 | return nsTextStore::GetIMEUpdatePreference(); |
michael@0 | 227 | } |
michael@0 | 228 | #endif //NS_ENABLE_TSF |
michael@0 | 229 | |
michael@0 | 230 | return nsIMM32Handler::GetIMEUpdatePreference(); |
michael@0 | 231 | } |
michael@0 | 232 | |
michael@0 | 233 | // static |
michael@0 | 234 | bool |
michael@0 | 235 | IMEHandler::GetOpenState(nsWindow* aWindow) |
michael@0 | 236 | { |
michael@0 | 237 | #ifdef NS_ENABLE_TSF |
michael@0 | 238 | if (IsTSFAvailable()) { |
michael@0 | 239 | return nsTextStore::GetIMEOpenState(); |
michael@0 | 240 | } |
michael@0 | 241 | #endif //NS_ENABLE_TSF |
michael@0 | 242 | |
michael@0 | 243 | nsIMEContext IMEContext(aWindow->GetWindowHandle()); |
michael@0 | 244 | return IMEContext.GetOpenState(); |
michael@0 | 245 | } |
michael@0 | 246 | |
michael@0 | 247 | // static |
michael@0 | 248 | void |
michael@0 | 249 | IMEHandler::OnDestroyWindow(nsWindow* aWindow) |
michael@0 | 250 | { |
michael@0 | 251 | #ifdef NS_ENABLE_TSF |
michael@0 | 252 | // We need to do nothing here for TSF. Just restore the default context |
michael@0 | 253 | // if it's been disassociated. |
michael@0 | 254 | if (!sIsInTSFMode) { |
michael@0 | 255 | // MSDN says we need to set IS_DEFAULT to avoid memory leak when we use |
michael@0 | 256 | // SetInputScopes API. Use an empty string to do this. |
michael@0 | 257 | SetInputScopeForIMM32(aWindow, EmptyString()); |
michael@0 | 258 | } |
michael@0 | 259 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 260 | AssociateIMEContext(aWindow, true); |
michael@0 | 261 | } |
michael@0 | 262 | |
michael@0 | 263 | // static |
michael@0 | 264 | void |
michael@0 | 265 | IMEHandler::SetInputContext(nsWindow* aWindow, |
michael@0 | 266 | InputContext& aInputContext, |
michael@0 | 267 | const InputContextAction& aAction) |
michael@0 | 268 | { |
michael@0 | 269 | // FYI: If there is no composition, this call will do nothing. |
michael@0 | 270 | NotifyIME(aWindow, IMENotification(REQUEST_TO_COMMIT_COMPOSITION)); |
michael@0 | 271 | |
michael@0 | 272 | const InputContext& oldInputContext = aWindow->GetInputContext(); |
michael@0 | 273 | |
michael@0 | 274 | // Assume that SetInputContext() is called only when aWindow has focus. |
michael@0 | 275 | sPluginHasFocus = (aInputContext.mIMEState.mEnabled == IMEState::PLUGIN); |
michael@0 | 276 | |
michael@0 | 277 | bool enable = WinUtils::IsIMEEnabled(aInputContext); |
michael@0 | 278 | bool adjustOpenState = (enable && |
michael@0 | 279 | aInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE); |
michael@0 | 280 | bool open = (adjustOpenState && |
michael@0 | 281 | aInputContext.mIMEState.mOpen == IMEState::OPEN); |
michael@0 | 282 | |
michael@0 | 283 | aInputContext.mNativeIMEContext = nullptr; |
michael@0 | 284 | |
michael@0 | 285 | #ifdef NS_ENABLE_TSF |
michael@0 | 286 | // Note that even while a plugin has focus, we need to notify TSF of that. |
michael@0 | 287 | if (sIsInTSFMode) { |
michael@0 | 288 | nsTextStore::SetInputContext(aWindow, aInputContext, aAction); |
michael@0 | 289 | if (IsTSFAvailable()) { |
michael@0 | 290 | aInputContext.mNativeIMEContext = nsTextStore::GetTextStore(); |
michael@0 | 291 | if (sIsIMMEnabled) { |
michael@0 | 292 | // Associate IME context for IMM-IMEs. |
michael@0 | 293 | AssociateIMEContext(aWindow, enable); |
michael@0 | 294 | } else if (oldInputContext.mIMEState.mEnabled == IMEState::PLUGIN) { |
michael@0 | 295 | // Disassociate the IME context from the window when plugin loses focus |
michael@0 | 296 | // in pure TSF mode. |
michael@0 | 297 | AssociateIMEContext(aWindow, false); |
michael@0 | 298 | } |
michael@0 | 299 | if (adjustOpenState) { |
michael@0 | 300 | nsTextStore::SetIMEOpenState(open); |
michael@0 | 301 | } |
michael@0 | 302 | return; |
michael@0 | 303 | } |
michael@0 | 304 | } else { |
michael@0 | 305 | // Set at least InputScope even when TextStore is not available. |
michael@0 | 306 | SetInputScopeForIMM32(aWindow, aInputContext.mHTMLInputType); |
michael@0 | 307 | } |
michael@0 | 308 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 309 | |
michael@0 | 310 | AssociateIMEContext(aWindow, enable); |
michael@0 | 311 | |
michael@0 | 312 | nsIMEContext IMEContext(aWindow->GetWindowHandle()); |
michael@0 | 313 | if (adjustOpenState) { |
michael@0 | 314 | IMEContext.SetOpenState(open); |
michael@0 | 315 | } |
michael@0 | 316 | |
michael@0 | 317 | if (aInputContext.mNativeIMEContext) { |
michael@0 | 318 | return; |
michael@0 | 319 | } |
michael@0 | 320 | |
michael@0 | 321 | // The old InputContext must store the default IMC or old TextStore. |
michael@0 | 322 | // When IME context is disassociated from the window, use it. |
michael@0 | 323 | aInputContext.mNativeIMEContext = enable ? |
michael@0 | 324 | static_cast<void*>(IMEContext.get()) : oldInputContext.mNativeIMEContext; |
michael@0 | 325 | } |
michael@0 | 326 | |
michael@0 | 327 | // static |
michael@0 | 328 | void |
michael@0 | 329 | IMEHandler::AssociateIMEContext(nsWindow* aWindow, bool aEnable) |
michael@0 | 330 | { |
michael@0 | 331 | nsIMEContext IMEContext(aWindow->GetWindowHandle()); |
michael@0 | 332 | if (aEnable) { |
michael@0 | 333 | IMEContext.AssociateDefaultContext(); |
michael@0 | 334 | return; |
michael@0 | 335 | } |
michael@0 | 336 | // Don't disassociate the context after the window is destroyed. |
michael@0 | 337 | if (aWindow->Destroyed()) { |
michael@0 | 338 | return; |
michael@0 | 339 | } |
michael@0 | 340 | IMEContext.Disassociate(); |
michael@0 | 341 | } |
michael@0 | 342 | |
michael@0 | 343 | // static |
michael@0 | 344 | void |
michael@0 | 345 | IMEHandler::InitInputContext(nsWindow* aWindow, InputContext& aInputContext) |
michael@0 | 346 | { |
michael@0 | 347 | // For a11y, the default enabled state should be 'enabled'. |
michael@0 | 348 | aInputContext.mIMEState.mEnabled = IMEState::ENABLED; |
michael@0 | 349 | |
michael@0 | 350 | #ifdef NS_ENABLE_TSF |
michael@0 | 351 | if (sIsInTSFMode) { |
michael@0 | 352 | nsTextStore::SetInputContext(aWindow, aInputContext, |
michael@0 | 353 | InputContextAction(InputContextAction::CAUSE_UNKNOWN, |
michael@0 | 354 | InputContextAction::GOT_FOCUS)); |
michael@0 | 355 | aInputContext.mNativeIMEContext = nsTextStore::GetTextStore(); |
michael@0 | 356 | MOZ_ASSERT(aInputContext.mNativeIMEContext); |
michael@0 | 357 | // IME context isn't necessary in pure TSF mode. |
michael@0 | 358 | if (!sIsIMMEnabled) { |
michael@0 | 359 | AssociateIMEContext(aWindow, false); |
michael@0 | 360 | } |
michael@0 | 361 | return; |
michael@0 | 362 | } |
michael@0 | 363 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 364 | |
michael@0 | 365 | // NOTE: mNativeIMEContext may be null if IMM module isn't installed. |
michael@0 | 366 | nsIMEContext IMEContext(aWindow->GetWindowHandle()); |
michael@0 | 367 | aInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get()); |
michael@0 | 368 | MOZ_ASSERT(aInputContext.mNativeIMEContext || !CurrentKeyboardLayoutHasIME()); |
michael@0 | 369 | // If no IME context is available, we should set the widget's pointer since |
michael@0 | 370 | // nullptr indicates there is only one context per process on the platform. |
michael@0 | 371 | if (!aInputContext.mNativeIMEContext) { |
michael@0 | 372 | aInputContext.mNativeIMEContext = static_cast<void*>(aWindow); |
michael@0 | 373 | } |
michael@0 | 374 | } |
michael@0 | 375 | |
michael@0 | 376 | #ifdef DEBUG |
michael@0 | 377 | // static |
michael@0 | 378 | bool |
michael@0 | 379 | IMEHandler::CurrentKeyboardLayoutHasIME() |
michael@0 | 380 | { |
michael@0 | 381 | #ifdef NS_ENABLE_TSF |
michael@0 | 382 | if (sIsInTSFMode) { |
michael@0 | 383 | return nsTextStore::CurrentKeyboardLayoutHasIME(); |
michael@0 | 384 | } |
michael@0 | 385 | #endif // #ifdef NS_ENABLE_TSF |
michael@0 | 386 | |
michael@0 | 387 | return nsIMM32Handler::IsIMEAvailable(); |
michael@0 | 388 | } |
michael@0 | 389 | #endif // #ifdef DEBUG |
michael@0 | 390 | |
michael@0 | 391 | // static |
michael@0 | 392 | void |
michael@0 | 393 | IMEHandler::SetInputScopeForIMM32(nsWindow* aWindow, |
michael@0 | 394 | const nsAString& aHTMLInputType) |
michael@0 | 395 | { |
michael@0 | 396 | if (sIsInTSFMode || !sSetInputScopes || aWindow->Destroyed()) { |
michael@0 | 397 | return; |
michael@0 | 398 | } |
michael@0 | 399 | UINT arraySize = 0; |
michael@0 | 400 | const InputScope* scopes = nullptr; |
michael@0 | 401 | // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html |
michael@0 | 402 | if (aHTMLInputType.IsEmpty() || aHTMLInputType.EqualsLiteral("text")) { |
michael@0 | 403 | static const InputScope inputScopes[] = { IS_DEFAULT }; |
michael@0 | 404 | scopes = &inputScopes[0]; |
michael@0 | 405 | arraySize = ArrayLength(inputScopes); |
michael@0 | 406 | } else if (aHTMLInputType.EqualsLiteral("url")) { |
michael@0 | 407 | static const InputScope inputScopes[] = { IS_URL }; |
michael@0 | 408 | scopes = &inputScopes[0]; |
michael@0 | 409 | arraySize = ArrayLength(inputScopes); |
michael@0 | 410 | } else if (aHTMLInputType.EqualsLiteral("search")) { |
michael@0 | 411 | static const InputScope inputScopes[] = { IS_SEARCH }; |
michael@0 | 412 | scopes = &inputScopes[0]; |
michael@0 | 413 | arraySize = ArrayLength(inputScopes); |
michael@0 | 414 | } else if (aHTMLInputType.EqualsLiteral("email")) { |
michael@0 | 415 | static const InputScope inputScopes[] = { IS_EMAIL_SMTPEMAILADDRESS }; |
michael@0 | 416 | scopes = &inputScopes[0]; |
michael@0 | 417 | arraySize = ArrayLength(inputScopes); |
michael@0 | 418 | } else if (aHTMLInputType.EqualsLiteral("password")) { |
michael@0 | 419 | static const InputScope inputScopes[] = { IS_PASSWORD }; |
michael@0 | 420 | scopes = &inputScopes[0]; |
michael@0 | 421 | arraySize = ArrayLength(inputScopes); |
michael@0 | 422 | } else if (aHTMLInputType.EqualsLiteral("datetime") || |
michael@0 | 423 | aHTMLInputType.EqualsLiteral("datetime-local")) { |
michael@0 | 424 | static const InputScope inputScopes[] = { |
michael@0 | 425 | IS_DATE_FULLDATE, IS_TIME_FULLTIME }; |
michael@0 | 426 | scopes = &inputScopes[0]; |
michael@0 | 427 | arraySize = ArrayLength(inputScopes); |
michael@0 | 428 | } else if (aHTMLInputType.EqualsLiteral("date") || |
michael@0 | 429 | aHTMLInputType.EqualsLiteral("month") || |
michael@0 | 430 | aHTMLInputType.EqualsLiteral("week")) { |
michael@0 | 431 | static const InputScope inputScopes[] = { IS_DATE_FULLDATE }; |
michael@0 | 432 | scopes = &inputScopes[0]; |
michael@0 | 433 | arraySize = ArrayLength(inputScopes); |
michael@0 | 434 | } else if (aHTMLInputType.EqualsLiteral("time")) { |
michael@0 | 435 | static const InputScope inputScopes[] = { IS_TIME_FULLTIME }; |
michael@0 | 436 | scopes = &inputScopes[0]; |
michael@0 | 437 | arraySize = ArrayLength(inputScopes); |
michael@0 | 438 | } else if (aHTMLInputType.EqualsLiteral("tel")) { |
michael@0 | 439 | static const InputScope inputScopes[] = { |
michael@0 | 440 | IS_TELEPHONE_FULLTELEPHONENUMBER, IS_TELEPHONE_LOCALNUMBER }; |
michael@0 | 441 | scopes = &inputScopes[0]; |
michael@0 | 442 | arraySize = ArrayLength(inputScopes); |
michael@0 | 443 | } else if (aHTMLInputType.EqualsLiteral("number")) { |
michael@0 | 444 | static const InputScope inputScopes[] = { IS_NUMBER }; |
michael@0 | 445 | scopes = &inputScopes[0]; |
michael@0 | 446 | arraySize = ArrayLength(inputScopes); |
michael@0 | 447 | } |
michael@0 | 448 | if (scopes && arraySize > 0) { |
michael@0 | 449 | sSetInputScopes(aWindow->GetWindowHandle(), scopes, arraySize, nullptr, 0, |
michael@0 | 450 | nullptr, nullptr); |
michael@0 | 451 | } |
michael@0 | 452 | } |
michael@0 | 453 | |
michael@0 | 454 | } // namespace widget |
michael@0 | 455 | } // namespace mozilla |