<commit_before>var handleSelect = function(grid, workflow, rowIndex, listeners) {
  var runId = this.getSelection()[0].get('_id');
  this.up('tabpanel').down('#misfit_runid').setValue(runId + '_<suffix set at submission time>');
};

var getMisfitJSON = function(runId, callback) {
  // get workflow from prov
  // && get solver configuration from liferay document store
  getWorkflowAndSolverConf(runId, function(err, prov_workflow, solver_conf, workflow_url) {
    if (err != null) {
      Ext.Msg.alert("Error", err);

      return;
    }

    // get the events
    var event_url = prov_workflow.quakeml.url.replace(/http:\/\/[^\/]*\//, '/');

    Ext.Ajax.request({
      method: "GET",
      url: "/j2ep-1.0/prov/entities/values-range",
      params: {
        "activity": "StoreStream",
        "mime-type": "application/octet-stream",
        "keys": "prov:type",
        "minvalues": "observed-waveform",
        "maxvalues": "observed-waveform",
        "runId": runId,
        "start": 0,
        "limit": 1000
      },
      success: function(response, config) {
        var observed = JSON.parse(response.responseText);

        Ext.Ajax.request({
          method: "GET",
          url: "/j2ep-1.0/prov/entities/values-range",
          params: {
            "activity": "StoreStream",
            "mime-type": "application/octet-stream",
            "keys": "prov:type",
            "minvalues": "synthetic-waveform",
            "maxvalues": "synthetic-waveform",
            "runId": runId,
            "start": 0,
            "limit": 1000
          },
          success: function(response, config) {
            var synthetics = JSON.parse(response.responseText);

            Ext.Ajax.request({
              method: "GET",
              url: "/j2ep-1.0/prov/entities/values-range",
              params: {
                "mime-type": "application/xml",
                "runId": runId,
                "start": 0,
                "limit": 1000
              },
              success: function(response, config) {
                var stations = JSON.parse(response.responseText);

                // "file://wn1//home/aspinuso/concrete_misfit_preproc2/output/"
                var data_path = observed.entities[0].location.replace(/[^.\/]*.[^.\/]*.[^.\/]*.observed.seed$/, "");
                // "file://wn1//home/aspinuso/concrete_misfit_preproc2/stationxml/"
                var station_path = stations.entities[0].location[0].replace(/[^.\/]*.[^.\/]*.xml$/, "");

                var misfitConfStore = Ext.getCmp('misfit_conf').getStore();
                var parameters = {};
                for (var ii = 0; ii < misfitConfStore.data.items.length; ++ii) {
                  parameters[misfitConfStore.data.items[ii].get('name')] = misfitConfStore.data.items[ii].get('value');
                }
                parameters.misfit_type = Ext.getCmp('misfit_type').getRawValue();

                var streamProducers = {};
                for (var ii = 0; ii < stations.entities.length; ++ii) {
                  var station = stations.entities[ii];
                  var station_file = station.location[0].replace(station_path, "");
                  var resultStation = {
                    "input": {
                      "quakeml": "../../quakeml",
                      "stationxml": "./stationxml/" + station_file,
                      "event_id": solver_conf.events[0], // "smi:webservices.rm.ingv.it/fdsnws/event/1/query?eventId=1744261",
                      "synthetics": [
                        // "./IV.SGG.HXZ.synthetic.seed",
                      ],
                      "data": [
                        // "./IV.SGG.BHZ.observed.seed",
                      ],
                      "output_folder": "./output/",
                      "parameters": parameters,
                    }
                  };

                  var network_dot_name = station.location[0].replace(station_path, "").split(".").slice(0, -1).join(".");
                  streamProducers[network_dot_name] = resultStation;
                }

                // Add synthetics
                for (var ii = 0; ii < synthetics.entities.length; ++ii) {
                  var network_dot_name = synthetics.entities[ii].location.replace(data_path, "").split(".").slice(0, -3).join(".");
                  streamProducers[network_dot_name].input.synthetics.push(synthetics.entities[ii].location.replace(data_path, ""));
                }

                // Add observations
                for (var ii = 0; ii < observed.entities.length; ++ii) {
                  var network_dot_name = observed.entities[ii].location.replace(data_path, "").split(".").slice(0, -3).join(".");
                  streamProducers[network_dot_name].input.data.push(observed.entities[ii].location.replace(data_path, ""));
                }

                var config = {
                  "user_name": userSN,
                  'processingRunId': runId,
                  'runId': Ext.getCmp('misfit_runid').getValue(),
                  'nproc': Ext.getCmp('misfit_nproc').getValue(),
                  "readJSONstgin": [{
                    "input": {
                      "data_dir": "./",
                      "synt_dir": "./",
                      "events": "../../quakeml",
                      // TODO multiple events
                      "event_id": solver_conf.events[0], // "smi:webservices.rm.ingv.it/fdsnws/event/1/query?eventId=1744261"
                      "stations_dir": "./stationxml/",
                      "output_dir": "./output/",
                      // TODO why an array?
                      "data_stagein_from": [
                        data_path
                      ],
                      "stationxml_stagein_from": [
                        station_path
                      ]
                    }
                  }],
                  "streamProducer": Ext.Object.getValues(streamProducers),
                };

                var params = {};

                params.config = config;
                params.description = Ext.getCmp('misfit_description').getValue();
                params.quakemlURL = prov_workflow.quakeml.url;

                params.input = Ext.encode([
                  prov_workflow.simulation_workflow,
                  prov_workflow.download_workflow, {
                    'url': '/j2ep-1.0/prov/workflow/export/' + runId + '?all=true&format=w3c-prov-xml',
                    'mime-type': 'application/octet-stream',
                    'prov-type': 'wfrun',
                    'name': 'processing_workflow',
                  }
                ]);

                callback(null, config, params);
                return;
              },
              failure: function(response, config) {
                callback("Failed to get synthetic-waveform provenance");
              },
            });
          },
          failure: function(response, config) {
            callback("Failed to get observed-waveform provenance");
          },
        });
      },
      failure: function(response, config) {
        callback("Failed to get observed-waveform provenance");
      },
    });
  });
};

var doSubmitMisfitWorkflow = function(config, params, callback) {
  var url = submitMisfitWorkflowURL;
  params.config = Ext.encode(config);

  var misfitWorkflow = Ext.getCmp('misfit_workflow').findRecordByValue(Ext.getCmp('misfit_workflow').getValue());
  if (misfitWorkflow == null) {
    Ext.Msg.alert("No Workflow", "No workflow configured, cannot submit. Please contact an administrator.");
    return;
  }

  params['workflowId'] = misfitWorkflow.get('workflowId');
  params['ownerId'] = misfitWorkflow.get('ownerId');
  params['workflowName'] = misfitWorkflow.get('workflowName');

  Ext.getCmp('viewport').setLoading(true);

  Ext.Ajax.request({
    url: url,
    params: params,
    success: function(response, config) {
      Ext.Msg.alert("Submission succeeded", "The misfit workflow can now be monitored on the control panel.");
      Ext.getCmp('viewport').setLoading(false);
      callback();
    },
    failure: function(response, config) {
      Ext.Msg.alert("Submission failed", response);
      Ext.getCmp('viewport').setLoading(false);
    },
  });
};

Ext.define('CF.view.PreprocessingSelection', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.preprocessing_selection',

  columns: [{
    text: 'Name',
    flex: 1,
    sortable: true,
    dataIndex: '_id'
  }, {
    text: 'Desc',
    flex: 1,
    sortable: true,
    dataIndex: 'description',
    renderer: function(value, metaData, record, row, col, store, gridView) {
      if (value == null || value === '' || value === 'null') {
        return '-';
      }

      return value;
    }
  }, {
    text: 'Workflow',
    flex: 1,
    sortable: true,
    dataIndex: 'workflowName',
    renderer: function(value, metaData, record, row, col, store, gridView) {
      if (value == null || value === '' || value === 'null') {
        return 'n/a';
      }

      return value;
    }
  }, {
    text: 'Date',
    xtype: 'datecolumn',
    format: 'd - m - Y',
    width: 90,
    sortable: true,
    dataIndex: 'startTime'
  }],
  flex: 1,
  initComponent: function() {
    this.store = Ext.create('CF.store.ProvWorkflow', {
      proxy: {
        type: 'ajax',
        url: "/j2ep-1.0/prov/workflow",
        reader: {
          rootProperty: 'list'
        },
        api: {
          read: PROV_SERVICE_BASEURL + 'workflow?username=' + userSN + '&activities=StreamMapper,readJSONstgin,StoreStreamChannel',
        },
        reader: {
          rootProperty: 'runIds',
          totalProperty: 'totalCount'
        },
      },
      autoLoad: true,
    });

    this.callParent(arguments);
  },
  listeners: {
    select: handleSelect,
  }
});

Ext.define('CF.view.Misfit', {
  extend: 'Ext.panel.Panel',
  alias: 'widget.misfit_panel',
  requires: [
    'Ext.layout.container.Border'
  ],
  layout: 'border', // border
  height: "100%",
  bodyBorder: false,

  defaults: {
    collapsible: false,
    split: true,
    bodyPadding: 0
  },

  items: [{
    xtype: 'tabpanel',
    region: 'center',
    layout: 'fit',
    height: "100%",
    bodyBorder: false,

    items: [{
      xtype: 'panel',
      height: "100%",
      title: 'Setup',
      bodyBorder: false,

      defaults: {
        collapsible: false,
        split: true,
        bodyPadding: 0
      },

      items: [{
        xtype: 'preprocessing_selection',
        height: 250,
        tools: [{
          type: 'refresh',
          tooltip: 'Refresh list',
          handler: function() {
            this.up('panel').getStore().load();
          },
        }],
      }, {
        xtype: 'combobox',
        fieldLabel: 'Misfit type:',
        id: 'misfit_type',
        queryMode: 'local',
        displayField: 'name',
        valueField: 'parameters',
        allowBlank: false,
        store: Ext.create("CF.store.MisfitType"),
        listeners: {
          change: function(f, e) {
            var conf = this.up('panel').down('conf');
            conf.getStore().loadData(this.getValue());
            conf.enable();
          }
        }
      }, {
        xtype: 'conf',
        height: 300,
        store: Ext.create('CF.store.MisfitConf'),
        features: [{
          id: 'grouping',
          ftype: 'grouping',
          startCollapsed: false
        }],
        id: 'misfit_conf',
      }],
    }, {
      xtype: 'panel',
      title: 'Submit',
      id: 'misfit_submit',
      border: false,
      layout: {
        type: 'vbox',
        align: 'stretch'
      },
      items: [{
        xtype: 'textarea',
        title: 'Configuration Summary',
        id: 'misfit_submit_summary',
        disabled: true,
        disabledCls: '',
        flex: 2,
      }, {
        xtype: 'fieldset',
        title: 'Submission settings',
        items: [{
          xtype: 'workflowcombo',
          id: 'misfit_workflow',
          store: Ext.create('CF.store.ExportedWorkflow', {
            data: misfitWorkflows
          }),
        }, {
          xtype: 'textfield',
          id: 'misfit_runid',
          disabled: true,
          fieldLabel: 'Name:',
        }, {
          xtype: 'textfield',
          id: 'misfit_description',
          fieldLabel: 'Description:',
        }, {
          xtype: 'numberfield',
          id: 'misfit_nproc',
          fieldLabel: 'NPROC',
          value: '64',
          step: 1,
        }]
      }],

      buttons: [{
        xtype: 'button',
        text: 'Submit',
        id: 'misfit_submit_button',
        handler: function() {
          var self = this;

          var processing_runId = this.up('tabpanel').down('preprocessing_selection').getSelection()[0].get('_id');
          var runId = 'misfit_' + processing_runId.replace(/^processing_/, '') + '_' + (new Date()).getTime();

          getMisfitJSON(processing_runId, function(err, config, params) {
            config.runId = runId;
            doSubmitMisfitWorkflow(config, params, function() {
              self.up('tabpanel').down('control').down('grid').getStore().reload();
            });
          });
        },
      }],
    }, {
      xtype: 'panel',
      title: 'Control',
      border: false,
      layout: 'fit',
      items: [{
        xtype: 'control',
        filters: [{
          property: 'prov:type',
          value: 'misfit',
        }]
      }]
    }],
    listeners: {
      'beforetabchange': function(tabPanel, tab) {
        if (tab.id === 'misfit_submit') {
          var processing_run = this.up('panel').down('preprocessing_selection').getSelection()[0];
          if (processing_run == null) {
            Ext.Msg.alert("No processing run selected", "Please select a processing run first");
            return false;
          }
        }
      },
      'tabchange': function(tabPanel, tab) {
        if (tab.id === 'misfit_submit') {
          var processing_run = this.up('panel').down('preprocessing_selection').getSelection()[0];
          var runId = processing_run.get('_id');
          Ext.getCmp('misfit_submit_summary').setLoading(true);
          getMisfitJSON(runId, function(err, config, params) {
            Ext.getCmp('misfit_submit_summary').setValue(JSON.stringify(config, null, 2));
            Ext.getCmp('misfit_submit_summary').setLoading(false);
          });
        }
      }
    }
  }],
});<commit_msg>Check for selected misfit type<commit_after>var handleSelect = function(grid, workflow, rowIndex, listeners) {
  var runId = this.getSelection()[0].get('_id');
  this.up('tabpanel').down('#misfit_runid').setValue(runId + '_<suffix set at submission time>');
};

var getMisfitJSON = function(runId, callback) {
  // get workflow from prov
  // && get solver configuration from liferay document store
  getWorkflowAndSolverConf(runId, function(err, prov_workflow, solver_conf, workflow_url) {
    if (err != null) {
      Ext.Msg.alert("Error", err);

      return;
    }

    // get the events
    var event_url = prov_workflow.quakeml.url.replace(/http:\/\/[^\/]*\//, '/');

    Ext.Ajax.request({
      method: "GET",
      url: "/j2ep-1.0/prov/entities/values-range",
      params: {
        "activity": "StoreStream",
        "mime-type": "application/octet-stream",
        "keys": "prov:type",
        "minvalues": "observed-waveform",
        "maxvalues": "observed-waveform",
        "runId": runId,
        "start": 0,
        "limit": 1000
      },
      success: function(response, config) {
        var observed = JSON.parse(response.responseText);

        Ext.Ajax.request({
          method: "GET",
          url: "/j2ep-1.0/prov/entities/values-range",
          params: {
            "activity": "StoreStream",
            "mime-type": "application/octet-stream",
            "keys": "prov:type",
            "minvalues": "synthetic-waveform",
            "maxvalues": "synthetic-waveform",
            "runId": runId,
            "start": 0,
            "limit": 1000
          },
          success: function(response, config) {
            var synthetics = JSON.parse(response.responseText);

            Ext.Ajax.request({
              method: "GET",
              url: "/j2ep-1.0/prov/entities/values-range",
              params: {
                "mime-type": "application/xml",
                "runId": runId,
                "start": 0,
                "limit": 1000
              },
              success: function(response, config) {
                var stations = JSON.parse(response.responseText);

                // "file://wn1//home/aspinuso/concrete_misfit_preproc2/output/"
                var data_path = observed.entities[0].location.replace(/[^.\/]*.[^.\/]*.[^.\/]*.observed.seed$/, "");
                // "file://wn1//home/aspinuso/concrete_misfit_preproc2/stationxml/"
                var station_path = stations.entities[0].location[0].replace(/[^.\/]*.[^.\/]*.xml$/, "");

                var misfitConfStore = Ext.getCmp('misfit_conf').getStore();
                var parameters = {};
                for (var ii = 0; ii < misfitConfStore.data.items.length; ++ii) {
                  parameters[misfitConfStore.data.items[ii].get('name')] = misfitConfStore.data.items[ii].get('value');
                }
                parameters.misfit_type = Ext.getCmp('misfit_type').getRawValue();

                var streamProducers = {};
                for (var ii = 0; ii < stations.entities.length; ++ii) {
                  var station = stations.entities[ii];
                  var station_file = station.location[0].replace(station_path, "");
                  var resultStation = {
                    "input": {
                      "quakeml": "../../quakeml",
                      "stationxml": "./stationxml/" + station_file,
                      "event_id": solver_conf.events[0], // "smi:webservices.rm.ingv.it/fdsnws/event/1/query?eventId=1744261",
                      "synthetics": [
                        // "./IV.SGG.HXZ.synthetic.seed",
                      ],
                      "data": [
                        // "./IV.SGG.BHZ.observed.seed",
                      ],
                      "output_folder": "./output/",
                      "parameters": parameters,
                    }
                  };

                  var network_dot_name = station.location[0].replace(station_path, "").split(".").slice(0, -1).join(".");
                  streamProducers[network_dot_name] = resultStation;
                }

                // Add synthetics
                for (var ii = 0; ii < synthetics.entities.length; ++ii) {
                  var network_dot_name = synthetics.entities[ii].location.replace(data_path, "").split(".").slice(0, -3).join(".");
                  streamProducers[network_dot_name].input.synthetics.push(synthetics.entities[ii].location.replace(data_path, ""));
                }

                // Add observations
                for (var ii = 0; ii < observed.entities.length; ++ii) {
                  var network_dot_name = observed.entities[ii].location.replace(data_path, "").split(".").slice(0, -3).join(".");
                  streamProducers[network_dot_name].input.data.push(observed.entities[ii].location.replace(data_path, ""));
                }

                var config = {
                  "user_name": userSN,
                  'processingRunId': runId,
                  'runId': Ext.getCmp('misfit_runid').getValue(),
                  'nproc': Ext.getCmp('misfit_nproc').getValue(),
                  "readJSONstgin": [{
                    "input": {
                      "data_dir": "./",
                      "synt_dir": "./",
                      "events": "../../quakeml",
                      // TODO multiple events
                      "event_id": solver_conf.events[0], // "smi:webservices.rm.ingv.it/fdsnws/event/1/query?eventId=1744261"
                      "stations_dir": "./stationxml/",
                      "output_dir": "./output/",
                      // TODO why an array?
                      "data_stagein_from": [
                        data_path
                      ],
                      "stationxml_stagein_from": [
                        station_path
                      ]
                    }
                  }],
                  "streamProducer": Ext.Object.getValues(streamProducers),
                };

                var params = {};

                params.config = config;
                params.description = Ext.getCmp('misfit_description').getValue();
                params.quakemlURL = prov_workflow.quakeml.url;

                params.input = Ext.encode([
                  prov_workflow.simulation_workflow,
                  prov_workflow.download_workflow, {
                    'url': '/j2ep-1.0/prov/workflow/export/' + runId + '?all=true&format=w3c-prov-xml',
                    'mime-type': 'application/octet-stream',
                    'prov-type': 'wfrun',
                    'name': 'processing_workflow',
                  }
                ]);

                callback(null, config, params);
                return;
              },
              failure: function(response, config) {
                callback("Failed to get synthetic-waveform provenance");
              },
            });
          },
          failure: function(response, config) {
            callback("Failed to get observed-waveform provenance");
          },
        });
      },
      failure: function(response, config) {
        callback("Failed to get observed-waveform provenance");
      },
    });
  });
};

var doSubmitMisfitWorkflow = function(config, params, callback) {
  var url = submitMisfitWorkflowURL;
  params.config = Ext.encode(config);

  var misfitWorkflow = Ext.getCmp('misfit_workflow').findRecordByValue(Ext.getCmp('misfit_workflow').getValue());
  if (misfitWorkflow == null) {
    Ext.Msg.alert("No Workflow", "No workflow configured, cannot submit. Please contact an administrator.");
    return;
  }

  params['workflowId'] = misfitWorkflow.get('workflowId');
  params['ownerId'] = misfitWorkflow.get('ownerId');
  params['workflowName'] = misfitWorkflow.get('workflowName');

  Ext.getCmp('viewport').setLoading(true);

  Ext.Ajax.request({
    url: url,
    params: params,
    success: function(response, config) {
      Ext.Msg.alert("Submission succeeded", "The misfit workflow can now be monitored on the control panel.");
      Ext.getCmp('viewport').setLoading(false);
      callback();
    },
    failure: function(response, config) {
      Ext.Msg.alert("Submission failed", response);
      Ext.getCmp('viewport').setLoading(false);
    },
  });
};

Ext.define('CF.view.PreprocessingSelection', {
  extend: 'Ext.grid.Panel',
  alias: 'widget.preprocessing_selection',

  columns: [{
    text: 'Name',
    flex: 1,
    sortable: true,
    dataIndex: '_id'
  }, {
    text: 'Desc',
    flex: 1,
    sortable: true,
    dataIndex: 'description',
    renderer: function(value, metaData, record, row, col, store, gridView) {
      if (value == null || value === '' || value === 'null') {
        return '-';
      }

      return value;
    }
  }, {
    text: 'Workflow',
    flex: 1,
    sortable: true,
    dataIndex: 'workflowName',
    renderer: function(value, metaData, record, row, col, store, gridView) {
      if (value == null || value === '' || value === 'null') {
        return 'n/a';
      }

      return value;
    }
  }, {
    text: 'Date',
    xtype: 'datecolumn',
    format: 'd - m - Y',
    width: 90,
    sortable: true,
    dataIndex: 'startTime'
  }],
  flex: 1,
  initComponent: function() {
    this.store = Ext.create('CF.store.ProvWorkflow', {
      proxy: {
        type: 'ajax',
        url: "/j2ep-1.0/prov/workflow",
        reader: {
          rootProperty: 'list'
        },
        api: {
          read: PROV_SERVICE_BASEURL + 'workflow?username=' + userSN + '&activities=StreamMapper,readJSONstgin,StoreStreamChannel',
        },
        reader: {
          rootProperty: 'runIds',
          totalProperty: 'totalCount'
        },
      },
      autoLoad: true,
    });

    this.callParent(arguments);
  },
  listeners: {
    select: handleSelect,
  }
});

Ext.define('CF.view.Misfit', {
  extend: 'Ext.panel.Panel',
  alias: 'widget.misfit_panel',
  requires: [
    'Ext.layout.container.Border'
  ],
  layout: 'border', // border
  height: "100%",
  bodyBorder: false,

  defaults: {
    collapsible: false,
    split: true,
    bodyPadding: 0
  },

  items: [{
    xtype: 'tabpanel',
    region: 'center',
    layout: 'fit',
    height: "100%",
    bodyBorder: false,

    items: [{
      xtype: 'panel',
      height: "100%",
      title: 'Setup',
      bodyBorder: false,

      defaults: {
        collapsible: false,
        split: true,
        bodyPadding: 0
      },

      items: [{
        xtype: 'preprocessing_selection',
        height: 250,
        tools: [{
          type: 'refresh',
          tooltip: 'Refresh list',
          handler: function() {
            this.up('panel').getStore().load();
          },
        }],
      }, {
        xtype: 'combobox',
        fieldLabel: 'Misfit type:',
        id: 'misfit_type',
        queryMode: 'local',
        displayField: 'name',
        valueField: 'parameters',
        allowBlank: false,
        store: Ext.create("CF.store.MisfitType"),
        listeners: {
          change: function(f, e) {
            var conf = this.up('panel').down('conf');
            conf.getStore().loadData(this.getValue());
            conf.enable();
          }
        }
      }, {
        xtype: 'conf',
        height: 300,
        store: Ext.create('CF.store.MisfitConf'),
        features: [{
          id: 'grouping',
          ftype: 'grouping',
          startCollapsed: false
        }],
        id: 'misfit_conf',
      }],
    }, {
      xtype: 'panel',
      title: 'Submit',
      id: 'misfit_submit',
      border: false,
      layout: {
        type: 'vbox',
        align: 'stretch'
      },
      items: [{
        xtype: 'textarea',
        title: 'Configuration Summary',
        id: 'misfit_submit_summary',
        disabled: true,
        disabledCls: '',
        flex: 2,
      }, {
        xtype: 'fieldset',
        title: 'Submission settings',
        items: [{
          xtype: 'workflowcombo',
          id: 'misfit_workflow',
          store: Ext.create('CF.store.ExportedWorkflow', {
            data: misfitWorkflows
          }),
        }, {
          xtype: 'textfield',
          id: 'misfit_runid',
          disabled: true,
          fieldLabel: 'Name:',
        }, {
          xtype: 'textfield',
          id: 'misfit_description',
          fieldLabel: 'Description:',
        }, {
          xtype: 'numberfield',
          id: 'misfit_nproc',
          fieldLabel: 'NPROC',
          value: '64',
          step: 1,
        }]
      }],

      buttons: [{
        xtype: 'button',
        text: 'Submit',
        id: 'misfit_submit_button',
        handler: function() {
          var self = this;

          var processing_runId = this.up('tabpanel').down('preprocessing_selection').getSelection()[0].get('_id');
          var runId = 'misfit_' + processing_runId.replace(/^processing_/, '') + '_' + (new Date()).getTime();

          getMisfitJSON(processing_runId, function(err, config, params) {
            config.runId = runId;
            doSubmitMisfitWorkflow(config, params, function() {
              self.up('tabpanel').down('control').down('grid').getStore().reload();
            });
          });
        },
      }],
    }, {
      xtype: 'panel',
      title: 'Control',
      border: false,
      layout: 'fit',
      items: [{
        xtype: 'control',
        filters: [{
          property: 'prov:type',
          value: 'misfit',
        }]
      }]
    }],
    listeners: {
      'beforetabchange': function(tabPanel, tab) {
        if (tab.id === 'misfit_submit') {
          var processing_run = this.up('panel').down('preprocessing_selection').getSelection()[0];
          if (processing_run == null) {
            Ext.Msg.alert("No processing run selected", "Please select a processing run first");
            return false;
          }

          var misfit_type = Ext.getCmp('misfit_type').getValue();
          if (misfit_type == null || misfit_type === "") {
            Ext.Msg.alert("No misfit type selected", "Please select a misfit type first");
            return false;
          }
        }
      },
      'tabchange': function(tabPanel, tab) {
        if (tab.id === 'misfit_submit') {
          var processing_run = this.up('panel').down('preprocessing_selection').getSelection()[0];
          var runId = processing_run.get('_id');
          Ext.getCmp('misfit_submit_summary').setLoading(true);
          getMisfitJSON(runId, function(err, config, params) {
            Ext.getCmp('misfit_submit_summary').setValue(JSON.stringify(config, null, 2));
            Ext.getCmp('misfit_submit_summary').setLoading(false);
          });
        }
      }
    }
  }],
});<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * TodoStore-test
 */

jest.dontMock('../../constants/TodoConstants');
jest.dontMock('../TodoStore');
jest.dontMock('object-assign');

describe('TodoStore', function() {

  var TodoConstants = require('../../constants/TodoConstants');
  var AppDispatcher;
  var TodoStore;
  var callback;

  // mock actions
  var actionTodoCreate = {
    actionType: TodoConstants.TODO_CREATE,
    text: 'foo'
  };
  var actionTodoDestroy = {
    actionType: TodoConstants.TODO_DESTROY,
    id: 'replace me in test'
  };

  beforeEach(function() {
    AppDispatcher = require('../../dispatcher/AppDispatcher');
    TodoStore = require('../TodoStore');
    callback = AppDispatcher.register.mock.calls[0][0];
  });

  it('registers a callback with the dispatcher', function() {
    expect(AppDispatcher.register.mock.calls.length).toBe(1);
  });

  it('should register a callback with the dispatcher', function() {
    expect(AppDispatcher.register.mock.calls.length).toBe(1);
  });

  it('should initialize with no to-do items', function() {
    var all = TodoStore.getAll();
    expect(all).toEqual({});
  });

  it('creates a to-do item', function() {
    callback(actionTodoCreate);
    var all = TodoStore.getAll();
    var keys = Object.keys(all);
    expect(keys.length).toBe(1);
    expect(all[keys[0]].text).toEqual('foo');
  });

  it('destroys a to-do item', function() {
    callback(actionTodoCreate);
    var all = TodoStore.getAll();
    var keys = Object.keys(all);
    expect(keys.length).toBe(1);
    actionTodoDestroy.id = keys[0];
    callback(actionTodoDestroy);
    expect(all[keys[0]]).toBeUndefined();
  });

  it('can determine whether all to-do items are complete', function() {
    var i = 0;
    for (; i < 3; i++) {
      callback(actionTodoCreate);
    }
    expect(Object.keys(TodoStore.getAll()).length).toBe(3);
    expect(TodoStore.areAllComplete()).toBe(false);

    var all = TodoStore.getAll();
    for (key in all) {
      callback({
        actionType: TodoConstants.TODO_COMPLETE,
        id: key
      });
    }
    expect(TodoStore.areAllComplete()).toBe(true);

    callback({
      actionType: TodoConstants.TODO_UNDO_COMPLETE,
      id: key
    });
    expect(TodoStore.areAllComplete()).toBe(false);
  });

});
<commit_msg>Removed duplicate test in TodoStore-test<commit_after>/*
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * TodoStore-test
 */

jest.dontMock('../../constants/TodoConstants');
jest.dontMock('../TodoStore');
jest.dontMock('object-assign');

describe('TodoStore', function() {

  var TodoConstants = require('../../constants/TodoConstants');
  var AppDispatcher;
  var TodoStore;
  var callback;

  // mock actions
  var actionTodoCreate = {
    actionType: TodoConstants.TODO_CREATE,
    text: 'foo'
  };
  var actionTodoDestroy = {
    actionType: TodoConstants.TODO_DESTROY,
    id: 'replace me in test'
  };

  beforeEach(function() {
    AppDispatcher = require('../../dispatcher/AppDispatcher');
    TodoStore = require('../TodoStore');
    callback = AppDispatcher.register.mock.calls[0][0];
  });

  it('registers a callback with the dispatcher', function() {
    expect(AppDispatcher.register.mock.calls.length).toBe(1);
  });

  it('should initialize with no to-do items', function() {
    var all = TodoStore.getAll();
    expect(all).toEqual({});
  });

  it('creates a to-do item', function() {
    callback(actionTodoCreate);
    var all = TodoStore.getAll();
    var keys = Object.keys(all);
    expect(keys.length).toBe(1);
    expect(all[keys[0]].text).toEqual('foo');
  });

  it('destroys a to-do item', function() {
    callback(actionTodoCreate);
    var all = TodoStore.getAll();
    var keys = Object.keys(all);
    expect(keys.length).toBe(1);
    actionTodoDestroy.id = keys[0];
    callback(actionTodoDestroy);
    expect(all[keys[0]]).toBeUndefined();
  });

  it('can determine whether all to-do items are complete', function() {
    var i = 0;
    for (; i < 3; i++) {
      callback(actionTodoCreate);
    }
    expect(Object.keys(TodoStore.getAll()).length).toBe(3);
    expect(TodoStore.areAllComplete()).toBe(false);

    var all = TodoStore.getAll();
    for (key in all) {
      callback({
        actionType: TodoConstants.TODO_COMPLETE,
        id: key
      });
    }
    expect(TodoStore.areAllComplete()).toBe(true);

    callback({
      actionType: TodoConstants.TODO_UNDO_COMPLETE,
      id: key
    });
    expect(TodoStore.areAllComplete()).toBe(false);
  });

});
<|endoftext|>


<commit_before>var path = require("path");
var webpack = require("webpack");
var AssetsPlugin = require('assets-webpack-plugin');
var WebpackMd5Hash = require('webpack-md5-hash');

// Ensure a FRONTEND_HOST is setup since we embed it in the assets.json file
if(!process.env.FRONTEND_HOST) {
  throw "No FRONTEND_HOST set";
}

// The FRONTEND_HOST must end with a /
if(process.env.FRONTEND_HOST.slice(-1) != "/") {
  throw "FRONTEND_HOST must end with a /";
}

// Include a hash of the bundle in the name when we're building these files for
// production so we can use non-expiring caches for them.
//
// Also, if we used hashes in development, we'd be forever filling up our dist
// folder with every hashed version of files we've changed (webpack doesn't
// clean up after itself)
var filenameFormat
var chunkFilename
if(process.env.NODE_ENV == "production") {
  filenameFormat = "[name]-[chunkhash].js"
  chunkFilename = "[id]-[chunkhash].js"
} else {
  filenameFormat = "[name].js"
  chunkFilename = "[id].js"
}

// Toggle between the devtool if on prod/dev since cheap-module-eval-source-map
// is way faster for development.
var devTool
if(process.env.NODE_ENV == "production") {
  devTool = "source-map"
} else {
  devTool = "cheap-module-eval-source-map"
}

var plugins = [
  new WebpackMd5Hash(),
  new webpack.ProvidePlugin({ 'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch' }),
  new webpack.optimize.CommonsChunkPlugin({ names: [ "emojis", "vendor", "loader" ] }),
  new AssetsPlugin({ path: path.join(__dirname, '..', 'dist'), filename: 'manifest.json' }),
  new webpack.NamedModulesPlugin()
]

// If we're building for production, minify the JS
if(process.env.NODE_ENV == "production") {
  plugins.push(new webpack.optimize.DedupePlugin());
  plugins.push(new webpack.optimize.UglifyJsPlugin({
    output: {
      comments: false
    },
    compress: {
      warnings: false,
      screw_ie8: true
    }
  }));
}

module.exports = {
  context: __dirname,

  devtool: devTool,

  entry: {
    vendor: ["classnames", "react", "react-dom", "react-relay", "react-router",
      "react-router-relay", "history", "graphql", "graphql-relay",
      "moment", "object-assign", "eventemitter3", "pusher-js",
      "whatwg-fetch", "es6-error", "escape-html", "react-addons-update",
      "react-document-title", "bugsnag-js", "deepmerge"],
    emojis: [ path.join(__dirname, './../app/emojis/buildkite.js'), path.join(__dirname, './../app/emojis/apple.js') ],
    app: path.join(__dirname, './../app/app.js')
  },

  output: {
    filename: filenameFormat,
    chunkFilename: chunkFilename,
    path: path.join(__dirname, '..', 'dist'),
    publicPath: process.env.FRONTEND_HOST
  },

  module: {
    loaders: [
      {
        test: /\.css$/i,
        loader: "style-loader!css-loader!postcss-loader"
      },
      {
        test: /\.js$/i,
        loader: 'babel',
        exclude: /node_modules/
      },
      {
        test: /\.(woff)$/i,
        loader: 'url-loader?limit=8192'
      },
      {
        test: /\.(png|svg|jpg|gif)$/i,
        loaders: [
          'url-loader?limit=8192',
          'image-webpack?optimizationLevel=7&interlaced=false'
        ]
      }
    ]
  },

  plugins: plugins,

  postcss: function (webpack) {
    return [
      require("postcss-import")({ addDependencyTo: webpack }),
      // require("postcss-url")(),
      require("postcss-cssnext")({ features: { rem: false } }),
      require('postcss-easings')(),
      // add your "plugins" here
      // ...
      // and if you want to compress,
      // just use css-loader option that already use cssnano under the hood
      require("postcss-browser-reporter")(),
      require("postcss-reporter")()
    ]
  }
}
<commit_msg>It was actually the DedupePlugin plugin giving the NamedModules plugin a hard time<commit_after>var path = require("path");
var webpack = require("webpack");
var AssetsPlugin = require('assets-webpack-plugin');
var WebpackMd5Hash = require('webpack-md5-hash');

// Ensure a FRONTEND_HOST is setup since we embed it in the assets.json file
if(!process.env.FRONTEND_HOST) {
  throw "No FRONTEND_HOST set";
}

// The FRONTEND_HOST must end with a /
if(process.env.FRONTEND_HOST.slice(-1) != "/") {
  throw "FRONTEND_HOST must end with a /";
}

// Include a hash of the bundle in the name when we're building these files for
// production so we can use non-expiring caches for them.
//
// Also, if we used hashes in development, we'd be forever filling up our dist
// folder with every hashed version of files we've changed (webpack doesn't
// clean up after itself)
var filenameFormat
var chunkFilename
if(process.env.NODE_ENV == "production") {
  filenameFormat = "[name]-[chunkhash].js"
  chunkFilename = "[id]-[chunkhash].js"
} else {
  filenameFormat = "[name].js"
  chunkFilename = "[id].js"
}

// Toggle between the devtool if on prod/dev since cheap-module-eval-source-map
// is way faster for development.
var devTool
if(process.env.NODE_ENV == "production") {
  devTool = "source-map"
} else {
  devTool = "cheap-module-eval-source-map"
}

var plugins = [
  new WebpackMd5Hash(),
  new webpack.ProvidePlugin({ 'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch' }),
  new webpack.optimize.CommonsChunkPlugin({ names: [ "emojis", "vendor", "loader" ] }),
  new AssetsPlugin({ path: path.join(__dirname, '..', 'dist'), filename: 'manifest.json' }),
  new webpack.NamedModulesPlugin()
]

// If we're building for production, minify the JS
if(process.env.NODE_ENV == "production") {
  // Need this plugin to ensure consistent module ordering so we can have determenistic filename hashes
  plugins.push(new webpack.optimize.OccurenceOrderPlugin(true));
  plugins.push(new webpack.optimize.UglifyJsPlugin({
    output: {
      comments: false
    },
    compress: {
      warnings: false,
      screw_ie8: true
    }
  }));
}

module.exports = {
  context: __dirname,

  devtool: devTool,

  entry: {
    vendor: ["classnames", "react", "react-dom", "react-relay", "react-router",
      "react-router-relay", "history", "graphql", "graphql-relay",
      "moment", "object-assign", "eventemitter3", "pusher-js",
      "whatwg-fetch", "es6-error", "escape-html", "react-addons-update",
      "react-document-title", "bugsnag-js", "deepmerge"],
    emojis: [ path.join(__dirname, './../app/emojis/buildkite.js'), path.join(__dirname, './../app/emojis/apple.js') ],
    app: path.join(__dirname, './../app/app.js')
  },

  output: {
    filename: filenameFormat,
    chunkFilename: chunkFilename,
    path: path.join(__dirname, '..', 'dist'),
    publicPath: process.env.FRONTEND_HOST
  },

  module: {
    loaders: [
      {
        test: /\.css$/i,
        loader: "style-loader!css-loader!postcss-loader"
      },
      {
        test: /\.js$/i,
        loader: 'babel',
        exclude: /node_modules/
      },
      {
        test: /\.(woff)$/i,
        loader: 'url-loader?limit=8192'
      },
      {
        test: /\.(png|svg|jpg|gif)$/i,
        loaders: [
          'url-loader?limit=8192',
          'image-webpack?optimizationLevel=7&interlaced=false'
        ]
      }
    ]
  },

  plugins: plugins,

  postcss: function (webpack) {
    return [
      require("postcss-import")({ addDependencyTo: webpack }),
      // require("postcss-url")(),
      require("postcss-cssnext")({ features: { rem: false } }),
      require('postcss-easings')(),
      // add your "plugins" here
      // ...
      // and if you want to compress,
      // just use css-loader option that already use cssnano under the hood
      require("postcss-browser-reporter")(),
      require("postcss-reporter")()
    ]
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import { props, t } from '../utils';
import { warn } from '../utils/log';
import Popover from '../popover/Popover';

/**
 * ### Text view which, if string content is too large, trims it and shows the full content on "hover" with a `Popover` (or custom component if any)
 */
@props({
  /**
   * in case you want to use a custom component (like a `Tooltip`) to render the full content which is passed as the first argument
   */
  children: t.maybe(t.Function),
  /**
   * this is the full string
   */
  label: t.String,
  id: t.maybe(t.String),
  className: t.maybe(t.String),
  style: t.maybe(t.Object)
}, { strict: false })
export default class TextOverflow extends React.Component {

  constructor(props) {
    super(props);
    this.state = { isOverflowing: false };
  }

  componentDidMount = () => this.verifyOverflow();

  componentDidUpdate = () => this.verifyOverflow();

  componentWillReceiveProps = (nextProps) => {
    if (nextProps.label !== this.props.label) {
      this.reset();
    }
  };

  reset = () => this.setState({ isOverflowing: false });

  logWarnings = () => {
    warn(() => {
      const node = React.findDOMNode(this.refs.text).parentNode;
      const { width, flex } = node.style;
      const flexBasis = flex ? flex.split(' ')[2] : null;
      if (width !== '100%' && flexBasis !== '100%') {
        return ['WARNING: TextOverflow\'s parent doesn\'t have "width: 100%" nor "flex-basis: 100%"', node];
      }
    });
  };

  verifyOverflow = (_state) => {
    const state = _state || this.state;
    if (state.isOverflowing === false && window) {
      const text = React.findDOMNode(this.refs.text);
      const { parentNode: parent } = text;

      const { offsetWidth: textOffsetWidth, scrollWidth: textScrollWidth } = text;
      const { width: parentWidth, 'max-width': parentMaxWidth } = window.getComputedStyle(parent);

      const isOverflowing = (textOffsetWidth < textScrollWidth) ||
        (textOffsetWidth === textScrollWidth && parseFloat(parentWidth) >= parseFloat(parentMaxWidth));

      if (isOverflowing) {
        this.setState({ isOverflowing: true }, this.logWarnings);
      } else {
        this.logWarnings();
      }
    }
  };

  getTextSpan = () => {
    const { label } = this.props;
    const style = {
      display: 'block',
      whiteSpace: 'nowrap',
      width: '100%',
      overflow: 'hidden',
      OTextOverflow: 'ellipsis', // Opera
      textOverflow: 'ellipsis'
    };
    return {label};
  };

  templateOverflow = () => {
    const { children, label, style, ...other } = this.props;

    if (children) {
      return children(this.getTextSpan());
    } else {
      const props = {
        ...other,
        popover: {
          content: label,
          event: 'hover'
        },
        style: {
          width: '100%',
          ...style
        }
      };

      return <Popover { ...props }>{this.getTextSpan()}</Popover>;
    }
  };

  templeteStandard = () => {
    const { children, label, style, ...other } = this.props;
    const props = {
      ...other,
      style: {
        width: '100%',
        ...style
      }
    };

    return
{this.getTextSpan()}
;
  };

  render() {
    return this.state.isOverflowing ? this.templateOverflow() : this.templeteStandard();
  }

}
<commit_msg>compare width with second invisible span without ellipsis<commit_after>import React from 'react';
import { props, t } from '../utils';
import { warn } from '../utils/log';
import Popover from '../popover/Popover';

/**
 * ### Text view which, if string content is too large, trims it and shows the full content on "hover" with a `Popover` (or custom component if any)
 */
@props({
  /**
   * in case you want to use a custom component (like a `Tooltip`) to render the full content which is passed as the first argument
   */
  children: t.maybe(t.Function),
  /**
   * this is the full string
   */
  label: t.String,
  id: t.maybe(t.String),
  className: t.maybe(t.String),
  style: t.maybe(t.Object)
}, { strict: false })
export default class TextOverflow extends React.Component {

  constructor(props) {
    super(props);
    this.state = { isOverflowing: false };
  }

  componentDidMount = () => this.verifyOverflow();

  componentDidUpdate = () => this.verifyOverflow();

  componentWillReceiveProps = (nextProps) => {
    if (nextProps.label !== this.props.label) {
      this.reset();
    }
  };

  reset = () => this.setState({ isOverflowing: false });

  logWarnings = () => {
    warn(() => {
      const node = React.findDOMNode(this.refs.text).parentNode;
      const { width, flex } = node.style;
      const flexBasis = flex ? flex.split(' ')[2] : null;
      if (width !== '100%' && flexBasis !== '100%') {
        return ['WARNING: TextOverflow\'s parent doesn\'t have "width: 100%" nor "flex-basis: 100%"', node];
      }
    });
  };

  verifyOverflow = (_state) => {
    const state = _state || this.state;
    if (state.isOverflowing === false) {
      const text = React.findDOMNode(this.refs.text);
      const textWithoutEllipsis = React.findDOMNode(this.refs.textWithoutEllipsis);

      const isOverflowing = (text.offsetWidth < textWithoutEllipsis.offsetWidth);
      if (isOverflowing) {
        this.setState({ isOverflowing: true }, this.logWarnings);
      } else {
        this.logWarnings();
      }
    }
  };

  getContent = () => {
    const { label } = this.props;
    const styleText = {
      display: 'block',
      whiteSpace: 'nowrap',
      width: '100%',
      overflow: 'hidden',
      OTextOverflow: 'ellipsis', // Opera
      textOverflow: 'ellipsis'
    };
    const styleTextWithoutEllipsis = {
      position: 'fixed',
      visibility: 'hidden',
      pointerEvents: 'none'
    };
    return (

        {label}
        {label}

    );
  };

  templateOverflow = () => {
    const { children, label, style, ...other } = this.props;

    if (children) {
      return children(this.getContent());
    } else {
      const props = {
        ...other,
        popover: {
          content: label,
          event: 'hover'
        },
        style: {
          width: '100%',
          ...style
        }
      };

      return <Popover { ...props }>{this.getContent()}</Popover>;
    }
  };

  templeteStandard = () => {
    const { children, label, style, ...other } = this.props;
    const props = {
      ...other,
      style: {
        width: '100%',
        ...style
      }
    };

    return
{this.getContent()}
;
  };

  render() {
    return this.state.isOverflowing ? this.templateOverflow() : this.templeteStandard();
  }

}
<|endoftext|>


<commit_before>{
var app = angular.module("app",['ui.bootstrap']);
app.controller('Input', function ($scope, $modalInstance) {

          $scope.gotMessage = function () {
            $modalInstance.close();
          };

          $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
          };
        });

app.controller('conversations', function($scope,$timeout,$modal,$log,$http,$interval) {
        $scope.message="ciao";
        $scope.input= {};
        $scope.messageid=0;
        $scope.setUserkey=function(u) {
                $scope.userkey=u;
                $scope.getConversation($scope.messageid);
                }
        $scope.getLogins=function(){$http.get("../api/Logins").success(function(xs){
                        $scope.logins=xs.result;
                        $scope.setUserkey($scope.logins[0]);
                        });
                }
        $scope.getLogins();
        $scope.getRoots=function(){$http.get("../api/Roots/" + $scope.userkey).success(function(xs){
                        $scope.roots=xs.result;
                        });
                }
        $timeout($scope.getRoots);
        $scope.getPersonal=function(){$http.get("../api/Personal/" + $scope.userkey).success(function(xs){
                        $scope.personali=xs.result;
                        });
                }
        $timeout($scope.getPersonal);
        $scope.lastConversation=Array();
        $scope.past=function(){
                if($scope.conversation[0].parent)
                $scope.getConversation($scope.conversation[0].parent);
                }
        $scope.gotox=function(){
                $scope.getConversation($scope.gotoConversation);
                }
        $scope.open = function (next) {
                var modalInstance = $modal.open({
                        animation: true,
                        templateUrl: '../input.html',
                        controller: 'Input',
                        size: 'md',
                        scope:$scope
                        });
                modalInstance.result.then(
                        function () {next ($scope.input.message);},
                        function () {}
                        );
                };
        $scope.actions= function(x) {
                var as=Array()
                if(x.canVote)
                        as.push({action:function (){$scope.voteUp(x.id)},
                            glyphicon:"glyphicon glyphicon-thumbs-up",tooltip:"Apprezza"});
                if(x.canVote)
                        as.push({action:function (){$scope.voteDown(x.id)},
                            glyphicon:"glyphicon glyphicon-thumbs-down",tooltip:"Disprezza"});
                if(x.canIntervein)
                        as.push({action:function(){$scope.respond(x.id)},
                        glyphicon:"glyphicon glyphicon-comment",tooltip:"Intervieni"});
                if(x.canRespond)
                        as.push({action:function(){$scope.respond(x.id)},
                        glyphicon:"glyphicon glyphicon-envelope",tooltip:"Rispondi"});
                if(x.canClose)
                        as.push({action:function(){$scope.closeConv(x.id)},
                                glyphicon:"glyphicon glyphicon-check",tooltip:"Chiudi"});
                if(x.canOpen)
                        as.push({action:function(){$scope.openMessage(x.id)},
                            glyphicon:"glyphicon glyphicon-share",tooltip:"Apri"});
                if(x.canRetract){
                        as.push({action:function(){$scope.retractMessage(x)},
                          glyphicon:"glyphicon glyphicon-trash",tooltip:"Rinuncia"});
                        as.push({action:function(){$scope.correctMessage(x)},
                          glyphicon:"glyphicon glyphicon-pencil",tooltip:"Correggi"});
                        }
                return as;
                }
            $scope.getConversation = function(id) {
                $scope.getRoots();
                $scope.getPersonal();
                $scope.lastConversation.push(id);
                $http.get("../api/Conversation/" + $scope.userkey + "/" + id).success (function(messages) {
                        $scope.conversation=messages.result;
                        for(var i=0;i< $scope.conversation.length;i++){
                                $scope.conversation[i].actions=$scope.actions($scope.conversation[i]);
                                $scope.conversation[i].roll=$scope.conversation[i].alter.indexOf($scope.conversation[i].id);
                                }

                        $scope.messageid=id;

                        });
                }
        $scope.rollLeft=function(x){
            if(x.roll>0){
              x.roll -= 1;
              $scope.getConversation(x.alter[x.roll]);
              }
            }
        $scope.rollLeft0=function(x){
            if(x.roll>0){
              x.roll = 0;
              $scope.getConversation(x.alter[x.roll]);
              }
            }
        $scope.canRollLeft=function(x){
            return(x.roll > 0);
            }
        $scope.rollRight=function(x){
            if(x.roll<x.alter.length-1){
              x.roll += 1;
              $scope.getConversation(x.alter[x.roll]);
              }
            }
        $scope.canRollRight=function(x){
            return(x.roll < x.alter.length - 1);
            }
        $scope.invite=function (){
                $http.post("../api/Invite/"+$scope.userkey,$scope.mailremainder).success(
                        function () {$scope.getConversation(0);$scope.mailremainder=null;$scope.getLogins();});
                }

        $scope.closeConv=function(id){
                $http.put("../api/Close/"+$scope.userkey +"/" + id).success(
                        function () {$scope.getConversation(id)});
                }

        $scope.openMessage=function(id){
                $http.put("../api/Open/"+$scope.userkey +"/" + id).success(
                        function () {$scope.getConversation(id)});
                }
        $scope.respond=function(id){
                $scope.open(function (){
                        $http.post("../api/New/"+$scope.userkey + "/Attach/" + id,$scope.input.message).success(
                                function (rs) {
                                        if(rs.events[0].newmessage)
                                            $scope.getConversation(rs.events[0].newmessage);
                                        else $scope.getConversation(0);
                                            $scope.input.message=null;

                                });
                        })
                };
        $scope.moot=function(){
                $scope.open(function (){
                        $http.post("../api/New/"+$scope.userkey + "/DontAttach",$scope.input.message).success(
                                function (rs) {
                                        if(rs.events[0].newmessage)
                                            $scope.getConversation(rs.events[0].newmessage);
                                        else $scope.getConversation(0);
                                            $scope.input.message=null;

                                });
                        })
                };
       $scope.correctMessage=function(x){
                $scope.input.message=x.text;
                $scope.open(function (){
                        $http.post("../api/New/"+$scope.userkey + "/Correct/" + x.id,$scope.input.message).success(
                                function () {
                                        $scope.getConversation(x.id);
                                        $scope.input.message=null;
                                });
                        })
                };

        $scope.retractMessage = function (x){
                $http.put("../api/Retract/"+$scope.userkey + "/" + x.id).success(
                function () {
                    if(x.parent) {
                        $scope.getConversation(x.parent);
                        }
                    else
                        $scope.getConversation(0);

                    });
                }

        //voting stuff
        $scope.voteUp=function(id){
                $http.put("../api/Vote/"+$scope.userkey + "/" +  id  + "/True").success(function () {$scope.getConversation(id)});}

        $scope.voteDown=function(id){
                $http.put("../api/Vote/"+$scope.userkey + "/" + id + "/False").success(function () {$scope.getConversation(id)});};
        $interval(function (){$scope.getConversation($scope.messageid)},3000);
        });
}

/*

        // messaging stuff
        $scope.correct=function(mid){
        if($scope.message){
                $http.post("../api/New/"+$scope.userkey + "/Correct/" + mid,$scope.message).success(
                        function () {$scope.getConversation(mid)});
                $scope.message=null;
                }
        };

        $scope.open = function(){
        if($scope.message){
                $http.post("../api/New/"+$scope.userkey + "/DontAttach",$scope.message).success(
                        function () {$scope.getConversation(0)});
                $scope.message=null;
                }
        };

        $scope.leave = function (){
        $http.put("../api/Leave/"+$scope.userkey + "/Accept/" + mid).success(
                function () {$scope.getConversation(mid)});
        }

        $scope.reminds=function (){
        $http.post("api/Reminds",$scope.mailremainder).success(
                function () {$scope.mailremainder=null});
        }
        $scope.logout=function (){
        $http.put("../api/Logout/"+$scope.userkey).success(
                function () {location.reload();});
        }
        $scope.clean=function(){
        $scope.message=null;
        };
        $scope.canClean=function(){
        return $scope.message
        };
        $scope.copi=function(){
        if($scope.message){
                $scope.copy=$scope.message;
                $scope.message=null;
                }
        };
        $scope.canCopi=function(){
        return $scope.message
        };
        $scope.paste=function(){
        if($scope.copy){
                $scope.message=$scope.copy;
                }
        };
        $scope.canPaste=function(){
        return $scope.copy;
        };

}
*/

<commit_msg>all featured<commit_after>{
var app = angular.module("app",['ui.bootstrap']);
app.controller('Input', function ($scope, $modalInstance) {

          $scope.gotMessage = function () {
            $modalInstance.close();
          };

          $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
          };
        });

app.controller('conversations', function($scope,$timeout,$modal,$log,$http,$interval) {
        $scope.message="ciao";
        $scope.input= {};
        $scope.messageid=0;
        $scope.setUserkey=function(u) {
                $scope.userkey=u;
                $scope.getConversation($scope.messageid);
                }
        $scope.getLogins=function(){$http.get("../api/Logins").success(function(xs){
                        $scope.logins=xs.result;
                        $scope.setUserkey($scope.logins[0]);
                        });
                }
        $scope.getLogins();
        $scope.getRoots=function(){$http.get("../api/Roots/" + $scope.userkey).success(function(xs){
                        $scope.roots=xs.result;
                        });
                }
        $timeout($scope.getRoots);
        $scope.getPersonal=function(){$http.get("../api/Personal/" + $scope.userkey).success(function(xs){
                        $scope.personali=xs.result;
                        });
                }
        $timeout($scope.getPersonal);
        $scope.lastConversation=Array();
        $scope.past=function(){
                if($scope.conversation[0].parent)
                $scope.getConversation($scope.conversation[0].parent);
                }
        $scope.gotox=function(){
                $scope.getConversation($scope.gotoConversation);
                }
        $scope.open = function (next) {
                var modalInstance = $modal.open({
                        animation: true,
                        templateUrl: '../input.html',
                        controller: 'Input',
                        size: 'md',
                        scope:$scope
                        });
                modalInstance.result.then(
                        function () {next ($scope.input.message);},
                        function () {}
                        );
                };
        $scope.actions= function(x) {
                var as=Array()
                if(x.canVote)
                        as.push({action:function (){$scope.voteUp(x.id)},
                            glyphicon:"glyphicon glyphicon-thumbs-up",tooltip:"Apprezza"});
                if(x.canVote)
                        as.push({action:function (){$scope.voteDown(x.id)},
                            glyphicon:"glyphicon glyphicon-thumbs-down",tooltip:"Disprezza"});
                if(x.canIntervein)
                        as.push({action:function(){$scope.respond(x.id)},
                        glyphicon:"glyphicon glyphicon-comment",tooltip:"Intervieni"});
                if(x.canRespond)
                        as.push({action:function(){$scope.respond(x.id)},
                        glyphicon:"glyphicon glyphicon-envelope",tooltip:"Rispondi"});
                if(x.canClose)
                        as.push({action:function(){$scope.closeConv(x.id)},
                                glyphicon:"glyphicon glyphicon-check",tooltip:"Chiudi"});
                if(x.canOpen)
                        as.push({action:function(){$scope.openMessage(x.id)},
                            glyphicon:"glyphicon glyphicon-share",tooltip:"Apri"});
                if(x.canRetract){
                        as.push({action:function(){$scope.retractMessage(x)},
                          glyphicon:"glyphicon glyphicon-trash",tooltip:"Rinuncia"});
                        as.push({action:function(){$scope.correctMessage(x)},
                          glyphicon:"glyphicon glyphicon-pencil",tooltip:"Correggi"});
                        }
                return as;
                }
            $scope.getConversation = function(id) {
                $scope.getRoots();
                $scope.getPersonal();
                $scope.lastConversation.push(id);
                $scope.notgetting=false;
                $http.get("../api/Conversation/" + $scope.userkey + "/" + id).success (function(messages) {
                        $scope.conversation=messages.result;
                        for(var i=0;i< $scope.conversation.length;i++){
                                $scope.conversation[i].actions=$scope.actions($scope.conversation[i]);
                                $scope.conversation[i].roll=$scope.conversation[i].alter.indexOf($scope.conversation[i].id);
                                }

                        $scope.notgetting=true;
                        $scope.messageid=id;

                        });
                }
        $scope.rollLeft=function(x){
            if(x.roll>0){
              x.roll -= 1;
              $scope.getConversation(x.alter[x.roll]);
              }
            }
        $scope.rollLeft0=function(x){
            if(x.roll>0){
              x.roll = 0;
              $scope.getConversation(x.alter[x.roll]);
              }
            }
        $scope.canRollLeft=function(x){
            return(x.roll > 0);
            }
        $scope.rollRight=function(x){
            if(x.roll<x.alter.length-1){
              x.roll += 1;
              $scope.getConversation(x.alter[x.roll]);
              }
            }
        $scope.canRollRight=function(x){
            return(x.roll < x.alter.length - 1);
            }
        $scope.invite=function (){
                $http.post("../api/Invite/"+$scope.userkey,$scope.mailremainder).success(
                        function () {$scope.getConversation(0);$scope.mailremainder=null;$scope.getLogins();});
                }

        $scope.closeConv=function(id){
                $http.put("../api/Close/"+$scope.userkey +"/" + id).success(
                        function () {$scope.getConversation(id)});
                }

        $scope.openMessage=function(id){
                $http.put("../api/Open/"+$scope.userkey +"/" + id).success(
                        function () {$scope.getConversation(id)});
                }
        $scope.respond=function(id){
                $scope.open(function (){
                        $http.post("../api/New/"+$scope.userkey + "/Attach/" + id,$scope.input.message).success(
                                function (rs) {
                                        if(rs.events[0].newmessage)
                                            $scope.getConversation(rs.events[0].newmessage);
                                        else $scope.getConversation(0);
                                            $scope.input.message=null;

                                });
                        })
                };
        $scope.moot=function(){
                $scope.open(function (){
                        $http.post("../api/New/"+$scope.userkey + "/DontAttach",$scope.input.message).success(
                                function (rs) {
                                        if(rs.events[0].newmessage)
                                            $scope.getConversation(rs.events[0].newmessage);
                                        else $scope.getConversation(0);
                                            $scope.input.message=null;

                                });
                        })
                };
       $scope.correctMessage=function(x){
                $scope.input.message=x.text;
                $scope.open(function (){
                        $http.post("../api/New/"+$scope.userkey + "/Correct/" + x.id,$scope.input.message).success(
                                function () {
                                        $scope.getConversation(x.id);
                                        $scope.input.message=null;
                                });
                        })
                };

        $scope.retractMessage = function (x){
                $http.put("../api/Retract/"+$scope.userkey + "/" + x.id).success(
                function () {
                    if(x.parent) {
                        $scope.getConversation(x.parent);
                        }
                    else
                        $scope.getConversation(0);

                    });
                }

        //voting stuff
        $scope.voteUp=function(id){
                $http.put("../api/Vote/"+$scope.userkey + "/" +  id  + "/True").success(function () {$scope.getConversation(id)});}

        $scope.voteDown=function(id){
                $http.put("../api/Vote/"+$scope.userkey + "/" + id + "/False").success(function () {$scope.getConversation(id)});};
        $interval(function (){
            if($scope.notgetting)
                $scope.getConversation($scope.messageid)}
            ,5000);
        });
}

/*

        // messaging stuff
        $scope.correct=function(mid){
        if($scope.message){
                $http.post("../api/New/"+$scope.userkey + "/Correct/" + mid,$scope.message).success(
                        function () {$scope.getConversation(mid)});
                $scope.message=null;
                }
        };

        $scope.open = function(){
        if($scope.message){
                $http.post("../api/New/"+$scope.userkey + "/DontAttach",$scope.message).success(
                        function () {$scope.getConversation(0)});
                $scope.message=null;
                }
        };

        $scope.leave = function (){
        $http.put("../api/Leave/"+$scope.userkey + "/Accept/" + mid).success(
                function () {$scope.getConversation(mid)});
        }

        $scope.reminds=function (){
        $http.post("api/Reminds",$scope.mailremainder).success(
                function () {$scope.mailremainder=null});
        }
        $scope.logout=function (){
        $http.put("../api/Logout/"+$scope.userkey).success(
                function () {location.reload();});
        }
        $scope.clean=function(){
        $scope.message=null;
        };
        $scope.canClean=function(){
        return $scope.message
        };
        $scope.copi=function(){
        if($scope.message){
                $scope.copy=$scope.message;
                $scope.message=null;
                }
        };
        $scope.canCopi=function(){
        return $scope.message
        };
        $scope.paste=function(){
        if($scope.copy){
                $scope.message=$scope.copy;
                }
        };
        $scope.canPaste=function(){
        return $scope.copy;
        };

}
*/

<|endoftext|>


<commit_before>define(['text!../templates/tilda_schema/_new.html',
    "../core/parser", '../core/file_search'],
  function(_NewView, _Parser, _FileSearch){
  var error = function(error){
    console.log(error.message);
    console.log(error.stack);
  }

  var Backbone = require('backbone');
  var _ = require('lodash');
  var promiseError = function(error, reject){
    console.error(error.message);
    console.error(error.stack);
    reject(error)
  }
  var SCHEMA_REGEX = /\_tilda\.([A-Z][A-Za-z_0-9]+)\.json/i;

  var fileInputHandler = function(viewScope, entry) {
    viewScope.currentEntry = entry;
    var reader = entry.createReader();
    var errorCallback = function(e) {
      console.error(e);
    }
    var $select = viewScope.$el.find('select');
    viewScope.$el.find('.actions').hide();
    var f = new _FileSearch(entry, viewScope.excludeRegex, function(files){
      console.log("Files ->");
      console.log(files);
      $select.html('');
      $select.append('<option value=\'\'>--- select a schema ---</option');
      viewScope.schemaEntries = files;
      for(i=0;i<files.length;i++){
        var file = files[i];
        $select.append('<option value=\''+i+'\'>'+file.name+'</option')
      }
      viewScope.$el.find('.actions').show();
    })
  }
  var TildaSchemaView = Backbone.View.extend({
    schemaName: null,
    currentEntry: null,
    packageInfo: null,
    schemaEntries: [],
    excludeRegex: null,
    events: {
      'click button[name="schema-file"]': 'handleFileInput',
      'click .saveSchema': 'saveSchema',
      'change input:radio[name="showObj"]': "togglePapers",
      'change select': "changeView",
      'click .save-regex': 'saveRegex',
      'click .filterRegex': function(){
        $('#filterD').modal('show');
      }
    },
    saveRegex: function(event){
      var value = $('.regex-f').val();
      this.excludeRegex = new RegExp(value, 'i');
      console.log(chrome.storage);
      if(chrome.storage){
        chrome.storage.local.set("regex-f", value);
      }
      console.log(value);
      console.log(this.excludeRegex);
      $('#filterD').modal('hide');
      fileInputHandler(this, this.savedEntry);
    },
    changeView: function(event){
      var that = this;
      var index = parseInt($(event.target).val());
      if(index == NaN)
        return;
      var schemaEntry = this.schemaEntries[index];
      this.currentEntry = schemaEntry;
      var init = function(objectEntries){
        var pkgInfo = objectEntries.packageInfo;
        that.packageInfo = pkgInfo;
        that.initCache(objectEntries.cacheEntry).then(function(cache){
          window.tildaCache = cache;
          var schemaFname = "_tilda."+pkgInfo.schema.name+".json";
          that.$el.find(".fName").html("
loaded "+schemaFname+"
")
          that.schemaFrom(objectEntries.schemaEntry).then(function(schema){
            that.$el.find("#obj_c").html("");
            that.$el.find("#view_c").html("");
            that.$el.find("#view_c").show();
            that.$el.find("#obj_c").show();
            that.schemaParser_object = new _Parser(_.clone(schema), "obj_c", {viewOnly: false});
            that.schemaParser_view = new _Parser(_.clone(schema), "view_c", {viewOnly: true});
          }).catch(error);
        }).catch(error);
      }
      // Call the reader.readEntries() until no more results are returned.
      var readEntries = function(dirReader) {
        var fName = schemaEntry.name;
        var match = SCHEMA_REGEX.exec(fName);
        var objects = {}
        objects.packageInfo = {
          "schema": {
            "name": match[1],
            "path": fName
          }
        };
        objects.schemaEntry = schemaEntry;
        dirReader.readEntries (function(results) {
         for(i=0; i<results.length; i++){
            var fName = results[i].name;
            var name = objects.schemaEntry.name.split(".")[1];
            if(fName == "_tilda."+name+".graphInfo.json"){
              objects.cacheEntry = results[i];
              break;
            }
          }
          init(objects)
        }, function(error){console.error(error.message);});
      };
      schemaEntry.getParent(function(dEntry){
        var dirReader = dEntry.createReader();
        readEntries(dirReader); // Start reading directory contents.
      }, function(error){
        console.error(error);
      })
    },
    togglePapers: function(){
      if($(event.target).val() == "object"){
        this.$el.find("#view_c").hide(); // hide for now.
        this.$el.find("#obj_c").show();
      } else{
        this.$el.find("#obj_c").hide(); // hide for now.
        this.$el.find("#view_c").show();
      }
    },
    render: function(){
      var that = this;
      that.$el.html(_NewView);
      if(chrome.storage){
        chrome.storage.local.get("regex-f", function(value){
          if(value != null || value.length > 0){
            that.excludeRegex = new RegExp(value, "i");
            console.log(value);
            console.log(that.excludeRegex);
            that.$el.find('.regex-f').val(value);
          }
        });
      }

      that.$el.find('.actions').hide();

      return this;
    },
    schemaFrom: function(fileEntry){
      var p = new Promise(function (resolve, reject) {
        var readFile = function(_file){
          var reader = new FileReader();
          reader.onload = function(event) {
            try{
              var schema = JSON.parse(event.target.result);
              resolve(schema)
            } catch(e){
              console.error("Error occured -> "+e.message);
              console.error(e.stack);
              reject(e);
            }
          };
          reader.readAsText(_file);
        }
        fileEntry.file(function(file){
          readFile(file);
        })
      })
      return p;
    },
    initCache: function(fileEntry){
      var p = new Promise(function (resolve, reject) {
        var readFile = function(_file){
          var reader = new FileReader();
          reader.onload = function(event) {
            try{
              var tildaCache = JSON.parse(event.target.result) || {};
              resolve(tildaCache)
            } catch(e){
              resolve({})
            }
          };
          reader.readAsText(_file);
        }
        if(fileEntry == null){
          // fileEntry might not be there.
          resolve({})
        } else {
          fileEntry.file(function(file){
            readFile(file);
          })
        }
      })
      return p;
    },
    handleFileInput: function(event){
      var that = this;
      var $select = that.$el.find('select');
      that.$el.find('.actions').hide();
      var error = function(error){
        console.log(error.message);
        console.log(error.stack);
      }
      chrome.fileSystem.chooseEntry({ type: 'openDirectory'},  function(entry) {
        that.savedEntry = entry;
        fileInputHandler(that, entry);
      });
      return 0;
    },
    saveSchema: function(event){
      that = this;
      this.currentEntry.getParent(function(dEntry){
        that.writeUserPrefs(dEntry, event);
        that.writeSVG(dEntry, event);
      })
    },
    writeSVG: function(entry, event){
      // TODO write to a file.
      var objSVG = this.schemaParser_object.paper.$el.find("svg")[0]

      var viewSVG = this.schemaParser_view.paper.$el.find("svg")[0];
      var that = this;
      var fileName = "_tilda."+this.packageInfo.schema.name.toUpperCase()+".html";
      // var docText = _.map(that.schemaParser_object.schema.documentation.description, function(line){
      //   return "
"+line+"
\n"
      // }).join("\n")
      $.get('css/viewonly_joint.css', function(css){
        entry.getFile(fileName, {create: true}, function(fileEntry){
          fileEntry.createWriter(function(fileWriter) {
            var truncated = false;
            var script = "\n\
              ";
            var blob = new Blob(["",
                "

Tables Graph

\n",
                "
\n",
                objSVG.parentElement.innerHTML,
                "\n
\n",
                "
\n",
                "

Views Graph

\n",
                "
\n",
                viewSVG.parentElement.innerHTML,
                "\n
\n",
                script
              ], {type: "image/svg"});
            fileWriter.onwriteend = function(e) {
              if (!truncated) {
                truncated = true;
                // You need to explicitly set the file size to truncate
                // any content that might have been there before
                this.truncate(blob.size);
                return;
              }
              console.log('Export to '+fileDisplayPath+' completed');
            };
            fileWriter.onerror = function(e) {
              console.error('Export failed: '+e.toString());
            };
            fileWriter.write(blob);
          });
        })
      })
    },
    writeUserPrefs: function(entry, event){
      var fileName = "_tilda."+this.packageInfo.schema.name+".graphInfo.json";
      entry.getFile(fileName, {create: true}, function(fileEntry){
        fileEntry.createWriter(function(fileWriter) {
          var blob = new Blob([JSON.stringify(window.tildaCache,null,2)]);
          fileWriter.onwriteend = function(e) {
            if (!truncated) {
              truncated = true;
              // You need to explicitly set the file size to truncate
              // any content that might have been there before
              this.truncate(blob.size);
              return;
            }
            console.log('Export to '+fileDisplayPath+' completed');
          };
          fileWriter.onerror = function(e) {
            console.error('Export failed: '+e.toString());
          };
          fileWriter.write(blob);
        });
      });
    },
    resetView: function(event){
      if(this.schemaParser_object){
        this.schemaParser_object.resetAll();
      }
      if(this.schemaParser_view){
        this.schemaParser_view.resetAll();
      }
    }
  })
  return TildaSchemaView;
})<commit_msg>Default excluding filter<commit_after>define(['text!../templates/tilda_schema/_new.html',
    "../core/parser", '../core/file_search'],
  function(_NewView, _Parser, _FileSearch){
  var error = function(error){
    console.log(error.message);
    console.log(error.stack);
  }

  var Backbone = require('backbone');
  var _ = require('lodash');
  var promiseError = function(error, reject){
    console.error(error.message);
    console.error(error.stack);
    reject(error)
  }
  var SCHEMA_REGEX = /\_tilda\.([A-Z][A-Za-z_0-9]+)\.json/i;

  var fileInputHandler = function(viewScope, entry) {
    viewScope.currentEntry = entry;
    var reader = entry.createReader();
    var errorCallback = function(e) {
      console.error(e);
    }
    var $select = viewScope.$el.find('select');
    viewScope.$el.find('.actions').hide();
    var f = new _FileSearch(entry, viewScope.excludeRegex, function(files){
      console.log("Files ->");
      console.log(files);
      $select.html('');
      $select.append('<option value=\'\'>--- select a schema ---</option');
      viewScope.schemaEntries = files;
      for(i=0;i<files.length;i++){
        var file = files[i];
        $select.append('<option value=\''+i+'\'>'+file.name+'</option')
      }
      viewScope.$el.find('.actions').show();
    })
  }
  var TildaSchemaView = Backbone.View.extend({
    schemaName: null,
    currentEntry: null,
    packageInfo: null,
    schemaEntries: [],
    excludeRegex: null,
    events: {
      'click button[name="schema-file"]': 'handleFileInput',
      'click .saveSchema': 'saveSchema',
      'change input:radio[name="showObj"]': "togglePapers",
      'change select': "changeView",
      'click .save-regex': 'saveRegex',
      'click .filterRegex': function(){
        $('#filterD').modal('show');
      }
    },
    saveRegex: function(event){
      var value = $('.regex-f').val();
      this.excludeRegex = new RegExp(value, 'i');
      console.log(chrome.storage);
      if(chrome.storage){
        chrome.storage.local.set("regex-f", value);
      }
      console.log(value);
      console.log(this.excludeRegex);
      $('#filterD').modal('hide');
      fileInputHandler(this, this.savedEntry);
    },
    changeView: function(event){
      var that = this;
      var index = parseInt($(event.target).val());
      if(index == NaN)
        return;
      var schemaEntry = this.schemaEntries[index];
      this.currentEntry = schemaEntry;
      var init = function(objectEntries){
        var pkgInfo = objectEntries.packageInfo;
        that.packageInfo = pkgInfo;
        that.initCache(objectEntries.cacheEntry).then(function(cache){
          window.tildaCache = cache;
          var schemaFname = "_tilda."+pkgInfo.schema.name+".json";
          that.$el.find(".fName").html("
loaded "+schemaFname+"
")
          that.schemaFrom(objectEntries.schemaEntry).then(function(schema){
            that.$el.find("#obj_c").html("");
            that.$el.find("#view_c").html("");
            that.$el.find("#view_c").show();
            that.$el.find("#obj_c").show();
            that.schemaParser_object = new _Parser(_.clone(schema), "obj_c", {viewOnly: false});
            that.schemaParser_view = new _Parser(_.clone(schema), "view_c", {viewOnly: true});
          }).catch(error);
        }).catch(error);
      }
      // Call the reader.readEntries() until no more results are returned.
      var readEntries = function(dirReader) {
        var fName = schemaEntry.name;
        var match = SCHEMA_REGEX.exec(fName);
        var objects = {}
        objects.packageInfo = {
          "schema": {
            "name": match[1],
            "path": fName
          }
        };
        objects.schemaEntry = schemaEntry;
        dirReader.readEntries (function(results) {
         for(i=0; i<results.length; i++){
            var fName = results[i].name;
            var name = objects.schemaEntry.name.split(".")[1];
            if(fName == "_tilda."+name+".graphInfo.json"){
              objects.cacheEntry = results[i];
              break;
            }
          }
          init(objects)
        }, function(error){console.error(error.message);});
      };
      schemaEntry.getParent(function(dEntry){
        var dirReader = dEntry.createReader();
        readEntries(dirReader); // Start reading directory contents.
      }, function(error){
        console.error(error);
      })
    },
    togglePapers: function(){
      if($(event.target).val() == "object"){
        this.$el.find("#view_c").hide(); // hide for now.
        this.$el.find("#obj_c").show();
      } else{
        this.$el.find("#obj_c").hide(); // hide for now.
        this.$el.find("#view_c").show();
      }
    },
    render: function(){
      var that = this;
      that.$el.html(_NewView);
      if(chrome.storage){
        chrome.storage.local.get("regex-f", function(value){
          if(value != null || value.length > 0){
            that.excludeRegex = new RegExp(value, "i");
            console.log(value);
            console.log(that.excludeRegex);
            that.$el.find('.regex-f').val(value);
          }
        });
      } else {
        that.excludeRegex = new RegExp("\/bin\/*", "i"); // default filter
      }

      that.$el.find('.actions').hide();

      return this;
    },
    schemaFrom: function(fileEntry){
      var p = new Promise(function (resolve, reject) {
        var readFile = function(_file){
          var reader = new FileReader();
          reader.onload = function(event) {
            try{
              var schema = JSON.parse(event.target.result);
              resolve(schema)
            } catch(e){
              console.error("Error occured -> "+e.message);
              console.error(e.stack);
              reject(e);
            }
          };
          reader.readAsText(_file);
        }
        fileEntry.file(function(file){
          readFile(file);
        })
      })
      return p;
    },
    initCache: function(fileEntry){
      var p = new Promise(function (resolve, reject) {
        var readFile = function(_file){
          var reader = new FileReader();
          reader.onload = function(event) {
            try{
              var tildaCache = JSON.parse(event.target.result) || {};
              resolve(tildaCache)
            } catch(e){
              resolve({})
            }
          };
          reader.readAsText(_file);
        }
        if(fileEntry == null){
          // fileEntry might not be there.
          resolve({})
        } else {
          fileEntry.file(function(file){
            readFile(file);
          })
        }
      })
      return p;
    },
    handleFileInput: function(event){
      var that = this;
      var $select = that.$el.find('select');
      that.$el.find('.actions').hide();
      var error = function(error){
        console.log(error.message);
        console.log(error.stack);
      }
      chrome.fileSystem.chooseEntry({ type: 'openDirectory'},  function(entry) {
        that.savedEntry = entry;
        fileInputHandler(that, entry);
      });
      return 0;
    },
    saveSchema: function(event){
      that = this;
      this.currentEntry.getParent(function(dEntry){
        that.writeUserPrefs(dEntry, event);
        that.writeSVG(dEntry, event);
      })
    },
    writeSVG: function(entry, event){
      // TODO write to a file.
      var objSVG = this.schemaParser_object.paper.$el.find("svg")[0]

      var viewSVG = this.schemaParser_view.paper.$el.find("svg")[0];
      var that = this;
      var fileName = "_tilda."+this.packageInfo.schema.name.toUpperCase()+".html";
      // var docText = _.map(that.schemaParser_object.schema.documentation.description, function(line){
      //   return "
"+line+"
\n"
      // }).join("\n")
      $.get('css/viewonly_joint.css', function(css){
        entry.getFile(fileName, {create: true}, function(fileEntry){
          fileEntry.createWriter(function(fileWriter) {
            var truncated = false;
            var script = "\n\
              ";
            var blob = new Blob(["",
                "

Tables Graph

\n",
                "
\n",
                objSVG.parentElement.innerHTML,
                "\n
\n",
                "
\n",
                "

Views Graph

\n",
                "
\n",
                viewSVG.parentElement.innerHTML,
                "\n
\n",
                script
              ], {type: "image/svg"});
            fileWriter.onwriteend = function(e) {
              if (!truncated) {
                truncated = true;
                // You need to explicitly set the file size to truncate
                // any content that might have been there before
                this.truncate(blob.size);
                return;
              }
              console.log('Export to '+fileDisplayPath+' completed');
            };
            fileWriter.onerror = function(e) {
              console.error('Export failed: '+e.toString());
            };
            fileWriter.write(blob);
          });
        })
      })
    },
    writeUserPrefs: function(entry, event){
      var fileName = "_tilda."+this.packageInfo.schema.name+".graphInfo.json";
      entry.getFile(fileName, {create: true}, function(fileEntry){
        fileEntry.createWriter(function(fileWriter) {
          var blob = new Blob([JSON.stringify(window.tildaCache,null,2)]);
          fileWriter.onwriteend = function(e) {
            if (!truncated) {
              truncated = true;
              // You need to explicitly set the file size to truncate
              // any content that might have been there before
              this.truncate(blob.size);
              return;
            }
            console.log('Export to '+fileDisplayPath+' completed');
          };
          fileWriter.onerror = function(e) {
            console.error('Export failed: '+e.toString());
          };
          fileWriter.write(blob);
        });
      });
    },
    resetView: function(event){
      if(this.schemaParser_object){
        this.schemaParser_object.resetAll();
      }
      if(this.schemaParser_view){
        this.schemaParser_view.resetAll();
      }
    }
  })
  return TildaSchemaView;
})<|endoftext|>


<commit_before>/*jslint plusplus: true, passfail: true, browser: true, devel: true, indent: 4, maxlen: 80 */
/*global chrome*/
(function () {
	'use strict';

	var winGrid = 20; // px to use for window grid

	function restore_options() {
		var inputs = document.getElementsByClassName('option'),
			value,
			def,
			i;

		for (i = 0; i < inputs.length; i++) {
			value = localStorage['ttw_' + inputs[i].id];
			if (inputs[i].id === "top") {
				def = 0;
			} else {
				def = 50;
			}

			if (typeof value === "undefined") {
				inputs[i].value = def;
			} else {
				inputs[i].value = value;
			}
		}
	}

	function save_options(event) {
		var inputs = document.getElementsByClassName('option'),
			submit = document.getElementById('sub'),
			valid = true,
			i;

		// Save to Local Storage
		for (i = 0; i < inputs.length; i++) {
			if (inputs[i].checkValidity()) {
				localStorage['ttw_' + inputs[i].id] = inputs[i].valueAsNumber;
			}
		}
	}

	function make_oninput_handler() {
		return function (event) {
			var input = event.target,
				val = Number(input.value),
				max = Number(input.max),
				min = Number(input.min),
				split = input.id.split('-'),
				$win = $('#' + split[0]);

			$win.css(split[1], val + '%');
			$win.resize();

			if (input.checkValidity()) {
				save_options();
			}
		};
	}

	function make_oninvalid_handler() {
		var submit = document.getElementById('sub');

		return function (event) {
			var input = event.target,
				val = Number(input.value),
				max = Number(input.max),
				min = Number(input.min);

			submit.click();
		};
	}

	function add_input_handlers() {
		var inputs = document.getElementsByClassName('option'),
			i;

		for (i = 0; i < inputs.length; i++) {
			inputs[i].oninput = make_oninput_handler();
			inputs[i].oninvalid = make_oninvalid_handler();
		}
	}

	function resize_screen() {
		var userScreen = document.getElementById('monitor'),
			width = userScreen.clientWidth,
			ratio = screen.height / screen.width,
			height = Math.round(width * ratio / winGrid) * winGrid;

		userScreen.style.height =  height+ "px";
	}

	function open_extensions() {
		chrome.tabs.update({
			url: 'chrome://extensions/'
		});
	}

	function update_window_size_and_position(win, ui) {
		var $userScreen, $win, $inner, screenWidth, screenHeight, width, height,
			left, top, innerHorizWidth, innerVertWidth;

		$userScreen = $('#screen');
		$win = $(win);
		$inner = $('.inner-window', $win);
		screenWidth = $userScreen.width();
		screenHeight = $userScreen.height();
		width = Math.floor(($(win).width() / screenWidth) * 100);
		height = Math.floor(($(win).height() / screenHeight) * 100);
		innerHorizWidth = parseInt($inner.css('border-left-width'), 10) +
			parseInt($inner.css('border-right-width'), 10);
		innerVertWidth = parseInt($inner.css('border-top-width'), 10) +
			parseInt($inner.css('border-bottom-width'), 10);

		// update inner-window for borders
		$inner.width($win.width() - innerHorizWidth);
		$inner.height($win.height() - innerVertWidth);

		// update form
		$('#' + $win.attr('id') + '-width').val(width);
		$('#' + $win.attr('id') + '-height').val(height);

		if (typeof ui !== 'undefined') {
			left = Math.floor((ui.position.left / screenWidth) * 100);
			top = Math.floor((ui.position.top / screenHeight) * 100);
			$('#' + $win.attr('id') + '-left').val(left);
			$('#' + $win.attr('id') + '-top').val(top);
		}
	}

	function setup_windows() {
		var $windows = $('.window'),
			$userScreen = $('#screen'),
			screenWidth = $userScreen.width(),
			screenHeight = $userScreen.height();

		// Restore positions from options
		$('.window').each(function () {
			var $this = $(this);
			$this.width($('#' + $this.attr('id') + '-width').val() + "%");
			$this.height($('#' + $this.attr('id') + '-height').val() + "%");
			$this.css('left', $('#' + $this.attr('id') + '-left').val() + "%");
			$this.css('top', $('#' + $this.attr('id') + '-top').val() + "%");

			$this.draggable({
				containment: "parent",
				grid: [screenWidth / winGrid, screenHeight / winGrid]
			});

			$this.resizable({
				containment: "parent",
				handles: "all",
				grid: [screenWidth / winGrid, screenHeight / winGrid],
				minWidth: $this.parent().width() * 0.2,
				minHeight: $this.parent().height() * 0.2
			});

			$this.on('resize', function(event, ui) {
				update_window_size_and_position(this, ui);
				save_options();
			});

			$this.on('drag', function(event, ui) {
				update_window_size_and_position(this, ui);
				save_options();
			});
		});

	}

	jQuery(document).ready(function($) {
		resize_screen();
		restore_options();
		add_input_handlers();
		setup_windows();

		$('.window').trigger('resize');
		$('#extensions').click(open_extensions);
		$('#sub').click(save_options);
	});
}());<commit_msg>Proper loading of defaults<commit_after>/*jslint plusplus: true, passfail: true, browser: true, devel: true, indent: 4, maxlen: 80 */
/*global chrome*/
(function () {
	'use strict';

	var winGrid = 20; // px to use for window grid
	var defaults = {
		"original": {width: 50, height: 100, left: 0, top: 0},
		"new": {width: 50, height: 100, left: 50, top: 0}
	};

	function restore_options() {
		var wKey, pKey, id, input, value;

		for (wKey in defaults) {
			if (defaults.hasOwnProperty(wKey)) {
				for (pKey in defaults[wKey]) {
					if (defaults[wKey].hasOwnProperty(pKey)) {
						id = wKey + "-" + pKey;
						input = document.getElementById(id);
						value = localStorage['ttw_' + id];

						if (typeof value === "undefined") {
							value = defaults[wKey][pKey];
						}

						input.value = value;
					}
				}
			}
		}
	}

	function save_options(event) {
		var inputs = document.getElementsByClassName('option'),
			submit = document.getElementById('sub'),
			valid = true,
			i;

		// Save to Local Storage
		for (i = 0; i < inputs.length; i++) {
			if (inputs[i].checkValidity()) {
				localStorage['ttw_' + inputs[i].id] = inputs[i].valueAsNumber;
			}
		}
	}

	function make_oninput_handler() {
		return function (event) {
			var input = event.target,
				val = Number(input.value),
				max = Number(input.max),
				min = Number(input.min),
				split = input.id.split('-'),
				$win = $('#' + split[0]);

			$win.css(split[1], val + '%');
			$win.resize();

			if (input.checkValidity()) {
				save_options();
			}
		};
	}

	function make_oninvalid_handler() {
		var submit = document.getElementById('sub');

		return function (event) {
			var input = event.target,
				val = Number(input.value),
				max = Number(input.max),
				min = Number(input.min);

			submit.click();
		};
	}

	function add_input_handlers() {
		var inputs = document.getElementsByClassName('option'),
			i;

		for (i = 0; i < inputs.length; i++) {
			inputs[i].oninput = make_oninput_handler();
			inputs[i].oninvalid = make_oninvalid_handler();
		}
	}

	function resize_screen() {
		var userScreen = document.getElementById('monitor'),
			width = userScreen.clientWidth,
			ratio = screen.height / screen.width,
			height = Math.round(width * ratio / winGrid) * winGrid;

		userScreen.style.height =  height+ "px";
	}

	function open_extensions() {
		chrome.tabs.update({
			url: 'chrome://extensions/'
		});
	}

	function update_window_size_and_position(win, ui) {
		var $userScreen, $win, $inner, screenWidth, screenHeight, width, height,
			left, top, innerHorizWidth, innerVertWidth;

		$userScreen = $('#screen');
		$win = $(win);
		$inner = $('.inner-window', $win);
		screenWidth = $userScreen.width();
		screenHeight = $userScreen.height();
		width = Math.floor(($(win).width() / screenWidth) * 100);
		height = Math.floor(($(win).height() / screenHeight) * 100);
		innerHorizWidth = parseInt($inner.css('border-left-width'), 10) +
			parseInt($inner.css('border-right-width'), 10);
		innerVertWidth = parseInt($inner.css('border-top-width'), 10) +
			parseInt($inner.css('border-bottom-width'), 10);

		// update inner-window for borders
		$inner.width($win.width() - innerHorizWidth);
		$inner.height($win.height() - innerVertWidth);

		// update form
		$('#' + $win.attr('id') + '-width').val(width);
		$('#' + $win.attr('id') + '-height').val(height);

		if (typeof ui !== 'undefined') {
			left = Math.floor((ui.position.left / screenWidth) * 100);
			top = Math.floor((ui.position.top / screenHeight) * 100);
			$('#' + $win.attr('id') + '-left').val(left);
			$('#' + $win.attr('id') + '-top').val(top);
		}
	}

	function setup_windows() {
		var $windows = $('.window'),
			$userScreen = $('#screen'),
			screenWidth = $userScreen.width(),
			screenHeight = $userScreen.height();

		// Restore positions from options
		$('.window').each(function () {
			var $this = $(this);
			$this.width($('#' + $this.attr('id') + '-width').val() + "%");
			$this.height($('#' + $this.attr('id') + '-height').val() + "%");
			$this.css('left', $('#' + $this.attr('id') + '-left').val() + "%");
			$this.css('top', $('#' + $this.attr('id') + '-top').val() + "%");

			$this.draggable({
				containment: "parent",
				grid: [screenWidth / winGrid, screenHeight / winGrid]
			});

			$this.resizable({
				containment: "parent",
				handles: "all",
				grid: [screenWidth / winGrid, screenHeight / winGrid],
				minWidth: $this.parent().width() * 0.2,
				minHeight: $this.parent().height() * 0.2
			});

			$this.on('resize', function(event, ui) {
				update_window_size_and_position(this, ui);
				save_options();
			});

			$this.on('drag', function(event, ui) {
				update_window_size_and_position(this, ui);
				save_options();
			});
		});

	}

	jQuery(document).ready(function($) {
		resize_screen();
		restore_options();
		add_input_handlers();
		setup_windows();

		$('.window').trigger('resize');
		$('#extensions').click(open_extensions);
		$('#sub').click(save_options);
	});
}());<|endoftext|>