+static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4])
+{
+ if (radii[3])
+ return;
+ if (!radii[2]) {
+ if (!radii[1])
+ radii[1] = radii[0];
+ radii[2] = radii[0];
+ }
+ radii[3] = radii[1];
+}
+
+// FIXME: This should be refactored with CSSParser::parseBorderRadius.
+// CSSParser::parseBorderRadius contains support for some legacy radius construction.
+PassRefPtr<CSSBasicShape> BisonCSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicShapeInset> shape, CSSParserValueList* args)
+{
+ CSSParserValue* argument = args->next();
+
+ if (!argument)
+ return 0;
+
+ CSSParserValueList radiusArguments;
+ while (argument) {
+ radiusArguments.addValue(*argument);
+ argument = args->next();
+ }
+
+ unsigned num = radiusArguments.size();
+ if (!num || num > 9)
+ return 0;
+
+ // FIXME: Refactor completeBorderRadii and the array
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
+
+ unsigned indexAfterSlash = 0;
+ for (unsigned i = 0; i < num; ++i) {
+ CSSParserValue* value = radiusArguments.valueAt(i);
+ if (value->unit == CSSParserValue::Operator) {
+ if (value->iValue != '/')
+ return 0;
+
+ if (!i || indexAfterSlash || i + 1 == num)
+ return 0;
+
+ indexAfterSlash = i + 1;
+ completeBorderRadii(radii[0]);
+ continue;
+ }
+
+ if (i - indexAfterSlash >= 4)
+ return 0;
+
+ if (!validUnit(value, FLength | FPercent | FNonNeg))
+ return 0;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
+
+ if (!indexAfterSlash)
+ radii[0][i] = radius;
+ else
+ radii[1][i - indexAfterSlash] = radius.release();
+ }
+
+ if (!indexAfterSlash) {
+ completeBorderRadii(radii[0]);
+ for (unsigned i = 0; i < 4; ++i)
+ radii[1][i] = radii[0][i];
+ } else {
+ completeBorderRadii(radii[1]);
+ }
+ shape->setTopLeftRadius(createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()));
+ shape->setTopRightRadius(createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()));
+ shape->setBottomRightRadius(createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()));
+ shape->setBottomLeftRadius(createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()));
+
+ return shape;
+}
+
+PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapeInset(CSSParserValueList* args)
+{
+ ASSERT(args);
+
+ RefPtr<CSSBasicShapeInset> shape = CSSBasicShapeInset::create();
+
+ CSSParserValue* argument = args->current();
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> > widthArguments;
+ bool hasRoundedInset = false;
+
+ while (argument) {
+ if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(argument->string, "round")) {
+ hasRoundedInset = true;
+ break;
+ }
+
+ Units unitFlags = FLength | FPercent;
+ if (!validUnit(argument, unitFlags) || widthArguments.size() > 4)
+ return 0;
+
+ widthArguments.append(createPrimitiveNumericValue(argument));
+ argument = args->next();
+ }
+
+ switch (widthArguments.size()) {
+ case 1: {
+ shape->updateShapeSize1Value(widthArguments[0].get());
+ break;
+ }
+ case 2: {
+ shape->updateShapeSize2Values(widthArguments[0].get(), widthArguments[1].get());
+ break;
+ }
+ case 3: {
+ shape->updateShapeSize3Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get());
+ break;
+ }
+ case 4: {
+ shape->updateShapeSize4Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get(), widthArguments[3].get());
+ break;
+ }
+ default:
+ return 0;
+ }
+
+ if (hasRoundedInset)
+ return parseInsetRoundedCorners(shape, args);
+ return shape;
+}
+