refactor(playground): make playground great again

This commit is contained in:
Joao Dias
2016-10-23 16:21:18 +02:00
committed by Victor Berchet
parent 69f87ca075
commit 3d9d839c6c
28 changed files with 212 additions and 382 deletions

View File

@ -6,7 +6,9 @@
* found in the LICENSE file at https://angular.io/license
*/
declare module 'B64' {
export function fromByteArray(arr: Uint8Array): string;
export function toByteArray(str: string): Uint8Array;
}
declare namespace base64js {
function fromByteArray(arr: Uint8Array): string;
function toByteArray(str: string): Uint8Array;
}
export = base64js;

View File

@ -1,16 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
declare class Bitmap {
constructor(width: number, height: number);
subsample(n: number): void;
dataURL(): string;
pixel: [any];
}

View File

@ -1,127 +0,0 @@
/*
Copyright 2011 Andrey Zholos
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
function Bitmap(width, height) {
this.width = width;
this.height = height;
this.pixel = new Array(width);
for (var x = 0; x < width; x++) {
this.pixel[x] = new Array(height);
for (var y = 0; y < height; y++) this.pixel[x][y] = [0, 0, 0, 0];
}
}
Bitmap.prototype.subsample =
function(n) {
var width = ~~(this.width / n);
var height = ~~(this.height / n);
var pixel = new Array(width);
for (var x = 0; x < width; x++) {
pixel[x] = new Array(height);
for (var y = 0; y < height; y++) {
var q = [0, 0, 0, 0];
for (var i = 0; i < n; i++)
for (var j = 0; j < n; j++) {
var r = this.pixel[x * n + i][y * n + j];
q[0] += r[3] * r[0];
q[1] += r[3] * r[1];
q[2] += r[3] * r[2];
q[3] += r[3];
}
if (q[3]) {
q[0] /= q[3];
q[1] /= q[3];
q[2] /= q[3];
q[3] /= n * n;
}
pixel[x][y] = q;
}
}
this.width = width;
this.height = height;
this.pixel = pixel;
}
Bitmap.prototype.dataURL = function() {
function sample(v) { return ~~(Math.max(0, Math.min(1, v)) * 255); }
function gamma(v) { return sample(Math.pow(v, .45455)); }
function row(pixel, width, y) {
var data = '\0';
for (var x = 0; x < width; x++) {
var r = pixel[x][y];
data += String.fromCharCode(gamma(r[0]), gamma(r[1]), gamma(r[2]), sample(r[3]));
}
return data;
}
function rows(pixel, width, height) {
var data = '';
for (var y = 0; y < height; y++) data += row(pixel, width, y);
return data;
}
function adler(data) {
var s1 = 1, s2 = 0;
for (var i = 0; i < data.length; i++) {
s1 = (s1 + data.charCodeAt(i)) % 65521;
s2 = (s2 + s1) % 65521;
}
return s2 << 16 | s1;
}
function hton(i) { return String.fromCharCode(i >>> 24, i >>> 16 & 255, i >>> 8 & 255, i & 255); }
function deflate(data) {
var len = data.length;
return '\170\1\1' + String.fromCharCode(len & 255, len >>> 8, ~len & 255, (~len >>> 8) & 255) +
data + hton(adler(data));
}
function crc32(data) {
var c = ~0;
for (var i = 0; i < data.length; i++)
for (var b = data.charCodeAt(i) | 0x100; b != 1; b >>>= 1)
c = (c >>> 1) ^ ((c ^ b) & 1 ? 0xedb88320 : 0);
return ~c;
}
function chunk(type, data) { return hton(data.length) + type + data + hton(crc32(type + data)); }
function base64(data) {
enc = '';
for (var i = 5, n = data.length * 8 + 5; i < n; i += 6)
enc += 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
[(data.charCodeAt(~~(i / 8) - 1) << 8 | data.charCodeAt(~~(i / 8))) >> 7 - i % 8 & 63];
for (; enc.length % 4; enc += '=')
;
return enc;
}
var png = '\211PNG\r\n\32\n' +
chunk('IHDR', hton(this.width) + hton(this.height) + '\10\6\0\0\0') +
chunk('IDAT', deflate(rows(this.pixel, this.width, this.height))) + chunk('IEND', '');
return 'data:image/png;base64,' + base64(png);
}

View File

@ -1,14 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
var _FileReader = FileReader;
export {_FileReader as FileReader};
export class Uint8ArrayWrapper {
static create(buffer: ArrayBuffer) { return new Uint8Array(buffer); }
}

View File

@ -8,20 +8,19 @@
import {Component} from '@angular/core';
import {FileReader, Uint8ArrayWrapper} from './file_api';
import {BitmapService} from './services/bitmap';
@Component({selector: 'image-demo', viewProviders: [BitmapService], templateUrl: 'image_demo.html'})
export class ImageDemo {
images: any[] /** TODO #9100 */ = [];
images: {src: string, buffer: ArrayBuffer, filtering: boolean}[] = [];
fileInput: String;
constructor(private _bitmapService: BitmapService) {}
uploadFiles(files: any /** TODO #9100 */) {
for (var i = 0; i < files.length; i++) {
var reader = new FileReader();
uploadFiles(files: FileList) {
for (let i = 0; i < files.length; i++) {
const reader = new FileReader();
reader.addEventListener('load', this.handleReaderLoad(reader));
reader.readAsArrayBuffer(files[i]);
}
@ -29,9 +28,9 @@ export class ImageDemo {
handleReaderLoad(reader: FileReader): EventListener {
return (e) => {
var buffer = reader.result;
const buffer = reader.result as ArrayBuffer;
this.images.push({
src: this._bitmapService.arrayBufferToDataUri(Uint8ArrayWrapper.create(reader.result)),
src: this._bitmapService.arrayBufferToDataUri(new Uint8Array(buffer)),
buffer: buffer,
filtering: false
});
@ -39,16 +38,16 @@ export class ImageDemo {
}
applyFilters() {
for (var i = 0; i < this.images.length; i++) {
for (let i = 0; i < this.images.length; i++) {
this.images[i].filtering = true;
setTimeout(this._filter(i), 0);
}
}
private _filter(i: number): (...args: any[]) => void {
private _filter(i: number): () => void {
return () => {
var imageData = this._bitmapService.convertToImageData(this.images[i].buffer);
let imageData = this._bitmapService.convertToImageData(this.images[i].buffer);
imageData = this._bitmapService.applySepia(imageData);
this.images[i].src = this._bitmapService.toDataUri(imageData);
this.images[i].filtering = false;

View File

@ -22,6 +22,7 @@ System.config({
'@angular/compiler': {main: 'index.js', defaultExtension: 'js'},
'@angular/common': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-webworker': {main: 'index.js', defaultExtension: 'js'},
'@angular/platform-webworker-dynamic': {main: 'index.js', defaultExtension: 'js'},
'@angular/router': {main: 'index.js', defaultExtension: 'js'},

View File

@ -6,31 +6,25 @@
* found in the LICENSE file at https://angular.io/license
*/
/// <reference path="../bitmap.d.ts" /> /// <reference path="../b64.d.ts" />
import {Injectable} from '@angular/core';
declare var base64js: any /** TODO #9100 */;
// Temporary fix for Typescript issue #4220 (https://github.com/Microsoft/TypeScript/issues/4220)
// var _ImageData: (width: number, height: number) => void = <any>postMessage;
var _ImageData: {prototype: ImageData, new (width: number, height: number): ImageData;} = ImageData;
import * as base64js from '../b64';
// This class is based on the Bitmap examples at:
// http://www.i-programmer.info/projects/36-web/6234-reading-a-bmp-file-in-javascript.html
// and
// http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
// and http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
@Injectable()
export class BitmapService {
convertToImageData(buffer: ArrayBuffer): ImageData {
var bmp = this._getBMP(buffer);
const bmp = this._getBMP(buffer);
return this._BMPToImageData(bmp);
}
applySepia(imageData: ImageData): ImageData {
var buffer = imageData.data;
for (var i = 0; i < buffer.length; i += 4) {
var r = buffer[i];
var g = buffer[i + 1];
var b = buffer[i + 2];
const buffer = imageData.data;
for (let i = 0; i < buffer.length; i += 4) {
const r = buffer[i];
const g = buffer[i + 1];
const b = buffer[i + 2];
buffer[i] = (r * .393) + (g * .769) + (b * .189);
buffer[i + 1] = (r * .349) + (g * .686) + (b * .168);
buffer[i + 2] = (r * .272) + (g * .534) + (b * .131);
@ -39,7 +33,7 @@ export class BitmapService {
}
toDataUri(imageData: ImageData): string {
var header = this._createBMPHeader(imageData);
const header = this._createBMPHeader(imageData);
imageData = this._imageDataToBMP(imageData);
return 'data:image/bmp;base64,' + btoa(header) + base64js.fromByteArray(imageData.data);
}
@ -51,14 +45,14 @@ export class BitmapService {
// returns a UInt8Array in BMP order (starting from the bottom)
private _imageDataToBMP(imageData: ImageData): ImageData {
var width = imageData.width;
var height = imageData.height;
const width = imageData.width;
const height = imageData.height;
var data = imageData.data;
for (var y = 0; y < height / 2; ++y) {
var topIndex = y * width * 4;
var bottomIndex = (height - y) * width * 4;
for (var i = 0; i < width * 4; i++) {
const data = imageData.data;
for (let y = 0; y < height / 2; ++y) {
let topIndex = y * width * 4;
let bottomIndex = (height - y) * width * 4;
for (let i = 0; i < width * 4; i++) {
this._swap(data, topIndex, bottomIndex);
topIndex++;
bottomIndex++;
@ -69,7 +63,7 @@ export class BitmapService {
}
private _swap(data: Uint8Array|Uint8ClampedArray|number[], index1: number, index2: number) {
var temp = data[index1];
const temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}
@ -77,9 +71,9 @@ export class BitmapService {
// Based on example from
// http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
private _createBMPHeader(imageData: ImageData): string {
var numFileBytes = this._getLittleEndianHex(imageData.width * imageData.height);
var w = this._getLittleEndianHex(imageData.width);
var h = this._getLittleEndianHex(imageData.height);
const numFileBytes = this._getLittleEndianHex(imageData.width * imageData.height);
const w = this._getLittleEndianHex(imageData.width);
const h = this._getLittleEndianHex(imageData.height);
return 'BM' + // Signature
numFileBytes + // size of the file (bytes)*
'\x00\x00' + // reserved
@ -99,18 +93,18 @@ export class BitmapService {
}
private _BMPToImageData(bmp: BitmapFile): ImageData {
var width = bmp.infoHeader.biWidth;
var height = bmp.infoHeader.biHeight;
var imageData = new _ImageData(width, height);
const width = bmp.infoHeader.biWidth;
const height = bmp.infoHeader.biHeight;
const imageData = new ImageData(width, height);
var data = imageData.data;
var bmpData = bmp.pixels;
var stride = bmp.stride;
const data = imageData.data;
const bmpData = bmp.pixels;
const stride = bmp.stride;
for (var y = 0; y < height; ++y) {
for (var x = 0; x < width; ++x) {
var index1 = (x + width * (height - y)) * 4;
var index2 = x * 3 + stride * y;
for (let y = 0; y < height; ++y) {
for (let x = 0; x < width; ++x) {
const index1 = (x + width * (height - y)) * 4;
const index2 = x * 3 + stride * y;
data[index1] = bmpData[index2 + 2];
data[index1 + 1] = bmpData[index2 + 1];
data[index1 + 2] = bmpData[index2];
@ -121,8 +115,8 @@ export class BitmapService {
}
private _getBMP(buffer: ArrayBuffer): BitmapFile {
var datav = new DataView(buffer);
var bitmap: BitmapFile = {
const datav = new DataView(buffer);
const bitmap: BitmapFile = {
fileHeader: {
bfType: datav.getUint16(0, true),
bfSize: datav.getUint32(2, true),
@ -146,7 +140,7 @@ export class BitmapService {
stride: null,
pixels: null
};
var start = bitmap.fileHeader.bfOffBits;
const start = bitmap.fileHeader.bfOffBits;
bitmap.stride =
Math.floor((bitmap.infoHeader.biBitCount * bitmap.infoHeader.biWidth + 31) / 32) * 4;
bitmap.pixels = new Uint8Array(datav.buffer, start);
@ -156,9 +150,9 @@ export class BitmapService {
// Based on example from
// http://www.worldwidewhat.net/2012/07/how-to-draw-bitmaps-using-javascript/
private _getLittleEndianHex(value: number): string {
var result: any[] /** TODO #9100 */ = [];
const result: string[] = [];
for (var bytes = 4; bytes > 0; bytes--) {
for (let bytes = 4; bytes > 0; bytes--) {
result.push(String.fromCharCode(value & 255));
value >>= 8;
}

View File

@ -26,7 +26,7 @@ export class InputCmp {
inputVal = '';
textareaVal = '';
inputChanged(e: any /** TODO #9100 */) { this.inputVal = e.target.value; }
inputChanged(e: Event) { this.inputVal = (e.target as HTMLInputElement).value; }
textAreaChanged(e: any /** TODO #9100 */) { this.textareaVal = e.target.value; }
textAreaChanged(e: Event) { this.textareaVal = (e.target as HTMLTextAreaElement).value; }
}

View File

@ -23,7 +23,6 @@ export class RedDec {
constructor(el: ElementRef, renderer: Renderer) {
renderer.setElementStyle(el.nativeElement, 'color', 'red');
}
// constructor(renderer: Renderer) {}
}
// Angular 2.0 supports 2 basic types of directives:
@ -54,7 +53,5 @@ export class HelloCmp {
changeGreeting(): void { this.greeting = 'howdy'; }
onKeyDown(event: any /** TODO #9100 */): void {
this.lastKey = String.fromCharCode(event.keyCode);
}
onKeyDown(event: KeyboardEvent): void { this.lastKey = String.fromCharCode(event.keyCode); }
}

View File

@ -18,15 +18,15 @@ export class TodoApp {
hideCompleted: boolean = false;
isComplete: boolean = false;
constructor(public todoStore: Store, public factory: TodoFactory) {}
constructor(public todoStore: Store<Todo>, public factory: TodoFactory) {}
enterTodo(): void {
this.addTodo(this.inputValue);
this.inputValue = '';
}
doneEditing($event: any /** TODO #9100 */, todo: Todo): void {
var which = $event.keyCode;
doneEditing($event: KeyboardEvent, todo: Todo): void {
const which = $event.keyCode;
if (which === 13) {
todo.title = todo.editTitle;
this.todoEdit = null;
@ -59,7 +59,7 @@ export class TodoApp {
deleteMe(todo: Todo): void { this.todoStore.remove(todo); }
toggleAll($event: any /** TODO #9100 */): void {
toggleAll($event: MouseEvent): void {
this.isComplete = !this.isComplete;
this.todoStore.list.forEach((todo: Todo) => { todo.completed = this.isComplete; });
}

View File

@ -7,7 +7,6 @@
*/
import {Injectable} from '@angular/core';
import {ListWrapper, Predicate} from '@angular/core/src/facade/collection';
// base model for RecordStore
export class KeyModel {
@ -35,25 +34,14 @@ export class TodoFactory {
// Store manages any generic item that inherits from KeyModel
@Injectable()
export class Store {
list: KeyModel[] = [];
export class Store<T extends KeyModel> {
list: T[] = [];
add(record: KeyModel): void { this.list.push(record); }
add(record: T): void { this.list.push(record); }
remove(record: KeyModel): void { this._spliceOut(record); }
remove(record: T): void { this.removeBy((item) => item === record); }
removeBy(callback: Predicate<KeyModel>): void {
var records = this.list.filter(callback);
ListWrapper.removeAll(this.list, records);
removeBy(callback: (record: T) => boolean): void {
this.list = this.list.filter((record) => !callback(record));
}
private _spliceOut(record: KeyModel) {
var i = this._indexFor(record);
if (i > -1) {
return this.list.splice(i, 1)[0];
}
return null;
}
private _indexFor(record: KeyModel) { return this.list.indexOf(record); }
}