• No results found

Re-engineering Cascading Style Sheets by preprocessing and refactoring

N/A
N/A
Protected

Academic year: 2021

Share "Re-engineering Cascading Style Sheets by preprocessing and refactoring"

Copied!
93
0
0

Bezig met laden.... (Bekijk nu de volledige tekst)

Hele tekst

(1)

Re-engineering Cascading Style Sheets by

preprocessing and refactoring

Axel Polet

axel.polet33@gmail.com August 23, 2015, 92 pages

Supervisor

Dr. Vadim Zaytsev

Universiteit van Amsterdam

Faculteit der Natuurwetenschappen, Wiskunde en Informatica Master Software Engineering

(2)

Contents

Abstract ... i

List of Tables ... ii

List of Figures ... iii

1. Introduction ... 1 1.1 Motivation ... 1 1.2 Contributions ... 2 1.3 Document structure ... 3 2. The CSS language ... 4 2.1 Selectors ... 4 2.2 Combinators ... 5 2.3 Media-queries ... 6 2.4 Inheritance ... 6

2.5 Cascading: Specificity and location ... 6

3. CSS code optimization and ISO 25010 ... 7

3.1 The ISO 25010 Quality Model ... 7

3.2 Optimizing CSS code ... 7

3.2.1 Transforming CSS code ... 8

3.2.2 Using SASS ... 9

3.2.3 Mapping transformations to quality attributes ... 10

4. Proposed transformations ... 12

4.1 CSS Transformations ... 12

4.1.1 Remove unmatched selectors ... 12

4.1.2 Normalization of colors, URLs, zero-values and shorthand declarations ... 12

4.1.3 Remove duplicate declarations intra-selector ... 13

4.1.4 Remove ineffective selectors and declarations ... 14

4.1.5 Remove unnecessary default declarations ... 17

4.1.6 Replace descendant selectors with child selectors ... 18

(3)

4.2 SASS Transformations ... 19

4.2.1 Generate variables ... 19

4.2.2 Encapsulate clones in mixins ... 20

4.2.3 Generate parameterized merge mixins ... 21

4.3 Transformation exclusions ... 22

4.3.1 Declaration-level exclusions ... 22

4.3.2 Selector-level exclusion ... 22

5. The CSS transformation framework ... 24

5.1 Crawljax ... 24 5.2 Plug-in implementation ... 25 5.2.1 OnNewState ... 25 5.2.2 PostCrawling ... 25 5.3 Components ... 26 5.4 Features ... 28 5.5 Algorithms ... 28

5.5.1 Declaration effectiveness analysis ... 29

5.5.2 Detecting and updating descendant selectors ... 31

5.5.3 Mixin generation by clone detection... 33

6. Evaluation approach ... 35

6.1 Research goal –and questions ... 35

6.2 Research objects ... 36

6.3 Crawljax configuration ... 36

6.4 Metrics on CSS code similarity (RQ1) ... 36

6.4.1 Node selection similarity ... 37

6.4.2 Declaration effectiveness similarity ... 38

6.5 Metrics on the extent of transformations (RQ2) ... 40

6.6 Metrics on ISO 25010 improvements (RQ3) ... 42

6.6.1 Maintainability (3.1-3.3) ... 42

6.6.2 Performance (3.4) ... 42

7. Evaluation results... 44

(4)

7.1.1 Node selection similarity ... 44

7.1.2 Declaration similarity... 46

7.1.3 False positives on non-similar declarations ... 48

7.1.4 Summary ... 50

7.2 Extent of transformations (RQ2) ... 51

7.2.1 Extent of CSS transformations... 51

7.2.2 Extent of SASS transformations ... 53

7.3 CSS code improvements by ISO 25010 (RQ3) ... 54

8. Conclusions ... 57 8.1 Conclusions ... 57 8.2 Threats to validity... 58 8.2.1 Internal validity ... 58 8.2.2 External validity ... 59 8.3 Contributions ... 59 8.4 Future Work ... 60 Bibliography ... 62 Appendix A ... 64 Appendix B ... 66 Appendix C ... 69 Appendix D ... 72 Appendix E ... 75 Appendix F ... 79 Appendix G ... 82

(5)

i

Abstract

Cascading Style Sheets (CSS) is a language designed to define styles on elements contained in HTML pages used in websites. Ongoing development by the World Wide Web Consortium has resulted in a powerful language that is used in approximately 90% of today’s websites. Recently it has gained attention of the research community with analyses on the extent of code smells including code clones and ineffective CSS selectors. The studies show that significant amounts of CSS code are unused (60%) and cloned (40% to 90%).

In this thesis we continue the work by combining these, and other, CSS code analysis approaches in a CSS Re-Engineering Tool called CRET using the open-source web crawler Crawljax. CRET automatically analyses, transforms and re-generates CSS code discovered by crawling real-world websites. We implement and evaluate ten transformations that result in more performant –and maintainable code. We relate the transformations to software quality attributes defined in the ISO 25010 model. Furthermore, features of the CSS preprocessor SASS are introduced in three of CRET’s transformations, providing additional improvements in modifiability –and reusability of CSS code.

Finally, we define multiple metrics to evaluate SASS –and CSS code generated by CRET on its similarity in behavior with the original code, the extent of transformation impact and improvements regarding performance and maintainability. 100 real-world websites were processed by CRET in three evaluation studies. Results indicate that the SASS –and CSS code generated by CRET shows significant improvements in analyzability, modifiability, reusability and expected performance.

(6)

ii

List of Tables

Table 1 - Transformation group by type of code change ... 10

Table 2 - Part of the SIG MM mapping ... 10

Table 3 - Final mapping between transformations and quality attributes ... 11

Table 4 - Transformation complexities ... 11

Table 5 - Supported color notations in CSS... 13

Table 6 - Assumed default declaration values as defined by the CSS standard specification ... 17

Table 7 - Supported shorthand normalizations ... 19

Table 8 - Descriptive statistics on :not selectors versus all selectors ... 23

Table 9 - Metrics on node selection similarity ... 38

Table 10 - Metrics on declaration similarity ... 40

Table 11 - Metrics on maintainability ... 42

Table 12 - Metric on performance ... 43

Table 13 - Descriptive statistics on node selection similarity metrics M1-4, M1-5, M1-6 ... 45

(7)

iii

List of Figures

Figure 1 - Example CSS selector and CSS declarations ... 4

Figure 2 - Transforming SASS into CSS ... 9

Figure 3 - Example unmatched selector... 12

Figure 4 - Example duplicate declaration intra-selector ... 14

Figure 5 - Specficity comparison example 1 ... 15

Figure 6 - Specificity comparison example 2 ... 15

Figure 7 - Specificity comparison example 3 ... 16

Figure 8 - Example invalid default style declaration ... 18

Figure 9 - Example descendant into child selector ... 18

Figure 10 - Example normalization of declarations to shorthand representation ... 19

Figure 11 - Example grouping cloned declarations in SASS mixin ... 20

Figure 12 - Parameterized mixin from http://sass-lang.com/guide ... 21

Figure 13 - Example parameterized mixin... 21

Figure 14 - Scatterplot comparing :not selectors and total selectors ... 22

Figure 15 - Domain model ICssTransformer ... 26

Figure 16 - Domain model SassBuilder ... 26

Figure 17 - Flowchart CRET ... 27

Figure 18 - Domain classes MDeclaration and MSelector ... 29

Figure 19 - Node selection analysis for http://www.apple.com ... 44

Figure 20 - Instances of detected missed nodes (M1-1), additional nodes (M1-2) and non-similarity (M1-3) ... 45

Figure 21 - Detected effective declarations for http://www.google.com ... 46

Figure 22 - Instances of detected mismatched declarations 7), additional declarations (M1-8) and non-similarity (M1-9) ... 47

Figure 23 - Transformation impact of IS, relative to previous ... 51

Figure 24 - Transformation impact of IS, relative to original ... 51

Figure 25 - Boxplot US (median 79.55%) ... 52

Figure 26 - Boxplot NU (median 0.08%) ... 52

Figure 27 - Boxplot NC (median 15.15%)... 52

Figure 28 - Boxplot CD (median 0.71%)... 52

Figure 29 - Boxplot NZ (median 5.33%) ... 52

Figure 30 - Boxplot DD (median 4.85%) ... 52

Figure 31 – Boxplot DCS (median 3.94%) ... 52

Figure 32 - Ratio to total affected CSS selectors (left) and CSS declarations (right) & averages 53 Figure 33 - Boxplot VT (median 16.55%) ... 53

Figure 34 - Boxplot CT (median 7.29%) ... 53

Figure 35 - Boxplot PT (median 5.66%) ... 54

(8)

iv

Figure 37 - Boxplot removed declarations (2_2) (median 80.05%) ... 54

Figure 38 - Boxplot removed selectors (2_1) (median 82.80%) ... 54

Figure 39 - Boxplot declarations per variable (2_5) (median 1.92) ... 55

Figure 40 - Boxplot declarations per clone (2_7) (median 6.89) ... 55

(9)

1

1. Introduction

Cascading Style Sheets (CSS) is the standard language responsible for describing the look-and-feel of HTML documents. With CSS, the presentation semantics of a webpage are separated from its content. The language is part of the web standards model[1] defined by the World Wide Web Consortium (W3C), alongside JavaScript and HTML.

A cascading style sheet consists of one or more rules which ‘select’ web elements contained in a HTML document. Each rule consists of one or more selectors and contains one or more styling properties. Apart from this relatively simple syntax, the CSS language also provides more complex features such as inheritance, cascading and specificity. Due to these features, maintaining and improving existing style sheets becomes a cumbersome task [2][3] for developers. Also, the development of CSS code is not based on a disciplined process [4] with specific design-principles.

Recent surveys has shown that CSS is used in over 90% of all websites [5]. Furthermore, the language is continuously under development and has become a powerful language with its latest release (CCS3). Responsive and scalable web-applications, that are usable on any device, have become a hot topic and have contributed to an increase in CSS code for these applications. Consequently, increased usage of CSS and more code leads to a higher chance of smelly code and lower maintainability.

Large CSS files also result in a higher load on the network through which they are transferred from the server to the client (browser). Furthermore, CSS code has to be processed by that client. Research have shown that processing CSS code consumes between 40% and 70% of the

browsers average time to process the entire page [6][7][8]. Thus, the overhead in the browser caused by duplicated, unused and ineffective CSS code is significant.

1.1 Motivation

As of 2012, the research community has given more attention to the (mis)use of Cascading Style Sheets. In a recent study [9], Mazinanian et al. provide empirical evidence on the prevalence and extent of code duplication in CSS code. By developing a tool that automatically detects and refactors three types of duplication and performing a case study on 38 websites, they found a high extent of duplication in the real world. In examined CSS files 40% to 90% of the CSS code was found to be cloned. The authors achieved an 8% size reduction by refactoring duplications, on average. In other research [10], Mesbah et al. developed a tool for detecting unused and ineffective CSS code. In their study, they found that, on average, 60% of the rules -and 52% of the styling properties were unused.

(10)

2

So, CSS code used in real-world websites contains significant amounts of smelly code, which impacts its performance and maintainability. The (open-source) development community has responded to the maintainability overhead of CSS by introducing extensions to the CSS language, such as SASS and LESS. These extensions, or preprocessors, provide additional features that can be used by CSS developers to easier maintain their CSS code. For example, a SASS developer edits SASS code, including SASS specific features, and uses the SASS compiler to transform that code into valid CSS code.

With increasingly larger amounts of CSS code used in today’s web applications, an automated approach by which existing CSS code is analyzed for smells, transformed -and optimized is required. Consequently, we have motivated the need for the work presented in this thesis.

1.2 Contributions

In this work, we provide an automated approach to improving maintainability and expected performance of existing CSS files, the CSS Re-Engineering Tool (CRET). The tool combines and extends several CSS analysis implementations of previous studies and introduces additional transformations, including those related to the CSS preprocessor SASS.

To the best of our knowledge, this is the first attempt to actually generate both optimized SASS and CSS code from existing CSS code used in real-world web applications. CRET is

implemented as a Crawljax plug-in, which allows it to automatically crawl (AJAX-based) web applications, gather CSS code from them and perform transformations.

This thesis contains elaborations on the ten transformations implemented in CRET. We relate the proposed transformations to the ISO 25010 software quality paradigm. The CSS code changes performed by CRET are mapped to the software quality attributes for analyzability,

modifiability, reusability and time-behavior.

We provide empirical evidence of high similarity in behavior of the CSS code generated by CRET, compared to the original CSS code discovered in a pre-defined set of 100 websites, by processing 193.835 CSS selectors.

Furthermore, additional evidence is provided on findings of previous research regarding

percentages of unused CSS code –and CSS code clones. A total of 2.342.136 lines of CSS code, including 479.708 CSS selectors, was processed by crawling the pre-defined websites.

Finally, evidence is provided showing improvements brought by generated SASS code, compared to the original CSS code, regarding the described ISO 25010 quality attributes. The introduction of SASS features to the original CSS code improves the reusability and

modifiability. It allows changes in SASS variables and SASS mixins to be propagated to 19% and 10% of CSS declarations, on average. Aside from that, all transformations combined

produce an average of around 70% less CSS selectors –and declarations, significantly increasing the analyzability of the code.

(11)

3

1.3 Document structure

This document is organized as follows. In chapter 2 we describe the CSS language. Chapter 3 describes proposed CSS –and SASS transformations and relates them to ISO 25010 quality attributes. Chapter 4 elaborates on the transformations by providing definitions and examples of them. Chapter 5 summarizes the features and components of the transformation framework implemented in CRET and presents pseudo-code on several algorithms.

We describe the design of our empirical evaluation in chapter 6, including the chosen research approach, research questions and metrics used to answer them. Chapter 7 presents the results of these studies. Finally, in chapter 8 we draw our conclusions, discuss the validity of our work and provide future work opportunities.

(12)

4

2. The CSS language

The W3 Consortium is an international community that is responsible for developing Web Standards. The consortium develops these standards by bringing various stakeholders together for involvement and by developing under a clear-and consensus-based process1. The W3C has

has defined the CSS language. We will summarize the language here by analyzing the latest recommendations for CSS. The last stable CSS version dates back to May 2011 [11] and includes CSS3 selectors and media-queries.

The primary purpose of the CSS language is to define one or more visual attributes or styles on elements in a web document. Any (HTML/XHTML) web document is defined by the Document Object Model[12] (DOM), and its elements are contained as nodes in the DOM-tree for that document.

2.1 Selectors

The CSS language is built upon three core concepts: rules, selectors and declarations. A CSS file consists of one or more CSS rules, which consists of one or more CSS selectors[13], which consists of one or more CSS declarations:

Selectors are matched against elements in the DOM-tree of a webpage, based on their

expression: expression x DOM element  boolean. If matched, the declarations contained in the selector are applied to the DOM element.

The following (simple) selectors are defined by W3C: (1) type/element selectors, (2) ID

selectors, (3) class selectors, (4) universal selectors, (5) attribute selectors and (6) pseudo-classes. A type selector matches document element types, for example h1, p, div, a. An ID selector is an identifier preceded by a hash(#) sign and matches an element in the document tree with the same identifier. A class selector is a name preceded by a period (.) sign and matches zero or more elements in the tree that declare this name in a ‘class’ attribute. The universal selector is an asterisk (*) and matches all elements in the document tree.

1http://www.w3.org/Consortium/facts.html selector1 { declaration1; declaration2; declaration3; } selectorN { declaration; }

Figure 1 - Example CSS selector and CSS declarations

(13)

5

Attribute selectors match DOM elements that contain the same attributes and/or values:  span[title] matches span elements with a title attribute, whatever the value is

 span[location=”left”] matches span elements with location attribute that has the value

left

Attribute selectors also support substring matching:

 span[location*=”left”] matches span elements with location attribute that contains the value left

 span[location^=”left”] matches span elements with location attribute that starts with the value left

 span[location$=”left”] matches span elements with location attribute that ends with the value left

Dynamic and UI element state pseudo-classes allow for selection of elements based on

information that lies outside the document tree or that cannot be expressed using the above selectors. A, so called nonstructural pseudo-class can be appended to any of the above selectors, prefixed by a semi-colon (:). Example:

 The :visited pseudo-class matches links that were previously visited by the user

Structural pseudo-classes allow for selection of elements based on information inside the

document tree, but that cannot be expressed using other selectors, for example:

 The :nth-child(an+b) pseudo-class matches siblings of elements in the DOM tree, for example .Block:first-child matches the first div element in:

<div class=”Block”>1</div> <div class=”Block”>2</div>

Finally, the language supports pseudo-elements, which are special elements that only apply to the last (i.e. the key) simple selector in a selector. Examples:

 The ::first-line pseudo-element applies styling to the first line of a text

 The ::before pseudo-element applies styling and/or content before the element selected by the preceding selector.

2.2 Combinators

Actual selectors are the above described ‘simple’ selectors combined in sequences, separated by a combinator. The most important combinator is whitespace, it allows the selection of an element that is descendant of another element. For example: .class1 span selects a span element which is descendant of an element with a class=class1 attribute, i.e. the span is located at least one level deeper in the DOM tree.

Child combinators (>) represent a direct child relationship between selectors. A direct-child is an

(14)

6

selects any p element contained at any level within a li element, while the li element should be exactly one level below an ol element.

Sibling (+) combinators select elements directly following other elements, at the same level in de

DOM tree. Generic sibling (~) combinators select any other following element at the same level in the DOM tree.

2.3 Media-queries

Media-queries[14] are supported since CSS2 and extended in CSS3. They allow for ‘labeling’ of style sheets to enable media-specific customization of presentation. The same web document can have various presentations based on the device it is viewed on.

A media-query consists of a @media declaration, one or more media-types, media-properties and values. For instance: the selectors of @media screen and (min-width: 800px) {selector(s)} are only applied if the viewport of the browser is at least 800px wide. Multiple media-properties may be applied to one media-type using and, and multiple media-types are applied by

comma-separating them.

2.4 Inheritance

CSS inheritance[15] allows for the propagation of style properties of parent elements to descending elements. For instance a color property on body will be propagated to any element inside that body.

2.5 Cascading: Specificity and location

The cascading[15] feature in the CSS language is the property that ultimately decides which selectors and/or styles are applied to the related DOM elements. Cascading is built upon two concepts: specificity and location.

More specific selectors are applied over less specific. The specificity of a selector is computed by the summation of all its (simple) selector types (in the sequence). For instance, the selector

.class span takes priority over the body span selector.

Also, the CSS language allows for an !important annotation on declarations within a selector. If a declaration is followed by an !important expression, that declaration will overrule any other (non-important) declaration, regardless of the specificity of the selectors in which they are contained.

Location is determined by the source, line-number and column-number of the CSS rule. The following sources are available: (1) inline (as an attribute to the element), (2) embedded (in the web document header) and (3) external (as a .css file). The priorities are defined as follows, from high to low: inline, embedded and external. Furthermore, within a file, declarations of a rule with higher line-number and/or column number, take priority over those that are located earlier.

(15)

7

3. CSS code optimization and ISO 25010

In this chapter, we summarize the transformations we propose to apply on CSS code and relate them to software quality attribute proposed by the ISO 25010 Software Quality Model[16].

3.1 The ISO 25010 Quality Model

In 2011, the ISO 25010 model was introduced to replace to older ISO 9126 model[17], which was issued in 1991 and revised in 2001. ISO 25010 consists of two parts: A software product quality model composed of eight quality characteristics and a system quality in use model composed of three characteristics. The latter is used to assess the interaction between users of a system and the system itself. In this work, we focus on the first model, by which we define a piece of CSS code as the ‘software’ in scope.

Product quality model. The model is composed of eight groups of attributes: Function

suitability, reliability, performance efficiency, usability, security, compatibility, maintainability and transferability. Each group contains several quality attributes that describe some form of quality on the software or hardware under scope, sometimes in relation to a ‘user’.

Selected quality attributes. We exclude any quality attribute relating to hardware or that are not

relevant for a piece CSS code. To do this, we define ‘users’ to be either a web browser agent, for example Internet Explorer, which interprets CSS code for a website, or a CSS developer who maintains the CSS code. The following attributes are in scope of this project:

 Time-behavior (Performance efficiency) – The rate by which response- and processing times of a system, during execution of its functionality, conforms to requirements.  Reusability (Maintainability) – The extent to which an existing component may be

reused multiple systems or when implementing a new component.

 Analyzability (Maintainability) – The extent to which determining the impact of a required change on a product or system is efficient or effective. This includes the ability to easily identify the components to be changed.

 Modifiability (Maintainability) – The extent to which a product or system is changed effectively and efficiently, without errors or loss of quality.

3.2 Optimizing CSS code

We propose ten transformations, based on previous research and other CSS development resources, each of which improves one or more of the selected quality attributes. We provide elaborate descriptions of these transformations in chapter 4. A transformation is classified as either a CSS transformation or a SASS transformation.

The transformations are similar to refactorings[18], because the transformed CSS code should display the same behavior as the original CSS code, i.e. they are semantics preserving.

(16)

8 3.2.1 Transforming CSS code

We propose the following CSS code transformations:

1) Remove unmatched selectors. We adopt this transformation from the research[10] of

Mazinanian et al. The transformation removes CSS selectors from CSS code, when they do not select any element in a web document. Stylesheets affected by this transformation will contain less CSS code. The stylesheets will contain less dependences between selectors and there is less cascading.

2) Normalize declarations. The transformation updates values of declarations into

pre-defined formats. This increases analyzability of the code, because equal colors and other normalized values are easier identifiable and comparable. This also results in an easier analysis of declarations in the following transformations.

3) Remove duplicate declaration intra-selector. The transformation identifies and

removes declaration clones inside CSS selectors. An intra-selector declaration clone consists of one or more declarations with the same name within the same selector.

4) Remove ineffective selectors –and declarations. This transformation is adapted from

the research[10] by Mesbah et al. We remove all selectors and declarations, which are deemed not effective by the cascading, specificity and location rules of the CSS language.

5) Remove unnecessary default declarations. This transformation is an adaptation and

extension to a specific smell detection proposed in the research[19] by Gharachorlu et al. The transformation removes declarations within CSS selectors that are redundant because they represent the default behavior.

6) Replace descendant selectors with child selectors. The transformation is adopted from

CSS development resources234, including a resource5 used by Gharachorlu[19]. The transformation changes CSS selectors, but does not remove them.

7) Normalize shorthand declarations. This transformation is implemented because it is a

feature of the CSS language and allows for shorter CSS code. It normalizes CSS

declarations by replacing non-shorthand declarations by their shorthand representations.

2 http://www.zyxware.com/articles/2800/css-tips-avoid-descendant-selectors-and-improve-page-rendering-performance 3https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS 4http://cssguidelin.es/#css-selectors 5http://www.smashingmagazine.com/2007/05/10/70-expert-ideas-for-better-css-coding/

(17)

9 3.2.2 Using SASS

SASS, or Syntactically Awesome Stylesheets6, is created as an extension to the CSS language, providing features not included in the original language. SASS is a preprocessing language, which means that SASS needs to be processed before it is usable by a browser.

SASS file (.scss or .sass)

CSS file (.css)

SassCompile()

Figure 2 - Transforming SASS into CSS

We propose the following transformations using SASS features:

8) Generate variables. The SASS language allows for the definition of variables7

containing CSS declaration values. Introducing variables in SASS code improves modifiability and reusability because the variable values are reusable in multiple declarations. Furthermore, it allows achieving higher style consistencies, because the values are only defined once.

This transformation will apply to all color, URL and font-stack values used in CSS declarations. These values are stored in SASS variables, for example $color_black: #000000. The CSS declarations are then updated to reference the variables: background-color: $color_black. A change in a variable is propagated via these references.

9) Encapsulate clones in mixins. Similar to variables, SASS mixins allow storing and

reusing values, but they support groups of declarations. We use mixins to store duplicate groups of declarations, to reduce the amount of CSS code. The extent of duplications[9] in CSS code is intense according to Mazinanian et al. We extend the method for

identifying and ‘merging’ cloned code proposed in his research.

10) Merge declarations in mixins. Besides storing clones in mixins, we also implement

parameterized mixins that allow for merging groups of declarations that are not merge-able as shorthand declarations. Any group of padding and margin declarations, not merged by transformation 7, are included. Ultimately, this leads to less CSS code.

6http://sass-lang.com

(18)

10

3.2.3 Mapping transformations to quality attributes

We are able to map transformations to the selected quality attributes by first grouping the transformations by the type of code change they perform, as displayed in table 1.

# Code change Related

transformation(s)

1 Removed selectors 1, 4

2 Updated selectors 6

3 Removed declarations 3, 5

4 Merged declarations 7, 10

5 Updated declaration values 2

6 Extracted variables 8

7 Extracted declaration clones 9

Table 1 - Transformation group by type of code change

SIG Maintainability Model. For the quality attributes analyzability and modifiability we adapt

the mapping of ISO 9126 quality attributes on source code properties, as proposed by the SIG Maintainability Model[20]. V ol ume C om ple xi ty per uni t D up li ca ti on U nit s ize U nit t es ti ng Analyzability X X X X Changeability X X

Table 2 - Part of the SIG MM mapping

By relating the transformation changes of table 1 to the source-code properties of SIG MM, we are able to relate changes to quality attributes. Also, the ISO 9126 quality attributes are

interpreted as ISO 25010 attributes as they are closely related: changeability (9126) is interpreted as modifiability (25010). R em ove se lec tor s R em ove decl ar at ions Me rg e dec lara ti ons U pd at e s el ect o r def in it ions U pd at e dec lar at ion val ue s E xt rac t var iab les E xt rac t de cl a rat ion cl one s Analyzability X X X X X Modifiability X X

(19)

11

Reusability X X

Time-behavior X X X X

Table 3 - Final mapping between transformations and quality attributes

Finally, we extend the mapping with the reusability and time-behavior quality attributes:  Variable extraction and declaration merges increases reusability in SASS code;  Selector –and declaration removal, selector updates, declaration merges increase the

expected time-behavior of a browser processing CSS code.

Refactoring complexities. Each of the ten proposed transformations is executed as a refactoring.

This means that any CSS/SASS code resulting from the transformations should the display equal behavior as the previous CSS/SASS code.

The complexity of semantic preservation differs per transformation. Table 4 indicates the complexity for each transformation, classified as simple, mediocre or hard.

Transformation Complexity factors Complexity

1 – Unmatched selectors

Select –and match CSS selectors on multiple DOM elements of multiple web documents

Mediocre

2 – Declaration normalization Transform all supported color formats, as

defined by the CSS language Mediocre

3 – Cloned declarations intra-selector None Simple

4 – Ineffective selectors

Interpret the rules defined by the CSS language and analyze CSS selectors and declarations accordingly. Deal with related selectors and declarations.

Hard

5 – Default declarations

Analyze multiple related selectors and declarations for default values. In some cases default values are valid.

Hard

6 – Descendant selectors

Recursively parse CSS selectors and the DOM element chains on which they apply, each time checking if a CSS selector update is possible

Hard

7 – Merge declarations

Several CSS declaration support merging a lot of values, e.g. the CSS background declaration

Mediocre

8 – Extract variables

Possibly extract multiple variables in shorthand declarations, do not duplicate variable values

Mediocre

9 – Extract clones using mixins

Adapt and extend algorithm used in previous research. Results of algorithm should be used to create SASS mixins instead of merging CSS selectors

Hard

10 – Merge declarations using mixins Only two declaration types will be merged Simple

(20)

12

4. Proposed transformations

In this chapter we elaborate on the transformations proposed in section 3.2. We propose several definitions to clarify how the transformations will identify transformable code and present examples.

The definitions are formalized: We denote a set of selectors s1…sN by Φ and a set of

declarations d1…dN by Θ. The set of DOM elements e1…eN in contained in one or more DOM states is denoted by Σ.

Also, the examples of declaration comparisons in this chapter use the following terms:

 Two declarations are defined to be equal-by-name (or EBN) if and only if they have the same name (i.e. the part before the colon);

 Two declarations are defined to be equal-by-value (or EBV) if and only if those declarations have the same name, value and !important expression;

 Two declarations are EBN if they are EBV.

4.1 CSS Transformations

4.1.1 Remove unmatched selectors

A CSS selector applies to a web document if the combination of all selector sequences, combinators and selector types, which reside inside that selector, select one or more elements (i.e. nodes) the DOM tree. If a CSS selector does not match any node in any DOM tree, the selector is not used, and should therefore be removed from the stylesheet.

CSS selector s1 is matched iff ∃e ∈ Σ, where s1 applies to E definition 4-1

.home .footer is unmatched in the given DOM tree, and should be removed

4.1.2 Normalization of colors, URLs, zero-values and shorthand declarations It is useful for a CSS code developer, as for the (static) analysis of CSS code, that some declaration values are normalized. This is the case if for example, one wishes to implement string-compares to verify equality of declarations and values. So, this transformation entails the normalization of color, URL –and zero-valued declarations. Also, the transformation includes

splitting-up shorthand declarations.

<div class=”home”> <div class=”header”> <span>Welcome</span> </div> </div> .home .header{ background-color: black } .home .footer{ background-color: white; }

(21)

13

Color values. The CSS language supports different notations for colors. For example[9] the

color Violet:

NOTATION VALUE

HTML Named Color (X118) Violet

Hexadecimal #EE82EE

RGB rgb(238, 130, 238)

RGBA rgba(238, 130, 238, 1)

HSL hsl(300, 76%, 72%)

HSLA hsla(300, 76%, 72%, 1)

Table 5 - Supported color notations in CSS

For more efficient analysis and a standardized output, we normalize every color according to the following rules:

1) Each X11(named) color, RGB color, RGBA color with Alpha value 1, HSL and HSLA color with value 1 is normalized to its Hexadecimal representation

2) Each RGBA and HSLA color with Alpha value lower than 1 is normalized by removing any whitespace inside brackets and removing the decimal prefix 0

3) Each transparent color is normalized to RGBA(0,0,0,0)

URL values. We normalize URL values by removing any http:// or https:// prefix.

Zero values. We normalize any zero-value by removing its unit. For example: the declaration

padding:0px, is normalized into padding: 0.

Normalization of shorthand declarations. We also normalize shorthand CSS declarations by

splitting them into multiple non-shorthand declarations. This transformation is useful when analyzing declarations for their effectiveness (3.1.4), because they can be analyzed without dealing with the multiple effects shorthand declarations may have. This normalization step is the exact opposite of the normalization described in 3.1.7

4.1.3 Remove duplicate declarations intra-selector

Within the scope of a single selector, declarations are applied by their order: lower located declarations are applied over higher located declarations. This behavior is not an issue if the declarations represent different style properties: they will not conflict. However, they do conflict if one or more declarations have equal names. Overridden declarations are not applied, and should be removed.

Declaration d1 in selector S is duplicate iff ∃d ∈ S, where d1.location < d.location AND

d1 EBN d AND d1 is not !important

definition 4-2

(22)

14

The second font-size declaration (at line 5) overrides the first font-size declaration (at line 2). The

declaration font-size: 2em; should be removed.

4.1.4 Remove ineffective selectors and declarations

A CSS declaration is effective if its value is applied to one or more DOM elements in one or more DOM states. The effectiveness a declaration depends on the selector in which the

declaration is contained: the specificity and cascading order of the selector, media-query scopes in which the selectors exists, and pseudo-selector presence in the selector.

These factors determine which selectors override other selectors, and thus which declarations override other declarations. Due to the possible combinations in which these factors may occur, we explain the rules for each rule separately. For simplicity, we use the term override in

definitions 4-3 –and 4-4.

The CSS language provides one exception to the factor mentioned above: if the !important

expression is appended to a declaration, the declaration is deemed effective, indifferent of the

selector in which it is contained. Unless another declaration also contains the !important expression.

In order to analyze the selectors, we need to order them first by their specificity and cascading order. The ordered list is then be processed by comparing media-queries, pseudo-selectors and declarations inside those selectors.

So, the following definitions apply to the effectiveness of selectors: Selector s1 is effective if it applies to ∃e ∈ Σ and ∀s ∈ Φ,

where s ≠ s1 AND s does not apply to e definition 4-3

Selector s1 is effective if it applies to ∃e ∈ Σ and ∃d ∈ s1, d ∉ s2, where s2 applies to e AND s2 overrides s1

definition 4-4

Finally, in the following descriptions on the factors influencing overrides, we assume that the selectors used in the examples always select the same element in a web document.

h2 { font-size: 2em; margin-bottom: 0.5em; padding-bottom: 0.5em; font-size: 30px; border-bottom: 1px solid #ccc; }

Figure 4 - Example duplicate declaration intra-selector

(23)

15

Specificity and cascading order. We adapted the CSS specification [15] based on a previous

Java implementation[10] to compute the specificity weight for CSS selectors. Inline CSS styles (inside DOM node tags) are excluded from the computation:

SW(s1) = concatenate (b, c, d) where SW is the specificity weight, s1 is a selector possibly composed of multiple selector types b, c and d.

 b = number of ID selectors in s1

 c = number class selectors and pseudo-class selectors in s1  d = number of element selectors and pseudo-elements in s1

definition 4-5

For example, we compute the following for CSS selector #id1 .class1:hover span::first-child: SW = 100000 (#id1) + 100 (.class1) + 100 (:hover) + 1 (span) + 1 (::first-child) = 100202 When two selectors have equal SW values, the overriding selector is determined by the cascading order (or location):

1) A selector is ordered by the order its origin: if it is defined in a stylesheet that is included later, it has a higher order;

2) A selector is ordered by its location within a stylesheet (i.e. its line number) 3) A selector is ordered by its location within a line (i.e. its column number)

Figures 5, 6 and 7 show examples of effectiveness comparisons. In these examples, we assume that all elements matched by the two selectors are ‘a’ elements with a ‘link’ class.

The second selector has a higher specificity and renders the first selector ineffective, because all declarations are EBN, thus overridden.

The first selector is still effective, because at least one declaration (font-size: 16px) is not overridden. .home #logo a{ SW = 100101

font-size: 16px; color: black; }

.home #logo .link{ SW = 100200

font-size: 18px color: white; } .home #logo a{ SW=100101 font-size: 16px; color: black; }

.home #logo .link{ SW=100200

color: white; }

Figure 5 - Specficity comparison example 1

(24)

16

The second selector has equal specificity but is placed lower in the file, thus rendering the first selector ineffective, due to its cascading order.

The same override is achieved by a second selector placed on the same line, but after the first selector. The same override is achieved by a second selector placed in another file, that is included in the web document after the selector in ‘this’ file is included.

Media-queries. Media-queries allow selector usage if specified conditions are met. Additional

rules are required to support queries in the analysis of effectiveness, because media-queries have no impact on specificity or the cascading order of selectors they contain. The following queries are checked while comparing two selectors:

1) On comparing a less-specific ‘regular’ selector to a more-specific ‘media’ selector, declarations contained in the regular selector are still effective.

2) On comparing a more-specific regular selector to a less-specific media selector, ebn declarations in the media selector not be effective, unless they are !important (see last paragraph)

3) On comparing two media selectors, but contained in different media-queries, declarations in both selectors are effective.

Note: This ruleset does not include analysis of the individual conditions expressed by two

media-queries, besides comparing them on difference. For instance, a media-query that applies to any screen with a max-width of 800px, also applies if the screen is 200px. Any other media-query, say max-width: 300px, may conflict with the first media-query.

Pseudo-selectors and pseudo-elements. Some pseudo-selectors have a similar effect as

media-queries. These nonstructural pseudo-selectors, are only applied when selectors deviate from their default UI state. The behavior of these selectors is dynamic and occurs from input the user provides via his browser. In the analysis of effectiveness the following rules apply to pseudo-selectors:

1) If both selectors have different pseudo-selectors, declarations in the less-specific selector are overridden if and only if the more-specific selector contains ebv declarations. Again, !important declarations may cause exceptions.

2) If both selectors have the same the same pseudo-selectors, declarations are processed normally, because the declarations are applied under the same conditions.

Pseudo-elements select specific parts, before, inside or after a DOM node. Therefore, if two selectors have different pseudo-elements, declarations inside the selectors are always effective.

The !important expression. As stated before, the !important expression allows for creating

exceptions to the normal CSS ruleset for applying declarations. Any declaration with an .home #logo a{ SW = 100101 font-size: 16px; color: black; } .home #logo a { SW = 100101 font-size: 18px color: white; }

(25)

17

!important expression will always be applied, unless there is another ebn !important declaration that is contained in a more specific selector, unless that selector is contained in a different media-selector or pseudo-media-selector.

4.1.5 Remove unnecessary default declarations

According to the CSS specification, every declaration type has either a default value or inherits a value from an ancestor element. For example, any browser should implement that a border has a default width value medium.

We assume the following default declaration values:

NAME DEFAULT VALUE

Width, height auto

Min-width, min-height 0

Max-width, max-height none

Padding, margin (-top, -right, -bottom, -left) 0

Border-width (-top, -right, -bottom, -left) medium

Border-style (-top, -right, -bottom, -left) none

Border-radius 0

Outline-width (-top, -right, -bottom, -left) 0

Outline-style (-top, -right, -bottom, -left) none

Background-image none Background-color rgba(0,0,0,0) Background-repeat repeat Background-position 0% 0% Background-attachment scroll Background-size auto Background-clip border-box Background-origin padding-box

Table 6 - Assumed default declaration values as defined by the CSS standard specification

Because these values should be built-in, it is not required to explicitly use declarations with default values. Previous research[19] however, has indicated the presence of declarations with default values in stylesheets. These may be used to undo previous non-default declarations, thus valid, or they are unnecessary and should be removed. In our analysis of these invalid default

styles, we assume that any browser is implemented according to the CSS standard specification.

Declaration d1 is an invalid undo style iff it applies to ∃e ∈ Σ and its value is a default value and ∀d2 ∈ Θ, where d2 EBN d1 AND d2 applies to e AND d1 is overridden by d2

(26)

18

The ‘border-bottom: none’ declaration in the .no-border undoes the .no-border-bottom declaration of the h2 selector, this is a valid undo style.

The ‘padding-bottom: 0’ declaration is an invalid undo style, because it has a default value and no other padding-bottom declaration exists.

4.1.6 Replace descendant selectors with child selectors

A CSS selector consists of multiple selector sequences divided by combinators, which allow for accurate selection of elements in a DOM tree. A CSS selector is interpreted from right to left by a browser. In case of a descendant combinator, for example .menu .item, the browser starts by matching an element with class item and search up the DOM tree for an ancestor element with class menu.

However, when this item element be located exactly one level deeper below the menu element, then the item element is a direct descendant or child of the menu element. CSS supports this structure with child combinators: .menu > .item.

According to CSS development resources (see section 3.2.1), a child combinator should be used when possible, in favor of performance. A browser matches child combinators faster than it matches descendant combinators.

A descendant combinator c1 must be transformed into a child combinator, if and only if ∀e ∈ Σ, the direct ancestor a of e is selectable by the first part of the c1, where c1 is part of selector s1 AND s1 applies to e.

definition 4-7

.home .header should be .home > .header, while .home span remains unchanged h2 { font-size: 2em; margin-bottom: 0.5em; border-bottom: 1px solid #ccc; } .no-border { padding-bottom: 0; border-bottom: none; } <div class=”home”> <div class=”header”> <span>Welcome</span> </div> </div> .home .header{ background-color: black } .home span { background-color: white; }

Figure 8 - Example invalid default style declaration

(27)

19 4.1.7 Normalization to shorthand

The CSS language supports shorthand declarations which group a set of individual declarations within the same selector. By introducing shorthand declarations, the total size of the stylesheet is reduced. The following CSS shorthand-declarations are included:

SHORTHAND PARTS

Margin margin-top, -right, -bottom, -left

Padding padding-top, -right, -bottom, -left

Background background-color, -image, -position, -size, -origin, -clip, -repeat,

-attachment

Outline outline-width, -style, -color

Border border-width, -style, -color

Border-width border-top-width, -right-width, -bottom-width, left-width

Border-style border-top-style, -right-style, -bottom-style, left-style

Border-color border-top-color, -right-color, -bottom-color, left-color

Border-top border-top-width, -top-style, -top-color

Border-right border-right-width, -right-style, -right-color

Border-bottom border-bottom-width, -bottom-style, -bottom-color

Border-left border-left-width, -left-style, -left-color

Border-radius border-top-left-radius, -top-right-radius, -bottom-right-radius,

-bottom-left-radius

Table 7 - Supported shorthand normalizations

The declarations at line 2-5 are transformed into

padding: 20px 10px. The declarations at line 6-8

are transformed into border: 1px solid red.

4.2 SASS Transformations

4.2.1 Generate variables

Variable generation in SASS is an easy way to collect information that is reusable throughout the entire stylesheet. For example, a color: red declaration is used several times in one stylesheet. By extracting a $color_red variable from these declarations, we are able to change one value (in the

h2 { padding-left: 20px; padding-right: 20px; padding-bottom: 10px; padding-top: 10px; border-width: 1px; border-style: solid; border-color: red; }

Figure 10 - Example normalization of declarations to shorthand representation

(28)

20

variable) which propagates to the declarations using that variable. In our example this would affect any declaration containing a $color_red value.

Shorthand declarations are also affected by the variable generation, for example background:

no-repeat #ffffff 20px 20px, is transformed into background: no-no-repeat $color_white 20px 20px,

while extracting the $color_white variable. We also generate variables for font-stacks and URLs used a given stylesheet: $font-stack: font… and $url: url(…).

4.2.2 Encapsulate clones in mixins

We adapt the approach used in the research by Mazinanian et al[9]. to identify clones in CSS code. The authors identify three duplication types in CSS: (1) lexically identical values for different properties, (2) declarations that have equivalent values for given properties and (3) a set of individual-property declarations that is equivalent with a shorthand-property declaration. The Growth association rule mining algorithm is used to find frequent itemsets using a FP-tree (frequent-pattern-FP-tree). Defined in the data mining domain, a selector is a transaction, its declarations are items, and a frequent itemset is a group of declarations that exists in at least two transactions. The algorithm produces a list of frequent itemsets. This list is analyzed for

refactoring opportunities by filtering conflicting[21] refactorings, such that transformations may be applied without changing the stylesheet’s semantics. Effectively, this is done by ranking the frequent itemsets impact (number of lines removed) and selecting the first itemset in that ordered list. Finally, the authors merge (parts of) transactions related to the selected frequent itemset, if the order dependencies (or cascading order) are not affected by that merge.

.largeTile {

border: 1px solid black; color: white; background: grey; height:200px; width:200px; } .smallTile { height:50px; width:50px;

border: 1px solid black; color: white;

background: grey; }

@mixin mixin1 {

border: 1px solid black; color: white; background: grey; } .largeTile{ @include mixin1; height:200px; width:200px; } .smallTile{ height:50px; width:50px; @include mixin1; }

Figure 11 - Example grouping cloned declarations in SASS mixin

(29)

21

Figure 11 shows the adaptation of SASS mixins, to extract declaration clones, instead of merging selectors. A mixin is a construct that allows us to reuse groups of declarations throughout a stylesheet. By using mixins, we avoid any order dependency problem, because the order of selectors (that contain the cloned declarations) remains unchanged. We simply replace groups of declarations with @include statements.

Finally, we do not generate SASS mixins when they do not adhere to a pre-defined threshold: SASS mixin m is included iff D(m) – 1 ∗ S(m) > D(m), where D is the

number of declarations grouped in mixin m, and S is the number of related selectors for mixin m

definition 4-8

In words: the number of declarations saved by introducing @include statements must exceed the number of declarations contained in the @mixin statement plus 1 (for the @include statement).

4.2.3 Generate parameterized merge mixins

SASS mixins are also useful for other optimizations, because they are able to use parameterized values in their body. An often shown example is an

adaption for vendor-specific declarations:

These solutions allow for shorter CSS code, much like CSS shorthand declarations.

We apply this feature on paddings and margins that are not fit for their shorthand counterparts.

For example, the following padding declarations

are not fit for a shorthand declaration, but are replaced by a padding mixin:

The transformation is only applied if at least two are replaced by the @include. The same

transformation is executed for any group of non-shorthand margin declarations within a selector. @mixin border-radius($radius) { -webkit-border-radius: $radius; -moz-border-radius: $radius; -ms-border-radius: $radius; border-radius: $radius; }

.box { @include border-radius(10px); }

.box {

padding-top: 20px; padding-right: 10px; padding-left: 5px; }

@mixin padding ($top:null, $right:null, $bottom:null, $left:null) { padding-top: $top; padding-right: $right; padding-bottom: $bottom;; padding-left: $left; } .box { @include padding($top:20px, $right:10px, $left:5px); }

Figure 12 - Parameterized mixin from

http://sass-lang.com/guide

(30)

22

4.3 Transformation exclusions

Some complex features of the CSS language are excluded from the transformations and not used in any way within the analysis. These declarations –and selectors are simply ignored and

provided as-is in the output of the transformations. 4.3.1 Declaration-level exclusions

The CSS language supports many complex declarations. The following declarations are ignored: (1) declarations with a vendor-prefixed value, (2) declarations with –gradient in their name, (3) declarations with progid: in their name and (4) declarations that start with an underscore.

4.3.2 Selector-level exclusion

The :not pseudo-selector is excluded from any transformation, because our tooling showed unexpected behavior during initial implementations. The Java library used to select DOM nodes by CSS selectors (see section 5.3) produced unhandled exceptions when testing :not selectors against DOM states. The impact of this exclusion is relatively low, as examined by conducting a small case study on our research objects.

We adapted part of the framework (chapter 5) to crawl a set of websites which include CSS code. We used the research objects defined in chapter 6.2. We measured the total number of selectors for any website, both inside and outside media-queries, and the total number of selectors including a :not selector. The case study results are displayed in Appendix B. Figure 14 shows the percentage of :not selectors to the total number of CSS selectors detected, per website.

Figure 14 - Scatterplot comparing :not selectors and total selectors

Results show that only 31 websites included CSS code containing at least one :not selector. Only 0.75% of all selectors in 100 websites used a :not selector.

0 1 2 3 4 5 6 0 2000 4000 6000 8000 10000 12000 14000 % d etec ted :n o t selec to rs # detected CSS selectors

(31)

23

If we observe the results for all websites, we find a low average and median value for the percentage of :not selectors, indicating a relatively low usage of :not selectors in our research objects.

Mean Median Max

Number of selectors 1919.16 771 12302

Number of :not selectors 14.39 0 424

% :not selectors 0.37 0.00 5.48

Table 8 - Descriptive statistics on :not selectors versus all selectors

Based on these values, we state that the impact of excluding :not selectors is low. On average, 0.37% less CSS selectors will be touched in the analysis, by excluding :not selectors.

(32)

24

5. The CSS transformation framework

We implemented the proposed transformations in Java application called CRET (CSS Re-Engineering Tool), which is publically available on GitHub9. In this chapter, we describe the framework containing these transformations. First, we show how the tool is able to automatically crawl a website –and detect any CSS code used inside it. Then, we describe the various libraries used in CRET. Finally, we elaborate on several transformations by describing the algorithms used in their implementations.

5.1 Crawljax

CRET’s target user is any front-end developer wanting to improve the maintainability and performance of the CSS code he works on. Therefore, the tool should be able to support two features:

1) The ability to automatically crawl a given website, detect different DOM states and CSS code –and execute the proposed transformations;

2) The ability to crawl any modern web application, including those that use AJAX10. AJAX. Asynchronous JavaScript and XML is a method that allows for more interactive web

applications by asynchronously handling user-input. This means that user interaction with a website does not require a full page reload, where the browser performs a HTTP request and waits for the webserver to return the new HTML page. Instead, the input of the user is processed by an ‘Ajax engine’, usually via a JavaScript call, which updates only parts of a webpage via an XML request-response. So, requests to the webserver are generated without blocking the user interaction and the responses are processed when they are returned to the browser.

Crawling web applications. The goal of crawling a web application, is to discover the web

pages contained inside that web application. Crawling any web application results in a model[22] consisting of the states that represent distinct pages and the transitions that represent the various ways to move between those states.

Different crawling strategies are required for different web applications. Traditionally, every distinct state was identifiable by its URL, because every change resulted from a full page-reload. Today however, many web applications employ client-side scripts (AJAX) to change their state without updating the URL. Event-based crawling features detection of new states by execution

every possible user interaction.

Crawljax. There are several crawlers[22] available, which employ various techniques to

discover different states, including breadth-first, depth-first and model-based search. CRET is implemented as a Crawljax[23][24] plug-in. Crawljax is a depth-first crawler, capable of

9https://github.com/axelpolet89/CRET

(33)

25

executing client-side code and discovering events that change the state of the web application. Crawljax has been successfully employed in previous research on CSS code smells[19] and JavaScript code smells[25].

5.2 Plug-in implementation

Initially, we reverse engineered Java implementations of previously implemented plug-ins, such as the Cilla[10] plug-in11, as foundations of CRET. These implementations provided good insight in Crawljax’ processes –and methods by which CSS code is parsed. Ultimately, CRET was implemented from scratch, only using the CSS code recognition –and CSS code parse implementation from Cilla.

The core of CRET (CssSuitePlugin class) implements two Crawljax interfaces,

OnNewStatePlugin and PostCrawlingPlugin, allowing it to interact with any newly discovered

DOM state –and performing a sequence of transformations after crawling is finished. 5.2.1 OnNewState

The following actions are performed when a new DOM state is discovered by Crawljax and propagated via the onNewState function call:

1) Parse the external CSS files from the related DOM by performing HTTP-GET requests on the stylesheet links contained inside the DOM’s <head> tag.

2) Verify the CSS file has not been encountered in a previously discovered DOM state, and store it.

3) Parse any embedded CSS code ‘one’ embedded CSS file by taking any string inside any

<style>…</style> tag, and store it.

4) Store the order in which the CSS files are included in the DOM state

5) Execute the first analysis, as described in section 4.2.1, by testing CSS selectors against elements contained in the DOM state.

Ultimately, we retain every matched DOM element in a single MatchedElements object, alongside the parsed external –and embedded CSS files.

5.2.2 PostCrawling

A crawling may finish on account of three conditions: the maximum crawltime is exceeded, the maximum amount of DOM states has been discovered or all DOM states within a certain depth have been discovered.

A finished crawling triggers the postCrawling function in the CssSuitePlugin class. The following actions are performed in the postCrawling function:

1) Execute transformations 1 through 7 in the following order: (1) normalize declarations and split shorthand declarations, (2) detect and remove cloned declarations intra-selectors, (3-4) detect and remove unmatched selectors and ineffective selectors and

(34)

26

declarations, (5) detect and remove any invalid undo declaration, (6) detect and change any descendant selector that can be transformed into a child selector and (7) normalize declarations by merging them into their shorthand representations.

2) Perform the described SASS transformations per CSS file in the following order: (1) extract any color, URL or font-stack declaration value into a SASS variable, (2) perform an FP-growth duplication detection to extract any groups of cloned declaration into SASS mixins and (3) merge any group of padding or margin declarations into one declarations using parameterized SASS mixins.

3) Compile any generated SASS code into CSS code by compiling each SASS file using the

JavaSassLib (see next section).

The CSS transformations listed under 1, are executed sequentially by triggering individual

ICssTransformer plugins. These plug-ins are instantiated once, then added to a list and then

executed by onPostCrawling. CssSuitePlugin onNewState(stateVertex, document) onPostCrawling() <<Interface>> ICssTransformer transform(cssRules, matchedElements) getStatistics(stringBuilder) 1-0..n

Figure 15 - Domain model ICssTransformer

The SASS transformations are performed by a single object, the SassBuilder. A SassBuilder is instantiated for every CSS file.

SassBuilder

_cssFile generateSass() generateVariables() processAndFilterClones() generateConvenienceMixins()

Figure 16 - Domain model SassBuilder

After performing these actions, CRET will have transformed and generated SASS (and CSS) code for each CSS file discovered during crawling.

5.3 Components

Figure 17 provides an overall view of the crawl –and transformation process performed on a single website. The flowchart depicts the order and relation between components, data and files. The ultimate result of this process is displayed in the lower-right corner: a set of SASS files and a set of CSS files, containing optimized CSS code.

(35)

27

Figure 17 - Flowchart CRET

CRET uses features provided by other (open-source) Java libraries the components responsible for parsing CSS code, validating CSS code, matching CSS to DOM elements and compiling SASS code into CSS code:

Component/Library Source

(SteadyState) CSS Parser http://cssparser.sourceforge.net/

W3C CSS Validator Service http://w3c.jcabi.com/css-validator.html (Fishtank) CSS Selectors https://github.com/chrsan/css-selectors JavaSass Compiler https://github.com/cathive/sass-java

CSS Object Model. The (SteadyState) CSS Parser library includes a CSS language object

model, in which CSS selectors are represented using the W3C Simple API12 for CSS (SAC).

CRET uses this object model in several transformations, for instance in the

descendant-to-child-transformation algorithm, see section 5.5.2.

(36)

28

DOM Object Model. Also, the (Fishtank) CSS Selectors library includes an object model

implementation based on org.w3c.dom interfaces13 for the Document Object Model. The most elementary class, Node, is also used in some transformations, including the

descendant-to-child-transformation, see section 5.5.3.

5.4 Features

CRET was originally based on the CSS analysis tool Cilla, and supported the CSS language features Cilla also supported. Additionally, CRET supports the extra CSS language features, including:

 Parse CSS3 selectors -and declarations;  Parse !important declarations;

 Ignore vendor declarations –and values;

 Recursively parse and analyze media-queries and their selectors;  Ignore non-style, non-media rules (such as @page and @import);  Ignore CSS selectors containing syntax-errors in rules, natively;

 Ignore CSS declarations that contain errors according to the W3C CSS validations;  Support attribute selectors in selecting DOM-nodes;

 Support structural pseudo-selectors in selecting DOM-nodes;

 Support non-structural pseudo-selectors in selecting DOM-nodes, except :not;  Support pseudo-elements in selecting DOM-nodes;

 Perform static analysis of selector/declaration effectiveness on normalized CSS code;

5.5 Algorithms

CRET incorporates several complex algorithms that perform analyses on CSS code, contained in one or more files, in combination with the DOM(s) related to that code. This section elaborates on the three most complex analyses implemented in CRET: Effectiveness of declarations and selectors (4.1.4), descendant-to-child selectors (4.1.6) and the detection and extraction of declaration clones into SASS mixins (4.2.2).

The algorithms use objects that represent CSS code structures, which are created at time of parsing CSS code discovered in a website. Two of the most important objects are the MSelector and MDeclaration, because their properties are used for the comparisons executed by the

algorithms.

Figure 18 shows the most used properties of the MDeclaration and MSelector objects. Each of the private fields in these classes is publically accessible by a getter function, such as getName or

isImportant, and is as such displayed in the algorithms of this section.

Referenties

GERELATEERDE DOCUMENTEN

Copyright and moral rights for the publications made accessible in the public portal are retained by the authors and/or other copyright owners and it is a condition of

National-8 - = Council for the judiciary Within each new District Court, the judges of the former Sub-district Courts will be part of a specialized canton law sector, headed by

The function of respiratory chain com- plexes was assessed by a strategy (Salabei et al. 2014 ) based on applying complex-specific substrates and inhibitors, with exact

The proposed two-step method is tested on a data set of 27 gas-phase molecules belonging to the carbon cycle: first, the errors are pinpointed based on formation energies, and

This article seeks to examine that issue from the perspective of the free movement of workers, with the first section setting out the rights that migrant workers and their family

These challenges will be divided into present compressor control limitations, shaft compressed air challenges and challenges with the supply lines of the

Experimental results show error-free wavelength selection of four modulated signals at distinct wavelengths by using two optical switches with a power penalty of

schade door hoge doses moet worden voorkomen, door het nemen van zo- danige maatregelen, dat het dosisequivalent voor individuele personen beneden het