diff --git a/src/com/google/common/css/JobDescription.java b/src/com/google/common/css/JobDescription.java index c42133c1..68eb99b2 100644 --- a/src/com/google/common/css/JobDescription.java +++ b/src/com/google/common/css/JobDescription.java @@ -48,6 +48,7 @@ public class JobDescription { public final boolean eliminateDeadStyles; public final boolean allowDefPropagation; public final boolean allowUnrecognizedFunctions; + public final boolean allowDuplicateDeclarations; public final Set allowedNonStandardFunctions; public final boolean allowUnrecognizedProperties; public final Set allowedUnrecognizedProperties; @@ -125,6 +126,7 @@ public enum SourceMapDetailLevel { ALL, DEFAULT } boolean swapLeftRightInUrl, boolean simplifyCss, boolean eliminateDeadStyles, boolean allowDefPropagation, boolean allowUnrecognizedFunctions, + boolean allowDuplicateDeclarations, Set allowedNonStandardFunctions, boolean allowUnrecognizedProperties, Set allowedUnrecognizedProperties, boolean allowUndefinedConstants, @@ -163,6 +165,7 @@ public enum SourceMapDetailLevel { ALL, DEFAULT } this.eliminateDeadStyles = eliminateDeadStyles; this.allowDefPropagation = allowDefPropagation; this.allowUnrecognizedFunctions = allowUnrecognizedFunctions; + this.allowDuplicateDeclarations = allowDuplicateDeclarations; this.allowedNonStandardFunctions = ImmutableSet.copyOf( allowedNonStandardFunctions); this.allowUnrecognizedProperties = allowUnrecognizedProperties; diff --git a/src/com/google/common/css/JobDescriptionBuilder.java b/src/com/google/common/css/JobDescriptionBuilder.java index 92fe03ca..a4e0a740 100644 --- a/src/com/google/common/css/JobDescriptionBuilder.java +++ b/src/com/google/common/css/JobDescriptionBuilder.java @@ -52,6 +52,7 @@ public class JobDescriptionBuilder { boolean eliminateDeadStyles; boolean allowDefPropagation; boolean allowUnrecognizedFunctions; + boolean allowDuplicateDeclarations; Set allowedNonStandardFunctions; boolean allowUnrecognizedProperties; Set allowedUnrecognizedProperties; @@ -89,6 +90,7 @@ public JobDescriptionBuilder() { this.eliminateDeadStyles = false; this.allowDefPropagation = false; this.allowUnrecognizedFunctions = false; + this.allowDuplicateDeclarations = false; this.allowedNonStandardFunctions = Sets.newHashSet(); this.allowUnrecognizedProperties = false; this.allowedUnrecognizedProperties = Sets.newHashSet(); @@ -125,6 +127,7 @@ public JobDescriptionBuilder copyFrom(JobDescription jobToCopy) { this.eliminateDeadStyles = jobToCopy.eliminateDeadStyles; this.allowDefPropagation = jobToCopy.allowDefPropagation; this.allowUnrecognizedFunctions = jobToCopy.allowUnrecognizedFunctions; + this.allowDuplicateDeclarations = jobToCopy.allowDuplicateDeclarations; this.allowedNonStandardFunctions = ImmutableSet.copyOf(jobToCopy.allowedNonStandardFunctions); this.allowUnrecognizedProperties = jobToCopy.allowUnrecognizedProperties; @@ -324,10 +327,20 @@ public JobDescriptionBuilder setAllowUnrecognizedFunctions(boolean allow) { return this; } + public JobDescriptionBuilder setAllowDuplicateDeclarations(boolean allow) { + checkJobIsNotAlreadyCreated(); + this.allowDuplicateDeclarations = allow; + return this; + } + public JobDescriptionBuilder allowUnrecognizedFunctions() { return setAllowUnrecognizedFunctions(true); } + public JobDescriptionBuilder allowDuplicateDeclarations() { + return setAllowDuplicateDeclarations(true); + } + public JobDescriptionBuilder setAllowedNonStandardFunctions( List functionNames) { checkJobIsNotAlreadyCreated(); @@ -464,7 +477,7 @@ public JobDescription getJobDescription() { copyrightNotice, outputFormat, inputOrientation, outputOrientation, optimize, trueConditionNames, useInternalBidiFlipper, swapLtrRtlInUrl, swapLeftRightInUrl, simplifyCss, eliminateDeadStyles, - allowDefPropagation, allowUnrecognizedFunctions, allowedNonStandardFunctions, + allowDefPropagation, allowUnrecognizedFunctions, allowDuplicateDeclarations, allowedNonStandardFunctions, allowUnrecognizedProperties, allowedUnrecognizedProperties, allowUndefinedConstants, allowMozDocument, vendor, allowKeyframes, allowWebkitKeyframes, processDependencies, diff --git a/src/com/google/common/css/compiler/commandline/ClosureCommandLineCompiler.java b/src/com/google/common/css/compiler/commandline/ClosureCommandLineCompiler.java index 51b7d751..a99b120d 100644 --- a/src/com/google/common/css/compiler/commandline/ClosureCommandLineCompiler.java +++ b/src/com/google/common/css/compiler/commandline/ClosureCommandLineCompiler.java @@ -154,6 +154,10 @@ static class Flags { "Allow unrecognized functions.") private boolean allowUnrecognizedFunctions = false; + @Option(name = "--allow-duplicate-declarations", usage = + "Allow duplicate declarations.") + private boolean allowDuplicateDeclarations = false; + @Option(name = "--allowed-non-standard-function", usage = "Specify a non-standard function to whitelist, like alpha()") private List allowedNonStandardFunctions = Lists.newArrayList(); @@ -224,6 +228,7 @@ JobDescription createJobDescription() { builder.setTrueConditionNames(trueConditions); builder.setAllowDefPropagation(allowDefPropagation); builder.setAllowUnrecognizedFunctions(allowUnrecognizedFunctions); + builder.setAllowDuplicateDeclarations(allowDuplicateDeclarations); builder.setAllowedNonStandardFunctions(allowedNonStandardFunctions); builder.setAllowedUnrecognizedProperties(allowedUnrecognizedProperties); builder.setAllowUnrecognizedProperties(allowUnrecognizedProperties); diff --git a/src/com/google/common/css/compiler/passes/PassRunner.java b/src/com/google/common/css/compiler/passes/PassRunner.java index 6dd0836d..6ec40dbd 100644 --- a/src/com/google/common/css/compiler/passes/PassRunner.java +++ b/src/com/google/common/css/compiler/passes/PassRunner.java @@ -142,10 +142,13 @@ public void runPasses(CssTree cssTree) { new AbbreviatePositionalValues( cssTree.getMutatingVisitController()).runPass(); } - if (job.eliminateDeadStyles) { - // Report errors for duplicate declarations + // Report errors for duplicate declarations + if (!job.allowDuplicateDeclarations) { new DisallowDuplicateDeclarations( cssTree.getVisitController(), errorManager).runPass(); + } + + if (job.eliminateDeadStyles) { // Split rules by selector and declaration. new SplitRulesetNodes(cssTree.getMutatingVisitController()).runPass(); // Dead code elimination.