Statement poolDecls = null;
if (!stringPool.isEmpty()) {
poolDecls = joinDeclarations(
poolDecls,
new Declaration(unk, new Identifier(unk, "s"),
new ArrayConstructor(unk, stringPool)));
}
if (!regexPool.isEmpty()) {
poolDecls = joinDeclarations(
poolDecls,
new Declaration(unk, new Identifier(unk, "c"),
new ArrayConstructor(unk, regexPool)));
}
// Given keyword sets like
// [['red','blue','green','transparent','inherit',;none'],
// ['red','blue','green'],
// ['inherit','none','bold','bolder']]
// recognize that ['red','blue','green'] probably occurs frequently and
// create a partition like
// [['red','blue','green'],['bold','bolder'],['inherit',none'],
// ['transparent']]
// and then store indices into the array of partition elements with
// CSS property names so they can be unioned as needed.
List<Set<String>> literalSets = Lists.newArrayList();
for (Pair<CssSchema.CssPropertyInfo, CssPropertyData> p : propData) {
literalSets.add(p.b.literals);
}
Partitions.Partition<String> litPartition = Partitions.partition(
literalSets, String.class, null);
List<ArrayConstructor> literalSetArrs = Lists.newArrayList();
for (int[] literalIndices : litPartition.partition) {
List<StringLiteral> literalArr = Lists.newArrayList();
for (int litIndex : literalIndices) {
literalArr.add(StringLiteral.valueOf(
unk, litPartition.universe[litIndex]));
}
literalSetArrs.add(new ArrayConstructor(unk, literalArr));
}
if (!literalSetArrs.isEmpty()) {
poolDecls = joinDeclarations(
poolDecls,
new Declaration(unk, new Identifier(unk, "L"),
new ArrayConstructor(unk, literalSetArrs)));
}
List<ValueProperty> cssSchemaProps = Lists.newArrayList();
StringLiteral regexObjKey = new StringLiteral(unk, "cssExtra");
StringLiteral alternatesObjKey = new StringLiteral(unk, "cssAlternates");
StringLiteral propbitsObjKey = new StringLiteral(unk, "cssPropBits");
StringLiteral litgroupObjKey = new StringLiteral(unk, "cssLitGroup");
for (int propIndex = 0, n = propData.size(); propIndex < n; ++propIndex) {
Pair<CssSchema.CssPropertyInfo, CssPropertyData> d
= propData.get(propIndex);
CssSchema.CssPropertyInfo prop = d.a;
CssPropertyData data = d.b;
ObjectConstructor dataObj = new ObjectConstructor(unk);
String regex = data.regex;
if (regex != null) {
int poolIndex = regexPoolMap.get(regex)[0];
Expression re = poolIndex < 0
? makeRegexp(commonSubstringMap, regex)
: (Expression) QuasiBuilder.substV(
"c[@i]", "i", new IntegerLiteral(unk, poolIndex));
dataObj.appendChild(new ValueProperty(regexObjKey, re));
}
String dom2property = propertyNameToDom2Property(prop.name);
ArrayConstructor altNames = null;
for (String altDom2Property : prop.dom2properties) {
if (altDom2Property.equals(dom2property)) { continue; }
if (altNames == null) {
altNames = new ArrayConstructor(
unk, Collections.<Expression>emptyList());
}
altNames.appendChild(StringLiteral.valueOf(unk, altDom2Property));
}
if (altNames != null) {
dataObj.appendChild(new ValueProperty(alternatesObjKey, altNames));
}
cssSchemaProps.add(new ValueProperty(
unk, StringLiteral.valueOf(unk, prop.name.getCanonicalForm()),
dataObj));
int propBits = 0;
for (CssPropBit b : data.properties) {
propBits |= b.jsValue;
}
if (LinkStyleWhitelist.HISTORY_INSENSITIVE_STYLE_WHITELIST
.contains(prop.name)) {
propBits |= CssPropBit.HISTORY_INSENSITIVE.jsValue;
} else if (LinkStyleWhitelist.PROPERTIES_ALLOWED_IN_LINK_CLASSES
.contains(prop.name)) {
propBits |= CssPropBit.ALLOWED_IN_LINK.jsValue;
}
dataObj.appendChild(
new ValueProperty(propbitsObjKey, new IntegerLiteral(unk, propBits)));
List<Expression> litGroups = Lists.newArrayList();
for (int groupIndex : litPartition.unions[propIndex]) {
litGroups.add((Expression) QuasiBuilder.substV(
"L[@i]", "i", new IntegerLiteral(unk, groupIndex)));
}
if (!litGroups.isEmpty()) {
dataObj.appendChild(new ValueProperty(
litgroupObjKey, new ArrayConstructor(unk, litGroups)));
}
}
ObjectConstructor cssSchema = new ObjectConstructor(unk, cssSchemaProps);