<!DOCTYPE html>
<html>

  <head>
    <script src="https://code.angularjs.org/1.5.5/angular.js"></script>
    <script src="https://code.angularjs.org/tools/traceur-runtime.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.2/jasmine.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.2/jasmine-html.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.2/boot.js"></script>

    <script src="config.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/angular2.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/testing.dev.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/http.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.17/upgrade.js"></script>
    <script>
      System.import('angular2/src/platform/browser/browser_adapter')
        .then(function(browser_adapter) {
          browser_adapter.BrowserDomAdapter.makeCurrent();
          System.import('app').then(function() {
            window.onload();
          });
        });
    </script>
  </head>

  <body>
    <div><ng1 value="'NG1_VALUE'"></ng1></div>
    <div><ng2></ng2></div>
  </body>

</html>
System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  //map tells the System loader where to look for things
  map: {
    app: "./src"
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    }
  }
});
import {bootstrap, View} from 'angular2/platform/browser';
import {
  Component,
  provide
} from 'angular2/core';
import {
  HTTP_PROVIDERS,
  Http,
  Response,
  ResponseOptions,
  XHRBackend
} from 'angular2/http';
import {beforeEachProviders} from 'angular2/testing';
import {MockBackend} from 'angular2/http/testing';
import {UpgradeAdapter} from 'angular2/upgrade';

const upgradeAdapter = new UpgradeAdapter();

/*
 * NG1 
 */
let ng1App = angular.module('ng1App', []);
ng1App.component('ng1', {
    bindings: {
      value: '='
    },
    template: `<span>NG1 => </span><span ng-bind="$ctrl.value"></span>`
  });

/*
 * NG2
 */

@Component({
  directives: [upgradeAdapter.upgradeNg1Component('ng1')],
  // providers: [HTTP_PROVIDERS],
  selector: 'ng2',
  template: '<span>NG2 => </span><ng1 [value]="value"></ng1>'
})
export class Ng2 {
  
  value:string = 'VALUE';
  
  constructor(private http: Http) {
    this.http.get('/test')
        .subscribe((response: Response) => {
          this.value = response.json().value;
        });
  }
}

ng1App.directive('ng2', upgradeAdapter.downgradeNg2Component(Ng2));


import {
  async,
  beforeEach,
  describe,
  it,
  inject,
  injectAsync,
  setBaseTestProviders,
  ComponentFixture,
  TestComponentBuilder
} from 'angular2/testing';

import {
  TEST_BROWSER_PLATFORM_PROVIDERS,
  TEST_BROWSER_APPLICATION_PROVIDERS
} from 'angular2/platform/testing/browser';

setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS);

describe('angular2 upgrade', () => {

  beforeEachProviders(() => [
    MockBackend
  ]);

  it('should load ng1 components into ng2 components',
    inject([MockBackend, TestComponentBuilder], (mockBackend, tcb) => {
      
      let playgroundElement;
      let resolve;
      let reject;
      let promise = new Promise((_resolve, _reject) => {
          resolve = _resolve;
          reject = _reject;
      });
      
      /* Testing in the angular 1 style works.
       * It probably works with $compile etc...*/
      
      playgroundElement = document.createElement('div');
      document.body.appendChild(playgroundElement);
      playgroundElement.innerHTML = '<ng2></ng2>';
      
      mockBackend.connections.subscribe(connection => {
        connection.mockRespond(new Response(new ResponseOptions({
          body: '{"value": "HTTP_VALUE"}'
        })));
      });
      
      upgradeAdapter.addProvider(HTTP_PROVIDERS);
      upgradeAdapter.addProvider(
        provide(XHRBackend, {
          useFactory: () => mockBackend
        })
      );
      
      upgradeAdapter.bootstrap(playgroundElement, ['ng1App'])
        .ready((ref) => {
          
          expect(playgroundElement.innerText)
            .toEqual('NG2 => NG1 => HTTP_VALUE');
            
          resolve();
          
        });
      
      return promise;
      
    });
  );
  
});

/*
 * Bootstrap.
 */
// upgradeAdapter.bootstrap(document.body, ['ng1App']);

// bootstrap(Ng2)
//   .catch(err => console.error(err));
import {Component, View, NgFor} from 'angular2/angular2';
import {Redify} from './directives';
import {LastnameUppercase} from './pipes';
import {PresidentialCandidate} from './services';

@Component({
    selector: "navbar",
    directives: [NgFor, Redify],
    providers: [PresidentialCandidate],
    pipes: [LastnameUppercase],
    styles: [`
        li{
          color: gray;
        }
    `],
    template: `
        <h2>Democratic Party presidential candidates</h2>
        <ul>
        <li redify *ngFor="#item of democrats; #i = index">{{item | lastnameUppercase}} {{i}}</li>
        </ul>
        <h2>Republican Party presidential candidates</h2>
        <ul>
        <li redify *ngFor="#item of republicans; #i = index">{{item | lastnameUppercase}} {{i}}</li>
        </ul>
    `
})
export class Navbar {
    democrats: Array<String>
    republicans: Array<String>

    constructor(private presidentialService :PresidentialCandidate) {
      this.democrats = presidentialService.getDemocraticList(); 
      this.republicans = presidentialService.getRepublicainList();
    }

    ngOnInit() {
        console.log('[Component] navbar ngOnInit');
    }
}
import {Directive, ElementRef, Renderer} from 'angular2/angular2';

@Directive({
  selector: '[redify]'
})
export class Redify {

  constructor(private _element: ElementRef, private renderer: Renderer) {
      renderer.setElementStyle(_element, 'color', 'red');
  }
}
import {Pipe} from 'angular2/angular2';

@Pipe({
  name: 'lastnameUppercase'
})
export class LastnameUppercase {
  transform(v, args) {
    return `${v.split(' ')[0]} ${v.split(' ')[1].toUpperCase()}`;
  }
}
import {Injectable} from 'angular2/angular2';

@Injectable()
export class PresidentialCandidate {

    constructor() {

    }

    getRepublicainList() {
        return [
        "Donald Trump",
        "Rand Paul",
        "Ben Carson"
      ]
    }

    getDemocraticList() {
        return [
        "Hillary Clinton",
        "Martin O'Malley",
        "Bernie Sanders"
      ]
    }
}