├── src
├── components
│ ├── test.styl
│ └── test.component.ts
├── typings
│ └── webpack.d.ts
├── app.component.ts
├── app.routes.ts
├── index.html
├── vendor.ts
├── bootstrap.ts
├── app.component.spec.ts
└── ie-shims
│ └── ie-shims.js
├── jsconfig.json
├── .gitignore
├── test
└── app.e2e.js
├── tsconfig.json
├── protractor.conf.js
├── karma.entry.ts
├── typings.json
├── tslint.json
├── .editorconfig
├── README.md
├── webpack.config.js
├── package.json
└── karma.conf.js
/src/components/test.styl:
--------------------------------------------------------------------------------
1 | :host
2 | color #333
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/typings/webpack.d.ts:
--------------------------------------------------------------------------------
1 | declare let WEBPACK_ENV: string;
2 | declare let System: {
3 | import: Function
4 | };
5 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log
2 |
3 | node_modules
4 |
5 | dist
6 |
7 | coverage
8 |
9 | typings
10 |
11 | .vscode
12 | .idea
13 |
--------------------------------------------------------------------------------
/src/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'sg-app',
5 | template: `
6 |
7 | `
8 | })
9 | export class AppComponent {}
10 |
--------------------------------------------------------------------------------
/test/app.e2e.js:
--------------------------------------------------------------------------------
1 | describe('App', () => {
2 |
3 | beforeEach(() => {
4 | browser.get('/');
5 | });
6 |
7 | it('should have proper title', () => {
8 | expect(browser.getTitle()).toEqual('Angular 2');
9 | });
10 |
11 | });
12 |
--------------------------------------------------------------------------------
/src/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes } from '@angular/router';
2 | import { TestComponent } from './components/test.component';
3 |
4 | export const AppRoutes: Routes = [
5 | { path: '', component: TestComponent },
6 | { path: 'test', component: TestComponent }
7 | ];
8 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Angular 2
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/components/test.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'sg-test',
5 | template: 'Hello from component: {{ test }}',
6 | styles: [require('./test.styl').toString()]
7 | })
8 | export class TestComponent {
9 | public test: string = 'test';
10 | constructor() {}
11 | }
12 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "buildOnSave": false,
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "target": "ES5",
6 | "module": "commonjs",
7 | "inlineSourceMap": true,
8 | "sourceMap": false,
9 | "emitDecoratorMetadata": true,
10 | "experimentalDecorators": true,
11 | "removeComments": false,
12 | "noImplicitAny": true,
13 | "types": ["node", "jasmine"]
14 | },
15 | "exclude": [
16 | "node_modules"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/src/vendor.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | // local shims
4 | import './ie-shims/ie-shims';
5 |
6 | // polyfills
7 | import 'core-js';
8 |
9 | // (these modules are what is in 'angular2/bundles/angular2-polyfills' so don't use that here)
10 | import 'reflect-metadata';
11 |
12 | require('zone.js/dist/zone');
13 |
14 | if (WEBPACK_ENV !== 'production') {
15 | require('zone.js/dist/long-stack-trace-zone');
16 | }
17 |
18 | // Angular 2 Deps
19 | import 'rxjs/Rx';
20 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | baseUrl: 'http://localhost:8080/',
3 |
4 | allScriptsTimeout: 10000,
5 |
6 | framework: 'jasmine',
7 |
8 | jasmineNodeOpts: {
9 | defaultTimeoutInterval: 60000,
10 | showTiming: true
11 | },
12 |
13 | capabilities: {
14 | 'browserName': 'chrome',
15 | 'chromeOptions': {
16 | 'args': ['show-fps-counter=true']
17 | }
18 | },
19 |
20 | specs: [
21 | 'test/**/*.e2e.js'
22 | ],
23 |
24 | onPrepare: function() {
25 | require('babel-core/register');
26 | browser.ignoreSynchronization = true;
27 | }
28 |
29 | };
30 |
--------------------------------------------------------------------------------
/karma.entry.ts:
--------------------------------------------------------------------------------
1 | import 'reflect-metadata';
2 | import 'zone.js/dist/zone';
3 | import 'zone.js/dist/sync-test';
4 | import 'zone.js/dist/async-test';
5 | import 'zone.js/dist/fake-async-test';
6 | import 'zone.js/dist/proxy';
7 | import 'zone.js/dist/jasmine-patch';
8 |
9 | const testContext = (<{ context?: Function }>require).context('./src', true, /\.spec\.ts/);
10 | testContext.keys().forEach(testContext);
11 |
12 | const coverageContext = (<{ context?: Function }>require).context(
13 | './src',
14 | true,
15 | /^(?=(?!.*[.]spec\.ts))(?=(?!.*[.]d\.ts))(?=(?!\.\/bootstrap\.ts$))(?=(?!\.\/vendor\.ts$)).*\.ts$/
16 | );
17 | coverageContext.keys().forEach(coverageContext);
18 |
--------------------------------------------------------------------------------
/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {},
3 | "globalDependencies": {
4 | "angular-protractor": "github:DefinitelyTyped/DefinitelyTyped/angular-protractor/angular-protractor.d.ts#17fa1e5f269189f7f8e0f53f8c443e6c2eac562c",
5 | "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#7de6c3dd94feaeb21f20054b9f30d5dabc5efabd",
6 | "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#bc92442c075929849ec41d28ab618892ba493504",
7 | "node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#aee0039a2d6686ec78352125010ebb38a7a7d743",
8 | "selenium-webdriver": "github:DefinitelyTyped/DefinitelyTyped/selenium-webdriver/selenium-webdriver.d.ts#a83677ed13add14c2ab06c7325d182d0ba2784ea"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "directive-selector": [true, "attribute", "sg", "camelCase"],
7 | "component-selector": [true, "element", "sg", "kebab-case"],
8 | "use-input-property-decorator": true,
9 | "use-output-property-decorator": true,
10 | "use-host-property-decorator": true,
11 | "no-attribute-parameter-decorator": true,
12 | "no-input-rename": true,
13 | "no-output-rename": true,
14 | "no-forward-ref" :true,
15 | "use-life-cycle-interface": true,
16 | "use-pipe-transform-interface": true,
17 | "pipe-naming": [true, "camelCase", "sg"],
18 | "component-class-suffix": true,
19 | "directive-class-suffix": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.js]
17 | indent_style = space
18 | indent_size = 2
19 |
20 | [*.hbs]
21 | insert_final_newline = false
22 | indent_style = space
23 | indent_size = 2
24 |
25 | [*.css]
26 | indent_style = space
27 | indent_size = 2
28 |
29 | [*.styl]
30 | indent_style = space
31 | indent_size = 2
32 |
33 | [*.html]
34 | indent_style = space
35 | indent_size = 2
36 |
37 | [*.{diff,md}]
38 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/src/bootstrap.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 |
3 | if (WEBPACK_ENV === 'production') {
4 | enableProdMode();
5 | }
6 |
7 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
8 |
9 | import { NgModule } from '@angular/core';
10 | import { RouterModule } from '@angular/router';
11 | import { BrowserModule } from '@angular/platform-browser';
12 |
13 | import { AppComponent } from './app.component';
14 | import { AppRoutes } from './app.routes';
15 | import { TestComponent } from './components/test.component';
16 |
17 | @NgModule({
18 | declarations: [
19 | AppComponent,
20 | TestComponent,
21 | ],
22 | imports: [
23 | BrowserModule,
24 | RouterModule.forRoot(AppRoutes),
25 | ],
26 | bootstrap: [
27 | AppComponent
28 | ],
29 | })
30 | export class AppModule {}
31 |
32 | platformBrowserDynamic().bootstrapModule(AppModule);
33 |
--------------------------------------------------------------------------------
/src/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AppComponent } from './app.component';
2 |
3 | import { RouterModule } from '@angular/router';
4 | import { async, TestBed } from '@angular/core/testing';
5 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
6 | import { APP_BASE_HREF } from '@angular/common';
7 |
8 | TestBed.initTestEnvironment(
9 | BrowserDynamicTestingModule,
10 | platformBrowserDynamicTesting()
11 | );
12 |
13 | describe('App', () => {
14 |
15 | beforeEach(() => {
16 | TestBed.configureTestingModule({
17 | declarations: [
18 | AppComponent
19 | ],
20 | imports: [
21 | RouterModule.forRoot([])
22 | ],
23 | providers: [{ provide: APP_BASE_HREF, useValue: '/' }]
24 | });
25 | });
26 |
27 | it('should be able to test', async(() => {
28 | const fixture = TestBed.createComponent(AppComponent);
29 | fixture.whenStable().then(() => {
30 | expect(true).toEqual(true);
31 | });
32 | }));
33 |
34 | });
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular2-webpack2
2 |
3 | Angular 2 Webpack 2 minimal starter. Includes both unit and e2e tests.
4 |
5 | ## Project scripts
6 |
7 | ### Install packages
8 | The only think you need when when you have prerequisites installed is to run:
9 | ```
10 | npm install
11 | ```
12 |
13 | ### Custom scripts
14 |
15 | Running in dev mode:
16 | ```
17 | npm run dev
18 | ```
19 |
20 | Running prod build:
21 | ```
22 | npm run build
23 | ```
24 |
25 | Running unit tests:
26 | ```
27 | npm test
28 | ```
29 |
30 | Running e2e tests:
31 | ```
32 | npm run e2e
33 | ```
34 |
35 | ## Prerequisites
36 |
37 | ### NodeJS with npm
38 |
39 | #### Mac OS X
40 | If you don't have [Brew](http://brew.sh) it is high time to install it:
41 | ```
42 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
43 | ```
44 |
45 | Then just run:
46 | ```
47 | brew install node
48 | ```
49 |
50 | #### Debian and Ubuntu
51 | ```
52 | sudo apt-get install nodejs
53 | ```
54 |
55 | #### Windows
56 |
57 | [Windows NodeJS Installer](http://nodejs.org/#download)
58 |
59 |
60 | ### Note for Windows users: install Python 2 (to run tests)
61 |
62 | This one is built-in when using Mac OS X and Linux. When you run Windows you have to care of it by yourself. Here's [offical Python website](https://www.python.org/downloads/)
63 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 |
4 | const CopyWebpackPlugin = require('copy-webpack-plugin');
5 |
6 | const config = {
7 | entry: {
8 | 'vendor': './src/vendor',
9 | 'app': './src/bootstrap'
10 | },
11 | output: {
12 | path: path.resolve(__dirname, './dist'),
13 | filename: '[name].js'
14 | },
15 | resolve: {
16 | extensions: ['.ts', '.es6', '.js', '.json']
17 | },
18 | module: {
19 | rules: [
20 | { enforce: 'pre', test: /\.ts$/, exclude: /node_modules/, loader: 'tslint-loader' },
21 | { test: /\.ts$/, exclude: /node_modules/, loader: 'ts-loader' },
22 | { test: /\.json$/, loader: 'json-loader' },
23 | { test: /\.html/, loader: 'html-loader?minimize=false' },
24 | { test: /\.styl$/, loader: 'css-loader!stylus-loader' },
25 | { test: /\.css$/, loader: 'style-loader!css-loader' },
26 | { test: /\.(gif|png|jpe?g)$/i, loader: 'file-loader?name=dist/images/[name].[ext]' },
27 | { test: /\.woff2?$/, loader: 'url-loader?name=dist/fonts/[name].[ext]&limit=10000&mimetype=application/font-woff' },
28 | { test: /\.(ttf|eot|svg)$/, loader: 'file-loader?name=dist/fonts/[name].[ext]' }
29 | ]
30 | },
31 | plugins: [
32 | // Fixes Angular 2 error
33 | new webpack.ContextReplacementPlugin(
34 | /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
35 | __dirname
36 | )
37 | ]
38 | };
39 |
40 | if (!(process.env.WEBPACK_ENV === 'production')) {
41 | config.devtool = 'source-map';
42 | config.plugins = config.plugins.concat([
43 | new webpack.DefinePlugin({
44 | 'WEBPACK_ENV': '"dev"'
45 | })
46 | ])
47 | } else {
48 | config.devtool = 'hidden-source-map';
49 | config.plugins = config.plugins.concat([
50 | new webpack.optimize.UglifyJsPlugin({
51 | compress: {
52 | screw_ie8: true,
53 | warnings: false
54 | },
55 | comments: false,
56 | sourceMap: true
57 | }),
58 | new webpack.DefinePlugin({
59 | 'WEBPACK_ENV': '"production"'
60 | }),
61 | new CopyWebpackPlugin([{ from: './src/index.html' }], {})
62 | ]);
63 | }
64 |
65 | module.exports = config;
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-webpack",
3 | "version": "1.0.0",
4 | "description": "Angular 2",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "WEBPACK_ENV=production webpack --progress --hide-modules",
8 | "dev": "webpack-dev-server --history-api-fallback --content-base ./src --open",
9 | "e2e": "protractor",
10 | "postinstall": "npm run webdriver-update",
11 | "test": "karma start",
12 | "posttest": "npm run coverage",
13 | "coverage": "npm run coverage:remap && npm run coverage:report",
14 | "coverage:remap": "remap-istanbul -i coverage/coverage.json -o coverage/coverage.json -t json -e node_modules,tests,karma.entry.ts",
15 | "coverage:report": "istanbul report",
16 | "webdriver-update": "webdriver-manager update"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/wkwiatek/angular2-webpack"
21 | },
22 | "author": "wkwiatek ",
23 | "license": "SEE LICENSE IN LICENSE",
24 | "dependencies": {
25 | "@angular/common": "^2.0.0",
26 | "@angular/compiler": "^2.0.0",
27 | "@angular/core": "^2.0.0",
28 | "@angular/forms": "^2.0.0",
29 | "@angular/http": "^2.0.0",
30 | "@angular/platform-browser": "^2.0.0",
31 | "@angular/platform-browser-dynamic": "^2.0.0",
32 | "@angular/router": "^3.0.0",
33 | "@types/core-js": "^0.9.34",
34 | "@types/jasmine": "^2.2.34",
35 | "@types/node": "^6.0.40",
36 | "@types/selenium-webdriver": "^2.53.30",
37 | "core-js": "^2.4.1",
38 | "reflect-metadata": "^0.1.3",
39 | "rxjs": "5.0.0-rc.4",
40 | "zone.js": "^0.7.2"
41 | },
42 | "devDependencies": {
43 | "babel-core": "^6.3.17",
44 | "babel-loader": "^6.2.0",
45 | "codelyzer": "^2.0.0-beta.2",
46 | "copy-webpack-plugin": "^4.0.0",
47 | "css-loader": "^0.26.0",
48 | "file-loader": "^0.9.0",
49 | "html-loader": "^0.4.4",
50 | "istanbul-instrumenter-loader": "^1.0.0",
51 | "jasmine-core": "^2.4.1",
52 | "json-loader": "^0.5.4",
53 | "karma": "^1.0.0",
54 | "karma-chrome-launcher": "^2.0.0",
55 | "karma-coverage": "^1.1.1",
56 | "karma-jasmine": "^1.0.0",
57 | "karma-mocha-reporter": "^2.0.0",
58 | "karma-remap-istanbul": "^0.2.1",
59 | "karma-source-map-support": "^1.1.0",
60 | "karma-sourcemap-loader": "^0.3.6",
61 | "karma-webpack": "^1.8.0",
62 | "protractor": "^4.0.0",
63 | "raw-loader": "^0.5.1",
64 | "stylus": "^0.54.2",
65 | "stylus-loader": "^2.0.0",
66 | "ts-loader": "^1.2.0",
67 | "tslint": "^4.1.1",
68 | "tslint-loader": "^3.3.0",
69 | "typescript": "^2.0.0",
70 | "webpack": "^2.2.0-rc.1",
71 | "webpack-dev-server": "^2.2.0-rc.0"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 |
3 | const ENV_PRODUCTION = process.env.WEBPACK_ENV === 'production';
4 |
5 | module.exports = config => {
6 | config.set({
7 |
8 | // base path that will be used to resolve all patterns (eg. files, exclude)
9 | basePath: '',
10 |
11 |
12 | // frameworks to use
13 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
14 | frameworks: ['jasmine', 'source-map-support'],
15 |
16 |
17 | // list of files / patterns to load in the browser
18 | files: [
19 | './karma.entry.ts'
20 | ],
21 |
22 |
23 | // list of files to exclude
24 | exclude: [
25 | ],
26 |
27 |
28 | // preprocess matching files before serving them to the browser
29 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
30 | preprocessors: {
31 | './karma.entry.ts': ['webpack']
32 | },
33 |
34 | coverageReporter: {
35 | dir: 'coverage',
36 | reporters: [{
37 | type: 'json',
38 | subdir: '.',
39 | file: 'coverage.json'
40 | }]
41 | },
42 |
43 | webpack: {
44 | devtool: 'inline-source-map',
45 | resolve: {
46 | extensions: ['.ts', '.js', '.json']
47 | },
48 | module: {
49 | rules: [
50 | // { enforce: 'pre', test: /\.ts$/, exclude: ['node_modules', /\.spec.ts$/], loader: 'istanbul-instrumenter-loader' },
51 | { test: /\.ts$/, exclude: /node_modules/, loader: 'ts-loader' },
52 | { test: /\.html/, loader: 'raw-loader' },
53 | { test: /\.styl$/, loader: 'css-loader!stylus-loader' },
54 | { test: /\.css$/, loader: 'css-loader' },
55 | { test: /\.(gif|png|jpe?g)$/i, loader: 'file-loader' }
56 | ]
57 | },
58 | stats: { colors: true, reasons: true },
59 | plugins: [
60 | // Fixes Angular 2 error
61 | new webpack.ContextReplacementPlugin(
62 | /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
63 | __dirname
64 | )
65 | ]
66 | },
67 |
68 | webpackMiddleware: {
69 | noInfo: true //please don't spam the console when running in karma!
70 | },
71 |
72 | // test results reporter to use
73 | // possible values: 'dots', 'progress'
74 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
75 | reporters: ['mocha'],
76 |
77 |
78 | // web server port
79 | port: 9876,
80 |
81 |
82 | // enable / disable colors in the output (reporters and logs)
83 | colors: true,
84 |
85 |
86 | // level of logging
87 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
88 | logLevel: config.LOG_INFO,
89 |
90 |
91 | // enable / disable watching file and executing tests whenever any file changes
92 | autoWatch: ENV_PRODUCTION ? false : true,
93 |
94 | // start these browsers
95 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
96 | browsers: ['Chrome'],
97 |
98 |
99 | // Continuous Integration mode
100 | // if true, Karma captures browsers, runs the tests and exits
101 | singleRun: ENV_PRODUCTION ? true : false,
102 |
103 | // fix for Chrome 55
104 | mime: {
105 | 'text/x-typescript': ['ts','tsx']
106 | },
107 |
108 | });
109 | };
110 |
--------------------------------------------------------------------------------
/src/ie-shims/ie-shims.js:
--------------------------------------------------------------------------------
1 | // function.name (all IE)
2 | /*! @source http://stackoverflow.com/questions/6903762/function-name-not-supported-in-ie*/
3 | if (!Object.hasOwnProperty('name')) {
4 | Object.defineProperty(Function.prototype, 'name', {
5 | get: function() {
6 | var matches = this.toString().match(/^\s*function\s*((?![0-9])[a-zA-Z0-9_$]*)\s*\(/);
7 | var name = matches && matches.length > 1 ? matches[1] : "";
8 | // For better performance only parse once, and then cache the
9 | // result through a new accessor for repeated access.
10 | Object.defineProperty(this, 'name', {value: name});
11 | return name;
12 | }
13 | });
14 | }
15 |
16 | // URL polyfill for SystemJS (all IE)
17 | /*! @source https://github.com/ModuleLoader/es6-module-loader/blob/master/src/url-polyfill.js*/
18 | // from https://gist.github.com/Yaffle/1088850
19 | (function(global) {
20 | function URLPolyfill(url, baseURL) {
21 | if (typeof url != 'string') {
22 | throw new TypeError('URL must be a string');
23 | }
24 | var m = String(url).replace(/^\s+|\s+$/g, "").match(/^([^:\/?#]+:)?(?:\/\/(?:([^:@\/?#]*)(?::([^:@\/?#]*))?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
25 | if (!m) {
26 | throw new RangeError();
27 | }
28 | var protocol = m[1] || "";
29 | var username = m[2] || "";
30 | var password = m[3] || "";
31 | var host = m[4] || "";
32 | var hostname = m[5] || "";
33 | var port = m[6] || "";
34 | var pathname = m[7] || "";
35 | var search = m[8] || "";
36 | var hash = m[9] || "";
37 | if (baseURL !== undefined) {
38 | var base = baseURL instanceof URLPolyfill ? baseURL : new URLPolyfill(baseURL);
39 | var flag = protocol === "" && host === "" && username === "";
40 | if (flag && pathname === "" && search === "") {
41 | search = base.search;
42 | }
43 | if (flag && pathname.charAt(0) !== "/") {
44 | pathname = (pathname !== "" ? (((base.host !== "" || base.username !== "") && base.pathname === "" ? "/" : "") + base.pathname.slice(0, base.pathname.lastIndexOf("/") + 1) + pathname) : base.pathname);
45 | }
46 | // dot segments removal
47 | var output = [];
48 | pathname.replace(/^(\.\.?(\/|$))+/, "")
49 | .replace(/\/(\.(\/|$))+/g, "/")
50 | .replace(/\/\.\.$/, "/../")
51 | .replace(/\/?[^\/]*/g, function (p) {
52 | if (p === "/..") {
53 | output.pop();
54 | } else {
55 | output.push(p);
56 | }
57 | });
58 | pathname = output.join("").replace(/^\//, pathname.charAt(0) === "/" ? "/" : "");
59 | if (flag) {
60 | port = base.port;
61 | hostname = base.hostname;
62 | host = base.host;
63 | password = base.password;
64 | username = base.username;
65 | }
66 | if (protocol === "") {
67 | protocol = base.protocol;
68 | }
69 | }
70 |
71 | // convert windows file URLs to use /
72 | if (protocol == 'file:')
73 | pathname = pathname.replace(/\\/g, '/');
74 |
75 | this.origin = protocol + (protocol !== "" || host !== "" ? "//" : "") + host;
76 | this.href = protocol + (protocol !== "" || host !== "" ? "//" : "") + (username !== "" ? username + (password !== "" ? ":" + password : "") + "@" : "") + host + pathname + search + hash;
77 | this.protocol = protocol;
78 | this.username = username;
79 | this.password = password;
80 | this.host = host;
81 | this.hostname = hostname;
82 | this.port = port;
83 | this.pathname = pathname;
84 | this.search = search;
85 | this.hash = hash;
86 | }
87 | global.URLPolyfill = URLPolyfill;
88 | })(typeof self != 'undefined' ? self : global);
89 |
90 | //classList (IE9)
91 | /*! @license please refer to http://unlicense.org/ */
92 | /*! @author Eli Grey */
93 | /*! @source https://github.com/eligrey/classList.js */
94 | ;if("document" in self&&!("classList" in document.createElement("_"))){(function(j){"use strict";if(!("Element" in j)){return}var a="classList",f="prototype",m=j.Element[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p