Source/WebCore/ChangeLog

 12012-08-16 Michelangelo De Simone <michelangelo@webkit.org>
 2
 3 [Part 3] Parse the custom() function in -webkit-filter: parse the 3d-transforms parameters
 4 https://bugs.webkit.org/show_bug.cgi?id=71443
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 custom() now correctly parses the 3d-tranforms parameters. In order to do that the parseTransform() method
 9 has been refactored and split to reuse already present code.
 10
 11 * css/CSSParser.cpp:
 12 (WebCore::parseTranslateTransformValue): Renamed from parseTransformValue()
 13 (WebCore::CSSParser::parseValue): Reference updated from parseTransformValue() to parseTranslateTransformValue()
 14 (WebCore::CSSParser::parseTransform): This method has been split in two to reuse already present code
 15 (WebCore):
 16 (WebCore::CSSParser::parseTransformValue): New method to parse single transform values
 17 (WebCore::CSSParser::parseCustomFilter): Updated to parse the transform parameters
 18 (WebCore::CSSParser::parseCustomFilterTransform): New method to parse custom() transforms
 19 * css/CSSParser.h:
 20
1212012-08-15 Joanmarie Diggs <jdiggs@igalia.com>
222
323 [Gtk] atk_text_get_text_at_offset() fails to provide the correct line for paragraphs in list items whose text wraps

Source/WebCore/css/CSSParser.cpp

@@static bool parseTransformArguments(WebKitCSSTransformValue* transformValue, Cha
10411041 return true;
10421042}
10431043
1044 static bool parseTransformValue(StylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
 1044static bool parseTranslateTransformValue(StylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
10451045{
10461046 if (propertyID != CSSPropertyWebkitTransform)
10471047 return false;

@@bool CSSParser::parseValue(StylePropertySet* declaration, CSSPropertyID property
11261126 return true;
11271127 if (parseKeywordValue(declaration, propertyID, string, important, contextStyleSheet->parserContext()))
11281128 return true;
1129  if (parseTransformValue(declaration, propertyID, string, important))
 1129 if (parseTranslateTransformValue(declaration, propertyID, string, important))
11301130 return true;
11311131
11321132 CSSParserContext context(cssParserMode);

@@bool CSSParser::parseValue(CSSPropertyID propId, bool important)
23202320 if (id == CSSValueNone)
23212321 validPrimitive = true;
23222322 else {
2323  PassRefPtr<CSSValue> val = parseTransform();
2324  if (val) {
2325  addProperty(propId, val, important);
 2323 RefPtr<CSSValue> transformValue = parseTransform();
 2324 if (transformValue) {
 2325 addProperty(propId, transformValue.release(), important);
23262326 return true;
23272327 }
23282328 return false;

@@PassRefPtr<CSSValueList> CSSParser::parseTransform()
72717271 if (!m_valueList)
72727272 return 0;
72737273
7274  // The transform is a list of functional primitives that specify transform operations.
7275  // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation.
72767274 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
72777275 for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
7278  if (value->unit != CSSParserValue::Function || !value->function)
 7276 RefPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
 7277 if (!parsedTransformValue)
72797278 return 0;
72807279
7281  // Every primitive requires at least one argument.
7282  CSSParserValueList* args = value->function->args.get();
7283  if (!args)
7284  return 0;
 7280 list->append(parsedTransformValue.release());
 7281 }
72857282
7286  // See if the specified primitive is one we understand.
7287  TransformOperationInfo info(value->function->name);
7288  if (info.unknown())
7289  return 0;
 7283 return list.release();
 7284}
 7285
72907286
7291  if (!info.hasCorrectArgCount(args->size()))
7292  return 0;
 7287PassRefPtr<CSSValue> CSSParser::parseTransformValue(CSSParserValue *value)
 7288{
 7289 if (value->unit != CSSParserValue::Function || !value->function)
 7290 return 0;
 7291
 7292 // Every primitive requires at least one argument.
 7293 CSSParserValueList* args = value->function->args.get();
 7294 if (!args)
 7295 return 0;
72937296
7294  // Create the new WebKitCSSTransformValue for this operation and add it to our list.
7295  RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(info.type());
7296  list->append(transformValue);
 7297 // See if the specified primitive is one we understand.
 7298 TransformOperationInfo info(value->function->name);
 7299 if (info.unknown())
 7300 return 0;
72977301
7298  // Snag our values.
7299  CSSParserValue* a = args->current();
7300  unsigned argNumber = 0;
7301  while (a) {
7302  CSSParser::Units unit = info.unit();
 7302 if (!info.hasCorrectArgCount(args->size()))
 7303 return 0;
73037304
7304  if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
7305  // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
7306  if (!validUnit(a, FAngle, CSSStrictMode))
7307  return 0;
7308  } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
7309  // 3rd param of translate3d() cannot be a percentage
7310  if (!validUnit(a, FLength, CSSStrictMode))
7311  return 0;
7312  } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation && argNumber == 0) {
7313  // 1st param of translateZ() cannot be a percentage
7314  if (!validUnit(a, FLength, CSSStrictMode))
7315  return 0;
7316  } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && argNumber == 0) {
7317  // 1st param of perspective() must be a non-negative number (deprecated) or length.
7318  if (!validUnit(a, FNumber | FLength | FNonNeg, CSSStrictMode))
7319  return 0;
7320  } else if (!validUnit(a, unit, CSSStrictMode))
7321  return 0;
 7305 // The transform is a list of functional primitives that specify transform operations.
 7306 // We collect a list of WebKitCSSTransformValues, where each value specifies a single operation.
73227307
7323  // Add the value to the current transform operation.
7324  transformValue->append(createPrimitiveNumericValue(a));
 7308 // Create the new WebKitCSSTransformValue for this operation and add it to our list.
 7309 RefPtr<WebKitCSSTransformValue> transformValue = WebKitCSSTransformValue::create(info.type());
73257310
7326  a = args->next();
7327  if (!a)
7328  break;
7329  if (a->unit != CSSParserValue::Operator || a->iValue != ',')
 7311 // Snag our values.
 7312 CSSParserValue* a = args->current();
 7313 unsigned argNumber = 0;
 7314 while (a) {
 7315 CSSParser::Units unit = info.unit();
 7316
 7317 if (info.type() == WebKitCSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
 7318 // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
 7319 if (!validUnit(a, FAngle, CSSStrictMode))
73307320 return 0;
7331  a = args->next();
 7321 } else if (info.type() == WebKitCSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
 7322 // 3rd param of translate3d() cannot be a percentage
 7323 if (!validUnit(a, FLength, CSSStrictMode))
 7324 return 0;
 7325 } else if (info.type() == WebKitCSSTransformValue::TranslateZTransformOperation && !argNumber) {
 7326 // 1st param of translateZ() cannot be a percentage
 7327 if (!validUnit(a, FLength, CSSStrictMode))
 7328 return 0;
 7329 } else if (info.type() == WebKitCSSTransformValue::PerspectiveTransformOperation && !argNumber) {
 7330 // 1st param of perspective() must be a non-negative number (deprecated) or length.
 7331 if (!validUnit(a, FNumber | FLength | FNonNeg, CSSStrictMode))
 7332 return 0;
 7333 } else if (!validUnit(a, unit, CSSStrictMode))
 7334 return 0;
73327335
7333  argNumber++;
7334  }
 7336 // Add the value to the current transform operation.
 7337 transformValue->append(createPrimitiveNumericValue(a));
 7338
 7339 a = args->next();
 7340 if (!a)
 7341 break;
 7342 if (a->unit != CSSParserValue::Operator || a->iValue != ',')
 7343 return 0;
 7344 a = args->next();
 7345
 7346 argNumber++;
73357347 }
73367348
7337  return list.release();
 7349 return transformValue.release();
73387350}
73397351
73407352bool CSSParser::isBlendMode(int ident)

@@PassRefPtr<WebKitCSSFilterValue> CSSParser::parseCustomFilter(CSSParserValue* va
75567568 if (!(arg = argsList->current()))
75577569 return 0;
75587570
 7571 RefPtr<CSSValue> parameterValue;
 7572
75597573 // TODO: Implement other parameters types parsing.
75607574 // textures: https://bugs.webkit.org/show_bug.cgi?id=71442
7561  // 3d-transforms: https://bugs.webkit.org/show_bug.cgi?id=71443
75627575 // mat2, mat3, mat4: https://bugs.webkit.org/show_bug.cgi?id=71444
7563  RefPtr<CSSValueList> paramValueList = CSSValueList::createSpaceSeparated();
7564  while ((arg = argsList->current())) {
7565  // If we hit a comma it means we finished this parameter's values.
7566  if (isComma(arg))
7567  break;
7568  if (!validUnit(arg, FNumber, CSSStrictMode))
 7576 // array: https://bugs.webkit.org/show_bug.cgi?id=94226
 7577 // 3d-transform shall be the last to be checked
 7578 if (arg->unit == CSSParserValue::Function && arg->function)
 7579 parameterValue = parseCustomFilterTransform(argsList);
 7580 else {
 7581 RefPtr<CSSValueList> paramValueList = CSSValueList::createSpaceSeparated();
 7582 while ((arg = argsList->current())) {
 7583 // If we hit a comma it means we finished this parameter's values.
 7584 if (isComma(arg))
 7585 break;
 7586 if (!validUnit(arg, FNumber, CSSStrictMode))
 7587 return 0;
 7588 paramValueList->append(cssValuePool().createValue(arg->fValue, CSSPrimitiveValue::CSS_NUMBER));
 7589 argsList->next();
 7590 }
 7591 if (!paramValueList->length() || paramValueList->length() > 4)
75697592 return 0;
7570  paramValueList->append(cssValuePool().createValue(arg->fValue, CSSPrimitiveValue::CSS_NUMBER));
7571  argsList->next();
 7593 parameterValue = paramValueList.release();
75727594 }
7573  if (!paramValueList->length() || paramValueList->length() > 4)
 7595
 7596 if (!parameterValue || !acceptCommaOperator(argsList))
75747597 return 0;
7575  parameter->append(paramValueList.release());
 7598
 7599 parameter->append(parameterValue.release());
75767600 paramList->append(parameter.release());
7577  if (!acceptCommaOperator(argsList))
7578  return 0;
75797601 }
75807602
75817603 if (paramList->length())

@@PassRefPtr<WebKitCSSFilterValue> CSSParser::parseCustomFilter(CSSParserValue* va
75837605
75847606 return filterValue;
75857607}
 7608
 7609PassRefPtr<CSSValueList> CSSParser::parseCustomFilterTransform(CSSParserValueList* valueList)
 7610{
 7611 if (!valueList)
 7612 return 0;
 7613
 7614 // CSS Shaders' custom() transforms are space separated and comma terminated.
 7615 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
 7616 for (CSSParserValue* value = valueList->current(); value; value = valueList->next()) {
 7617 if (isComma(value))
 7618 break;
 7619
 7620 RefPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
 7621 if (!parsedTransformValue)
 7622 return 0;
 7623
 7624 list->append(parsedTransformValue.release());
 7625 }
 7626
 7627 return list.release();
 7628}
75867629#endif
75877630
75887631PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParserValueList* args, WebKitCSSFilterValue::FilterOperationType filterType)

Source/WebCore/css/CSSParser.h

@@public:
219219#if ENABLE(CSS_SHADERS)
220220 PassRefPtr<WebKitCSSMixFunctionValue> parseMixFunction(CSSParserValue*);
221221 PassRefPtr<WebKitCSSFilterValue> parseCustomFilter(CSSParserValue*);
 222 PassRefPtr<CSSValueList> parseCustomFilterTransform(CSSParserValueList*);
222223#endif
223224#endif
224225

@@public:
226227 static bool isCompositeOperator(int ident);
227228
228229 PassRefPtr<CSSValueList> parseTransform();
 230 PassRefPtr<CSSValue> parseTransformValue(CSSParserValue*);
229231 bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
230232 bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
231233

LayoutTests/ChangeLog

 12012-08-16 Michelangelo De Simone <michelangelo@webkit.org>
 2
 3 [Part 3] Parse the custom() function in -webkit-filter: parse the 3d-transforms parameters
 4 https://bugs.webkit.org/show_bug.cgi?id=71443
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 New round of tests for custom() to assess the correct parsing of the 3d-transform parameters.
 9
 10 * css3/filters/custom/custom-filter-property-parsing-expected.txt:
 11 * css3/filters/custom/custom-filter-property-parsing-invalid-expected.txt:
 12 * css3/filters/script-tests/custom-filter-property-parsing-invalid.js:
 13 * css3/filters/script-tests/custom-filter-property-parsing.js:
 14 * platform/chromium/css3/filters/custom/custom-filter-property-parsing-expected.txt:
 15
1162012-08-15 Arpita Bahuguna <arpitabahuguna@gmail.com>
217
318 There is additional space not belonged to a table between the table cells

LayoutTests/css3/filters/custom/custom-filter-property-parsing-expected.txt

@@PASS jsWrapperClass(filterRule.constructor) is 'CSSValueListConstructor'
513513PASS filterRule.length is 1
514514PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CUSTOM
515515PASS removeBaseURL(subRule.cssText) is 'custom(url(vertex.shader))'
 516
 517Custom with one transform : custom(none url(fragment.shader), oneTransform rotate(0deg))
 518PASS cssRule.type is 1
 519PASS declaration.length is 1
 520PASS removeBaseURL(declaration.getPropertyValue('-webkit-filter')) is 'custom(none url(fragment.shader), oneTransform rotate(0deg))'
 521PASS jsWrapperClass(filterRule) is 'CSSValueList'
 522PASS jsWrapperClass(filterRule.__proto__) is 'CSSValueListPrototype'
 523PASS jsWrapperClass(filterRule.constructor) is 'CSSValueListConstructor'
 524PASS filterRule.length is 1
 525PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CUSTOM
 526PASS removeBaseURL(subRule.cssText) is 'custom(none url(fragment.shader), oneTransform rotate(0deg))'
 527
 528Custom with multiple transforms : custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))
 529PASS cssRule.type is 1
 530PASS declaration.length is 1
 531PASS removeBaseURL(declaration.getPropertyValue('-webkit-filter')) is 'custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))'
 532PASS jsWrapperClass(filterRule) is 'CSSValueList'
 533PASS jsWrapperClass(filterRule.__proto__) is 'CSSValueListPrototype'
 534PASS jsWrapperClass(filterRule.constructor) is 'CSSValueListConstructor'
 535PASS filterRule.length is 1
 536PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CUSTOM
 537PASS removeBaseURL(subRule.cssText) is 'custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))'
516538PASS successfullyParsed is true
517539
518540TEST COMPLETE

LayoutTests/css3/filters/custom/custom-filter-property-parsing-invalid-expected.txt

@@No parameter value 2 : custom(url(shader), p1, p2, p3)
213213PASS cssRule.type is 1
214214PASS declaration.length is 0
215215PASS declaration.getPropertyValue('-webkit-filter') is null
 216
 217One invalid transform : custom(none url(shader), someId invalid_rotate(0deg))
 218PASS cssRule.type is 1
 219PASS declaration.length is 0
 220PASS declaration.getPropertyValue('-webkit-filter') is null
 221
 222Multiple invalid transforms : custom(none url(shader), someId invalid_rotate(0deg) invalid_perspective(0))
 223PASS cssRule.type is 1
 224PASS declaration.length is 0
 225PASS declaration.getPropertyValue('-webkit-filter') is null
 226
 227Invalid transform between valid ones : custom(none url(shader), someId rotate(0deg) invalid_rotate(0deg) perspective(0))
 228PASS cssRule.type is 1
 229PASS declaration.length is 0
 230PASS declaration.getPropertyValue('-webkit-filter') is null
 231
 232Valid transform between invalid ones : custom(none url(shader), someId invalid_rotate(0deg) perspective(0) another_invalid(0))
 233PASS cssRule.type is 1
 234PASS declaration.length is 0
 235PASS declaration.getPropertyValue('-webkit-filter') is null
 236
 237Valid transform without leading comma : custom(none url(shader) someId perspective(0))
 238PASS cssRule.type is 1
 239PASS declaration.length is 0
 240PASS declaration.getPropertyValue('-webkit-filter') is null
 241
 242Valid transform with trailing comma : custom(none url(shader), someId perspective(0),)
 243PASS cssRule.type is 1
 244PASS declaration.length is 0
 245PASS declaration.getPropertyValue('-webkit-filter') is null
 246
 247Valid transform with trailing comma and without leading comma : custom(none url(shader) someId perspective(0),)
 248PASS cssRule.type is 1
 249PASS declaration.length is 0
 250PASS declaration.getPropertyValue('-webkit-filter') is null
 251
 252Invalid transform with trailing comma : custom(none url(shader), someId invalid_rotate(0deg),)
 253PASS cssRule.type is 1
 254PASS declaration.length is 0
 255PASS declaration.getPropertyValue('-webkit-filter') is null
 256
 257Invalid transform without leading comma : custom(none url(shader) someId invalid_rotate(0deg))
 258PASS cssRule.type is 1
 259PASS declaration.length is 0
 260PASS declaration.getPropertyValue('-webkit-filter') is null
 261
 262Empty transform (only the id) : custom(none url(shader), someId)
 263PASS cssRule.type is 1
 264PASS declaration.length is 0
 265PASS declaration.getPropertyValue('-webkit-filter') is null
 266
 267Empty transform (without the id) : custom(none url(shader),)
 268PASS cssRule.type is 1
 269PASS declaration.length is 0
 270PASS declaration.getPropertyValue('-webkit-filter') is null
 271
 272Empty transform (two empty commas) : custom(none url(shader),,)
 273PASS cssRule.type is 1
 274PASS declaration.length is 0
 275PASS declaration.getPropertyValue('-webkit-filter') is null
 276
 277Valid transform with invalid characters : custom(none url(shader),someId rotate(0deg) *.-,)
 278PASS cssRule.type is 1
 279PASS declaration.length is 0
 280PASS declaration.getPropertyValue('-webkit-filter') is null
216281PASS successfullyParsed is true
217282
218283TEST COMPLETE

LayoutTests/css3/filters/script-tests/custom-filter-property-parsing-invalid.js

@@testInvalidFilterRule("Invalid parameter types", "custom(url(shader), p1 1.0 2.0
7575testInvalidFilterRule("No parameter value 1", "custom(url(shader), p1)");
7676testInvalidFilterRule("No parameter value 2", "custom(url(shader), p1, p2, p3)");
7777
 78testInvalidFilterRule("One invalid transform", "custom(none url(shader), someId invalid_rotate(0deg))");
 79testInvalidFilterRule("Multiple invalid transforms", "custom(none url(shader), someId invalid_rotate(0deg) invalid_perspective(0))");
 80testInvalidFilterRule("Invalid transform between valid ones", "custom(none url(shader), someId rotate(0deg) invalid_rotate(0deg) perspective(0))");
 81testInvalidFilterRule("Valid transform between invalid ones", "custom(none url(shader), someId invalid_rotate(0deg) perspective(0) another_invalid(0))");
 82testInvalidFilterRule("Valid transform without leading comma", "custom(none url(shader) someId perspective(0))");
 83testInvalidFilterRule("Valid transform with trailing comma", "custom(none url(shader), someId perspective(0),)");
 84testInvalidFilterRule("Valid transform with trailing comma and without leading comma", "custom(none url(shader) someId perspective(0),)");
 85testInvalidFilterRule("Invalid transform with trailing comma", "custom(none url(shader), someId invalid_rotate(0deg),)");
 86testInvalidFilterRule("Invalid transform without leading comma", "custom(none url(shader) someId invalid_rotate(0deg))");
 87testInvalidFilterRule("Empty transform (only the id)", "custom(none url(shader), someId)");
 88testInvalidFilterRule("Empty transform (without the id)", "custom(none url(shader),)");
 89testInvalidFilterRule("Empty transform (two empty commas)", "custom(none url(shader),,)");
 90testInvalidFilterRule("Valid transform with invalid characters", "custom(none url(shader),someId rotate(0deg) *.-,)");

LayoutTests/css3/filters/script-tests/custom-filter-property-parsing.js

@@testFilterRule("Multiple with fragment shader",
155155
156156testFilterRule("Custom in CAPS",
157157 "CUSTOM(url(vertex.shader))", "custom(url(vertex.shader))");
 158
 159testFilterRule("Custom with one transform",
 160 "custom(none url(fragment.shader), oneTransform rotate(0deg))",
 161 "custom(none url(fragment.shader), oneTransform rotate(0deg))");
 162
 163testFilterRule("Custom with multiple transforms",
 164 "custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))",
 165 "custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))");

LayoutTests/platform/chromium/css3/filters/custom/custom-filter-property-parsing-expected.txt

@@FAIL jsWrapperClass(filterRule.constructor) should be CSSValueListConstructor. W
513513PASS filterRule.length is 1
514514PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CUSTOM
515515PASS removeBaseURL(subRule.cssText) is 'custom(url(vertex.shader))'
 516
 517Custom with one transform : custom(none url(fragment.shader), oneTransform rotate(0deg))
 518PASS cssRule.type is 1
 519PASS declaration.length is 1
 520PASS removeBaseURL(declaration.getPropertyValue('-webkit-filter')) is 'custom(none url(fragment.shader), oneTransform rotate(0deg))'
 521PASS jsWrapperClass(filterRule) is 'CSSValueList'
 522FAIL jsWrapperClass(filterRule.__proto__) should be CSSValueListPrototype. Was Object.
 523FAIL jsWrapperClass(filterRule.constructor) should be CSSValueListConstructor. Was Function.
 524PASS filterRule.length is 1
 525PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CUSTOM
 526PASS removeBaseURL(subRule.cssText) is 'custom(none url(fragment.shader), oneTransform rotate(0deg))'
 527
 528Custom with multiple transforms : custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))
 529PASS cssRule.type is 1
 530PASS declaration.length is 1
 531PASS removeBaseURL(declaration.getPropertyValue('-webkit-filter')) is 'custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))'
 532PASS jsWrapperClass(filterRule) is 'CSSValueList'
 533FAIL jsWrapperClass(filterRule.__proto__) should be CSSValueListPrototype. Was Object.
 534FAIL jsWrapperClass(filterRule.constructor) should be CSSValueListConstructor. Was Function.
 535PASS filterRule.length is 1
 536PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CUSTOM
 537PASS removeBaseURL(subRule.cssText) is 'custom(none url(fragment.shader), multipleTransform rotate(0deg) perspective(0) scale(0, 0) translate(0px, 0px))'
516538PASS successfullyParsed is true
517539
518540TEST COMPLETE