1/*
2 * Copyright (C) 2013 Adobe Systems Incorporated. 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 *
8 * 1. Redistributions of source code must retain the above
9 *    copyright notice, this list of conditions and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 *    copyright notice, this list of conditions and the following
13 *    disclaimer in the documentation and/or other materials
14 *    provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 * OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "core/css/RuntimeCSSEnabled.h"
32
33#include "RuntimeEnabledFeatures.h"
34
35namespace WebCore {
36
37// FIXME: We should use a real BitVector class instead!
38typedef Vector<bool> BoolVector;
39
40static void setCSSPropertiesEnabled(CSSPropertyID* properties, size_t length, bool featureFlag)
41{
42    for (size_t i = 0; i < length; i++)
43        RuntimeCSSEnabled::setCSSPropertyEnabled(properties[i], featureFlag);
44}
45
46static void setPropertySwitchesFromRuntimeFeatures()
47{
48    CSSPropertyID regionProperites[] = {
49        CSSPropertyWebkitFlowInto,
50        CSSPropertyWebkitFlowFrom,
51        CSSPropertyWebkitRegionFragment,
52        CSSPropertyWebkitRegionBreakAfter,
53        CSSPropertyWebkitRegionBreakBefore,
54        CSSPropertyWebkitRegionBreakInside
55    };
56    setCSSPropertiesEnabled(regionProperites, WTF_ARRAY_LENGTH(regionProperites), RuntimeEnabledFeatures::cssRegionsEnabled());
57    CSSPropertyID exclusionProperties[] = {
58        CSSPropertyWebkitWrapFlow,
59        CSSPropertyWebkitWrapThrough,
60    };
61    setCSSPropertiesEnabled(exclusionProperties, WTF_ARRAY_LENGTH(exclusionProperties), RuntimeEnabledFeatures::cssExclusionsEnabled());
62    CSSPropertyID shapeProperties[] = {
63        CSSPropertyShapeMargin,
64        CSSPropertyShapePadding,
65        CSSPropertyShapeImageThreshold,
66        CSSPropertyShapeInside,
67        CSSPropertyShapeOutside,
68    };
69    setCSSPropertiesEnabled(shapeProperties, WTF_ARRAY_LENGTH(shapeProperties), RuntimeEnabledFeatures::cssShapesEnabled());
70    CSSPropertyID css3TextDecorationProperties[] = {
71        CSSPropertyTextDecorationColor,
72        CSSPropertyTextDecorationLine,
73        CSSPropertyTextDecorationStyle,
74        CSSPropertyTextUnderlinePosition,
75    };
76    setCSSPropertiesEnabled(css3TextDecorationProperties, WTF_ARRAY_LENGTH(css3TextDecorationProperties), RuntimeEnabledFeatures::css3TextDecorationsEnabled());
77    CSSPropertyID css3TextProperties[] = {
78        CSSPropertyTextAlignLast,
79        CSSPropertyTextJustify,
80    };
81    setCSSPropertiesEnabled(css3TextProperties, WTF_ARRAY_LENGTH(css3TextProperties), RuntimeEnabledFeatures::css3TextEnabled());
82    CSSPropertyID cssGridLayoutProperties[] = {
83        CSSPropertyGridAutoColumns,
84        CSSPropertyGridAutoRows,
85        CSSPropertyGridDefinitionColumns,
86        CSSPropertyGridDefinitionRows,
87        CSSPropertyGridColumnStart,
88        CSSPropertyGridColumnEnd,
89        CSSPropertyGridRowStart,
90        CSSPropertyGridRowEnd,
91        CSSPropertyGridColumn,
92        CSSPropertyGridRow,
93        CSSPropertyGridArea,
94        CSSPropertyGridAutoFlow,
95        CSSPropertyGridTemplate
96    };
97    setCSSPropertiesEnabled(cssGridLayoutProperties, WTF_ARRAY_LENGTH(cssGridLayoutProperties), RuntimeEnabledFeatures::cssGridLayoutEnabled());
98    CSSPropertyID cssObjectFitPositionProperties[] = {
99        CSSPropertyObjectFit,
100        CSSPropertyObjectPosition
101    };
102    setCSSPropertiesEnabled(cssObjectFitPositionProperties, WTF_ARRAY_LENGTH(cssObjectFitPositionProperties), RuntimeEnabledFeatures::objectFitPositionEnabled());
103
104    CSSPropertyID animationProperties[] = {
105        CSSPropertyAnimation,
106        CSSPropertyAnimationName,
107        CSSPropertyAnimationDuration,
108        CSSPropertyAnimationTimingFunction,
109        CSSPropertyAnimationDelay,
110        CSSPropertyAnimationIterationCount,
111        CSSPropertyAnimationDirection,
112        CSSPropertyAnimationFillMode,
113        CSSPropertyAnimationPlayState
114    };
115    setCSSPropertiesEnabled(animationProperties, WTF_ARRAY_LENGTH(animationProperties), RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
116
117    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyBackgroundBlendMode, RuntimeEnabledFeatures::cssCompositingEnabled());
118    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyMixBlendMode, RuntimeEnabledFeatures::cssCompositingEnabled());
119    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyIsolation, RuntimeEnabledFeatures::cssCompositingEnabled());
120    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyTouchAction, RuntimeEnabledFeatures::cssTouchActionEnabled());
121    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyPaintOrder, RuntimeEnabledFeatures::svgPaintOrderEnabled());
122    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyVariable, RuntimeEnabledFeatures::cssVariablesEnabled());
123    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyMaskSourceType, RuntimeEnabledFeatures::cssMaskSourceTypeEnabled());
124    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyColumnFill, RuntimeEnabledFeatures::regionBasedColumnsEnabled());
125
126    // InternalCallback is an implementation detail, rather than an experimental feature, and should never be exposed to the web.
127    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyInternalCallback, false);
128}
129
130static BoolVector& propertySwitches()
131{
132    static BoolVector* switches = 0;
133    if (!switches) {
134        switches = new BoolVector;
135        // Accomodate CSSPropertyIDs that fall outside the firstCSSProperty, lastCSSProperty range (eg. CSSPropertyVariable).
136        switches->fill(true, lastCSSProperty + 1);
137        setPropertySwitchesFromRuntimeFeatures();
138    }
139    return *switches;
140}
141
142size_t indexForProperty(CSSPropertyID propertyId)
143{
144    RELEASE_ASSERT(propertyId >= 0 && propertyId <= lastCSSProperty);
145    ASSERT(propertyId != CSSPropertyInvalid);
146    return static_cast<size_t>(propertyId);
147}
148
149bool RuntimeCSSEnabled::isCSSPropertyEnabled(CSSPropertyID propertyId)
150{
151    // Internal properties shouldn't be exposed to the web
152    // so they are considered to be always disabled.
153    if (isInternalProperty(propertyId))
154        return false;
155
156    return propertySwitches()[indexForProperty(propertyId)];
157}
158
159void RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyID propertyId, bool enable)
160{
161    propertySwitches()[indexForProperty(propertyId)] = enable;
162}
163
164void RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(const CSSPropertyID* properties, size_t propertyCount, Vector<CSSPropertyID>& outVector)
165{
166    for (unsigned i = 0; i < propertyCount; i++) {
167        CSSPropertyID property = properties[i];
168        if (RuntimeCSSEnabled::isCSSPropertyEnabled(property))
169            outVector.append(property);
170    }
171}
172
173} // namespace WebCore
174