• No results found

Resolving DOM conflicts

6.5 Graph Marking

7.3.1 Resolving DOM conflicts

When resolving DOM conflicts, the first step is to identify all static and dynamic code positions that can cause conflicts when a new page is cre- ated by merging the DOMs of two applications. Once these positions are identified, conflicted HTML attributes are renamed, new HTML at- tributes are added, and CSS rules and JavaScript DOM queries are mod- ified in order to localize them in a way that they only interact with nodes from their respective applications. Algorithm 11 describes the process of handling both the DOM conflicts and their propagation to CSS and

JavaScript. As input the algorithm receives the dependency graph GA

and execution summary EA of A for scenario sa, and the dependency

graph GB and the execution summary EB of B for scenarios SB.

Algorithm 11 resolveDOM(GA, EA, GB, EB)

1: attrConflicts ← getHtmlAttrsConflicts(EA, EB)

2: resourceConflicts ← getResourceConflicts(GA)

3: for all item : concat(attrConflicts, resourceConflicts) do

4: new ← genName(item, EA, EB)

5: for all pos : getUsagePos(item, EA) do

6: if isInHtml(pos) or isInCss(pos) then

7: replaceVal(pos, item, new )

8: else if isInJs(pos) then

9: replaceDomStrLit(pos, item, new, GA)

10: end if

11: end for

12: end for

13: expandNodes(genName(’f’, EA, EB), GA, EA)

14: expandNodes(genName(’b’, EA, EB), GB, EB)

The algorithm finds all conflicting HTML node name attributes and all conflicting resources (lines 1, 2), and for each found item a new,

7.3 Resolving Conflicts 103

non-conflicting name is generated. An item can be used in a number of different positions: in HTML code as node attributes, in CSS code as selectors or key values, and in JavaScript code as assignment or call expressions (e.g. assignment expressions that modify node attributes, or DOM querying call expressions). If the usage position is in HTML or CSS code then the old value in the feature code is simply replaced with the new, non-conflicting value. If the usage position is in JavaScript code, the process traverses the dependency graph and attempts to find the string literal that matches the old value and replace it with the new value (if the string literal can not be found, e.g. is constructed by concatenating strings, a comment notifying that a conflict was not resolved is added to the access position).

Example. There are two conflicts caused by attribute namings (List- ing 7.3): the id imCont (@30, A and @33, B); and class attributes mI (@31, 32 A and @34, 35 B), which are resolved by renaming access posi- tions in application A: i) attribute imCont is used only in HTML code, so imCont (@30, A) is replaced with r imCont; ii) mI is used both in HTML code (@31, 32 A) and CSS code (@5, A), and is in both places replaced with r mI.

. . . A . . . . 05 A :. mI { width : 200 px ; }

30 A :< div id =" imCont " >

31 A : < img class =" mI " src =" img / C . jpg "/ >

32 A : < img class =" mI " src =" img / D . jpg "/ >

33 A :</ div >

. . . B . . . . 33 B :< div id =" imCont " >

34 B : < img class =" mI " src =" img / C . jpg "/ >

35 B : < img class =" mI " src =" img / D . jpg "/ >

36 B :</ div >

. . . B ’ . . . . B ’:. r_mI { width : 200 px ; }

B ’:< div id =" r _ i m C o n t " o =r >

B ’: < img class =" r_mI " src =" img / C . jpg "/ >

B ’: < img class =" r_mI " src =" img / D . jpg "/ >

B ’:</ div >

Listing 7.3: Excerpts from applications A and B and the final result when resolving attribute conflicts

The process continues in line 13, Algorithm 11, by handling selector conflicts in CSS and JavaScript code. The goal is to make the selectors more specific by limiting them only to parts of the DOM that match the

102 Chapter 7. Integrating Features

then, we can not be sure if they are applied to correct expressions). For this reason, the conflict detection process is based on the analysis of execution summaries and client-side dependency graphs. Once the conflicting positions are located, by following the dependencies in the dependency graphs, it is possible to make accurate modifications of the correct code constructs.

7.3.1

Resolving DOM conflicts

When resolving DOM conflicts, the first step is to identify all static and dynamic code positions that can cause conflicts when a new page is cre- ated by merging the DOMs of two applications. Once these positions are identified, conflicted HTML attributes are renamed, new HTML at- tributes are added, and CSS rules and JavaScript DOM queries are mod- ified in order to localize them in a way that they only interact with nodes from their respective applications. Algorithm 11 describes the process of handling both the DOM conflicts and their propagation to CSS and

JavaScript. As input the algorithm receives the dependency graph GA

and execution summary EA of A for scenario sa, and the dependency

graph GB and the execution summary EB of B for scenarios SB.

Algorithm 11 resolveDOM(GA, EA, GB, EB)

1: attrConflicts ← getHtmlAttrsConflicts(EA, EB)

2: resourceConflicts ← getResourceConflicts(GA)

3: for all item : concat(attrConflicts, resourceConflicts) do

4: new ← genName(item, EA, EB)

5: for all pos : getUsagePos(item, EA) do

6: if isInHtml(pos) or isInCss(pos) then

7: replaceVal(pos, item, new )

8: else if isInJs(pos) then

9: replaceDomStrLit(pos, item, new, GA)

10: end if

11: end for

12: end for

13: expandNodes(genName(’f’, EA, EB), GA, EA)

14: expandNodes(genName(’b’, EA, EB), GB, EB)

The algorithm finds all conflicting HTML node name attributes and all conflicting resources (lines 1, 2), and for each found item a new,

7.3 Resolving Conflicts 103

non-conflicting name is generated. An item can be used in a number of different positions: in HTML code as node attributes, in CSS code as selectors or key values, and in JavaScript code as assignment or call expressions (e.g. assignment expressions that modify node attributes, or DOM querying call expressions). If the usage position is in HTML or CSS code then the old value in the feature code is simply replaced with the new, non-conflicting value. If the usage position is in JavaScript code, the process traverses the dependency graph and attempts to find the string literal that matches the old value and replace it with the new value (if the string literal can not be found, e.g. is constructed by concatenating strings, a comment notifying that a conflict was not resolved is added to the access position).

Example. There are two conflicts caused by attribute namings (List- ing 7.3): the id imCont (@30, A and @33, B); and class attributes mI (@31, 32 A and @34, 35 B), which are resolved by renaming access posi- tions in application A: i) attribute imCont is used only in HTML code, so imCont (@30, A) is replaced with r imCont; ii) mI is used both in HTML code (@31, 32 A) and CSS code (@5, A), and is in both places replaced with r mI.

. . . A . . . . 05 A :. mI { width : 200 px ; }

30 A :< div id =" imCont " >

31 A : < img class =" mI " src =" img / C . jpg "/ >

32 A : < img class =" mI " src =" img / D . jpg "/ >

33 A :</ div >

. . . B . . . . 33 B :< div id =" imCont " >

34 B : < img class =" mI " src =" img / C . jpg "/ >

35 B : < img class =" mI " src =" img / D . jpg "/ >

36 B :</ div >

. . . B ’ . . . . B ’:. r_mI { width : 200 px ; }

B ’:< div id =" r _ i m C o n t " o =r >

B ’: < img class =" r_mI " src =" img / C . jpg "/ >

B ’: < img class =" r_mI " src =" img / D . jpg "/ >

B ’:</ div >

Listing 7.3: Excerpts from applications A and B and the final result when resolving attribute conflicts

The process continues in line 13, Algorithm 11, by handling selector conflicts in CSS and JavaScript code. The goal is to make the selectors more specific by limiting them only to parts of the DOM that match the

104 Chapter 7. Integrating Features

originating application. Non-conflicting names are generated with calls to the genName function and are added as attributes to enable differ- entiation between nodes originating from different applications. Type selectors are expanded so they target only nodes they have targeted in the originating applications (both for CSS selectors, and JavaScript DOM queries).

Example. There are two selector caused conflicting expressions (List- ing 7.4): CSS selector img (@4, A and B), and doc.querySelectorAll(’img’) (@21, A and @23, B). Failing to resolve the CSS selectors would cause the wrong styles to be applied to images from application B, and fail- ing to resolve the querySelectorAll call would result in more elements returned by the query in the context of the final application than in the context of each application. For this reason, the body descendants in application A (@29, A) are expanded with an additional attribute (e.g. attribute origin with value reuse, represented by o = r). This is followed with the expansion of CSS selectors: for A, the img selector is replaced with img[o=r] (@4, A); and for B (@4, B) with img:not([o=r]) (the

CSS rule in application B becomes: img:not([o=r]){ border: dashed;},

meaning apply dashed border to img elements that do not have the o attribute with a value of r ). With this change, instead of styles that are applied to HTML nodes from the other application, we have obtained CSS rules that target only the HTML nodes from their respective ap- plications. Finally, DOM querying conflicts in JavaScript are resolved by replacing the query arguments with the same values as in the CSS replacement.

. . . A . . . . 04 A : img { border : solid ; }

05 A : . mI { width : 200 px ; }

21 A : var im = d o c u m e n t . q u e r y S e l e c t o r A l l ( ’ img ’)

29 A :< body >

30 A : < div id =" imCont " >

31 A : < img class =" mI " src =" img / C . jpg "/ >

32 A : < img class =" mI " src =" img / D . jpg "/ >

33 A : </ div >

34 A :</ body >

. . . B . . . . 04 B : img { border : dashed ; }

05 B : . mI { width : 300 px ; }

23 B : var im = d o c u m e n t . q u e r y S e l e c t o r A l l (" img ")

36 B :</ div >

. . . B ’ . . . . B ’:img [ o = r ] { border : solid ; }

7.3 Resolving Conflicts 105

B ’:. mI { width : 200 px ; }

B ’:img : not ([ o = r ]) { border : dashed ; }

B ’:. mI : not ([ o = r ]) { width : 300 px ; }

B ’: var im = d o c u m e n t . q u e r y S e l e c t o r A l l ( ’ img [ o = r ] ’)

B ’: var im = d o c u m e n t . q u e r y S e l e c t o r A l l ( ’ img : not ([ o = r ]) ’)

B ’: < div id =" imCont " o =r >

B ’: < img class =" mI " src =" img / C . jpg " o = r / >

B ’: < img class =" mI " src =" img / D . jpg " o = r / >

B ’: </ div >

Listing 7.4: Excerpts from applications A and B and the final result when resolving selector conflicts