OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 3014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3025 ASSERT_EQ(4ul, renders.size()); | 3025 ASSERT_EQ(4ul, renders.size()); |
3026 for (size_t i = 0; i < renders.size(); ++i) { | 3026 for (size_t i = 0; i < renders.size(); ++i) { |
3027 double docStartTime = frame->domWindow()->document()->loader()->timing()
.monotonicTimeToZeroBasedDocumentTime(renderPairs[i].startTime) * 1000.0; | 3027 double docStartTime = frame->domWindow()->document()->loader()->timing()
.monotonicTimeToZeroBasedDocumentTime(renderPairs[i].startTime) * 1000.0; |
3028 ASSERT_DOUBLE_EQ(docStartTime, renders[i]->startTime()); | 3028 ASSERT_DOUBLE_EQ(docStartTime, renders[i]->startTime()); |
3029 double docFinishTime = frame->domWindow()->document()->loader()->timing(
).monotonicTimeToZeroBasedDocumentTime(renderPairs[i].finishTime) * 1000.0; | 3029 double docFinishTime = frame->domWindow()->document()->loader()->timing(
).monotonicTimeToZeroBasedDocumentTime(renderPairs[i].finishTime) * 1000.0; |
3030 double docDuration = docFinishTime - docStartTime; | 3030 double docDuration = docFinishTime - docStartTime; |
3031 ASSERT_DOUBLE_EQ(docDuration, renders[i]->duration()); | 3031 ASSERT_DOUBLE_EQ(docDuration, renders[i]->duration()); |
3032 } | 3032 } |
3033 } | 3033 } |
3034 | 3034 |
| 3035 TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithKeyEventListenersAn
dNonEditableElements) |
| 3036 { |
| 3037 const std::string testFile = "advance_focus_in_form_with_key_event_listeners
.html"; |
| 3038 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c
_str()), WebString::fromUTF8(testFile.c_str())); |
| 3039 WebView* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + testFil
e, true, nullptr); |
| 3040 webViewImpl->setInitialFocus(false); |
| 3041 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame()); |
| 3042 HTMLDocument* document = toHTMLDocument(frame->frame()->document()); |
| 3043 const int defaultTextInputFlags = WebTextInputFlagAutocapitalizeSentences; |
| 3044 |
| 3045 struct FocusedElement { |
| 3046 const char* elementId; |
| 3047 int textInputFlags; |
| 3048 } focusedElements[] = { |
| 3049 {"input1", defaultTextInputFlags | WebTextInputFlagHaveNextFocusableElem
ent}, |
| 3050 {"contenteditable1", WebTextInputFlagHaveNextFocusableElement | WebTextI
nputFlagHavePreviousFocusableElement}, |
| 3051 {"input2", defaultTextInputFlags | WebTextInputFlagHaveNextFocusableElem
ent | WebTextInputFlagHavePreviousFocusableElement | WebTextInputFlagListeningTo
KeyboardEvents}, |
| 3052 {"textarea1", defaultTextInputFlags | WebTextInputFlagHaveNextFocusableE
lement | WebTextInputFlagHavePreviousFocusableElement}, |
| 3053 {"input3", defaultTextInputFlags | WebTextInputFlagHaveNextFocusableElem
ent | WebTextInputFlagHavePreviousFocusableElement}, |
| 3054 {"textarea2", defaultTextInputFlags | WebTextInputFlagHavePreviousFocusa
bleElement}, |
| 3055 }; |
| 3056 |
| 3057 // Forward Navigation in form1 with NEXT |
| 3058 Element* input1 = document->getElementById("input1"); |
| 3059 input1->focus(); |
| 3060 Element* currentFocus = nullptr; |
| 3061 WebTextInputInfo textInputInfo; |
| 3062 for (size_t i = 0; i < WTF_ARRAY_LENGTH(focusedElements); ++i) { |
| 3063 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3064 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3065 textInputInfo = webViewImpl->textInputInfo(); |
| 3066 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3067 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3068 } |
| 3069 // Now focus will stay on previous focus itself, because it has no next |
| 3070 // element. |
| 3071 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3072 |
| 3073 // Backward Navigation in form1 with PREVIOUS |
| 3074 for (size_t i = WTF_ARRAY_LENGTH(focusedElements); i-- > 0;) { |
| 3075 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3076 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3077 textInputInfo = webViewImpl->textInputInfo(); |
| 3078 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3079 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3080 } |
| 3081 // Now focus will stay on previous focus itself, because it has no previous |
| 3082 // element. |
| 3083 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3084 |
| 3085 // Setting a non editable element as focus in form1, and ensuring editable |
| 3086 // navigation is fine in forward and backward. |
| 3087 Element* button1 = document->getElementById("button1"); |
| 3088 button1->focus(); |
| 3089 textInputInfo = webViewImpl->textInputInfo(); |
| 3090 // No Next/Previous element for elements outside form. |
| 3091 EXPECT_EQ(0, textInputInfo.flags); |
| 3092 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3093 Element* contenteditable1 = document->getElementById("contenteditable1"); |
| 3094 EXPECT_EQ(contenteditable1, document->focusedElement()); |
| 3095 button1->focus(); |
| 3096 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3097 EXPECT_EQ(input1, document->focusedElement()); |
| 3098 |
| 3099 Element* anchor1 = document->getElementById("anchor1"); |
| 3100 anchor1->focus(); |
| 3101 textInputInfo = webViewImpl->textInputInfo(); |
| 3102 // No Next/Previous element for elements outside form. |
| 3103 EXPECT_EQ(0, textInputInfo.flags); |
| 3104 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3105 // Since anchor is not a form control element, next/previous element will |
| 3106 // be null, hence focus will stay same as it is. |
| 3107 EXPECT_EQ(anchor1, document->focusedElement()); |
| 3108 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3109 EXPECT_EQ(anchor1, document->focusedElement()); |
| 3110 |
| 3111 // Navigation of elements which is not part of any forms. |
| 3112 Element* textarea3 = document->getElementById("textarea3"); |
| 3113 textarea3->focus(); |
| 3114 textInputInfo = webViewImpl->textInputInfo(); |
| 3115 // No Next/Previous element for elements outside form. |
| 3116 EXPECT_EQ(defaultTextInputFlags, textInputInfo.flags); |
| 3117 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3118 // No Next/Previous element to this element because it's not part of any |
| 3119 // form. Hence focus won't change wrt NEXT/PREVIOUS. |
| 3120 EXPECT_EQ(textarea3, document->focusedElement()); |
| 3121 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3122 EXPECT_EQ(textarea3, document->focusedElement()); |
| 3123 |
| 3124 // Navigation from an element which is part of a form but not an editable |
| 3125 // element. |
| 3126 Element* button2 = document->getElementById("button2"); |
| 3127 button2->focus(); |
| 3128 textInputInfo = webViewImpl->textInputInfo(); |
| 3129 // No Next element for this element, due to last element outside the form. |
| 3130 EXPECT_EQ(0, textInputInfo.flags); |
| 3131 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3132 // No Next element to this element because it's not part of any form. |
| 3133 // Hence focus won't change wrt NEXT. |
| 3134 EXPECT_EQ(button2, document->focusedElement()); |
| 3135 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3136 // Since button is a form control element from form1, ensuring focus is set |
| 3137 // at correct position. |
| 3138 Element* textarea2 = document->getElementById("textarea2"); |
| 3139 EXPECT_EQ(textarea2, document->focusedElement()); |
| 3140 |
| 3141 Element* contenteditable2 = document->getElementById("contenteditable2"); |
| 3142 document->setFocusedElement(contenteditable2); |
| 3143 textInputInfo = webViewImpl->textInputInfo(); |
| 3144 // No Next/Previous element for elements outside form. |
| 3145 EXPECT_EQ(0, textInputInfo.flags); |
| 3146 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3147 // No Next/Previous element to this element because it's not part of any |
| 3148 // form. Hence focus won't change wrt NEXT/PREVIOUS. |
| 3149 EXPECT_EQ(contenteditable2, document->focusedElement()); |
| 3150 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3151 EXPECT_EQ(contenteditable2, document->focusedElement()); |
| 3152 |
| 3153 // Navigation of elements which is having invalid form attribute and hence |
| 3154 // not part of any forms. |
| 3155 Element* textarea4 = document->getElementById("textarea4"); |
| 3156 textarea4->focus(); |
| 3157 textInputInfo = webViewImpl->textInputInfo(); |
| 3158 // No Next/Previous element for elements which is having invalid form |
| 3159 // attribute. |
| 3160 EXPECT_EQ(defaultTextInputFlags, textInputInfo.flags); |
| 3161 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3162 // No Next/Previous element to this element because it's not part of any |
| 3163 // form. Hence focus won't change wrt NEXT/PREVIOUS. |
| 3164 EXPECT_EQ(textarea4, document->focusedElement()); |
| 3165 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3166 EXPECT_EQ(textarea4, document->focusedElement()); |
| 3167 |
| 3168 m_webViewHelper.reset(); |
| 3169 } |
| 3170 |
| 3171 TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithNonEditableNonFormC
ontrolElements) |
| 3172 { |
| 3173 const std::string testFile = "advance_focus_in_form_with_key_event_listeners
.html"; |
| 3174 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c
_str()), WebString::fromUTF8(testFile.c_str())); |
| 3175 WebView* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + testFil
e, true, nullptr); |
| 3176 webViewImpl->setInitialFocus(false); |
| 3177 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame()); |
| 3178 HTMLDocument* document = toHTMLDocument(frame->frame()->document()); |
| 3179 const int defaultTextInputFlags = WebTextInputFlagAutocapitalizeSentences; |
| 3180 |
| 3181 struct FocusedElement { |
| 3182 const char* elementId; |
| 3183 int textInputFlags; |
| 3184 } focusedElements[] = { |
| 3185 {"textarea5", defaultTextInputFlags | WebTextInputFlagListeningToKeyboar
dEvents | WebTextInputFlagHaveNextFocusableElement}, |
| 3186 {"input4", defaultTextInputFlags | WebTextInputFlagListeningToKeyboardEv
ents | WebTextInputFlagHaveNextFocusableElement | WebTextInputFlagHavePreviousFo
cusableElement}, |
| 3187 {"contenteditable3", WebTextInputFlagListeningToKeyboardEvents | WebText
InputFlagHavePreviousFocusableElement}, |
| 3188 }; |
| 3189 |
| 3190 // Forward Navigation in form2 with NEXT |
| 3191 Element* textarea5 = document->getElementById("textarea5"); |
| 3192 textarea5->focus(); |
| 3193 Element* currentFocus = nullptr; |
| 3194 WebTextInputInfo textInputInfo; |
| 3195 for (size_t i = 0; i < WTF_ARRAY_LENGTH(focusedElements); ++i) { |
| 3196 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3197 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3198 textInputInfo = webViewImpl->textInputInfo(); |
| 3199 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3200 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3201 } |
| 3202 // Now focus will stay on previous focus itself, because it has no next |
| 3203 // element. |
| 3204 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3205 |
| 3206 // Backward Navigation in form1 with PREVIOUS |
| 3207 for (size_t i = WTF_ARRAY_LENGTH(focusedElements); i-- > 0;) { |
| 3208 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3209 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3210 textInputInfo = webViewImpl->textInputInfo(); |
| 3211 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3212 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3213 } |
| 3214 // Now focus will stay on previous focus itself, because it has no previous |
| 3215 // element. |
| 3216 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3217 |
| 3218 // Setting a non editable element as focus in form1, and ensuring editable |
| 3219 // navigation is fine in forward and backward. |
| 3220 Element* anchor2 = document->getElementById("anchor2"); |
| 3221 anchor2->focus(); |
| 3222 textInputInfo = webViewImpl->textInputInfo(); |
| 3223 // No Next/Previous element for elements outside form. |
| 3224 EXPECT_EQ(0, textInputInfo.flags); |
| 3225 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3226 // No editable element after this inside the form, hence focus won't change. |
| 3227 EXPECT_EQ(anchor2, document->focusedElement()); |
| 3228 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3229 // Since anchor is not a form control element, next/previous element will |
| 3230 // be null, hence focus will stay same as it is. |
| 3231 EXPECT_EQ(anchor2, document->focusedElement()); |
| 3232 |
| 3233 m_webViewHelper.reset(); |
| 3234 } |
| 3235 |
| 3236 TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithTabIndexElements) |
| 3237 { |
| 3238 const std::string testFile = "advance_focus_in_form_with_tabindex_elements.h
tml"; |
| 3239 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c
_str()), WebString::fromUTF8(testFile.c_str())); |
| 3240 WebView* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + testFil
e, true, nullptr); |
| 3241 webViewImpl->setInitialFocus(false); |
| 3242 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame()); |
| 3243 HTMLDocument* document = toHTMLDocument(frame->frame()->document()); |
| 3244 const int defaultTextInputFlags = WebTextInputFlagAutocapitalizeSentences; |
| 3245 |
| 3246 struct FocusedElement { |
| 3247 const char* elementId; |
| 3248 int textInputFlags; |
| 3249 } focusedElements[] = { |
| 3250 {"textarea6", defaultTextInputFlags | WebTextInputFlagHaveNextFocusableE
lement}, |
| 3251 {"input5", defaultTextInputFlags | WebTextInputFlagHaveNextFocusableElem
ent | WebTextInputFlagHavePreviousFocusableElement}, |
| 3252 {"contenteditable4", WebTextInputFlagHaveNextFocusableElement | WebTextI
nputFlagHavePreviousFocusableElement}, |
| 3253 {"input6", defaultTextInputFlags | WebTextInputFlagHavePreviousFocusable
Element}, |
| 3254 }; |
| 3255 |
| 3256 // Forward Navigation in form with NEXT which has tabindex attribute |
| 3257 // which differs visual order. |
| 3258 Element* textarea6 = document->getElementById("textarea6"); |
| 3259 textarea6->focus(); |
| 3260 Element* currentFocus = nullptr; |
| 3261 WebTextInputInfo textInputInfo; |
| 3262 for (size_t i = 0; i < WTF_ARRAY_LENGTH(focusedElements); ++i) { |
| 3263 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3264 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3265 textInputInfo = webViewImpl->textInputInfo(); |
| 3266 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3267 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3268 } |
| 3269 // No next editable element which is focusable with proper tab index, hence |
| 3270 // staying on previous focus. |
| 3271 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3272 |
| 3273 // Backward Navigation in form with PREVIOUS which has tabindex attribute |
| 3274 // which differs visual order. |
| 3275 for (size_t i = WTF_ARRAY_LENGTH(focusedElements); i-- > 0;) { |
| 3276 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3277 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3278 textInputInfo = webViewImpl->textInputInfo(); |
| 3279 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3280 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3281 } |
| 3282 // Now focus will stay on previous focus itself, because it has no previous |
| 3283 // element. |
| 3284 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3285 |
| 3286 // Setting an element which has invalid tabindex and ensuring it is not |
| 3287 // modifying further navigation. |
| 3288 Element* contenteditable5 = document->getElementById("contenteditable5"); |
| 3289 contenteditable5->focus(); |
| 3290 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3291 Element* input6 = document->getElementById("input6"); |
| 3292 EXPECT_EQ(input6, document->focusedElement()); |
| 3293 contenteditable5->focus(); |
| 3294 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3295 EXPECT_EQ(textarea6, document->focusedElement()); |
| 3296 |
| 3297 m_webViewHelper.reset(); |
| 3298 } |
| 3299 |
| 3300 TEST_F(WebViewTest, MoveFocusToNextFocusableElementInFormWithDisabledAndReadonly
Elements) |
| 3301 { |
| 3302 const std::string testFile = "advance_focus_in_form_with_disabled_and_readon
ly_elements.html"; |
| 3303 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c
_str()), WebString::fromUTF8(testFile.c_str())); |
| 3304 WebView* webViewImpl = m_webViewHelper.initializeAndLoad(m_baseURL + testFil
e, true, nullptr); |
| 3305 webViewImpl->setInitialFocus(false); |
| 3306 WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewImpl->mainFrame()); |
| 3307 HTMLDocument* document = toHTMLDocument(frame->frame()->document()); |
| 3308 |
| 3309 struct FocusedElement { |
| 3310 const char* elementId; |
| 3311 int textInputFlags; |
| 3312 } focusedElements[] = { |
| 3313 {"contenteditable6", WebTextInputFlagHaveNextFocusableElement}, |
| 3314 {"contenteditable7", WebTextInputFlagHavePreviousFocusableElement}, |
| 3315 }; |
| 3316 // Forward Navigation in form with NEXT which has has disabled/enabled |
| 3317 // elements which will gets skipped during navigation. |
| 3318 Element* contenteditable6 = document->getElementById("contenteditable6"); |
| 3319 contenteditable6->focus(); |
| 3320 Element* currentFocus = nullptr; |
| 3321 WebTextInputInfo textInputInfo; |
| 3322 for (size_t i = 0; i < WTF_ARRAY_LENGTH(focusedElements); ++i) { |
| 3323 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3324 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3325 textInputInfo = webViewImpl->textInputInfo(); |
| 3326 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3327 webViewImpl->advanceFocusInForm(WebFocusTypeForward); |
| 3328 } |
| 3329 // No next editable element which is focusable, hence staying on previous |
| 3330 // focus. |
| 3331 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3332 |
| 3333 // Backward Navigation in form with PREVIOUS which has has |
| 3334 // disabled/enabled elements which will gets skipped during navigation. |
| 3335 for (size_t i = WTF_ARRAY_LENGTH(focusedElements); i-- > 0;) { |
| 3336 currentFocus = document->getElementById(focusedElements[i].elementId); |
| 3337 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3338 textInputInfo = webViewImpl->textInputInfo(); |
| 3339 EXPECT_EQ(focusedElements[i].textInputFlags, textInputInfo.flags); |
| 3340 webViewImpl->advanceFocusInForm(WebFocusTypeBackward); |
| 3341 } |
| 3342 // Now focus will stay on previous focus itself, because it has no previous |
| 3343 // element. |
| 3344 EXPECT_EQ(currentFocus, document->focusedElement()); |
| 3345 |
| 3346 m_webViewHelper.reset(); |
| 3347 } |
| 3348 |
3035 } // namespace blink | 3349 } // namespace blink |
OLD | NEW |