packages feed

reload-0.0.0.1: web/src/my-app.html

<!--
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/app-route/app-location.html">
<link rel="import" href="../bower_components/app-route/app-route.html">
<link rel="import" href="../bower_components/app-layout/app-drawer-layout/app-drawer-layout.html">
<link rel="import" href="../bower_components/app-layout/app-drawer/app-drawer.html">
<link rel="import" href="../bower_components/app-layout/app-scroll-effects/app-scroll-effects.html">
<link rel="import" href="../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../bower_components/iron-selector/iron-selector.html">
<link rel="import" href="../bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../bower_components/paper-item/paper-item.html">
<link rel="import" href="../bower_components/paper-item/paper-icon-item.html">
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../bower_components/iron-icons/editor-icons.html">
<link rel="import" href="../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">

<link rel="import" href="file-browser.html">
<link rel="import" href="file-actions.html">
<link rel="import" href="file-editor.html">
<link rel="import" href="build-status.html">

<dom-module id="my-app">

    <style>

      :host {
        display: block;
        --app-primary-color: #453a62;
        --app-secondary-color: black;
      }
      app-header {
        background-color: var(--app-primary-color);
        color: #fff;
      }
      app-header paper-icon-button {
        --paper-icon-button-ink-color: white;
      }

    </style>

  <template>
    <iron-ajax id="ajax" auto url="/file/reload.json" handle-as="json"
      on-response="handleConfigResponse"></iron-ajax>
    <iron-ajax id="ajaxProjectAction" url="/launch" handle-as="json" method="POST"
      ></iron-ajax>
      <iron-ajax id="ajaxPing" url="/ping" handle-as="json" method="GET"
          ></iron-ajax>
    <iron-ajax id="ajaxRoot" url="/root" auto handle-as="json" method="GET" on-response="handleRootResponse"
          ></iron-ajax>

    <app-location route="{{route}}"></app-location>
    <app-route
        route="{{route}}"
        pattern="/:page"
        data="{{routeData}}"
        tail="{{subroute}}"></app-route>
    <app-drawer-layout fullbleed>
      <!-- Drawer content -->
      <app-drawer>
        <!-- https://github.com/PolymerElements/app-layout/tree/master/app-drawer -->
        <div style="height:100%;overflow:auto;">
          <file-actions id="fileActions" on-file-system-changed="fileSystemChanged" on-project-action="projectAction"></file-actions>
          <file-browser id="fileBrowser" class="drawer-list" parent="/" on-path-selected="pathSelected" on-file-selected="fileOpened">
          </file-browser>
        </div>
      </app-drawer>
      <!-- Main content -->
      <app-header-layout has-scrolling-region>
        <app-header condenses reveals effects="waterfall">
          <app-toolbar>
            <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
            <paper-menu-button>
              <paper-icon-button icon="expand-more" class="dropdown-trigger"></paper-icon-button>
              <paper-menu id="openedList" class="dropdown-content" on-iron-select="openedItemSelected">
                <template is="dom-repeat" items="[[openedItems]]">
                  <paper-item><img border="0" src="[[showIcon(item)]]" alt="[[item.mime]]" on-error="iconError"></img><span>[[item.path]]</span></paper-item>
                </template>
              </paper-menu>
            </paper-menu-button>
            <div main-title id="title">[[appTitle]]</div>
            <build-status on-file-selected="fileOpened" on-status-changed="statusChanged" on-process-stream="processStream" on-reload-file="reloadFile"></build-status>
            <paper-icon-button id="help" on-tap="onHelp" icon="help"></paper-icon-button>
            <paper-menu-button id="openedFileActions" disabled horizontal-align="right">
              <paper-icon-button icon="more-vert" class="dropdown-trigger"></paper-icon-button>
              <paper-menu class="dropdown-content">
                <paper-icon-item on-tap="infoCurrent"><iron-icon icon="info" alt="Info" item-icon></iron-icon><b>Ctrl-I</b>: Info</paper-icon-item>
                <paper-icon-item on-tap="formatCurrent"><iron-icon icon="editor:format-line-spacing" alt="Format" item-icon></iron-icon>Format</paper-icon-item>
                <paper-icon-item on-tap="closeCurrent"><iron-icon icon="close" alt="Close" item-icon></iron-icon>Close</paper-icon-item>
                <paper-icon-item on-tap="closeAll"><iron-icon icon="close" alt="Close All" item-icon></iron-icon>Close All</paper-icon-item>
              </paper-menu>
            </paper-menu-button>

          </app-toolbar>
        </app-header>
        <file-editor id="editor" on-config-changed="configChanged"></file-editor>
      </app-header-layout>
    </app-drawer-layout>

    <paper-dialog id="help_dialog">
      <h2>Help</h2>
      <paper-dialog-scrollable>
        <h3>Editor commands</h3>
        <div><b>Ctrl-I</b>: Info on current word</div>
      </paper-dialog-scrollable>
      <div class="buttons">
        <paper-button dialog-dismiss>Close</paper-button>
      </div>
    </paper-dialog>

  </template>
  <script>

    Polymer({
      is: 'my-app',
      properties: {
      },

      pathSelected : function (e){
        this.$.fileActions.pathSelected(e);
      },
      fileSystemChanged: function (e){
        this.$.fileBrowser.fileSystemChanged(e);
        var deletedPath=e.detail.deleted;
        if (deletedPath!==undefined){
          var idx=this.openedPaths[deletedPath];
          if (idx!==undefined){
            delete this.openedPaths[deletedPath];
            this.splice('openedItems',idx-1,1);
            this.onClose();
          }
        }

      },
      fileOpened: function(e){
          var item=e.detail;
          var empty=this.openedItems.length==0;
          if (!this.openedPaths[item.path]){
            this.openedPaths[item.path]=this.openedItems.length+1;
            // clone without details
            this.push('openedItems',{'path':item.path,'mime':item.mime,'type':item.type});
          }
          var idx=this.openedPaths[item.path]-1;
          if (empty || this.$.openedList.selected!=idx){
            this.notifyEditor=false;
            this.$.openedList.selected=idx;
          }

          // with details if any
          this.$.editor.fileOpened({detail:item});

          this.$.openedFileActions.disabled=false;
      },
      openedItemSelected: function(){
        var sel=this.$.openedList.selected;
        if (sel>-1){
          var item=this.openedItems[sel];
          if (item !== undefined){
            if (this.notifyEditor){
              this.$.editor.fileOpened({detail:item});
            }
            this.notifyEditor=true;
            Polymer.dom(this.$.title).innerHTML=item.path;
            this.currentPath=item.path;
            if (item.type==="process"){
              var cnt=this.processes[item.path];
              if (cnt){
                this.$.editor.setValue(cnt);
              }
            }
          }
        }
      },
      ready: function() {
          this.openedItems = [];
          this.openedPaths = {};
          this.currentPath = null;
          this.appTitle='Reload Haskell IDE';
          this.notifyEditor = true;
          this.config= {};
          this.processes={};
          var aj=this.$.ajaxPing;
          setInterval(function(){aj.generateRequest();},30*1000);
      },
      showIcon: function(item){
        if (item.mime){
            return "/images/"+item.mime+".png";
        }
        return "/images/text/plain.png";
      },
      iconError:function(e){
        e.target.src="/images/text/plain.png";
      },
      closeCurrent:function(e){
        if (this.currentPath){
          var idx=this.openedPaths[this.currentPath]-1
          delete this.openedPaths[this.currentPath];
          this.splice('openedItems',idx,1);
          this.onClose();
        }
      },
      infoCurrent:function(e){
        if (this.currentPath){
          this.$.editor.info();
        }
      },
      formatCurrent:function(e){
        if (this.currentPath){
          this.$.editor.format();
        }
      },
      onClose: function(){
        if (this.openedItems.length>0){
          var item=this.openedItems[0];
          this.currentPath=item.path;
          this.$.editor.fileOpened({detail:item});
          Polymer.dom(this.$.title).innerHTML=item.path;
        } else {
          this.currentPath=null;
          this.$.editor.fileOpened(null);
          Polymer.dom(this.$.title).innerHTML=this.appTitle;
          this.$.openedFileActions.disabled=true;
        }
      },
      closeAll: function(e){
        this.openedPaths={};
        this.currentPath=null;
        this.splice('openedItems',0,this.openedItems.length);
        this.$.editor.fileOpened(null);
        Polymer.dom(this.$.title).innerHTML=this.appTitle;
        this.$.openedFileActions.disabled=true;
      },
      statusChanged: function(e){
        this.$.editor.statusChanged(e);
      },
      handleConfigResponse : function(e){
        this.config=e.detail.response;
        this.$.editor.setConfig(this.config);
        this.runActions(this.config);
      },
      configChanged : function (e){
        this.config=e.detail;
        this.runActions(this.config);
      },
      runActions : function(config){
        var acts=[];
        for (var i in config["actions"]){
          if (i!="build" && i!="test" && i!="bench"){
            acts.push(i);
          }
        }
        this.$.fileActions.setRunActions(acts);
      },
      handleRootResponse: function(e){
        var root=e.detail.response;
        document.title="Reload Haskell IDE: "+root;
      },
      projectAction: function(e){
        var act=e.detail.action;
        this.processes[act]="";
        var cmd="<tool> "+act;
        if (this.config["actions"] && this.config["actions"][act]){
          cmd=this.config["actions"][act];
        }
        var aj=this.$.ajaxProjectAction;
        aj.url="launch/"+act;
        aj.body=cmd;
        aj.generateRequest();
      },
      processStream: function(e){
        var p=e.detail;
        var cnt = this.processes[p.process];
        if (!cnt){
          cnt=""
          this.processes[p.process]=cnt;
        }
        var current=false;
        var sel=this.$.openedList.selected;
        if (sel>-1){
          var item=this.openedItems[sel];
          if ("process"==item.type && item.path==p.process){
            current=true;
          }
        }

        if (p.stream){
          if (cnt.length>0){
            cnt+="\n";
          }
          cnt+=p.line;
          this.processes[p.process]=cnt;
          if (current){
            this.$.editor.addLine(p.line);
          }
        } else {
          this.processes[p.process]="";
          this.fileOpened({detail:{path:p.process,type:'process',mime:'text/x-process'}});
          if (current){
            this.$.editor.setValue("");
          }
        }
      },
      onHelp: function(e){
        this.$.help_dialog.open();
      },
      reloadFile: function(e){
        this.$.editor.reloadFile(e.detail);
      }
    });

  </script>

</dom-module>