Ejemplo n.º 1
0
        public static IEnumerable <CssRuleBlockSyncAction> ComputeSyncActions(RuleSet existingRule, string newText, string oldText = null)
        {
            var realOldText = oldText ?? existingRule.Text;
            var parser      = new CssParser();
            var oldDoc      = parser.Parse(realOldText, false);
            var oldDict     = ProduceKeyValuePairsFromRuleSet(oldDoc.Children.OfType <RuleSet>().Single());

            if (newText == null && oldText != null)
            {
                return(OrderAndExtractSyncActions(oldDict.Keys.Select(x => SyncAction.Delete(existingRule, x))));
            }

            var newDoc            = parser.Parse(newText, false);
            var newDict           = ProduceKeyValuePairsFromRuleSet(newDoc.Children.OfType <RuleSet>().Single());
            var oldToNewDiff      = CompareNewRuleAndOldRule(existingRule, newDict, oldDict);
            var processedElements = new HashSet <string>(oldToNewDiff.Select(x => x.PropertyName));

            foreach (var item in oldDict.Keys.Except(processedElements))
            {
                //Delete
                oldToNewDiff.Add(SyncAction.Delete(existingRule, item));
                processedElements.Add(item);
            }

            if (oldText == null)
            {
                return(oldToNewDiff.Select(x => x.Action));
            }

            var priorityDiff = ReconcileExistingRuleWithDiff(existingRule, oldToNewDiff);
            var combined     = priorityDiff.Union(oldToNewDiff);
            var simplified   = SimplifySyncActions(combined);

            return(OrderAndExtractSyncActions(simplified));
        }
Ejemplo n.º 2
0
        private static IEnumerable <SyncAction> ReconcileExistingRuleWithDiff(RuleSet comparisonRuleSet, ICollection <SyncAction> oldToNewDiff)
        {
            var existingDict = ProduceKeyValuePairsFromRuleSet(comparisonRuleSet);
            var priorityDiff = new HashSet <SyncAction>();

            foreach (var element in oldToNewDiff.Where(x => x.ActionKind == CssDeltaAction.Update || x.ActionKind == CssDeltaAction.Delete))
            {
                var parts = element.PropertyName.Split('-');

                //If the declaration we're looking at is for a property that we've processed in the old -> new rule diff, don't bother with it, it'll get cleaned up on its own
                if (parts[0].Length == 0 || existingDict.ContainsKey(element.PropertyName))
                {
                    continue;
                }

                //Start looking for expansions on the base property that we're examining and delete the ones that aren't explicitly otherwise specified in our diff
                //Ex. If we have a record "background", locate "background-color", "background-attachment", etc and delete them if we didn't get them back from the browser (they've been shorthanded)
                var prefix = "";

                for (var i = 0; i < parts.Length - 1; ++i)
                {
                    if (prefix.Length > 0)
                    {
                        prefix += "-";
                    }

                    prefix += parts[i];

                    var localPrefix = prefix;

                    foreach (var conflictingValue in existingDict.Keys.Where(x => x.StartsWith(localPrefix, StringComparison.Ordinal)))
                    {
                        //Leave manually specified long form declarations intact but remove ones that are now shorthand
                        if (!oldToNewDiff.Contains(SyncAction.NoOp(comparisonRuleSet, conflictingValue)))
                        {
                            priorityDiff.Add(SyncAction.Delete(comparisonRuleSet, conflictingValue));
                        }
                    }
                }
            }

            return(priorityDiff);
        }
Ejemplo n.º 3
0
        private static HashSet <SyncAction> CompareNewRuleAndOldRule(RuleSet comparisonRuleSet, IEnumerable <KeyValuePair <string, string> > newRule, IDictionary <string, string> oldRule)
        {
            var oldToNewDiff = new HashSet <SyncAction>();

            foreach (var entry in newRule)
            {
                string oldValue;

                if (oldRule.TryGetValue(entry.Key, out oldValue))
                {
                    //Possible Update
                    if (!string.Equals(oldValue, entry.Value))
                    {
                        if (!IsValueAnyRepetitionOfInitial(entry.Value))
                        {
                            //Update
                            oldToNewDiff.Add(SyncAction.Update(comparisonRuleSet, entry.Key, entry.Value));
                        }
                        else
                        {
                            //Delete
                            oldToNewDiff.Add(SyncAction.Delete(comparisonRuleSet, entry.Key));
                        }
                    }
                    else
                    {
                        //Same - don't do anything
                        oldToNewDiff.Add(SyncAction.NoOp(comparisonRuleSet, entry.Key));
                    }
                }
                else if (!IsValueAnyRepetitionOfInitial(entry.Value))
                {
                    //Add
                    oldToNewDiff.Add(SyncAction.Add(comparisonRuleSet, entry.Key, entry.Value));
                }
            }

            return(oldToNewDiff);
        }