CSC/ECE 517 Spring 2016 M1602 Make image loads conform with the spec: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(70 intermediate revisions by 4 users not shown)
Line 1: Line 1:
<font size="5">Making image load conform with the spec</font><br>
<font size="5">Making image load conform with the spec</font><br>
[https://en.wikipedia.org/wiki/HTML5 HTML 5] specifies a complex model for image loading on a web browser. It has specifications<ref>https://html.spec.whatwg.org/multipage/#the-picture-element</ref> for [https://html.spec.whatwg.org/multipage/#the-picture-element picture element] as well as img element, and browsers need to follow these HTML 5 specifications to conform to the standard. Servo's current implementation of image loading is [http://mxr.mozilla.org/servo/source/components/script/dom/htmlimageelement.rs#107 straightforward, but non-compliant] with HTML 5 standards<ref>https://html.spec.whatwg.org/multipage/</ref> in a number of important ways. The goal of this project is to implement image loading behavior on Servo browser that is more compliant with HTML 5 so its easy to both implement and verify against the text of the specification.
[https://en.wikipedia.org/wiki/HTML5 HTML 5] specifies a complex model for image loading on a web browser. It has specifications<ref>https://html.spec.whatwg.org/multipage/#the-picture-element</ref> for [https://html.spec.whatwg.org/multipage/#the-picture-element picture element] as well as img element, and browsers need to follow these HTML 5 specifications to conform to the standard. Servo's current implementation of image loading is [http://mxr.mozilla.org/servo/source/components/script/dom/htmlimageelement.rs#107 straightforward, but non-compliant] with HTML 5 standards<ref>https://html.spec.whatwg.org/multipage/</ref> in a number of important ways. The goal of this project is to implement image loading behavior on Servo browser that is more compliant with HTML 5 so its easy to both implement and verify against the text of the specification.
==Introduction==


===Servo===
[https://github.com/servo/servo Servo] is a [https://en.wikipedia.org/wiki/Web_browser web browser] layout engine written in [https://www.mozilla.org/en-US/?v=b Mozilla]'s new [https://en.wikipedia.org/wiki/System_programming_language systems language] [https://en.wikipedia.org/wiki/Rust_(programming_language) Rust]<ref>https://servo.org/</ref>. It is currently being developed by Mozilla Research. The aim of the project is not to create a full browser but rather to create better parallelism<ref>https://www.usenix.org/legacy/event/hotpar09/tech/full_papers/jones/jones.pdf</ref>, security<ref>https://en.wikipedia.org/wiki/Browser_security</ref>, modularity<ref>https://msdn.microsoft.com/en-us/library/ff709921.aspx</ref> and performance. The Servo project is [https://en.wikipedia.org/wiki/Open-source_software open sourced] and receives contributions from individual contributors from around the globe. It currently supports [https://www.linux.com/ Linux], [http://www.apple.com/osx/ OS X], [https://www.microsoft.com/en-us/windows Windows], [https://www.android.com/ Android], and [https://en.wikipedia.org/wiki/Gonk Gonk] (Firefox OS).


[https://github.com/servo/servo Servo] is a [https://en.wikipedia.org/wiki/Web_browser web browser] layout engine written in [https://www.mozilla.org/en-US/?v=b Mozilla]'s new [https://en.wikipedia.org/wiki/System_programming_language systems language] [https://en.wikipedia.org/wiki/Rust_(programming_language) Rust]<ref>https://servo.org/</ref>. It is currently being developed by Mozilla Research. The aim of the project is not to create a full browser but rather to create better parallelism<ref>https://www.usenix.org/legacy/event/hotpar09/tech/full_papers/jones/jones.pdf</ref>, security<ref>https://en.wikipedia.org/wiki/Browser_security</ref>, modularity<ref>https://msdn.microsoft.com/en-us/library/ff709921.aspx</ref> and performance. The Servo project is [https://en.wikipedia.org/wiki/Open-source_software open sourced] and receives contributions from individual contributors from around the globe. It currently supports [https://www.linux.com/ Linux], [http://www.apple.com/osx/ OS X], [https://www.microsoft.com/en-us/windows Windows], [https://www.android.com/ Android], and [https://en.wikipedia.org/wiki/Gonk Gonk] (Firefox OS).
Hatched by Mozilla employee Graydon Hoare back in 2009, Rust was built from the ground up using elements from modern programming language design<ref>http://readwrite.com/2015/07/02/mozilla-rust-programming-language-potential/</ref>. Rust is a [https://en.wikipedia.org/wiki/General-purpose_programming_language general-purpose], [https://developer.mozilla.org/ar/docs/multiparadigmlanguage.html multi-paradigm], [https://en.wikipedia.org/wiki/Compiled_language compiled programming] language, supporting pure-functional, imperative-procedural, and object-oriented styles<ref>https://en.wikipedia.org/wiki/Rust_(programming_language)</ref>. It focuses on performance, parallelization, and memory safety and does so because unlike other programming languages it doesn't suffer from "backward-compatibility requirements"<ref>http://readwrite.com/2015/07/02/mozilla-rust-programming-language-potential/</ref>.


===Rust===
==Project Description==
The detailed description of the project can be found [https://github.com/servo/servo/wiki/Image-load-conformance-student-project here].


Hatched by Mozilla employee Graydon Hoare back in 2009, Rust was built from the ground up using elements from modern programming language design<ref>http://readwrite.com/2015/07/02/mozilla-rust-programming-language-potential/</ref>. Rust is a [https://en.wikipedia.org/wiki/General-purpose_programming_language general-purpose], [https://developer.mozilla.org/ar/docs/multiparadigmlanguage.html multi-paradigm], [https://en.wikipedia.org/wiki/Compiled_language compiled programming] language, supporting pure-functional, imperative-procedural, and object-oriented styles<ref>https://en.wikipedia.org/wiki/Rust_(programming_language)</ref>. It focuses on performance, parallelization, and memory safety and does so because unlike other programming languages it doesn't suffer from "backward-compatibility requirements"<ref>http://readwrite.com/2015/07/02/mozilla-rust-programming-language-potential/</ref>.
The steps are as follows:


===HTML Image Element===
===Compilation and Build===
HTML image element has "image request" parameter which further has 3 parameters:
* The first step is to compile Servo browser and build it on a local machine. The steps for compiling and building Servo are:
* State
Servo is built with [https://mail.mozilla.org/pipermail/rust-dev/2014-March/009090.html Cargo], the Rust package manager. Mozilla's Mach tools are used to orchestrate the build and other tasks.
* Current URL
* Image data


The state parameter can be classified as one of 4 possible states:
    git clone https://github.com/servo/servo
* Unavailable
    cd servo
The user agent hasn't obtained any image data, or has obtained some or all of the image data but hasn't yet decoded enough of the image to get the image dimensions.
    ./mach build --dev
* Partially available
    ./mach run tests/html/about-mozilla.html
The user agent has obtained some of the image data and at least the image dimensions are available.
* Completely available
The user agent has obtained all of the image data and at least the image dimensions are available.
* Broken
The user agent has obtained all of the image data that it can, but it cannot even decode the image enough to get the image dimensions (e.g. the image is corrupted, or the format is not supported, or no data could be obtained).


Image request can be set to Pending Request, which is initially set to null or Current Request, which usually refers to the img element itself.
compile Servo and ensure that it runs tests/html/about-mozilla.html


==Scope==
===Initial Steps===
The scope of the project was to complete the initial steps mentioned [https://github.com/servo/servo/wiki/Image-load-conformance-student-project here].
The initial steps for the project were completed as a part of OSS project 2. The functionalities implemented were:
* Additional data types were defined in the HTML Image Element to add pending requests as well as current requests. The existing data types were modified so current request was used to store the image properties.
* A new attribute called Cross Origin was uncommented from existing Servo code and the make_enumerated_getter and setter macros were added to the code to implement Cross Origin.
* Current Src attribute was added to HTMLImageElement.webidl and appropriate attributes were added for its functionality.
* Image caching task was implemented, which accepted a URL and a vector of bytes. The cache was used to store the data collected as a newly-complete network request and continue decoding the result into pixel data.


The steps are as follows:
==Design Principles==
compile Servo and ensure that it runs on  tests/html/about-mozilla.html 
* Define data types to represent the image request concept, and add pending and current requests to the  HTMLImageElement  type in  htmlimageelement.rs . These should subsume the existing fields in  HTMLImageElement  that are used for storing the image's properties, and the fields of the current request should be used instead.
* Implement the crossOrigin attribute using the  make_enumerated_getter / make_setter  macros and uncommenting the attribute in  HTMLImageElement.webidl 
* Implement the currentSrc attribute by adding the appropriate attribute to  HTMLImageElement.webidl 
* Run  ./mach test-wpt tests/wpt/web-platform-tests/html/dom/interfaces.html  and adjust the test result expectations according to the documenatation.
* Add a command for the image cache task that accepts a URL and a vector of bytes. This command should instruct the cache to store this data as a newly-complete network request and continue decoding the result into pixel data.


These principles, when combined together, make it easy for a programmer to develop software that are easy to maintain and extend. They also make it easy for developers to avoid code smells, easily refactor code, and are also a part of the agile or adaptive software development.


The subsequent steps mentioned [https://github.com/servo/servo/wiki/Image-load-conformance-student-project here] are to be done for the final project.
===DRY Principle===


==Design Principals==
The very first design principle used was the DRY (don't repeat yourself) principle. The essence of this principle is to reduce repetition of information of all kinds. With the use of DRY principle, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync<ref>https://en.wikipedia.org/wiki/Don%27t_repeat_yourself</ref>.


There were no particular design principles used in this project as it was a modification of existing code. The same principals of the original Servo code can be thought of as being followed by the project. The main aim was to increase the code coverage and to make the Servo browser more compliant to HMTL 5 standards when it comes to image loading.
===Observer Pattern===


==Implementation==
The Servo project follows an Event-driven architecture (EDA), also known as Message-driven architecture, which is any software architecture pattern promoting the production, detection, consumption of, and reaction to [https://en.wikipedia.org/wiki/Event_(computing) events]. An event can be defined as "a significant change in state".<ref>https://en.wikipedia.org/wiki/Event-driven_architecture</ref> The biggest example of event-driven architecture is the Observer Pattern, which is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.<ref>https://en.wikipedia.org/wiki/Observer_pattern</ref> We are following the Observer Pattern by defining subjects having some observer dependencies, which are notified about state changes through the calling of one of our methods.


The following steps were followed to meet the project requirements as per this [https://github.com/servo/servo/wiki/Image-load-conformance-student-project github page].
===UML Class Diagram===


===Step 1===
The following is a class diagram depicting the steps involved in the project. For readability purposes, only the classes relevant to the project have been depicted.


As we need to define data types to represent the image request concept, and add pending and current requests to the  HTMLImageElement  type in  htmlimageelement.rs . These should subsume the existing fields in  HTMLImageElement  that are used for storing the image's properties, and the fields of the current request should be used instead.  
[[File:class_diagram_M1602.png]]


===Flowcharts===


[[File:ImageRequest.png]]
This project involves implementing several algorithms while making changes in the HTML image element. The flowcharts of the algorithms have been depicted below.


===Step 2===
====Algorithm 1====


As we had to implement the crossOrigin attribute , we uncommented it in the HTMLImageElement.webidl file and then we created a getter and setter method for it in the HTMLImageElement.rd file using the  make_enumerated_getter / make_setter  macros .
[[File:parsasize.png]]


==Implementation==
===Initial Steps===
The following steps were followed to meet the project requirements as per this [https://github.com/servo/servo/wiki/Image-load-conformance-student-project github page].


[[File:CrossOrigin_webidl.png]]
====Step 1====


HTMLImageElement.rs file
Defined data types to represent the image request concept, and add pending and current requests to the  HTML image element. These had to subsume the existing fields in HTMLImageElement that are used for storing the image's properties, and the fields of the current request had to be used instead.  


[[File:CrossOrigin.png]]
====Step 2====


===Step 3===
Implemented the cross origin attribute , for which we uncommented it in the HTMLImageElement.webidl file and then we created a getter and setter method for it in the HTMLImageElement.rd file using the  make_enumerated_getter / make_setter  macros .


implement the currentSrc attribute by adding the appropriate attribute to  HTMLImageElement.webidl 
====Step 3====


[[File:currentSrc.png]]
Implemented the current SRC attribute by adding the appropriate attribute to  HTMLImageElement.webidl.


== Testing ==
===Subsequent Steps===
 
These steps have to be implemented as a part of the final OSS project. The class diagram for this project is given [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2016_M1602_Make_image_loads_conform_with_the_spec#UML_Class_Diagram here]. The following are the steps required to complete the final project.
 
====Step 1====


Following are the steps to run all the tests for HTMLImageElement:
Adding a functionality html image element to replace existing image cache functionality and instruct it to fetch a URL directly from a network request. The code should enable the result to be sent directly to the image cache.


# Install the pre-requisites required for servo as mentioned [https://github.com/servo/servo/blob/master/README.md here]
====Step 2====
# Run the following commands


<code>
Implementing the parse a srcset attribute algorithm by defining a method to parse a scrset based on HTML 5 standards. To demonstrate the correctness of the algorithm, write unit tests in  tests/unit/script/htmlimageelement.rs.
  cd
====Step 3====
</code>


<code>
Implementing the parse a sizes attribute algorithm by defining a method to parse an image size based on HTML 5 standards. To demonstrate the correctness of the algorithm, write unit tests in tests/unit/script/htmlimageelement.rs . The flowchart for the algorithm can be found [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Spring_2016_M1602_Make_image_loads_conform_with_the_spec#Algorithm_1 here]
  git clone https://github.com/akhan7/servo.git
</code>


<code>
== Testing ==
cd servo
</code>


<code>
Following are the steps to run all the tests for HTMLImageElement:
./mach build --dev
</code>


'''Note:''' It may take around 30-40 mins to build. Check to see if the build is successful by running
# Install the pre-requisites required for servo as mentioned [https://github.com/servo/servo/blob/master/README.md here]
# Run the following command on your terminal


<code>
<code>
Line 105: Line 98:


The Servo browser should open and load the about-Mozilla web page.
The Servo browser should open and load the about-Mozilla web page.
Now open terminal and run
Now run the following command:


<code>
<code>
Line 114: Line 107:


'''Note:''' We have not added any new tests to the test suite as servo follows TDD and tests were previously written for HTML image element. We have just adjusted some of the test expectations for the tests which now pass due to our implementation.
'''Note:''' We have not added any new tests to the test suite as servo follows TDD and tests were previously written for HTML image element. We have just adjusted some of the test expectations for the tests which now pass due to our implementation.
===Test Tidy===
The Mozilla development team has a strict coding standard that all projects have to adhere to. To ensure that the project code conforms with the Mozilla coding standard, they have a code given below:
<code>
./mach test-tidy 
</code>
Issues reported by test are to be fixed before pull request can be generated. Once the test passes, it means that our code is following the standards of Mozilla. Running the above code, you can see that it passes and our code conforms to the Mozilla coding standards.
===Unit Test Cases===
Unit test cases have been added for parse a size algorithm. The result value (size) was checked and the correctness of the parsed expressions (MQ) was also checked. These test cases are passing, implying the algorithm is working as expected.


=== Testing From UI ===
=== Testing From UI ===
Line 125: Line 132:
</code>
</code>


==Pull Request==
If the browser is opened without any error messages, it means Servo is working as expected and our code modifications have not caused existing code to break.
Here is our [https://github.com/servo/servo/pull/10134 pull request]. In the link you can see all code snippets changed due to implementing the above steps, as well as integration test progression information.
 
==Conclusion==
 
As a result of the changes made in the initial and subsequent parts of the project, Servo's image loading algorithms and behavior are aligned to the specs given by HTML 5 in a more comprehensive way.
 
A video has been made demonstrating the functioning of the algorithms. You can find the video [https://youtu.be/n6GeN3uZNek here].


==References==
==References==
<references/>
<references/>

Latest revision as of 13:04, 4 May 2016

Making image load conform with the spec
HTML 5 specifies a complex model for image loading on a web browser. It has specifications<ref>https://html.spec.whatwg.org/multipage/#the-picture-element</ref> for picture element as well as img element, and browsers need to follow these HTML 5 specifications to conform to the standard. Servo's current implementation of image loading is straightforward, but non-compliant with HTML 5 standards<ref>https://html.spec.whatwg.org/multipage/</ref> in a number of important ways. The goal of this project is to implement image loading behavior on Servo browser that is more compliant with HTML 5 so its easy to both implement and verify against the text of the specification.

Servo is a web browser layout engine written in Mozilla's new systems language Rust<ref>https://servo.org/</ref>. It is currently being developed by Mozilla Research. The aim of the project is not to create a full browser but rather to create better parallelism<ref>https://www.usenix.org/legacy/event/hotpar09/tech/full_papers/jones/jones.pdf</ref>, security<ref>https://en.wikipedia.org/wiki/Browser_security</ref>, modularity<ref>https://msdn.microsoft.com/en-us/library/ff709921.aspx</ref> and performance. The Servo project is open sourced and receives contributions from individual contributors from around the globe. It currently supports Linux, OS X, Windows, Android, and Gonk (Firefox OS).

Hatched by Mozilla employee Graydon Hoare back in 2009, Rust was built from the ground up using elements from modern programming language design<ref>http://readwrite.com/2015/07/02/mozilla-rust-programming-language-potential/</ref>. Rust is a general-purpose, multi-paradigm, compiled programming language, supporting pure-functional, imperative-procedural, and object-oriented styles<ref>https://en.wikipedia.org/wiki/Rust_(programming_language)</ref>. It focuses on performance, parallelization, and memory safety and does so because unlike other programming languages it doesn't suffer from "backward-compatibility requirements"<ref>http://readwrite.com/2015/07/02/mozilla-rust-programming-language-potential/</ref>.

Project Description

The detailed description of the project can be found here.

The steps are as follows:

Compilation and Build

  • The first step is to compile Servo browser and build it on a local machine. The steps for compiling and building Servo are:

Servo is built with Cargo, the Rust package manager. Mozilla's Mach tools are used to orchestrate the build and other tasks.

   git clone https://github.com/servo/servo
   cd servo
   ./mach build --dev
   ./mach run tests/html/about-mozilla.html

compile Servo and ensure that it runs tests/html/about-mozilla.html

Initial Steps

The initial steps for the project were completed as a part of OSS project 2. The functionalities implemented were:

  • Additional data types were defined in the HTML Image Element to add pending requests as well as current requests. The existing data types were modified so current request was used to store the image properties.
  • A new attribute called Cross Origin was uncommented from existing Servo code and the make_enumerated_getter and setter macros were added to the code to implement Cross Origin.
  • Current Src attribute was added to HTMLImageElement.webidl and appropriate attributes were added for its functionality.
  • Image caching task was implemented, which accepted a URL and a vector of bytes. The cache was used to store the data collected as a newly-complete network request and continue decoding the result into pixel data.

Design Principles

These principles, when combined together, make it easy for a programmer to develop software that are easy to maintain and extend. They also make it easy for developers to avoid code smells, easily refactor code, and are also a part of the agile or adaptive software development.

DRY Principle

The very first design principle used was the DRY (don't repeat yourself) principle. The essence of this principle is to reduce repetition of information of all kinds. With the use of DRY principle, a modification of any single element of a system does not require a change in other logically unrelated elements. Additionally, elements that are logically related all change predictably and uniformly, and are thus kept in sync<ref>https://en.wikipedia.org/wiki/Don%27t_repeat_yourself</ref>.

Observer Pattern

The Servo project follows an Event-driven architecture (EDA), also known as Message-driven architecture, which is any software architecture pattern promoting the production, detection, consumption of, and reaction to events. An event can be defined as "a significant change in state".<ref>https://en.wikipedia.org/wiki/Event-driven_architecture</ref> The biggest example of event-driven architecture is the Observer Pattern, which is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.<ref>https://en.wikipedia.org/wiki/Observer_pattern</ref> We are following the Observer Pattern by defining subjects having some observer dependencies, which are notified about state changes through the calling of one of our methods.

UML Class Diagram

The following is a class diagram depicting the steps involved in the project. For readability purposes, only the classes relevant to the project have been depicted.

Flowcharts

This project involves implementing several algorithms while making changes in the HTML image element. The flowcharts of the algorithms have been depicted below.

Algorithm 1

Implementation

Initial Steps

The following steps were followed to meet the project requirements as per this github page.

Step 1

Defined data types to represent the image request concept, and add pending and current requests to the HTML image element. These had to subsume the existing fields in HTMLImageElement that are used for storing the image's properties, and the fields of the current request had to be used instead.

Step 2

Implemented the cross origin attribute , for which we uncommented it in the HTMLImageElement.webidl file and then we created a getter and setter method for it in the HTMLImageElement.rd file using the make_enumerated_getter / make_setter macros .

Step 3

Implemented the current SRC attribute by adding the appropriate attribute to HTMLImageElement.webidl.

Subsequent Steps

These steps have to be implemented as a part of the final OSS project. The class diagram for this project is given here. The following are the steps required to complete the final project.

Step 1

Adding a functionality html image element to replace existing image cache functionality and instruct it to fetch a URL directly from a network request. The code should enable the result to be sent directly to the image cache.

Step 2

Implementing the parse a srcset attribute algorithm by defining a method to parse a scrset based on HTML 5 standards. To demonstrate the correctness of the algorithm, write unit tests in tests/unit/script/htmlimageelement.rs.

Step 3

Implementing the parse a sizes attribute algorithm by defining a method to parse an image size based on HTML 5 standards. To demonstrate the correctness of the algorithm, write unit tests in tests/unit/script/htmlimageelement.rs . The flowchart for the algorithm can be found here

Testing

Following are the steps to run all the tests for HTMLImageElement:

  1. Install the pre-requisites required for servo as mentioned here
  2. Run the following command on your terminal

./mach run tests/html/about-mozilla.html

The Servo browser should open and load the about-Mozilla web page. Now run the following command:

./mach test-wpt tests/wpt/web-platform-tests/html/dom/interfaces.html

You will see that all tests pass as expected.

Note: We have not added any new tests to the test suite as servo follows TDD and tests were previously written for HTML image element. We have just adjusted some of the test expectations for the tests which now pass due to our implementation.

Test Tidy

The Mozilla development team has a strict coding standard that all projects have to adhere to. To ensure that the project code conforms with the Mozilla coding standard, they have a code given below:

./mach test-tidy  

Issues reported by test are to be fixed before pull request can be generated. Once the test passes, it means that our code is following the standards of Mozilla. Running the above code, you can see that it passes and our code conforms to the Mozilla coding standards.

Unit Test Cases

Unit test cases have been added for parse a size algorithm. The result value (size) was checked and the correctness of the parsed expressions (MQ) was also checked. These test cases are passing, implying the algorithm is working as expected.

Testing From UI

Our project cannot be tested from UI since the project aims to make image loading on Servo browser more conformant to HTML5 standards. However you can check that it doesn't break the existing code and the browser runs correctly by running a test page on servo after performing the build as mentioned above.

Run the following command after the project is build:

./mach run tests/html/about-mozilla.html

If the browser is opened without any error messages, it means Servo is working as expected and our code modifications have not caused existing code to break.

Conclusion

As a result of the changes made in the initial and subsequent parts of the project, Servo's image loading algorithms and behavior are aligned to the specs given by HTML 5 in a more comprehensive way.

A video has been made demonstrating the functioning of the algorithms. You can find the video here.

References

<references/>