summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src')
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.html20
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts38
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.ts34
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.module.ts20
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts106
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts63
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts16
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.ts9
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css376
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css141
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts3
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.ts8
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/favicon.icobin0 -> 5430 bytes
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/index.html15
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/main.ts11
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/polyfills.ts68
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/styles.css1
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/test.ts32
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json13
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json20
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/typings.d.ts5
21 files changed, 999 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.html b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.html
new file mode 100644
index 0000000000..9a5a568732
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.html
@@ -0,0 +1,20 @@
+<section class="todoapp">
+ <header class="header">
+ <h1>Todos</h1>
+ <input class="new-todo" placeholder="What needs to be done?" autofocus="" [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()">
+ </header>
+ <section class="main" *ngIf="todos.length > 0">
+ <ul class="todo-list">
+ <li *ngFor="let todo of todos" [class.completed]="todo.complete">
+ <div class="view">
+ <input class="toggle" type="checkbox" (click)="toggleTodoComplete(todo)" [checked]="todo.complete">
+ <label>{{todo.title}}</label>
+ <button class="destroy" (click)="removeTodo(todo)"></button>
+ </div>
+ </li>
+ </ul>
+ </section>
+ <footer class="footer" *ngIf="todos.length > 0">
+ <span class="todo-count"><strong>{{todos.length}}</strong> {{todos.length == 1 ? 'item' : 'items'}} left</span>
+ </footer>
+</section> \ No newline at end of file
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts
new file mode 100644
index 0000000000..a8e9525e9d
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.spec.ts
@@ -0,0 +1,38 @@
+/* tslint:disable:no-unused-variable */
+
+import { TestBed, async } from '@angular/core/testing';
+import { AppComponent } from './app.component';
+import { FormsModule } from '@angular/forms';
+import { Todo } from './todo';
+
+describe('AppComponent', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ FormsModule
+ ],
+ declarations: [
+ AppComponent
+ ],
+ });
+ });
+
+ it('should create the app', async(() => {
+ let fixture = TestBed.createComponent(AppComponent);
+ let app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ }));
+
+ it(`should have a newTodo todo`, async(() => {
+ let fixture = TestBed.createComponent(AppComponent);
+ let app = fixture.debugElement.componentInstance;
+ expect(app.newTodo instanceof Todo).toBeTruthy()
+ }));
+
+ it('should display "Todos" in h1 tag', async(() => {
+ let fixture = TestBed.createComponent(AppComponent);
+ fixture.detectChanges();
+ let compiled = fixture.debugElement.nativeElement;
+ expect(compiled.querySelector('h1').textContent).toContain('Todos');
+ }));
+});
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.ts
new file mode 100644
index 0000000000..1ea0d80679
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.component.ts
@@ -0,0 +1,34 @@
+import {Component} from '@angular/core';
+import {Todo} from './todo';
+import {TodoDataService} from './todo-data.service';
+
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ providers: [TodoDataService]
+})
+export class AppComponent {
+
+ newTodo: Todo = new Todo();
+
+ constructor(private todoDataService: TodoDataService) {
+ }
+
+ addTodo() {
+ this.todoDataService.addTodo(this.newTodo);
+ this.newTodo = new Todo();
+ }
+
+ toggleTodoComplete(todo) {
+ this.todoDataService.toggleTodoComplete(todo);
+ }
+
+ removeTodo(todo) {
+ this.todoDataService.deleteTodoById(todo.id);
+ }
+
+ get todos() {
+ return this.todoDataService.getAllTodos();
+ }
+
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.module.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.module.ts
new file mode 100644
index 0000000000..67ae49119b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/app.module.ts
@@ -0,0 +1,20 @@
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { HttpModule } from '@angular/http';
+
+import { AppComponent } from './app.component';
+
+@NgModule({
+ declarations: [
+ AppComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpModule
+ ],
+ providers: [],
+ bootstrap: [AppComponent]
+})
+export class AppModule { }
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts
new file mode 100644
index 0000000000..1a15db9b5b
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.spec.ts
@@ -0,0 +1,106 @@
+import {TestBed, async, inject} from '@angular/core/testing';
+import {Todo} from './todo';
+import {TodoDataService} from './todo-data.service';
+
+describe('TodoDataService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [TodoDataService]
+ });
+ });
+
+ it('should ...', inject([TodoDataService], (service: TodoDataService) => {
+ expect(service).toBeTruthy();
+ }));
+
+ describe('#getAllTodos()', () => {
+
+ it('should return an empty array by default', inject([TodoDataService], (service: TodoDataService) => {
+ expect(service.getAllTodos()).toEqual([]);
+ }));
+
+ it('should return all todos', inject([TodoDataService], (service: TodoDataService) => {
+ let todo1 = new Todo({title: 'Hello 1', complete: false});
+ let todo2 = new Todo({title: 'Hello 2', complete: true});
+ service.addTodo(todo1);
+ service.addTodo(todo2);
+ expect(service.getAllTodos()).toEqual([todo1, todo2]);
+ }));
+
+ });
+
+ describe('#save(todo)', () => {
+
+ it('should automatically assign an incrementing id', inject([TodoDataService], (service: TodoDataService) => {
+ let todo1 = new Todo({title: 'Hello 1', complete: false});
+ let todo2 = new Todo({title: 'Hello 2', complete: true});
+ service.addTodo(todo1);
+ service.addTodo(todo2);
+ expect(service.getTodoById(1)).toEqual(todo1);
+ expect(service.getTodoById(2)).toEqual(todo2);
+ }));
+
+ });
+
+ describe('#deleteTodoById(id)', () => {
+
+ it('should remove todo with the corresponding id', inject([TodoDataService], (service: TodoDataService) => {
+ let todo1 = new Todo({title: 'Hello 1', complete: false});
+ let todo2 = new Todo({title: 'Hello 2', complete: true});
+ service.addTodo(todo1);
+ service.addTodo(todo2);
+ expect(service.getAllTodos()).toEqual([todo1, todo2]);
+ service.deleteTodoById(1);
+ expect(service.getAllTodos()).toEqual([todo2]);
+ service.deleteTodoById(2);
+ expect(service.getAllTodos()).toEqual([]);
+ }));
+
+ it('should not removing anything if todo with corresponding id is not found', inject([TodoDataService], (service: TodoDataService) => {
+ let todo1 = new Todo({title: 'Hello 1', complete: false});
+ let todo2 = new Todo({title: 'Hello 2', complete: true});
+ service.addTodo(todo1);
+ service.addTodo(todo2);
+ expect(service.getAllTodos()).toEqual([todo1, todo2]);
+ service.deleteTodoById(3);
+ expect(service.getAllTodos()).toEqual([todo1, todo2]);
+ }));
+
+ });
+
+ describe('#updateTodoById(id, values)', () => {
+
+ it('should return todo with the corresponding id and updated data', inject([TodoDataService], (service: TodoDataService) => {
+ let todo = new Todo({title: 'Hello 1', complete: false});
+ service.addTodo(todo);
+ let updatedTodo = service.updateTodoById(1, {
+ title: 'new title'
+ });
+ expect(updatedTodo.title).toEqual('new title');
+ }));
+
+ it('should return null if todo is not found', inject([TodoDataService], (service: TodoDataService) => {
+ let todo = new Todo({title: 'Hello 1', complete: false});
+ service.addTodo(todo);
+ let updatedTodo = service.updateTodoById(2, {
+ title: 'new title'
+ });
+ expect(updatedTodo).toEqual(null);
+ }));
+
+ });
+
+ describe('#toggleTodoComplete(todo)', () => {
+
+ it('should return the updated todo with inverse complete status', inject([TodoDataService], (service: TodoDataService) => {
+ let todo = new Todo({title: 'Hello 1', complete: false});
+ service.addTodo(todo);
+ let updatedTodo = service.toggleTodoComplete(todo);
+ expect(updatedTodo.complete).toEqual(true);
+ service.toggleTodoComplete(todo);
+ expect(updatedTodo.complete).toEqual(false);
+ }));
+
+ });
+
+}); \ No newline at end of file
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts
new file mode 100644
index 0000000000..509e37d5d4
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo-data.service.ts
@@ -0,0 +1,63 @@
+import {Injectable} from '@angular/core';
+import {Todo} from './todo';
+
+@Injectable()
+export class TodoDataService {
+
+ // Placeholder for last id so we can simulate
+ // automatic incrementing of id's
+ lastId: number = 0;
+
+ // Placeholder for todo's
+ todos: Todo[] = [];
+
+ constructor() {
+ }
+
+ // Simulate POST /todos
+ addTodo(todo: Todo): TodoDataService {
+ if (!todo.id) {
+ todo.id = ++this.lastId;
+ }
+ this.todos.push(todo);
+ return this;
+ }
+
+ // Simulate DELETE /todos/:id
+ deleteTodoById(id: number): TodoDataService {
+ this.todos = this.todos
+ .filter(todo => todo.id !== id);
+ return this;
+ }
+
+ // Simulate PUT /todos/:id
+ updateTodoById(id: number, values: Object = {}): Todo {
+ let todo = this.getTodoById(id);
+ if (!todo) {
+ return null;
+ }
+ Object.assign(todo, values);
+ return todo;
+ }
+
+ // Simulate GET /todos
+ getAllTodos(): Todo[] {
+ return this.todos;
+ }
+
+ // Simulate GET /todos/:id
+ getTodoById(id: number): Todo {
+ return this.todos
+ .filter(todo => todo.id === id)
+ .pop();
+ }
+
+ // Toggle todo complete
+ toggleTodoComplete(todo: Todo){
+ let updatedTodo = this.updateTodoById(todo.id, {
+ complete: !todo.complete
+ });
+ return updatedTodo;
+ }
+
+} \ No newline at end of file
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts
new file mode 100644
index 0000000000..5a54add348
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.spec.ts
@@ -0,0 +1,16 @@
+import {Todo} from './todo';
+
+describe('Todo', () => {
+ it('should create an instance', () => {
+ expect(new Todo()).toBeTruthy();
+ });
+
+ it('should accept values in the constructor', () => {
+ let todo = new Todo({
+ title: 'hello',
+ complete: true
+ });
+ expect(todo.title).toEqual('hello');
+ expect(todo.complete).toEqual(true);
+ });
+}); \ No newline at end of file
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.ts
new file mode 100644
index 0000000000..a1d0a768b7
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/app/todo.ts
@@ -0,0 +1,9 @@
+export class Todo {
+ id: number;
+ title: string = '';
+ complete: boolean = false;
+
+ constructor(values: Object = {}) {
+ Object.assign(this, values);
+ }
+} \ No newline at end of file
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css
new file mode 100644
index 0000000000..e04fbdbdb4
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-app.css
@@ -0,0 +1,376 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+button {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ background: none;
+ font-size: 100%;
+ vertical-align: baseline;
+ font-family: inherit;
+ font-weight: inherit;
+ color: inherit;
+ -webkit-appearance: none;
+ appearance: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ line-height: 1.4em;
+ background: #f5f5f5;
+ color: #4d4d4d;
+ min-width: 230px;
+ max-width: 550px;
+ margin: 0 auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-weight: 300;
+}
+
+:focus {
+ outline: 0;
+}
+
+.hidden {
+ display: none;
+}
+
+.todoapp {
+ background: #fff;
+ margin: 130px 0 40px 0;
+ position: relative;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
+ 0 25px 50px 0 rgba(0, 0, 0, 0.1);
+}
+
+.todoapp input::-webkit-input-placeholder {
+ font-style: italic;
+ font-weight: 300;
+ color: #e6e6e6;
+}
+
+.todoapp input::-moz-placeholder {
+ font-style: italic;
+ font-weight: 300;
+ color: #e6e6e6;
+}
+
+.todoapp input::input-placeholder {
+ font-style: italic;
+ font-weight: 300;
+ color: #e6e6e6;
+}
+
+.todoapp h1 {
+ position: absolute;
+ top: -155px;
+ width: 100%;
+ font-size: 100px;
+ font-weight: 100;
+ text-align: center;
+ color: rgba(175, 47, 47, 0.15);
+ -webkit-text-rendering: optimizeLegibility;
+ -moz-text-rendering: optimizeLegibility;
+ text-rendering: optimizeLegibility;
+}
+
+.new-todo,
+.edit {
+ position: relative;
+ margin: 0;
+ width: 100%;
+ font-size: 24px;
+ font-family: inherit;
+ font-weight: inherit;
+ line-height: 1.4em;
+ border: 0;
+ color: inherit;
+ padding: 6px;
+ border: 1px solid #999;
+ box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
+ box-sizing: border-box;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.new-todo {
+ padding: 16px 16px 16px 60px;
+ border: none;
+ background: rgba(0, 0, 0, 0.003);
+ box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
+}
+
+.main {
+ position: relative;
+ z-index: 2;
+ border-top: 1px solid #e6e6e6;
+}
+
+.toggle-all {
+ text-align: center;
+ border: none; /* Mobile Safari */
+ opacity: 0;
+ position: absolute;
+}
+
+.toggle-all + label {
+ width: 60px;
+ height: 34px;
+ font-size: 0;
+ position: absolute;
+ top: -52px;
+ left: -13px;
+ -webkit-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+
+.toggle-all + label:before {
+ content: '❯';
+ font-size: 22px;
+ color: #e6e6e6;
+ padding: 10px 27px 10px 27px;
+}
+
+.toggle-all:checked + label:before {
+ color: #737373;
+}
+
+.todo-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.todo-list li {
+ position: relative;
+ font-size: 24px;
+ border-bottom: 1px solid #ededed;
+}
+
+.todo-list li:last-child {
+ border-bottom: none;
+}
+
+.todo-list li.editing {
+ border-bottom: none;
+ padding: 0;
+}
+
+.todo-list li.editing .edit {
+ display: block;
+ width: 506px;
+ padding: 12px 16px;
+ margin: 0 0 0 43px;
+}
+
+.todo-list li.editing .view {
+ display: none;
+}
+
+.todo-list li .toggle {
+ text-align: center;
+ width: 40px;
+ /* auto, since non-WebKit browsers doesn't support input styling */
+ height: auto;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ margin: auto 0;
+ border: none; /* Mobile Safari */
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+.todo-list li .toggle {
+ opacity: 0;
+}
+
+.todo-list li .toggle + label {
+ /*
+ Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
+ IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
+ */
+ background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
+ background-repeat: no-repeat;
+ background-position: center left;
+}
+
+.todo-list li .toggle:checked + label {
+ background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
+}
+
+.todo-list li label {
+ word-break: break-all;
+ padding: 15px 15px 15px 60px;
+ display: block;
+ line-height: 1.2;
+ transition: color 0.4s;
+}
+
+.todo-list li.completed label {
+ color: #d9d9d9;
+ text-decoration: line-through;
+}
+
+.todo-list li .destroy {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 10px;
+ bottom: 0;
+ width: 40px;
+ height: 40px;
+ margin: auto 0;
+ font-size: 30px;
+ color: #cc9a9a;
+ margin-bottom: 11px;
+ transition: color 0.2s ease-out;
+}
+
+.todo-list li .destroy:hover {
+ color: #af5b5e;
+}
+
+.todo-list li .destroy:after {
+ content: '×';
+}
+
+.todo-list li:hover .destroy {
+ display: block;
+}
+
+.todo-list li .edit {
+ display: none;
+}
+
+.todo-list li.editing:last-child {
+ margin-bottom: -1px;
+}
+
+.footer {
+ color: #777;
+ padding: 10px 15px;
+ height: 20px;
+ text-align: center;
+ border-top: 1px solid #e6e6e6;
+}
+
+.footer:before {
+ content: '';
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ height: 50px;
+ overflow: hidden;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
+ 0 8px 0 -3px #f6f6f6,
+ 0 9px 1px -3px rgba(0, 0, 0, 0.2),
+ 0 16px 0 -6px #f6f6f6,
+ 0 17px 2px -6px rgba(0, 0, 0, 0.2);
+}
+
+.todo-count {
+ float: left;
+ text-align: left;
+}
+
+.todo-count strong {
+ font-weight: 300;
+}
+
+.filters {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ position: absolute;
+ right: 0;
+ left: 0;
+}
+
+.filters li {
+ display: inline;
+}
+
+.filters li a {
+ color: inherit;
+ margin: 3px;
+ padding: 3px 7px;
+ text-decoration: none;
+ border: 1px solid transparent;
+ border-radius: 3px;
+}
+
+.filters li a:hover {
+ border-color: rgba(175, 47, 47, 0.1);
+}
+
+.filters li a.selected {
+ border-color: rgba(175, 47, 47, 0.2);
+}
+
+.clear-completed,
+html .clear-completed:active {
+ float: right;
+ position: relative;
+ line-height: 20px;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.clear-completed:hover {
+ text-decoration: underline;
+}
+
+.info {
+ margin: 65px auto 0;
+ color: #bfbfbf;
+ font-size: 10px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-align: center;
+}
+
+.info p {
+ line-height: 1;
+}
+
+.info a {
+ color: inherit;
+ text-decoration: none;
+ font-weight: 400;
+}
+
+.info a:hover {
+ text-decoration: underline;
+}
+
+/*
+ Hack to remove background from Mobile Safari.
+ Can't use it globally since it destroys checkboxes in Firefox
+*/
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+ .toggle-all,
+ .todo-list li .toggle {
+ background: none;
+ }
+
+ .todo-list li .toggle {
+ height: 40px;
+ }
+}
+
+@media (max-width: 430px) {
+ .footer {
+ height: 50px;
+ }
+
+ .filters {
+ bottom: 10px;
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css
new file mode 100644
index 0000000000..4d25d3c84a
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/assets/css/todomvc-common.css
@@ -0,0 +1,141 @@
+hr {
+ margin: 20px 0;
+ border: 0;
+ border-top: 1px dashed #c5c5c5;
+ border-bottom: 1px dashed #f7f7f7;
+}
+
+.learn a {
+ font-weight: normal;
+ text-decoration: none;
+ color: #b83f45;
+}
+
+.learn a:hover {
+ text-decoration: underline;
+ color: #787e7e;
+}
+
+.learn h3,
+.learn h4,
+.learn h5 {
+ margin: 10px 0;
+ font-weight: 500;
+ line-height: 1.2;
+ color: #000;
+}
+
+.learn h3 {
+ font-size: 24px;
+}
+
+.learn h4 {
+ font-size: 18px;
+}
+
+.learn h5 {
+ margin-bottom: 0;
+ font-size: 14px;
+}
+
+.learn ul {
+ padding: 0;
+ margin: 0 0 30px 25px;
+}
+
+.learn li {
+ line-height: 20px;
+}
+
+.learn p {
+ font-size: 15px;
+ font-weight: 300;
+ line-height: 1.3;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#issue-count {
+ display: none;
+}
+
+.quote {
+ border: none;
+ margin: 20px 0 60px 0;
+}
+
+.quote p {
+ font-style: italic;
+}
+
+.quote p:before {
+ content: '“';
+ font-size: 50px;
+ opacity: .15;
+ position: absolute;
+ top: -20px;
+ left: 3px;
+}
+
+.quote p:after {
+ content: '”';
+ font-size: 50px;
+ opacity: .15;
+ position: absolute;
+ bottom: -42px;
+ right: 3px;
+}
+
+.quote footer {
+ position: absolute;
+ bottom: -40px;
+ right: 0;
+}
+
+.quote footer img {
+ border-radius: 3px;
+}
+
+.quote footer a {
+ margin-left: 5px;
+ vertical-align: middle;
+}
+
+.speech-bubble {
+ position: relative;
+ padding: 10px;
+ background: rgba(0, 0, 0, .04);
+ border-radius: 5px;
+}
+
+.speech-bubble:after {
+ content: '';
+ position: absolute;
+ top: 100%;
+ right: 30px;
+ border: 13px solid transparent;
+ border-top-color: rgba(0, 0, 0, .04);
+}
+
+.learn-bar > .learn {
+ position: absolute;
+ width: 272px;
+ top: 8px;
+ left: -300px;
+ padding: 10px;
+ border-radius: 5px;
+ background-color: rgba(255, 255, 255, .6);
+ transition-property: left;
+ transition-duration: 500ms;
+}
+
+@media (min-width: 899px) {
+ .learn-bar {
+ width: auto;
+ padding-left: 300px;
+ }
+
+ .learn-bar > .learn {
+ left: 8px;
+ }
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts
new file mode 100644
index 0000000000..3612073bc3
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.prod.ts
@@ -0,0 +1,3 @@
+export const environment = {
+ production: true
+};
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.ts
new file mode 100644
index 0000000000..f77781d5a6
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/environments/environment.ts
@@ -0,0 +1,8 @@
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build -prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `.angular-cli.json`.
+
+export const environment = {
+ production: false
+};
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/favicon.ico b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/favicon.ico
new file mode 100644
index 0000000000..8081c7ceaf
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/favicon.ico
Binary files differ
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/index.html b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/index.html
new file mode 100644
index 0000000000..5373d94497
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Angular 4 TodoMVC example</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="icon" type="image/x-icon" href="favicon.ico">
+ <link rel="stylesheet" href="assets/css/todomvc-common.css">
+ <link rel="stylesheet" href="assets/css/todomvc-app.css">
+</head>
+<body>
+ <app-root>Loading...</app-root>
+ <!-- Credits: Addy Osmani -->
+</body>
+</html>
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/main.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/main.ts
new file mode 100644
index 0000000000..a9ca1caf8c
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/main.ts
@@ -0,0 +1,11 @@
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/polyfills.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/polyfills.ts
new file mode 100644
index 0000000000..53bdaf1b86
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/polyfills.ts
@@ -0,0 +1,68 @@
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ * file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/** IE9, IE10 and IE11 requires all of the following polyfills. **/
+// import 'core-js/es6/symbol';
+// import 'core-js/es6/object';
+// import 'core-js/es6/function';
+// import 'core-js/es6/parse-int';
+// import 'core-js/es6/parse-float';
+// import 'core-js/es6/number';
+// import 'core-js/es6/math';
+// import 'core-js/es6/string';
+// import 'core-js/es6/date';
+// import 'core-js/es6/array';
+// import 'core-js/es6/regexp';
+// import 'core-js/es6/map';
+// import 'core-js/es6/set';
+
+/** IE10 and IE11 requires the following for NgClass support on SVG elements */
+// import 'classlist.js'; // Run `npm install --save classlist.js`.
+
+/** IE10 and IE11 requires the following to support `@angular/animation`. */
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+
+/** Evergreen browsers require these. **/
+import 'core-js/es6/reflect';
+import 'core-js/es7/reflect';
+
+
+/** ALL Firefox browsers require the following to support `@angular/animation`. **/
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+
+
+/***************************************************************************************************
+ * Zone JS is required by Angular itself.
+ */
+import 'zone.js/dist/zone'; // Included with Angular CLI.
+
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
+
+/**
+ * Date, currency, decimal and percent pipes.
+ * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
+ */
+// import 'intl'; // Run `npm install --save intl`.
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/styles.css b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/styles.css
new file mode 100644
index 0000000000..90d4ee0072
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/styles.css
@@ -0,0 +1 @@
+/* You can add global styles to this file, and also import other style files */
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/test.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/test.ts
new file mode 100644
index 0000000000..9bf72267e9
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/test.ts
@@ -0,0 +1,32 @@
+// This file is required by karma.conf.js and loads recursively all the .spec and framework files
+
+import 'zone.js/dist/long-stack-trace-zone';
+import 'zone.js/dist/proxy.js';
+import 'zone.js/dist/sync-test';
+import 'zone.js/dist/jasmine-patch';
+import 'zone.js/dist/async-test';
+import 'zone.js/dist/fake-async-test';
+import { getTestBed } from '@angular/core/testing';
+import {
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
+declare var __karma__: any;
+declare var require: any;
+
+// Prevent Karma from running prematurely.
+__karma__.loaded = function () {};
+
+// First, initialize the Angular testing environment.
+getTestBed().initTestEnvironment(
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting()
+);
+// Then we find all the tests.
+const context = require.context('./', true, /\.spec\.ts$/);
+// And load the modules.
+context.keys().map(context);
+// Finally, start Karma to run the tests.
+__karma__.start();
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json
new file mode 100644
index 0000000000..5e2507db58
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.app.json
@@ -0,0 +1,13 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/app",
+ "module": "es2015",
+ "baseUrl": "",
+ "types": []
+ },
+ "exclude": [
+ "test.ts",
+ "**/*.spec.ts"
+ ]
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json
new file mode 100644
index 0000000000..510e3f1fda
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/tsconfig.spec.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/spec",
+ "module": "commonjs",
+ "target": "es5",
+ "baseUrl": "",
+ "types": [
+ "jasmine",
+ "node"
+ ]
+ },
+ "files": [
+ "test.ts"
+ ],
+ "include": [
+ "**/*.spec.ts",
+ "**/*.d.ts"
+ ]
+}
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/typings.d.ts b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/typings.d.ts
new file mode 100644
index 0000000000..ef5c7bd620
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/angular/src/typings.d.ts
@@ -0,0 +1,5 @@
+/* SystemJS module definition */
+declare var module: NodeModule;
+interface NodeModule {
+ id: string;
+}