• No results found

Challenges

In document Dynamic Styling in Web Development (Page 54-56)

In the following sections, some of the problems regarding styling based on rules are presented, along with some possible solutions.

4.3.1. Conflict Resolution and Elimination 47

4.3.1 Conflict Resolution and Elimination

As with CSS, several rules can be in conflict with each other. For instance, setting alldiv

elements to be red in one rule, and then setting all divelements to be blue in another. In CSS, these conflicts are solved by means of specificity and cascading rules (see section 2.2). We feel that some of the semantics of this way to resolve the conflicts can cause elements to be styled in unexpected ways.

To solve this, the idea is to have a simpler conflict resolution scheme, which will be based on the order in which rules are introduced. This also makes more sense when styling is meant to be done in a dynamic fashion rather than statically.

1 d i v 2 { 3 c o l o r: r e d; 4 f o n t−s i z e: 14p t; 5 } 6 7 d i v 8 { 9 c o l o r: b l u e; 10 }

Code example 4.1: Two rules, one overriding the color property of the other. When having a rule that defines the values of several properties; X, Y and Z, and then having a second rule with the same selector, but only defines the properties; X and Y, the previously defined value of the Z property should stick, while X and Y are redefined. Code example 4.1 gives an example of an obsoleted property declaration. CSS notation is used here because the syntax and the semantics of our solution will first be defined in section 5.2. In order to perform elimination of obsoleted declarations, we need to split rules into sets of rules that define only a single property each. The point in eliminating obsolete declarations is to avoid computing values that will be overwritten by subsequent evaluations.

If the declarations in a rule are simple assignments, it will be trivial to eliminate ob- solete declarations of properties. Code example 4.1 is suitably simple. But if conditional statements and loops are allowed inside style blocks, it will become harder to determine if the rule can be eliminated. In fact, there can be cases where this will be undecidable, be- cause it is undecidable to determine if two arbitrary program pieces will perform equivalent computations. The same holds true if the developer decides to use homemade predicates in selectors, since these predicates are simply conditional statements that call a function which can contain arbitrary code.

For this reason, we need to explicitly support a range of sensible predicates, because that will allow us to compare the semantics of the two predicates and eliminate the other. For instance, assume that the developer creates a rule using a predicate that says every sixth child must be selected. Later, the developer creates an equivalent rule, where the predicate selects every third child. Clearly every sixth child is covered by every third child, so we can remove the first rule altogether if we know the exact semantics of the predicate. If the developer implemented the predicate, there would be no guarantee that we could eliminate any of the rules. Now assume that the precedence of the two rules are opposite. The rule that selects every third child will now be overruled by the other rule, which means that some of the elements will have their property written twice. Again, this can be prevented if the semantics of the predicates are known.

When it comes to selectors without predicates, there should not be any computational problems determining what elements two different arbitrary selectors have in common, in order to eliminate excessive writing of properties.

4.3.2 Property Dependencies

The idea that the styling of an element can depend on the style of another element can yield some problems. For instance, given two elements, A and B, where B is a descendant of A, and the developer creates a style that says A must be twice as wide as B. Usually, the width of B will automatically be determined by the width of A, so what is supposed to happen when a style suddenly says that A must be defined by the width of B? Having such a rule does not make sense, because the width of both A and B will really depend on how many times the rule is evaluated.

Suppose that two other elements, C and D, where D is a sibling to C and C comes before D in the document tree. Usually, C will be evaluated first, and then D. Now suppose we make a rule that says C must be twice as wide as D. There should not be anything wrong with this, as the width of an element should not affect the width of its siblings. But we still need a way to make sure that the width of C is not evaluated until D has been given a width.

In order to detect cases like this, a graph of dependencies needs to be generated. If a rule generates a cycle in that graph, the rule cannot be enforced, and an error will be emitted. If there are no cycles, then the rules can be ordered in a way that will allow all dependencies of a rule to be evaluated first.

This must however be combined with the concept of splitting rules as described in the section about conflict resolution. This is because two rules can each set two properties, where one property from one rule depends on one property of the other rule, while the other property of the other rule depends on the other property of the first rule. See Code example 4.2 for an example.

1 A 2 { 3 c o l o r: r e d; 4 f o n t−t y p e: B.f o n t−t y p e; // s e t t h e f o n t t y p e t o t h a t o f e l e m e n t B 5 } 6 7 B 8 { 9 f o n t−t y p e: V e r d a n a; 10 c o l o r: A.c o l o r; // s e t t h e c o l o r t o t h a t o f e l e m e n t A 11 }

Code example 4.2: Double dependency.

If we look at the two rules in their entirety, they form a circular dependency. But these two rules can easily be split into four rules that do not form a circular dependency.

In document Dynamic Styling in Web Development (Page 54-56)