1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef SelectorCheckerTestFunctions_h
27#define SelectorCheckerTestFunctions_h
28
29#include "HTMLInputElement.h"
30#include "HTMLOptionElement.h"
31#include <wtf/Compiler.h>
32
33#if ENABLE(VIDEO_TRACK)
34#include "WebVTTElement.h"
35#endif
36
37namespace WebCore {
38
39ALWAYS_INLINE bool isAutofilled(const Element* element)
40{
41    if (element->isFormControlElement()) {
42        if (const HTMLInputElement* inputElement = element->toInputElement())
43            return inputElement->isAutofilled();
44    }
45    return false;
46}
47
48ALWAYS_INLINE bool isDefaultButtonForForm(const Element* element)
49{
50    return element->isDefaultButtonForForm();
51}
52
53ALWAYS_INLINE bool isDisabled(const Element* element)
54{
55    if (element->isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
56        return element->isDisabledFormControl();
57    return false;
58}
59
60ALWAYS_INLINE bool isEnabled(const Element* element)
61{
62    if (element->isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
63        return !element->isDisabledFormControl();
64    return false;
65}
66
67ALWAYS_INLINE bool isChecked(Element* element)
68{
69    // Even though WinIE allows checked and indeterminate to co-exist, the CSS selector spec says that
70    // you can't be both checked and indeterminate. We will behave like WinIE behind the scenes and just
71    // obey the CSS spec here in the test for matching the pseudo.
72    const HTMLInputElement* inputElement = element->toInputElement();
73    if (inputElement && inputElement->shouldAppearChecked() && !inputElement->shouldAppearIndeterminate())
74        return true;
75    if (isHTMLOptionElement(element) && toHTMLOptionElement(element)->selected())
76        return true;
77    return false;
78}
79
80ALWAYS_INLINE bool isInRange(Element* element)
81{
82    element->document().setContainsValidityStyleRules();
83    return element->isInRange();
84}
85
86ALWAYS_INLINE bool isOutOfRange(Element* element)
87{
88    element->document().setContainsValidityStyleRules();
89    return element->isOutOfRange();
90}
91
92ALWAYS_INLINE bool isInvalid(const Element* element)
93{
94    element->document().setContainsValidityStyleRules();
95    return element->willValidate() && !element->isValidFormControlElement();
96}
97
98ALWAYS_INLINE bool isOptionalFormControl(const Element* element)
99{
100    return element->isOptionalFormControl();
101}
102
103ALWAYS_INLINE bool isRequiredFormControl(const Element* element)
104{
105    return element->isRequiredFormControl();
106}
107
108ALWAYS_INLINE bool isValid(const Element* element)
109{
110    element->document().setContainsValidityStyleRules();
111    return element->willValidate() && element->isValidFormControlElement();
112}
113
114inline bool matchesLangPseudoClass(const Element* element, AtomicStringImpl* filter)
115{
116    AtomicString value;
117#if ENABLE(VIDEO_TRACK)
118    if (element->isWebVTTElement())
119        value = toWebVTTElement(element)->language();
120    else
121#endif
122        value = element->computeInheritedLanguage();
123
124    if (value.isNull())
125        return false;
126
127    if (value.impl() == filter)
128        return true;
129
130    if (value.impl()->startsWith(filter, false)) {
131        if (value.length() == filter->length())
132            return true;
133        return value[filter->length()] == '-';
134    }
135    return false;
136}
137
138ALWAYS_INLINE bool matchesReadOnlyPseudoClass(const Element* element)
139{
140    return element->matchesReadOnlyPseudoClass();
141}
142
143ALWAYS_INLINE bool matchesReadWritePseudoClass(const Element* element)
144{
145    return element->matchesReadWritePseudoClass();
146}
147
148ALWAYS_INLINE bool shouldAppearIndeterminate(const Element* element)
149{
150    return element->shouldAppearIndeterminate();
151}
152
153#if ENABLE(FULLSCREEN_API)
154ALWAYS_INLINE bool matchesFullScreenPseudoClass(const Element* element)
155{
156    // While a Document is in the fullscreen state, and the document's current fullscreen
157    // element is an element in the document, the 'full-screen' pseudoclass applies to
158    // that element. Also, an <iframe>, <object> or <embed> element whose child browsing
159    // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
160    if (element->isFrameElementBase() && element->containsFullScreenElement())
161        return true;
162    if (!element->document().webkitIsFullScreen())
163        return false;
164    return element == element->document().webkitCurrentFullScreenElement();
165}
166#endif
167
168#if ENABLE(VIDEO_TRACK)
169ALWAYS_INLINE bool matchesFutureCuePseudoClass(const Element* element)
170{
171    return (element->isWebVTTElement() && !toWebVTTElement(element)->isPastNode());
172}
173
174ALWAYS_INLINE bool matchesPastCuePseudoClass(const Element* element)
175{
176    return (element->isWebVTTElement() && toWebVTTElement(element)->isPastNode());
177}
178#endif
179
180} // namespace WebCore
181
182#endif // SelectorCheckerTestFunctions_h
183