<commit_before><<<<<<< HEAD
const _ = require('sdk/l10n').get,
      clipboard = require('sdk/clipboard'),
      contextMenu = require('sdk/context-menu'),
      data = require('sdk/self').data,
      notify = require('./simple-notify').notify,
      prefs = require('sdk/simple-prefs').prefs,
      xhr = require('sdk/net/xhr'),
      tabs = require('sdk/tabs'),
      // Deprecated
      aboutconfig = require('sdk/preferences/service');

const { Hotkey } = require('sdk/hotkeys');

// about:config preferences, deprecated
const serviceurl_pref = 'extensions.copyshorturl.serviceURL';

// Service defaults.
const default_service = 'isgd',
      serviceurl_docs = 'http://copy-shorturl.readthedocs.org/en/latest/serviceurl.html';

// Specify 'url' for plain-text GET APIs, or request/result for more complex
// variants.
var serviceurls = {
  isgd: {
    url: 'http://is.gd/api.php?longurl=%URL%'
  },
  tinyurl: {
    url: 'http://tinyurl.com/api-create.php?url=%URL%'
  },
  googl: {
    // https://developers.google.com/url-shortener/v1/getting_started
    request: function(url) {
      let req = new xhr.XMLHttpRequest();
      req.open("POST", 'https://www.googleapis.com/urlshortener/v1/url', false);
      req.setRequestHeader('Content-Type', 'application/json');
      req.send(JSON.stringify({ longUrl: url }));
      return req;
    },
    result: function(req) {
      let shortened = JSON.parse(req.responseText);
      return shortened.id;
    }
  }
};
// Hook up pref button to service URL docs.
require('sdk/simple-prefs').on('serviceurl_docs', function() {
  require('sdk/tabs').open(serviceurl_docs);
});

/** Determine service URL */
function getShorteningService() {
  if (prefs.service === 'custom') {
    if (prefs.customurl) {
      return {
        url: prefs.customurl
      };
    } else {
      // Restore default.
      prefs.service = default_service;
    }
  }
  return serviceurls[prefs.service];
}

/** Create a short URL from is.gd, tinyurl, etc. */
function createShortUrl(url) {
    let req,
        service = getShorteningService();

    try {
      if (service.request) {
        req = service.request(url);
      } else {
        req = new xhr.XMLHttpRequest();
        let _uri = service.url.replace('%URL%', encodeURIComponent(url));
        req.open("GET", _uri, false);
        req.send(null);
      }
      if (req.status === 200) {
          let result = service.result ? service.result(req) : req.responseText.trim();
          notify(_('none_found_notice', url, result));
          return result;
      } else {
        throw new Error(_('shorten_error'));
      }
    } catch (e) {
      notify(e.message);
      return false;
    }
}

exports.main = function(options, callbacks) {
    /* Set URL from preference if set in old version of add-on. */
    if (aboutconfig.has(serviceurl_pref)) {
      prefs.service = 'custom';
      prefs.customurl = aboutconfig.get(serviceurl_pref);
      aboutconfig.reset(serviceurl_pref);
    }

    /* Add and hook up context menu */
    var item = contextMenu.Item({
        label: 'Copy ShortURL',
        contentScriptFile: data.url('js/find-short-url.js'),
        onMessage: function(found_url) {
            let url = found_url['url'];

            if (found_url['short']) {
                notify(_('found_notice', url));
            } else {
                url = createShortUrl(url);
            }

            if (url) clipboard.set(url);
        }
    });

    Hotkey({
        combo: "accel-shift-l",
        onPress: function() {
            let shortened = createShortUrl(tabs.activeTab.url);
            if (shortened) clipboard.set(shortened);
        }
    });
}
<commit_msg>Leftover gunk<commit_after>const _ = require('sdk/l10n').get,
      clipboard = require('sdk/clipboard'),
      contextMenu = require('sdk/context-menu'),
      data = require('sdk/self').data,
      notify = require('./simple-notify').notify,
      prefs = require('sdk/simple-prefs').prefs,
      xhr = require('sdk/net/xhr'),
      tabs = require('sdk/tabs'),
      // Deprecated
      aboutconfig = require('sdk/preferences/service');

const { Hotkey } = require('sdk/hotkeys');

// about:config preferences, deprecated
const serviceurl_pref = 'extensions.copyshorturl.serviceURL';

// Service defaults.
const default_service = 'isgd',
      serviceurl_docs = 'http://copy-shorturl.readthedocs.org/en/latest/serviceurl.html';

// Specify 'url' for plain-text GET APIs, or request/result for more complex
// variants.
var serviceurls = {
  isgd: {
    url: 'http://is.gd/api.php?longurl=%URL%'
  },
  tinyurl: {
    url: 'http://tinyurl.com/api-create.php?url=%URL%'
  },
  googl: {
    // https://developers.google.com/url-shortener/v1/getting_started
    request: function(url) {
      let req = new xhr.XMLHttpRequest();
      req.open("POST", 'https://www.googleapis.com/urlshortener/v1/url', false);
      req.setRequestHeader('Content-Type', 'application/json');
      req.send(JSON.stringify({ longUrl: url }));
      return req;
    },
    result: function(req) {
      let shortened = JSON.parse(req.responseText);
      return shortened.id;
    }
  }
};
// Hook up pref button to service URL docs.
require('sdk/simple-prefs').on('serviceurl_docs', function() {
  require('sdk/tabs').open(serviceurl_docs);
});

/** Determine service URL */
function getShorteningService() {
  if (prefs.service === 'custom') {
    if (prefs.customurl) {
      return {
        url: prefs.customurl
      };
    } else {
      // Restore default.
      prefs.service = default_service;
    }
  }
  return serviceurls[prefs.service];
}

/** Create a short URL from is.gd, tinyurl, etc. */
function createShortUrl(url) {
    let req,
        service = getShorteningService();

    try {
      if (service.request) {
        req = service.request(url);
      } else {
        req = new xhr.XMLHttpRequest();
        let _uri = service.url.replace('%URL%', encodeURIComponent(url));
        req.open("GET", _uri, false);
        req.send(null);
      }
      if (req.status === 200) {
          let result = service.result ? service.result(req) : req.responseText.trim();
          notify(_('none_found_notice', url, result));
          return result;
      } else {
        throw new Error(_('shorten_error'));
      }
    } catch (e) {
      notify(e.message);
      return false;
    }
}

exports.main = function(options, callbacks) {
    /* Set URL from preference if set in old version of add-on. */
    if (aboutconfig.has(serviceurl_pref)) {
      prefs.service = 'custom';
      prefs.customurl = aboutconfig.get(serviceurl_pref);
      aboutconfig.reset(serviceurl_pref);
    }

    /* Add and hook up context menu */
    var item = contextMenu.Item({
        label: 'Copy ShortURL',
        contentScriptFile: data.url('js/find-short-url.js'),
        onMessage: function(found_url) {
            let url = found_url['url'];

            if (found_url['short']) {
                notify(_('found_notice', url));
            } else {
                url = createShortUrl(url);
            }

            if (url) clipboard.set(url);
        }
    });

    Hotkey({
        combo: "accel-shift-l",
        onPress: function() {
            let shortened = createShortUrl(tabs.activeTab.url);
            if (shortened) clipboard.set(shortened);
        }
    });
}
<|endoftext|>


<commit_before>/*!
Copyright 2013 Hewlett-Packard Development Company, L.P.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

/**
 * Main package module.
 *
 * @module caf_ca/main
 *
 */

/* eslint-disable max-len */

/**
 * @external caf_session
 * @see {@link https://cafjs.github.io/api/caf_session/index.html}
 */

/**
 * @external caf_sharing
 * @see {@link https://cafjs.github.io/api/caf_sharing/index.html}
 */

/**
 * @external caf_ca
 * @see {@link https://cafjs.github.io/api/caf_ca/index.html}
 */

/* eslint-enable max-len */

module.exports = require('./Session');
<commit_msg>Fix jsdoc<commit_after>/*!
Copyright 2013 Hewlett-Packard Development Company, L.P.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

'use strict';

/**
 * Main package module.
 *
 * @module caf_cli/main
 *
 */

/* eslint-disable max-len */

/**
 * @external caf_session
 * @see {@link https://cafjs.github.io/api/caf_session/index.html}
 */

/**
 * @external caf_sharing
 * @see {@link https://cafjs.github.io/api/caf_sharing/index.html}
 */

/**
 * @external caf_ca
 * @see {@link https://cafjs.github.io/api/caf_ca/index.html}
 */

/* eslint-enable max-len */

module.exports = require('./Session');
<|endoftext|>


<commit_before>'use strict';

var bunyan        = require('bunyan');

var logger = bunyan.createLogger({
   name: "cloudlet-platform",
   src: true,
   streams: [
      {
         level: 'info',
         path: '/opt/openi/cloudlet_platform/logs/cloudletPlatformInfo.log'
      },
      {
         level: 'error',
         path: '/opt/openi/cloudlet_platform/logs/cloudletPlatformError.log'
      },
      {
         level: 'debug',
         path: '/opt/openi/cloudlet_platform/logs/cloudletPlatformDebug.log'
      }
   ]
});

module.exports = logger;<commit_msg>setting single log file<commit_after>'use strict';

var bunyan        = require('bunyan');

var logger = bunyan.createLogger({
   name: "cloudlet-platform",
   src: true,
   streams: [
      {
         level: 'info',
         path: '/opt/openi/cloudlet_platform/logs/cloudletPlatform.log'
      },
      {
         level: 'error',
         path: '/opt/openi/cloudlet_platform/logs/cloudletPlatform.log'
      },
      {
         level: 'debug',
         path: '/opt/openi/cloudlet_platform/logs/cloudletPlatform.log'
      }
   ]
});

module.exports = logger;<|endoftext|>


<commit_before>var obSvc = require('observer-service');
var data = require("self").data;
var {Ci, Cr} = require('chrome');

//var BASE_URL = "http://localhost:8001/";
var BASE_URL = "https://secure.toolness.com/collusion/";

require("page-mod").PageMod({
  include: [BASE_URL],
  contentScriptWhen: 'start',
  contentScriptFile: data.url("force-content-script.js"),
  onAttach: function(worker) {
    workers.push(worker);
    worker.on("detach", function() {
      workers.splice(workers.indexOf(worker), 1);
    });
    worker.port.emit("log", JSON.stringify(log));
  }
});

require("widget").Widget({
  id: "collusion",
  label: "Display Collusion Diagram",
  contentURL: data.url("favicon.ico"),
  onClick: function() {
    require("tabs").open({url: BASE_URL});
  }
});

var log = {};
var workers = [];

function queueInfo(info) {
  if (!(info.domain in log))
    log[info.domain] = {};

  var referrers = log[info.domain];

  if (!(info.referrer in referrers))
    referrers[info.referrer] = [];

  var types = referrers[info.referrer];

  if (types.indexOf(info.type) == -1) {
    types.push(info.type);
    workers.forEach(function(worker) {
      worker.port.emit("log", JSON.stringify(log));
    });
  }
}

function getDomain(host) {
  return host.split('.').slice(-2).join('.');
}

obSvc.add("http-on-examine-response", function(subject, topic, data) {
  var channel = subject.QueryInterface(Ci.nsIHttpChannel),
      type = null,
      cookie = null;

  if (channel.referrer) {
    var referrerDomain = getDomain(channel.referrer.host);
    var domain = getDomain(channel.URI.host);
    if (domain != referrerDomain) {
      try {
        type = subject.getResponseHeader("Content-Type");
      } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {}

      try {
        var cookie = subject.getRequestHeader("Cookie");
      } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {}

      if (!cookie) {
        try {
          cookie = subject.getResponseHeader("Set-Cookie");
        } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {}
      }

      if (cookie)
        queueInfo({
          type: type,
          domain: domain,
          referrer: referrerDomain
        });
    }
  }
});
<commit_msg>add timestamp information to log<commit_after>var obSvc = require('observer-service');
var data = require("self").data;
var {Ci, Cr} = require('chrome');

//var BASE_URL = "http://localhost:8001/";
var BASE_URL = "https://secure.toolness.com/collusion/";

require("page-mod").PageMod({
  include: [BASE_URL],
  contentScriptWhen: 'start',
  contentScriptFile: data.url("force-content-script.js"),
  onAttach: function(worker) {
    workers.push(worker);
    worker.on("detach", function() {
      workers.splice(workers.indexOf(worker), 1);
    });
    worker.port.emit("log", JSON.stringify(log));
  }
});

require("widget").Widget({
  id: "collusion",
  label: "Display Collusion Diagram",
  contentURL: data.url("favicon.ico"),
  onClick: function() {
    require("tabs").open({url: BASE_URL});
  }
});

var startTime = new Date();
var log = {};
var workers = [];

function queueInfo(info) {
  if (!(info.domain in log))
    log[info.domain] = {};

  var referrers = log[info.domain];

  if (!(info.referrer in referrers))
    referrers[info.referrer] = [(new Date()) - startTime];

  var types = referrers[info.referrer];

  if (types.indexOf(info.type) == -1) {
    types.push(info.type);
    workers.forEach(function(worker) {
      worker.port.emit("log", JSON.stringify(log));
    });
  }
}

function getDomain(host) {
  return host.split('.').slice(-2).join('.');
}

obSvc.add("http-on-examine-response", function(subject, topic, data) {
  var channel = subject.QueryInterface(Ci.nsIHttpChannel),
      type = null,
      cookie = null;

  if (channel.referrer) {
    var referrerDomain = getDomain(channel.referrer.host);
    var domain = getDomain(channel.URI.host);
    if (domain != referrerDomain) {
      try {
        type = subject.getResponseHeader("Content-Type");
      } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {}

      try {
        var cookie = subject.getRequestHeader("Cookie");
      } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {}

      if (!cookie) {
        try {
          cookie = subject.getResponseHeader("Set-Cookie");
        } catch (e if e.result == Cr.NS_ERROR_NOT_AVAILABLE) {}
      }

      if (cookie)
        queueInfo({
          type: type,
          domain: domain,
          referrer: referrerDomain
        });
    }
  }
});
<|endoftext|>


<commit_before>var buttons = require('sdk/ui/button/action');
var cm = require('sdk/context-menu');
var tabs = require('sdk/tabs');
var url = require('sdk/url');
var notifications = require('sdk/notifications');
var {Cc, Ci, Cu} = require('chrome');
Cu.import('resource://gre/modules/LoadContextInfo.jsm');
var cache_storage_service = Cc['@mozilla.org/network/cache-storage-service;1'].getService(Ci.nsICacheStorageService);

var icons = {
    '16': './icon-16.png',
    '32': './icon-32.png',
    '64': './icon-64.png'
};

var button = buttons.ActionButton({
    id: 'clear-cache',
    label: 'Initializing',
    icon: icons,
    disabled: true,
    onClick: clearCache
});

function updateButton () {
    var active_url = url.URL(tabs.activeTab.url);
    if (active_url.scheme === 'http' || active_url.scheme === 'https') {
        button.label = 'Clear cache for "' + active_url.host + '"';
        button.state('tab', {disabled: false});
    } else {
        button.label = 'Can\'t clear the cache for this type of site';
        button.state('tab', {disabled: true});
    }
}
updateButton(); // Set the initial state

tabs.on('activate', function (tab) {
    updateButton();
});

tabs.on('ready', function (tab) {
    if (tab.id === tabs.activeTab.id) {
        updateButton();
    }
});

var stats = {
    host: null,
    removed: null,
    total_size: null
};

var disk_visitor = {
    onCacheStorageInfo: function () {},

    onCacheEntryInfo: function (uri, _, size) {
        if (stats.host !== uri.host) {
            return;
        }

        stats.removed++;
        stats.total_size += size;
        cache_storage_service.diskCacheStorage(LoadContextInfo.default, false).asyncDoomURI(uri, null, null);
    },

    onCacheEntryVisitCompleted: function () {
        notifications.notify({
            title: 'Site cache cleared',
            iconURL: icons['64'],
            text: (0 + stats.removed) + ' entries removed (' + (0 + stats.total_size) + ' bytes)'
        });

        for (var key in stats) {
            stats[key] = null;
        }
    }
};

cm.Item({
    label: 'Clear Site Cache',
    context: cm.URLContext('*'),
    contentScript: 'self.on("click", self.postMessage);',
    onMessage: clearCache
});

function clearCache (state) {
    stats.host = url.URL(tabs.activeTab.url).host;
    cache_storage_service.diskCacheStorage(LoadContextInfo.default, false).asyncVisitStorage(disk_visitor, true);
}
<commit_msg>Add trailing commas to all arrays<commit_after>var buttons = require('sdk/ui/button/action');
var cm = require('sdk/context-menu');
var tabs = require('sdk/tabs');
var url = require('sdk/url');
var notifications = require('sdk/notifications');
var {Cc, Ci, Cu} = require('chrome');
Cu.import('resource://gre/modules/LoadContextInfo.jsm');
var cache_storage_service = Cc['@mozilla.org/network/cache-storage-service;1'].getService(Ci.nsICacheStorageService);

var icons = {
    '16': './icon-16.png',
    '32': './icon-32.png',
    '64': './icon-64.png',
};

var button = buttons.ActionButton({
    id: 'clear-cache',
    label: 'Initializing',
    icon: icons,
    disabled: true,
    onClick: clearCache,
});

function updateButton () {
    var active_url = url.URL(tabs.activeTab.url);
    if (active_url.scheme === 'http' || active_url.scheme === 'https') {
        button.label = 'Clear cache for "' + active_url.host + '"';
        button.state('tab', {disabled: false});
    } else {
        button.label = 'Can\'t clear the cache for this type of site';
        button.state('tab', {disabled: true});
    }
}
updateButton(); // Set the initial state

tabs.on('activate', function (tab) {
    updateButton();
});

tabs.on('ready', function (tab) {
    if (tab.id === tabs.activeTab.id) {
        updateButton();
    }
});

var stats = {
    host: null,
    removed: null,
    total_size: null,
};

var disk_visitor = {
    onCacheStorageInfo: function () {},

    onCacheEntryInfo: function (uri, _, size) {
        if (stats.host !== uri.host) {
            return;
        }

        stats.removed++;
        stats.total_size += size;
        cache_storage_service.diskCacheStorage(LoadContextInfo.default, false).asyncDoomURI(uri, null, null);
    },

    onCacheEntryVisitCompleted: function () {
        notifications.notify({
            title: 'Site cache cleared',
            iconURL: icons['64'],
            text: (0 + stats.removed) + ' entries removed (' + (0 + stats.total_size) + ' bytes)',
        });

        for (var key in stats) {
            stats[key] = null;
        }
    },
};

cm.Item({
    label: 'Clear Site Cache',
    context: cm.URLContext('*'),
    contentScript: 'self.on("click", self.postMessage);',
    onMessage: clearCache,
});

function clearCache (state) {
    stats.host = url.URL(tabs.activeTab.url).host;
    cache_storage_service.diskCacheStorage(LoadContextInfo.default, false).asyncVisitStorage(disk_visitor, true);
}
<|endoftext|>


<commit_before>'use babel';

/* @flow */

import { CompositeDisposable } from 'atom';
import Commands from './commands';
import EditorsRegistry from './editor-registry';
import TesterRegistry from './tester-registry';
import * as OutputViewManager from './output-view-manager';
/* flow-include
import type { Panel } from 'atom';
import type { State, Tester as TesterProvider } from './types'
*/
class Tester {
    /* ::
  state: any;
  commands: Commands;
  subscriptions: CompositeDisposable;
  modalPanel: Panel;
  registryTesters: TesterRegistry;
  registryEditors: EditorsRegistry;
  statusBarTile: Object;
  markers: Array<Object>;
  */

  constructor(state/* : State*/) {
    console.log('MAIN', state);
    this.state = state;
    this.commands = new Commands();
    this.registryEditors = new EditorsRegistry();
    this.registryTesters = new TesterRegistry();
    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(this.commands);
    this.subscriptions.add(this.registryEditors);
    this.subscriptions.add(this.registryTesters);
    this.markers = [];
    const self = this;

    this.subscriptions.add(atom.config.observe('tester.gutterEnabled', (gutterEnabled) => {
      this.registryEditors.gutterEnabled = gutterEnabled;
    }));

    this.commands.onShouldTest(() => {
      console.log('MAIN.onShouldTest', self.registryEditors);
      const editorTester = self.registryEditors.get(atom.workspace.getActiveTextEditor());
      console.log('MAIN.editorTester', editorTester);
      if (editorTester) {
        self.statusBarTile.testRunning();
        editorTester.test();
      }
    });

    this.commands.onShouldToggleActiveEditor(() => {
      const textEditor = atom.workspace.getActiveTextEditor();
      const editor = self.registryEditors.get(textEditor);
      if (editor) {
        editor.dispose();
      } else if (textEditor) {
        self.registryEditors.createFromTextEditor(textEditor);
      }
    });

    this.registryEditors.observe((editorTester) => {
      editorTester.onShouldTest((onChange) => {
        self.registryTesters.test(onChange, editorTester);
      });
    });

    this.registryTesters.onDidUpdateMessages(({ tester, editor, messages }) => {
      console.log('onDidUpdateMessages', { tester, editor, messages });
      self.statusBarTile.testResults(messages);
      const gutter = self.registryEditors.handleGutter(editor);
      if (!gutter) {
        return;
      }
      editor.getBuffer().getMarkers().forEach((marker) => {
        marker.destroy();
      });
      messages.forEach((message) => {
        const item = document.createElement('span');
        item.className = `tester-gutter tester-highlight ${message.state}`;
        // https://atom.io/docs/api/v1.14.4/TooltipManager#instance-add
        atom.tooltips.add(item, {
          title: JSON.stringify(message, null, 2),
          placement: 'right',
          delay: { show: 100, hide: 100 },
        });
        const marker = editor.getBuffer().markRange(message.range, { invalidate: 'inside' });
        gutter.decorateMarker(marker, {
          class: 'tester-row',
          item,
        });
      });
    });

    this.registryTesters.onDidBeginTesting(({ tester, editor, messages }) => {
      console.log('onDidBeginTesting', { tester, editor, messages });
      if (self.statusBarTile) {
        self.statusBarTile.testRunning();
      }
    });

    this.registryTesters.onDidFinishTesting(({ tester, editor, messages }) => {
      console.log('onDidFinishTesting', { tester, editor, messages });
      self.statusBarTile.testFinished();
    });

    this.registryEditors.activate();

    setTimeout(() => {
            // NOTE: Atom triggers this on boot so wait a while
      if (!self.subscriptions.disposed) {
        self.subscriptions.add(atom.project.onDidChangePaths(() => {
          self.registryEditors.handleGutter();
          self.commands.test();
        }));
      }
    }, 100);
  }

  createStatusBar(statusBar/* : Object*/) {
    const div = document.createElement('div');
    div.classList.add('inline-block');
    const passedTestsSpan = document.createElement('span');
    passedTestsSpan.textContent = '0';
    passedTestsSpan.className = 'tester-bottom-status tester-status-passed highlight';
    const failedTestsSpan = document.createElement('span');
    failedTestsSpan.textContent = '0';
    failedTestsSpan.className = 'tester-bottom-status tester-status-failed highlight';
    const skippedTestsSpan = document.createElement('span');
    skippedTestsSpan.textContent = '0';
    skippedTestsSpan.className = 'tester-bottom-status tester-status-skipped highlight';
    const statusTiny = document.createElement('span');
    statusTiny.textContent = '';
    statusTiny.className = 'tester-bottom-status tester-tiny loading loading-spinner-tiny highlight';
    statusTiny.style.display = 'none';
    const button = document.createElement('span');
    button.appendChild(failedTestsSpan);
    button.appendChild(passedTestsSpan);
    button.appendChild(skippedTestsSpan);
    button.appendChild(statusTiny);

    button.onclick = function linkOnClick(e) {
      OutputViewManager.getView().toggle();
      return console.log('Tester is here!', e);
    };

    atom.tooltips.add(div, {
      title: 'Toggle Tester Output Console',
    });

    div.appendChild(button);

    const statusBarTile = statusBar.addLeftTile({
      item: div,
      priority: 0,
    });

    statusBarTile.status = {};
    statusBarTile.status.passed = passedTestsSpan;
    statusBarTile.status.failed = failedTestsSpan;
    statusBarTile.status.skipped = skippedTestsSpan;
    statusBarTile.testRunning = function () {
      console.log('---> statusBarTile.testRunning', statusBarTile.status);
      statusTiny.style.display = 'inline-block';
    };
    statusBarTile.testFinished = function () {
      console.log('---> statusBarTile.testFinished', statusBarTile.status);
      statusTiny.style.display = 'none';
    };

    statusBarTile.testResults = function (results) {
      console.log('---> statusBarTile.testResults', statusBarTile.status, results);
      OutputViewManager.getView().setContent(JSON.stringify(results, null, 2));
      if (!results) {
        this.status.passed.textContent = '0';
        this.status.failed.textContent = '0';
        this.status.skipped.textContent = '0';
      } else {
        this.status.passed.textContent = results.filter(result => result.state === 'passed').length;
        this.status.failed.textContent = results.filter(result => result.state === 'failed').length;
        this.status.skipped.textContent = results.filter(result => result.state === 'skipped').length;
      }
    };
    this.statusBarTile = statusBarTile;
  }

  dispose() {
    this.subscriptions.dispose();
  }

  addTester(tester/* : TesterProvider*/) {
    this.registryTesters.addTester(tester);
  }

  deleteTester(tester/* : TesterProvider*/) {
    this.registryTesters.deleteTester(tester);
  }
}

module.exports = Tester;
<commit_msg>location change<commit_after>'use babel';

/* @flow */

import { CompositeDisposable } from 'atom';
import Commands from './commands';
import EditorsRegistry from './editor-registry';
import TesterRegistry from './tester-registry';
import * as OutputViewManager from './output-view-manager';
/* flow-include
import type { Panel } from 'atom';
import type { State, Tester as TesterProvider } from './types'
*/
class Tester {
    /* ::
  state: any;
  commands: Commands;
  subscriptions: CompositeDisposable;
  modalPanel: Panel;
  registryTesters: TesterRegistry;
  registryEditors: EditorsRegistry;
  statusBarTile: Object;
  markers: Array<Object>;
  */

  constructor(state/* : State*/) {
    console.log('MAIN', state);
    this.state = state;
    this.commands = new Commands();
    this.registryEditors = new EditorsRegistry();
    this.registryTesters = new TesterRegistry();
    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(this.commands);
    this.subscriptions.add(this.registryEditors);
    this.subscriptions.add(this.registryTesters);
    this.markers = [];
    const self = this;

    this.subscriptions.add(atom.config.observe('tester.gutterEnabled', (gutterEnabled) => {
      this.registryEditors.gutterEnabled = gutterEnabled;
    }));

    this.commands.onShouldTest(() => {
      console.log('MAIN.onShouldTest', self.registryEditors);
      const editorTester = self.registryEditors.get(atom.workspace.getActiveTextEditor());
      console.log('MAIN.editorTester', editorTester);
      if (editorTester) {
        self.statusBarTile.testRunning();
        editorTester.test();
      }
    });

    this.commands.onShouldToggleActiveEditor(() => {
      const textEditor = atom.workspace.getActiveTextEditor();
      const editor = self.registryEditors.get(textEditor);
      if (editor) {
        editor.dispose();
      } else if (textEditor) {
        self.registryEditors.createFromTextEditor(textEditor);
      }
    });

    this.registryEditors.observe((editorTester) => {
      editorTester.onShouldTest((onChange) => {
        self.registryTesters.test(onChange, editorTester);
      });
    });

    this.registryTesters.onDidUpdateMessages(({ tester, editor, messages }) => {
      console.log('onDidUpdateMessages', { tester, editor, messages });
      self.statusBarTile.testResults(messages);
      const gutter = self.registryEditors.handleGutter(editor);
      if (!gutter) {
        return;
      }
      editor.getBuffer().getMarkers().forEach((marker) => {
        marker.destroy();
      });
      messages.forEach((message) => {
        const item = document.createElement('span');
        item.className = `tester-gutter tester-highlight ${message.state}`;
        // https://atom.io/docs/api/v1.14.4/TooltipManager#instance-add
        atom.tooltips.add(item, {
          title: JSON.stringify(message, null, 2),
          placement: 'right',
          delay: { show: 100, hide: 100 },
        });
        const marker = editor.getBuffer().markRange(message.range, { invalidate: 'inside' });
        gutter.decorateMarker(marker, {
          class: 'tester-row',
          item,
        });
      });
    });

    this.registryTesters.onDidBeginTesting(({ tester, editor, messages }) => {
      console.log('onDidBeginTesting', { tester, editor, messages });
      if (self.statusBarTile) {
        self.statusBarTile.testRunning();
      }
    });

    this.registryTesters.onDidFinishTesting(({ tester, editor, messages }) => {
      console.log('onDidFinishTesting', { tester, editor, messages });
      self.statusBarTile.testFinished();
    });

    this.registryEditors.activate();

    setTimeout(() => {
            // NOTE: Atom triggers this on boot so wait a while
      if (!self.subscriptions.disposed) {
        self.subscriptions.add(atom.project.onDidChangePaths(() => {
          self.registryEditors.handleGutter();
          self.commands.test();
        }));
      }
    }, 100);
  }

  createStatusBar(statusBar/* : Object*/) {
    const div = document.createElement('div');
    div.classList.add('inline-block');
    const passedTestsSpan = document.createElement('span');
    passedTestsSpan.textContent = '0';
    passedTestsSpan.className = 'tester-bottom-status tester-status-passed highlight';
    const failedTestsSpan = document.createElement('span');
    failedTestsSpan.textContent = '0';
    failedTestsSpan.className = 'tester-bottom-status tester-status-failed highlight';
    const skippedTestsSpan = document.createElement('span');
    skippedTestsSpan.textContent = '0';
    skippedTestsSpan.className = 'tester-bottom-status tester-status-skipped highlight';
    const statusTiny = document.createElement('span');
    statusTiny.textContent = '';
    statusTiny.className = 'tester-bottom-status tester-tiny loading loading-spinner-tiny highlight';
    statusTiny.style.display = 'none';
    const button = document.createElement('span');
    button.appendChild(failedTestsSpan);
    button.appendChild(skippedTestsSpan);
    button.appendChild(passedTestsSpan);
    button.appendChild(statusTiny);

    button.onclick = function linkOnClick(e) {
      OutputViewManager.getView().toggle();
      return console.log('Tester is here!', e);
    };

    atom.tooltips.add(div, {
      title: 'Toggle Tester Output Console',
    });

    div.appendChild(button);

    const statusBarTile = statusBar.addLeftTile({
      item: div,
      priority: 0,
    });

    statusBarTile.status = {};
    statusBarTile.status.passed = passedTestsSpan;
    statusBarTile.status.failed = failedTestsSpan;
    statusBarTile.status.skipped = skippedTestsSpan;
    statusBarTile.testRunning = function () {
      console.log('---> statusBarTile.testRunning', statusBarTile.status);
      statusTiny.style.display = 'inline-block';
    };
    statusBarTile.testFinished = function () {
      console.log('---> statusBarTile.testFinished', statusBarTile.status);
      statusTiny.style.display = 'none';
    };

    statusBarTile.testResults = function (results) {
      console.log('---> statusBarTile.testResults', statusBarTile.status, results);
      OutputViewManager.getView().setContent(JSON.stringify(results, null, 2));
      if (!results) {
        this.status.passed.textContent = '0';
        this.status.failed.textContent = '0';
        this.status.skipped.textContent = '0';
      } else {
        this.status.passed.textContent = results.filter(result => result.state === 'passed').length;
        this.status.failed.textContent = results.filter(result => result.state === 'failed').length;
        this.status.skipped.textContent = results.filter(result => result.state === 'skipped').length;
      }
    };
    this.statusBarTile = statusBarTile;
  }

  dispose() {
    this.subscriptions.dispose();
  }

  addTester(tester/* : TesterProvider*/) {
    this.registryTesters.addTester(tester);
  }

  deleteTester(tester/* : TesterProvider*/) {
    this.registryTesters.deleteTester(tester);
  }
}

module.exports = Tester;
<|endoftext|>


<commit_before>'use babel';

// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions
import { CompositeDisposable } from 'atom';
import * as helpers from 'atom-linter';
import { dirname } from 'path';

// Local variables
const parseRegex = /^(?:Parse|Fatal) error:\s+(.+) in .+?(?: on line |:)(\d+)/gm;
const phpCheckCache = new Map();

// Settings
let executablePath;
let errorReporting;

const testBin = async () => {
  if (phpCheckCache.has(executablePath)) {
    return;
  }
  const title = 'linter-php: Unable to determine PHP version';
  const message = `Unable to determine the version of "${executablePath}` +
    '", please verify that this is the right path to PHP. If you believe you ' +
    'have fixed this problem please restart Atom.';

  let output;
  try {
    output = await helpers.exec(executablePath, ['-v']);
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
    phpCheckCache.set(executablePath, false);
    atom.notifications.addError(title, { detail: message });
  }

  const regex = /PHP (\d+)\.(\d+)\.(\d+)/g;
  if (!regex.exec(output)) {
    phpCheckCache.set(executablePath, false);
    atom.notifications.addError(title, { detail: message });
  }
  phpCheckCache.set(executablePath, true);
};

export default {
  activate() {
    require('atom-package-deps').install('linter-php');

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(
      atom.config.observe('linter-php.executablePath', (value) => {
        executablePath = value;
        testBin();
      }),
    );
    this.subscriptions.add(
      atom.config.observe('linter-php.errorReporting', (value) => {
        errorReporting = value;
      }),
    );
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  provideLinter() {
    return {
      name: 'PHP',
      grammarScopes: ['text.html.php', 'source.php'],
      scope: 'file',
      lintOnFly: true,
      lint: async (textEditor) => {
        if (!phpCheckCache.has(executablePath)) {
          await testBin();
        }
        if (!phpCheckCache.get(executablePath)) {
          // We don't have a valid PHP version, don't update messages
          return null;
        }

        const filePath = textEditor.getPath();
        const fileText = textEditor.getText();

        const parameters = [
          '--syntax-check',
          '--define', 'display_errors=On',
          '--define', 'log_errors=Off',
        ];
        if (errorReporting) {
          parameters.push('--define', 'error_reporting=E_ALL');
        }

        const execOptions = {
          stdin: fileText,
          ignoreExitCode: true,
        };

        if (filePath !== null) {
          // Only specify a CWD if the file has been saved
          const [projectPath] = atom.project.relativizePath(filePath);
          execOptions.cwd = projectPath !== null ? projectPath : dirname(filePath);
        }

        const output = await helpers.exec(executablePath, parameters, execOptions);

        if (textEditor.getText() !== fileText) {
          // Editor contents have changed, don't update messages
          return null;
        }

        const messages = [];
        let match = parseRegex.exec(output);
        while (match !== null) {
          const line = Number.parseInt(match[2], 10) - 1;
          messages.push({
            type: 'Error',
            filePath,
            range: helpers.generateRange(textEditor, line),
            text: match[1],
          });
          match = parseRegex.exec(output);
        }
        return messages;
      },
    };
  },
};
<commit_msg>Remove check for PHP version<commit_after>'use babel';

// eslint-disable-next-line import/no-extraneous-dependencies, import/extensions
import { CompositeDisposable } from 'atom';
import * as helpers from 'atom-linter';
import { dirname } from 'path';

// Local variables
const parseRegex = /^(?:Parse|Fatal) error:\s+(.+) in .+?(?: on line |:)(\d+)/gm;

// Settings
let executablePath;
let errorReporting;

export default {
  activate() {
    require('atom-package-deps').install('linter-php');

    this.subscriptions = new CompositeDisposable();
    this.subscriptions.add(
      atom.config.observe('linter-php.executablePath', (value) => {
        executablePath = value;
      }),
    );
    this.subscriptions.add(
      atom.config.observe('linter-php.errorReporting', (value) => {
        errorReporting = value;
      }),
    );
  },

  deactivate() {
    this.subscriptions.dispose();
  },

  provideLinter() {
    return {
      name: 'PHP',
      grammarScopes: ['text.html.php', 'source.php'],
      scope: 'file',
      lintOnFly: true,
      lint: async (textEditor) => {
        const filePath = textEditor.getPath();
        const fileText = textEditor.getText();

        const parameters = [
          '--syntax-check',
          '--define', 'display_errors=On',
          '--define', 'log_errors=Off',
        ];
        if (errorReporting) {
          parameters.push('--define', 'error_reporting=E_ALL');
        }

        const execOptions = {
          stdin: fileText,
          ignoreExitCode: true,
        };

        if (filePath !== null) {
          // Only specify a CWD if the file has been saved
          const [projectPath] = atom.project.relativizePath(filePath);
          execOptions.cwd = projectPath !== null ? projectPath : dirname(filePath);
        }

        const output = await helpers.exec(executablePath, parameters, execOptions);

        if (textEditor.getText() !== fileText) {
          // Editor contents have changed, don't update messages
          return null;
        }

        const messages = [];
        let match = parseRegex.exec(output);
        while (match !== null) {
          const line = Number.parseInt(match[2], 10) - 1;
          messages.push({
            type: 'Error',
            filePath,
            range: helpers.generateRange(textEditor, line),
            text: match[1],
          });
          match = parseRegex.exec(output);
        }
        return messages;
      },
    };
  },
};
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

"use strict";

const { Cu, Ci } = require("chrome");
const { prefs } = require("sdk/simple-prefs");
const { EventTarget } = require("sdk/event/target");
const { emit } = require("sdk/event/core");

// Export global event-target before all Firebug modules are loaded.
// This way modules can wait for 'initialize' event and get also
// access to the 'Firebug' singleton object as soon as possible.
const { target } = require("./target.js");
exports.target = target;

// Load Firebug modules now!
const { Firebug } = require("./firebug.js");
const { Trace, TraceError } = require("./core/trace.js").get(module.id);
const { start } = require("./debug/startup.js");

/**
 * Entry point of the extension. Both 'main' and 'onUnload' methods are
 * exported from this module and executed automatically by Add-ons SDK.
 */
function main(options, callbacks) {
  Trace.sysout("main;", options);

  // Initialize Firebug, the main application object (a singleton).
  // There is one Firebug instance shared across all browser windows.
  Firebug.initialize(options);

  // Fire an event, so other modules might initialize as well.
  emit(target, "initialize", Firebug);

  // Run custom start up sequence (e.g. open the toolbox automatically)
  // Use for debugging purposes only.
  if (prefs["debugStartup"]) {
    start();
  }
}

function onUnload(reason) {
  Trace.sysout("main.onUnload; " + reason);

  // Fire an event, so other modules might execute destroy sequences too.
  emit(target, "shutdown", reason, Firebug);

  Firebug.shutdown(reason);
}

// Exports from this module
exports.main = main;
exports.onUnload = onUnload;
exports.Firebug = Firebug;
<commit_msg>Open the toolbox after Firebug installation<commit_after>/* See license.txt for terms of usage */

"use strict";

const { Cu, Ci } = require("chrome");
const { prefs } = require("sdk/simple-prefs");
const { EventTarget } = require("sdk/event/target");
const { emit } = require("sdk/event/core");
const { openToolbox } = require("dev/utils");

// Export global event-target before all Firebug modules are loaded.
// This way modules can wait for 'initialize' event and get also
// access to the 'Firebug' singleton object as soon as possible.
const { target } = require("./target.js");
exports.target = target;

// Load Firebug modules now!
const { Firebug } = require("./firebug.js");
const { Trace, TraceError } = require("./core/trace.js").get(module.id);
const { start } = require("./debug/startup.js");

const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});

/**
 * Entry point of the extension. Both 'main' and 'onUnload' methods are
 * exported from this module and executed automatically by Add-ons SDK.
 */
function main(options, callbacks) {
  Trace.sysout("main;", options);

  // Initialize Firebug, the main application object (a singleton).
  // There is one Firebug instance shared across all browser windows.
  Firebug.initialize(options);

  // Fire an event, so other modules might initialize as well.
  emit(target, "initialize", Firebug);

  // Run custom start up sequence (e.g. open the toolbox automatically)
  // Use for debugging purposes only.
  if (prefs["debugStartup"]) {
    start();
  }

  // Open Firebug by default after installation.
  let reason = options.loadReason;
  if (reason == "install" || reason == "enable") {
    let toolId = Services.prefs.getCharPref("devtools.toolbox.selectedTool");
    // Workaround for https://github.com/mozilla/addon-sdk/pull/1688
    openToolbox({prototype: {}, id: toolId});
  }
}

function onUnload(reason) {
  Trace.sysout("main.onUnload; " + reason);

  // Fire an event, so other modules might execute destroy sequences too.
  emit(target, "shutdown", reason, Firebug);

  Firebug.shutdown(reason);
}

// Exports from this module
exports.main = main;
exports.onUnload = onUnload;
exports.Firebug = Firebug;
<|endoftext|>


<commit_before>const fb_events = require('./fb_events.js');
const smileys_events = require('./smileys_events.js');
const radioroom_events = require('./radioroom_events.js');
const currentEvents2Json = require('./currentEvents2Json.js');
const clog = console.log;
const mongodb = require('mongodb');
const fs = require('fs');
const getMLabKey = require('./getMLabKey');

let _events = [];

const venueList = [
    'gottrocks',
    'groundzero',
    'ipa',
    'radioroom',
    'villive',
    'iongreenville',
    'smileys'
];

const _smileysData = function() {
    return smileys_events(); //.then(x => {console.log(x.items.length)});
};

const _facebookData = function() {
    return fb_events();
};

const _radioroomData = function() {
    return radioroom_events();
};

Promise.all(
    [
        _facebookData(),
        _smileysData(),
        _radioroomData()
    ])
    .then(arr => {
        // --
        // use Array Spread syntax to concat arr array;
        // --
        // currentEvents2Json(_events.concat(...arr));
        return _events.concat(...arr);
    })
    .then(events => {
        clog('LOG:\tFound ' + events.length + ' events.')

        getMLabKey()
        .then(uri => {
            mongodb.MongoClient.connect(uri, function(err, db){
                if (err) throw err;
                clog('LOG:\tConnection to ALLEVENTS mlab opened')
                let colArr = ['events'];

                events.forEach(el => {
                    colArr.push(el.collection);
                    let allEvents = db.collection('events');
                    allEvents.update(
                        {
                            title: el.title,
                            date: el.date
                        },
                        {
                            collection: el.collection,
                            venue: el.venue,
                            venueUrl: el.venueUrl,
                            title: el.title,
                            description: el.description,
                            url: el.url,
                            time: el.time,
                            date: el.date,
                            datetime: el.datetime
                        },
                        {
                            upsert: true
                        }
                    )
                })

                db.close(function (err) {
                    if(err) throw err;
                    clog('LOG:\tMongo Collections: ' + [ ...new Set(colArr) ].toString());
                    clog('LOG:\tConnection to ALLEVENTS mlab closed')
                });
            })
        })
    }
);
<commit_msg>make lib/main.js executable<commit_after>#!/usr/bin/env node

const fb_events = require('./fb_events.js');
const smileys_events = require('./smileys_events.js');
const radioroom_events = require('./radioroom_events.js');
const currentEvents2Json = require('./currentEvents2Json.js');
const clog = console.log;
const mongodb = require('mongodb');
const fs = require('fs');
const getMLabKey = require('./getMLabKey');

let _events = [];

const venueList = [
    'gottrocks',
    'groundzero',
    'ipa',
    'radioroom',
    'villive',
    'iongreenville',
    'smileys'
];

const _smileysData = function() {
    return smileys_events(); //.then(x => {console.log(x.items.length)});
};

const _facebookData = function() {
    return fb_events();
};

const _radioroomData = function() {
    return radioroom_events();
};

Promise.all(
    [
        _facebookData(),
        _smileysData(),
        _radioroomData()
    ])
    .then(arr => {
        // --
        // use Array Spread syntax to concat arr array;
        // --
        // currentEvents2Json(_events.concat(...arr));
        return _events.concat(...arr);
    })
    .then(events => {
        clog('LOG:\tFound ' + events.length + ' events.')

        getMLabKey()
        .then(uri => {
            mongodb.MongoClient.connect(uri, function(err, db){
                if (err) throw err;
                clog('LOG:\tConnection to ALLEVENTS mlab opened')
                let colArr = ['events'];

                events.forEach(el => {
                    colArr.push(el.collection);
                    let allEvents = db.collection('events');
                    allEvents.update(
                        {
                            title: el.title,
                            date: el.date
                        },
                        {
                            collection: el.collection,
                            venue: el.venue,
                            venueUrl: el.venueUrl,
                            title: el.title,
                            description: el.description,
                            url: el.url,
                            time: el.time,
                            date: el.date,
                            datetime: el.datetime
                        },
                        {
                            upsert: true
                        }
                    )
                })

                db.close(function (err) {
                    if(err) throw err;
                    clog('LOG:\tMongo Collections: ' + [ ...new Set(colArr) ].toString());
                    clog('LOG:\tConnection to ALLEVENTS mlab closed')
                });
            })
        })
    }
);
<|endoftext|>


<commit_before>/*jslint browser: true, unparam: true, todo: true, evil: true*/
/*globals Reflect: false, HTMLElement: true, define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/
'use strict';

import component from './component';
import defaults from './defaults';
import draw from './draw';
import events from './events';
import touch from './touch';
import intf from './intf';
import contextMenu from './contextMenu';
import dom from './dom';
import publicMethods from './publicMethods';

var webComponent = component();

var modules = [
  defaults,
  draw,
  events,
  touch,
  intf,
  contextMenu,
  dom,
  publicMethods,
];

function Grid(args) {
  args = args || {};
  var self = {};
  self.isComponent = args.component === undefined;
  self.isChildGrid =
    args.parentNode &&
    /canvas-datagrid-(cell|tree)/.test(args.parentNode.nodeType);
  if (self.isChildGrid) {
    self.intf = {};
  } else {
    self.intf = self.isComponent
      ? eval('Reflect.construct(HTMLElement, [], new.target)')
      : document.createElement('canvas');
  }
  self.args = args;
  self.intf.args = args;
  self.applyComponentStyle = webComponent.applyComponentStyle;
  self.hyphenateProperty = webComponent.hyphenateProperty;
  self.dehyphenateProperty = webComponent.dehyphenateProperty;
  self.createGrid = function grid(args) {
    args.component = false;
    return new Grid(args);
  };

  modules.forEach(function (module) {
    module(self);
  });

  if (self.isChildGrid) {
    self.shadowRoot = args.parentNode.shadowRoot;
    self.parentNode = args.parentNode;
  } else {
    self.shadowRoot = self.intf.attachShadow({ mode: 'open' });
    self.parentNode = self.shadowRoot;
  }
  self.init();
  return self.intf;
}
if (window.HTMLElement) {
  Grid.prototype = Object.create(window.HTMLElement.prototype);
}
// export web component
if (window.customElements) {
  Grid.observedAttributes = webComponent.getObservableAttributes();
  Grid.prototype.disconnectedCallback = webComponent.disconnectedCallback;
  Grid.prototype.attributeChangedCallback =
    webComponent.attributeChangedCallback;
  Grid.prototype.connectedCallback = webComponent.connectedCallback;
  Grid.prototype.adoptedCallback = webComponent.adoptedCallback;
  window.customElements.define('canvas-datagrid', Grid);
}

// export global
if (
  window &&
  !window.canvasDatagrid &&
  !window.require &&
  // Present to exclude global declarations from ES Module bundles
  !window.EXCLUDE_GLOBAL
) {
  window.canvasDatagrid = function (args) {
    return new Grid(args);
  };
}

// export amd loader
export default function canvasDatagrid(args) {
  args = args || {};
  var i,
    tKeys = [
      'style',
      'formatters',
      'sorters',
      'filters',
      'treeGridAttributes',
      'cellGridAttributes',
      'data',
      'schema',
    ];
  if (window.customElements) {
    i = document.createElement('canvas-datagrid');
    Object.keys(args).forEach(function (argKey) {
      // set data and parentNode after everything else
      if (argKey === 'data') {
        return;
      }
      if (argKey === 'parentNode') {
        return;
      }
      // top level keys in args
      if (tKeys.indexOf(argKey) !== -1) {
        tKeys.forEach(function (tKey) {
          if (args[tKey] === undefined || tKey !== argKey) {
            return;
          }
          if (['formatters', 'sorters', 'filters'].indexOf(argKey) !== -1) {
            if (typeof args[tKey] === 'object' && args[tKey] !== null) {
              Object.keys(args[tKey]).forEach(function (sKey) {
                i[tKey][sKey] = args[tKey][sKey];
              });
            }
          } else {
            i[tKey] = args[tKey];
          }
        });
        return;
      }
      // all others are attribute level keys
      i.attributes[argKey] = args[argKey];
    });
    if (args.data) {
      i.data = args.data;
    }
    // add to the dom very last to avoid redraws
    if (args.parentNode) {
      args.parentNode.appendChild(i);
    }
    return i;
  }
  args.component = false;
  i = new Grid(args);
  if (args.parentNode && args.parentNode.appendChild) {
    args.parentNode.appendChild(i);
  }
  return i;
}
<commit_msg>Remove eval (fixes #311)<commit_after>/*jslint browser: true, unparam: true, todo: true, evil: true*/
/*globals Reflect: false, HTMLElement: true, define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/
'use strict';

import component from './component';
import defaults from './defaults';
import draw from './draw';
import events from './events';
import touch from './touch';
import intf from './intf';
import contextMenu from './contextMenu';
import dom from './dom';
import publicMethods from './publicMethods';

var webComponent = component();

var modules = [
  defaults,
  draw,
  events,
  touch,
  intf,
  contextMenu,
  dom,
  publicMethods,
];

function Grid(args) {
  args = args || {};
  var self = {};
  self.isComponent = args.component === undefined;
  self.isChildGrid =
    args.parentNode &&
    /canvas-datagrid-(cell|tree)/.test(args.parentNode.nodeType);
  if (self.isChildGrid) {
    self.intf = {};
  } else {
    self.intf = self.isComponent
      ? Reflect.construct(HTMLElement, [], new.target)
      : document.createElement('canvas');
  }
  self.args = args;
  self.intf.args = args;
  self.applyComponentStyle = webComponent.applyComponentStyle;
  self.hyphenateProperty = webComponent.hyphenateProperty;
  self.dehyphenateProperty = webComponent.dehyphenateProperty;
  self.createGrid = function grid(args) {
    args.component = false;
    return new Grid(args);
  };

  modules.forEach(function (module) {
    module(self);
  });

  if (self.isChildGrid) {
    self.shadowRoot = args.parentNode.shadowRoot;
    self.parentNode = args.parentNode;
  } else {
    self.shadowRoot = self.intf.attachShadow({ mode: 'open' });
    self.parentNode = self.shadowRoot;
  }
  self.init();
  return self.intf;
}
if (window.HTMLElement) {
  Grid.prototype = Object.create(window.HTMLElement.prototype);
}
// export web component
if (window.customElements) {
  Grid.observedAttributes = webComponent.getObservableAttributes();
  Grid.prototype.disconnectedCallback = webComponent.disconnectedCallback;
  Grid.prototype.attributeChangedCallback =
    webComponent.attributeChangedCallback;
  Grid.prototype.connectedCallback = webComponent.connectedCallback;
  Grid.prototype.adoptedCallback = webComponent.adoptedCallback;
  window.customElements.define('canvas-datagrid', Grid);
}

// export global
if (
  window &&
  !window.canvasDatagrid &&
  !window.require &&
  // Present to exclude global declarations from ES Module bundles
  !window.EXCLUDE_GLOBAL
) {
  window.canvasDatagrid = function (args) {
    return new Grid(args);
  };
}

// export amd loader
export default function canvasDatagrid(args) {
  args = args || {};
  var i,
    tKeys = [
      'style',
      'formatters',
      'sorters',
      'filters',
      'treeGridAttributes',
      'cellGridAttributes',
      'data',
      'schema',
    ];
  if (window.customElements) {
    i = document.createElement('canvas-datagrid');
    Object.keys(args).forEach(function (argKey) {
      // set data and parentNode after everything else
      if (argKey === 'data') {
        return;
      }
      if (argKey === 'parentNode') {
        return;
      }
      // top level keys in args
      if (tKeys.indexOf(argKey) !== -1) {
        tKeys.forEach(function (tKey) {
          if (args[tKey] === undefined || tKey !== argKey) {
            return;
          }
          if (['formatters', 'sorters', 'filters'].indexOf(argKey) !== -1) {
            if (typeof args[tKey] === 'object' && args[tKey] !== null) {
              Object.keys(args[tKey]).forEach(function (sKey) {
                i[tKey][sKey] = args[tKey][sKey];
              });
            }
          } else {
            i[tKey] = args[tKey];
          }
        });
        return;
      }
      // all others are attribute level keys
      i.attributes[argKey] = args[argKey];
    });
    if (args.data) {
      i.data = args.data;
    }
    // add to the dom very last to avoid redraws
    if (args.parentNode) {
      args.parentNode.appendChild(i);
    }
    return i;
  }
  args.component = false;
  i = new Grid(args);
  if (args.parentNode && args.parentNode.appendChild) {
    args.parentNode.appendChild(i);
  }
  return i;
}
<|endoftext|>


<commit_before>App.Router = Ember.Router.extend({
  location: 'hash',
  enableLogging: true,

  root: Em.Route.extend({
    contacts: Em.Route.extend({
      route: '/',

      showContact: function(router, event) {
        router.transitionTo('contacts.contact.index', event.context);
      },

      showNewContact: function(router) {
        router.transitionTo('contacts.newContact', {});
      },

      index: Em.Route.extend({
        route: '/',

        connectOutlets: function(router) {
          router.get('applicationController').connectOutlet('contacts', router.get('store').findAll(App.Contact));
        }
      }),

      newContact: Em.Route.extend({
        route: '/contacts/new',

        cancelEdit: function(router) {
          router.transitionTo('contacts.index');
        },

        connectOutlets: function(router) {
          router.get('contactsController').connectOutlet('editContact', {});
          router.get('editContactController').enterEditing();
        },

        exit: function(router) {
          router.get('editContactController').exitEditing();
        }
      }),

      contact: Em.Route.extend({
        route: '/contacts/:contact_id',

        connectOutlets: function(router, context) {
          router.get('contactsController').connectOutlet('contact', context);
        },

        index: Em.Route.extend({
          route: '/',

          showEdit: function(router) {
            router.transitionTo('contacts.contact.edit');
          },

          connectOutlets: function(router, context) {
            router.get('contactController').connectOutlet('showContact');
          }
        }),

        edit: Em.Route.extend({
          route: 'edit',

          cancelEdit: function(router) {
            router.transitionTo('contacts.contact.index');
          },

          connectOutlets: function(router) {
            var contactController = router.get('contactController');
            contactController.connectOutlet('editContact', contactController.get('content'));
            router.get('editContactController').enterEditing();
          },

          exit: function(router) {
            router.get('editContactController').exitEditing();
          }
        })
      })
    })
  })
});<commit_msg>remove router logging (committed by mistake)<commit_after>App.Router = Ember.Router.extend({
  location: 'hash',

  root: Em.Route.extend({
    contacts: Em.Route.extend({
      route: '/',

      showContact: function(router, event) {
        router.transitionTo('contacts.contact.index', event.context);
      },

      showNewContact: function(router) {
        router.transitionTo('contacts.newContact', {});
      },

      index: Em.Route.extend({
        route: '/',

        connectOutlets: function(router) {
          router.get('applicationController').connectOutlet('contacts', router.get('store').findAll(App.Contact));
        }
      }),

      newContact: Em.Route.extend({
        route: '/contacts/new',

        cancelEdit: function(router) {
          router.transitionTo('contacts.index');
        },

        connectOutlets: function(router) {
          router.get('contactsController').connectOutlet('editContact', {});
          router.get('editContactController').enterEditing();
        },

        exit: function(router) {
          router.get('editContactController').exitEditing();
        }
      }),

      contact: Em.Route.extend({
        route: '/contacts/:contact_id',

        connectOutlets: function(router, context) {
          router.get('contactsController').connectOutlet('contact', context);
        },

        index: Em.Route.extend({
          route: '/',

          showEdit: function(router) {
            router.transitionTo('contacts.contact.edit');
          },

          connectOutlets: function(router, context) {
            router.get('contactController').connectOutlet('showContact');
          }
        }),

        edit: Em.Route.extend({
          route: 'edit',

          cancelEdit: function(router) {
            router.transitionTo('contacts.contact.index');
          },

          connectOutlets: function(router) {
            var contactController = router.get('contactController');
            contactController.connectOutlet('editContact', contactController.get('content'));
            router.get('editContactController').enterEditing();
          },

          exit: function(router) {
            router.get('editContactController').exitEditing();
          }
        })
      })
    })
  })
});<|endoftext|>


<commit_before>"use strict";

var self = require("sdk/self");
var tabs = require("sdk/tabs");
var ffStorage = require("sdk/simple-storage");
var timers = require("sdk/timers");
var panelSdk = require("sdk/panel");
var options = require("sdk/simple-prefs");
var notifications = require("sdk/notifications");
var _ = require("sdk/l10n").get;
var events = require("sdk/system/events");
var { Ci } = require("chrome");
var feedlyApi = require("./feedly.api");
var userstyles = require("./userstyles");
var system = require("sdk/system");

var appGlobal = {
    feedlyApiClient: feedlyApi.getClient(),
    feedlyUrl: "feedly.com",
    feedlyTab: null,
    icons: {
        default: "images/icon20.png",
        inactive: "images/icon20_inactive.png"
    },
    options: {
        _updateInterval: 1,
        _maxNumberOfFeeds: 20,

        markReadOnClick: true,
        showDesktopNotifications: true,
        showFullFeedContent: false,
        openSiteOnIconClick: false,

        get maxNumberOfFeeds() {
            return this._maxNumberOfFeeds;
        },
        set maxNumberOfFeeds(value) {
            var defaultValue = 1;
            this._maxNumberOfFeeds = value ? value >= defaultValue ? value : defaultValue : defaultValue;
        },

        get updateInterval() {
            return this._updateInterval;
        },
        set updateInterval(value) {
            var defaultValue = 1;
            return this._updateInterval = value ? value >= defaultValue ? value : defaultValue : defaultValue;
        }
    },
    //Firefox sdk doesn't support more than 1 notification at once
    maxNotificationsCount: 1,
    cachedFeeds: [],
    isLoggedIn: false,
    intervalId: 0,
    toolbarButton: null
};

/* Create controls */

var panel = panelSdk.Panel({
    width: 400,
    height: 500,
    contentURL: self.data.url("popup.html"),
    contentScriptFile: [self.data.url("scripts/jquery-2.0.3.min.js"),
        self.data.url("scripts/timeago/jquery.timeago.js"),
        self.data.url(_("TimeAgoLocalizedLink")),
        self.data.url("scripts/popup.js")]
});

/* Listeners */
panel.port.on("updateToken", function () {
    getAccessToken();
});

panel.port.on("resizePanel", function (size) {
    panel.resize(size.width, size.height);
});

panel.port.on("markRead", function (markReadData) {
    if (!markReadData.isLinkOpened || appGlobal.options.markReadOnClick) {
        markAsRead(markReadData.feedIds);
    }
});

panel.on("show", function () {
    showPopupLoader();
    getFeeds(function (data) {
        sendFeedsToPopup(data);
    });
});

panel.port.on("getFeeds", function () {
    showPopupLoader();
    getFeeds(function (data) {
        sendFeedsToPopup(data);
    });
});

options.on("", function (optionName) {
    appGlobal.options[optionName] = options.prefs[optionName];
    options.prefs[optionName] = appGlobal.options[optionName];
    initialize();
});

options.on("logout", function () {
    ffStorage.storage.accessToken = "";
    initialize();
});

/* Load styles */
(function(){
    userstyles.load(self.data.url("styles/widget.css"));

    if(system.platform === "darwin"){
        userstyles.load(self.data.url("styles/widget_macos.css"));
    } else if (system.platform === "linux") {
        userstyles.load(self.data.url("styles/widget_linux.css"));
    }
})();

/* Senders */
function sendFeedsToPopup(feedsData) {
    panel.port.emit("feedsUpdated", feedsData);
}

function showPopupLoader() {
    panel.port.emit("showLoader", null);
}

function sendMarkAsReadResult(feedIds) {
    panel.port.emit("feedMarkedAsRead", feedIds);
}

/* Core functional */

/* Initializes api client, stops scheduler and runs new one */
function initialize() {
    if (appGlobal.options.openSiteOnIconClick) {

        appGlobal.toolbarButton.setListeners({
            panel: null,
            onCommand: function () {
                if (appGlobal.isLoggedIn) {
                    openFeedlyTab();
                } else {
                    getAccessToken();
                }
            }
        });
    } else {
        appGlobal.toolbarButton.setListeners({
            panel: panel,
            onCommand: null
        });
    }
    appGlobal.feedlyApiClient.accessToken = ffStorage.storage.accessToken;
    startSchedule(appGlobal.options.updateInterval);
}

/* Starts new scheduler */
function startSchedule(updateInterval) {
    stopSchedule(appGlobal.intervalId);
    updateFeeds();
    appGlobal.intervalId = timers.setInterval(updateFeeds, updateInterval * 60000);
}

/* Stops scheduler */
function stopSchedule() {
    timers.clearInterval(appGlobal.intervalId);
}

/* Sends desktop notifications */
function sendDesktopNotification(feeds) {
    //if notifications too many, then to show only count
    if (feeds.length > appGlobal.maxNotificationsCount) {
        //We can detect only limit count of new feeds at time, but actually count of feeds may be more
        var count = feeds.length === appGlobal.options.maxNumberOfFeeds ? _("many") : feeds.length.toString();
        notifications.notify({
            title: _("NewFeeds"),
            text: _("YouHaveNewFeeds", count),
            iconURL: self.data.url(appGlobal.icons.default)
        });
    } else {
        for (var i = 0; i < feeds.length; i++) {
            notifications.notify({
                title: feeds[i].blog,
                text: feeds[i].title,
                iconURL: feeds[i].blogIcon,
                data: JSON.stringify(feeds[i]),
                onClick: function (feed) {
                    var feed = JSON.parse(feed);
                    tabs.open({
                        url: feed.url
                    });
                    if (appGlobal.options.markReadOnClick) {
                        markAsRead([feed.id]);
                    }
                }
            });
        }
    }
}

/* Returns only new feeds and set date of last feed */
function filterByNewFeeds(feeds) {
    var lastFeedTime = new Date(ffStorage.storage.lastFeedTime) || new Date(0);
    var maxFeedTime = lastFeedTime;
    var newFeeds = [];

    for (var i = 0; i < feeds.length; i++) {
        if (feeds[i].date > lastFeedTime) {
            newFeeds.push(feeds[i]);
            if (feeds[i].date > maxFeedTime) {
                maxFeedTime = feeds[i].date;
            }
        }
    }

    ffStorage.storage.lastFeedTime = maxFeedTime.getTime();
    return newFeeds;
}

/* Removes feeds from cache by feed ID */
function removeFeedFromCache(feedId) {
    var indexFeedForRemove;
    for (var i = 0; i < appGlobal.cachedFeeds.length; i++) {
        if (appGlobal.cachedFeeds[i].id === feedId) {
            indexFeedForRemove = i;
            break;
        }
    }

    //Remove feed from cached feeds
    if (indexFeedForRemove !== undefined) {
        appGlobal.cachedFeeds.splice(indexFeedForRemove, 1);
    }
}

function openFeedlyTab() {
    if (appGlobal.feedlyTab) {
        appGlobal.feedlyTab.reload();
        appGlobal.feedlyTab.activate();
    } else {
        tabs.open({
            url: appGlobal.feedlyUrl,
            onOpen: function (tab) {
                appGlobal.feedlyTab = tab;
            },
            onClose: function () {
                appGlobal.feedlyTab = null;
            }
        });
    }

}

/* Stops scheduler, sets badge as inactive and resets counter */
function setInactiveStatus() {
    /*    chrome.browserAction.setIcon({ path: appGlobal.icons.inactive }, function () {
     });
     chrome.browserAction.setBadgeText({ text: ""});*/
    appGlobal.toolbarButton.setIcon({image: self.data.url(appGlobal.icons.inactive)});
    appGlobal.toolbarButton.setBadge(0);
    appGlobal.cachedFeeds = [];
    appGlobal.isLoggedIn = false;
    stopSchedule();
}

/* Sets badge as active */
function setActiveStatus() {
    appGlobal.toolbarButton.setIcon({image: self.data.url(appGlobal.icons.default)});
    appGlobal.isLoggedIn = true;
}

/* Runs feeds update and stores unread feeds in cache
 * Callback will be started after function complete */
function updateFeeds(callback, silentUpdate) {
    appGlobal.feedlyApiClient.request("markers/counts", {
        onSuccess: function (response) {
            setActiveStatus();

            var unreadFeedsCount = -1;
            var globalCategoryId = "";

            var unreadCounts = response.unreadcounts;
            for (var i = 0; i < unreadCounts.length; i++) {
                if (unreadFeedsCount < unreadCounts[i].count) {
                    unreadFeedsCount = unreadCounts[i].count;

                    //Search category(global or uncategorized) with max feeds
                    globalCategoryId = unreadCounts[i].id;
                }
            }
            appGlobal.toolbarButton.setBadge(unreadFeedsCount);

            //If user set show only counter and don't show notifications, then we don't need to load feeds
            if (appGlobal.options.showDesktopNotifications || !appGlobal.options.openSiteOnIconClick) {
                appGlobal.feedlyApiClient.request("streams/" + encodeURIComponent(globalCategoryId) + "/contents", {
                    parameters: {
                        unreadOnly: true,
                        count: appGlobal.options.maxNumberOfFeeds
                    },
                    onSuccess: function (response) {
                        appGlobal.cachedFeeds = parseFeeds(response);
                        if (appGlobal.options.showDesktopNotifications) {
                            var newFeeds = filterByNewFeeds(appGlobal.cachedFeeds);
                            if (!silentUpdate) {
                                sendDesktopNotification(newFeeds);
                            }
                        }
                        if (typeof callback === "function") {
                            callback();
                        }
                    },
                    onAuthorizationRequired: function () {
                        setInactiveStatus();
                        if (typeof callback === "function") {
                            callback();
                        }
                    }
                });
            }

        },
        onAuthorizationRequired: function () {
            setInactiveStatus();
            if (typeof callback === "function") {
                callback();
            }
        }
    });
}

/* Converts feedly response to feeds */
function parseFeeds(feedlyResponse) {
    var feeds = feedlyResponse.items.map(function (item) {
        var blogUrl;
        try {
            blogUrl = item.origin.htmlUrl.match(/http(?:s)?:\/\/[^/]+/i).pop();
        } catch (exception) {
            blogUrl = "#";
        }

        //Set content
        var content = "";
        var contentDirection = "";
        if (appGlobal.options.showFullFeedContent) {
            if (item.content !== undefined) {
                content = item.content.content;
                contentDirection = item.content.direction;
            }
        }
        if (content === "") {
            if (item.summary !== undefined) {
                content = item.summary.content;
                contentDirection = item.summary.direction;
            }
        }

        //Set title
        var title = "";
        var titleDirection = "";
        if (item.title !== undefined) {
            if (item.title.indexOf("direction:rtl") !== -1) {
                //Feedly wraps rtl titles in div, we remove div because desktopNotification supports only text
                title = item.title.replace(/<\/?div.*?>/gi, "");
                titleDirection = "rtl";
            } else {
                title = item.title;
            }
        }

        return {
            //Feedly wraps rtl titles in div, we remove div because desktopNotification supports only text
            title: title,
            titleDirection: titleDirection,
            url: item.alternate === undefined || item.alternate[0] === undefined ? "" : item.alternate[0].href,
            blog: item.origin === undefined ? "" : item.origin.title,
            blogUrl: blogUrl,
            blogIcon: "https://www.google.com/s2/favicons?domain=" + blogUrl + "&alt=feed",
            id: item.id,
            content: content,
            contentDirection: contentDirection,
            isoDate: item.crawled === undefined ? "" : new Date(item.crawled).toISOString(),
            date: item.crawled === undefined ? "" : new Date(item.crawled)
        };
    });
    return feeds;
}

/* Marks feed as read, remove it from the cache and decrement badge.
 * array of the ID of feeds
 */
function markAsRead(feedIds) {
    appGlobal.feedlyApiClient.request("markers", {
        method: "POST",
        body: {
            action: "markAsRead",
            type: "entries",
            entryIds: feedIds
        }
    });

    for (var i = 0; i < feedIds.length; i++) {
        removeFeedFromCache(feedIds[i]);
    }
    appGlobal.toolbarButton.badge = +appGlobal.toolbarButton.badge - feedIds.length;
    sendMarkAsReadResult(feedIds);
}

/* Reads all options from the storage */
function readOptions() {
    for (var optionName in appGlobal.options) {
        appGlobal.options[optionName] = options.prefs[optionName];
    }
}

/* Opens feedly site and if user are logged in,
 * then read access token and stores in the storage and initializes scheduler */
function getAccessToken() {
    events.on("http-on-modify-request", function getAccessTokenFromRequest(event) {
        var channel = event.subject.QueryInterface(Ci.nsIHttpChannel);
        var accessToken;

        //Trying get access token from header
        if (!accessToken) {
            try {
                accessToken = channel.getRequestHeader("X-Feedly-Access-Token");
            } catch (exception) {

            }
        }

        //Trying get access token from cookies
        try {
            var cookies = channel.getRequestHeader("Cookie");
            var feedlyParametersRegex = /session@cloud=({.+?})/i;
            var feedlyParameters = JSON.parse(feedlyParametersRegex.exec(cookies)[1]);
            if(feedlyParameters.feedlyExpirationTime > new Date()){
                accessToken = feedlyParameters.feedlyToken;
            }
        } catch (exception) {

        }

        if (accessToken) {
            ffStorage.storage.accessToken = accessToken;
            initialize();
            events.off("http-on-modify-request", getAccessTokenFromRequest);
        }
    });
    openFeedlyTab();
}

/* Returns feeds from the cache.
 If the cache is empty, then it will be updated before return */
function getFeeds(callback) {
    if (appGlobal.cachedFeeds.length > 0) {
        callback({feeds: appGlobal.cachedFeeds.slice(0), isLoggedIn: appGlobal.isLoggedIn});
    } else {
        updateFeeds(function () {
            callback({feeds: appGlobal.cachedFeeds.slice(0), isLoggedIn: appGlobal.isLoggedIn});
        }, true);
    }
}

exports.main = function (options, callbacks) {
    // create toolbarbutton
    appGlobal.toolbarButton = require("toolbarbutton").ToolbarButton({
        id: "feedlynotifier",
        tooltiptext: "Feedly Notifier",
        label: "Feedly notifier",
        badge: "",
        image: self.data.url(appGlobal.icons.inactive),
        panel: panel
    });

    appGlobal.toolbarButton.moveTo({
        toolbarID: "nav-bar",
        forceMove: false,
        insertbefore: "home-button"
    });

    readOptions();
    initialize();
};
<commit_msg>Fixed notifications problem<commit_after>"use strict";

var self = require("sdk/self");
var tabs = require("sdk/tabs");
var ffStorage = require("sdk/simple-storage");
var timers = require("sdk/timers");
var panelSdk = require("sdk/panel");
var options = require("sdk/simple-prefs");
var notifications = require("sdk/notifications");
var _ = require("sdk/l10n").get;
var events = require("sdk/system/events");
var { Ci } = require("chrome");
var feedlyApi = require("./feedly.api");
var userstyles = require("./userstyles");
var system = require("sdk/system");

var appGlobal = {
    feedlyApiClient: feedlyApi.getClient(),
    feedlyUrl: "feedly.com",
    feedlyTab: null,
    icons: {
        default: "images/icon20.png",
        inactive: "images/icon20_inactive.png"
    },
    options: {
        _updateInterval: 1,
        _maxNumberOfFeeds: 20,

        markReadOnClick: true,
        showDesktopNotifications: true,
        showFullFeedContent: false,
        openSiteOnIconClick: false,

        get maxNumberOfFeeds() {
            return this._maxNumberOfFeeds;
        },
        set maxNumberOfFeeds(value) {
            var defaultValue = 1;
            this._maxNumberOfFeeds = value ? value >= defaultValue ? value : defaultValue : defaultValue;
        },

        get updateInterval() {
            return this._updateInterval;
        },
        set updateInterval(value) {
            var defaultValue = 1;
            return this._updateInterval = value ? value >= defaultValue ? value : defaultValue : defaultValue;
        }
    },
    //Firefox sdk doesn't support more than 1 notification at once
    maxNotificationsCount: 1,
    cachedFeeds: [],
    isLoggedIn: false,
    intervalId: 0,
    toolbarButton: null
};

/* Create controls */

var panel = panelSdk.Panel({
    width: 400,
    height: 500,
    contentURL: self.data.url("popup.html"),
    contentScriptFile: [self.data.url("scripts/jquery-2.0.3.min.js"),
        self.data.url("scripts/timeago/jquery.timeago.js"),
        self.data.url(_("TimeAgoLocalizedLink")),
        self.data.url("scripts/popup.js")]
});

/* Listeners */
panel.port.on("updateToken", function () {
    getAccessToken();
});

panel.port.on("resizePanel", function (size) {
    panel.resize(size.width, size.height);
});

panel.port.on("markRead", function (markReadData) {
    if (!markReadData.isLinkOpened || appGlobal.options.markReadOnClick) {
        markAsRead(markReadData.feedIds);
    }
});

panel.on("show", function () {
    showPopupLoader();
    getFeeds(function (data) {
        sendFeedsToPopup(data);
    });
});

panel.port.on("getFeeds", function () {
    showPopupLoader();
    getFeeds(function (data) {
        sendFeedsToPopup(data);
    });
});

options.on("", function (optionName) {
    appGlobal.options[optionName] = options.prefs[optionName];
    options.prefs[optionName] = appGlobal.options[optionName];
    initialize();
});

options.on("logout", function () {
    ffStorage.storage.accessToken = "";
    initialize();
});

/* Load styles */
(function(){
    userstyles.load(self.data.url("styles/widget.css"));

    if(system.platform === "darwin"){
        userstyles.load(self.data.url("styles/widget_macos.css"));
    } else if (system.platform === "linux") {
        userstyles.load(self.data.url("styles/widget_linux.css"));
    }
})();

/* Senders */
function sendFeedsToPopup(feedsData) {
    panel.port.emit("feedsUpdated", feedsData);
}

function showPopupLoader() {
    panel.port.emit("showLoader", null);
}

function sendMarkAsReadResult(feedIds) {
    panel.port.emit("feedMarkedAsRead", feedIds);
}

/* Core functional */

/* Initializes api client, stops scheduler and runs new one */
function initialize() {
    if (appGlobal.options.openSiteOnIconClick) {

        appGlobal.toolbarButton.setListeners({
            panel: null,
            onCommand: function () {
                if (appGlobal.isLoggedIn) {
                    openFeedlyTab();
                } else {
                    getAccessToken();
                }
            }
        });
    } else {
        appGlobal.toolbarButton.setListeners({
            panel: panel,
            onCommand: null
        });
    }
    appGlobal.feedlyApiClient.accessToken = ffStorage.storage.accessToken;
    startSchedule(appGlobal.options.updateInterval);
}

/* Starts new scheduler */
function startSchedule(updateInterval) {
    stopSchedule(appGlobal.intervalId);
    updateFeeds();
    appGlobal.intervalId = timers.setInterval(updateFeeds, updateInterval * 60000);
}

/* Stops scheduler */
function stopSchedule() {
    timers.clearInterval(appGlobal.intervalId);
}

/* Sends desktop notifications */
function sendDesktopNotification(feeds) {
    //if notifications too many, then to show only count
    if (feeds.length > appGlobal.maxNotificationsCount) {
        //We can detect only limit count of new feeds at time, but actually count of feeds may be more
        var count = feeds.length === appGlobal.options.maxNumberOfFeeds ? _("many") : feeds.length.toString();
        notifications.notify({
            title: _("NewFeeds"),
            text: _("YouHaveNewFeeds", count),
            iconURL: self.data.url(appGlobal.icons.default)
        });
    } else {
        for (var i = 0; i < feeds.length; i++) {
            notifications.notify({
                title: feeds[i].blog,
                text: feeds[i].title,
                iconURL: feeds[i].blogIcon,
                data: JSON.stringify(feeds[i]),
                onClick: function (feed) {
                    var feed = JSON.parse(feed);
                    tabs.open({
                        url: feed.url
                    });
                    if (appGlobal.options.markReadOnClick) {
                        markAsRead([feed.id]);
                    }
                }
            });
        }
    }
}

/* Returns only new feeds and set date of last feed */
function filterByNewFeeds(feeds) {
    var lastFeedTime = new Date(ffStorage.storage.lastFeedTime || 0);
    var maxFeedTime = lastFeedTime;
    var newFeeds = [];

    for (var i = 0; i < feeds.length; i++) {
        if (feeds[i].date > lastFeedTime) {
            newFeeds.push(feeds[i]);
            if (feeds[i].date > maxFeedTime) {
                maxFeedTime = feeds[i].date;
            }
        }
    }

    ffStorage.storage.lastFeedTime = maxFeedTime.getTime();
    return newFeeds;
}

/* Removes feeds from cache by feed ID */
function removeFeedFromCache(feedId) {
    var indexFeedForRemove;
    for (var i = 0; i < appGlobal.cachedFeeds.length; i++) {
        if (appGlobal.cachedFeeds[i].id === feedId) {
            indexFeedForRemove = i;
            break;
        }
    }

    //Remove feed from cached feeds
    if (indexFeedForRemove !== undefined) {
        appGlobal.cachedFeeds.splice(indexFeedForRemove, 1);
    }
}

function openFeedlyTab() {
    if (appGlobal.feedlyTab) {
        appGlobal.feedlyTab.reload();
        appGlobal.feedlyTab.activate();
    } else {
        tabs.open({
            url: appGlobal.feedlyUrl,
            onOpen: function (tab) {
                appGlobal.feedlyTab = tab;
            },
            onClose: function () {
                appGlobal.feedlyTab = null;
            }
        });
    }

}

/* Stops scheduler, sets badge as inactive and resets counter */
function setInactiveStatus() {
    /*    chrome.browserAction.setIcon({ path: appGlobal.icons.inactive }, function () {
     });
     chrome.browserAction.setBadgeText({ text: ""});*/
    appGlobal.toolbarButton.setIcon({image: self.data.url(appGlobal.icons.inactive)});
    appGlobal.toolbarButton.setBadge(0);
    appGlobal.cachedFeeds = [];
    appGlobal.isLoggedIn = false;
    stopSchedule();
}

/* Sets badge as active */
function setActiveStatus() {
    appGlobal.toolbarButton.setIcon({image: self.data.url(appGlobal.icons.default)});
    appGlobal.isLoggedIn = true;
}

/* Runs feeds update and stores unread feeds in cache
 * Callback will be started after function complete */
function updateFeeds(callback, silentUpdate) {
    appGlobal.feedlyApiClient.request("markers/counts", {
        onSuccess: function (response) {
            setActiveStatus();

            var unreadFeedsCount = -1;
            var globalCategoryId = "";

            var unreadCounts = response.unreadcounts;
            for (var i = 0; i < unreadCounts.length; i++) {
                if (unreadFeedsCount < unreadCounts[i].count) {
                    unreadFeedsCount = unreadCounts[i].count;

                    //Search category(global or uncategorized) with max feeds
                    globalCategoryId = unreadCounts[i].id;
                }
            }
            appGlobal.toolbarButton.setBadge(unreadFeedsCount);

            //If user set show only counter and don't show notifications, then we don't need to load feeds
            if (appGlobal.options.showDesktopNotifications || !appGlobal.options.openSiteOnIconClick) {
                appGlobal.feedlyApiClient.request("streams/" + encodeURIComponent(globalCategoryId) + "/contents", {
                    parameters: {
                        unreadOnly: true,
                        count: appGlobal.options.maxNumberOfFeeds
                    },
                    onSuccess: function (response) {
                        appGlobal.cachedFeeds = parseFeeds(response);
                        if (appGlobal.options.showDesktopNotifications) {
                            var newFeeds = filterByNewFeeds(appGlobal.cachedFeeds);
                            if (!silentUpdate) {
                                sendDesktopNotification(newFeeds);
                            }
                        }
                        if (typeof callback === "function") {
                            callback();
                        }
                    },
                    onAuthorizationRequired: function () {
                        setInactiveStatus();
                        if (typeof callback === "function") {
                            callback();
                        }
                    }
                });
            }

        },
        onAuthorizationRequired: function () {
            setInactiveStatus();
            if (typeof callback === "function") {
                callback();
            }
        }
    });
}

/* Converts feedly response to feeds */
function parseFeeds(feedlyResponse) {
    var feeds = feedlyResponse.items.map(function (item) {
        var blogUrl;
        try {
            blogUrl = item.origin.htmlUrl.match(/http(?:s)?:\/\/[^/]+/i).pop();
        } catch (exception) {
            blogUrl = "#";
        }

        //Set content
        var content = "";
        var contentDirection = "";
        if (appGlobal.options.showFullFeedContent) {
            if (item.content !== undefined) {
                content = item.content.content;
                contentDirection = item.content.direction;
            }
        }
        if (content === "") {
            if (item.summary !== undefined) {
                content = item.summary.content;
                contentDirection = item.summary.direction;
            }
        }

        //Set title
        var title = "";
        var titleDirection = "";
        if (item.title !== undefined) {
            if (item.title.indexOf("direction:rtl") !== -1) {
                //Feedly wraps rtl titles in div, we remove div because desktopNotification supports only text
                title = item.title.replace(/<\/?div.*?>/gi, "");
                titleDirection = "rtl";
            } else {
                title = item.title;
            }
        }

        return {
            //Feedly wraps rtl titles in div, we remove div because desktopNotification supports only text
            title: title,
            titleDirection: titleDirection,
            url: item.alternate === undefined || item.alternate[0] === undefined ? "" : item.alternate[0].href,
            blog: item.origin === undefined ? "" : item.origin.title,
            blogUrl: blogUrl,
            blogIcon: "https://www.google.com/s2/favicons?domain=" + blogUrl + "&alt=feed",
            id: item.id,
            content: content,
            contentDirection: contentDirection,
            isoDate: item.crawled === undefined ? "" : new Date(item.crawled).toISOString(),
            date: item.crawled === undefined ? "" : new Date(item.crawled)
        };
    });
    return feeds;
}

/* Marks feed as read, remove it from the cache and decrement badge.
 * array of the ID of feeds
 */
function markAsRead(feedIds) {
    appGlobal.feedlyApiClient.request("markers", {
        method: "POST",
        body: {
            action: "markAsRead",
            type: "entries",
            entryIds: feedIds
        }
    });

    for (var i = 0; i < feedIds.length; i++) {
        removeFeedFromCache(feedIds[i]);
    }
    appGlobal.toolbarButton.badge = +appGlobal.toolbarButton.badge - feedIds.length;
    sendMarkAsReadResult(feedIds);
}

/* Reads all options from the storage */
function readOptions() {
    for (var optionName in appGlobal.options) {
        appGlobal.options[optionName] = options.prefs[optionName];
    }
}

/* Opens feedly site and if user are logged in,
 * then read access token and stores in the storage and initializes scheduler */
function getAccessToken() {
    events.on("http-on-modify-request", function getAccessTokenFromRequest(event) {
        var channel = event.subject.QueryInterface(Ci.nsIHttpChannel);
        var accessToken;

        //Trying get access token from header
        if (!accessToken) {
            try {
                accessToken = channel.getRequestHeader("X-Feedly-Access-Token");
            } catch (exception) {

            }
        }

        //Trying get access token from cookies
        try {
            var cookies = channel.getRequestHeader("Cookie");
            var feedlyParametersRegex = /session@cloud=({.+?})/i;
            var feedlyParameters = JSON.parse(feedlyParametersRegex.exec(cookies)[1]);
            if(feedlyParameters.feedlyExpirationTime > new Date()){
                accessToken = feedlyParameters.feedlyToken;
            }
        } catch (exception) {

        }

        if (accessToken) {
            ffStorage.storage.accessToken = accessToken;
            initialize();
            events.off("http-on-modify-request", getAccessTokenFromRequest);
        }
    });
    openFeedlyTab();
}

/* Returns feeds from the cache.
 If the cache is empty, then it will be updated before return */
function getFeeds(callback) {
    if (appGlobal.cachedFeeds.length > 0) {
        callback({feeds: appGlobal.cachedFeeds.slice(0), isLoggedIn: appGlobal.isLoggedIn});
    } else {
        updateFeeds(function () {
            callback({feeds: appGlobal.cachedFeeds.slice(0), isLoggedIn: appGlobal.isLoggedIn});
        }, true);
    }
}

exports.main = function (options, callbacks) {
    // create toolbarbutton
    appGlobal.toolbarButton = require("toolbarbutton").ToolbarButton({
        id: "feedlynotifier",
        tooltiptext: "Feedly Notifier",
        label: "Feedly notifier",
        badge: "",
        image: self.data.url(appGlobal.icons.inactive),
        panel: panel
    });

    appGlobal.toolbarButton.moveTo({
        toolbarID: "nav-bar",
        forceMove: false,
        insertbefore: "home-button"
    });

    readOptions();
    initialize();
};
<|endoftext|>


<commit_before>// In production, we register a service worker to serve assets from local cache.

// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.

// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.

const isLocalhost = Boolean(
  window.location.hostname === 'localhost' ||
  // [::1] is the IPv6 localhost address.
  window.location.hostname === '[::1]' ||
  // 127.0.0.1/8 is considered localhost for IPv4.
  window.location.hostname.match(
    /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
  )
);

function registerValidSW(swUrl) {
  navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
      registration.update();
      console.log("SW updated");
    })
    .catch(error => {
      console.error('Error during service worker registration:', error);
    });
}

function checkValidServiceWorker(swUrl) {
  // Check if the service worker can be found. If it can't reload the page.
  fetch(swUrl)
    .then(response => {
      // Ensure service worker exists, and that we really are getting a JS file.
      if (
        response.status === 404 ||
        response.headers.get('content-type').indexOf('javascript') === -1
      ) {
        // No service worker found. Probably a different app. Reload the page.
        navigator.serviceWorker.ready.then(registration => {
          registration.unregister().then(() => {
            window.location.reload();
          });
        });
      } else {
        // Service worker found. Proceed as normal.
        registerValidSW(swUrl);
      }
    })
    .catch(() => {
      console.log(
        'No internet connection found. App is running in offline mode.'
      );
    });
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.unregister();
    });
  }
}

export default function register() {
  if ('serviceWorker' in navigator) {
    // The URL constructor is available in all browsers that support SW.
    const publicUrl = new URL('https://freecourses.github.io/', window.location);
    if (publicUrl.origin !== window.location.origin) {
      // Our service worker won't work if PUBLIC_URL is on a different origin
      // from what our page is served on. This might happen if a CDN is used to
      // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
      return;
    }

    window.addEventListener('load', () => {
      const swUrl = './sw.js';

      if (!isLocalhost) {
        // Is not local host. Just register service worker
        registerValidSW(swUrl);
      } else {
        // This is running on localhost. Lets check if a service worker still exists or not.
        checkValidServiceWorker(swUrl);
      }
    });
  }
}
<commit_msg>teste SW<commit_after>// In production, we register a service worker to serve assets from local cache.

// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since previously
// cached resources are updated in the background.

// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
// This link also includes instructions on opting out of this behavior.

const isLocalhost = Boolean(
  window.location.hostname === 'localhost' ||
  // [::1] is the IPv6 localhost address.
  window.location.hostname === '[::1]' ||
  // 127.0.0.1/8 is considered localhost for IPv4.
  window.location.hostname.match(
    /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
  )
);

function registerValidSW(swUrl) {
  navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
      registration.update();
      setInterval(() => {
        registration.update();
        console.log("Update");
      }, 1000);
    })
    .catch(error => {
      console.error('Error during service worker registration:', error);
    });
}

function checkValidServiceWorker(swUrl) {
  // Check if the service worker can be found. If it can't reload the page.
  fetch(swUrl)
    .then(response => {
      // Ensure service worker exists, and that we really are getting a JS file.
      if (
        response.status === 404 ||
        response.headers.get('content-type').indexOf('javascript') === -1
      ) {
        // No service worker found. Probably a different app. Reload the page.
        navigator.serviceWorker.ready.then(registration => {
          registration.unregister().then(() => {
            window.location.reload();
          });
        });
      } else {
        // Service worker found. Proceed as normal.
        registerValidSW(swUrl);
      }
    })
    .catch(() => {
      console.log(
        'No internet connection found. App is running in offline mode.'
      );
    });
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.unregister();
    });
  }
}

export default function register() {
  if ('serviceWorker' in navigator) {
    // The URL constructor is available in all browsers that support SW.
    const publicUrl = new URL('https://freecourses.github.io/', window.location);
    if (publicUrl.origin !== window.location.origin) {
      // Our service worker won't work if PUBLIC_URL is on a different origin
      // from what our page is served on. This might happen if a CDN is used to
      // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
      return;
    }

    window.addEventListener('load', () => {
      const swUrl = './sw.js';

      if (!isLocalhost) {
        // Is not local host. Just register service worker
        registerValidSW(swUrl);
      } else {
        // This is running on localhost. Lets check if a service worker still exists or not.
        checkValidServiceWorker(swUrl);
      }
    });
  }
}
<|endoftext|>