1
2/*
3 * Copyright (C) 2012 Google, Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "core/frame/UseCounter.h"
29
30#include "core/css/CSSStyleSheet.h"
31#include "core/css/StyleSheetContents.h"
32#include "core/dom/Document.h"
33#include "core/dom/ExecutionContext.h"
34#include "core/frame/LocalDOMWindow.h"
35#include "core/frame/FrameConsole.h"
36#include "core/frame/FrameHost.h"
37#include "core/frame/LocalFrame.h"
38#include "core/inspector/ConsoleMessage.h"
39#include "core/workers/WorkerGlobalScope.h"
40#include "public/platform/Platform.h"
41
42namespace blink {
43
44static int totalPagesMeasuredCSSSampleId() { return 1; }
45
46int UseCounter::m_muteCount = 0;
47
48// FIXME : This mapping should be autogenerated. This function should
49//         be moved to a separate file and a script run at build time
50//         to detect new values in CSSPropertyID and add them to the
51//         end of this function. This file would be checked in.
52//         https://code.google.com/p/chromium/issues/detail?id=234940
53int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
54{
55    CSSPropertyID cssPropertyID = convertToCSSPropertyID(id);
56
57    switch (cssPropertyID) {
58    // Begin at 2, because 1 is reserved for totalPagesMeasuredCSSSampleId.
59    case CSSPropertyColor: return 2;
60    case CSSPropertyDirection: return 3;
61    case CSSPropertyDisplay: return 4;
62    case CSSPropertyFont: return 5;
63    case CSSPropertyFontFamily: return 6;
64    case CSSPropertyFontSize: return 7;
65    case CSSPropertyFontStyle: return 8;
66    case CSSPropertyFontVariant: return 9;
67    case CSSPropertyFontWeight: return 10;
68    case CSSPropertyTextRendering: return 11;
69    case CSSPropertyWebkitFontFeatureSettings: return 12;
70    case CSSPropertyFontKerning: return 13;
71    case CSSPropertyWebkitFontSmoothing: return 14;
72    case CSSPropertyFontVariantLigatures: return 15;
73    case CSSPropertyWebkitLocale: return 16;
74    case CSSPropertyWebkitTextOrientation: return 17;
75    case CSSPropertyWebkitWritingMode: return 18;
76    case CSSPropertyZoom: return 19;
77    case CSSPropertyLineHeight: return 20;
78    case CSSPropertyBackground: return 21;
79    case CSSPropertyBackgroundAttachment: return 22;
80    case CSSPropertyBackgroundClip: return 23;
81    case CSSPropertyBackgroundColor: return 24;
82    case CSSPropertyBackgroundImage: return 25;
83    case CSSPropertyBackgroundOrigin: return 26;
84    case CSSPropertyBackgroundPosition: return 27;
85    case CSSPropertyBackgroundPositionX: return 28;
86    case CSSPropertyBackgroundPositionY: return 29;
87    case CSSPropertyBackgroundRepeat: return 30;
88    case CSSPropertyBackgroundRepeatX: return 31;
89    case CSSPropertyBackgroundRepeatY: return 32;
90    case CSSPropertyBackgroundSize: return 33;
91    case CSSPropertyBorder: return 34;
92    case CSSPropertyBorderBottom: return 35;
93    case CSSPropertyBorderBottomColor: return 36;
94    case CSSPropertyBorderBottomLeftRadius: return 37;
95    case CSSPropertyBorderBottomRightRadius: return 38;
96    case CSSPropertyBorderBottomStyle: return 39;
97    case CSSPropertyBorderBottomWidth: return 40;
98    case CSSPropertyBorderCollapse: return 41;
99    case CSSPropertyBorderColor: return 42;
100    case CSSPropertyBorderImage: return 43;
101    case CSSPropertyBorderImageOutset: return 44;
102    case CSSPropertyBorderImageRepeat: return 45;
103    case CSSPropertyBorderImageSlice: return 46;
104    case CSSPropertyBorderImageSource: return 47;
105    case CSSPropertyBorderImageWidth: return 48;
106    case CSSPropertyBorderLeft: return 49;
107    case CSSPropertyBorderLeftColor: return 50;
108    case CSSPropertyBorderLeftStyle: return 51;
109    case CSSPropertyBorderLeftWidth: return 52;
110    case CSSPropertyBorderRadius: return 53;
111    case CSSPropertyBorderRight: return 54;
112    case CSSPropertyBorderRightColor: return 55;
113    case CSSPropertyBorderRightStyle: return 56;
114    case CSSPropertyBorderRightWidth: return 57;
115    case CSSPropertyBorderSpacing: return 58;
116    case CSSPropertyBorderStyle: return 59;
117    case CSSPropertyBorderTop: return 60;
118    case CSSPropertyBorderTopColor: return 61;
119    case CSSPropertyBorderTopLeftRadius: return 62;
120    case CSSPropertyBorderTopRightRadius: return 63;
121    case CSSPropertyBorderTopStyle: return 64;
122    case CSSPropertyBorderTopWidth: return 65;
123    case CSSPropertyBorderWidth: return 66;
124    case CSSPropertyBottom: return 67;
125    case CSSPropertyBoxShadow: return 68;
126    case CSSPropertyBoxSizing: return 69;
127    case CSSPropertyCaptionSide: return 70;
128    case CSSPropertyClear: return 71;
129    case CSSPropertyClip: return 72;
130    case CSSPropertyWebkitClipPath: return 73;
131    case CSSPropertyContent: return 74;
132    case CSSPropertyCounterIncrement: return 75;
133    case CSSPropertyCounterReset: return 76;
134    case CSSPropertyCursor: return 77;
135    case CSSPropertyEmptyCells: return 78;
136    case CSSPropertyFloat: return 79;
137    case CSSPropertyFontStretch: return 80;
138    case CSSPropertyHeight: return 81;
139    case CSSPropertyImageRendering: return 82;
140    case CSSPropertyLeft: return 83;
141    case CSSPropertyLetterSpacing: return 84;
142    case CSSPropertyListStyle: return 85;
143    case CSSPropertyListStyleImage: return 86;
144    case CSSPropertyListStylePosition: return 87;
145    case CSSPropertyListStyleType: return 88;
146    case CSSPropertyMargin: return 89;
147    case CSSPropertyMarginBottom: return 90;
148    case CSSPropertyMarginLeft: return 91;
149    case CSSPropertyMarginRight: return 92;
150    case CSSPropertyMarginTop: return 93;
151    case CSSPropertyMaxHeight: return 94;
152    case CSSPropertyMaxWidth: return 95;
153    case CSSPropertyMinHeight: return 96;
154    case CSSPropertyMinWidth: return 97;
155    case CSSPropertyOpacity: return 98;
156    case CSSPropertyOrphans: return 99;
157    case CSSPropertyOutline: return 100;
158    case CSSPropertyOutlineColor: return 101;
159    case CSSPropertyOutlineOffset: return 102;
160    case CSSPropertyOutlineStyle: return 103;
161    case CSSPropertyOutlineWidth: return 104;
162    case CSSPropertyOverflow: return 105;
163    case CSSPropertyOverflowWrap: return 106;
164    case CSSPropertyOverflowX: return 107;
165    case CSSPropertyOverflowY: return 108;
166    case CSSPropertyPadding: return 109;
167    case CSSPropertyPaddingBottom: return 110;
168    case CSSPropertyPaddingLeft: return 111;
169    case CSSPropertyPaddingRight: return 112;
170    case CSSPropertyPaddingTop: return 113;
171    case CSSPropertyPage: return 114;
172    case CSSPropertyPageBreakAfter: return 115;
173    case CSSPropertyPageBreakBefore: return 116;
174    case CSSPropertyPageBreakInside: return 117;
175    case CSSPropertyPointerEvents: return 118;
176    case CSSPropertyPosition: return 119;
177    case CSSPropertyQuotes: return 120;
178    case CSSPropertyResize: return 121;
179    case CSSPropertyRight: return 122;
180    case CSSPropertySize: return 123;
181    case CSSPropertySrc: return 124;
182    case CSSPropertySpeak: return 125;
183    case CSSPropertyTableLayout: return 126;
184    case CSSPropertyTabSize: return 127;
185    case CSSPropertyTextAlign: return 128;
186    case CSSPropertyTextDecoration: return 129;
187    case CSSPropertyTextIndent: return 130;
188    /* Removed CSSPropertyTextLineThrough* - 131-135 */
189    case CSSPropertyTextOverflow: return 136;
190    /* Removed CSSPropertyTextOverline* - 137-141 */
191    case CSSPropertyTextShadow: return 142;
192    case CSSPropertyTextTransform: return 143;
193    /* Removed CSSPropertyTextUnderline* - 144-148 */
194    case CSSPropertyTop: return 149;
195    case CSSPropertyTransition: return 150;
196    case CSSPropertyTransitionDelay: return 151;
197    case CSSPropertyTransitionDuration: return 152;
198    case CSSPropertyTransitionProperty: return 153;
199    case CSSPropertyTransitionTimingFunction: return 154;
200    case CSSPropertyUnicodeBidi: return 155;
201    case CSSPropertyUnicodeRange: return 156;
202    case CSSPropertyVerticalAlign: return 157;
203    case CSSPropertyVisibility: return 158;
204    case CSSPropertyWhiteSpace: return 159;
205    case CSSPropertyWidows: return 160;
206    case CSSPropertyWidth: return 161;
207    case CSSPropertyWordBreak: return 162;
208    case CSSPropertyWordSpacing: return 163;
209    case CSSPropertyWordWrap: return 164;
210    case CSSPropertyZIndex: return 165;
211    case CSSPropertyWebkitAnimation: return 166;
212    case CSSPropertyWebkitAnimationDelay: return 167;
213    case CSSPropertyWebkitAnimationDirection: return 168;
214    case CSSPropertyWebkitAnimationDuration: return 169;
215    case CSSPropertyWebkitAnimationFillMode: return 170;
216    case CSSPropertyWebkitAnimationIterationCount: return 171;
217    case CSSPropertyWebkitAnimationName: return 172;
218    case CSSPropertyWebkitAnimationPlayState: return 173;
219    case CSSPropertyWebkitAnimationTimingFunction: return 174;
220    case CSSPropertyWebkitAppearance: return 175;
221    case CSSPropertyWebkitAspectRatio: return 176;
222    case CSSPropertyWebkitBackfaceVisibility: return 177;
223    case CSSPropertyWebkitBackgroundClip: return 178;
224    case CSSPropertyWebkitBackgroundComposite: return 179;
225    case CSSPropertyWebkitBackgroundOrigin: return 180;
226    case CSSPropertyWebkitBackgroundSize: return 181;
227    case CSSPropertyWebkitBorderAfter: return 182;
228    case CSSPropertyWebkitBorderAfterColor: return 183;
229    case CSSPropertyWebkitBorderAfterStyle: return 184;
230    case CSSPropertyWebkitBorderAfterWidth: return 185;
231    case CSSPropertyWebkitBorderBefore: return 186;
232    case CSSPropertyWebkitBorderBeforeColor: return 187;
233    case CSSPropertyWebkitBorderBeforeStyle: return 188;
234    case CSSPropertyWebkitBorderBeforeWidth: return 189;
235    case CSSPropertyWebkitBorderEnd: return 190;
236    case CSSPropertyWebkitBorderEndColor: return 191;
237    case CSSPropertyWebkitBorderEndStyle: return 192;
238    case CSSPropertyWebkitBorderEndWidth: return 193;
239    case CSSPropertyWebkitBorderFit: return 194;
240    case CSSPropertyWebkitBorderHorizontalSpacing: return 195;
241    case CSSPropertyWebkitBorderImage: return 196;
242    case CSSPropertyWebkitBorderRadius: return 197;
243    case CSSPropertyWebkitBorderStart: return 198;
244    case CSSPropertyWebkitBorderStartColor: return 199;
245    case CSSPropertyWebkitBorderStartStyle: return 200;
246    case CSSPropertyWebkitBorderStartWidth: return 201;
247    case CSSPropertyWebkitBorderVerticalSpacing: return 202;
248    case CSSPropertyWebkitBoxAlign: return 203;
249    case CSSPropertyWebkitBoxDirection: return 204;
250    case CSSPropertyWebkitBoxFlex: return 205;
251    case CSSPropertyWebkitBoxFlexGroup: return 206;
252    case CSSPropertyWebkitBoxLines: return 207;
253    case CSSPropertyWebkitBoxOrdinalGroup: return 208;
254    case CSSPropertyWebkitBoxOrient: return 209;
255    case CSSPropertyWebkitBoxPack: return 210;
256    case CSSPropertyWebkitBoxReflect: return 211;
257    case CSSPropertyWebkitBoxShadow: return 212;
258    // CSSPropertyWebkitColumnAxis was 214
259    case CSSPropertyWebkitColumnBreakAfter: return 215;
260    case CSSPropertyWebkitColumnBreakBefore: return 216;
261    case CSSPropertyWebkitColumnBreakInside: return 217;
262    case CSSPropertyWebkitColumnCount: return 218;
263    case CSSPropertyWebkitColumnGap: return 219;
264    // CSSPropertyWebkitColumnProgression was 220
265    case CSSPropertyWebkitColumnRule: return 221;
266    case CSSPropertyWebkitColumnRuleColor: return 222;
267    case CSSPropertyWebkitColumnRuleStyle: return 223;
268    case CSSPropertyWebkitColumnRuleWidth: return 224;
269    case CSSPropertyWebkitColumnSpan: return 225;
270    case CSSPropertyWebkitColumnWidth: return 226;
271    case CSSPropertyWebkitColumns: return 227;
272#if defined(ENABLE_CSS_BOX_DECORATION_BREAK) && ENABLE_CSS_BOX_DECORATION_BREAK
273    case CSSPropertyWebkitBoxDecorationBreak: return 228;
274#endif
275#if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS
276    case CSSPropertyWebkitFilter: return 229;
277#endif
278    case CSSPropertyAlignContent: return 230;
279    case CSSPropertyAlignItems: return 231;
280    case CSSPropertyAlignSelf: return 232;
281    case CSSPropertyFlex: return 233;
282    case CSSPropertyFlexBasis: return 234;
283    case CSSPropertyFlexDirection: return 235;
284    case CSSPropertyFlexFlow: return 236;
285    case CSSPropertyFlexGrow: return 237;
286    case CSSPropertyFlexShrink: return 238;
287    case CSSPropertyFlexWrap: return 239;
288    case CSSPropertyJustifyContent: return 240;
289    case CSSPropertyWebkitFontSizeDelta: return 241;
290    case CSSPropertyGridTemplateColumns: return 242;
291    case CSSPropertyGridTemplateRows: return 243;
292    case CSSPropertyGridColumnStart: return 244;
293    case CSSPropertyGridColumnEnd: return 245;
294    case CSSPropertyGridRowStart: return 246;
295    case CSSPropertyGridRowEnd: return 247;
296    case CSSPropertyGridColumn: return 248;
297    case CSSPropertyGridRow: return 249;
298    case CSSPropertyGridAutoFlow: return 250;
299    case CSSPropertyWebkitHighlight: return 251;
300    case CSSPropertyWebkitHyphenateCharacter: return 252;
301    case CSSPropertyWebkitLineBoxContain: return 257;
302    // case CSSPropertyWebkitLineAlign: return 258;
303    case CSSPropertyWebkitLineBreak: return 259;
304    case CSSPropertyWebkitLineClamp: return 260;
305    // case CSSPropertyWebkitLineGrid: return 261;
306    // case CSSPropertyWebkitLineSnap: return 262;
307    case CSSPropertyWebkitLogicalWidth: return 263;
308    case CSSPropertyWebkitLogicalHeight: return 264;
309    case CSSPropertyWebkitMarginAfterCollapse: return 265;
310    case CSSPropertyWebkitMarginBeforeCollapse: return 266;
311    case CSSPropertyWebkitMarginBottomCollapse: return 267;
312    case CSSPropertyWebkitMarginTopCollapse: return 268;
313    case CSSPropertyWebkitMarginCollapse: return 269;
314    case CSSPropertyWebkitMarginAfter: return 270;
315    case CSSPropertyWebkitMarginBefore: return 271;
316    case CSSPropertyWebkitMarginEnd: return 272;
317    case CSSPropertyWebkitMarginStart: return 273;
318    // CSSPropertyWebkitMarquee was 274.
319    // CSSPropertyInternalMarquee* were 275-279.
320    case CSSPropertyWebkitMask: return 280;
321    case CSSPropertyWebkitMaskBoxImage: return 281;
322    case CSSPropertyWebkitMaskBoxImageOutset: return 282;
323    case CSSPropertyWebkitMaskBoxImageRepeat: return 283;
324    case CSSPropertyWebkitMaskBoxImageSlice: return 284;
325    case CSSPropertyWebkitMaskBoxImageSource: return 285;
326    case CSSPropertyWebkitMaskBoxImageWidth: return 286;
327    case CSSPropertyWebkitMaskClip: return 287;
328    case CSSPropertyWebkitMaskComposite: return 288;
329    case CSSPropertyWebkitMaskImage: return 289;
330    case CSSPropertyWebkitMaskOrigin: return 290;
331    case CSSPropertyWebkitMaskPosition: return 291;
332    case CSSPropertyWebkitMaskPositionX: return 292;
333    case CSSPropertyWebkitMaskPositionY: return 293;
334    case CSSPropertyWebkitMaskRepeat: return 294;
335    case CSSPropertyWebkitMaskRepeatX: return 295;
336    case CSSPropertyWebkitMaskRepeatY: return 296;
337    case CSSPropertyWebkitMaskSize: return 297;
338    case CSSPropertyWebkitMaxLogicalWidth: return 298;
339    case CSSPropertyWebkitMaxLogicalHeight: return 299;
340    case CSSPropertyWebkitMinLogicalWidth: return 300;
341    case CSSPropertyWebkitMinLogicalHeight: return 301;
342    // WebkitNbspMode has been deleted, was return 302;
343    case CSSPropertyOrder: return 303;
344    case CSSPropertyWebkitPaddingAfter: return 304;
345    case CSSPropertyWebkitPaddingBefore: return 305;
346    case CSSPropertyWebkitPaddingEnd: return 306;
347    case CSSPropertyWebkitPaddingStart: return 307;
348    case CSSPropertyWebkitPerspective: return 308;
349    case CSSPropertyWebkitPerspectiveOrigin: return 309;
350    case CSSPropertyWebkitPerspectiveOriginX: return 310;
351    case CSSPropertyWebkitPerspectiveOriginY: return 311;
352    case CSSPropertyWebkitPrintColorAdjust: return 312;
353    case CSSPropertyWebkitRtlOrdering: return 313;
354    case CSSPropertyWebkitRubyPosition: return 314;
355    case CSSPropertyWebkitTextCombine: return 315;
356    case CSSPropertyWebkitTextDecorationsInEffect: return 316;
357    case CSSPropertyWebkitTextEmphasis: return 317;
358    case CSSPropertyWebkitTextEmphasisColor: return 318;
359    case CSSPropertyWebkitTextEmphasisPosition: return 319;
360    case CSSPropertyWebkitTextEmphasisStyle: return 320;
361    case CSSPropertyWebkitTextFillColor: return 321;
362    case CSSPropertyWebkitTextSecurity: return 322;
363    case CSSPropertyWebkitTextStroke: return 323;
364    case CSSPropertyWebkitTextStrokeColor: return 324;
365    case CSSPropertyWebkitTextStrokeWidth: return 325;
366    case CSSPropertyWebkitTransform: return 326;
367    case CSSPropertyWebkitTransformOrigin: return 327;
368    case CSSPropertyWebkitTransformOriginX: return 328;
369    case CSSPropertyWebkitTransformOriginY: return 329;
370    case CSSPropertyWebkitTransformOriginZ: return 330;
371    case CSSPropertyWebkitTransformStyle: return 331;
372    case CSSPropertyWebkitTransition: return 332;
373    case CSSPropertyWebkitTransitionDelay: return 333;
374    case CSSPropertyWebkitTransitionDuration: return 334;
375    case CSSPropertyWebkitTransitionProperty: return 335;
376    case CSSPropertyWebkitTransitionTimingFunction: return 336;
377    case CSSPropertyWebkitUserDrag: return 337;
378    case CSSPropertyWebkitUserModify: return 338;
379    case CSSPropertyWebkitUserSelect: return 339;
380    // case CSSPropertyWebkitFlowInto: return 340;
381    // case CSSPropertyWebkitFlowFrom: return 341;
382    // case CSSPropertyWebkitRegionFragment: return 342;
383    // case CSSPropertyWebkitRegionBreakAfter: return 343;
384    // case CSSPropertyWebkitRegionBreakBefore: return 344;
385    // case CSSPropertyWebkitRegionBreakInside: return 345;
386    // case CSSPropertyShapeInside: return 346;
387    case CSSPropertyShapeOutside: return 347;
388    case CSSPropertyShapeMargin: return 348;
389    // case CSSPropertyShapePadding: return 349;
390    // case CSSPropertyWebkitWrapFlow: return 350;
391    // case CSSPropertyWebkitWrapThrough: return 351;
392    // CSSPropertyWebkitWrap was 352.
393#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
394    case CSSPropertyWebkitTapHighlightColor: return 353;
395#endif
396#if defined(ENABLE_DRAGGABLE_REGION) && ENABLE_DRAGGABLE_REGION
397    case CSSPropertyWebkitAppRegion: return 354;
398#endif
399    case CSSPropertyClipPath: return 355;
400    case CSSPropertyClipRule: return 356;
401    case CSSPropertyMask: return 357;
402    case CSSPropertyEnableBackground: return 358;
403    case CSSPropertyFilter: return 359;
404    case CSSPropertyFloodColor: return 360;
405    case CSSPropertyFloodOpacity: return 361;
406    case CSSPropertyLightingColor: return 362;
407    case CSSPropertyStopColor: return 363;
408    case CSSPropertyStopOpacity: return 364;
409    case CSSPropertyColorInterpolation: return 365;
410    case CSSPropertyColorInterpolationFilters: return 366;
411    // case CSSPropertyColorProfile: return 367;
412    case CSSPropertyColorRendering: return 368;
413    case CSSPropertyFill: return 369;
414    case CSSPropertyFillOpacity: return 370;
415    case CSSPropertyFillRule: return 371;
416    case CSSPropertyMarker: return 372;
417    case CSSPropertyMarkerEnd: return 373;
418    case CSSPropertyMarkerMid: return 374;
419    case CSSPropertyMarkerStart: return 375;
420    case CSSPropertyMaskType: return 376;
421    case CSSPropertyShapeRendering: return 377;
422    case CSSPropertyStroke: return 378;
423    case CSSPropertyStrokeDasharray: return 379;
424    case CSSPropertyStrokeDashoffset: return 380;
425    case CSSPropertyStrokeLinecap: return 381;
426    case CSSPropertyStrokeLinejoin: return 382;
427    case CSSPropertyStrokeMiterlimit: return 383;
428    case CSSPropertyStrokeOpacity: return 384;
429    case CSSPropertyStrokeWidth: return 385;
430    case CSSPropertyAlignmentBaseline: return 386;
431    case CSSPropertyBaselineShift: return 387;
432    case CSSPropertyDominantBaseline: return 388;
433    case CSSPropertyGlyphOrientationHorizontal: return 389;
434    case CSSPropertyGlyphOrientationVertical: return 390;
435    // CSSPropertyKerning has been removed, was return 391;
436    case CSSPropertyTextAnchor: return 392;
437    case CSSPropertyVectorEffect: return 393;
438    case CSSPropertyWritingMode: return 394;
439    // CSSPropertyWebkitSvgShadow has been removed, was return 395;
440    // CSSPropertyWebkitCursorVisibility has been removed, was return 396;
441    // CSSPropertyImageOrientation has been removed, was return 397;
442    // CSSPropertyImageResolution has been removed, was return 398;
443#if defined(ENABLE_CSS_COMPOSITING) && ENABLE_CSS_COMPOSITING
444    case CSSPropertyWebkitBlendMode: return 399;
445    case CSSPropertyWebkitBackgroundBlendMode: return 400;
446#endif
447    case CSSPropertyTextDecorationLine: return 401;
448    case CSSPropertyTextDecorationStyle: return 402;
449    case CSSPropertyTextDecorationColor: return 403;
450    case CSSPropertyTextAlignLast: return 404;
451    case CSSPropertyTextUnderlinePosition: return 405;
452    case CSSPropertyMaxZoom: return 406;
453    case CSSPropertyMinZoom: return 407;
454    case CSSPropertyOrientation: return 408;
455    case CSSPropertyUserZoom: return 409;
456    // CSSPropertyWebkitDashboardRegion was 410.
457    // CSSPropertyWebkitOverflowScrolling was 411.
458    case CSSPropertyWebkitAppRegion: return 412;
459    case CSSPropertyWebkitFilter: return 413;
460    case CSSPropertyWebkitBoxDecorationBreak: return 414;
461    case CSSPropertyWebkitTapHighlightColor: return 415;
462    case CSSPropertyBufferedRendering: return 416;
463    case CSSPropertyGridAutoRows: return 417;
464    case CSSPropertyGridAutoColumns: return 418;
465    case CSSPropertyBackgroundBlendMode: return 419;
466    case CSSPropertyMixBlendMode: return 420;
467    case CSSPropertyTouchAction: return 421;
468    case CSSPropertyGridArea: return 422;
469    case CSSPropertyGridTemplateAreas: return 423;
470    case CSSPropertyAnimation: return 424;
471    case CSSPropertyAnimationDelay: return 425;
472    case CSSPropertyAnimationDirection: return 426;
473    case CSSPropertyAnimationDuration: return 427;
474    case CSSPropertyAnimationFillMode: return 428;
475    case CSSPropertyAnimationIterationCount: return 429;
476    case CSSPropertyAnimationName: return 430;
477    case CSSPropertyAnimationPlayState: return 431;
478    case CSSPropertyAnimationTimingFunction: return 432;
479    case CSSPropertyObjectFit: return 433;
480    case CSSPropertyPaintOrder: return 434;
481    case CSSPropertyMaskSourceType: return 435;
482    case CSSPropertyIsolation: return 436;
483    case CSSPropertyObjectPosition: return 437;
484    // case CSSPropertyInternalCallback: return 438;
485    case CSSPropertyShapeImageThreshold: return 439;
486    case CSSPropertyColumnFill: return 440;
487    case CSSPropertyTextJustify: return 441;
488    case CSSPropertyTouchActionDelay: return 442;
489    case CSSPropertyJustifySelf: return 443;
490    case CSSPropertyScrollBehavior: return 444;
491    case CSSPropertyWillChange: return 445;
492    case CSSPropertyTransform: return 446;
493    case CSSPropertyTransformOrigin: return 447;
494    case CSSPropertyTransformStyle: return 448;
495    case CSSPropertyPerspective: return 449;
496    case CSSPropertyPerspectiveOrigin: return 450;
497    case CSSPropertyBackfaceVisibility: return 451;
498    case CSSPropertyGridTemplate: return 452;
499    case CSSPropertyGrid: return 453;
500    case CSSPropertyAll: return 454;
501    case CSSPropertyJustifyItems: return 455;
502
503    // 1. Add new features above this line (don't change the assigned numbers of the existing
504    // items).
505    // 2. Update maximumCSSSampleId() with the new maximum value.
506    // 3. Run the update_use_counter_css.py script in
507    // chromium/src/tools/metrics/histograms to update the UMA histogram names.
508
509    // Internal properties should not be counted.
510    case CSSPropertyInternalMarqueeDirection:
511    case CSSPropertyInternalMarqueeIncrement:
512    case CSSPropertyInternalMarqueeRepetition:
513    case CSSPropertyInternalMarqueeSpeed:
514    case CSSPropertyInternalMarqueeStyle:
515    case CSSPropertyInvalid:
516        ASSERT_NOT_REACHED();
517        return 0;
518    }
519
520    ASSERT_NOT_REACHED();
521    return 0;
522}
523
524static int maximumCSSSampleId() { return 455; }
525
526void UseCounter::muteForInspector()
527{
528    UseCounter::m_muteCount++;
529}
530
531void UseCounter::unmuteForInspector()
532{
533    UseCounter::m_muteCount--;
534}
535
536UseCounter::UseCounter()
537{
538    m_CSSFeatureBits.ensureSize(lastCSSProperty + 1);
539    m_CSSFeatureBits.clearAll();
540}
541
542UseCounter::~UseCounter()
543{
544    // We always log PageDestruction so that we have a scale for the rest of the features.
545    blink::Platform::current()->histogramEnumeration("WebCore.FeatureObserver", PageDestruction, NumberOfFeatures);
546
547    updateMeasurements();
548}
549
550void UseCounter::updateMeasurements()
551{
552    blink::Platform::current()->histogramEnumeration("WebCore.FeatureObserver", PageVisits, NumberOfFeatures);
553
554    if (m_countBits) {
555        for (unsigned i = 0; i < NumberOfFeatures; ++i) {
556            if (m_countBits->quickGet(i))
557                blink::Platform::current()->histogramEnumeration("WebCore.FeatureObserver", i, NumberOfFeatures);
558        }
559        // Clearing count bits is timing sensitive.
560        m_countBits->clearAll();
561    }
562
563    // FIXME: Sometimes this function is called more than once per page. The following
564    //        bool guards against incrementing the page count when there are no CSS
565    //        bits set. http://crbug.com/236262.
566    bool needsPagesMeasuredUpdate = false;
567    for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
568        if (m_CSSFeatureBits.quickGet(i)) {
569            int cssSampleId = mapCSSPropertyIdToCSSSampleIdForHistogram(i);
570            blink::Platform::current()->histogramEnumeration("WebCore.FeatureObserver.CSSProperties", cssSampleId, maximumCSSSampleId());
571            needsPagesMeasuredUpdate = true;
572        }
573    }
574
575    if (needsPagesMeasuredUpdate)
576        blink::Platform::current()->histogramEnumeration("WebCore.FeatureObserver.CSSProperties", totalPagesMeasuredCSSSampleId(), maximumCSSSampleId());
577
578    m_CSSFeatureBits.clearAll();
579}
580
581void UseCounter::didCommitLoad()
582{
583    updateMeasurements();
584}
585
586void UseCounter::count(const Document& document, Feature feature)
587{
588    FrameHost* host = document.frameHost();
589    if (!host)
590        return;
591
592    ASSERT(host->useCounter().deprecationMessage(feature).isEmpty());
593    host->useCounter().recordMeasurement(feature);
594}
595
596void UseCounter::count(const ExecutionContext* context, Feature feature)
597{
598    if (!context)
599        return;
600    if (context->isDocument()) {
601        count(*toDocument(context), feature);
602        return;
603    }
604    if (context->isWorkerGlobalScope())
605        toWorkerGlobalScope(context)->countFeature(feature);
606}
607
608void UseCounter::countDeprecation(ExecutionContext* context, Feature feature)
609{
610    if (!context)
611        return;
612    if (context->isDocument()) {
613        UseCounter::countDeprecation(*toDocument(context), feature);
614        return;
615    }
616    if (context->isWorkerGlobalScope())
617        toWorkerGlobalScope(context)->countDeprecation(feature);
618}
619
620void UseCounter::countDeprecation(const LocalDOMWindow* window, Feature feature)
621{
622    if (!window || !window->document())
623        return;
624    UseCounter::countDeprecation(*window->document(), feature);
625}
626
627void UseCounter::countDeprecation(const Document& document, Feature feature)
628{
629    FrameHost* host = document.frameHost();
630    LocalFrame* frame = document.frame();
631    if (!host || !frame)
632        return;
633
634    if (host->useCounter().recordMeasurement(feature)) {
635        ASSERT(!host->useCounter().deprecationMessage(feature).isEmpty());
636        frame->console().addMessage(ConsoleMessage::create(DeprecationMessageSource, WarningMessageLevel, host->useCounter().deprecationMessage(feature)));
637    }
638}
639
640// FIXME: Update other UseCounter::deprecationMessage() cases to use this.
641static String replacedBy(const char* oldString, const char* newString)
642{
643    return String::format("'%s' is deprecated. Please use '%s' instead.", oldString, newString);
644}
645
646String UseCounter::deprecationMessage(Feature feature)
647{
648    switch (feature) {
649    // Quota
650    case PrefixedStorageInfo:
651        return "'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.";
652
653    // Keyboard Event (DOM Level 3)
654    case KeyboardEventKeyLocation:
655        return replacedBy("KeyboardEvent.keyLocation", "KeyboardEvent.location");
656
657    case ConsoleMarkTimeline:
658        return "console.markTimeline is deprecated. Please use the console.timeStamp instead.";
659
660    case FileError:
661        return "FileError is deprecated. Please use the 'name' or 'message' attributes of DOMError rather than 'code'.";
662
663    case ShowModalDialog:
664        return "showModalDialog is deprecated. Please use window.open and postMessage instead.";
665
666    case CSSStyleSheetInsertRuleOptionalArg:
667        return "Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0).";
668
669    case PrefixedVideoSupportsFullscreen:
670        return "'HTMLVideoElement.webkitSupportsFullscreen' is deprecated. Its value is true if the video is loaded.";
671
672    case PrefixedVideoDisplayingFullscreen:
673        return "'HTMLVideoElement.webkitDisplayingFullscreen' is deprecated. Please use the 'fullscreenchange' and 'webkitfullscreenchange' events instead.";
674
675    case PrefixedVideoEnterFullscreen:
676        return "'HTMLVideoElement.webkitEnterFullscreen()' is deprecated. Please use 'Element.requestFullscreen()' and 'Element.webkitRequestFullscreen()' instead.";
677
678    case PrefixedVideoExitFullscreen:
679        return "'HTMLVideoElement.webkitExitFullscreen()' is deprecated. Please use 'Document.exitFullscreen()' and 'Document.webkitExitFullscreen()' instead.";
680
681    case PrefixedVideoEnterFullScreen:
682        return "'HTMLVideoElement.webkitEnterFullScreen()' is deprecated. Please use 'Element.requestFullscreen()' and 'Element.webkitRequestFullscreen()' instead.";
683
684    case PrefixedVideoExitFullScreen:
685        return "'HTMLVideoElement.webkitExitFullScreen()' is deprecated. Please use 'Document.exitFullscreen()' and 'Document.webkitExitFullscreen()' instead.";
686
687    case MediaErrorEncrypted:
688        return "'MediaError.MEDIA_ERR_ENCRYPTED' is deprecated. This error code is never used.";
689
690    case PrefixedGamepad:
691        return replacedBy("navigator.webkitGetGamepads", "navigator.getGamepads");
692
693    case PrefixedIndexedDB:
694        return replacedBy("webkitIndexedDB", "indexedDB");
695
696    case PrefixedIDBCursorConstructor:
697        return replacedBy("webkitIDBCursor", "IDBCursor");
698
699    case PrefixedIDBDatabaseConstructor:
700        return replacedBy("webkitIDBDatabase", "IDBDatabase");
701
702    case PrefixedIDBFactoryConstructor:
703        return replacedBy("webkitIDBFactory", "IDBFactory");
704
705    case PrefixedIDBIndexConstructor:
706        return replacedBy("webkitIDBIndex", "IDBIndex");
707
708    case PrefixedIDBKeyRangeConstructor:
709        return replacedBy("webkitIDBKeyRange", "IDBKeyRange");
710
711    case PrefixedIDBObjectStoreConstructor:
712        return replacedBy("webkitIDBObjectStore", "IDBObjectStore");
713
714    case PrefixedIDBRequestConstructor:
715        return replacedBy("webkitIDBRequest", "IDBRequest");
716
717    case PrefixedIDBTransactionConstructor:
718        return replacedBy("webkitIDBTransaction", "IDBTransaction");
719
720    case PrefixedRequestAnimationFrame:
721        return "'webkitRequestAnimationFrame' is vendor-specific. Please use the standard 'requestAnimationFrame' instead.";
722
723    case PrefixedCancelAnimationFrame:
724        return "'webkitCancelAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead.";
725
726    case PrefixedCancelRequestAnimationFrame:
727        return "'webkitCancelRequestAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead.";
728
729    case DocumentCreateAttributeNS:
730        return "'Document.createAttributeNS' is deprecated and has been removed from DOM4 (http://w3.org/tr/dom).";
731
732    case AttributeOwnerElement:
733        return "'Attr.ownerElement' is deprecated and has been removed from DOM4 (http://w3.org/tr/dom).";
734
735    case ElementSetAttributeNodeNS:
736        return "'Element.setAttributeNodeNS' is deprecated and has been removed from DOM4 (http://w3.org/tr/dom).";
737
738    case NodeIteratorDetach:
739        return "'NodeIterator.detach' is now a no-op, as per DOM (http://dom.spec.whatwg.org/#dom-nodeiterator-detach).";
740
741    case AttrNodeValue:
742        return replacedBy("Attr.nodeValue", "value");
743
744    case AttrTextContent:
745        return replacedBy("Attr.textContent", "value");
746
747    case NodeIteratorExpandEntityReferences:
748        return "'NodeIterator.expandEntityReferences' is deprecated and has been removed from DOM. It always returns false.";
749
750    case TreeWalkerExpandEntityReferences:
751        return "'TreeWalker.expandEntityReferences' is deprecated and has been removed from DOM. It always returns false.";
752
753    case RangeDetach:
754        return "'Range.detach' is now a no-op, as per DOM (http://dom.spec.whatwg.org/#dom-range-detach).";
755
756    case OverflowChangedEvent:
757        return "The 'overflowchanged' event is deprecated and may be removed. Please do not use it.";
758
759    case HTMLHeadElementProfile:
760        return "'HTMLHeadElement.profile' is deprecated. The reflected attribute has no effect.";
761
762    case ElementSetPrefix:
763        return "Setting 'Element.prefix' is deprecated, as it is read-only per DOM (http://dom.spec.whatwg.org/#element).";
764
765    case SyncXHRWithCredentials:
766        return "Setting 'XMLHttpRequest.withCredentials' for synchronous requests is deprecated.";
767
768    case EventSourceURL:
769        return "'EventSource.URL' is deprecated. Please use 'EventSource.url' instead.";
770
771    case WebSocketURL:
772        return "'WebSocket.URL' is deprecated. Please use 'WebSocket.url' instead.";
773
774    case HTMLTableElementVspace:
775        return "The 'vspace' attribute on table is deprecated. Please use CSS instead.";
776
777    case HTMLTableElementHspace:
778        return "The 'hspace' attribute on table is deprecated. Please use CSS instead.";
779
780    case PictureSourceSrc:
781        return "<source src> with a <picture> parent is invalid and therefore ignored. Please use <source srcset> instead.";
782
783    case XHRProgressEventPosition:
784        return "The XMLHttpRequest progress event property 'position' is deprecated. Please use 'loaded' instead.";
785
786    case XHRProgressEventTotalSize:
787        return "The XMLHttpRequest progress event property 'totalSize' is deprecated. Please use 'total' instead.";
788
789    case ConsoleTimeline:
790        return "console.timeline is deprecated. Please use the console.time instead.";
791
792    case ConsoleTimelineEnd:
793        return "console.timelineEnd is deprecated. Please use the console.timeEnd instead.";
794
795    // Features that aren't deprecated don't have a deprecation message.
796    default:
797        return String();
798    }
799}
800
801void UseCounter::count(CSSParserContext context, CSSPropertyID feature)
802{
803    ASSERT(feature >= firstCSSProperty);
804    ASSERT(feature <= lastCSSProperty);
805    ASSERT(!isInternalProperty(feature));
806
807    if (!isUseCounterEnabledForMode(context.mode()))
808        return;
809
810    m_CSSFeatureBits.quickSet(feature);
811}
812
813void UseCounter::count(Feature feature)
814{
815    ASSERT(deprecationMessage(feature).isEmpty());
816    recordMeasurement(feature);
817}
818
819UseCounter* UseCounter::getFrom(const Document* document)
820{
821    if (document && document->frameHost())
822        return &document->frameHost()->useCounter();
823    return 0;
824}
825
826UseCounter* UseCounter::getFrom(const CSSStyleSheet* sheet)
827{
828    if (sheet)
829        return getFrom(sheet->contents());
830    return 0;
831}
832
833UseCounter* UseCounter::getFrom(const StyleSheetContents* sheetContents)
834{
835    // FIXME: We may want to handle stylesheets that have multiple owners
836    //        http://crbug.com/242125
837    if (sheetContents && sheetContents->hasSingleOwnerNode())
838        return getFrom(sheetContents->singleOwnerDocument());
839    return 0;
840}
841
842} // namespace blink
843