Add snapshot of release-1.0.3 sources
@@ -0,0 +1,10 @@
|
||||
===== TypeScript Sample: AMD Module =====
|
||||
|
||||
=== Overview ===
|
||||
This sample shows a simple Typescript application using an AMD module.
|
||||
|
||||
=== Running ===
|
||||
tsc --module amd app.ts
|
||||
start default.htm
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
body
|
||||
{
|
||||
font-family: 'Segoe UI', sans-serif
|
||||
}
|
||||
|
||||
span {
|
||||
font-style: italic
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import model = require("greeter")
|
||||
|
||||
var el = document.getElementById('content');
|
||||
var greeter = new model.Greeter(el);
|
||||
greeter.start();
|
||||
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>TypeScript HTML App</title>
|
||||
<link rel="stylesheet" href="app.css" type="text/css" />
|
||||
<script data-main="app" type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.1/require.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>TypeScript HTML App</h1>
|
||||
|
||||
<div id="content"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
export class Greeter
|
||||
{
|
||||
element: HTMLElement;
|
||||
span: HTMLElement;
|
||||
timerToken: number;
|
||||
|
||||
constructor (element: HTMLElement)
|
||||
{
|
||||
this.element = element;
|
||||
this.element.innerText += "The time is: ";
|
||||
this.span = document.createElement('span');
|
||||
this.element.appendChild(this.span);
|
||||
this.span.innerText = new Date().toUTCString();
|
||||
}
|
||||
|
||||
start()
|
||||
{
|
||||
this.timerToken = setInterval(() => this.span.innerText = new Date().toUTCString(), 500);
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
clearTimeout(this.timerToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
===== TypeScript Sample: D3 =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
D3 visualization
|
||||
- Use of the D3 wrapper
|
||||
- Use of modules and interfaces
|
||||
|
||||
=== Running ===
|
||||
tsc data.ts
|
||||
start perf.html
|
||||
@@ -0,0 +1,277 @@
|
||||
interface ID3Selectors {
|
||||
select: (selector: string) => ID3Selection;
|
||||
selectAll: (selector: string) => ID3Selection;
|
||||
}
|
||||
|
||||
interface ID3Base extends ID3Selectors {
|
||||
// Array Helpers
|
||||
ascending: (a: number, b: number) => number;
|
||||
descending: (a: number, b: number) => number;
|
||||
min<T, U>(arr: T[], map: (v: T) => U ): U;
|
||||
min<T>(arr: T[]): T;
|
||||
max<T, U>(arr: T[], map: (v: T) => U ): U;
|
||||
max<T>(arr: T[]): T;
|
||||
extent<T, U>(arr: T[], map: (v: T) => U): U[];
|
||||
extent<T>(arr: T[]): T[];
|
||||
quantile: (arr: number[], p: number) => number;
|
||||
bisectLeft<T>(arr: T[], x: T, low?: number, high?: number): number;
|
||||
bisect<T>(arr: T[], x: T, low?: number, high?: number): number;
|
||||
bisectRight<T>(arr: T[], x: T, low?: number, high?: number): number;
|
||||
|
||||
// Loading resources
|
||||
xhr: {
|
||||
(url: string, callback: (xhr: XMLHttpRequest) => void): void;
|
||||
(url: string, mime: string, callback: (xhr: XMLHttpRequest) => void): void;
|
||||
};
|
||||
text: {
|
||||
(url: string, callback: (response: string) => void): void;
|
||||
(url: string, mime: string, callback: (response: string) => void): void;
|
||||
};
|
||||
json: (url: string, callback: (response: any) => void) => void;
|
||||
xml: {
|
||||
(url: string, callback: (response: Document) => void): void;
|
||||
(url: string, mime: string, callback: (response: Document) => void): void;
|
||||
};
|
||||
html: (url: string, callback: (response: DocumentFragment) => void) => void;
|
||||
csv: {
|
||||
(url: string, callback: (response: any[]) => void);
|
||||
parse(string: string): any[];
|
||||
parseRows(string: string, accessor: (row: any[], index: number) => any): any;
|
||||
format(rows: any[]): string;
|
||||
};
|
||||
|
||||
time: ID3Time;
|
||||
scale: {
|
||||
linear(): ID3LinearScale;
|
||||
};
|
||||
interpolate: ID3BaseInterpolate;
|
||||
interpolateNumber: ID3BaseInterpolate;
|
||||
interpolateRound: ID3BaseInterpolate;
|
||||
interpolateString: ID3BaseInterpolate;
|
||||
interpolateRgb: ID3BaseInterpolate;
|
||||
interpolateHsl: ID3BaseInterpolate;
|
||||
interpolateArray: ID3BaseInterpolate;
|
||||
interpolateObject: ID3BaseInterpolate;
|
||||
interpolateTransform: ID3BaseInterpolate;
|
||||
layout: ID3Layout;
|
||||
svg: ID3Svg;
|
||||
random: ID3Random;
|
||||
}
|
||||
|
||||
interface ID3Selection extends ID3Selectors {
|
||||
attr: {
|
||||
(name: string): string;
|
||||
(name: string, value: any): ID3Selection;
|
||||
(name: string, valueFunction: (data: any, index: number) => any): ID3Selection;
|
||||
};
|
||||
|
||||
classed: {
|
||||
(name: string): string;
|
||||
(name: string, value: any): ID3Selection;
|
||||
(name: string, valueFunction: (data: any, index: number) => any): ID3Selection;
|
||||
};
|
||||
|
||||
style: {
|
||||
(name: string): string;
|
||||
(name: string, value: any, priority?: string): ID3Selection;
|
||||
(name: string, valueFunction: (data: any, index: number) => any, priority?: string): ID3Selection;
|
||||
};
|
||||
|
||||
property: {
|
||||
(name: string): void;
|
||||
(name: string, value: any): ID3Selection;
|
||||
(name: string, valueFunction: (data: any, index: number) => any): ID3Selection;
|
||||
};
|
||||
|
||||
text: {
|
||||
(): string;
|
||||
(value: any): ID3Selection;
|
||||
(valueFunction: (data: any, index: number) => any): ID3Selection;
|
||||
};
|
||||
|
||||
html: {
|
||||
(): string;
|
||||
(value: any): ID3Selection;
|
||||
(valueFunction: (data: any, index: number) => any): ID3Selection;
|
||||
};
|
||||
|
||||
append: (name: string) => ID3Selection;
|
||||
insert: (name: string, before: string) => ID3Selection;
|
||||
remove: () => ID3Selection;
|
||||
|
||||
data: {
|
||||
(values: (data: any, index: number) => any) : any;
|
||||
(values: any[], key?: (data: any, index: number) => any): ID3UpdateSelection;
|
||||
};
|
||||
|
||||
call(callback: (selection: ID3Selection) => void): ID3Selection;
|
||||
}
|
||||
|
||||
interface ID3EnterSelection {
|
||||
append: (name: string) => ID3Selection;
|
||||
insert: (name: string, before: string) => ID3Selection;
|
||||
select: (selector: string) => ID3Selection;
|
||||
empty: () => boolean;
|
||||
node: () => Node;
|
||||
}
|
||||
|
||||
interface ID3UpdateSelection extends ID3Selection {
|
||||
enter: () => ID3EnterSelection;
|
||||
update: () => ID3Selection;
|
||||
exit: () => ID3Selection;
|
||||
}
|
||||
|
||||
interface ID3Time {
|
||||
second: ID3Interval;
|
||||
minute: ID3Interval;
|
||||
hour: ID3Interval;
|
||||
day: ID3Interval;
|
||||
week: ID3Interval;
|
||||
sunday: ID3Interval;
|
||||
monday: ID3Interval;
|
||||
tuesday: ID3Interval;
|
||||
wednesday: ID3Interval;
|
||||
thursday: ID3Interval;
|
||||
friday: ID3Interval;
|
||||
saturday: ID3Interval;
|
||||
month: ID3Interval;
|
||||
year: ID3Interval;
|
||||
|
||||
seconds: ID3Range;
|
||||
minutes: ID3Range;
|
||||
hours: ID3Range;
|
||||
days: ID3Range;
|
||||
weeks: ID3Range;
|
||||
months: ID3Range;
|
||||
years: ID3Range;
|
||||
|
||||
sundays: ID3Range;
|
||||
mondays: ID3Range;
|
||||
tuesdays: ID3Range;
|
||||
wednesdays: ID3Range;
|
||||
thursdays: ID3Range;
|
||||
fridays: ID3Range;
|
||||
saturdays: ID3Range;
|
||||
format: {
|
||||
|
||||
(specifier: string): ID3TimeFormat;
|
||||
utc: (specifier: string) => ID3TimeFormat;
|
||||
iso: ID3TimeFormat;
|
||||
};
|
||||
|
||||
scale(): ID3TimeScale;
|
||||
}
|
||||
|
||||
interface ID3Range {
|
||||
(start: Date, end: Date, step?: number): Date[];
|
||||
}
|
||||
|
||||
interface ID3Interval {
|
||||
(date: Date): Date;
|
||||
floor: (date: Date) => Date;
|
||||
round: (date: Date) => Date;
|
||||
ceil: (date: Date) => Date;
|
||||
range: ID3Range;
|
||||
offset: (date: Date, step: number) => Date;
|
||||
utc: ID3Interval;
|
||||
}
|
||||
|
||||
interface ID3TimeFormat {
|
||||
(date: Date): string;
|
||||
parse: (string: string) => Date;
|
||||
}
|
||||
|
||||
interface ID3LinearScale {
|
||||
(value: number): number;
|
||||
invert(value: number): number;
|
||||
domain(numbers: any[]): ID3LinearScale;
|
||||
range: {
|
||||
(values: any[]): ID3LinearScale;
|
||||
(): any[];
|
||||
};
|
||||
rangeRound: (values: any[]) => ID3LinearScale;
|
||||
interpolate: {
|
||||
(): ID3Interpolate;
|
||||
(factory: ID3Interpolate): ID3LinearScale;
|
||||
};
|
||||
clamp(clamp: boolean): ID3LinearScale;
|
||||
nice(): ID3LinearScale;
|
||||
ticks(count: number): any[];
|
||||
tickFormat(count: number): (n: number) => string;
|
||||
copy: ID3LinearScale;
|
||||
}
|
||||
|
||||
interface ID3TimeScale {
|
||||
(value: Date): number;
|
||||
invert(value: number): Date;
|
||||
domain(numbers: any[]): ID3TimeScale;
|
||||
range: {
|
||||
(values: any[]): ID3TimeScale;
|
||||
(): any[];
|
||||
};
|
||||
rangeRound: (values: any[]) => ID3TimeScale;
|
||||
interpolate: {
|
||||
(): ID3Interpolate;
|
||||
(factory: ID3InterpolateFactory): ID3TimeScale;
|
||||
};
|
||||
clamp(clamp: boolean): ID3TimeScale;
|
||||
ticks: {
|
||||
(count: number): any[];
|
||||
(range: ID3Range, count: number): any[];
|
||||
};
|
||||
tickFormat(count: number): (n: number) => string;
|
||||
copy(): ID3TimeScale;
|
||||
}
|
||||
|
||||
interface ID3InterpolateFactory {
|
||||
(a: any, b: any): ID3BaseInterpolate;
|
||||
}
|
||||
interface ID3BaseInterpolate {
|
||||
(a: any, b: any): ID3Interpolate;
|
||||
}
|
||||
|
||||
interface ID3Interpolate {
|
||||
(t: number): number;
|
||||
}
|
||||
|
||||
interface ID3Layout {
|
||||
stack(): ID3StackLayout;
|
||||
}
|
||||
|
||||
interface ID3StackLayout {
|
||||
(layers: any[], index?: number): any[];
|
||||
values(accessor?: (d: any) => any): ID3StackLayout;
|
||||
offset(offset: string): ID3StackLayout;
|
||||
}
|
||||
|
||||
interface ID3Svg {
|
||||
axis(): ID3SvgAxis;
|
||||
}
|
||||
|
||||
interface ID3SvgAxis {
|
||||
(selection: ID3Selection): void;
|
||||
scale: {
|
||||
(): any;
|
||||
(scale: any): ID3SvgAxis;
|
||||
};
|
||||
|
||||
orient: {
|
||||
(): string;
|
||||
(orientation: string): ID3SvgAxis;
|
||||
};
|
||||
|
||||
ticks: {
|
||||
(count: number): ID3SvgAxis;
|
||||
(range: ID3Range, count?: number): ID3SvgAxis;
|
||||
};
|
||||
|
||||
tickSubdivide(count: number): ID3SvgAxis;
|
||||
tickSize(major?: number, minor?: number, end?: number): ID3SvgAxis;
|
||||
tickFormat(formatter: (value: any) => string): ID3SvgAxis;
|
||||
}
|
||||
|
||||
interface ID3Random {
|
||||
normal(mean?: number, deviation?: number): () => number;
|
||||
}
|
||||
|
||||
declare var d3: ID3Base;
|
||||
@@ -0,0 +1,282 @@
|
||||
///<reference path="d3.d.ts" />
|
||||
"use strict";
|
||||
|
||||
interface IDataSeries {
|
||||
desc: string;
|
||||
data: IRun[];
|
||||
}
|
||||
|
||||
interface IRun {
|
||||
date: Date;
|
||||
pass: boolean;
|
||||
}
|
||||
|
||||
interface IPerfDataSeries {
|
||||
desc: string;
|
||||
data: IPerfRun[];
|
||||
}
|
||||
|
||||
interface IPerfRun {
|
||||
x: Date;
|
||||
y: number;
|
||||
}
|
||||
|
||||
module Chart {
|
||||
|
||||
export class Base {
|
||||
public iso8601 = d3.time.format('%Y-%m-%d');
|
||||
public chartWidth = 800;
|
||||
|
||||
constructor (public element) { }
|
||||
}
|
||||
|
||||
export class Bar extends Base {
|
||||
public element: ID3Selection;
|
||||
constructor(element: ID3Selection) {
|
||||
super(element);
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public chartHeight = 400;
|
||||
public chartWidth = 800;
|
||||
public legendItemHeight = 30;
|
||||
public legendWidth = 150;
|
||||
public colors = ['rgb(0, 113, 188)', 'rgb(0, 174, 239)', 'rgb(145, 0, 145)'];
|
||||
public xAxisHashHeight = 10;
|
||||
public layout = 'wiggle';
|
||||
|
||||
|
||||
public render(data: IPerfDataSeries[]) {
|
||||
|
||||
// Create stack layout
|
||||
var stackLayout = d3.layout.stack()
|
||||
.values(function(d) { return d.data })
|
||||
.offset(this.layout);
|
||||
|
||||
var stackData = stackLayout(data);
|
||||
|
||||
// Maximum measurement in the dataset
|
||||
var maxY = d3.max(stackData, (d) => d3.max<any, any>(d.data, (d) => d.y0 + d.y));
|
||||
|
||||
// Earliest day in the dataset
|
||||
var minX = d3.min(data, (d) => d3.min(d.data, (d) => d.x));
|
||||
|
||||
// All days in the dataset (from earliest day until now)
|
||||
var days = d3.time.days(minX, new Date());
|
||||
|
||||
// Area of the region containing the bars
|
||||
var areaWidth = this.chartWidth - this.legendWidth;
|
||||
|
||||
var barWidth = areaWidth / days.length;
|
||||
|
||||
// Create scales for X and Y axis (X based on dates, Y based on performance data)
|
||||
var x = d3.time.scale()
|
||||
.domain([minX, d3.time.day(d3.time.day.offset(new Date(), 1))])
|
||||
.range([0, this.chartWidth - this.legendWidth]);
|
||||
var y = d3.scale.linear()
|
||||
.domain([0, maxY])
|
||||
.range([0, this.chartHeight]);
|
||||
var ticks = x.ticks(d3.time.mondays, 1);
|
||||
|
||||
// SVG element
|
||||
var svg = this.element.append('svg')
|
||||
.attr('height', this.chartHeight + 25)
|
||||
.attr('width', this.chartWidth);
|
||||
|
||||
// Groups that contain bar segments for each dataset
|
||||
var barGroups = svg.selectAll('g.bars')
|
||||
.data(stackData)
|
||||
.enter().append('g')
|
||||
.attr('class', 'bars')
|
||||
.style('fill', (d, i) => this.colors[<number>i])
|
||||
.attr('transform', 'translate(' + this.legendWidth + ', 0)');
|
||||
|
||||
// Legend
|
||||
var legendGroup = svg.append('g')
|
||||
.attr('class', 'legend')
|
||||
|
||||
// Legend items
|
||||
var legendItem = legendGroup.selectAll('g.legendItem')
|
||||
.data(stackData)
|
||||
.enter().append('g')
|
||||
.attr('class', 'legendItem')
|
||||
.style('fill', (d, i) => this.colors[<number>i])
|
||||
.attr('transform', (d, i) => 'translate(0, ' + (this.legendItemHeight * (2 - i)) + ')');
|
||||
|
||||
legendItem.append('rect')
|
||||
.attr('width', 25)
|
||||
.attr('height', 25);
|
||||
|
||||
legendItem.append('text')
|
||||
.text((d) => d.desc)
|
||||
.attr('x', 30)
|
||||
.attr('dy', '1em');
|
||||
|
||||
|
||||
// Bars
|
||||
var rects = barGroups.selectAll('rect')
|
||||
.data((d) => d.data)
|
||||
.enter()
|
||||
.append('rect')
|
||||
.attr('x', (d, i) => x(d.x))
|
||||
.attr('y', (d, i) => this.chartHeight - y(d.y + d.y0))
|
||||
.attr('width', barWidth)
|
||||
.attr('height', (d, i) => y(d.y));
|
||||
|
||||
// Add title (mouseover popup) to bars
|
||||
rects.append('title')
|
||||
.text((d) => this.iso8601(d.x) + ' - ' + d.y + 'ms');
|
||||
|
||||
|
||||
// Add an axis marker to the bottom
|
||||
var axis = d3.svg.axis();
|
||||
axis.scale(x)
|
||||
.ticks(d3.time.mondays, 1)
|
||||
.tickSubdivide(6)
|
||||
.tickFormat(this.iso8601)
|
||||
.tickSize(10, 5, 0);
|
||||
|
||||
var axisGroup = svg.append('g')
|
||||
.attr('class', 'axis')
|
||||
.attr('transform', 'translate(' + this.legendWidth + ',' + this.chartHeight + ')')
|
||||
.call(axis);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class DailyBuild extends Base {
|
||||
public element: ID3Selection;
|
||||
constructor (element: ID3Selection) {
|
||||
super(element);
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public labelWidth = 140;
|
||||
public labelGutter = 10;
|
||||
public chartWidth = 800;
|
||||
|
||||
private getTextDataString(data) {
|
||||
return data.pass ? 'pass' : 'fail';
|
||||
}
|
||||
|
||||
public render(data: IDataSeries[]) {
|
||||
// Minimum date in the dataset
|
||||
var minDate = d3.min(data.map(function(d) { return d3.time.day(d.data[0].date) }));
|
||||
|
||||
// All the days in the dataset, from min until now.
|
||||
var days = d3.time.days(minDate, new Date());
|
||||
|
||||
var boxSize = (this.chartWidth - this.labelWidth - this.labelGutter) / days.length;
|
||||
|
||||
// Create our scales for x and y axis
|
||||
var x = d3.time.scale()
|
||||
.domain([minDate, d3.time.day(new Date())])
|
||||
.range([0, boxSize * (days.length - 1)]);
|
||||
|
||||
var y = d3.scale.linear()
|
||||
.domain([0, 1])
|
||||
.range([0, boxSize]);
|
||||
|
||||
|
||||
// SVG element
|
||||
var svg = this.element.append('svg')
|
||||
.attr('height', y(data.length + 1))
|
||||
.attr('width', this.chartWidth);
|
||||
|
||||
svg.selectAll('text')
|
||||
.data(data)
|
||||
.enter().append('text')
|
||||
.attr('x', this.labelWidth)
|
||||
.attr('transform', function(d, i) { return 'translate(0,' + y(i) + ')' })
|
||||
.attr('dy', '1em')
|
||||
.attr('text-anchor', 'end')
|
||||
.text(function(d) { return d.desc });
|
||||
|
||||
// Groups of boxes for updated builds
|
||||
var g = svg.selectAll('g.boxes')
|
||||
.data(data)
|
||||
.enter().append('g')
|
||||
.attr('class', 'boxes')
|
||||
.attr('transform', function(d, i) { return 'translate(0,' + y(i) + ')' });
|
||||
|
||||
// Boxes of build info
|
||||
var rects = g.selectAll('rect')
|
||||
.data(function(d, i) { return d.data; })
|
||||
.enter().append('rect')
|
||||
.attr('class', (d) => 'day ' + this.getTextDataString(d))
|
||||
.attr('x', (d, i) => this.labelWidth + this.labelGutter + x(d.date))
|
||||
.attr('width', boxSize)
|
||||
.attr('height', boxSize);
|
||||
|
||||
rects.append('title')
|
||||
.text( (d) => this.iso8601(d.date) + ' - ' + this.getTextDataString(d) );
|
||||
|
||||
var ticks = x.ticks(d3.time.mondays, 1);
|
||||
|
||||
// Date text boxes
|
||||
svg.append('g').attr('class', 'dates').selectAll('text')
|
||||
.data(ticks)
|
||||
.enter().append('text')
|
||||
.text((d) => this.iso8601(d) )
|
||||
.attr('transform', (d, i) => 'translate(' + (this.labelWidth + this.labelGutter + x(d) + 5) + ', ' + y(data.length + 1) + ')')
|
||||
.attr('text-anchor', 'start')
|
||||
|
||||
// Vertical hashes at week boundaries
|
||||
svg.append('g').attr('class', 'hashes').selectAll('line')
|
||||
.data(ticks)
|
||||
.enter().append('line')
|
||||
.attr('x1', (d) => this.labelWidth + this.labelGutter + x(d) )
|
||||
.attr('x2', (d) => this.labelWidth + this.labelGutter + x(d) )
|
||||
.attr('y1', 0)
|
||||
.attr('y2', y(data.length + 1));
|
||||
|
||||
return svg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var start = d3.time.day.offset(new Date(), -30);
|
||||
var end = new Date()
|
||||
var days = d3.time.days(start, end);
|
||||
|
||||
var buildData: IRun[] = days.map(day => ({ date: day, pass: Math.random() > 0.1 }));
|
||||
var compilerTestData: IRun[] = days.map(day => ({ date: day, pass: Math.random() > 0.1 }));
|
||||
var servicesTestData: IRun[] = days.map(day => ({ date: day, pass: Math.random() > 0.1 }));
|
||||
|
||||
function decreasingRandom(start: number, deviation: number, factor: number) {
|
||||
var factorRandom = d3.random.normal(factor, 0.05);
|
||||
|
||||
return function () {
|
||||
var random = d3.random.normal(start, deviation)();
|
||||
start = start * factorRandom();
|
||||
|
||||
return parseFloat(random.toFixed())
|
||||
}
|
||||
}
|
||||
|
||||
var parseRandom = decreasingRandom(400, 20, 0.97);
|
||||
var typecheckRandom = decreasingRandom(500, 20, 0.97);
|
||||
var emitRandom = decreasingRandom(100, 10, 0.97);
|
||||
|
||||
var parseData: IPerfRun[] = days.map(day => ({ x: day, y: parseRandom() }));
|
||||
var typecheckData: IPerfRun[] = days.map(day => ({ x: day, y: typecheckRandom() }));
|
||||
var emitData: IPerfRun[] = days.map(day => ({ x: day, y: emitRandom() }));
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var chart = new Chart.DailyBuild(d3.select('#passchart'));
|
||||
|
||||
chart.render([
|
||||
{ desc: "Build Status", data: buildData },
|
||||
{ desc: "Compiler Tests", data: compilerTestData },
|
||||
{ desc: "Services Tests", data: servicesTestData },
|
||||
]);
|
||||
|
||||
var normalizedData = [
|
||||
{ desc: 'Emit', data: emitData },
|
||||
{ desc: 'Typecheck', data: typecheckData },
|
||||
{ desc: 'Parse', data: parseData }
|
||||
]
|
||||
|
||||
var perfchart = new Chart.Bar(d3.select('#performanceChart'));
|
||||
perfchart.render(normalizedData);
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="http://d3js.org/d3.v2.js"></script>
|
||||
<script src="data.js"></script>
|
||||
<style>
|
||||
svg {
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
.day {
|
||||
stroke: #ccc;
|
||||
}
|
||||
|
||||
.pass {
|
||||
fill: rgb(0, 166, 0);
|
||||
}
|
||||
|
||||
.fail {
|
||||
fill: rgb(255, 83, 0);
|
||||
}
|
||||
|
||||
.hashes line {
|
||||
stroke: #000; stroke-width: 2;
|
||||
}
|
||||
|
||||
.tick {
|
||||
stroke: #000; stroke-width: 2;
|
||||
}
|
||||
|
||||
.axis path {
|
||||
stroke: #000; stroke-width: 2;
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI';
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Status</h1>
|
||||
<div id="passchart"></div>
|
||||
|
||||
<h1>Compiler Performance</h1>
|
||||
<div id="performanceChart"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
===== TypeScript Sample: Greeter =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample shows basic class definition and instantiation.
|
||||
|
||||
=== Running ===
|
||||
tsc greeter.ts
|
||||
start greeter.html
|
||||
@@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title> TypeScript Greeter </title></head>
|
||||
<body>
|
||||
<script src='greeter.js'></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
class Greeter {
|
||||
constructor(public greeting: string) { }
|
||||
greet() {
|
||||
return "<h1>" + this.greeting + "</h1>";
|
||||
}
|
||||
};
|
||||
var greeter = new Greeter("Hello, world!");
|
||||
var str = greeter.greet();
|
||||
document.body.innerHTML = str;
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{BE268EA8-89D1-44DB-839D-FB007556CC97}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<NoStandardLibraries>false</NoStandardLibraries>
|
||||
<AssemblyName>ClassLibrary</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RootNamespace>ImageBoard</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.ts" />
|
||||
<None Include="db.ts" />
|
||||
<None Include="mongodb.ts" />
|
||||
<None Include="package.json" />
|
||||
<None Include="routes\index.ts" />
|
||||
<None Include="views\board.jade" />
|
||||
<None Include="views\image.jade" />
|
||||
<None Include="views\index.jade" />
|
||||
<None Include="views\layout.jade" />
|
||||
<None Include="views\user.jade" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="public\stylesheets\style.css" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="public\images\" />
|
||||
<Folder Include="public\javascripts\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSHARP.Targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio AllowExistingFolder="true" />
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -0,0 +1,41 @@
|
||||
===== TypeScript Sample: Image Board =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample implements a complete Node.js application.
|
||||
Notable features:
|
||||
- Typed usage of express for server side MVC
|
||||
- Typed usage of mongodb for server side database
|
||||
- Typed usage of Node.js
|
||||
- Use of TypeScript module syntax
|
||||
- Visual Studio project file for working with the project
|
||||
|
||||
=== Running ===
|
||||
|
||||
Note: Perform steps 3 - 6 with your working directory set to the folder containing this README:
|
||||
|
||||
1. Install MongoDB if necessary (see http://docs.mongodb.org/manual/installation/ )
|
||||
|
||||
2. Run the following command to launch the MongoDB process:
|
||||
|
||||
<mongoinstalldir>\bin\mongod
|
||||
|
||||
3. Restore the sample app data to MongoDB in another command prompt with the following command:
|
||||
|
||||
<mongoinstalldir>\bin\mongorestore dump
|
||||
|
||||
4. Install the app's node dependencies with the following command:
|
||||
|
||||
npm install
|
||||
|
||||
5. Compile the app with the following command:
|
||||
|
||||
tsc --module commonjs app.ts
|
||||
|
||||
6. Launch the Node process to serve the app using the following command:
|
||||
|
||||
node app.js
|
||||
|
||||
7. Open your favorite browser and going to the following URL to access the app:
|
||||
|
||||
http://localhost:3000/
|
||||
@@ -0,0 +1,129 @@
|
||||
///<reference path='../node/node.d.ts' />
|
||||
|
||||
import http = require("http")
|
||||
import url = require("url")
|
||||
import routes = require("./routes/index")
|
||||
import db = require("./db")
|
||||
import express = require("express")
|
||||
|
||||
var app = express();
|
||||
|
||||
// Configuration
|
||||
app.configure(function(){
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'jade');
|
||||
app.set('view options', { layout: false });
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
});
|
||||
|
||||
app.configure('development', function(){
|
||||
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
|
||||
});
|
||||
|
||||
app.configure('production', function(){
|
||||
app.use(express.errorHandler());
|
||||
});
|
||||
|
||||
|
||||
// Routes
|
||||
|
||||
app.get('/', routes.index);
|
||||
|
||||
app.get('/findImages', function(req, res) {
|
||||
console.log('getting images from' + req.query['url']);
|
||||
|
||||
var req2 = http.get(url.parse(req.query['url']), function(urlres) {
|
||||
console.log("Got response: " + urlres.statusCode);
|
||||
var text = "";
|
||||
urlres.on('data', function(chunk: string) {
|
||||
text += chunk;
|
||||
});
|
||||
urlres.on('end', function() {
|
||||
console.log(text);
|
||||
var re = /<img[^>]+src=[\"\']([^\'\"]+)[\"\']/g;
|
||||
var match, matches = [];
|
||||
while(match = re.exec(text)) {
|
||||
matches.push(match[1]);
|
||||
}
|
||||
res.write(JSON.stringify(matches));
|
||||
res.end();
|
||||
});
|
||||
}).on('error', function(a,e) {
|
||||
console.log("Got error: " + e.message);
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/user/:userid', function(req, res) {
|
||||
console.log('getting user ' + req.params.userid);
|
||||
db.getUser(req.params.userid, function(user) {
|
||||
res.render('user', {
|
||||
title: user._id,
|
||||
username: user._id,
|
||||
boards: user.boards
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/user/:userid/newboard', function(req, res) {
|
||||
res.render('newboard', {
|
||||
username: req.params.userid
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/user/:userid/newboard', function(req, res) {
|
||||
db.addBoard(req.params.userid, req.param('title'), req.param('description'), function(user) {
|
||||
res.redirect('/user/'+req.params.userid)
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/user/:userid/:boardid', function(req, res) {
|
||||
console.log('getting ' + req.params.userid + ", " + req.params.boardid);
|
||||
db.getUser(req.params.userid, function(user) {
|
||||
var board = user.boards.filter(function(board) {
|
||||
return decodeURIComponent(req.params.boardid) === board.title;
|
||||
})[0];
|
||||
if(board) {
|
||||
db.getImages(board.images, function(images) {
|
||||
res.render('board', {
|
||||
title: user._id,
|
||||
username: user._id,
|
||||
board: board,
|
||||
images: images
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.send('not found', 404);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/user/:userid/:boardid/newpin', function(req, res) {
|
||||
res.render('newpin', {
|
||||
username: req.params.userid,
|
||||
boardid: req.params.boardid
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/user/:userid/:boardid/newpin', function(req, res) {
|
||||
db.addPin(req.params.userid, req.params.boardid, req.param('imageUri'), req.param('link'), req.param('caption'), function(user) {
|
||||
res.redirect('/user/'+req.params.userid +"/" + req.params.boardid)
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/image/:imageid', function(req, res) {
|
||||
console.log('getting image ' + req.params.imageid);
|
||||
db.getImage(req.params.imageid, function(image) {
|
||||
res.render('image', {
|
||||
title: "image",
|
||||
image: image
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000, function(){
|
||||
console.log("Demo Express server listening on port %d in %s mode", 3000, app.settings.env);
|
||||
});
|
||||
|
||||
export var App = app;
|
||||
@@ -0,0 +1,110 @@
|
||||
// Mongo
|
||||
import mongodb = require('mongodb');
|
||||
|
||||
var server = new mongodb.Server('localhost', 27017, {auto_reconnect: true}, {})
|
||||
var db = new mongodb.Db('mydb', server);
|
||||
db.open(function() {});
|
||||
|
||||
export interface User {
|
||||
_id: string;
|
||||
email: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
fbId: number;
|
||||
boards: Board[];
|
||||
}
|
||||
|
||||
export interface Board {
|
||||
title: string;
|
||||
description: string;
|
||||
images: mongodb.ObjectID[];
|
||||
}
|
||||
|
||||
export interface Image {
|
||||
_id: mongodb.ObjectID;
|
||||
user: string;
|
||||
caption: string;
|
||||
imageUri: string;
|
||||
link: string;
|
||||
board: string;
|
||||
comments: {text: string; user: string;}[];
|
||||
}
|
||||
|
||||
export function getUser(id: string, callback: (user: User) => void) {
|
||||
db.collection('users', function(error, users) {
|
||||
if(error) { console.error(error); return; }
|
||||
users.findOne({_id: id}, function(error, user) {
|
||||
if(error) { console.error(error); return; }
|
||||
callback(user);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getUsers(callback: (users: User[]) => void) {
|
||||
db.collection('users', function(error, users_collection) {
|
||||
if(error) { console.error(error); return; }
|
||||
users_collection.find({}, { '_id': 1 }).toArray(function(error, userobjs) {
|
||||
if(error) { console.error(error); return; }
|
||||
callback(userobjs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getImage(imageId: string, callback: (image: Image) => void) {
|
||||
db.collection('images', function(error, images_collection) {
|
||||
if(error) { console.error(error); return; }
|
||||
images_collection.findOne({_id: new mongodb.ObjectID(imageId)}, function(error, image) {
|
||||
if(error) { console.error(error); return; }
|
||||
callback(image);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getImages(imageIds: mongodb.ObjectID[], callback: (images: Image[]) => void) {
|
||||
db.collection('images', function(error, images_collection) {
|
||||
if(error) { console.error(error); return; }
|
||||
images_collection.find({_id: {$in: imageIds}}).toArray(function(error, images) {
|
||||
callback(images);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function addBoard(userid: any, title: string, description: string, callback: (user: User) => void) {
|
||||
db.collection('users', function(error, users) {
|
||||
if(error) { console.error(error); return; }
|
||||
users.update(
|
||||
{_id: userid},
|
||||
{"$push": {boards: { title: title, description: description, images: []}}},
|
||||
function(error, user) {
|
||||
if(error) { console.error(error); return; }
|
||||
callback(user);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function addPin(userid: string, boardid: string, imageUri: string, link: string, caption: string, callback: (user: User) => void) {
|
||||
db.collection('images', function(error, images_collection) {
|
||||
if(error) { console.error(error); return; }
|
||||
images_collection.insert({
|
||||
user: userid,
|
||||
caption: caption,
|
||||
imageUri: imageUri,
|
||||
link: link,
|
||||
board: boardid,
|
||||
comments: []
|
||||
}, function(error, image) {
|
||||
console.log(image);
|
||||
db.collection('users', function(error, users) {
|
||||
if(error) { console.error(error); return; }
|
||||
users.update(
|
||||
{_id: userid, "boards.title": boardid},
|
||||
{"$push": {"boards.$.images": image[0]._id}},
|
||||
function(error, user) {
|
||||
callback(user);
|
||||
}
|
||||
);
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{indexes:[{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "mydb.images", "name" : "_id_" }]}
|
||||
@@ -0,0 +1 @@
|
||||
{indexes:[{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "mydb.users", "name" : "_id_" }]}
|
||||
@@ -0,0 +1,128 @@
|
||||
///<reference path='../node/node.d.ts' />
|
||||
|
||||
declare module "express" {
|
||||
import http = require("http");
|
||||
function express(): express.ExpressServer;
|
||||
module express {
|
||||
export function createServer(): ExpressServer;
|
||||
export function static(path: string): any;
|
||||
export var listen;
|
||||
|
||||
// Connect middleware
|
||||
export function bodyParser(options?: any): (req: ExpressServerRequest, res: ExpressServerResponse, next) => void;
|
||||
export function errorHandler(opts?: any): (req: ExpressServerRequest, res: ExpressServerResponse, next) => void;
|
||||
export function methodOverride(): (req: ExpressServerRequest, res: ExpressServerResponse, next) => void;
|
||||
|
||||
export interface ExpressSettings {
|
||||
env?: string;
|
||||
views?: string;
|
||||
}
|
||||
|
||||
export interface ExpressServer {
|
||||
set(name: string): any;
|
||||
set(name: string, val: any): any;
|
||||
enable(name: string): ExpressServer;
|
||||
disable(name: string): ExpressServer;
|
||||
enabled(name: string): boolean;
|
||||
disabled(name: string): boolean;
|
||||
configure(env: string, callback: () => void ): ExpressServer;
|
||||
configure(env: string, env2: string, callback: () => void ): ExpressServer;
|
||||
configure(callback: () => void ): ExpressServer;
|
||||
settings: ExpressSettings;
|
||||
engine(ext: string, callback: any): void;
|
||||
param(param: Function): ExpressServer;
|
||||
param(name: string, callback: Function): ExpressServer;
|
||||
param(name: string, expressParam: any): ExpressServer;
|
||||
param(name: any[], callback: Function): ExpressServer;
|
||||
get(name: string): any;
|
||||
get(path: string, handler: (req: ExpressServerRequest, res: ExpressServerResponse) => void ): void;
|
||||
get(path: RegExp, handler: (req: ExpressServerRequest, res: ExpressServerResponse) => void ): void;
|
||||
get(path: string, callbacks: any, callback: () => void ): void;
|
||||
post(path: string, handler: (req: ExpressServerRequest, res: ExpressServerResponse) => void ): void;
|
||||
post(path: RegExp, handler: (req: ExpressServerRequest, res: ExpressServerResponse) => void ): void;
|
||||
post(path: string, callbacks: any, callback: () => void ): void;
|
||||
all(path: string, callback: Function): void;
|
||||
all(path: string, callback: Function, callback2: Function): void;
|
||||
locals: any;
|
||||
render(view: string, callback: (err: Error, html) => void ): void;
|
||||
render(view: string, opts: any, callback: (err: Error, html) => void ): void;
|
||||
routes: any;
|
||||
listen(port: number, hostname: string, backlog: number, callback: Function): void;
|
||||
listen(port: number, callback: Function): void;
|
||||
listen(path: string, callback?: Function): void;
|
||||
listen(handle: any, listeningListener?: Function): void;
|
||||
use(route: string, callback: Function): ExpressServer;
|
||||
use(route: string, server: ExpressServer): ExpressServer;
|
||||
use(callback: Function): ExpressServer;
|
||||
use(server: ExpressServer): ExpressServer;
|
||||
}
|
||||
|
||||
export class ExpressServerRequest extends http.ServerRequest {
|
||||
params: any;
|
||||
query: any;
|
||||
body: any;
|
||||
files: any;
|
||||
param(name: string): any;
|
||||
route: any;
|
||||
cookies: any;
|
||||
signedCookies: any;
|
||||
get(field: string): string;
|
||||
accepts(types: string): any;
|
||||
accepts(types: string[]): any;
|
||||
accepted: any;
|
||||
is(type: string): boolean;
|
||||
ip: string;
|
||||
ips: string[];
|
||||
path: string;
|
||||
host: string;
|
||||
fresh: boolean;
|
||||
stale: boolean;
|
||||
xhr: boolean;
|
||||
protocol: string;
|
||||
secure: boolean;
|
||||
subdomains: string[];
|
||||
acceptedLanguages: string[];
|
||||
acceptedCharsets: string[];
|
||||
acceptsCharset(charset: string): boolean;
|
||||
acceptsLanguage(lang: string): boolean;
|
||||
}
|
||||
|
||||
export class ExpressServerResponse extends http.ServerResponse {
|
||||
status(code: number): any;
|
||||
set(field: any): void;
|
||||
set(field: string, value: string): void;
|
||||
header(field: any): void;
|
||||
header(field: string, value: string): void;
|
||||
get(field: string): any;
|
||||
cookie(name: string, value: any, options?: any): void;
|
||||
clearcookie(name: string, options?: any): void;
|
||||
redirect(status: number, url: string): void;
|
||||
redirect(url: string): void;
|
||||
charset: string;
|
||||
send(bodyOrStatus: any);
|
||||
send(body: any, status: any);
|
||||
send(body: any, headers: any, status: number);
|
||||
json(bodyOrStatus: any);
|
||||
json(body: any, status: any);
|
||||
json(body: any, headers: any, status: number);
|
||||
jsonp(bodyOrStatus: any);
|
||||
jsonp(body: any, status: any);
|
||||
jsonp(body: any, headers: any, status: number);
|
||||
type(type: string): void;
|
||||
format(object: any): void;
|
||||
attachment(filename?: string);
|
||||
sendfile(path: string): void;
|
||||
sendfile(path: string, options: any): void;
|
||||
sendfile(path: string, options: any, fn: (err: Error) => void ): void;
|
||||
download(path: string): void;
|
||||
download(path: string, filename: string): void;
|
||||
download(path: string, filename: string, fn: (err: Error) => void ): void;
|
||||
links(links: any): void;
|
||||
locals: any;
|
||||
render(view: string, locals: any): void;
|
||||
render(view: string, callback: (err: Error, html: any) => void ): void;
|
||||
render(view: string, locals: any, callback: (err: Error, html: any) => void ): void;
|
||||
}
|
||||
}
|
||||
export = express;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
///<reference path='../node/node.d.ts' />
|
||||
|
||||
declare module "mongodb" {
|
||||
export class Server {
|
||||
constructor(host: string, port: number, opts?: any, moreopts?: any);
|
||||
}
|
||||
export class Db {
|
||||
constructor(databaseName: string, serverConfig: Server);
|
||||
public open(callback: ()=>void);
|
||||
public collection(name: string, callback: (err: any, collection: MongoCollection) => void);
|
||||
}
|
||||
export class ObjectID {
|
||||
constructor(s: string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface MongoDb {
|
||||
|
||||
}
|
||||
|
||||
interface MongoCollection {
|
||||
find(query: any): MongoCursor;
|
||||
find(query: any, callback?: (err: any, result: any) => void): MongoCursor;
|
||||
find(query: any, select: any, callback?: (err: any, result: any) => void): MongoCursor;
|
||||
findOne(query: any, callback: (err: any, result: any) => void): void;
|
||||
update(query: any, updates: any, callback: (err: any, result: any) => void): void;
|
||||
insert(query: any, callback: (err: any, result: any) => void): void;
|
||||
}
|
||||
|
||||
interface MongoCursor {
|
||||
toArray(callback: (err: any, results: any[]) => void);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "application-name"
|
||||
, "version": "0.0.1"
|
||||
, "private": true
|
||||
, "dependencies": {
|
||||
"express": ">= 3.0.0"
|
||||
, "ejs": ">= 0.5.0"
|
||||
, "jade": ">= 0.0.1"
|
||||
, "mongodb": ">= 1.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
///<reference path="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js" />
|
||||
///<reference path="http://connect.facebook.net/en_US/all.js" />
|
||||
|
||||
// initialize the library with the API key
|
||||
FB.init({ appId: '349900301735115' });
|
||||
|
||||
// fetch the status on load
|
||||
FB.getLoginStatus(handleSessionResponse2);
|
||||
|
||||
$('#login').bind('click', function () {
|
||||
FB.login(handleSessionResponse);
|
||||
});
|
||||
|
||||
$('#logout').bind('click', function () {
|
||||
FB.logout(handleSessionResponse);
|
||||
});
|
||||
|
||||
function handleSessionResponse2() { }
|
||||
// handle a session response from any of the auth related calls
|
||||
function handleSessionResponse() {
|
||||
FB.api('/me', function (response) {
|
||||
console.dir(response);
|
||||
//$('#user-info').html(response.id + ' - ' + response.name);
|
||||
});
|
||||
FB.api('/me/picture', function (response) {
|
||||
console.dir(response);
|
||||
var img = document.createElement('img');
|
||||
img.src = response;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
html { background-color: #f9f9f9; margin: 0; padding: 0; }
|
||||
body { margin: 0 auto; padding: 0; font-family:"Segoe UI","HelveticaNeue-Light", sans-serif; font-weight:200;}
|
||||
h1, h2, p, summary, footer, li { line-height: 170%; }
|
||||
h1, h2 { border-bottom: 1px solid #aaa; font-family:"Segoe UI Light","HelveticaNeue-UltraLight", sans-serif; font-weight:100; }
|
||||
h2 { font-size: 16pt; }
|
||||
p { margin: 1em 20px 0 20px; }
|
||||
ul { margin-top: 1em; }
|
||||
#footer { font-style: italic; color: #999; text-align: center; padding: 1em 0 2em 0; margin-top: 1em; font-size: 80%; }
|
||||
em { letter-spacing: 1px; }
|
||||
li { margin-left: 1em; }
|
||||
|
||||
#container
|
||||
{
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
.imglink
|
||||
{
|
||||
text: none;
|
||||
}
|
||||
|
||||
img.small
|
||||
{
|
||||
border:0;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
img.large
|
||||
{
|
||||
border:0;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto
|
||||
}
|
||||
|
||||
|
||||
.image
|
||||
{
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
word-wrap: break-word;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #bbbbbb;
|
||||
background-color: #ffffff;
|
||||
|
||||
}
|
||||
|
||||
.imagebox
|
||||
{
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.commentbox
|
||||
{
|
||||
margin: 5px -5px -5px -5px;
|
||||
padding: 5px;
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.primarysource
|
||||
{
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
form
|
||||
{
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.inputtitle
|
||||
{
|
||||
display:block;
|
||||
float: left;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
input[type="text"], textarea
|
||||
{
|
||||
padding: 6px 12px;
|
||||
line-height: 1.4;
|
||||
border: 1px solid #A4A2A2;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
|
||||
input.button
|
||||
{
|
||||
padding: 6px 12px;
|
||||
line-height: 1.4;
|
||||
border: 1px solid #A4A2A2;
|
||||
border-radius: 6px;
|
||||
background-color: #ab2222;
|
||||
color: #ffffff;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import express = require("express")
|
||||
import db = require("../db")
|
||||
|
||||
export function index(req: express.ExpressServerRequest, res: express.ExpressServerResponse){
|
||||
db.getUsers(function(users) {
|
||||
console.dir(users);
|
||||
res.render('index', { title: 'ImageBoard', users: users })
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
extends layout
|
||||
|
||||
block mainContent
|
||||
h1 #{board.title} by
|
||||
a(href= "/user/"+username)!= username
|
||||
div.board
|
||||
h4.description= board.description
|
||||
#board.images
|
||||
- each image in images
|
||||
div.image.grid_3
|
||||
div.imagebox
|
||||
div
|
||||
a(href= "/image/"+image._id.toString())
|
||||
img.small(src= image.imageUri)
|
||||
=image.caption
|
||||
div.primarysource
|
||||
a(href= image.link)!= /http:\/\/([^\/]*)\//.exec(image.link)[1]
|
||||
div.commentbox
|
||||
- each comment in image.comments
|
||||
div.comment
|
||||
a(href= "/user/"+comment.user)
|
||||
b= comment.user
|
||||
#{comment.text}
|
||||
.grid_12
|
||||
br
|
||||
a(href= "/user/"+username+"/"+board.title+"/newpin") Add a new pin...
|
||||
@@ -0,0 +1,15 @@
|
||||
extends layout
|
||||
|
||||
block mainContent
|
||||
h1 Posted by #{image.user}
|
||||
div.image.grid_9
|
||||
div.imagebox
|
||||
div
|
||||
img.large(src= image.imageUri)
|
||||
=image.caption
|
||||
div.commentbox
|
||||
- each comment in image.comments
|
||||
div.comment
|
||||
a(href= "/user/"+comment.user)
|
||||
b= comment.user
|
||||
#{comment.text}
|
||||
@@ -0,0 +1,11 @@
|
||||
extends layout
|
||||
|
||||
block mainContent
|
||||
h1= title
|
||||
p Welcome to #{title}
|
||||
|
||||
ul
|
||||
- each user in users
|
||||
li
|
||||
a(href= "/user/"+user._id)
|
||||
b= user._id
|
||||
@@ -0,0 +1,14 @@
|
||||
!!!
|
||||
html
|
||||
head
|
||||
title ImageBoard
|
||||
link(rel='stylesheet', href='http://cachedcommons.org/cache/960/0.0.0/stylesheets/960.css')
|
||||
link(rel='stylesheet', href='/stylesheets/style.css')
|
||||
body
|
||||
#header.container_12
|
||||
#fb-root
|
||||
script(src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js')
|
||||
script(src='http://connect.facebook.net/en_US/all.js')
|
||||
script(src='/javascripts/fb.js')
|
||||
#container.container_12!= body
|
||||
block mainContent
|
||||
@@ -0,0 +1,18 @@
|
||||
extends layout
|
||||
|
||||
block mainContent
|
||||
h1 Create a new board for
|
||||
a(href= "/user/"+username)!= username
|
||||
form( method="post")
|
||||
div
|
||||
br
|
||||
div
|
||||
span.inputtitle Title :
|
||||
input(type="text", name="title", id="editArticleTitle")
|
||||
br
|
||||
div
|
||||
span.inputtitle Description :
|
||||
textarea( name="description", rows=10, cols=16, id="editArticleBody")
|
||||
br
|
||||
#editArticleSubmit
|
||||
input.button(type="submit", value="Save board")
|
||||
@@ -0,0 +1,24 @@
|
||||
extends layout
|
||||
|
||||
block mainContent
|
||||
h1 Pin new image to
|
||||
a(href= "/user/"+username)!= username
|
||||
's board
|
||||
a(href= "/user/"+username+"/"+boardid)!= boardid
|
||||
form( method="post")
|
||||
div
|
||||
br
|
||||
div
|
||||
span.inputtitle Image url:
|
||||
input(type="text", name="imageUri")
|
||||
br
|
||||
div
|
||||
span.inputtitle Link :
|
||||
input(type="text", name="link")
|
||||
br
|
||||
div
|
||||
span.inputtitle Caption :
|
||||
textarea( name="caption", rows=10, cols=16)
|
||||
br
|
||||
#editArticleSubmit
|
||||
input.button(type="submit", value="Save pin")
|
||||
@@ -0,0 +1,13 @@
|
||||
extends layout
|
||||
|
||||
block mainContent
|
||||
h1 #{username}'s ImageBoard
|
||||
#boards
|
||||
- each board in boards
|
||||
div.board
|
||||
br
|
||||
div.title
|
||||
a(href= "/user/"+username+"/"+board.title)!= board.title
|
||||
div.description= board.description
|
||||
br
|
||||
a(href= "/user/"+username+"/newboard") Add a new board...
|
||||
@@ -0,0 +1,18 @@
|
||||
===== TypeScript Sample: Simple =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
Simple use of classes and inheritance:
|
||||
- Interface: A simple interface that defines the interface for something that can drive.
|
||||
- Class: An implementation of a car.
|
||||
|
||||
=== Keep Playing ===
|
||||
|
||||
Want to experiment? Try adding a second interface: Flyable. Implement it in a Helicopter class, then write a FlyingCar class that implements both Drivable and Flyable!
|
||||
|
||||
interface Flyable { ... }
|
||||
class Helicopter implements Flyable { ... }
|
||||
class FlyingCar implements Drivable, Flyable { ... }
|
||||
|
||||
=== Running ===
|
||||
tsc interfaces.ts
|
||||
@@ -0,0 +1,52 @@
|
||||
interface Drivable {
|
||||
|
||||
// Starts the car's ignition so that it can drive.
|
||||
start(): void;
|
||||
// Attempt to drive a distance. Returns true or false based on whether or not the drive was successful.
|
||||
drive(distance: number): boolean;
|
||||
// Give the distance from the start.
|
||||
getPosition(): number;
|
||||
}
|
||||
|
||||
class Car implements Drivable {
|
||||
private _isRunning: boolean;
|
||||
private _distanceFromStart: number;
|
||||
|
||||
constructor() {
|
||||
this._isRunning = false;
|
||||
this._distanceFromStart = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the car's ignition so that it can drive.
|
||||
*/
|
||||
public start() {
|
||||
this._isRunning = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to drive a distance. Returns true or false based on whether or not the drive was successful.
|
||||
*
|
||||
* @param {number} distance The distance attempting to cover
|
||||
*
|
||||
* @returns {boolean} Whether or not the drive was successful
|
||||
*/
|
||||
public drive(distance: number): boolean {
|
||||
if (this._isRunning) {
|
||||
this._distanceFromStart += distance;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the distance from starting position
|
||||
*
|
||||
* @returns {number} Distance from starting position;
|
||||
*/
|
||||
public getPosition(): number {
|
||||
return this._distanceFromStart;
|
||||
}
|
||||
}
|
||||
|
||||
// Want to experiment? Try adding a second interface: Flyable. Implement it in a Helicopter class, then write a FlyingCar class that implements both Drivable and Flyable!
|
||||
@@ -0,0 +1,13 @@
|
||||
===== TypeScript Sample: JQuery Parallax Starfield =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample shows a simple jQuery application in TypeScript using a jQuery TypeScript typing.
|
||||
|
||||
=== Usage ===
|
||||
|
||||
For best results, scroll the window using the scrollbar.
|
||||
|
||||
=== Running ===
|
||||
tsc --target ES5 parallax.ts
|
||||
start parallax.html
|
||||
@@ -0,0 +1,703 @@
|
||||
/* *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
// Typing for the jQuery library, version 1.10
|
||||
|
||||
/*
|
||||
Interface for the AJAX setting that will configure the AJAX request
|
||||
*/
|
||||
interface JQueryAjaxSettings {
|
||||
accepts?: any;
|
||||
async?: boolean;
|
||||
beforeSend? (jqXHR: JQueryXHR, settings: JQueryAjaxSettings): any;
|
||||
cache?: boolean;
|
||||
complete? (jqXHR: JQueryXHR, textStatus: string): any;
|
||||
contents?: { [key: string]: any; };
|
||||
contentType?: any;
|
||||
context?: any;
|
||||
converters?: { [key: string]: any; };
|
||||
crossDomain?: boolean;
|
||||
data?: any;
|
||||
dataFilter? (data: any, ty: any): any;
|
||||
dataType?: string;
|
||||
error? (jqXHR: JQueryXHR, textStatus: string, errorThrow: string): any;
|
||||
global?: boolean;
|
||||
headers?: { [key: string]: any; };
|
||||
ifModified?: boolean;
|
||||
isLocal?: boolean;
|
||||
jsonp?: string;
|
||||
jsonpCallback?: any;
|
||||
mimeType?: string;
|
||||
password?: string;
|
||||
processData?: boolean;
|
||||
scriptCharset?: string;
|
||||
statusCode?: { [key: string]: any; };
|
||||
success? (data: any, textStatus: string, jqXHR: JQueryXHR): any;
|
||||
timeout?: number;
|
||||
traditional?: boolean;
|
||||
type?: string;
|
||||
url?: string;
|
||||
username?: string;
|
||||
xhr?: any;
|
||||
xhrFields?: { [key: string]: any; };
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the jqXHR object
|
||||
*/
|
||||
interface JQueryXHR extends XMLHttpRequest {
|
||||
overrideMimeType(): any;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the JQuery callback
|
||||
*/
|
||||
interface JQueryCallback {
|
||||
add(...callbacks: any[]): any;
|
||||
disable(): any;
|
||||
empty(): any;
|
||||
fire(...arguments: any[]): any;
|
||||
fired(): boolean;
|
||||
fireWith(context: any, ...args: any[]): any;
|
||||
has(callback: any): boolean;
|
||||
lock(): any;
|
||||
locked(): boolean;
|
||||
removed(...callbacks: any[]): any;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the JQuery promise, part of callbacks
|
||||
*/
|
||||
interface JQueryPromise {
|
||||
always(...alwaysCallbacks: any[]): JQueryDeferred;
|
||||
done(...doneCallbacks: any[]): JQueryDeferred;
|
||||
fail(...failCallbacks: any[]): JQueryDeferred;
|
||||
pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise;
|
||||
then(doneCallbacks: any, failCallbacks: any, progressCallbacks?: any): JQueryDeferred;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the JQuery deferred, part of callbacks
|
||||
*/
|
||||
interface JQueryDeferred extends JQueryPromise {
|
||||
notify(...args: any[]): JQueryDeferred;
|
||||
notifyWith(context: any, ...args: any[]): JQueryDeferred;
|
||||
|
||||
progress(...progressCallbacks: any[]): JQueryDeferred;
|
||||
reject(...args: any[]): JQueryDeferred;
|
||||
rejectWith(context: any, ...args: any[]): JQueryDeferred;
|
||||
resolve(...args: any[]): JQueryDeferred;
|
||||
resolveWith(context: any, ...args: any[]): JQueryDeferred;
|
||||
state(): string;
|
||||
then(doneCallbacks: any, failCallbacks?: any, progressCallbacks?: any): JQueryDeferred;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface of the JQuery extension of the W3C event object
|
||||
*/
|
||||
interface JQueryEventObject extends Event {
|
||||
data: any;
|
||||
delegateTarget: Element;
|
||||
isDefaultPrevented(): boolean;
|
||||
isImmediatePropogationStopped(): boolean;
|
||||
isPropogationStopped(): boolean;
|
||||
namespace: string;
|
||||
preventDefault(): any;
|
||||
relatedTarget: Element;
|
||||
result: any;
|
||||
stopImmediatePropagation(): void;
|
||||
stopPropagation(): void;
|
||||
pageX: number;
|
||||
pageY: number;
|
||||
which: number;
|
||||
metaKey: any;
|
||||
}
|
||||
|
||||
/*
|
||||
Collection of properties of the current browser
|
||||
*/
|
||||
interface JQueryBrowserInfo {
|
||||
safari: boolean;
|
||||
opera: boolean;
|
||||
msie: boolean;
|
||||
mozilla: boolean;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface JQuerySupport {
|
||||
ajax?: boolean;
|
||||
boxModel?: boolean;
|
||||
changeBubbles?: boolean;
|
||||
checkClone?: boolean;
|
||||
checkOn?: boolean;
|
||||
cors?: boolean;
|
||||
cssFloat?: boolean;
|
||||
hrefNormalized?: boolean;
|
||||
htmlSerialize?: boolean;
|
||||
leadingWhitespace?: boolean;
|
||||
noCloneChecked?: boolean;
|
||||
noCloneEvent?: boolean;
|
||||
opacity?: boolean;
|
||||
optDisabled?: boolean;
|
||||
optSelected?: boolean;
|
||||
scriptEval? (): boolean;
|
||||
style?: boolean;
|
||||
submitBubbles?: boolean;
|
||||
tbody?: boolean;
|
||||
}
|
||||
|
||||
interface JQueryTransport {
|
||||
send(headers: { [index: string]: string; }, completeCallback: (status: number, statusText: string, responses: { [dataType: string]: any; }, headers: string) => void): void;
|
||||
abort(): void;
|
||||
}
|
||||
|
||||
/*
|
||||
Static members of jQuery (those on $ and jQuery themselves)
|
||||
*/
|
||||
interface JQueryStatic {
|
||||
|
||||
// AJAX
|
||||
ajax(settings: JQueryAjaxSettings): JQueryXHR;
|
||||
ajax(url: string, settings: JQueryAjaxSettings): JQueryXHR;
|
||||
|
||||
ajaxPrefilter(handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
|
||||
ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
|
||||
|
||||
ajaxSetup(options: any): void;
|
||||
ajaxTransport(dataType: string, handler: (options: JQueryAjaxSettings, originalOptions: JQueryAjaxSettings, jqXHR: JQueryXHR) => JQueryTransport): void;
|
||||
|
||||
get(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
|
||||
getJSON(url: string, data?: any, success?: any): JQueryXHR;
|
||||
getScript(url: string, success?: any): JQueryXHR;
|
||||
|
||||
param(obj: any): string;
|
||||
param(obj: any, traditional: boolean): string;
|
||||
|
||||
post(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
|
||||
|
||||
// Callbacks
|
||||
Callbacks(flags: any): JQueryCallback;
|
||||
|
||||
// Core
|
||||
holdReady(hold: boolean): any;
|
||||
|
||||
(): JQuery;
|
||||
(selector: string, context?: any): JQuery;
|
||||
(element: Element): JQuery;
|
||||
(elementArray: Element[]): JQuery;
|
||||
(object: JQuery): JQuery;
|
||||
(func: Function): JQuery;
|
||||
(object: {}): JQuery;
|
||||
|
||||
noConflict(removeAll?: boolean): Object;
|
||||
|
||||
when(...deferreds: any[]): JQueryPromise;
|
||||
|
||||
// CSS
|
||||
css(e: any, propertyName: string, value?: any): any;
|
||||
css(e: any, propertyName: any, value?: any): any;
|
||||
cssHooks: { [key: string]: any; };
|
||||
|
||||
// Data
|
||||
data(element: Element, key: string, value: any): Object;
|
||||
|
||||
dequeue(element: Element, queueName?: string): any;
|
||||
|
||||
hasData(element: Element): boolean;
|
||||
|
||||
queue(element: Element, queueName?: string): any[];
|
||||
queue(element: Element, queueName: string, newQueueOrCallback: any): JQuery;
|
||||
|
||||
removeData(element: Element, name?: string): JQuery;
|
||||
|
||||
// Deferred
|
||||
Deferred(beforeStart?: (deferred: JQueryDeferred) => any): JQueryDeferred;
|
||||
|
||||
// Effects
|
||||
fx: { tick: () => void; interval: number; stop: () => void; speeds: { slow: number; fast: number; }; off: boolean; step: any; };
|
||||
|
||||
// Events
|
||||
proxy(func: Function, context: any): any;
|
||||
proxy(context: any, name: string): any;
|
||||
|
||||
// Internals
|
||||
error(message: any): void;
|
||||
|
||||
// Miscellaneous
|
||||
expr: any;
|
||||
fn: any; //TODO: Decide how we want to type this
|
||||
isReady: boolean;
|
||||
|
||||
// Properties
|
||||
browser: JQueryBrowserInfo;
|
||||
support: JQuerySupport;
|
||||
|
||||
// Utilities
|
||||
contains(container: Element, contained: Element): boolean;
|
||||
|
||||
each(collection: any, callback: (indexInArray: any, valueOfElement: any) => any): any;
|
||||
|
||||
extend(deep: boolean, target: any, ...objs: any[]): Object;
|
||||
extend(target: any, ...objs: any[]): Object;
|
||||
|
||||
globalEval(code: string): any;
|
||||
|
||||
grep(array: any[], func: any, invert: boolean): any[];
|
||||
|
||||
inArray(value: any, array: any[], fromIndex?: number): number;
|
||||
|
||||
isArray(obj: any): boolean;
|
||||
isEmptyObject(obj: any): boolean;
|
||||
isFunction(obj: any): boolean;
|
||||
isNumeric(value: any): boolean;
|
||||
isPlainObject(obj: any): boolean;
|
||||
isWindow(obj: any): boolean;
|
||||
isXMLDoc(node: Node): boolean;
|
||||
|
||||
makeArray(obj: any): any[];
|
||||
|
||||
map(array: any[], callback: (elementOfArray: any, indexInArray: any) => any): any[];
|
||||
|
||||
merge(first: any[], second: any[]): any[];
|
||||
|
||||
noop(): any;
|
||||
|
||||
now(): number;
|
||||
|
||||
parseHTML(data: string, context?: Element, keepScripts?: boolean): any[];
|
||||
parseJSON(json: string): any;
|
||||
|
||||
//FIXME: This should return an XMLDocument
|
||||
parseXML(data: string): any;
|
||||
|
||||
queue(element: Element, queueName: string, newQueue: any[]): JQuery;
|
||||
|
||||
trim(str: string): string;
|
||||
|
||||
type(obj: any): string;
|
||||
|
||||
unique(arr: any[]): any[];
|
||||
}
|
||||
|
||||
/*
|
||||
The jQuery instance members
|
||||
*/
|
||||
interface JQuery {
|
||||
// AJAX
|
||||
ajaxComplete(handler: any): JQuery;
|
||||
ajaxError(handler: (evt: any, xhr: any, opts: any) => any): JQuery;
|
||||
ajaxSend(handler: (evt: any, xhr: any, opts: any) => any): JQuery;
|
||||
ajaxStart(handler: () => any): JQuery;
|
||||
ajaxStop(handler: () => any): JQuery;
|
||||
ajaxSuccess(handler: (evt: any, xml: any, opts: any) => any): JQuery;
|
||||
|
||||
serialize(): string;
|
||||
serializeArray(): any[];
|
||||
|
||||
// Attributes
|
||||
addClass(classNames: string): JQuery;
|
||||
addClass(func: (index: any, currentClass: any) => JQuery): JQuery;
|
||||
|
||||
attr(attributeName: string): string;
|
||||
attr(attributeName: string, func: (index: any, attr: any) => any): JQuery;
|
||||
attr(attributeName: string, value: any): JQuery;
|
||||
attr(map: { [key: string]: any; }): JQuery;
|
||||
|
||||
hasClass(className: string): boolean;
|
||||
|
||||
html(): string;
|
||||
html(htmlString: string): JQuery;
|
||||
|
||||
prop(propertyName: string): any;
|
||||
prop(propertyName: string, func: (index: any, oldPropertyValue: any) => any): JQuery;
|
||||
prop(propertyName: string, value: any): JQuery;
|
||||
prop(map: any): JQuery;
|
||||
|
||||
removeAttr(attributeName: any): JQuery;
|
||||
|
||||
removeClass(func: (index: any, cls: any) => any): JQuery;
|
||||
removeClass(className?: string): JQuery;
|
||||
|
||||
removeProp(propertyName: any): JQuery;
|
||||
|
||||
toggleClass(func: (index: any, cls: any, swtch: any) => any): JQuery;
|
||||
toggleClass(swtch?: boolean): JQuery;
|
||||
toggleClass(className: any, swtch?: boolean): JQuery;
|
||||
|
||||
val(): any;
|
||||
val(value: string[]): JQuery;
|
||||
val(value: string): JQuery;
|
||||
val(func: (index: any, value: any) => any): JQuery;
|
||||
|
||||
// CSS
|
||||
css(propertyNames: any[]): string;
|
||||
css(propertyName: string): string;
|
||||
css(propertyName: string, value: any): JQuery;
|
||||
css(propertyName: any, value?: any): JQuery;
|
||||
|
||||
height(): number;
|
||||
height(value: number): JQuery;
|
||||
height(func: (index: any, height: any) => any): JQuery;
|
||||
|
||||
innerHeight(): number;
|
||||
innerWidth(): number;
|
||||
|
||||
offset(): { top: number; left: number; };
|
||||
offset(func: (index: any, coords: any) => any): JQuery;
|
||||
offset(coordinates: any): JQuery;
|
||||
|
||||
outerHeight(includeMargin?: boolean): number;
|
||||
outerWidth(includeMargin?: boolean): number;
|
||||
|
||||
position(): { top: number; left: number; };
|
||||
|
||||
scrollLeft(): number;
|
||||
scrollLeft(value: number): JQuery;
|
||||
|
||||
scrollTop(): number;
|
||||
scrollTop(value: number): JQuery;
|
||||
|
||||
width(): number;
|
||||
width(value: number): JQuery;
|
||||
width(func: (index: any, height: any) => any): JQuery;
|
||||
|
||||
// Data
|
||||
clearQueue(queueName?: string): JQuery;
|
||||
|
||||
data(key: string, value: any): JQuery;
|
||||
data(obj: { [key: string]: any; }): JQuery;
|
||||
data(key?: string): any;
|
||||
|
||||
dequeue(queueName?: string): JQuery;
|
||||
|
||||
queue(queueName?: string): any[];
|
||||
queue(queueName: string, newQueueOrCallback: any): JQuery;
|
||||
queue(newQueueOrCallback: any): JQuery;
|
||||
|
||||
removeData(nameOrList?: any): JQuery;
|
||||
|
||||
// Deferred
|
||||
promise(type?: any, target?: any): JQueryPromise;
|
||||
|
||||
// Effects
|
||||
animate(properties: any, options: { duration?: any; easing?: string; complete?: Function; step?: Function; queue?: boolean; specialEasing?: any; }): JQuery;
|
||||
animate(properties: any, duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
animate(properties: any, duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
animate(properties: any, duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
|
||||
delay(duration: number, queueName?: string): JQuery;
|
||||
|
||||
fadeIn(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeIn(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeIn(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
fadeIn(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
|
||||
fadeOut(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeOut(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeOut(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
fadeOut(duration?: any, complete?: any): JQuery;
|
||||
|
||||
fadeTo(duration: any, opacity: number, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeTo(duration: any, opacity: number, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeTo(duration: any, opacity: number, easing?: string, complete?: Function): JQuery;
|
||||
fadeTo(duration: any, opacity: number, complete?: Function): JQuery;
|
||||
|
||||
fadeToggle(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeToggle(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeToggle(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
|
||||
finish(queue?: string): JQuery;
|
||||
|
||||
hide(duration?: any, easing?: "linear", callback?: Function): JQuery;
|
||||
hide(duration?: any, easing?: "swing", callback?: Function): JQuery;
|
||||
hide(duration?: any, easing?: string, callback?: Function): JQuery;
|
||||
hide(duration?: any, callback?: Function): JQuery;
|
||||
|
||||
show(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
show(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
show(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
show(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
slideDown(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
slideDown(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
slideDown(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
slideDown(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
slideToggle(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
slideToggle(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
slideToggle(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
slideToggle(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
slideUp(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
slideUp(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
slideUp(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
slideUp(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
stop(clearQueue?: boolean, jumpToEnd?: boolean): JQuery;
|
||||
stop(queue?: any, clearQueue?: boolean, jumpToEnd?: boolean): JQuery;
|
||||
|
||||
toggle(showOrHide: boolean): JQuery;
|
||||
toggle(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
toggle(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
toggle(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
toggle(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
// Events
|
||||
bind(eventType: string, preventBubble: boolean): JQuery;
|
||||
bind(eventType: string, eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
bind(eventType: string, eventData: any, preventBubble: boolean): JQuery;
|
||||
bind(...events: any[]): JQuery;
|
||||
|
||||
blur(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
blur(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
change(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
change(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
click(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
click(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
dblclick(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
dblclick(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
delegate(selector: any, eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
focus(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
focus(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
focusin(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
focusin(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
focusout(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
focusout(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
hover(handlerIn: (eventObject: JQueryEventObject) => any, handlerOut: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
hover(handlerInOut: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
keydown(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
keydown(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
keypress(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
keypress(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
keyup(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
keyup(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mousedown(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mousedown(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseevent(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseevent(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseenter(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseenter(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseleave(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseleave(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mousemove(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mousemove(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseout(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseout(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseover(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseover(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseup(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseup(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
off(events?: string, selector?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
off(eventsMap: { [key: string]: any; }, selector?: any): JQuery;
|
||||
|
||||
on(events: string, selector?: any, data?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
on(eventsMap: { [key: string]: any; }, selector?: any, data?: any): JQuery;
|
||||
|
||||
one(events: string, selector?: any, data?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
one(eventsMap: { [key: string]: any; }, selector?: any, data?: any): JQuery;
|
||||
|
||||
ready(handler: any): JQuery;
|
||||
|
||||
resize(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
resize(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
scroll(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
scroll(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
select(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
select(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
submit(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
submit(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
trigger(eventType: string, ...extraParameters: any[]): JQuery;
|
||||
trigger(event: JQueryEventObject): JQuery;
|
||||
|
||||
triggerHandler(eventType: string, ...extraParameters: any[]): Object;
|
||||
|
||||
unbind(eventType?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
unbind(eventType: string, fls: boolean): JQuery;
|
||||
unbind(evt: any): JQuery;
|
||||
|
||||
undelegate(): JQuery;
|
||||
undelegate(selector: any, eventType: string, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
undelegate(selector: any, events: any): JQuery;
|
||||
undelegate(namespace: string): JQuery;
|
||||
|
||||
// Internals
|
||||
context: Element;
|
||||
jquery: string;
|
||||
pushStack(elements: any[]): JQuery;
|
||||
pushStack(elements: any[], name: any, arguments: any): JQuery;
|
||||
|
||||
// Manipulation
|
||||
after(func: (index: any) => any): JQuery;
|
||||
after(...content: any[]): JQuery;
|
||||
|
||||
append(func: (index: any, html: any) => any): JQuery;
|
||||
append(...content: any[]): JQuery;
|
||||
|
||||
appendTo(target: any): JQuery;
|
||||
|
||||
before(func: (index: any) => any): JQuery;
|
||||
before(...content: any[]): JQuery;
|
||||
|
||||
clone(withDataAndEvents?: boolean, deepWithDataAndEvents?: boolean): JQuery;
|
||||
|
||||
detach(selector?: any): JQuery;
|
||||
|
||||
empty(): JQuery;
|
||||
|
||||
insertAfter(target: any): JQuery;
|
||||
insertBefore(target: any): JQuery;
|
||||
|
||||
prepend(func: (index: any, html: any) => any): JQuery;
|
||||
prepend(...content: any[]): JQuery;
|
||||
|
||||
prependTo(target: any): JQuery;
|
||||
|
||||
remove(selector?: any): JQuery;
|
||||
|
||||
replaceAll(target: any): JQuery;
|
||||
|
||||
replaceWith(func: any): JQuery;
|
||||
|
||||
text(textString: string): JQuery;
|
||||
text(): string;
|
||||
|
||||
toArray(): any[];
|
||||
|
||||
unwrap(): JQuery;
|
||||
|
||||
wrap(func: (index: any) => any): JQuery;
|
||||
wrap(wrappingElement: any): JQuery;
|
||||
|
||||
wrapAll(wrappingElement: any): JQuery;
|
||||
|
||||
wrapInner(func: (index: any) => any): JQuery;
|
||||
wrapInner(wrappingElement: any): JQuery;
|
||||
|
||||
// Miscellaneous
|
||||
each(func: (index: any, elem: Element) => any): JQuery;
|
||||
|
||||
get(index?: number): any;
|
||||
|
||||
index(selectorOrElement?: any): number;
|
||||
|
||||
// Properties
|
||||
length: number;
|
||||
[x: number]: HTMLElement;
|
||||
|
||||
// Traversing
|
||||
add(selector: string, context?: any): JQuery;
|
||||
add(html: string): JQuery;
|
||||
add(obj: JQuery): JQuery;
|
||||
add(...elements: any[]): JQuery;
|
||||
|
||||
addBack(selector?: any): JQuery;
|
||||
|
||||
children(selector?: any): JQuery;
|
||||
|
||||
closest(selector: string): JQuery;
|
||||
closest(selector: string, context?: Element): JQuery;
|
||||
closest(obj: JQuery): JQuery;
|
||||
closest(element: any): JQuery;
|
||||
closest(selectors: any, context?: Element): any[];
|
||||
|
||||
contents(): JQuery;
|
||||
|
||||
end(): JQuery;
|
||||
|
||||
eq(index: number): JQuery;
|
||||
|
||||
filter(selector: string): JQuery;
|
||||
filter(func: (index: any) => any): JQuery;
|
||||
filter(obj: JQuery): JQuery;
|
||||
filter(element: any): JQuery;
|
||||
|
||||
find(selector: string): JQuery;
|
||||
find(element: any): JQuery;
|
||||
find(obj: JQuery): JQuery;
|
||||
|
||||
first(): JQuery;
|
||||
|
||||
has(selector: string): JQuery;
|
||||
has(contained: Element): JQuery;
|
||||
|
||||
is(selector: string): boolean;
|
||||
is(func: (index: any) => any): boolean;
|
||||
is(obj: JQuery): boolean;
|
||||
is(element: any): boolean;
|
||||
|
||||
last(): JQuery;
|
||||
|
||||
map(callback: (index: any, domElement: Element) => any): JQuery;
|
||||
|
||||
next(selector?: string): JQuery;
|
||||
|
||||
nextAll(selector?: string): JQuery;
|
||||
|
||||
nextUntil(selector?: string, filter?: string): JQuery;
|
||||
nextUntil(element?: Element, filter?: string): JQuery;
|
||||
|
||||
not(selector: string): JQuery;
|
||||
not(func: (index: any) => any): JQuery;
|
||||
not(obj: JQuery): JQuery;
|
||||
not(element: any): JQuery;
|
||||
|
||||
offsetParent(): JQuery;
|
||||
|
||||
parent(selector?: string): JQuery;
|
||||
|
||||
parents(selector?: string): JQuery;
|
||||
|
||||
parentsUntil(selector?: string, filter?: string): JQuery;
|
||||
parentsUntil(element?: Element, filter?: string): JQuery;
|
||||
|
||||
prev(selector?: string): JQuery;
|
||||
|
||||
prevAll(selector?: string): JQuery;
|
||||
|
||||
prevUntil(selector?: string, filter?: string): JQuery;
|
||||
prevUntil(element?: Element, filter?: string): JQuery;
|
||||
|
||||
siblings(selector?: string): JQuery;
|
||||
|
||||
slice(start: number, end?: number): JQuery;
|
||||
}
|
||||
|
||||
declare var jQuery: JQueryStatic;
|
||||
declare var $: JQueryStatic;
|
||||
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title></title>
|
||||
<style type="text/css">
|
||||
#plaxHost {
|
||||
height: 2000px;
|
||||
background-color: Black;
|
||||
}
|
||||
|
||||
#plaxHost div {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
#plax1 {
|
||||
position: fixed;
|
||||
color:White;
|
||||
height: 2000px;
|
||||
background-image: url(starfield2.png);
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#plax2 {
|
||||
position: fixed;
|
||||
height: 2000px;
|
||||
background-image: url(starfield.png);
|
||||
background-position: 1087px 0;
|
||||
top: 0;
|
||||
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#plax3 {
|
||||
position: fixed;
|
||||
height: 2000px;
|
||||
background-position: 577px 0;
|
||||
background-image: url(starfield.png);
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
#plax4 {
|
||||
position: fixed;
|
||||
height: 2000px;
|
||||
background-position: 337px 0;
|
||||
background-image: url(starfield.png);
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
#plax5 {
|
||||
position: fixed;
|
||||
height: 2000px;
|
||||
background-position: 145px 0;
|
||||
background-image: url(starfield.png);
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="plaxHost">
|
||||
<div id="plax1">
|
||||
|
||||
</div>
|
||||
<div id="plax2">
|
||||
|
||||
</div>
|
||||
<div id="plax3">
|
||||
|
||||
</div>
|
||||
<div id="plax4">
|
||||
|
||||
</div>
|
||||
<div id="plax5">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.1.min.js"></script>
|
||||
<script type="text/javascript" src="parallax.js"></script>
|
||||
<script type="text/javascript">
|
||||
var p = new Parallax.ParallaxContainer(window, 0.7);
|
||||
for (i = 1; i <= 5; ++i) {
|
||||
var star_layer = new Parallax.ParallaxSurface(document.querySelector('#plax' + i));
|
||||
p.addSurface(star_layer);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,58 @@
|
||||
/// <reference path="jquery.d.ts" />
|
||||
|
||||
module Parallax {
|
||||
export class ParallaxContainer {
|
||||
private content: HTMLElement;
|
||||
private perspective: number;
|
||||
private surface: ParallaxSurface[];
|
||||
|
||||
/**
|
||||
* Creates a Container for a Parallax
|
||||
*
|
||||
* @param {HTMLElement} scrollableContent The container that will be parallaxed
|
||||
* @param {perspective} perspective The ratio of how much back content should be scroleld relative to forward content. For example, if this value is 0.5, and there are 2 surfaces,
|
||||
* the front-most surface would be scrolled normally, and the surface behind it would be scrolled half as much.
|
||||
*/
|
||||
constructor(scrollableContent: HTMLElement,
|
||||
perspective: number) {
|
||||
this.perspective = perspective;
|
||||
this.surface = [];
|
||||
this.content = scrollableContent;
|
||||
|
||||
$(scrollableContent).scroll((event: JQueryEventObject) => {
|
||||
this.onContainerScroll(event);
|
||||
});
|
||||
}
|
||||
|
||||
private onContainerScroll(e: JQueryEventObject): void {
|
||||
var currentScrollPos = $(this.content).scrollTop();
|
||||
var currentParallax = 1;
|
||||
for (var i = 0; i < this.surface.length; i++) {
|
||||
var surface = this.surface[i];
|
||||
var offset = -(currentScrollPos * currentParallax);
|
||||
surface.currentY = offset;
|
||||
currentParallax *= this.perspective;
|
||||
}
|
||||
}
|
||||
|
||||
addSurface(surface: ParallaxSurface): void {
|
||||
this.surface.push(surface);
|
||||
}
|
||||
}
|
||||
|
||||
export class ParallaxSurface {
|
||||
private content: HTMLElement;
|
||||
|
||||
constructor(surfaceContents: HTMLElement) {
|
||||
this.content = surfaceContents;
|
||||
}
|
||||
|
||||
get currentY(): number {
|
||||
return -$(this.content).css('margin-top');
|
||||
}
|
||||
|
||||
set currentY(value: number) {
|
||||
$(this.content).css({ marginTop: value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,72 @@
|
||||
///<reference path="Driver.ts"/>
|
||||
|
||||
module Base {
|
||||
export interface IList {
|
||||
isHead: boolean;
|
||||
next: IList;
|
||||
prev: IList;
|
||||
insertAfter(entry: IList): IList;
|
||||
insertBefore(entry: IList): IList;
|
||||
item();
|
||||
empty(): boolean;
|
||||
}
|
||||
|
||||
export class List implements IList {
|
||||
next: IList;
|
||||
prev: IList;
|
||||
|
||||
constructor (public isHead: boolean, public data) { }
|
||||
|
||||
item() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
empty(): boolean {
|
||||
return this.next == this;
|
||||
}
|
||||
|
||||
insertAfter(entry: IList): IList {
|
||||
entry.next = this.next;
|
||||
entry.prev = this;
|
||||
this.next = entry;
|
||||
entry.next.prev = entry;
|
||||
return (entry);
|
||||
}
|
||||
|
||||
insertBefore(entry: IList): IList {
|
||||
this.prev.next = entry;
|
||||
entry.next = this;
|
||||
entry.prev = this.prev;
|
||||
this.prev = entry;
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
export function listMakeEntry(data): IList {
|
||||
var entry: List = new List(false, data);
|
||||
entry.prev = entry;
|
||||
entry.next = entry;
|
||||
return entry;
|
||||
}
|
||||
|
||||
export function listMakeHead(): IList {
|
||||
var entry: List = new List(true, null);
|
||||
entry.prev = entry;
|
||||
entry.next = entry;
|
||||
return entry;
|
||||
}
|
||||
|
||||
export function listRemove(entry: IList): IList {
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
else if (entry.isHead) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
entry.next.prev = entry.prev;
|
||||
entry.prev.next = entry.next;
|
||||
}
|
||||
return (entry);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
///<reference path='Position.ts'/>
|
||||
///<reference path='Geometry.ts'/>
|
||||
///<reference path='Game.ts'/>
|
||||
///<reference path='Features.ts'/>
|
||||
///<reference path='Base.ts'/>
|
||||
|
||||
if (!this.document) {
|
||||
var game = new Mankala.Game();
|
||||
game.test();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
///<reference path="Driver.ts"/>
|
||||
|
||||
module Mankala {
|
||||
export class Features {
|
||||
public turnContinues = false;
|
||||
public seedStoredCount = 0;
|
||||
public capturedCount = 0;
|
||||
public spaceCaptured = NoSpace;
|
||||
|
||||
public clear() {
|
||||
this.turnContinues = false;
|
||||
this.seedStoredCount = 0;
|
||||
this.capturedCount = 0;
|
||||
this.spaceCaptured = NoSpace;
|
||||
}
|
||||
|
||||
public toString() {
|
||||
var stringBuilder = "";
|
||||
if (this.turnContinues) {
|
||||
stringBuilder += " turn continues,";
|
||||
}
|
||||
stringBuilder += " stores " + this.seedStoredCount;
|
||||
if (this.capturedCount > 0) {
|
||||
stringBuilder += " captures " + this.capturedCount + " from space " + this.spaceCaptured;
|
||||
}
|
||||
return stringBuilder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
///<reference path="Driver.ts"/>
|
||||
|
||||
module Mankala {
|
||||
export var NoSpace = -1;
|
||||
export var homeSpaces = [[0, 1, 2, 3, 4, 5],
|
||||
[7, 8, 9, 10, 11, 12]];
|
||||
export var firstHomeSpace = [0, 7];
|
||||
export var lastHomeSpace = [5, 12];
|
||||
export var capturedSpaces = [12, 11, 10, 9, 8, 7, NoSpace, 5, 4, 3, 2, 1, 0, NoSpace];
|
||||
export var NoScore = 31;
|
||||
export var NoMove = -1;
|
||||
|
||||
export interface IPositionList extends Base.IList {
|
||||
data: Position;
|
||||
push(pos: Position);
|
||||
pop(): Position;
|
||||
}
|
||||
|
||||
function pushPosition(pos: Position, l: IPositionList) {
|
||||
l.insertAfter(Base.listMakeEntry(pos));
|
||||
}
|
||||
|
||||
function popPosition(l: IPositionList) {
|
||||
var entry: IPositionList = <IPositionList>Base.listRemove(l.next);
|
||||
if (entry != null) {
|
||||
return entry.data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function testBrowser() {
|
||||
var game = new Game();
|
||||
game.interactive();
|
||||
var bod = document.getElementById("bod");
|
||||
bod.onresize = function() {
|
||||
game.resize();
|
||||
}
|
||||
}
|
||||
|
||||
export class Game {
|
||||
private position = new DisplayPosition([3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0], NoMove, 0);
|
||||
private prevConfig: SeedCoords[][];
|
||||
private q: IPositionList = null;
|
||||
private scores: number[] = null;
|
||||
private positionCount = 0;
|
||||
private moveCount = 0;
|
||||
private isInteractive = false;
|
||||
|
||||
private features = new Features();
|
||||
private nextSeedCounts: number[] = new Array<number>(14);
|
||||
private bod: Element;
|
||||
private boardElm: Element = null;
|
||||
|
||||
public resize() {
|
||||
if (this.boardElm != null) {
|
||||
this.bod.removeChild(this.boardElm);
|
||||
}
|
||||
this.showMove();
|
||||
}
|
||||
|
||||
private step(): boolean {
|
||||
var move = this.findMove();
|
||||
if (move != NoMove) {
|
||||
this.position.move(move, this.nextSeedCounts, this.features);
|
||||
this.position = new DisplayPosition(this.nextSeedCounts.slice(0), NoMove,
|
||||
this.features.turnContinues ? this.position.turn : 1 - this.position.turn);
|
||||
this.position.config = this.prevConfig;
|
||||
if ((!this.isInteractive) || (this.position.turn == 1)) {
|
||||
this.setStep();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private setStep() {
|
||||
setTimeout(/*function()*/ () => {
|
||||
if (!this.step()) {
|
||||
this.finish();
|
||||
}
|
||||
this.bod.removeChild(this.boardElm);
|
||||
this.showMove();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private finish() {
|
||||
var sum = 0;
|
||||
var otherSpaces = homeSpaces[1 - this.position.turn];
|
||||
for (var k = 0, len = otherSpaces.length; k < len; k++) {
|
||||
sum += this.position.seedCounts[otherSpaces[k]];
|
||||
this.position.seedCounts[otherSpaces[k]] = 0;
|
||||
}
|
||||
this.position.seedCounts[storeHouses[this.position.turn]] += sum;
|
||||
}
|
||||
|
||||
private auto() {
|
||||
// initialize
|
||||
this.bod = document.getElementById("bod");
|
||||
this.showMove();
|
||||
// run with timeout
|
||||
this.setStep();
|
||||
}
|
||||
|
||||
private showMove(): void {
|
||||
var hsc = document.getElementById("humscore");
|
||||
var csc = document.getElementById("compscore");
|
||||
|
||||
var g = this;
|
||||
if (!this.isInteractive) {
|
||||
g = null;
|
||||
}
|
||||
this.boardElm = this.position.toCircleSVG(g);
|
||||
this.prevConfig = this.position.config;
|
||||
hsc.innerText = this.position.seedCounts[storeHouses[0]] +
|
||||
((this.position.turn == 0) ? " <-Turn" : "");
|
||||
csc.innerText = this.position.seedCounts[storeHouses[1]] +
|
||||
((this.position.turn == 1) ? " <-Turn" : "");
|
||||
this.bod.appendChild(this.boardElm);
|
||||
}
|
||||
|
||||
public humanMove(seed: number) {
|
||||
if (this.position.turn == 0) {
|
||||
this.position.move(seed, this.nextSeedCounts, this.features);
|
||||
this.position = new DisplayPosition(this.nextSeedCounts.slice(0), NoMove,
|
||||
this.features.turnContinues ? this.position.turn : 1 - this.position.turn);
|
||||
this.position.config = this.prevConfig;
|
||||
this.bod.removeChild(this.boardElm);
|
||||
this.showMove();
|
||||
if (this.position.turn == 1) {
|
||||
this.setStep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interactive() {
|
||||
this.isInteractive = true;
|
||||
this.bod = document.getElementById("bod");
|
||||
this.showMove();
|
||||
}
|
||||
|
||||
private expand(curPos: Position, move: number,
|
||||
startMove: number, nextSeedCounts: number[]) {
|
||||
var features = new Features();
|
||||
if (curPos.move(move, nextSeedCounts, features)) {
|
||||
var pos = new Position(nextSeedCounts.slice(0), startMove, curPos.turn);
|
||||
this.positionCount++;
|
||||
if (!features.turnContinues) {
|
||||
pos.turn = 1 - pos.turn;
|
||||
}
|
||||
var score = pos.score();
|
||||
if (this.scores[startMove] == NoScore) {
|
||||
this.scores[startMove] = score;
|
||||
}
|
||||
else {
|
||||
this.scores[startMove] += score;
|
||||
}
|
||||
pushPosition(pos, this.q);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private findMove() {
|
||||
var timeStart = new Date().getTime();
|
||||
this.q = <IPositionList>Base.listMakeHead();
|
||||
this.scores = [NoScore, NoScore, NoScore, NoScore, NoScore, NoScore];
|
||||
pushPosition(this.position, this.q);
|
||||
var deltaTime = 0;
|
||||
var moves = homeSpaces[this.position.turn];
|
||||
var nextSeedCounts: number[] = new Array<number>(14);
|
||||
var movePossible = false;
|
||||
while ((!this.q.empty()) && (deltaTime < 500)) {
|
||||
var firstPos = popPosition(this.q);
|
||||
for (var i = 0, len = moves.length; i < len; i++) {
|
||||
var startMove = firstPos.startMove;
|
||||
if (startMove == NoMove) {
|
||||
startMove = i;
|
||||
}
|
||||
if (this.expand(firstPos, moves[i], startMove, nextSeedCounts)) {
|
||||
movePossible = true;
|
||||
}
|
||||
}
|
||||
deltaTime = new Date().getTime() - timeStart;
|
||||
}
|
||||
if (movePossible) {
|
||||
var bestScore = -100;
|
||||
var bestMove = NoMove;
|
||||
for (var j = 0, scoresLen = this.scores.length; j < scoresLen; j++) {
|
||||
if ((this.scores[j] != NoScore) && ((this.scores[j] > bestScore) || (bestMove == NoMove))) {
|
||||
bestScore = this.scores[j];
|
||||
bestMove = j;
|
||||
}
|
||||
}
|
||||
if (bestMove != NoMove) {
|
||||
return moves[bestMove];
|
||||
} else {
|
||||
return NoMove;
|
||||
}
|
||||
}
|
||||
return NoMove;
|
||||
}
|
||||
|
||||
public test() {
|
||||
var features = new Features();
|
||||
var nextSeedCounts: number[] = new Array<number>(14);
|
||||
WScript.Echo("position: ")
|
||||
WScript.Echo(this.position.seedCounts.slice(0, 7));
|
||||
WScript.Echo(this.position.seedCounts.slice(7));
|
||||
do {
|
||||
var move = this.findMove();
|
||||
if (move == NoMove) {
|
||||
// TODO: capture rest of other side
|
||||
} else {
|
||||
this.moveCount++;
|
||||
WScript.Echo(this.position.turn + " moves seeds in space " + move);
|
||||
this.position.move(move, nextSeedCounts, features);
|
||||
WScript.Echo(features.toString());
|
||||
this.position = new DisplayPosition(nextSeedCounts.slice(0), NoMove,
|
||||
features.turnContinues ? this.position.turn : 1 - this.position.turn);
|
||||
WScript.Echo("position: ")
|
||||
WScript.Echo(this.position.seedCounts.slice(0, 7));
|
||||
WScript.Echo(this.position.seedCounts.slice(7));
|
||||
}
|
||||
} while (move != NoMove);
|
||||
var sum = 0;
|
||||
var otherSpaces = homeSpaces[1 - this.position.turn];
|
||||
for (var k = 0, len = otherSpaces.length; k < len; k++) {
|
||||
sum += this.position.seedCounts[otherSpaces[k]];
|
||||
this.position.seedCounts[otherSpaces[k]] = 0;
|
||||
}
|
||||
this.position.seedCounts[storeHouses[this.position.turn]] += sum;
|
||||
WScript.Echo("final position: ")
|
||||
WScript.Echo(this.position.seedCounts.slice(0, 7));
|
||||
WScript.Echo(this.position.seedCounts.slice(7));
|
||||
var player1Count = this.position.seedCounts[storeHouses[0]];
|
||||
var player2Count = this.position.seedCounts[storeHouses[1]];
|
||||
WScript.Echo("storehouse 1 has " + player1Count);
|
||||
WScript.Echo("storehouse 2 has " + player2Count);
|
||||
WScript.Echo("average positions explored per move " +
|
||||
(this.positionCount / this.moveCount).toFixed(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
///<reference path="Driver.ts"/>
|
||||
|
||||
module Mankala {
|
||||
export var storeHouses = [6, 13];
|
||||
var svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
function createSVGRect(r: Rectangle) {
|
||||
var rect = document.createElementNS(svgNS, "rect");
|
||||
rect.setAttribute("x", r.x.toString());
|
||||
rect.setAttribute("y", r.y.toString());
|
||||
rect.setAttribute("width", r.width.toString());
|
||||
rect.setAttribute("height", r.height.toString());
|
||||
return rect;
|
||||
}
|
||||
|
||||
function createSVGEllipse(r: Rectangle) {
|
||||
var ell = document.createElementNS(svgNS, "ellipse");
|
||||
ell.setAttribute("rx", (r.width / 2).toString());
|
||||
ell.setAttribute("ry", (r.height / 2).toString());
|
||||
ell.setAttribute("cx", (r.x + r.width / 2).toString());
|
||||
ell.setAttribute("cy", (r.y + r.height / 2).toString());
|
||||
return ell;
|
||||
}
|
||||
|
||||
function createSVGEllipsePolar(angle: number, radius: number, tx: number, ty: number,
|
||||
cxo: number, cyo: number) {
|
||||
var ell = document.createElementNS(svgNS, "ellipse");
|
||||
ell.setAttribute("rx", radius.toString());
|
||||
ell.setAttribute("ry", (radius / 3).toString());
|
||||
ell.setAttribute("cx", cxo.toString());
|
||||
ell.setAttribute("cy", cyo.toString());
|
||||
var dangle = angle * (180 / Math.PI);
|
||||
ell.setAttribute("transform", "rotate(" + dangle + "," + cxo + "," + cyo + ") translate(" + tx +
|
||||
"," + ty + ")");
|
||||
return ell;
|
||||
}
|
||||
|
||||
function createSVGInscribedCircle(sq: Square) {
|
||||
var circle = document.createElementNS(svgNS, "circle");
|
||||
circle.setAttribute("r", (sq.len / 2).toString());
|
||||
circle.setAttribute("cx", (sq.x + (sq.len / 2)).toString());
|
||||
circle.setAttribute("cy", (sq.y + (sq.len / 2)).toString());
|
||||
return circle;
|
||||
}
|
||||
|
||||
export class Position {
|
||||
constructor (public seedCounts: number[], public startMove: number, public turn: number) { }
|
||||
public score() {
|
||||
var baseScore = this.seedCounts[storeHouses[1 - this.turn]] - this.seedCounts[storeHouses[this.turn]];
|
||||
var otherSpaces = homeSpaces[this.turn];
|
||||
var sum = 0;
|
||||
for (var k = 0, len = otherSpaces.length; k < len; k++) {
|
||||
sum += this.seedCounts[otherSpaces[k]];
|
||||
}
|
||||
if (sum == 0) {
|
||||
var mySpaces = homeSpaces[1 - this.turn];
|
||||
var mySum = 0;
|
||||
for (var j = 0, length = mySpaces.length; j < length; j++) {
|
||||
mySum += this.seedCounts[mySpaces[j]];
|
||||
}
|
||||
|
||||
baseScore -= mySum;
|
||||
}
|
||||
return baseScore;
|
||||
}
|
||||
|
||||
public move(space: number, nextSeedCounts: number[], features: Features) {
|
||||
if ((space == storeHouses[0]) || (space == storeHouses[1])) {
|
||||
// can't move seeds in storehouse
|
||||
return false;
|
||||
}
|
||||
if (this.seedCounts[space] > 0) {
|
||||
features.clear();
|
||||
var len = this.seedCounts.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
nextSeedCounts[i] = this.seedCounts[i];
|
||||
}
|
||||
var seedCount = this.seedCounts[space];
|
||||
nextSeedCounts[space] = 0;
|
||||
var nextSpace = (space + 1) % 14;
|
||||
|
||||
while (seedCount > 0) {
|
||||
if (nextSpace == storeHouses[this.turn]) {
|
||||
features.seedStoredCount++;
|
||||
}
|
||||
if ((nextSpace != storeHouses[1 - this.turn])) {
|
||||
nextSeedCounts[nextSpace]++;
|
||||
seedCount--;
|
||||
}
|
||||
if (seedCount == 0) {
|
||||
if (nextSpace == storeHouses[this.turn]) {
|
||||
features.turnContinues = true;
|
||||
} else if ((nextSeedCounts[nextSpace] == 1) &&
|
||||
(nextSpace >= firstHomeSpace[this.turn]) &&
|
||||
(nextSpace <= lastHomeSpace[this.turn])) {
|
||||
// capture
|
||||
var capturedSpace = capturedSpaces[nextSpace];
|
||||
if (capturedSpace >= 0) {
|
||||
features.spaceCaptured = capturedSpace;
|
||||
features.capturedCount = nextSeedCounts[capturedSpace];
|
||||
nextSeedCounts[capturedSpace] = 0;
|
||||
nextSeedCounts[storeHouses[this.turn]] += features.capturedCount;
|
||||
features.seedStoredCount += nextSeedCounts[capturedSpace];
|
||||
}
|
||||
}
|
||||
}
|
||||
nextSpace = (nextSpace + 1) % 14;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class SeedCoords {
|
||||
constructor(public tx: number, public ty: number, public angle: number) { }
|
||||
}
|
||||
|
||||
export class DisplayPosition extends Position {
|
||||
constructor (seedCounts: number[], startMove: number, turn: number) {
|
||||
super(seedCounts, startMove, turn);
|
||||
|
||||
for (var i = 0; i < seedCounts.length; i++) {
|
||||
this.config[i] = [];
|
||||
}
|
||||
}
|
||||
public config: SeedCoords[][] = [];
|
||||
|
||||
|
||||
private seedCircleRect(rect: Rectangle, seedCount: number, board: Element, seed: number, circleClick: EventListener) {
|
||||
var coords = this.config[seed];
|
||||
var sq = rect.inner(0.95).square();
|
||||
var cxo = (sq.width / 2) + sq.x;
|
||||
var cyo = (sq.height / 2) + sq.y;
|
||||
var seedNumbers = [5, 7, 9, 11];
|
||||
var ringIndex = 0;
|
||||
var ringRem = seedNumbers[ringIndex];
|
||||
var angleDelta = (2 * Math.PI) / ringRem;
|
||||
var angle = angleDelta;
|
||||
var seedLength = sq.width / (seedNumbers.length << 1);
|
||||
var crMax = sq.width / 2 - (seedLength / 2);
|
||||
var pit = createSVGInscribedCircle(sq);
|
||||
if (seed < 7) {
|
||||
pit.setAttribute("fill", "brown");
|
||||
if (circleClick != null) {
|
||||
pit.addEventListener('click', circleClick);
|
||||
}
|
||||
} else {
|
||||
pit.setAttribute("fill", "saddlebrown");
|
||||
}
|
||||
board.appendChild(pit);
|
||||
var seedsSeen = 0;
|
||||
while (seedCount > 0) {
|
||||
if (ringRem == 0) {
|
||||
ringIndex++;
|
||||
ringRem = seedNumbers[ringIndex];
|
||||
angleDelta = (2 * Math.PI) / ringRem;
|
||||
angle = angleDelta;
|
||||
}
|
||||
var tx: number;
|
||||
var ty: number;
|
||||
var tangle = angle;
|
||||
if (coords.length > seedsSeen) {
|
||||
tx = coords[seedsSeen].tx;
|
||||
ty = coords[seedsSeen].ty;
|
||||
tangle = coords[seedsSeen].angle;
|
||||
} else {
|
||||
tx = (Math.random() * crMax) - (crMax / 3);
|
||||
ty = (Math.random() * crMax) - (crMax / 3);
|
||||
coords[seedsSeen] = new SeedCoords(tx, ty, angle);
|
||||
}
|
||||
var ell = createSVGEllipsePolar(tangle, seedLength, tx, ty, cxo, cyo);
|
||||
board.appendChild(ell);
|
||||
angle += angleDelta;
|
||||
ringRem--;
|
||||
seedCount--;
|
||||
seedsSeen++;
|
||||
}
|
||||
}
|
||||
|
||||
public toCircleSVG(game: Game) {
|
||||
var seedDivisions = 14;
|
||||
var bod = document.getElementById("bod");
|
||||
var board = document.createElementNS(svgNS, "svg");
|
||||
var w = window.innerWidth - 40;
|
||||
var h = window.innerHeight - 40;
|
||||
var boardRect = new Rectangle(0, 0, w, h);
|
||||
board.setAttribute("width", w.toString());
|
||||
board.setAttribute("height", h.toString());
|
||||
var whole = createSVGRect(boardRect);
|
||||
whole.setAttribute("fill", "tan");
|
||||
board.appendChild(whole);
|
||||
//var labPlayLab=boardRect.proportionalSplitVert(20,760,20);
|
||||
//var playSurface=labPlayLab[1];
|
||||
var playSurface = boardRect;
|
||||
var storeMainStore = playSurface.proportionalSplitHoriz(8, 48, 8);
|
||||
var mainPair = storeMainStore[1].subDivideVert(2);
|
||||
var playerRects = [mainPair[0].subDivideHoriz(6),
|
||||
mainPair[1].subDivideHoriz(6)];
|
||||
// reverse top layer because storehouse on left
|
||||
for (var k = 0; k < 3; k++) {
|
||||
var temp = playerRects[0][k];
|
||||
playerRects[0][k] = playerRects[0][5 - k];
|
||||
playerRects[0][5 - k] = temp;
|
||||
}
|
||||
var storehouses = [storeMainStore[0], storeMainStore[2]];
|
||||
var playerSeeds = this.seedCounts.length >> 1;
|
||||
for (var i = 0; i < 2; i++) {
|
||||
var player = playerRects[i];
|
||||
var storehouse = storehouses[i];
|
||||
var r: Rectangle;
|
||||
for (var j = 0; j < playerSeeds; j++) {
|
||||
var seed = (i * playerSeeds) + j;
|
||||
var seedCount = this.seedCounts[seed];
|
||||
if (j == (playerSeeds - 1)) {
|
||||
r = storehouse;
|
||||
} else {
|
||||
r = player[j];
|
||||
}
|
||||
if (game != null) {
|
||||
this.seedCircleRect(r, seedCount, board, seed,
|
||||
function(seed: number) {
|
||||
return function(evt: Event) {
|
||||
game.humanMove(seed);
|
||||
}
|
||||
}(seed));
|
||||
}
|
||||
else {
|
||||
this.seedCircleRect(r, seedCount, board, seed, null);
|
||||
}
|
||||
if (seedCount == 0) {
|
||||
// clear
|
||||
this.config[seed] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
return board;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
===== TypeScript Sample: Mankala =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample implements the game logic for the Mankala board game. The following
|
||||
features of TypeScript are highlighted:
|
||||
- Multi-file compilation: The sample is compiled from several separate files
|
||||
- SVG: Geometry
|
||||
- Class inheritance: Rectangle and Square in geometry.ts
|
||||
- Command line: The game driver can be run as a command-line app using cscript
|
||||
|
||||
|
||||
=== Running ===
|
||||
tsc Driver.ts -out game.js
|
||||
cscript game.js
|
||||
|
||||
For web execution use play.htm.
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
///<reference path="Driver.ts"/>
|
||||
|
||||
module Mankala {
|
||||
export class Rectangle {
|
||||
|
||||
constructor (public x: number, public y: number,
|
||||
public width: number, public height: number) { }
|
||||
|
||||
public square() {
|
||||
var len = this.width;
|
||||
var adj = 0;
|
||||
if (len > this.height) {
|
||||
len = this.height;
|
||||
adj = (this.width - len) / 2;
|
||||
return new Square(this.x + adj, this.y, len);
|
||||
} else {
|
||||
adj = (this.height - len) / 2;
|
||||
return new Square(this.x, this.y + adj, len);
|
||||
}
|
||||
}
|
||||
|
||||
public inner(factor: number) {
|
||||
var iw = factor * this.width;
|
||||
var ih = factor * this.height;
|
||||
var ix = this.x + ((this.width - iw) / 2);
|
||||
var iy = this.y + ((this.height - ih) / 2);
|
||||
return (new Rectangle(ix, iy, iw, ih));
|
||||
}
|
||||
|
||||
public proportionalSplitHoriz(...proportionalWidths: number[]) {
|
||||
var totalPropWidth = 0;
|
||||
var i:number;
|
||||
|
||||
for (i = 0; i < proportionalWidths.length; i++) {
|
||||
totalPropWidth += proportionalWidths[i];
|
||||
}
|
||||
|
||||
var totalWidth = 0;
|
||||
var widths: number[] = [];
|
||||
for (i = 0; i < proportionalWidths.length; i++) {
|
||||
widths[i] = (proportionalWidths[i] / totalPropWidth) * this.width;
|
||||
totalWidth += widths[i];
|
||||
}
|
||||
|
||||
var extraWidth = this.width - totalWidth;
|
||||
/* Add back round-off error equally to all rectangles */
|
||||
i = 0;
|
||||
while (extraWidth > 0) {
|
||||
widths[i]++;
|
||||
extraWidth--;
|
||||
if ((++i) == widths.length) {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
var rects: Rectangle[] = [];
|
||||
var curX = this.x;
|
||||
for (i = 0; i < widths.length; i++) {
|
||||
rects[i] = new Rectangle(curX, this.y, widths[i], this.height);
|
||||
curX += widths[i];
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
|
||||
private proportionalSplitVert(...proportionalHeights: number[]): Rectangle[]{
|
||||
var totalPropHeight = 0;
|
||||
var i: number;
|
||||
|
||||
for (i = 0; i < proportionalHeights.length; i++) {
|
||||
totalPropHeight += proportionalHeights[i];
|
||||
}
|
||||
|
||||
var totalHeight = 0;
|
||||
var heights: number[] = [];
|
||||
for (i = 0; i < proportionalHeights.length; i++) {
|
||||
heights[i] = (proportionalHeights[i] / totalPropHeight) * this.height;
|
||||
totalHeight += heights[i];
|
||||
}
|
||||
|
||||
var extraHeight = this.height - totalHeight;
|
||||
/* Add back round-off error equally to all rectangles */
|
||||
i = 0;
|
||||
while (extraHeight > 0) {
|
||||
heights[i]++;
|
||||
extraHeight--;
|
||||
if ((++i) == heights.length) {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
var rects: Rectangle[] = [];
|
||||
var curY = this.y;
|
||||
for (i = 0; i < heights.length; i++) {
|
||||
rects[i] = new Rectangle(this.x, curY, this.width, heights[i]);
|
||||
curY += heights[i];
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
|
||||
public subDivideHoriz(n: number) {
|
||||
var rects: Rectangle[] = [];
|
||||
|
||||
var tileWidth = this.width / n;
|
||||
var rem = this.width % n;
|
||||
var tileX = this.x;
|
||||
for (var i = 0; i < n; i++) {
|
||||
rects[i] = new Rectangle(tileX, this.y, tileWidth, this.height);
|
||||
if (rem > 0) {
|
||||
rects[i].width++;
|
||||
rem--;
|
||||
}
|
||||
tileX += rects[i].width;
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
|
||||
public subDivideVert(n: number) {
|
||||
var rects: Rectangle[] = [];
|
||||
var tileHeight = this.height / n;
|
||||
var rem = this.height % n;
|
||||
var tileY = this.y;
|
||||
for (var i = 0; i < n; i++) {
|
||||
rects[i] = new Rectangle(this.x, tileY, this.width, tileHeight);
|
||||
if (rem > 0) {
|
||||
rects[i].height++;
|
||||
rem--;
|
||||
}
|
||||
tileY += rects[i].height;
|
||||
}
|
||||
return rects;
|
||||
}
|
||||
}
|
||||
|
||||
export class Square extends Rectangle {
|
||||
len: number;
|
||||
|
||||
constructor(x: number, y: number, len: number) {
|
||||
super(x, y, len, len);
|
||||
this.len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
.hscore {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: brown;
|
||||
}
|
||||
|
||||
.cscore {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: saddlebrown;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Mankala</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<script type="text/javascript" src="game.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="play.css"/>
|
||||
</head>
|
||||
<body id="bod" onload="Mankala.testBrowser()">
|
||||
<div class="hscore">Human: <span id="humscore">0</span></div>
|
||||
<div class="cscore">Computer: <span id="compscore">0</span></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
///<reference path='node.d.ts'/>
|
||||
import http = require("http");
|
||||
|
||||
http.createServer(function (req, res) {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.end('Hello World\n');
|
||||
}).listen(1337, '127.0.0.1');
|
||||
|
||||
console.log('Server running at http://127.0.0.1:1337/');
|
||||
@@ -0,0 +1,14 @@
|
||||
===== TypeScript Sample: Node.js =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample implements a very basic node.js application using TypeScript
|
||||
|
||||
=== Running ===
|
||||
For HttpServer
|
||||
tsc --module commonjs HttpServer.ts
|
||||
node HttpServer.js
|
||||
|
||||
For TcpServer
|
||||
tsc --module commonjs TcpServer.ts
|
||||
node TcpServer.js
|
||||
@@ -0,0 +1,9 @@
|
||||
///<reference path='node.d.ts'/>
|
||||
import net = require('net');
|
||||
|
||||
var server = net.createServer(function (socket) {
|
||||
socket.write('Echo server\r\n');
|
||||
socket.pipe(socket);
|
||||
});
|
||||
|
||||
server.listen(1337, '127.0.0.1');
|
||||
@@ -0,0 +1,9 @@
|
||||
===== TypeScript Sample: Raytracer =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample shows a raytracer implementation in TypeScript.
|
||||
|
||||
=== Running ===
|
||||
tsc raytracer.ts
|
||||
start raytracer.html
|
||||
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Raytracer</title>
|
||||
</head>
|
||||
<body >
|
||||
<script src="raytracer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,277 @@
|
||||
|
||||
class Vector {
|
||||
constructor(public x: number,
|
||||
public y: number,
|
||||
public z: number) {
|
||||
}
|
||||
static times(k: number, v: Vector) { return new Vector(k * v.x, k * v.y, k * v.z); }
|
||||
static minus(v1: Vector, v2: Vector) { return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); }
|
||||
static plus(v1: Vector, v2: Vector) { return new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z); }
|
||||
static dot(v1: Vector, v2: Vector) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; }
|
||||
static mag(v: Vector) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); }
|
||||
static norm(v: Vector) {
|
||||
var mag = Vector.mag(v);
|
||||
var div = (mag === 0) ? Infinity : 1.0 / mag;
|
||||
return Vector.times(div, v);
|
||||
}
|
||||
static cross(v1: Vector, v2: Vector) {
|
||||
return new Vector(v1.y * v2.z - v1.z * v2.y,
|
||||
v1.z * v2.x - v1.x * v2.z,
|
||||
v1.x * v2.y - v1.y * v2.x);
|
||||
}
|
||||
}
|
||||
|
||||
class Color {
|
||||
constructor(public r: number,
|
||||
public g: number,
|
||||
public b: number) {
|
||||
}
|
||||
static scale(k: number, v: Color) { return new Color(k * v.r, k * v.g, k * v.b); }
|
||||
static plus(v1: Color, v2: Color) { return new Color(v1.r + v2.r, v1.g + v2.g, v1.b + v2.b); }
|
||||
static times(v1: Color, v2: Color) { return new Color(v1.r * v2.r, v1.g * v2.g, v1.b * v2.b); }
|
||||
static white = new Color(1.0, 1.0, 1.0);
|
||||
static grey = new Color(0.5, 0.5, 0.5);
|
||||
static black = new Color(0.0, 0.0, 0.0);
|
||||
static background = Color.black;
|
||||
static defaultColor = Color.black;
|
||||
static toDrawingColor(c: Color) {
|
||||
var legalize = d => d > 1 ? 1 : d;
|
||||
return {
|
||||
r: Math.floor(legalize(c.r) * 255),
|
||||
g: Math.floor(legalize(c.g) * 255),
|
||||
b: Math.floor(legalize(c.b) * 255)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Camera {
|
||||
public forward: Vector;
|
||||
public right: Vector;
|
||||
public up: Vector;
|
||||
|
||||
constructor(public pos: Vector, lookAt: Vector) {
|
||||
var down = new Vector(0.0, -1.0, 0.0);
|
||||
this.forward = Vector.norm(Vector.minus(lookAt, this.pos));
|
||||
this.right = Vector.times(1.5, Vector.norm(Vector.cross(this.forward, down)));
|
||||
this.up = Vector.times(1.5, Vector.norm(Vector.cross(this.forward, this.right)));
|
||||
}
|
||||
}
|
||||
|
||||
interface Ray {
|
||||
start: Vector;
|
||||
dir: Vector;
|
||||
}
|
||||
|
||||
interface Intersection {
|
||||
thing: Thing;
|
||||
ray: Ray;
|
||||
dist: number;
|
||||
}
|
||||
|
||||
interface Surface {
|
||||
diffuse: (pos: Vector) => Color;
|
||||
specular: (pos: Vector) => Color;
|
||||
reflect: (pos: Vector) => number;
|
||||
roughness: number;
|
||||
}
|
||||
|
||||
interface Thing {
|
||||
intersect: (ray: Ray) => Intersection;
|
||||
normal: (pos: Vector) => Vector;
|
||||
surface: Surface;
|
||||
}
|
||||
|
||||
interface Light {
|
||||
pos: Vector;
|
||||
color: Color;
|
||||
}
|
||||
|
||||
interface Scene {
|
||||
things: Thing[];
|
||||
lights: Light[];
|
||||
camera: Camera;
|
||||
}
|
||||
|
||||
class Sphere implements Thing {
|
||||
public radius2: number;
|
||||
|
||||
constructor(public center: Vector, radius: number, public surface: Surface) {
|
||||
this.radius2 = radius * radius;
|
||||
}
|
||||
normal(pos: Vector): Vector { return Vector.norm(Vector.minus(pos, this.center)); }
|
||||
intersect(ray: Ray) {
|
||||
var eo = Vector.minus(this.center, ray.start);
|
||||
var v = Vector.dot(eo, ray.dir);
|
||||
var dist = 0;
|
||||
if (v >= 0) {
|
||||
var disc = this.radius2 - (Vector.dot(eo, eo) - v * v);
|
||||
if (disc >= 0) {
|
||||
dist = v - Math.sqrt(disc);
|
||||
}
|
||||
}
|
||||
if (dist === 0) {
|
||||
return null;
|
||||
} else {
|
||||
return { thing: this, ray: ray, dist: dist };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Plane implements Thing {
|
||||
public normal: (pos: Vector) =>Vector;
|
||||
public intersect: (ray: Ray) =>Intersection;
|
||||
constructor(norm: Vector, offset: number, public surface: Surface) {
|
||||
this.normal = function(pos: Vector) { return norm; }
|
||||
this.intersect = function(ray: Ray): Intersection {
|
||||
var denom = Vector.dot(norm, ray.dir);
|
||||
if (denom > 0) {
|
||||
return null;
|
||||
} else {
|
||||
var dist = (Vector.dot(norm, ray.start) + offset) / (-denom);
|
||||
return { thing: this, ray: ray, dist: dist };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module Surfaces {
|
||||
export var shiny: Surface = {
|
||||
diffuse: function(pos) { return Color.white; },
|
||||
specular: function(pos) { return Color.grey; },
|
||||
reflect: function(pos) { return 0.7; },
|
||||
roughness: 250
|
||||
}
|
||||
export var checkerboard: Surface = {
|
||||
diffuse: function(pos) {
|
||||
if ((Math.floor(pos.z) + Math.floor(pos.x)) % 2 !== 0) {
|
||||
return Color.white;
|
||||
} else {
|
||||
return Color.black;
|
||||
}
|
||||
},
|
||||
specular: function(pos) { return Color.white; },
|
||||
reflect: function(pos) {
|
||||
if ((Math.floor(pos.z) + Math.floor(pos.x)) % 2 !== 0) {
|
||||
return 0.1;
|
||||
} else {
|
||||
return 0.7;
|
||||
}
|
||||
},
|
||||
roughness: 150
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RayTracer {
|
||||
private maxDepth = 5;
|
||||
|
||||
private intersections(ray: Ray, scene: Scene) {
|
||||
var closest = +Infinity;
|
||||
var closestInter: Intersection = undefined;
|
||||
for (var i in scene.things) {
|
||||
var inter = scene.things[i].intersect(ray);
|
||||
if (inter != null && inter.dist < closest) {
|
||||
closestInter = inter;
|
||||
closest = inter.dist;
|
||||
}
|
||||
}
|
||||
return closestInter;
|
||||
}
|
||||
|
||||
private testRay(ray: Ray, scene: Scene) {
|
||||
var isect = this.intersections(ray, scene);
|
||||
if (isect != null) {
|
||||
return isect.dist;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private traceRay(ray: Ray, scene: Scene, depth: number): Color {
|
||||
var isect = this.intersections(ray, scene);
|
||||
if (isect === undefined) {
|
||||
return Color.background;
|
||||
} else {
|
||||
return this.shade(isect, scene, depth);
|
||||
}
|
||||
}
|
||||
|
||||
private shade(isect: Intersection, scene: Scene, depth: number) {
|
||||
var d = isect.ray.dir;
|
||||
var pos = Vector.plus(Vector.times(isect.dist, d), isect.ray.start);
|
||||
var normal = isect.thing.normal(pos);
|
||||
var reflectDir = Vector.minus(d, Vector.times(2, Vector.times(Vector.dot(normal, d), normal)));
|
||||
var naturalColor = Color.plus(Color.background,
|
||||
this.getNaturalColor(isect.thing, pos, normal, reflectDir, scene));
|
||||
var reflectedColor = (depth >= this.maxDepth) ? Color.grey : this.getReflectionColor(isect.thing, pos, normal, reflectDir, scene, depth);
|
||||
return Color.plus(naturalColor, reflectedColor);
|
||||
}
|
||||
|
||||
private getReflectionColor(thing: Thing, pos: Vector, normal: Vector, rd: Vector, scene: Scene, depth: number) {
|
||||
return Color.scale(thing.surface.reflect(pos), this.traceRay({ start: pos, dir: rd }, scene, depth + 1));
|
||||
}
|
||||
|
||||
private getNaturalColor(thing: Thing, pos: Vector, norm: Vector, rd: Vector, scene: Scene) {
|
||||
var addLight = (col, light) => {
|
||||
var ldis = Vector.minus(light.pos, pos);
|
||||
var livec = Vector.norm(ldis);
|
||||
var neatIsect = this.testRay({ start: pos, dir: livec }, scene);
|
||||
var isInShadow = (neatIsect === undefined) ? false : (neatIsect <= Vector.mag(ldis));
|
||||
if (isInShadow) {
|
||||
return col;
|
||||
} else {
|
||||
var illum = Vector.dot(livec, norm);
|
||||
var lcolor = (illum > 0) ? Color.scale(illum, light.color)
|
||||
: Color.defaultColor;
|
||||
var specular = Vector.dot(livec, Vector.norm(rd));
|
||||
var scolor = (specular > 0) ? Color.scale(Math.pow(specular, thing.surface.roughness), light.color)
|
||||
: Color.defaultColor;
|
||||
return Color.plus(col, Color.plus(Color.times(thing.surface.diffuse(pos), lcolor),
|
||||
Color.times(thing.surface.specular(pos), scolor)));
|
||||
}
|
||||
}
|
||||
return scene.lights.reduce(addLight, Color.defaultColor);
|
||||
}
|
||||
|
||||
render(scene, ctx, screenWidth, screenHeight) {
|
||||
var getPoint = (x, y, camera) => {
|
||||
var recenterX = x =>(x - (screenWidth / 2.0)) / 2.0 / screenWidth;
|
||||
var recenterY = y => - (y - (screenHeight / 2.0)) / 2.0 / screenHeight;
|
||||
return Vector.norm(Vector.plus(camera.forward, Vector.plus(Vector.times(recenterX(x), camera.right), Vector.times(recenterY(y), camera.up))));
|
||||
}
|
||||
for (var y = 0; y < screenHeight; y++) {
|
||||
for (var x = 0; x < screenWidth; x++) {
|
||||
var color = this.traceRay({ start: scene.camera.pos, dir: getPoint(x, y, scene.camera) }, scene, 0);
|
||||
var c = Color.toDrawingColor(color);
|
||||
ctx.fillStyle = "rgb(" + String(c.r) + ", " + String(c.g) + ", " + String(c.b) + ")";
|
||||
ctx.fillRect(x, y, x + 1, y + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function defaultScene(): Scene {
|
||||
return {
|
||||
things: [new Plane(new Vector(0.0, 1.0, 0.0), 0.0, Surfaces.checkerboard),
|
||||
new Sphere(new Vector(0.0, 1.0, -0.25), 1.0, Surfaces.shiny),
|
||||
new Sphere(new Vector(-1.0, 0.5, 1.5), 0.5, Surfaces.shiny)],
|
||||
lights: [{ pos: new Vector(-2.0, 2.5, 0.0), color: new Color(0.49, 0.07, 0.07) },
|
||||
{ pos: new Vector(1.5, 2.5, 1.5), color: new Color(0.07, 0.07, 0.49) },
|
||||
{ pos: new Vector(1.5, 2.5, -1.5), color: new Color(0.07, 0.49, 0.071) },
|
||||
{ pos: new Vector(0.0, 3.5, 0.0), color: new Color(0.21, 0.21, 0.35) }],
|
||||
camera: new Camera(new Vector(3.0, 2.0, 4.0), new Vector(-1.0, 0.5, 0.0))
|
||||
};
|
||||
}
|
||||
|
||||
function exec() {
|
||||
var canv = document.createElement("canvas");
|
||||
canv.width = 256;
|
||||
canv.height = 256;
|
||||
document.body.appendChild(canv);
|
||||
var ctx = canv.getContext("2d");
|
||||
var rayTracer = new RayTracer();
|
||||
return rayTracer.render(defaultScene(), ctx, 256, 256);
|
||||
}
|
||||
|
||||
exec();
|
||||
@@ -0,0 +1,11 @@
|
||||
===== TypeScript Sample: Simple =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
Simple use of classes and inheritance:
|
||||
- Classes: A base class and two subclasses
|
||||
- Super calls: Derived classes make super calls
|
||||
|
||||
|
||||
=== Running ===
|
||||
tsc animals.ts
|
||||
@@ -0,0 +1,26 @@
|
||||
class Animal {
|
||||
constructor(public name) { }
|
||||
move(meters) {
|
||||
alert(this.name + " moved " + meters + "m.");
|
||||
}
|
||||
}
|
||||
|
||||
class Snake extends Animal {
|
||||
move() {
|
||||
alert("Slithering...");
|
||||
super.move(5);
|
||||
}
|
||||
}
|
||||
|
||||
class Horse extends Animal {
|
||||
move() {
|
||||
alert("Galloping...");
|
||||
super.move(45);
|
||||
}
|
||||
}
|
||||
|
||||
var sam = new Snake("Sammy the Python")
|
||||
var tom: Animal = new Horse("Tommy the Palomino")
|
||||
|
||||
sam.move()
|
||||
tom.move(34)
|
||||
@@ -0,0 +1,57 @@
|
||||
===== TypeScript Sample: Todo MVC =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
This sample shows an implementation of the Backbone.js TODO sample derived from
|
||||
https://github.com/documentcloud/backbone/tree/master/examples/todos. The following
|
||||
TypeScript integration points are highlighted:
|
||||
- Backbone.js: Using TypeScript classes to create Backbone models and views
|
||||
- jQuery: Using jQuery for all DOM manipulation
|
||||
|
||||
|
||||
=== Running ===
|
||||
tsc js\todos.ts
|
||||
start index.html
|
||||
|
||||
=== Caveats ===
|
||||
|
||||
This sample uses local storage and will not run properly on Internet Explore if run
|
||||
from the local filesystem. Instead, host the sample from a web server (eg. IIS).
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
Microsoft grants you the right to use these script files under the Apache 2.0 license.
|
||||
Microsoft reserves all other rights to the files not expressly granted by Microsoft,
|
||||
whether by implication, estoppel or otherwise. The copyright notices and MIT licenses
|
||||
below are for informational purposes only.
|
||||
|
||||
Portions Copyright © Microsoft Corporation
|
||||
Apache 2.0 License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
file except in compliance with the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under
|
||||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
ANY KIND, either express or implied.
|
||||
|
||||
See the License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
------------------------------------------------------------------------------------------
|
||||
Provided for Informational Purposes Only
|
||||
MIT License
|
||||
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.
|
||||
|
After Width: | Height: | Size: 555 B |
@@ -0,0 +1,574 @@
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Todos.css
|
||||
Microsoft grants you the right to use these script files under the Apache 2.0 license.
|
||||
Microsoft reserves all other rights to the files not expressly granted by Microsoft,
|
||||
whether by implication, estoppel or otherwise. The copyright notices and MIT licenses
|
||||
below are for informational purposes only.
|
||||
|
||||
Portions Copyright © Microsoft Corporation
|
||||
Apache 2.0 License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
file except in compliance with the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under
|
||||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
ANY KIND, either express or implied.
|
||||
|
||||
See the License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
------------------------------------------------------------------------------------------
|
||||
Provided for Informational Purposes Only
|
||||
MIT License
|
||||
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.
|
||||
---------------------------------------------------------------------------------------
|
||||
todos.css
|
||||
https://github.com/documentcloud/backbone/blob/master/examples/todos/todos.css
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
font-size: 100%;
|
||||
font-family: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
color: black;
|
||||
background: white;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #eeeeee;
|
||||
}
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.4em;
|
||||
background: #eeeeee;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
#todoapp {
|
||||
width: 480px;
|
||||
margin: 0 auto 40px;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
|
||||
}
|
||||
#todoapp h1 {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 20px 0 30px 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#create-todo {
|
||||
position: relative;
|
||||
}
|
||||
#create-todo input {
|
||||
width: 466px;
|
||||
font-size: 24px;
|
||||
font-family: inherit;
|
||||
line-height: 1.4em;
|
||||
border: 0;
|
||||
outline: none;
|
||||
padding: 6px;
|
||||
border: 1px solid #999999;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
}
|
||||
|
||||
#create-todo span {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
width: 170px;
|
||||
left: 50%;
|
||||
margin-left: -85px;
|
||||
}
|
||||
|
||||
#todo-list {
|
||||
margin-top: 10px;
|
||||
}
|
||||
#todo-list li {
|
||||
padding: 12px 20px 11px 0;
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
line-height: 1.1em;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
}
|
||||
#todo-list li:after {
|
||||
content: "\0020";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
#todo-list li.editing {
|
||||
padding: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
#todo-list .editing .display,
|
||||
#todo-list .edit {
|
||||
display: none;
|
||||
}
|
||||
#todo-list .editing .edit {
|
||||
display: block;
|
||||
}
|
||||
#todo-list .editing input {
|
||||
width: 444px;
|
||||
font-size: 24px;
|
||||
font-family: inherit;
|
||||
margin: 0;
|
||||
line-height: 1.6em;
|
||||
border: 0;
|
||||
outline: none;
|
||||
padding: 10px 7px 0px 27px;
|
||||
border: 1px solid #999999;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
}
|
||||
#todo-list .check {
|
||||
position: relative;
|
||||
top: 9px;
|
||||
margin: 0 10px 0 7px;
|
||||
float: left;
|
||||
}
|
||||
#todo-list .done .todo-content {
|
||||
text-decoration: line-through;
|
||||
color: #777777;
|
||||
}
|
||||
#todo-list .todo-destroy {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 14px;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(destroy.png) no-repeat 0 0;
|
||||
}
|
||||
#todo-list li:hover .todo-destroy {
|
||||
display: block;
|
||||
}
|
||||
#todo-list .todo-destroy:hover {
|
||||
background-position: 0 -20px;
|
||||
}
|
||||
|
||||
#todo-stats {
|
||||
*zoom: 1;
|
||||
margin-top: 10px;
|
||||
color: #777777;
|
||||
}
|
||||
#todo-stats:after {
|
||||
content: "\0020";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
#todo-stats .todo-count {
|
||||
float: left;
|
||||
}
|
||||
#todo-stats .todo-count .number {
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
#todo-stats .todo-clear {
|
||||
float: right;
|
||||
}
|
||||
#todo-stats .todo-clear a {
|
||||
color: #777777;
|
||||
font-size: 12px;
|
||||
}
|
||||
#todo-stats .todo-clear a:visited {
|
||||
color: #777777;
|
||||
}
|
||||
#todo-stats .todo-clear a:hover {
|
||||
color: #336699;
|
||||
}
|
||||
|
||||
#instructions {
|
||||
width: 520px;
|
||||
margin: 10px auto;
|
||||
color: #777777;
|
||||
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
|
||||
text-align: center;
|
||||
}
|
||||
#instructions a {
|
||||
color: #336699;
|
||||
}
|
||||
|
||||
#credits {
|
||||
width: 520px;
|
||||
margin: 30px auto;
|
||||
color: #999;
|
||||
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
|
||||
text-align: center;
|
||||
}
|
||||
#credits a {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* François 'cahnory' Germain
|
||||
*/
|
||||
.ui-tooltip, .ui-tooltip-top, .ui-tooltip-right, .ui-tooltip-bottom, .ui-tooltip-left {
|
||||
color:#ffffff;
|
||||
cursor:normal;
|
||||
display:-moz-inline-stack;
|
||||
display:inline-block;
|
||||
font-size:12px;
|
||||
font-family:arial;
|
||||
padding:.5em 1em;
|
||||
position:relative;
|
||||
text-align:center;
|
||||
text-shadow:0 -1px 1px #111111;
|
||||
-webkit-border-top-left-radius:4px ;
|
||||
-webkit-border-top-right-radius:4px ;
|
||||
-webkit-border-bottom-right-radius:4px ;
|
||||
-webkit-border-bottom-left-radius:4px ;
|
||||
-khtml-border-top-left-radius:4px ;
|
||||
-khtml-border-top-right-radius:4px ;
|
||||
-khtml-border-bottom-right-radius:4px ;
|
||||
-khtml-border-bottom-left-radius:4px ;
|
||||
-moz-border-radius-topleft:4px ;
|
||||
-moz-border-radius-topright:4px ;
|
||||
-moz-border-radius-bottomright:4px ;
|
||||
-moz-border-radius-bottomleft:4px ;
|
||||
border-top-left-radius:4px ;
|
||||
border-top-right-radius:4px ;
|
||||
border-bottom-right-radius:4px ;
|
||||
border-bottom-left-radius:4px ;
|
||||
-o-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
|
||||
-moz-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
|
||||
-khtml-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
|
||||
-webkit-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
|
||||
box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
|
||||
background-color:#3b3b3b;
|
||||
background-image:-moz-linear-gradient(top,#555555,#222222);
|
||||
background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#555555),color-stop(1,#222222));
|
||||
filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222);
|
||||
-ms-filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222);
|
||||
}
|
||||
.ui-tooltip:after, .ui-tooltip-top:after, .ui-tooltip-right:after, .ui-tooltip-bottom:after, .ui-tooltip-left:after {
|
||||
content:"\25B8";
|
||||
display:block;
|
||||
font-size:2em;
|
||||
height:0;
|
||||
line-height:0;
|
||||
position:absolute;
|
||||
}
|
||||
.ui-tooltip:after, .ui-tooltip-bottom:after {
|
||||
color:#2a2a2a;
|
||||
bottom:0;
|
||||
left:1px;
|
||||
text-align:center;
|
||||
text-shadow:1px 0 2px #000000;
|
||||
-o-transform:rotate(90deg);
|
||||
-moz-transform:rotate(90deg);
|
||||
-khtml-transform:rotate(90deg);
|
||||
-webkit-transform:rotate(90deg);
|
||||
width:100%;
|
||||
}
|
||||
.ui-tooltip-top:after {
|
||||
bottom:auto;
|
||||
color:#4f4f4f;
|
||||
left:-2px;
|
||||
top:0;
|
||||
text-align:center;
|
||||
text-shadow:none;
|
||||
-o-transform:rotate(-90deg);
|
||||
-moz-transform:rotate(-90deg);
|
||||
-khtml-transform:rotate(-90deg);
|
||||
-webkit-transform:rotate(-90deg);
|
||||
width:100%;
|
||||
}
|
||||
.ui-tooltip-right:after {
|
||||
color:#222222;
|
||||
right:-0.375em;
|
||||
top:50%;
|
||||
margin-top:-.05em;
|
||||
text-shadow:0 1px 2px #000000;
|
||||
-o-transform:rotate(0);
|
||||
-moz-transform:rotate(0);
|
||||
-khtml-transform:rotate(0);
|
||||
-webkit-transform:rotate(0);
|
||||
}
|
||||
.ui-tooltip-left:after {
|
||||
color:#222222;
|
||||
left:-0.375em;
|
||||
top:50%;
|
||||
margin-top:.1em;
|
||||
text-shadow:0 -1px 2px #000000;
|
||||
-o-transform:rotate(180deg);
|
||||
-moz-transform:rotate(180deg);
|
||||
-khtml-transform:rotate(180deg);
|
||||
-webkit-transform:rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*the following changes require some cleanup and integration with the above.**/
|
||||
|
||||
/* line 9 */
|
||||
|
||||
|
||||
/* line 17 */
|
||||
#todoapp {
|
||||
background: white;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
|
||||
-moz-border-radius-bottomleft: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
-o-border-bottom-left-radius: 5px;
|
||||
-ms-border-bottom-left-radius: 5px;
|
||||
-khtml-border-bottom-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
-moz-border-radius-bottomright: 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-o-border-bottom-right-radius: 5px;
|
||||
-ms-border-bottom-right-radius: 5px;
|
||||
-khtml-border-bottom-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
/* line 24 */
|
||||
|
||||
|
||||
/* line 32 */
|
||||
#todoapp .content #create-todo {
|
||||
position: relative;
|
||||
}
|
||||
/* line 34 */
|
||||
#todoapp .content #create-todo input {
|
||||
font-size: 24px;
|
||||
font-family: inherit;
|
||||
line-height: 1.4em;
|
||||
border: 0;
|
||||
outline: none;
|
||||
padding: 6px;
|
||||
border: 1px solid #999999;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
}
|
||||
|
||||
/* line 47 */
|
||||
#todoapp .content #create-todo span {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
width: 170px;
|
||||
left: 50%;
|
||||
margin-left: -85px;
|
||||
}
|
||||
/* line 55 */
|
||||
#todoapp .content ul#todo-list {
|
||||
margin-top: 10px;
|
||||
}
|
||||
/* line 57 */
|
||||
#todoapp .content ul#todo-list li {
|
||||
padding: 15px 20px 15px 0;
|
||||
position: relative;
|
||||
font-size: 24px;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
*zoom: 1;
|
||||
cursor: move;
|
||||
}
|
||||
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
|
||||
#todoapp .content ul#todo-list li:after {
|
||||
content: "\0020";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
/* line 64 */
|
||||
#todoapp .content ul#todo-list li.editing {
|
||||
padding: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
/* line 67 */
|
||||
#todoapp .content ul#todo-list li.editing .todo-input {
|
||||
display: block;
|
||||
width: 466px;
|
||||
font-size: 24px;
|
||||
font-family: inherit;
|
||||
line-height: 1.4em;
|
||||
border: 0;
|
||||
outline: none;
|
||||
padding: 6px;
|
||||
border: 1px solid #999999;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
|
||||
}
|
||||
/* line 79 */
|
||||
#todoapp .content ul#todo-list li.editing .todo-content {
|
||||
display: none;
|
||||
}
|
||||
/* line 81 */
|
||||
#todoapp .content ul#todo-list li.editing .todo-check {
|
||||
display: none;
|
||||
}
|
||||
/* line 83 */
|
||||
#todoapp .content ul#todo-list li.editing .todo-destroy {
|
||||
display: none !important;
|
||||
}
|
||||
/* line 85 */
|
||||
#todoapp .content ul#todo-list li .todo-input {
|
||||
display: none;
|
||||
}
|
||||
/* line 87 */
|
||||
#todoapp .content ul#todo-list li .todo-check {
|
||||
position: relative;
|
||||
top: 6px;
|
||||
margin: 0 10px 0 7px;
|
||||
float: left;
|
||||
}
|
||||
/* line 93 */
|
||||
#todoapp .content ul#todo-list li.done .todo-content {
|
||||
text-decoration: line-through;
|
||||
color: #777777;
|
||||
}
|
||||
/* line 96 */
|
||||
#todoapp .content ul#todo-list li .todo-destroy {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 16px;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
/* line 106 */
|
||||
#todoapp .content ul#todo-list li:hover .todo-destroy {
|
||||
display: block;
|
||||
}
|
||||
/* line 109 */
|
||||
#todoapp #todo-stats {
|
||||
*zoom: 1;
|
||||
margin-top: 10px;
|
||||
color: #555555;
|
||||
-moz-border-radius-bottomleft: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
-o-border-bottom-left-radius: 5px;
|
||||
-ms-border-bottom-left-radius: 5px;
|
||||
-khtml-border-bottom-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
-moz-border-radius-bottomright: 5px;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-o-border-bottom-right-radius: 5px;
|
||||
-ms-border-bottom-right-radius: 5px;
|
||||
-khtml-border-bottom-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
background: #f4fce8;
|
||||
border-top: 1px solid #ededed;
|
||||
padding: 0 20px;
|
||||
line-height: 36px;
|
||||
}
|
||||
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
|
||||
#todoapp #todo-stats:after {
|
||||
content: "\0020";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
/* line 118 */
|
||||
#todoapp #todo-stats .todo-count {
|
||||
float: left;
|
||||
}
|
||||
/* line 120 */
|
||||
#todoapp #todo-stats .todo-count .number {
|
||||
font-weight: bold;
|
||||
color: #555555;
|
||||
}
|
||||
/* line 123 */
|
||||
#todoapp #todo-stats .todo-clear {
|
||||
float: right;
|
||||
}
|
||||
/* line 125 */
|
||||
#todoapp #todo-stats .todo-clear a {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 12px;
|
||||
-webkit-border-radius: 12px;
|
||||
-o-border-radius: 12px;
|
||||
-ms-border-radius: 12px;
|
||||
-khtml-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
color: #555555;
|
||||
font-size: 11px;
|
||||
margin-top: 8px;
|
||||
padding: 0 10px 1px;
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
|
||||
}
|
||||
/* line 136 */
|
||||
#todoapp #todo-stats .todo-clear a:hover, #todoapp #todo-stats .todo-clear a:focus {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
-o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
|
||||
}
|
||||
/* line 139 */
|
||||
#todoapp #todo-stats .todo-clear a:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<!-- ---------------------------------------------------------------------------------------
|
||||
index.html
|
||||
Microsoft grants you the right to use these script files under the Apache 2.0 license.
|
||||
Microsoft reserves all other rights to the files not expressly granted by Microsoft,
|
||||
whether by implication, estoppel or otherwise. The copyright notices and MIT licenses
|
||||
below are for informational purposes only.
|
||||
|
||||
Portions Copyright © Microsoft Corporation
|
||||
Apache 2.0 License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
file except in compliance with the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under
|
||||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
ANY KIND, either express or implied.
|
||||
|
||||
See the License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
------------------------------------------------------------------------------------------
|
||||
Provided for Informational Purposes Only
|
||||
MIT License
|
||||
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.
|
||||
---------------------------------------------------------------------------------------
|
||||
|
||||
index.html
|
||||
https://github.com/documentcloud/backbone/blob/master/examples/todos/index.html
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Backbone.js</title>
|
||||
<link href="css/todos.css" media="all" rel="stylesheet" type="text/css"/>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js"></script>
|
||||
<script src="js/todos.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Todo App Interface -->
|
||||
|
||||
<div id="todoapp">
|
||||
|
||||
<div class="title">
|
||||
<h1>Todos</h1>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div id="create-todo">
|
||||
<input id="new-todo" placeholder="What needs to be done?" type="text" />
|
||||
<span class="ui-tooltip-top" style="display:none;">Press Enter to save this task</span>
|
||||
</div>
|
||||
|
||||
<div id="todos">
|
||||
<input class="check mark-all-done" type="checkbox"/>
|
||||
<label for="check-all">Mark all as complete</label>
|
||||
<ul id="todo-list"></ul>
|
||||
</div>
|
||||
|
||||
<div id="todo-stats"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="credits">
|
||||
Created by
|
||||
<br />
|
||||
<a href="http://jgn.me/">Jérôme Gravel-Niquet</a>.
|
||||
<br />Cleanup, edits: <a href="http://addyosmani.com">Addy Osmani</a>.
|
||||
<br />TypeScript version by <a href="http://blogs.msdn.com/lukeh">Luke Hoban</a>.
|
||||
</div>
|
||||
|
||||
<!-- Templates -->
|
||||
|
||||
<script type="text/template" id="item-template">
|
||||
<div class="todo <%= done ? 'done' : '' %>">
|
||||
<div class="display">
|
||||
<input class="check" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
|
||||
<label class="todo-content"><%= content %></label>
|
||||
<span class="todo-destroy"></span>
|
||||
</div>
|
||||
<div class="edit">
|
||||
<input class="todo-input" type="text" value="<%= content %>" />
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="stats-template">
|
||||
<% if (total) { %>
|
||||
<span class="todo-count">
|
||||
<span class="number"><%= remaining %></span>
|
||||
<span class="word"><%= remaining == 1 ? 'item' : 'items' %></span> left.
|
||||
</span>
|
||||
<% } %>
|
||||
<% if (done) { %>
|
||||
<span class="todo-clear">
|
||||
<a href="#">
|
||||
Clear <span class="number-done"><%= done %></span>
|
||||
completed <span class="word-done"><%= done == 1 ? 'item' : 'items' %></span>
|
||||
</a>
|
||||
</span>
|
||||
<% } %>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,376 @@
|
||||
/* ---------------------------------------------------------------------------------------
|
||||
Todos.ts
|
||||
Microsoft grants you the right to use these script files under the Apache 2.0 license.
|
||||
Microsoft reserves all other rights to the files not expressly granted by Microsoft,
|
||||
whether by implication, estoppel or otherwise. The copyright notices and MIT licenses
|
||||
below are for informational purposes only.
|
||||
|
||||
Portions Copyright © Microsoft Corporation
|
||||
Apache 2.0 License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
file except in compliance with the License. You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under
|
||||
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
ANY KIND, either express or implied.
|
||||
|
||||
See the License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
------------------------------------------------------------------------------------------
|
||||
Provided for Informational Purposes Only
|
||||
MIT License
|
||||
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.
|
||||
--------------------------------------------------------------------------------------- */
|
||||
// Todos.js
|
||||
// https://github.com/documentcloud/backbone/blob/master/examples/todos/todos.js
|
||||
|
||||
// An example Backbone application contributed by
|
||||
// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses a simple
|
||||
// [LocalStorage adapter](backbone-localstorage.js)
|
||||
// to persist Backbone models within your browser.
|
||||
|
||||
declare module Backbone {
|
||||
export class Model {
|
||||
constructor (attr? , opts? );
|
||||
get(name: string): any;
|
||||
set(name: string, val: any): void;
|
||||
set(obj: any): void;
|
||||
save(attr? , opts? ): void;
|
||||
destroy(): void;
|
||||
bind(ev: string, f: Function, ctx?: any): void;
|
||||
toJSON(): any;
|
||||
}
|
||||
export class Collection<T> {
|
||||
constructor (models? , opts? );
|
||||
bind(ev: string, f: Function, ctx?: any): void;
|
||||
length: number;
|
||||
create(attrs, opts? ): any;
|
||||
each(f: (elem: T) => void ): void;
|
||||
fetch(opts?: any): void;
|
||||
last(): T;
|
||||
last(n: number): T[];
|
||||
filter(f: (elem: T) => boolean): T[];
|
||||
without(...values: T[]): T[];
|
||||
}
|
||||
export class View {
|
||||
constructor (options? );
|
||||
$(selector: string): JQuery;
|
||||
el: HTMLElement;
|
||||
$el: JQuery;
|
||||
model: Model;
|
||||
remove(): void;
|
||||
delegateEvents: any;
|
||||
make(tagName: string, attrs? , opts? ): View;
|
||||
setElement(element: HTMLElement, delegate?: boolean): void;
|
||||
setElement(element: JQuery, delegate?: boolean): void;
|
||||
tagName: string;
|
||||
events: any;
|
||||
|
||||
static extend: any;
|
||||
}
|
||||
}
|
||||
interface JQuery {
|
||||
fadeIn(): JQuery;
|
||||
fadeOut(): JQuery;
|
||||
focus(): JQuery;
|
||||
html(): string;
|
||||
html(val: string): JQuery;
|
||||
show(): JQuery;
|
||||
addClass(className: string): JQuery;
|
||||
removeClass(className: string): JQuery;
|
||||
append(el: HTMLElement): JQuery;
|
||||
val(): string;
|
||||
val(value: string): JQuery;
|
||||
attr(attrName: string): string;
|
||||
}
|
||||
declare var $: {
|
||||
(el: HTMLElement): JQuery;
|
||||
(selector: string): JQuery;
|
||||
(readyCallback: () => void ): JQuery;
|
||||
};
|
||||
declare var _: {
|
||||
each<T, U>(arr: T[], f: (elem: T) => U): U[];
|
||||
delay(f: Function, wait: number, ...arguments: any[]): number;
|
||||
template(template: string): (model: any) => string;
|
||||
bindAll(object: any, ...methodNames: string[]): void;
|
||||
};
|
||||
declare var Store: any;
|
||||
|
||||
|
||||
// Todo Model
|
||||
// ----------
|
||||
|
||||
// Our basic **Todo** model has `content`, `order`, and `done` attributes.
|
||||
class Todo extends Backbone.Model {
|
||||
|
||||
// Default attributes for the todo.
|
||||
defaults() {
|
||||
return {
|
||||
content: "empty todo...",
|
||||
done: false
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that each todo created has `content`.
|
||||
initialize() {
|
||||
if (!this.get("content")) {
|
||||
this.set({ "content": this.defaults().content });
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle the `done` state of this todo item.
|
||||
toggle() {
|
||||
this.save({ done: !this.get("done") });
|
||||
}
|
||||
|
||||
// Remove this Todo from *localStorage* and delete its view.
|
||||
clear() {
|
||||
this.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Todo Collection
|
||||
// ---------------
|
||||
|
||||
// The collection of todos is backed by *localStorage* instead of a remote
|
||||
// server.
|
||||
class TodoList extends Backbone.Collection<Todo> {
|
||||
|
||||
// Reference to this collection's model.
|
||||
model = Todo;
|
||||
|
||||
// Save all of the todo items under the `"todos"` namespace.
|
||||
localStorage = new Store("todos-backbone");
|
||||
|
||||
// Filter down the list of all todo items that are finished.
|
||||
done() {
|
||||
return this.filter(todo => todo.get('done'));
|
||||
}
|
||||
|
||||
// Filter down the list to only todo items that are still not finished.
|
||||
remaining() {
|
||||
return this.without.apply(this, this.done());
|
||||
}
|
||||
|
||||
// We keep the Todos in sequential order, despite being saved by unordered
|
||||
// GUID in the database. This generates the next order number for new items.
|
||||
nextOrder() {
|
||||
if (!this.length) return 1;
|
||||
return this.last().get('order') + 1;
|
||||
}
|
||||
|
||||
// Todos are sorted by their original insertion order.
|
||||
comparator(todo: Todo) {
|
||||
return todo.get('order');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create our global collection of **Todos**.
|
||||
var Todos = new TodoList();
|
||||
|
||||
// Todo Item View
|
||||
// --------------
|
||||
|
||||
// The DOM element for a todo item...
|
||||
class TodoView extends Backbone.View {
|
||||
|
||||
// The TodoView listens for changes to its model, re-rendering. Since there's
|
||||
// a one-to-one correspondence between a **Todo** and a **TodoView** in this
|
||||
// app, we set a direct reference on the model for convenience.
|
||||
template: (data: any) => string;
|
||||
|
||||
// A TodoView model must be a Todo, redeclare with specific type
|
||||
model: Todo;
|
||||
input: JQuery;
|
||||
|
||||
constructor (options? ) {
|
||||
//... is a list tag.
|
||||
this.tagName = "li";
|
||||
|
||||
// The DOM events specific to an item.
|
||||
this.events = {
|
||||
"click .check": "toggleDone",
|
||||
"dblclick label.todo-content": "edit",
|
||||
"click span.todo-destroy": "clear",
|
||||
"keypress .todo-input": "updateOnEnter",
|
||||
"blur .todo-input": "close"
|
||||
};
|
||||
|
||||
super(options);
|
||||
|
||||
// Cache the template function for a single item.
|
||||
this.template = _.template($('#item-template').html());
|
||||
|
||||
_.bindAll(this, 'render', 'close', 'remove');
|
||||
this.model.bind('change', this.render);
|
||||
this.model.bind('destroy', this.remove);
|
||||
}
|
||||
|
||||
// Re-render the contents of the todo item.
|
||||
render() {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
this.input = this.$('.todo-input');
|
||||
return this;
|
||||
}
|
||||
|
||||
// Toggle the `"done"` state of the model.
|
||||
toggleDone() {
|
||||
this.model.toggle();
|
||||
}
|
||||
|
||||
// Switch this view into `"editing"` mode, displaying the input field.
|
||||
edit() {
|
||||
this.$el.addClass("editing");
|
||||
this.input.focus();
|
||||
}
|
||||
|
||||
// Close the `"editing"` mode, saving changes to the todo.
|
||||
close() {
|
||||
this.model.save({ content: this.input.val() });
|
||||
this.$el.removeClass("editing");
|
||||
}
|
||||
|
||||
// If you hit `enter`, we're through editing the item.
|
||||
updateOnEnter(e) {
|
||||
if (e.keyCode == 13) close();
|
||||
}
|
||||
|
||||
// Remove the item, destroy the model.
|
||||
clear() {
|
||||
this.model.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The Application
|
||||
// ---------------
|
||||
|
||||
// Our overall **AppView** is the top-level piece of UI.
|
||||
class AppView extends Backbone.View {
|
||||
|
||||
// Delegated events for creating new items, and clearing completed ones.
|
||||
events = {
|
||||
"keypress #new-todo": "createOnEnter",
|
||||
"keyup #new-todo": "showTooltip",
|
||||
"click .todo-clear a": "clearCompleted",
|
||||
"click .mark-all-done": "toggleAllComplete"
|
||||
};
|
||||
|
||||
input: JQuery;
|
||||
allCheckbox: HTMLInputElement;
|
||||
statsTemplate: (params: any) => string;
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
// Instead of generating a new element, bind to the existing skeleton of
|
||||
// the App already present in the HTML.
|
||||
this.setElement($("#todoapp"), true);
|
||||
|
||||
// At initialization we bind to the relevant events on the `Todos`
|
||||
// collection, when items are added or changed. Kick things off by
|
||||
// loading any preexisting todos that might be saved in *localStorage*.
|
||||
_.bindAll(this, 'addOne', 'addAll', 'render', 'toggleAllComplete');
|
||||
|
||||
this.input = this.$("#new-todo");
|
||||
this.allCheckbox = this.$(".mark-all-done")[0];
|
||||
this.statsTemplate = _.template($('#stats-template').html());
|
||||
|
||||
Todos.bind('add', this.addOne);
|
||||
Todos.bind('reset', this.addAll);
|
||||
Todos.bind('all', this.render);
|
||||
|
||||
Todos.fetch();
|
||||
}
|
||||
|
||||
// Re-rendering the App just means refreshing the statistics -- the rest
|
||||
// of the app doesn't change.
|
||||
render() {
|
||||
var done = Todos.done().length;
|
||||
var remaining = Todos.remaining().length;
|
||||
|
||||
this.$('#todo-stats').html(this.statsTemplate({
|
||||
total: Todos.length,
|
||||
done: done,
|
||||
remaining: remaining
|
||||
}));
|
||||
|
||||
this.allCheckbox.checked = !remaining;
|
||||
}
|
||||
|
||||
// Add a single todo item to the list by creating a view for it, and
|
||||
// appending its element to the `<ul>`.
|
||||
addOne(todo) {
|
||||
var view = new TodoView({ model: todo });
|
||||
this.$("#todo-list").append(view.render().el);
|
||||
}
|
||||
|
||||
// Add all items in the **Todos** collection at once.
|
||||
addAll() {
|
||||
Todos.each(this.addOne);
|
||||
}
|
||||
|
||||
// Generate the attributes for a new Todo item.
|
||||
newAttributes() {
|
||||
return {
|
||||
content: this.input.val(),
|
||||
order: Todos.nextOrder(),
|
||||
done: false
|
||||
};
|
||||
}
|
||||
|
||||
// If you hit return in the main input field, create new **Todo** model,
|
||||
// persisting it to *localStorage*.
|
||||
createOnEnter(e) {
|
||||
if (e.keyCode != 13) return;
|
||||
Todos.create(this.newAttributes());
|
||||
this.input.val('');
|
||||
}
|
||||
|
||||
// Clear all done todo items, destroying their models.
|
||||
clearCompleted() {
|
||||
_.each(Todos.done(), todo => todo.clear());
|
||||
return false;
|
||||
}
|
||||
|
||||
tooltipTimeout: number = null;
|
||||
// Lazily show the tooltip that tells you to press `enter` to save
|
||||
// a new todo item, after one second.
|
||||
showTooltip(e) {
|
||||
var tooltip = $(".ui-tooltip-top");
|
||||
var val = this.input.val();
|
||||
tooltip.fadeOut();
|
||||
if (this.tooltipTimeout) clearTimeout(this.tooltipTimeout);
|
||||
if (val == '' || val == this.input.attr('placeholder')) return;
|
||||
this.tooltipTimeout = _.delay(() => tooltip.show().fadeIn(), 1000);
|
||||
}
|
||||
|
||||
toggleAllComplete() {
|
||||
var done = this.allCheckbox.checked;
|
||||
Todos.each(todo => todo.save({ 'done': done }));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Load the application once the DOM is ready, using `jQuery.ready`:
|
||||
$(() => {
|
||||
// Finally, we kick things off by creating the **App**.
|
||||
new AppView();
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
===== TypeScript Sample: Warship Combat =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
The classic grid-based warship combat game
|
||||
- Use of the jQuery and jQuery UI wrappers
|
||||
- Use of object-oriented techniques
|
||||
|
||||
|
||||
=== Running ===
|
||||
tsc --target ES5 warship.ts
|
||||
start default.html
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
|
||||
<script src="http://code.jquery.com/jquery-1.8.0.js"></script>
|
||||
<script src="http://code.jquery.com/ui/1.8.23/jquery-ui.js"></script>
|
||||
<link href="styles.css" rel="stylesheet" />
|
||||
<script src="warship.js"></script>
|
||||
<title>Warship Combat</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<div id="banner" class="quadrant">Warship Combat!</div>
|
||||
<div class="quadrant"><div id="status"></div></div>
|
||||
</div>
|
||||
<div id="boards">
|
||||
<div id="computerBoard" class="quadrant board"></div>
|
||||
<div id="playerBoard" class="quadrant board"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,703 @@
|
||||
/* *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
// Typing for the jQuery library, version 1.10
|
||||
|
||||
/*
|
||||
Interface for the AJAX setting that will configure the AJAX request
|
||||
*/
|
||||
interface JQueryAjaxSettings {
|
||||
accepts?: any;
|
||||
async?: boolean;
|
||||
beforeSend? (jqXHR: JQueryXHR, settings: JQueryAjaxSettings): any;
|
||||
cache?: boolean;
|
||||
complete? (jqXHR: JQueryXHR, textStatus: string): any;
|
||||
contents?: { [key: string]: any; };
|
||||
contentType?: any;
|
||||
context?: any;
|
||||
converters?: { [key: string]: any; };
|
||||
crossDomain?: boolean;
|
||||
data?: any;
|
||||
dataFilter? (data: any, ty: any): any;
|
||||
dataType?: string;
|
||||
error? (jqXHR: JQueryXHR, textStatus: string, errorThrow: string): any;
|
||||
global?: boolean;
|
||||
headers?: { [key: string]: any; };
|
||||
ifModified?: boolean;
|
||||
isLocal?: boolean;
|
||||
jsonp?: string;
|
||||
jsonpCallback?: any;
|
||||
mimeType?: string;
|
||||
password?: string;
|
||||
processData?: boolean;
|
||||
scriptCharset?: string;
|
||||
statusCode?: { [key: string]: any; };
|
||||
success? (data: any, textStatus: string, jqXHR: JQueryXHR): any;
|
||||
timeout?: number;
|
||||
traditional?: boolean;
|
||||
type?: string;
|
||||
url?: string;
|
||||
username?: string;
|
||||
xhr?: any;
|
||||
xhrFields?: { [key: string]: any; };
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the jqXHR object
|
||||
*/
|
||||
interface JQueryXHR extends XMLHttpRequest {
|
||||
overrideMimeType(): any;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the JQuery callback
|
||||
*/
|
||||
interface JQueryCallback {
|
||||
add(...callbacks: any[]): any;
|
||||
disable(): any;
|
||||
empty(): any;
|
||||
fire(...arguments: any[]): any;
|
||||
fired(): boolean;
|
||||
fireWith(context: any, ...args: any[]): any;
|
||||
has(callback: any): boolean;
|
||||
lock(): any;
|
||||
locked(): boolean;
|
||||
removed(...callbacks: any[]): any;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the JQuery promise, part of callbacks
|
||||
*/
|
||||
interface JQueryPromise {
|
||||
always(...alwaysCallbacks: any[]): JQueryDeferred;
|
||||
done(...doneCallbacks: any[]): JQueryDeferred;
|
||||
fail(...failCallbacks: any[]): JQueryDeferred;
|
||||
pipe(doneFilter?: (x: any) => any, failFilter?: (x: any) => any, progressFilter?: (x: any) => any): JQueryPromise;
|
||||
then(doneCallbacks: any, failCallbacks: any, progressCallbacks?: any): JQueryDeferred;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface for the JQuery deferred, part of callbacks
|
||||
*/
|
||||
interface JQueryDeferred extends JQueryPromise {
|
||||
notify(...args: any[]): JQueryDeferred;
|
||||
notifyWith(context: any, ...args: any[]): JQueryDeferred;
|
||||
|
||||
progress(...progressCallbacks: any[]): JQueryDeferred;
|
||||
reject(...args: any[]): JQueryDeferred;
|
||||
rejectWith(context: any, ...args: any[]): JQueryDeferred;
|
||||
resolve(...args: any[]): JQueryDeferred;
|
||||
resolveWith(context: any, ...args: any[]): JQueryDeferred;
|
||||
state(): string;
|
||||
then(doneCallbacks: any, failCallbacks?: any, progressCallbacks?: any): JQueryDeferred;
|
||||
}
|
||||
|
||||
/*
|
||||
Interface of the JQuery extension of the W3C event object
|
||||
*/
|
||||
interface JQueryEventObject extends Event {
|
||||
data: any;
|
||||
delegateTarget: Element;
|
||||
isDefaultPrevented(): boolean;
|
||||
isImmediatePropogationStopped(): boolean;
|
||||
isPropogationStopped(): boolean;
|
||||
namespace: string;
|
||||
preventDefault(): any;
|
||||
relatedTarget: Element;
|
||||
result: any;
|
||||
stopImmediatePropagation(): void;
|
||||
stopPropagation(): void;
|
||||
pageX: number;
|
||||
pageY: number;
|
||||
which: number;
|
||||
metaKey: any;
|
||||
}
|
||||
|
||||
/*
|
||||
Collection of properties of the current browser
|
||||
*/
|
||||
interface JQueryBrowserInfo {
|
||||
safari: boolean;
|
||||
opera: boolean;
|
||||
msie: boolean;
|
||||
mozilla: boolean;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface JQuerySupport {
|
||||
ajax?: boolean;
|
||||
boxModel?: boolean;
|
||||
changeBubbles?: boolean;
|
||||
checkClone?: boolean;
|
||||
checkOn?: boolean;
|
||||
cors?: boolean;
|
||||
cssFloat?: boolean;
|
||||
hrefNormalized?: boolean;
|
||||
htmlSerialize?: boolean;
|
||||
leadingWhitespace?: boolean;
|
||||
noCloneChecked?: boolean;
|
||||
noCloneEvent?: boolean;
|
||||
opacity?: boolean;
|
||||
optDisabled?: boolean;
|
||||
optSelected?: boolean;
|
||||
scriptEval? (): boolean;
|
||||
style?: boolean;
|
||||
submitBubbles?: boolean;
|
||||
tbody?: boolean;
|
||||
}
|
||||
|
||||
interface JQueryTransport {
|
||||
send(headers: { [index: string]: string; }, completeCallback: (status: number, statusText: string, responses: { [dataType: string]: any; }, headers: string) => void): void;
|
||||
abort(): void;
|
||||
}
|
||||
|
||||
/*
|
||||
Static members of jQuery (those on $ and jQuery themselves)
|
||||
*/
|
||||
interface JQueryStatic {
|
||||
|
||||
// AJAX
|
||||
ajax(settings: JQueryAjaxSettings): JQueryXHR;
|
||||
ajax(url: string, settings: JQueryAjaxSettings): JQueryXHR;
|
||||
|
||||
ajaxPrefilter(handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
|
||||
ajaxPrefilter(dataTypes: string, handler: (opts: any, originalOpts: any, jqXHR: JQueryXHR) => any): any;
|
||||
|
||||
ajaxSetup(options: any): void;
|
||||
ajaxTransport(dataType: string, handler: (options: JQueryAjaxSettings, originalOptions: JQueryAjaxSettings, jqXHR: JQueryXHR) => JQueryTransport): void;
|
||||
|
||||
get(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
|
||||
getJSON(url: string, data?: any, success?: any): JQueryXHR;
|
||||
getScript(url: string, success?: any): JQueryXHR;
|
||||
|
||||
param(obj: any): string;
|
||||
param(obj: any, traditional: boolean): string;
|
||||
|
||||
post(url: string, data?: any, success?: any, dataType?: any): JQueryXHR;
|
||||
|
||||
// Callbacks
|
||||
Callbacks(flags: any): JQueryCallback;
|
||||
|
||||
// Core
|
||||
holdReady(hold: boolean): any;
|
||||
|
||||
(): JQuery;
|
||||
(selector: string, context?: any): JQuery;
|
||||
(element: Element): JQuery;
|
||||
(elementArray: Element[]): JQuery;
|
||||
(object: JQuery): JQuery;
|
||||
(func: Function): JQuery;
|
||||
(object: {}): JQuery;
|
||||
|
||||
noConflict(removeAll?: boolean): Object;
|
||||
|
||||
when(...deferreds: any[]): JQueryPromise;
|
||||
|
||||
// CSS
|
||||
css(e: any, propertyName: string, value?: any): any;
|
||||
css(e: any, propertyName: any, value?: any): any;
|
||||
cssHooks: { [key: string]: any; };
|
||||
|
||||
// Data
|
||||
data(element: Element, key: string, value: any): Object;
|
||||
|
||||
dequeue(element: Element, queueName?: string): any;
|
||||
|
||||
hasData(element: Element): boolean;
|
||||
|
||||
queue(element: Element, queueName?: string): any[];
|
||||
queue(element: Element, queueName: string, newQueueOrCallback: any): JQuery;
|
||||
|
||||
removeData(element: Element, name?: string): JQuery;
|
||||
|
||||
// Deferred
|
||||
Deferred(beforeStart?: (deferred: JQueryDeferred) => any): JQueryDeferred;
|
||||
|
||||
// Effects
|
||||
fx: { tick: () => void; interval: number; stop: () => void; speeds: { slow: number; fast: number; }; off: boolean; step: any; };
|
||||
|
||||
// Events
|
||||
proxy(func: Function, context: any): any;
|
||||
proxy(context: any, name: string): any;
|
||||
|
||||
// Internals
|
||||
error(message: any): void;
|
||||
|
||||
// Miscellaneous
|
||||
expr: any;
|
||||
fn: any; //TODO: Decide how we want to type this
|
||||
isReady: boolean;
|
||||
|
||||
// Properties
|
||||
browser: JQueryBrowserInfo;
|
||||
support: JQuerySupport;
|
||||
|
||||
// Utilities
|
||||
contains(container: Element, contained: Element): boolean;
|
||||
|
||||
each(collection: any, callback: (indexInArray: any, valueOfElement: any) => any): any;
|
||||
|
||||
extend(deep: boolean, target: any, ...objs: any[]): Object;
|
||||
extend(target: any, ...objs: any[]): Object;
|
||||
|
||||
globalEval(code: string): any;
|
||||
|
||||
grep(array: any[], func: any, invert: boolean): any[];
|
||||
|
||||
inArray(value: any, array: any[], fromIndex?: number): number;
|
||||
|
||||
isArray(obj: any): boolean;
|
||||
isEmptyObject(obj: any): boolean;
|
||||
isFunction(obj: any): boolean;
|
||||
isNumeric(value: any): boolean;
|
||||
isPlainObject(obj: any): boolean;
|
||||
isWindow(obj: any): boolean;
|
||||
isXMLDoc(node: Node): boolean;
|
||||
|
||||
makeArray(obj: any): any[];
|
||||
|
||||
map(array: any[], callback: (elementOfArray: any, indexInArray: any) => any): any[];
|
||||
|
||||
merge(first: any[], second: any[]): any[];
|
||||
|
||||
noop(): any;
|
||||
|
||||
now(): number;
|
||||
|
||||
parseHTML(data: string, context?: Element, keepScripts?: boolean): any[];
|
||||
parseJSON(json: string): any;
|
||||
|
||||
//FIXME: This should return an XMLDocument
|
||||
parseXML(data: string): any;
|
||||
|
||||
queue(element: Element, queueName: string, newQueue: any[]): JQuery;
|
||||
|
||||
trim(str: string): string;
|
||||
|
||||
type(obj: any): string;
|
||||
|
||||
unique(arr: any[]): any[];
|
||||
}
|
||||
|
||||
/*
|
||||
The jQuery instance members
|
||||
*/
|
||||
interface JQuery {
|
||||
// AJAX
|
||||
ajaxComplete(handler: any): JQuery;
|
||||
ajaxError(handler: (evt: any, xhr: any, opts: any) => any): JQuery;
|
||||
ajaxSend(handler: (evt: any, xhr: any, opts: any) => any): JQuery;
|
||||
ajaxStart(handler: () => any): JQuery;
|
||||
ajaxStop(handler: () => any): JQuery;
|
||||
ajaxSuccess(handler: (evt: any, xml: any, opts: any) => any): JQuery;
|
||||
|
||||
serialize(): string;
|
||||
serializeArray(): any[];
|
||||
|
||||
// Attributes
|
||||
addClass(classNames: string): JQuery;
|
||||
addClass(func: (index: any, currentClass: any) => JQuery): JQuery;
|
||||
|
||||
attr(attributeName: string): string;
|
||||
attr(attributeName: string, func: (index: any, attr: any) => any): JQuery;
|
||||
attr(attributeName: string, value: any): JQuery;
|
||||
attr(map: { [key: string]: any; }): JQuery;
|
||||
|
||||
hasClass(className: string): boolean;
|
||||
|
||||
html(): string;
|
||||
html(htmlString: string): JQuery;
|
||||
|
||||
prop(propertyName: string): any;
|
||||
prop(propertyName: string, func: (index: any, oldPropertyValue: any) => any): JQuery;
|
||||
prop(propertyName: string, value: any): JQuery;
|
||||
prop(map: any): JQuery;
|
||||
|
||||
removeAttr(attributeName: any): JQuery;
|
||||
|
||||
removeClass(func: (index: any, cls: any) => any): JQuery;
|
||||
removeClass(className?: string): JQuery;
|
||||
|
||||
removeProp(propertyName: any): JQuery;
|
||||
|
||||
toggleClass(func: (index: any, cls: any, swtch: any) => any): JQuery;
|
||||
toggleClass(swtch?: boolean): JQuery;
|
||||
toggleClass(className: any, swtch?: boolean): JQuery;
|
||||
|
||||
val(): any;
|
||||
val(value: string[]): JQuery;
|
||||
val(value: string): JQuery;
|
||||
val(func: (index: any, value: any) => any): JQuery;
|
||||
|
||||
// CSS
|
||||
css(propertyNames: any[]): string;
|
||||
css(propertyName: string): string;
|
||||
css(propertyName: string, value: any): JQuery;
|
||||
css(propertyName: any, value?: any): JQuery;
|
||||
|
||||
height(): number;
|
||||
height(value: number): JQuery;
|
||||
height(func: (index: any, height: any) => any): JQuery;
|
||||
|
||||
innerHeight(): number;
|
||||
innerWidth(): number;
|
||||
|
||||
offset(): { top: number; left: number; };
|
||||
offset(func: (index: any, coords: any) => any): JQuery;
|
||||
offset(coordinates: any): JQuery;
|
||||
|
||||
outerHeight(includeMargin?: boolean): number;
|
||||
outerWidth(includeMargin?: boolean): number;
|
||||
|
||||
position(): { top: number; left: number; };
|
||||
|
||||
scrollLeft(): number;
|
||||
scrollLeft(value: number): JQuery;
|
||||
|
||||
scrollTop(): number;
|
||||
scrollTop(value: number): JQuery;
|
||||
|
||||
width(): number;
|
||||
width(value: number): JQuery;
|
||||
width(func: (index: any, height: any) => any): JQuery;
|
||||
|
||||
// Data
|
||||
clearQueue(queueName?: string): JQuery;
|
||||
|
||||
data(key: string, value: any): JQuery;
|
||||
data(obj: { [key: string]: any; }): JQuery;
|
||||
data(key?: string): any;
|
||||
|
||||
dequeue(queueName?: string): JQuery;
|
||||
|
||||
queue(queueName?: string): any[];
|
||||
queue(queueName: string, newQueueOrCallback: any): JQuery;
|
||||
queue(newQueueOrCallback: any): JQuery;
|
||||
|
||||
removeData(nameOrList?: any): JQuery;
|
||||
|
||||
// Deferred
|
||||
promise(type?: any, target?: any): JQueryPromise;
|
||||
|
||||
// Effects
|
||||
animate(properties: any, options: { duration?: any; easing?: string; complete?: Function; step?: Function; queue?: boolean; specialEasing?: any; }): JQuery;
|
||||
animate(properties: any, duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
animate(properties: any, duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
animate(properties: any, duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
|
||||
delay(duration: number, queueName?: string): JQuery;
|
||||
|
||||
fadeIn(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeIn(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeIn(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
fadeIn(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
|
||||
fadeOut(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeOut(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeOut(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
fadeOut(duration?: any, complete?: any): JQuery;
|
||||
|
||||
fadeTo(duration: any, opacity: number, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeTo(duration: any, opacity: number, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeTo(duration: any, opacity: number, easing?: string, complete?: Function): JQuery;
|
||||
fadeTo(duration: any, opacity: number, complete?: Function): JQuery;
|
||||
|
||||
fadeToggle(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
fadeToggle(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
fadeToggle(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
|
||||
finish(queue?: string): JQuery;
|
||||
|
||||
hide(duration?: any, easing?: "linear", callback?: Function): JQuery;
|
||||
hide(duration?: any, easing?: "swing", callback?: Function): JQuery;
|
||||
hide(duration?: any, easing?: string, callback?: Function): JQuery;
|
||||
hide(duration?: any, callback?: Function): JQuery;
|
||||
|
||||
show(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
show(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
show(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
show(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
slideDown(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
slideDown(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
slideDown(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
slideDown(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
slideToggle(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
slideToggle(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
slideToggle(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
slideToggle(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
slideUp(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
slideUp(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
slideUp(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
slideUp(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
stop(clearQueue?: boolean, jumpToEnd?: boolean): JQuery;
|
||||
stop(queue?: any, clearQueue?: boolean, jumpToEnd?: boolean): JQuery;
|
||||
|
||||
toggle(showOrHide: boolean): JQuery;
|
||||
toggle(duration?: any, easing?: "linear", complete?: Function): JQuery;
|
||||
toggle(duration?: any, easing?: "swing", complete?: Function): JQuery;
|
||||
toggle(duration?: any, easing?: string, complete?: Function): JQuery;
|
||||
toggle(duration?: any, complete?: Function): JQuery;
|
||||
|
||||
// Events
|
||||
bind(eventType: string, preventBubble: boolean): JQuery;
|
||||
bind(eventType: string, eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
bind(eventType: string, eventData: any, preventBubble: boolean): JQuery;
|
||||
bind(...events: any[]): JQuery;
|
||||
|
||||
blur(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
blur(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
change(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
change(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
click(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
click(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
dblclick(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
dblclick(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
delegate(selector: any, eventType: string, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
focus(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
focus(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
focusin(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
focusin(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
focusout(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
focusout(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
hover(handlerIn: (eventObject: JQueryEventObject) => any, handlerOut: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
hover(handlerInOut: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
keydown(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
keydown(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
keypress(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
keypress(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
keyup(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
keyup(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mousedown(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mousedown(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseevent(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseevent(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseenter(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseenter(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseleave(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseleave(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mousemove(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mousemove(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseout(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseout(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseover(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseover(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
mouseup(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
mouseup(eventData: any, handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
off(events?: string, selector?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
off(eventsMap: { [key: string]: any; }, selector?: any): JQuery;
|
||||
|
||||
on(events: string, selector?: any, data?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
on(eventsMap: { [key: string]: any; }, selector?: any, data?: any): JQuery;
|
||||
|
||||
one(events: string, selector?: any, data?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
one(eventsMap: { [key: string]: any; }, selector?: any, data?: any): JQuery;
|
||||
|
||||
ready(handler: any): JQuery;
|
||||
|
||||
resize(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
resize(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
scroll(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
scroll(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
select(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
select(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
submit(handler: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
submit(eventData?: any, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
|
||||
trigger(eventType: string, ...extraParameters: any[]): JQuery;
|
||||
trigger(event: JQueryEventObject): JQuery;
|
||||
|
||||
triggerHandler(eventType: string, ...extraParameters: any[]): Object;
|
||||
|
||||
unbind(eventType?: string, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
unbind(eventType: string, fls: boolean): JQuery;
|
||||
unbind(evt: any): JQuery;
|
||||
|
||||
undelegate(): JQuery;
|
||||
undelegate(selector: any, eventType: string, handler?: (eventObject: JQueryEventObject) => any): JQuery;
|
||||
undelegate(selector: any, events: any): JQuery;
|
||||
undelegate(namespace: string): JQuery;
|
||||
|
||||
// Internals
|
||||
context: Element;
|
||||
jquery: string;
|
||||
pushStack(elements: any[]): JQuery;
|
||||
pushStack(elements: any[], name: any, arguments: any): JQuery;
|
||||
|
||||
// Manipulation
|
||||
after(func: (index: any) => any): JQuery;
|
||||
after(...content: any[]): JQuery;
|
||||
|
||||
append(func: (index: any, html: any) => any): JQuery;
|
||||
append(...content: any[]): JQuery;
|
||||
|
||||
appendTo(target: any): JQuery;
|
||||
|
||||
before(func: (index: any) => any): JQuery;
|
||||
before(...content: any[]): JQuery;
|
||||
|
||||
clone(withDataAndEvents?: boolean, deepWithDataAndEvents?: boolean): JQuery;
|
||||
|
||||
detach(selector?: any): JQuery;
|
||||
|
||||
empty(): JQuery;
|
||||
|
||||
insertAfter(target: any): JQuery;
|
||||
insertBefore(target: any): JQuery;
|
||||
|
||||
prepend(func: (index: any, html: any) => any): JQuery;
|
||||
prepend(...content: any[]): JQuery;
|
||||
|
||||
prependTo(target: any): JQuery;
|
||||
|
||||
remove(selector?: any): JQuery;
|
||||
|
||||
replaceAll(target: any): JQuery;
|
||||
|
||||
replaceWith(func: any): JQuery;
|
||||
|
||||
text(textString: string): JQuery;
|
||||
text(): string;
|
||||
|
||||
toArray(): any[];
|
||||
|
||||
unwrap(): JQuery;
|
||||
|
||||
wrap(func: (index: any) => any): JQuery;
|
||||
wrap(wrappingElement: any): JQuery;
|
||||
|
||||
wrapAll(wrappingElement: any): JQuery;
|
||||
|
||||
wrapInner(func: (index: any) => any): JQuery;
|
||||
wrapInner(wrappingElement: any): JQuery;
|
||||
|
||||
// Miscellaneous
|
||||
each(func: (index: any, elem: Element) => any): JQuery;
|
||||
|
||||
get(index?: number): any;
|
||||
|
||||
index(selectorOrElement?: any): number;
|
||||
|
||||
// Properties
|
||||
length: number;
|
||||
[x: number]: HTMLElement;
|
||||
|
||||
// Traversing
|
||||
add(selector: string, context?: any): JQuery;
|
||||
add(html: string): JQuery;
|
||||
add(obj: JQuery): JQuery;
|
||||
add(...elements: any[]): JQuery;
|
||||
|
||||
addBack(selector?: any): JQuery;
|
||||
|
||||
children(selector?: any): JQuery;
|
||||
|
||||
closest(selector: string): JQuery;
|
||||
closest(selector: string, context?: Element): JQuery;
|
||||
closest(obj: JQuery): JQuery;
|
||||
closest(element: any): JQuery;
|
||||
closest(selectors: any, context?: Element): any[];
|
||||
|
||||
contents(): JQuery;
|
||||
|
||||
end(): JQuery;
|
||||
|
||||
eq(index: number): JQuery;
|
||||
|
||||
filter(selector: string): JQuery;
|
||||
filter(func: (index: any) => any): JQuery;
|
||||
filter(obj: JQuery): JQuery;
|
||||
filter(element: any): JQuery;
|
||||
|
||||
find(selector: string): JQuery;
|
||||
find(element: any): JQuery;
|
||||
find(obj: JQuery): JQuery;
|
||||
|
||||
first(): JQuery;
|
||||
|
||||
has(selector: string): JQuery;
|
||||
has(contained: Element): JQuery;
|
||||
|
||||
is(selector: string): boolean;
|
||||
is(func: (index: any) => any): boolean;
|
||||
is(obj: JQuery): boolean;
|
||||
is(element: any): boolean;
|
||||
|
||||
last(): JQuery;
|
||||
|
||||
map(callback: (index: any, domElement: Element) => any): JQuery;
|
||||
|
||||
next(selector?: string): JQuery;
|
||||
|
||||
nextAll(selector?: string): JQuery;
|
||||
|
||||
nextUntil(selector?: string, filter?: string): JQuery;
|
||||
nextUntil(element?: Element, filter?: string): JQuery;
|
||||
|
||||
not(selector: string): JQuery;
|
||||
not(func: (index: any) => any): JQuery;
|
||||
not(obj: JQuery): JQuery;
|
||||
not(element: any): JQuery;
|
||||
|
||||
offsetParent(): JQuery;
|
||||
|
||||
parent(selector?: string): JQuery;
|
||||
|
||||
parents(selector?: string): JQuery;
|
||||
|
||||
parentsUntil(selector?: string, filter?: string): JQuery;
|
||||
parentsUntil(element?: Element, filter?: string): JQuery;
|
||||
|
||||
prev(selector?: string): JQuery;
|
||||
|
||||
prevAll(selector?: string): JQuery;
|
||||
|
||||
prevUntil(selector?: string, filter?: string): JQuery;
|
||||
prevUntil(element?: Element, filter?: string): JQuery;
|
||||
|
||||
siblings(selector?: string): JQuery;
|
||||
|
||||
slice(start: number, end?: number): JQuery;
|
||||
}
|
||||
|
||||
declare var jQuery: JQueryStatic;
|
||||
declare var $: JQueryStatic;
|
||||
@@ -0,0 +1,92 @@
|
||||
/// <reference path="jquery.d.ts"/>
|
||||
|
||||
// Partial typing for the jQueryUI library, version 1.8.x
|
||||
|
||||
interface DraggableEventUIParam {
|
||||
helper: JQuery;
|
||||
position: { top: number; left: number;};
|
||||
offset: { top: number; left: number;};
|
||||
}
|
||||
|
||||
interface DraggableEvent {
|
||||
(event: Event, ui: DraggableEventUIParam): void;
|
||||
}
|
||||
|
||||
interface Draggable {
|
||||
// Options
|
||||
disabled?: boolean;
|
||||
addClasses?: boolean;
|
||||
appendTo?: any;
|
||||
axis?: string;
|
||||
cancel?: string;
|
||||
connectToSortable?: string;
|
||||
containment?: any;
|
||||
cursor?: string;
|
||||
cursorAt?: any;
|
||||
delay?: number;
|
||||
distance?: number;
|
||||
grid?: number[];
|
||||
handle?: any;
|
||||
helper?: any;
|
||||
iframeFix?: any;
|
||||
opacity?: number;
|
||||
refreshPositions?: boolean;
|
||||
revert?: any;
|
||||
revertDuration?: number;
|
||||
scope?: string;
|
||||
scroll?: boolean;
|
||||
scrollSensitivity?: number;
|
||||
scrollSpeed?: number;
|
||||
snap?: any;
|
||||
snapMode?: string;
|
||||
snapTolerance?: number;
|
||||
stack?: string;
|
||||
zIndex?: number;
|
||||
// Events
|
||||
create?: DraggableEvent;
|
||||
start?: DraggableEvent;
|
||||
drag?: DraggableEvent;
|
||||
stop?: DraggableEvent;
|
||||
}
|
||||
|
||||
interface DroppableEventUIParam {
|
||||
draggable: JQuery;
|
||||
helper: JQuery;
|
||||
position: { top: number; left: number;};
|
||||
offset: { top: number; left: number;};
|
||||
}
|
||||
|
||||
interface DroppableEvent {
|
||||
(event: Event, ui: DroppableEventUIParam): void;
|
||||
}
|
||||
|
||||
interface Droppable {
|
||||
// Options
|
||||
disabled?: boolean;
|
||||
accept?: any;
|
||||
activeClass?: string;
|
||||
greedy?: boolean;
|
||||
hoverClass?: string;
|
||||
scope?: string;
|
||||
tolerance?: string;
|
||||
// Events
|
||||
create?: DroppableEvent;
|
||||
activate?: DroppableEvent;
|
||||
deactivate?: DroppableEvent;
|
||||
over?: DroppableEvent;
|
||||
out?: DroppableEvent;
|
||||
drop?: DroppableEvent;
|
||||
}
|
||||
|
||||
interface JQuery {
|
||||
draggable(options: Draggable): JQuery;
|
||||
draggable(optionLiteral: string, options: Draggable): JQuery;
|
||||
draggable(optionLiteral: string, optionName: string, optionValue: any): JQuery;
|
||||
draggable(optionLiteral: string, optionName: string): any;
|
||||
// draggable(methodName: string): any;
|
||||
droppable(options: Droppable): JQuery;
|
||||
droppable(optionLiteral: string, options: Draggable): JQuery;
|
||||
droppable(optionLiteral: string, optionName: string, optionValue: any): JQuery;
|
||||
droppable(optionLiteral: string, optionName: string): any;
|
||||
droppable(methodName: string): any;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
html
|
||||
{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
-ms-content-zooming: none;
|
||||
margin: 0px;
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/*background-color: #b5caae;*/
|
||||
background: url('img/bg2.jpg');
|
||||
margin: 0px;
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
min-height: 480px;
|
||||
min-width: 640px;
|
||||
}
|
||||
#header {
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
}
|
||||
#boards {
|
||||
width: 100%;
|
||||
height: 75%;
|
||||
}
|
||||
.quadrant
|
||||
{
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
width: 40%;
|
||||
margin: 2%;
|
||||
vertical-align: top;
|
||||
}
|
||||
#banner {
|
||||
font-size: 40pt;
|
||||
font-weight: 800;
|
||||
font-style: italic;
|
||||
color: white;
|
||||
text-shadow: -1px 0 black, 0 2px black, 1px 0 black, 0 -1px black;
|
||||
height: 100px;
|
||||
}
|
||||
#status
|
||||
{
|
||||
width: 80%;
|
||||
border: 1px dotted gray;
|
||||
padding: 1%;
|
||||
background-color: #CCCCCC;
|
||||
height: 80%;
|
||||
}
|
||||
.board {
|
||||
background-color: #111111;
|
||||
border: 2px groove black;
|
||||
height: 80%;
|
||||
padding: 0%;
|
||||
position: relative;
|
||||
}
|
||||
.cell {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
float: left;
|
||||
height: 10%;
|
||||
width: 10%;
|
||||
border: 1px dotted #A0A0FF;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.notBombed {
|
||||
opacity: 0.2;
|
||||
background: url('img/bg.jpg') repeat;
|
||||
/*background-color: black;*/
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.cellHit {
|
||||
opacity: 0.5;
|
||||
background-color: #C00000;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.cellMiss{
|
||||
opacity: 0.5;
|
||||
background-color: #008000;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.ship {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
margin: 0%;
|
||||
padding: 0%;
|
||||
width: 10%;
|
||||
height: 10%;
|
||||
border-radius: 20%;
|
||||
/*background-color: #FFFF80;*/
|
||||
background: #666666;
|
||||
border: 2px solid black;
|
||||
z-index: 1;
|
||||
-ms-touch-action: none;
|
||||
}
|
||||
|
||||
.dropTarget {
|
||||
background-color: white;
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
/// <reference path="jquery.d.ts" />
|
||||
/// <reference path='jqueryui.d.ts' />
|
||||
|
||||
class Cell {
|
||||
shipIndex: number;
|
||||
hasHit: boolean;
|
||||
element: HTMLElement;
|
||||
|
||||
constructor(public row: number, public column: number) {
|
||||
this.element = $("<div class='cell notBombed'></div>")[0];
|
||||
}
|
||||
|
||||
// Parse a cell location of the format "row,column"
|
||||
static parseCellLocation(pos: string) {
|
||||
var indices: string[] = pos.split(",");
|
||||
return { 'row': parseInt(indices[0]), 'column': parseInt(indices[1]) };
|
||||
}
|
||||
|
||||
// Return the cell location of the format "row,column"
|
||||
cellLocation() {
|
||||
return "" + this.row + "," + this.column;
|
||||
}
|
||||
}
|
||||
|
||||
class Ship {
|
||||
column = 0;
|
||||
row = 0;
|
||||
isVertical = true;
|
||||
hits = 0;
|
||||
element: HTMLElement;
|
||||
|
||||
constructor(public size: number) {
|
||||
this.element = $("<div class='ship'></div>")[0];
|
||||
}
|
||||
|
||||
updatePosition(row: number, column: number, vertical: boolean) {
|
||||
this.row = row;
|
||||
this.column = column;
|
||||
this.isVertical = vertical;
|
||||
this.updateLayout();
|
||||
}
|
||||
|
||||
updateLayout() {
|
||||
var width = "9.9%";
|
||||
var height = "" + (this.size * 9.9) + "%";
|
||||
this.element.style.left = "" + (this.column * 10) + "%";
|
||||
this.element.style.top = "" + (this.row * 10) + "%";
|
||||
this.element.style.width = this.isVertical ? width : height;
|
||||
this.element.style.height = this.isVertical ? height : width;
|
||||
}
|
||||
|
||||
flipShip() {
|
||||
this.isVertical = !this.isVertical;
|
||||
if (this.isVertical) {
|
||||
if (this.row + this.size > 10) {
|
||||
this.row = 10 - this.size;
|
||||
}
|
||||
} else {
|
||||
if (this.column + this.size > 10) {
|
||||
this.column = 10 - this.size;
|
||||
}
|
||||
}
|
||||
this.updateLayout();
|
||||
}
|
||||
|
||||
getCellsCovered() {
|
||||
var cells: string[] = [];
|
||||
var row = this.row;
|
||||
var col = this.column;
|
||||
for (var i = 0; i < this.size; i++) {
|
||||
cells.push(row.toString() + "," + col.toString());
|
||||
if (this.isVertical) {
|
||||
row++;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
}
|
||||
return cells;
|
||||
}
|
||||
|
||||
isSunk() {
|
||||
return this.hits === this.size;
|
||||
}
|
||||
}
|
||||
|
||||
class Board {
|
||||
ships: Ship[];
|
||||
cells: Cell[][]; // Indexed by [rows][columns]
|
||||
playerTurn = false; // Set to true when player can move
|
||||
onEvent: Function; // Callback function when an action on the board occurs
|
||||
shipSizes = [5, 4, 3, 3, 2];
|
||||
|
||||
private positioningEnabled: boolean; // Set to true when the player can position the ships
|
||||
|
||||
constructor(public element: HTMLElement, playerBoard: boolean = true) {
|
||||
this.positioningEnabled = playerBoard;
|
||||
this.cells = [];
|
||||
this.ships = [];
|
||||
var cell: Cell = null;
|
||||
|
||||
// Create the cells for the board
|
||||
for (var row = 0; row < 10; row++) {
|
||||
this.cells[row] = [];
|
||||
for (var column = 0; column < 10; column++) {
|
||||
cell = new Cell(row, column);
|
||||
this.cells[row][column] = cell;
|
||||
element.appendChild(cell.element);
|
||||
$(cell.element).data("cellLocation", cell.cellLocation());
|
||||
if (playerBoard) {
|
||||
$(cell.element).droppable({
|
||||
disabled: false,
|
||||
drop: (event, ui) => {
|
||||
var shipElement = <HTMLElement>ui.draggable[0];
|
||||
var shipIndex: number = $(shipElement).data("shipIndex");
|
||||
var ship = this.ships[shipIndex];
|
||||
var shipX = Math.round(shipElement.offsetLeft / cell.element.offsetWidth);
|
||||
var shipY = Math.round(shipElement.offsetTop / cell.element.offsetHeight);
|
||||
ship.updatePosition(shipY, shipX, ship.isVertical);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var referenceCell = $(cell.element);
|
||||
for (var i = 0; i < this.shipSizes.length; i++) {
|
||||
var ship = new Ship(this.shipSizes[i]);
|
||||
this.ships[i] = ship;
|
||||
ship.updatePosition(i, 0, false);
|
||||
if (playerBoard) { // Show the ships for positioning.
|
||||
this.element.appendChild(ship.element);
|
||||
ship.updateLayout();
|
||||
$(ship.element).data("shipIndex", i).draggable({
|
||||
disabled: false,
|
||||
containment: 'parent',
|
||||
// Reduce size slightly to avoid overlap issues blocking the last cell
|
||||
grid: [referenceCell.width() * 0.99 + 2, referenceCell.height() * 0.99 + 2],
|
||||
cursor: 'crosshair'
|
||||
}).click((evt: JQueryEventObject) => {
|
||||
if (this.positioningEnabled) {
|
||||
var shipIndex: number = $(evt.target).data("shipIndex");
|
||||
this.ships[shipIndex].flipShip();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(window).resize((evt) => {
|
||||
$(this.element).children(".ship").draggable("option", "grid", [referenceCell.width() * 0.99 + 2, referenceCell.height() * 0.99 + 2]);
|
||||
});
|
||||
|
||||
if (!playerBoard) {
|
||||
// Computer board, this is where the player clicks to bomb
|
||||
$(element).click((evt: JQueryEventObject) => this.onCellClick(evt));
|
||||
}
|
||||
}
|
||||
|
||||
set dragAndDropEnabled(val: boolean) {
|
||||
var cells = $(this.element).children(".cell");
|
||||
var ships = $(this.element).children(".ship");
|
||||
|
||||
this.positioningEnabled = val;
|
||||
ships.draggable("option", "disabled", !val);
|
||||
cells.droppable("option", "disabled", !val);
|
||||
}
|
||||
|
||||
static getRandomPosition() {
|
||||
return {
|
||||
"row": Math.floor(Math.random() * 10),
|
||||
"column": Math.floor(Math.random() * 10),
|
||||
"vertical": (Math.floor(Math.random() * 2) === 1)
|
||||
}
|
||||
}
|
||||
|
||||
onCellClick(evt: JQueryEventObject) {
|
||||
var x = <HTMLElement>evt.target;
|
||||
if ($(x).hasClass("cell") === false) {
|
||||
return;
|
||||
}
|
||||
if (!this.playerTurn) {
|
||||
this.onEvent.call(this, 'click');
|
||||
}
|
||||
if (this.playerTurn) { // May be updated by prior onEvent call, so check again
|
||||
this.bombCell(x);
|
||||
}
|
||||
}
|
||||
|
||||
bombCell(cellElem: HTMLElement) {
|
||||
var cellPos = Cell.parseCellLocation($(cellElem).data("cellLocation"));
|
||||
var cell = this.cells[cellPos.row][cellPos.column];
|
||||
|
||||
if (cell.hasHit) {
|
||||
return; // Already been clicked on
|
||||
}
|
||||
cell.hasHit = true;
|
||||
if (cell.shipIndex >= 0) { // Has a ship
|
||||
$(cellElem).removeClass("notBombed");
|
||||
$(cellElem).addClass("cellHit");
|
||||
var ship = this.ships[cell.shipIndex];
|
||||
ship.hits++;
|
||||
if (ship.isSunk()) {
|
||||
if (this.allShipsSunk()) {
|
||||
this.onEvent.call(this, 'allSunk');
|
||||
} else {
|
||||
this.onEvent.call(this, 'shipSunk');
|
||||
}
|
||||
} else {
|
||||
this.onEvent.call(this, 'hit');
|
||||
}
|
||||
} else {
|
||||
$(cellElem).removeClass("notBombed");
|
||||
$(cellElem).addClass("cellMiss");
|
||||
this.onEvent.call(this, 'playerMissed');
|
||||
}
|
||||
}
|
||||
|
||||
randomize() {
|
||||
var shipCount = this.ships.length;
|
||||
do {
|
||||
for (var shipIndex = 0; shipIndex < shipCount; shipIndex++) {
|
||||
var pos = Board.getRandomPosition();
|
||||
this.ships[shipIndex].updatePosition(pos.row, pos.column, pos.vertical);
|
||||
}
|
||||
} while (!this.boardIsValid());
|
||||
}
|
||||
|
||||
boardIsValid() {
|
||||
// Check if any ships overlap my checking their cells for duplicates.
|
||||
// Do this by putting into a flat array, sorting, and seeing if any adjacent cells are equal
|
||||
var allCells: string[] = [];
|
||||
for (var i = 0; i < this.ships.length; i++) {
|
||||
allCells = allCells.concat(this.ships[i].getCellsCovered());
|
||||
}
|
||||
allCells.sort();
|
||||
var dups = allCells.some(function (val, idx, arr) { return val === arr[idx + 1]; });
|
||||
|
||||
// See if any ship cells are off the board
|
||||
var outOfRange = allCells.some(function (val: string) {
|
||||
var pos = Cell.parseCellLocation(val);
|
||||
return !(pos.column >= 0 && pos.column <= 9 && pos.row >= 0 && pos.row <= 9);
|
||||
});
|
||||
if (dups || outOfRange) {
|
||||
return false;
|
||||
} else {
|
||||
this.updateCellData();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
chooseMove() {
|
||||
do {
|
||||
var pos = Board.getRandomPosition();
|
||||
var cell = this.cells[pos.row][pos.column];
|
||||
} while (cell.hasHit);
|
||||
this.bombCell(cell.element);
|
||||
}
|
||||
|
||||
private updateCellData() {
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var x = this.cells[Math.floor(i / 10)][i % 10];
|
||||
x.hasHit = false;
|
||||
x.shipIndex = -1;
|
||||
}
|
||||
|
||||
for (var index = 0; index < this.ships.length; index++) {
|
||||
var ship = this.ships[index]
|
||||
ship.hits = 0;
|
||||
var cells = ship.getCellsCovered();
|
||||
for (var cell = 0; cell < cells.length; cell++) {
|
||||
var cellPos = Cell.parseCellLocation(cells[cell]);
|
||||
var targetCell = this.cells[cellPos.row][cellPos.column];
|
||||
targetCell.shipIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
$(this.element).children(".cell").removeClass("cellHit cellMiss").addClass("notBombed");
|
||||
}
|
||||
|
||||
private allShipsSunk() {
|
||||
return this.ships.every(function (val) { return val.isSunk(); });
|
||||
}
|
||||
}
|
||||
|
||||
class Game {
|
||||
static gameState = { begin: 0, computerTurn: 1, playerTurn: 2, finished: 3 };
|
||||
static msgs = {
|
||||
gameStart: "Drag your ships to the desired location on your board (on the right), then bomb a square on the left board to start the game!",
|
||||
invalidPositions: "All ships must be in valid positions before the game can begin.",
|
||||
wait: "Wait your turn!",
|
||||
gameOn: "Game on!",
|
||||
hit: "Good hit!",
|
||||
shipSunk: "You sunk a ship!",
|
||||
lostShip: "You lost a ship :-(",
|
||||
lostGame: "You lost this time. Click anywhere on the left board to play again.",
|
||||
allSunk: "Congratulations! You won! Click anywhere on the left board to play again."
|
||||
};
|
||||
|
||||
state = Game.gameState.begin;
|
||||
playerBoard: Board;
|
||||
computerBoard: Board;
|
||||
|
||||
constructor() {
|
||||
this.updateStatus(Game.msgs.gameStart);
|
||||
this.playerBoard = new Board($("#playerBoard")[0]);
|
||||
this.computerBoard = new Board($("#computerBoard")[0], false);
|
||||
this.computerBoard.randomize();
|
||||
this.playerBoard.randomize();
|
||||
this.playerBoard.dragAndDropEnabled = true;
|
||||
this.computerBoard.onEvent = (evt: string) => {
|
||||
switch (evt) {
|
||||
case 'click': // The user has click outside a turn. Action depends on current state
|
||||
switch (this.state) {
|
||||
case Game.gameState.begin:
|
||||
this.startGame();
|
||||
break;
|
||||
case Game.gameState.computerTurn: // Not their turn yet. Ask to wait.
|
||||
this.updateStatus(Game.msgs.wait);
|
||||
break;
|
||||
case Game.gameState.finished: // Start a new game
|
||||
this.computerBoard.randomize();
|
||||
this.playerBoard.randomize();
|
||||
this.playerBoard.dragAndDropEnabled = true;
|
||||
this.updateStatus(Game.msgs.gameStart);
|
||||
this.state = Game.gameState.begin;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'playerMissed':
|
||||
this.computersTurn();
|
||||
break;
|
||||
case 'hit':
|
||||
this.updateStatus(Game.msgs.hit);
|
||||
this.computersTurn();
|
||||
break;
|
||||
case 'shipSunk':
|
||||
this.updateStatus(Game.msgs.shipSunk);
|
||||
this.computersTurn();
|
||||
break;
|
||||
case 'allSunk':
|
||||
this.state = Game.gameState.finished;
|
||||
this.computerBoard.playerTurn = false;
|
||||
this.updateStatus(Game.msgs.allSunk);
|
||||
break;
|
||||
}
|
||||
};
|
||||
this.playerBoard.onEvent = (evt: string) => {
|
||||
switch (evt) {
|
||||
case 'playerMissed':
|
||||
case 'hit':
|
||||
this.computerBoard.playerTurn = true;
|
||||
break;
|
||||
case 'shipSunk':
|
||||
this.updateStatus(Game.msgs.lostShip);
|
||||
this.computerBoard.playerTurn = true;
|
||||
break;
|
||||
case 'allSunk':
|
||||
this.updateStatus(Game.msgs.lostGame);
|
||||
this.computerBoard.playerTurn = false;
|
||||
this.state = Game.gameState.finished;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private computersTurn() {
|
||||
this.computerBoard.playerTurn = false;
|
||||
this.state = Game.gameState.computerTurn;
|
||||
setTimeout(() => {
|
||||
this.playerBoard.chooseMove();
|
||||
}, 250);
|
||||
}
|
||||
|
||||
private startGame() {
|
||||
if (this.playerBoard.boardIsValid()) {
|
||||
this.state = Game.gameState.playerTurn;
|
||||
this.playerBoard.dragAndDropEnabled = false;
|
||||
this.computerBoard.playerTurn = true;
|
||||
this.updateStatus(Game.msgs.gameOn);
|
||||
}
|
||||
else {
|
||||
this.updateStatus(Game.msgs.invalidPositions);
|
||||
}
|
||||
}
|
||||
|
||||
private updateStatus(msg: string) {
|
||||
$("#status").slideUp('fast', function () { // Slide out the old text
|
||||
$(this).text(msg).slideDown('fast'); // Then slide in the new text
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(new Function("var game = new Game();"));
|
||||
@@ -0,0 +1,14 @@
|
||||
===== TypeScript Sample: Windows 8 Windows store app =====
|
||||
|
||||
=== Overview ===
|
||||
|
||||
The encyclopedia includes a complete sample app for a Windows 8 app
|
||||
built using TypeScript. The following features of TypeScript are highlighted:
|
||||
- VS project integration: TypeScript compilation integrated into VS build
|
||||
- Typing WinJS and WinRT: Early work on typing these libraries
|
||||
- Mostly JS in TypeScript: Code is mostly the original JS, with a little
|
||||
TypeScript
|
||||
|
||||
=== Running ===
|
||||
Open encyclopedia\Encyclopedia.sln in Visual Studio 2012
|
||||
F5
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "Encyclopedia", "Encyclopedia\Encyclopedia.jsproj", "{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|x64.Build.0 = Debug|x64
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|x86.Build.0 = Debug|x86
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|ARM.Build.0 = Release|ARM
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|x64.ActiveCfg = Release|x64
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|x64.Build.0 = Release|x64
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|x64.Deploy.0 = Release|x64
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|x86.ActiveCfg = Release|x86
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|x86.Build.0 = Release|x86
|
||||
{CB97C74A-DB4A-42FA-8B3B-FFED5198621B}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|AnyCPU">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x86">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|AnyCPU">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>AnyCPU</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{cb97c74a-db4a-42fa-8b3b-ffed5198621b}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
|
||||
<PropertyGroup>
|
||||
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>8.0</TargetPlatformVersion>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<Content Include="css\wikipedia.css" />
|
||||
<Content Include="default.html" />
|
||||
<Content Include="css\groupDetailPage.css" />
|
||||
<Content Include="css\default.css" />
|
||||
<Content Include="css\itemDetailPage.css" />
|
||||
<Content Include="css\groupedItemsPage.css" />
|
||||
<Content Include="html\groupDetailPage.html" />
|
||||
<Content Include="html\itemDetailPage.html" />
|
||||
<Content Include="html\groupedItemsPage.html" />
|
||||
<Content Include="images\ep-badge.png" />
|
||||
<Content Include="images\ep-logo-small.png" />
|
||||
<Content Include="images\ep-logo.png" />
|
||||
<Content Include="images\ep-splashscreen.png" />
|
||||
<Content Include="images\ep-storelogo.png" />
|
||||
<Content Include="images\ep-widetile.png" />
|
||||
<TypeScriptCompile Include="js\groupDetailPage.ts" />
|
||||
<TypeScriptCompile Include="js\default.ts" />
|
||||
<TypeScriptCompile Include="js\navigator.ts" />
|
||||
<TypeScriptCompile Include="js\data.ts" />
|
||||
<TypeScriptCompile Include="js\itemDetailPage.ts" />
|
||||
<TypeScriptCompile Include="js\groupedItemsPage.ts" />
|
||||
<TypeScriptCompile Include="js\topic.ts" />
|
||||
<TypeScriptCompile Include="js\win.ts" />
|
||||
<Content Include="js\groupDetailPage.js">
|
||||
<DependentUpon>groupDetailPage.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="js\default.js">
|
||||
<DependentUpon>default.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="js\navigator.js">
|
||||
<DependentUpon>navigator.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="js\data.js">
|
||||
<DependentUpon>data.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="js\itemDetailPage.js">
|
||||
<DependentUpon>itemDetailPage.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="js\groupedItemsPage.js">
|
||||
<DependentUpon>groupedItemsPage.ts</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="js\topic.js">
|
||||
<DependentUpon>topic.ts</DependentUpon>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="Microsoft.WinJS.1.0, Version=1.0" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.VisualStudio.$(WMSJSProject).targets" />
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<TypeScriptTarget>ES5</TypeScriptTarget>
|
||||
<TypeScriptIncludeComments>true</TypeScriptIncludeComments>
|
||||
<TypeScriptSourceMap>true</TypeScriptSourceMap>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<TypeScriptTarget>ES5</TypeScriptTarget>
|
||||
<TypeScriptIncludeComments>false</TypeScriptIncludeComments>
|
||||
<TypeScriptSourceMap>false</TypeScriptSourceMap>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,181 @@
|
||||
html {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#contenthost {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fragment {
|
||||
/* Define a grid with rows for a banner and a body */
|
||||
-ms-grid-columns: 1fr;
|
||||
-ms-grid-rows: 128px 1fr 0px;
|
||||
display: -ms-grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] {
|
||||
/* Define a grid with columns for the back button and page title. */
|
||||
-ms-grid-columns: 120px 1fr;
|
||||
-ms-grid-rows: 1fr;
|
||||
display: -ms-grid;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton {
|
||||
margin-left: 39px;
|
||||
margin-top: 59px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titlearea {
|
||||
-ms-grid-column: 2;
|
||||
margin-top: 37px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titlearea .pagetitle {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.fragment section[role=main] {
|
||||
-ms-grid-row: 2;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: snapped) {
|
||||
.fragment header[role=banner] {
|
||||
-ms-grid-columns: auto 1fr;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton {
|
||||
margin: 0;
|
||||
margin-right: 10px;
|
||||
margin-top: 76px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton:disabled {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titlearea {
|
||||
-ms-grid-column: 2;
|
||||
margin-left: 0;
|
||||
margin-top: 68px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: fullscreen-portrait) {
|
||||
.fragment header[role=banner] {
|
||||
-ms-grid-columns: 100px 1fr;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton {
|
||||
margin-left: 29px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*html
|
||||
{
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#contentHost
|
||||
{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fragment
|
||||
{
|
||||
-ms-grid-columns: 1fr;
|
||||
-ms-grid-rows: 133px 1fr 0px;
|
||||
display: -ms-grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fragment header[role=banner]
|
||||
{
|
||||
-ms-grid-columns: 120px 1fr;
|
||||
-ms-grid-rows: 1fr;
|
||||
display: -ms-grid;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton
|
||||
{
|
||||
margin-left: 39px;
|
||||
margin-top: 59px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titleArea
|
||||
{
|
||||
-ms-grid-column: 2;
|
||||
margin-top: 44px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titleArea .win-type-xx-large
|
||||
{
|
||||
display: inline;
|
||||
height: 60pt;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.fragment section[role=main]
|
||||
{
|
||||
-ms-grid-row: 2;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: snapped)
|
||||
{
|
||||
.fragment .win-type-x-large
|
||||
{
|
||||
font-size: 11pt;
|
||||
line-height: 15pt;
|
||||
}
|
||||
|
||||
.fragment header[role=banner]
|
||||
{
|
||||
-ms-grid-columns: 60px 1fr;
|
||||
-ms-grid-rows: 1fr;
|
||||
display: -ms-grid;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton
|
||||
{
|
||||
margin-left: 20px;
|
||||
margin-top: 75px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titleArea
|
||||
{
|
||||
margin-top: 71px;
|
||||
max-width: 260px;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .titleArea .win-type-xx-large
|
||||
{
|
||||
font-size: 20pt;
|
||||
line-height: 24pt;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: fullscreen-portrait)
|
||||
{
|
||||
.fragment header[role=banner]
|
||||
{
|
||||
-ms-grid-columns: 100px 1fr;
|
||||
}
|
||||
|
||||
.fragment header[role=banner] .win-backbutton
|
||||
{
|
||||
margin-left: 29px;
|
||||
}
|
||||
}*/
|
||||
@@ -0,0 +1,173 @@
|
||||
.groupDetailPage .groupList
|
||||
{
|
||||
height: 100%;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-groupheader
|
||||
{
|
||||
-ms-grid-columns: 1fr;
|
||||
-ms-grid-rows: auto 11px auto 20px 1fr 36px;
|
||||
display: -ms-grid;
|
||||
font-family: "Segoe UI";
|
||||
font-size: 11pt;
|
||||
height: 100%;
|
||||
line-height: 15pt;
|
||||
margin-left: 120px;
|
||||
margin-right: 70px;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-groupheader .win-type-x-large
|
||||
{
|
||||
-ms-grid-row: 1;
|
||||
margin: 0;
|
||||
max-height: 48pt;
|
||||
overflow: hidden;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-groupheader .image
|
||||
{
|
||||
-ms-grid-row: 3;
|
||||
background-color: rgba(147, 149, 152, 1);
|
||||
height: 238px;
|
||||
margin: 0;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-groupheader .description
|
||||
{
|
||||
-ms-grid-row: 5;
|
||||
column-fill: auto;
|
||||
column-gap: 70px;
|
||||
columns: 480px auto;
|
||||
margin-bottom: 12px;
|
||||
margin-top: -2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-groupheader .description p
|
||||
{
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item
|
||||
{
|
||||
-ms-grid-columns: 110px 10px 1fr;
|
||||
-ms-grid-rows: 1fr;
|
||||
display: -ms-grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item .item-info
|
||||
{
|
||||
-ms-grid-column: 3;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item .item-info .item-title
|
||||
{
|
||||
margin-top: 4px;
|
||||
max-height: 20px;
|
||||
opacity: 0.8;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item .item-info .item-subtitle
|
||||
{
|
||||
max-height: 20px;
|
||||
opacity: 0.49;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item .item-info .item-description
|
||||
{
|
||||
max-height: 60px;
|
||||
opacity: 0.8;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-item
|
||||
{
|
||||
height: 110px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 60px;
|
||||
padding: 10px;
|
||||
width: 472px;
|
||||
}
|
||||
|
||||
.groupDetailPage header[role=banner] .menu
|
||||
{
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.groupDetailPage header[role=banner] .menu .win-command
|
||||
{
|
||||
color: #2A2A2A;
|
||||
font-size: 20pt;
|
||||
line-height: 24pt;
|
||||
margin-bottom: 13px;
|
||||
margin-top: 6px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: snapped)
|
||||
{
|
||||
.groupDetailPage .groupList
|
||||
{
|
||||
width: calc(100% - 10px);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-groupheader
|
||||
{
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .win-item
|
||||
{
|
||||
height: 64px;
|
||||
margin: 0;
|
||||
margin-right: 18px;
|
||||
padding: 10px 0px 10px 10px;
|
||||
width: 282px;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item
|
||||
{
|
||||
-ms-grid-columns: 60px 10px 1fr;
|
||||
-ms-grid-rows: 1fr;
|
||||
display: -ms-grid;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item .item-info .item-title
|
||||
{
|
||||
max-height: 30pt;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.groupDetailPage .groupList .item .item-info .item-description
|
||||
{
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: fullscreen-portrait)
|
||||
{
|
||||
.groupDetailPage .groupList .win-groupheader
|
||||
{
|
||||
margin-left: 100px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
.wiki
|
||||
{
|
||||
font-weight:300;
|
||||
font-family: 'Segoe UI';
|
||||
color: black;
|
||||
}
|
||||
.bee
|
||||
{
|
||||
font-weight:300;
|
||||
font-family: 'Segoe UI';
|
||||
color: #ffdd33;
|
||||
}
|
||||
|
||||
/* This selector is used to prevent ui-dark/light.css from overwriting changes
|
||||
to .win-surface. */
|
||||
.groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface {
|
||||
margin-left: 45px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .win-groupheader {
|
||||
margin-top: 5px;
|
||||
margin-left: 70px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .win-groupheader .group-title {
|
||||
margin-bottom: 10px;
|
||||
margin-left: 5px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item {
|
||||
-ms-grid-columns: 1fr;
|
||||
-ms-grid-rows: 1fr 90px;
|
||||
display: -ms-grid;
|
||||
height: 250px;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-image {
|
||||
-ms-grid-row-span: 2;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay {
|
||||
-ms-grid-row: 2;
|
||||
-ms-grid-rows: 1fr 21px;
|
||||
display: -ms-grid;
|
||||
padding: 6px 15px 2px 15px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay .item-title {
|
||||
-ms-grid-row: 1;
|
||||
overflow: hidden;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay .item-subtitle {
|
||||
-ms-grid-row: 2;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: fullscreen-landscape), screen and (-ms-view-state: fullscreen-portrait), screen and (-ms-view-state: filled) {
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay {
|
||||
background: rgba(0,0,0,0.65);
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay .item-title {
|
||||
color: rgba(255,255,255,0.87);
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay .item-subtitle {
|
||||
color: rgba(255,255,255,0.6);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: snapped) {
|
||||
|
||||
.groupeditemspage .groupeditemslist .win-vertical.win-viewport .win-surface {
|
||||
margin-bottom: 30px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .win-vertical.win-viewport .win-container {
|
||||
margin-right: 42px;
|
||||
margin-bottom: 15px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item {
|
||||
-ms-grid-columns: 60px 1fr;
|
||||
-ms-grid-rows: 1fr;
|
||||
display: -ms-grid;
|
||||
height: 60px;
|
||||
width: 272px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-image {
|
||||
-ms-grid-column: 1;
|
||||
-ms-grid-row-span: 1;
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay {
|
||||
-ms-grid-column: 2;
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-row-align: stretch;
|
||||
background: transparent;
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay .item-title {
|
||||
margin-top: 4px;
|
||||
max-height: 40px;
|
||||
width: 202px;
|
||||
}
|
||||
|
||||
.groupeditemspage .groupeditemslist .item .item-overlay .item-subtitle {
|
||||
opacity: 0.6;
|
||||
width: 202px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: fullscreen-portrait) {
|
||||
.groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface {
|
||||
margin-left: 25px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
.itemDetailPage section[role=main]
|
||||
{
|
||||
-ms-grid-row: 2;
|
||||
display: block;
|
||||
height: 100%;
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article
|
||||
{
|
||||
column-fill: auto;
|
||||
column-gap: 80px;
|
||||
column-width: 480px;
|
||||
height: calc(100% - 50px);
|
||||
margin-left: 120px;
|
||||
width: 480px;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article header .win-type-x-large
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article header .win-type-medium
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article .image
|
||||
{
|
||||
height: 240px;
|
||||
margin-bottom: 3px;
|
||||
width: 460px;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article p
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
margin-right: 20px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.itemDetailPage header[role=banner] .menu
|
||||
{
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.itemDetailPage header[role=banner] .menu .win-command
|
||||
{
|
||||
color: #2A2A2A;
|
||||
font-size: 20pt;
|
||||
line-height: 24pt;
|
||||
margin-bottom: 13px;
|
||||
margin-top: 6px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: snapped)
|
||||
{
|
||||
.itemDetailPage section[role=main] article
|
||||
{
|
||||
-ms-grid-columns: 300px 1fr;
|
||||
-ms-grid-row: 2;
|
||||
-ms-grid-rows: auto 60px;
|
||||
display: -ms-grid;
|
||||
height: 100%;
|
||||
margin-left: 20px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article header .win-type-x-large
|
||||
{
|
||||
font-size: 11pt;
|
||||
line-height: 15pt;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article .image
|
||||
{
|
||||
height: 140px;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.itemDetailPage section[role=main] article .content
|
||||
{
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (-ms-view-state: fullscreen-portrait)
|
||||
{
|
||||
.detailPage section[role=main] article
|
||||
{
|
||||
margin-left: 100px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
body
|
||||
{
|
||||
word-wrap: break-word !important;
|
||||
font-size:1.5em !important;
|
||||
}
|
||||
|
||||
h2
|
||||
{
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h3
|
||||
{
|
||||
font-size: 1.5em;
|
||||
}
|
||||
h4
|
||||
{
|
||||
font-size: 1.5em;
|
||||
}
|
||||
*/
|
||||
|
||||
h2, h3, h4, h5, h6, h7
|
||||
{
|
||||
break-after: avoid;
|
||||
}
|
||||
|
||||
img.tex
|
||||
{
|
||||
/*max-width: 380px !important;*/
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration:none !important;
|
||||
}
|
||||
|
||||
.firstHeading
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
.noprint
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
.printfooter
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.catlinks
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.metadata
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#footer
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
#jump-to-nav
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
.toc
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
#siteSub { display:none !important; }
|
||||
#contentSub { display: none !important; }
|
||||
|
||||
|
||||
.dablink
|
||||
{
|
||||
float:none !important;
|
||||
width: 100%!important;
|
||||
display:block !important;
|
||||
background-color:rgb(230, 230, 230) !important;
|
||||
margin: 2px 2px 2px 2px !important;
|
||||
font-size: .6em !important;
|
||||
font-style: italic !important;
|
||||
}
|
||||
|
||||
.infobox
|
||||
{
|
||||
float:none !important;
|
||||
width: 100% !important;
|
||||
background-color: rgb(230, 230, 230) !important;
|
||||
margin: 2px 2px 2px 2px !important;
|
||||
border-style:solid !important;
|
||||
border-width: 1px !important;
|
||||
border-color: rgb(200,200,200) !important;
|
||||
font-size: .75em !important;
|
||||
}
|
||||
|
||||
.infobox caption
|
||||
{
|
||||
display:none;
|
||||
}
|
||||
|
||||
#coordinates
|
||||
{
|
||||
display: block !important;
|
||||
border-style:outset !important;
|
||||
border-width: 2px !important;
|
||||
border-color: rgb(200,200,200) !important;
|
||||
}
|
||||
|
||||
.floatnone
|
||||
{
|
||||
float:none !important;
|
||||
}
|
||||
|
||||
.rellink
|
||||
{
|
||||
font-size: .9em !important;
|
||||
margin: 10px 10px 10px 10px !important;
|
||||
font-style: italic !important;
|
||||
background-color:rgb(230, 230, 230) !important;
|
||||
break-inside: avoid;
|
||||
break-before: avoid;
|
||||
}
|
||||
|
||||
.editsection
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
.magnify
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
.thumb
|
||||
{
|
||||
display:block;
|
||||
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.8em;
|
||||
border-width: 1px;
|
||||
border-color: #cccccc !important;
|
||||
break-inside:avoid !important;
|
||||
text-align: center;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.tright
|
||||
{
|
||||
width:40% !important;
|
||||
float:right !important;
|
||||
clear:both !important;
|
||||
margin-top: 0.5em;
|
||||
margin-left: 0.8em;
|
||||
/*margin-right: 0px;*/
|
||||
margin-bottom: 0.8em;
|
||||
}
|
||||
|
||||
.tleft
|
||||
{
|
||||
width:40% !important;
|
||||
float:left !important;
|
||||
clear:both !important;
|
||||
margin-top: 0.5em;
|
||||
margin-right: 0.4em;
|
||||
/*margin-left: 0px;*/
|
||||
margin-bottom: 0.8em;
|
||||
}
|
||||
|
||||
.tnone
|
||||
{
|
||||
margin-top: 0.5em;
|
||||
margin-right: 0.4em;
|
||||
margin-left: 0.4em;
|
||||
margin-bottom: 0.8em;
|
||||
}
|
||||
|
||||
.thumbinner
|
||||
{
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
padding: 3px;
|
||||
font-size: 94%;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
width: 90% !important;
|
||||
}
|
||||
|
||||
.thumbimage
|
||||
{
|
||||
width:100% !important;
|
||||
height:100% !important;
|
||||
}
|
||||
|
||||
.thumbcaption
|
||||
{
|
||||
font-size:0.8em;
|
||||
}
|
||||
|
||||
.references-small
|
||||
{
|
||||
font-size:0.5em;
|
||||
}
|
||||
|
||||
.wikitable
|
||||
{
|
||||
float:none !important;
|
||||
width: 400px !important;
|
||||
max-width: 400px !important;
|
||||
background-color: rgb(230, 230, 230) !important;
|
||||
margin: 2px 2px 2px 2px !important;
|
||||
font-size: .6em !important;
|
||||
}
|
||||
|
||||
.wikitable th
|
||||
{
|
||||
background-color: rgb(220,220,220);
|
||||
border-style: solid !important;
|
||||
border-width: 1px !important;
|
||||
border-color: rgb(200,200,200) !important;
|
||||
}
|
||||
|
||||
.wikitable td
|
||||
{
|
||||
border-style: solid !important;
|
||||
border-width: 1px !important;
|
||||
border-color: rgb(200,200,200) !important;
|
||||
}
|
||||
|
||||
table.autocollapse tbody tr
|
||||
{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
table.autocollapse tbody tr:first
|
||||
{
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
table.collapsed tr.collapsable {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.collapseButton { /* 'show'/'hide' buttons created dynamically by the */
|
||||
float: right; /* CollapsibleTables JavaScript in [[MediaWiki:Common.js]] */
|
||||
font-weight: normal; /* are styled here so they can be customised. */
|
||||
text-align: right;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.NavFrame
|
||||
{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/*#ogg_player_1
|
||||
{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
a.image img
|
||||
{
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
|
||||
div.thumbinner div div button
|
||||
{
|
||||
width: 100% !important;
|
||||
}*/
|
||||
|
||||
.multicol
|
||||
{
|
||||
font-size: .8em !important;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Encyclopedia</title>
|
||||
|
||||
<!-- WinJS references -->
|
||||
<link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
|
||||
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
|
||||
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
|
||||
|
||||
<!-- Encyclopedia references -->
|
||||
<link href="/css/default.css" rel="stylesheet">
|
||||
<script src="/js/topic.js"></script>
|
||||
<script src="/js/data.js"></script>
|
||||
<script src="/js/navigator.js"></script>
|
||||
<script src="/js/default.js"></script>
|
||||
<script src="/js/groupedItemsPage.js"></script>
|
||||
<script src="/js/groupDetailPage.js"></script>
|
||||
<script src="/js/itemDetailPage.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="contenthost" data-win-control="Encyclopedia.PageControlNavigator" data-win-options="{home: '/html/groupedItemsPage.html'}">
|
||||
</div>
|
||||
<div id="appbar" data-win-control="WinJS.UI.AppBar" data-win-options="
|
||||
{commands:[{id:'home', label:'Home', icon:'', section: 'global', onclick: Encyclopedia.navigateHome},
|
||||
{id:'refresh', label:'Refresh', icon:'', section: 'selection', onclick: Encyclopedia.refresh},
|
||||
{id:'addfavorite', label:'Add Favorite', icon:'', section: 'selection', onclick: Encyclopedia.addFavorite},
|
||||
{id:'removefavorite', label:'Remove Favorite', icon:'', section: 'selection', onclick: Encyclopedia.removeFavorite},
|
||||
{id:'pin', label:'Pin', icon:'', section: 'selection', onclick: Encyclopedia.pin}
|
||||
]}">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>groupDetailPage</title>
|
||||
|
||||
<!-- WinJS references -->
|
||||
<link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet">
|
||||
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
|
||||
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
|
||||
|
||||
<link href="/css/default.css" rel="stylesheet">
|
||||
<link href="/css/groupDetailPage.css" rel="stylesheet">
|
||||
<script src="/js/data.js"></script>
|
||||
<script src="/js/groupDetailPage.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- These templates are used to display each item in the ListView declared below. -->
|
||||
<div class="headerTemplate" data-win-control="WinJS.Binding.Template">
|
||||
<h3 class="win-type-x-large" data-win-bind="textContent: subtitle"></h3>
|
||||
<img class="image" data-win-bind="src: backgroundImage; alt: title" />
|
||||
<div class="description win-normalText" data-win-bind="innerHTML: description"></div>
|
||||
</div>
|
||||
<div class="itemTemplate" data-win-control="WinJS.Binding.Template">
|
||||
<div class="item">
|
||||
<!--<img class="item-image" data-win-bind="src: backgroundImage; alt: title" />-->
|
||||
<div class="item-image" data-win-bind="style.backgroundImage: imageSrc"></div>
|
||||
<div class="item-info">
|
||||
<div class="win-type-medium item-title" data-win-bind="textContent: title"></div>
|
||||
<!--<div class="win-type-xx-small item-subtitle" data-win-bind="textContent: subtitle"></div>
|
||||
<div class="item-description win-type-medium" data-win-bind="textContent: description"></div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- The content that will be loaded and displayed. -->
|
||||
<div class="groupDetailPage fragment">
|
||||
<header aria-label="Header content" role="banner">
|
||||
<button class="win-backbutton" aria-label="Back" disabled></button>
|
||||
<div class="titleArea">
|
||||
<h1 class="win-type-xx-large" tabindex="0"></h1>
|
||||
</div>
|
||||
<div class="menu"></div>
|
||||
</header>
|
||||
<section aria-label="Main content" role="main">
|
||||
<div class="groupList" aria-label="List of groups" data-win-control="WinJS.UI.ListView" data-win-options="{ selectionMode: 'none' }"></div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>groupedItemsPage</title>
|
||||
|
||||
<!-- WinJS references -->
|
||||
<link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
|
||||
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
|
||||
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
|
||||
|
||||
<link href="/css/default.css" rel="stylesheet">
|
||||
<link href="/css/groupedItemsPage.css" rel="stylesheet">
|
||||
<script src="/js/data.js"></script>
|
||||
<script src="/js/groupedItemsPage.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- These templates are used to display each item in the ListView declared below. -->
|
||||
<div class="headerTemplate" data-win-control="WinJS.Binding.Template">
|
||||
<p class="group-title win-type-x-large" data-win-bind="onclick: click; textContent: title" role="link"></p>
|
||||
</div>
|
||||
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
|
||||
<div class="item">
|
||||
<img class="item-image" data-win-bind="src: imageSrc" />
|
||||
<!--<div class="item-image" data-win-bind="style.backgroundImage: imageSrc"></div>-->
|
||||
<div class="item-overlay">
|
||||
<h2 class="item-title" data-win-bind="textContent: title"></h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- The content that will be loaded and displayed. -->
|
||||
<div class="fragment groupeditemspage">
|
||||
<header aria-label="Header content" role="banner">
|
||||
<button class="win-backbutton" aria-label="Back" disabled></button>
|
||||
<h1 class="titlearea win-type-ellipsis">
|
||||
<span class="pagetitle"><span class="wiki">Encyclo</span><span class="bee">pedia</span></span>
|
||||
</h1>
|
||||
</header>
|
||||
<section aria-label="Main content" role="main">
|
||||
<div class="groupeditemslist" aria-label="List of groups" data-win-control="WinJS.UI.ListView" data-win-options="{ selectionMode: 'none' }"></div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>itemDetailPage</title>
|
||||
|
||||
<!-- WinJS references -->
|
||||
<link href="//Microsoft.WinJS.1.0/css/ui-light.css" rel="stylesheet" />
|
||||
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
|
||||
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
|
||||
|
||||
<link href="/css/default.css" rel="stylesheet">
|
||||
<link href="/css/itemDetailPage.css" rel="stylesheet">
|
||||
<link href="/css/wikipedia.css" rel="stylesheet" />
|
||||
<script src="/js/data.js"></script>
|
||||
<script src="/js/itemDetailPage.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The content that will be loaded and displayed. -->
|
||||
<div class="itemDetailPage fragment">
|
||||
<header aria-label="Header content" role="banner">
|
||||
<button class="win-backbutton" aria-label="Back" disabled></button>
|
||||
<h1 class="titlearea win-type-ellipsis">
|
||||
<span class="pagetitle"></span>
|
||||
</h1>
|
||||
</header>
|
||||
<section aria-label="Main content" role="main">
|
||||
<article>
|
||||
<div>
|
||||
<!-- <header>
|
||||
<div class="win-type-x-large"></div>
|
||||
<div class="win-type-medium"></div>
|
||||
</header>
|
||||
<img class="image" />-->
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 158 B |
|
After Width: | Height: | Size: 194 B |
|
After Width: | Height: | Size: 491 B |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 999 B |
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,117 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='topic.ts'/>
|
||||
///<reference path='navigator.ts'/>
|
||||
|
||||
module Data {
|
||||
"use strict";
|
||||
|
||||
export interface UserData {
|
||||
favorites: string[];
|
||||
recent: string[];
|
||||
today: string[];
|
||||
}
|
||||
|
||||
export interface Group {
|
||||
key: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
interface Groups {
|
||||
[idx: string]: Group;
|
||||
}
|
||||
|
||||
var groupsHash = <Groups>(<any>{
|
||||
recent: { key: 'recent', title: 'Recent' },
|
||||
favorites: { key: 'favorites', title: 'Favorites' },
|
||||
today: { key: 'today', title: 'Today' },
|
||||
nearby: { key: 'xxnearby', title: 'Nearby' }
|
||||
});
|
||||
|
||||
var list = new WinJS.Binding.List([]);
|
||||
|
||||
function saveUserData() {
|
||||
Windows.Storage.ApplicationData.current.localSettings.values["userdata"] = JSON.stringify(userData);
|
||||
}
|
||||
|
||||
var userdatastring: string = Windows.Storage.ApplicationData.current.localSettings.values["userdata"];
|
||||
var userData: UserData;
|
||||
//if (userdatastring != null) {
|
||||
// userData = JSON.parse(userdatastring);
|
||||
//} else {
|
||||
userData = {
|
||||
favorites: ['Topology', 'Windows 8', 'Windows Phone 7'],
|
||||
recent: ['Einstein', 'Quantum Field Theory', 'Einstein Field Equations', 'Macleay\'s Swallowtail', 'Gödel metric'],
|
||||
today: ['Transformers', 'XBox', 'Mount Rainier', 'Independence Day (film)', 'Independence Day', 'Roland Emmerich', 'Padmanabhaswamy Temple']
|
||||
};
|
||||
saveUserData();
|
||||
//}
|
||||
Object.keys(userData).forEach(function (groupName) {
|
||||
msSetImmediate(function () { populate(groupName, userData[groupName]); });
|
||||
});
|
||||
|
||||
function populate(groupName: string, itemTitles: string[]) {
|
||||
for (var i = 0; i < itemTitles.length; i++) {
|
||||
list.push(createTopicFromTitle(itemTitles[i], groupsHash[groupName]));
|
||||
}
|
||||
}
|
||||
var locator = new Windows.Devices.Geolocation.Geolocator();
|
||||
locator.getGeopositionAsync().then(function (pos) {
|
||||
var lat = pos.coordinate.latitude;
|
||||
var long = pos.coordinate.longitude;
|
||||
var url = 'http://api.wikilocation.org/articles?radius=100000&limit=10&lat=' + lat + '&lng=' + long;
|
||||
return WinJS.xhr({ url: url });
|
||||
}).then(function (xhr) {
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
addTopicsToGroup(data.articles, groupsHash['nearby']);
|
||||
}).done();
|
||||
|
||||
function addTopicsToGroup(articles: { title: string; }[], group: Data.Group) {
|
||||
articles.forEach(function (article) {
|
||||
msSetImmediate(function () {
|
||||
list.push(createTopicFromTitle(article.title, group));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function addFavorite(title: string) {
|
||||
if (userData.favorites.indexOf(title) == -1) {
|
||||
userData.favorites.push(title);
|
||||
saveUserData();
|
||||
var topic = createTopicFromTitle(title, groupsHash['favorites'])
|
||||
list.push(topic);
|
||||
Encyclopedia.addToTile(title, topic.localImageSrc);
|
||||
}
|
||||
}
|
||||
|
||||
export function removeFavorite(title: string) {
|
||||
var i = userData.favorites.indexOf(title);
|
||||
if (i != -1) {
|
||||
userData.favorites.splice(i, 1);
|
||||
saveUserData();
|
||||
var j = list.indexOf(createTopicFromTitle(title, groupsHash['favorites']));
|
||||
if (j != -1) {
|
||||
list.splice(j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var groupedItems = list.createGrouped(groupKeySelector, groupDataSelector);
|
||||
|
||||
function groupKeySelector(item) {
|
||||
return item.group.key;
|
||||
}
|
||||
|
||||
function groupDataSelector(item) {
|
||||
return item.group;
|
||||
}
|
||||
|
||||
export function getItemsFromGroup(group: Group) {
|
||||
return list.createFiltered(function (item) { return item.group.key === group.key; });
|
||||
}
|
||||
|
||||
export var items = groupedItems;
|
||||
export var groups = groupedItems.groups;
|
||||
export function getItemReference(item) {
|
||||
return [item.group.key, item.title];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='topic.ts'/>
|
||||
|
||||
module Default {
|
||||
"use strict";
|
||||
|
||||
var app = WinJS.Application;
|
||||
var activation = Windows.ApplicationModel.Activation;
|
||||
var nav = WinJS.Navigation;
|
||||
//WinJS.strictProcessing();
|
||||
|
||||
var searchPane = Windows.ApplicationModel.Search.SearchPane.getForCurrentView();
|
||||
searchPane.onquerysubmitted = function (ev: Windows.ApplicationModel.Search.ISearchPaneQuerySubmittedEventArgs) {
|
||||
var topic = createTopicFromTitle(ev.queryText, null);
|
||||
WinJS.Navigation.navigate('/html/itemDetailPage.html', { item: topic });
|
||||
}
|
||||
|
||||
searchPane.onsuggestionsrequested = function (ev: Windows.ApplicationModel.Search.SearchPaneSuggestionsRequestedEventArgs) {
|
||||
var deferral = ev.request.getDeferral();
|
||||
var url = 'http://en.wikipedia.org/w/api.php?action=opensearch&limit=20&search='
|
||||
+ encodeURI(ev.queryText);
|
||||
WinJS.xhr({ url: url }).then(function (xhr) {
|
||||
var data = JSON.parse(xhr.response);
|
||||
ev.request.searchSuggestionCollection.appendQuerySuggestions(data[1]);
|
||||
deferral.complete();
|
||||
});
|
||||
}
|
||||
|
||||
var settingsPane = Windows.UI.ApplicationSettings.SettingsPane.getForCurrentView();
|
||||
settingsPane.oncommandsrequested = function (ev: Windows.UI.ApplicationSettings.SettingsPaneCommandsRequestedEventArgs) {
|
||||
ev.request.applicationCommands.push(new Windows.UI.ApplicationSettings.SettingsCommand("1", "Encyclopedia Settings", function (a) {
|
||||
var panel = document.getElementById('KnownSettingsCommand.Preferences');
|
||||
WinJS.UI.process(panel);
|
||||
}));
|
||||
};
|
||||
|
||||
app.addEventListener("activated", function (args: WinJS.Application.ApplicationActivationEvent) {
|
||||
if (args.detail.kind === activation.ActivationKind.launch) {
|
||||
var launchEv = <Windows.ApplicationModel.Activation.LaunchActivatedEventArgs>args.detail;
|
||||
|
||||
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
|
||||
// TODO: This application has been newly launched. Initialize
|
||||
// your application here.
|
||||
} else {
|
||||
// TODO: This application has been reactivated from suspension.
|
||||
// Restore application state here.
|
||||
}
|
||||
|
||||
if (app.sessionState.history) {
|
||||
nav.history = app.sessionState.history;
|
||||
}
|
||||
args.setPromise(WinJS.UI.processAll().then(function () {
|
||||
if (nav.location) {
|
||||
nav.history.current.initialPlaceholder = true;
|
||||
return nav.navigate(nav.location, nav.state);
|
||||
} else {
|
||||
if (launchEv.arguments !== '') {
|
||||
var topic = createTopicFromTitle(launchEv.arguments, null);
|
||||
nav.navigate('/html/itemDetailPage.html', { item: topic });
|
||||
} else {
|
||||
return nav.navigate(Encyclopedia.navigator.home);
|
||||
}
|
||||
}
|
||||
}));
|
||||
} else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.search) {
|
||||
var searchEv = <Windows.ApplicationModel.Activation.SearchActivatedEventArgs>args.detail;
|
||||
WinJS.UI.processAll();
|
||||
var topic = createTopicFromTitle(searchEv.queryText, null);
|
||||
WinJS.Navigation.navigate('/html/itemDetailPage.html', { item: topic });
|
||||
}
|
||||
});
|
||||
|
||||
app.oncheckpoint = function (args) {
|
||||
// TODO: This application is about to be suspended. Save any state
|
||||
// that needs to persist across suspensions here. If you need to
|
||||
// complete an asynchronous operation before your application is
|
||||
// suspended, call args.setPromise().
|
||||
app.sessionState.history = nav.history;
|
||||
};
|
||||
|
||||
app.start();
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='data.ts'/>
|
||||
|
||||
module GroupDetailPage {
|
||||
"use strict";
|
||||
|
||||
var nav = WinJS.Navigation;
|
||||
var ui = WinJS.UI;
|
||||
var utils = WinJS.Utilities;
|
||||
var views = Windows.UI.ViewManagement;
|
||||
var group: Data.Group;
|
||||
var items;
|
||||
|
||||
function updateLayout(element: HTMLElement) {
|
||||
var listView = element.querySelector(".groupList").winControl;
|
||||
|
||||
if (views.ApplicationView.value === views.ApplicationViewState.snapped) {
|
||||
listView.layout = new ui.ListLayout();
|
||||
} else {
|
||||
listView.layout = new ui.GridLayout({ groupHeaderPosition: "left" });
|
||||
}
|
||||
}
|
||||
|
||||
function ready(element: HTMLElement, options: { group: Data.Group; }) {
|
||||
group = (options && options.group) ? options.group : Data.groups.getAt(0);
|
||||
items = Data.getItemsFromGroup(group);
|
||||
var pageList = items.createGrouped(
|
||||
function (item) { return group.key; },
|
||||
function (item) { return group; }
|
||||
);
|
||||
var groupDataSource = pageList.groups.dataSource;
|
||||
|
||||
element.querySelector("header[role=banner] .win-type-xx-large").textContent = group.title;
|
||||
setupMenu(element);
|
||||
|
||||
var listView = element.querySelector(".groupList").winControl;
|
||||
ui.setOptions(listView, {
|
||||
itemDataSource: pageList.dataSource,
|
||||
itemTemplate: element.querySelector(".itemTemplate"),
|
||||
groupDataSource: pageList.groups.dataSource,
|
||||
groupHeaderTemplate: element.querySelector(".headerTemplate"),
|
||||
oniteminvoked: itemInvoked
|
||||
});
|
||||
}
|
||||
|
||||
function itemInvoked(e) {
|
||||
var item = items.getAt(e.detail.itemIndex);
|
||||
nav.navigate("/html/itemDetailPage.html", { item: item });
|
||||
}
|
||||
|
||||
function setupMenu(element: HTMLElement) {
|
||||
var commandList = [];
|
||||
Data.groups.forEach(function (group) {
|
||||
commandList.push({
|
||||
label: group.title, onclick: function () {
|
||||
nav.navigate("/html/groupDetailPage.html", { group: group });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var menu = new ui.Menu(element.querySelector("header[role=banner] .menu"), { commands: commandList });
|
||||
var title = <HTMLElement>element.querySelector(".titleArea .win-type-xx-large");
|
||||
|
||||
title.onclick = function (eventObject) { menu.show(title, "bottom", "left"); };
|
||||
title.onkeypress = function (eventObject) {
|
||||
if (eventObject.keyCode === utils.Key.enter || eventObject.keyCode === utils.Key.space) {
|
||||
menu.show(title, "bottom", "left");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ui.Pages.define("/html/groupDetailPage.html", {
|
||||
ready: ready,
|
||||
updateLayout: updateLayout
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='data.ts'/>
|
||||
|
||||
module GroupedItemsPage {
|
||||
"use strict";
|
||||
|
||||
var appView = Windows.UI.ViewManagement.ApplicationView;
|
||||
var appViewState = Windows.UI.ViewManagement.ApplicationViewState;
|
||||
var nav = WinJS.Navigation;
|
||||
var ui = WinJS.UI;
|
||||
var utils = WinJS.Utilities;
|
||||
|
||||
ui.Pages.define("/html/groupedItemsPage.html", {
|
||||
|
||||
// This function updates the ListView with new layouts
|
||||
initializeLayout: function (listView, viewState) {
|
||||
|
||||
if (viewState === appViewState.snapped) {
|
||||
listView.itemDataSource = Data.groups.dataSource;
|
||||
listView.groupDataSource = null;
|
||||
listView.layout = new ui.ListLayout();
|
||||
} else {
|
||||
listView.itemDataSource = Data.items.dataSource;
|
||||
listView.groupDataSource = Data.groups.dataSource;
|
||||
listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });
|
||||
}
|
||||
},
|
||||
|
||||
itemInvoked: function (args) {
|
||||
if (appView.value === appViewState.snapped) {
|
||||
// If the page is snapped, the user invoked a group.
|
||||
var group = Data.groups.getAt(args.detail.itemIndex);
|
||||
nav.navigate("/html/groupDetailPage.html", { groupKey: group.key });
|
||||
} else {
|
||||
// If the page is not snapped, the user invoked an item.
|
||||
var item = Data.items.getAt(args.detail.itemIndex);
|
||||
nav.navigate("/html/itemDetailPage.html", { item: item });
|
||||
}
|
||||
},
|
||||
|
||||
// This function is called whenever a user navigates to this page. It
|
||||
// populates the page elements with the app's data.
|
||||
ready: function (element, options) {
|
||||
var listView = element.querySelector(".groupeditemslist").winControl;
|
||||
listView.groupHeaderTemplate = element.querySelector(".headerTemplate");
|
||||
listView.itemTemplate = element.querySelector(".itemtemplate");
|
||||
listView.oniteminvoked = this.itemInvoked.bind(this);
|
||||
|
||||
var appbarControl = (<any> document.querySelector('#appbar')).winControl;
|
||||
appbarControl.hideCommands(['addfavorite', 'removefavorite', 'pin']);
|
||||
|
||||
this.initializeLayout(listView, appView.value);
|
||||
listView.element.focus();
|
||||
},
|
||||
|
||||
// This function updates the page layout in response to viewState changes.
|
||||
updateLayout: function (element, viewState, lastViewState) {
|
||||
|
||||
var listView = element.querySelector(".groupeditemslist").winControl;
|
||||
if (lastViewState !== viewState) {
|
||||
if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
|
||||
var handler: (e: Event) => void = function (e) {
|
||||
listView.removeEventListener("contentanimating", handler, false);
|
||||
e.preventDefault();
|
||||
}
|
||||
listView.addEventListener("contentanimating", handler, false);
|
||||
this.initializeLayout(listView, viewState);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//"use strict";
|
||||
|
||||
//var appView = Windows.UI.ViewManagement.ApplicationView;
|
||||
//var appViewState = Windows.UI.ViewManagement.ApplicationViewState;
|
||||
//var nav = WinJS.Navigation;
|
||||
//var ui = WinJS.UI;
|
||||
//var utils = WinJS.Utilities;
|
||||
|
||||
//function updateLayout(element: HTMLElement) {
|
||||
// var listView = element.querySelector(".landingList").winControl;
|
||||
// if (appLayout.value === appLayoutState.snapped) {
|
||||
// ui.setOptions(listView, {
|
||||
// itemDataSource: data.items.dataSource,
|
||||
// itemTemplate: element.querySelector(".itemTemplate"),
|
||||
// groupDataSource: null,
|
||||
// oniteminvoked: itemInvoked
|
||||
// });
|
||||
|
||||
// listView.layout = new ui.ListLayout();
|
||||
// } else {
|
||||
// var groupDataSource = data.items.createGrouped(groupKeySelector, groupDataSelector).groups;
|
||||
|
||||
// ui.setOptions(listView, {
|
||||
// itemDataSource: data.items.dataSource,
|
||||
// itemTemplate: element.querySelector(".itemTemplate"),
|
||||
// groupDataSource: groupDataSource.dataSource,
|
||||
// groupHeaderTemplate: element.querySelector(".headerTemplate"),
|
||||
// oniteminvoked: itemInvoked
|
||||
// });
|
||||
// listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });
|
||||
// }
|
||||
//}
|
||||
|
||||
//function groupKeySelector(item) {
|
||||
// return item.group.key;
|
||||
//}
|
||||
|
||||
//function groupDataSelector(item) {
|
||||
// return {
|
||||
// title: item.group.title,
|
||||
// click: function () {
|
||||
// nav.navigate("/html/groupDetailPage.html", { group: item.group });
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//function ready(element: HTMLElement, options) {
|
||||
// var appbarControl = (<any> document.querySelector('#appbar')).winControl;
|
||||
// appbarControl.hideCommands(['addfavorite', 'removefavorite', 'pin']);
|
||||
|
||||
// setupMenu(element);
|
||||
//}
|
||||
|
||||
//function itemInvoked(e: {detail: {itemIndex: number; }; }) {
|
||||
// //if (appLayout.value === appLayoutState.snapped) {
|
||||
// // var group = data.groups.getAt(e.detail.itemIndex);
|
||||
// // nav.navigate("/html/groupDetailPage.html", { group: group });
|
||||
// //} else {
|
||||
// var item = data.items.getAt(e.detail.itemIndex);
|
||||
// nav.navigate("/html/itemDetailPage.html", { item: item });
|
||||
// //}
|
||||
//}
|
||||
|
||||
//function setupMenu(element: HTMLElement) {
|
||||
// var commandList = [];
|
||||
// //data.groups.forEach(function (group) {
|
||||
// // commandList.push({
|
||||
// // label: group.title, onclick: function () {
|
||||
// // nav.navigate("/html/groupDetailPage.html", { group: group });
|
||||
// // }
|
||||
// // });
|
||||
// //});
|
||||
|
||||
// var menu = new ui.Menu(element.querySelector("header[role=banner] .menu"), { commands: commandList });
|
||||
// var title = element.querySelector(".titleArea .win-type-xx-large");
|
||||
|
||||
// //title.onclick = function (eventObject) { menu.show(title, "bottom", "left"); };
|
||||
// //title.onkeypress = function (eventObject) {
|
||||
// // if (eventObject.keyCode === utils.Key.enter || eventObject.keyCode === utils.Key.space) {
|
||||
// // menu.show(title, "bottom", "left");
|
||||
// // }
|
||||
// //};
|
||||
//}
|
||||
|
||||
//ui.Pages.define("/html/groupedItemsPage.html", {
|
||||
// ready: ready,
|
||||
// updateLayout: updateLayout
|
||||
//});
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='topic.ts'/>
|
||||
///<reference path='data.ts'/>
|
||||
|
||||
module ItemDetailPage {
|
||||
"use strict";
|
||||
|
||||
var ui = WinJS.UI;
|
||||
var utils = WinJS.Utilities;
|
||||
|
||||
function ready(element: HTMLElement, options: { item: Topic; }) {
|
||||
|
||||
var item: Topic = options && options.item ? options.item : Data.items.getAt(0);
|
||||
element.querySelector(".titlearea .pagetitle").textContent = item.title;
|
||||
var content = <HTMLElement>element.querySelector('.content');
|
||||
goToPage(content, item);
|
||||
document.body.focus();
|
||||
setupMenu(element);
|
||||
|
||||
var appbarControl = document.querySelector('#appbar').winControl;
|
||||
appbarControl.showCommands(['addfavorite', 'removefavorite', 'pin']);
|
||||
var pin = appbarControl.getCommandById('pin');
|
||||
pin.onclick = function handler() {
|
||||
var uri = new Windows.Foundation.Uri("ms-appdata:///local/" + item.localImageSrc);
|
||||
var tile = new Windows.UI.StartScreen.SecondaryTile();
|
||||
tile.tileId = encodeURIComponent(item.title);
|
||||
tile.displayName = item.title;
|
||||
tile.shortName = item.title;
|
||||
tile.arguments = item.title;
|
||||
tile.tileOptions = Windows.UI.StartScreen.TileOptions.showNameOnLogo;
|
||||
tile.logo = uri;
|
||||
tile.foregroundText = Windows.UI.StartScreen.ForegroundText.light;
|
||||
tile.requestCreateAsync().done();
|
||||
}
|
||||
}
|
||||
|
||||
function setupMenu(elements: Element) {
|
||||
var commandList = [];
|
||||
var menu = new ui.Menu(elements.querySelector('header[role=banner] .menu'), { commands: commandList });
|
||||
var title = elements.querySelector('.titleArea .win-type-xx-large');
|
||||
}
|
||||
|
||||
|
||||
function goToPage(rootElem: HTMLElement, topic: Topic) {
|
||||
|
||||
topic.htmlContent.done(function(bodyInnerText: string) {
|
||||
//document.querySelector(".win-contentTitle").innerText = topic.title;
|
||||
MSApp.execUnsafeLocalFunction(function() {
|
||||
rootElem.innerHTML = toStaticHTML(bodyInnerText);
|
||||
Array.prototype.forEach.call(rootElem.querySelectorAll('*[href]'), function(a: HTMLAnchorElement) {
|
||||
a.addEventListener("click", function(ev) {
|
||||
//console.log("Clicked: " + ev.target + ", " + ev.currentTarget.href);
|
||||
ev.preventDefault();
|
||||
var url = a.href;
|
||||
if (url.indexOf('ms-appx:') == 0) {
|
||||
var i = a.href.lastIndexOf('\/');
|
||||
var topicRef = decodeURIComponent(a.href.slice(i + 1)).replace(/_/g, " ");
|
||||
var topic = createTopicFromTitle(topicRef, null);
|
||||
WinJS.Navigation.navigate("/html/itemDetailPage.html", { item: topic });
|
||||
}
|
||||
else {
|
||||
var dialog = new Windows.UI.Popups.MessageDialog("This link will take you to an external page. Would you like to launch the browser?", "Open external browser?");
|
||||
dialog.commands.push(new Windows.UI.Popups.UICommand("launch browser", function() {
|
||||
// External page
|
||||
Windows.System.Launcher.launchUriAsync(new Windows.Foundation.Uri(url)).done();
|
||||
}));
|
||||
dialog.commands.push(new Windows.UI.Popups.UICommand("cancel", function() { }));
|
||||
dialog.showAsync().done();
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
}, noInternetConnection);
|
||||
}
|
||||
|
||||
function refreshCurrent(element: Element) {
|
||||
var title = element.querySelector(".itemDetailPage header[role=banner] .pagetitle").textContent;
|
||||
var topic = createTopicFromTitle(title, null);
|
||||
downloadAndCacheLocally(topic);
|
||||
goToPage(<HTMLElement>element.querySelector('.content'), topic);
|
||||
}
|
||||
|
||||
ui.Pages.define("/html/itemDetailPage.html", {
|
||||
ready: ready,
|
||||
refreshCurrent: refreshCurrent
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='data.ts'/>
|
||||
|
||||
module Encyclopedia {
|
||||
"use strict";
|
||||
|
||||
var appView = Windows.UI.ViewManagement.ApplicationView;
|
||||
var displayProps = Windows.Graphics.Display.DisplayProperties;
|
||||
var nav = WinJS.Navigation;
|
||||
var ui = WinJS.UI;
|
||||
var utils = WinJS.Utilities;
|
||||
|
||||
export var navigator: PageControlNavigator = null;
|
||||
|
||||
export class PageControlNavigator {
|
||||
|
||||
public element = <HTMLElement>null;
|
||||
public home = "";
|
||||
public lastViewstate = 0;
|
||||
|
||||
// Define the constructor function for the PageControlNavigator.
|
||||
constructor(element: Element, options: { home: string; }) {
|
||||
this.element = <HTMLElement>(element || document.createElement("div"));
|
||||
this.element.appendChild(this._createPageElement());
|
||||
|
||||
this.home = options.home;
|
||||
this.lastViewstate = appView.value;
|
||||
|
||||
nav.onnavigated = <any>this._navigated.bind(this);
|
||||
window.onresize = <any>this._resized.bind(this);
|
||||
|
||||
document.body.onkeyup = <any>this._keyupHandler.bind(this);
|
||||
document.body.onkeypress = <any>this._keypressHandler.bind(this);
|
||||
document.body.onmspointerup = <any>this._mspointerupHandler.bind(this);
|
||||
|
||||
Encyclopedia.navigator = this;
|
||||
}
|
||||
|
||||
private get pageControl() { return this.pageElement && this.pageElement.winControl; }
|
||||
private get pageElement() { return this.element.firstElementChild; }
|
||||
|
||||
// This function creates a new container for each page.
|
||||
private _createPageElement() {
|
||||
var element = <HTMLElement>document.createElement("div");
|
||||
element.style.width = "100%";
|
||||
element.style.height = "100%";
|
||||
return element;
|
||||
}
|
||||
|
||||
// This function responds to keypresses to only navigate when
|
||||
// the backspace key is not used elsewhere.
|
||||
private _keypressHandler(args) {
|
||||
if (args.key === "Backspace") {
|
||||
nav.back();
|
||||
}
|
||||
}
|
||||
|
||||
private _keyupHandler(args) {
|
||||
if ((args.key === "Left" && args.altKey) || (args.key === "BrowserBack")) {
|
||||
nav.back();
|
||||
} else if ((args.key === "Right" && args.altKey) || (args.key === "BrowserForward")) {
|
||||
nav.forward();
|
||||
}
|
||||
}
|
||||
|
||||
private _mspointerupHandler(args) {
|
||||
if (args.button === 3) {
|
||||
nav.back();
|
||||
} else if (args.button === 4) {
|
||||
nav.forward();
|
||||
}
|
||||
}
|
||||
|
||||
private _fwdbackHandler(e: KeyboardEvent) {
|
||||
if (e.altKey) {
|
||||
switch (e.keyCode) {
|
||||
case utils.Key.leftArrow: nav.back(); break;
|
||||
case utils.Key.rightArrow: nav.forward(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//private _viewstatechanged(e) {
|
||||
// this._updateLayout()(this.pageElement, e.layout, displayProps.currentOrientation);
|
||||
//}
|
||||
|
||||
// This function responds to navigation by adding new pages
|
||||
// to the DOM.
|
||||
private _navigated(args) {
|
||||
var oldElement = <HTMLElement>this.pageElement;
|
||||
var newElement = this._createPageElement();
|
||||
var parentedComplete;
|
||||
var parented = new WinJS.Promise(function(c) { parentedComplete = c; });
|
||||
|
||||
args.detail.setPromise(
|
||||
WinJS.Promise.timeout().then(function() {
|
||||
if (oldElement.winControl && oldElement.winControl.unload) {
|
||||
oldElement.winControl.unload();
|
||||
}
|
||||
return WinJS.UI.Pages.render(args.detail.location, newElement, args.detail.state, parented);
|
||||
}).then((control) => {
|
||||
this.element.appendChild(newElement);
|
||||
this.element.removeChild(oldElement);
|
||||
oldElement.innerText = "";
|
||||
this.navigated();
|
||||
parentedComplete();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _resized(args) {
|
||||
if (this.pageControl && this.pageControl.updateLayout) {
|
||||
this.pageControl.updateLayout.call(this.pageControl, this.pageElement, appView.value, this.lastViewstate);
|
||||
}
|
||||
this.lastViewstate = appView.value;
|
||||
}
|
||||
|
||||
//private _updateLayout() { return (this.pageControl() && this.pageControl().updateLayout) || function() { }; }
|
||||
|
||||
// This function updates application controls once a navigation
|
||||
// has completed.
|
||||
public navigated() {
|
||||
// Do application specific on-navigated work here
|
||||
var backButton = <HTMLElement>this.pageElement.querySelector("header[role=banner] .win-backbutton");
|
||||
if (backButton != null) {
|
||||
backButton.onclick = function() { nav.back(); };
|
||||
|
||||
if (nav.canGoBack) {
|
||||
backButton.removeAttribute("disabled");
|
||||
}
|
||||
else {
|
||||
backButton.setAttribute("disabled", "disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
WinJS.Utilities.markSupportedForProcessing(PageControlNavigator);
|
||||
|
||||
export function navigateHome() {
|
||||
var home = <string>document.querySelector("#contenthost").winControl.home;
|
||||
var loc = nav.location;
|
||||
if (loc !== "" && loc !== home) {
|
||||
nav.navigate(home);
|
||||
}
|
||||
}
|
||||
WinJS.Utilities.markSupportedForProcessing(navigateHome);
|
||||
|
||||
export function refresh() {
|
||||
var control = (<any>document.querySelector("#contenthost")).winControl;
|
||||
if (control && control.pageControl && control.pageControl.refreshCurrent) {
|
||||
control.pageControl.refreshCurrent(control.element);
|
||||
}
|
||||
}
|
||||
WinJS.Utilities.markSupportedForProcessing(refresh);
|
||||
|
||||
export function addFavorite() {
|
||||
var control = (<any>document.querySelector("#contenthost")).winControl;
|
||||
if (control && control.pageControl && control.pageControl.refreshCurrent) {
|
||||
var elem: Element = control.element.querySelector(".itemDetailPage header[role=banner] .pagetitle");
|
||||
var title = elem.textContent;
|
||||
Data.addFavorite(title);
|
||||
}
|
||||
}
|
||||
WinJS.Utilities.markSupportedForProcessing(addFavorite);
|
||||
|
||||
export function removeFavorite() {
|
||||
var control = (<any>document.querySelector("#contenthost")).winControl;
|
||||
if (control && control.pageControl && control.pageControl.refreshCurrent) {
|
||||
var title = control.element.querySelector(".itemDetailPage header[role=banner] .pagetitle").textContent;
|
||||
Data.removeFavorite(title);
|
||||
}
|
||||
}
|
||||
WinJS.Utilities.markSupportedForProcessing(removeFavorite);
|
||||
|
||||
export function addToTile(text: string, imgSrc: string) {
|
||||
var tileUpdater = Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication();
|
||||
var template = Windows.UI.Notifications.TileTemplateType.tileWideImageAndText01;
|
||||
var tileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(template);
|
||||
var tileTextAttributes = tileXml.getElementsByTagName("text");
|
||||
tileTextAttributes.forEach(function(value, index) {
|
||||
value.appendChild(tileXml.createTextNode("textField " + (index + 1)));
|
||||
});
|
||||
var tileImageAttributes = tileXml.getElementsByTagName("image");
|
||||
var imgUri = new Windows.Foundation.Uri(Windows.Storage.ApplicationData.current.localFolder.path + "/").combineUri(imgSrc);
|
||||
var elem = <Windows.Data.Xml.Dom.IXmlElement>tileImageAttributes.getAt(0);
|
||||
elem.setAttribute("src", imgUri.absoluteUri);
|
||||
elem.setAttribute("alt", "graphic");
|
||||
elem.setAttribute("id", "1");
|
||||
var tileNotification = new Windows.UI.Notifications.TileNotification(tileXml);
|
||||
tileUpdater.enableNotificationQueue(true);
|
||||
tileUpdater.update(tileNotification);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
///<reference path='win.ts'/>
|
||||
///<reference path='data.ts'/>
|
||||
|
||||
interface Topic {
|
||||
group: any;
|
||||
title: string;
|
||||
imageSrc: string;
|
||||
localImageSrc: string;
|
||||
htmlContent: any;
|
||||
}
|
||||
|
||||
var topiccache: { [name: string]: Topic } = {};
|
||||
|
||||
function createTopicFromUrl(url: string, group: Data.Group): Topic {
|
||||
var encodedName = url.slice(url.lastIndexOf('/') + 1);
|
||||
var title = decodeURIComponent(encodedName).replace('_', ' ');
|
||||
return createTopicFromTitle(title, group);
|
||||
}
|
||||
|
||||
function downloadImageAndStoreLocal(bodyInnerText: string, topic: Topic) {
|
||||
var imageSrc = findImage(bodyInnerText);
|
||||
WinJS.xhr({ url: imageSrc, responseType: "blob" }).then(function (xhr) {
|
||||
var blob = xhr.response;
|
||||
topic.imageSrc = URL.createObjectURL(blob);
|
||||
var encodedImageUri = imageSrc.slice(imageSrc.lastIndexOf('/') + 1);
|
||||
topic.localImageSrc = encodedImageUri;
|
||||
Windows.Storage.ApplicationData.current.localFolder.createFileAsync(encodedImageUri, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (file) {
|
||||
file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(function (ras) {
|
||||
var inputStream = blob.msDetachStream().getInputStreamAt(0);
|
||||
var outputStream = ras.getOutputStreamAt(0);
|
||||
Windows.Storage.Streams.RandomAccessStream.copyAsync(inputStream, outputStream).then(function () {
|
||||
inputStream.close();
|
||||
return outputStream.flushAsync();
|
||||
}).done();
|
||||
}).then(function () {
|
||||
Windows.Storage.ApplicationData.current.localSettings.values[topic.title + "image"] = encodedImageUri;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createTopicFromTitle(title: string, group: Data.Group): Topic {
|
||||
var topic = topiccache[title + "--" + (group && group.title)];
|
||||
if (topic)
|
||||
return topic;
|
||||
|
||||
// Create the topic as a databindable object
|
||||
topic = WinJS.Binding.as({
|
||||
group: group,
|
||||
title: title,
|
||||
imageSrc: null,
|
||||
localImageSrc: null
|
||||
});
|
||||
|
||||
// Kick off the work to aquire the HTML content
|
||||
var url = "http://en.wikipedia.org/w/index.php?title=" + encodeURI(title);
|
||||
|
||||
var htmlContentPromise: WinJS.Promise<string>;
|
||||
var localContent = Windows.Storage.ApplicationData.current.localSettings.values[title];
|
||||
|
||||
//
|
||||
htmlContentPromise = localContent ? retrieveCached(topic) : downloadAndCacheLocally(topic);
|
||||
|
||||
// Don't want the topic to be tracked by the observable (TODO: I'm sure there is a 'better' way to do this)
|
||||
topic.htmlContent = htmlContentPromise;
|
||||
|
||||
topiccache[title + "--" + (group && group.title)] = topic;
|
||||
return topic;
|
||||
}
|
||||
|
||||
function retrieveCached(topic: Topic) {
|
||||
// If content is already available locally:
|
||||
// 1) set the htmlContentPromise to read it from disk
|
||||
// 2) in parallel, grab the image from disk and display it.
|
||||
var title = topic.title;
|
||||
var encodedTitle = encodeURIComponent(title);
|
||||
var htmlContentPromise = WinJS.Application.local.readText(encodedTitle + ".html");
|
||||
var localImageSrc = <string>Windows.Storage.ApplicationData.current.localSettings.values[title + "image"];
|
||||
topic.localImageSrc = localImageSrc;
|
||||
|
||||
Windows.Storage.ApplicationData.current.localFolder.getFileAsync(localImageSrc)
|
||||
.then(function (file) {
|
||||
return file.openAsync(Windows.Storage.FileAccessMode.read);
|
||||
}).then(function (ras) {
|
||||
var blob = MSApp.createBlobFromRandomAccessStream("image/png", ras);
|
||||
topic.imageSrc = URL.createObjectURL(blob);
|
||||
}).then(null, function (err) {
|
||||
// The image file wasn't available for some reason,
|
||||
// retry downloading the image.
|
||||
return htmlContentPromise.then(function (bodyInnerHtml) {
|
||||
downloadImageAndStoreLocal(bodyInnerHtml, topic);
|
||||
});
|
||||
}).done();
|
||||
|
||||
return htmlContentPromise;
|
||||
}
|
||||
|
||||
function downloadAndCacheLocally(topic: Topic) {
|
||||
// If content is *not* already available locally, set htmlContentPromise to do the following:
|
||||
// 1) read it from the network
|
||||
// 2) then write it to local disk
|
||||
// 2.5) also record in local settings that it is stored locally
|
||||
// 3) find the associated image
|
||||
// 4) set that as the databound imageSrc
|
||||
// 5) write the image to disk
|
||||
// 5.5) also record in local settings that it is stored locally
|
||||
var title = topic.title;
|
||||
var url = "http://en.wikipedia.org/w/index.php?title=" + encodeURI(title);
|
||||
var htmlContentPromise = WinJS.xhr({ url: url })
|
||||
.then(function (result) {
|
||||
var text = <string>result.response;
|
||||
var bodyStartStart = text.indexOf("<body");
|
||||
var bodyStartEnd = text.indexOf(">", bodyStartStart) + 1;
|
||||
var bodyEndStart = text.indexOf("</body>");
|
||||
text = text.slice(bodyStartEnd, bodyEndStart);
|
||||
text = text.replace(/"\/\//g, '"http://');
|
||||
return text;
|
||||
});
|
||||
|
||||
var encodedTitle = encodeURIComponent(title);
|
||||
|
||||
var bodyInnerText: string = null;
|
||||
htmlContentPromise.then(function (innerText) {
|
||||
bodyInnerText = innerText;
|
||||
// Store text to local storage
|
||||
return WinJS.Application.local.writeText(encodedTitle + ".html", bodyInnerText);
|
||||
}).then(function () {
|
||||
Windows.Storage.ApplicationData.current.localSettings.values[title] = encodedTitle + ".html";
|
||||
// Download the image and store to local storage
|
||||
return downloadImageAndStoreLocal(bodyInnerText, topic);
|
||||
}).done(null, function (err) {
|
||||
if (err instanceof XMLHttpRequest) {
|
||||
return;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
return htmlContentPromise;
|
||||
}
|
||||
|
||||
function findImage(bodyHtml: string) {
|
||||
var dummyDiv = document.createElement('div');
|
||||
dummyDiv.innerHTML = toStaticHTML(bodyHtml);
|
||||
var imgs: HTMLImageElement[] = Array.prototype.slice.call(dummyDiv.getElementsByTagName('img'), 0);
|
||||
imgs = imgs.filter(function (img) {
|
||||
var widthAttr = img.attributes["width"];
|
||||
if (!widthAttr) return false;
|
||||
var keep = (+widthAttr.value) > 100;
|
||||
return keep;
|
||||
});
|
||||
imgs.forEach(function (img, i) {
|
||||
img.attributes["width"].value *= (1 - (i / imgs.length) / 2);
|
||||
img.attributes["height"].value *= (1 - (i / imgs.length) / 2);
|
||||
});
|
||||
imgs.sort(function (img1, img2) {
|
||||
var awidth = +img1.attributes["width"].value;
|
||||
var aheight = +img1.attributes["height"].value;
|
||||
var bwidth = +img2.attributes["width"].value;
|
||||
var bheight = +img2.attributes["height"].value;
|
||||
return Math.min(bwidth, bheight) - Math.min(awidth, aheight);
|
||||
});
|
||||
var jpgs = imgs.filter(function (img) {
|
||||
var s = img.src;
|
||||
if (s.slice(s.length - 4) == ".jpg" || s.slice(s.length - 5) == ".jpeg")
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
if (jpgs.length > 0 && (+jpgs[0].attributes["width"].value > 100) && (+jpgs[0].attributes["height"].value > 100)) {
|
||||
return jpgs[0].src;
|
||||
} else if (imgs.length > 0) {
|
||||
return (<HTMLImageElement>imgs[0]).src;
|
||||
} else {
|
||||
return "http://upload.wikimedia.org/wikipedia/commons/6/63/Wikipedia-logo.png";
|
||||
}
|
||||
}
|
||||
|
||||
function noInternetConnection(err) {
|
||||
var flyout = new Windows.UI.Popups.MessageDialog("No internet connection");
|
||||
flyout.showAsync().done();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
///<reference path='..\..\..\..\..\typings\winrt.d.ts'/>
|
||||
///<reference path='..\..\..\..\..\typings\winjs.d.ts'/>
|
||||
|
||||
declare var msSetImmediate: (expression: any) => void;
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
|
||||
<Identity Name="55019TS.Encyclopedia" Version="1.0.0.5" Publisher="CN=2D965ED7-3EF5-4803-AEC3-26E173EE9D03" />
|
||||
<Properties>
|
||||
<DisplayName>Encyclopedia</DisplayName>
|
||||
<Description>Encyclopedia</Description>
|
||||
<PublisherDisplayName>TS</PublisherDisplayName>
|
||||
<Logo>images\ep-storelogo.png</Logo>
|
||||
</Properties>
|
||||
<Prerequisites>
|
||||
<OSMinVersion>6.2</OSMinVersion>
|
||||
<OSMaxVersionTested>6.2</OSMaxVersionTested>
|
||||
</Prerequisites>
|
||||
<Resources>
|
||||
<Resource Language="en-US" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" StartPage="default.html">
|
||||
<VisualElements DisplayName="Encyclopedia" Logo="images\ep-logo.png" SmallLogo="images\ep-logo-small.png" Description="Encyclopedia" ForegroundText="light" BackgroundColor="#0084FF" ToastCapable="false">
|
||||
<DefaultTile ShowName="allLogos" WideLogo="images\ep-widetile.png" />
|
||||
<SplashScreen Image="images\ep-splashscreen.png" BackgroundColor="#FFFFFF" />
|
||||
</VisualElements>
|
||||
<Extensions>
|
||||
<Extension Category="windows.search" StartPage="default.html" />
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
<DeviceCapability Name="location" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||