<commit_before>define([
  'expect',
  'jquery',
  'mockup-utils'
], function(expect, $, utils) {
  'use strict';

  window.mocha.setup('bdd');
  $.fx.off = true;

  describe('utils', function () {

    describe('setId', function() {

      it('by default uses "id" as prefix', function() {
        var $el = $('
'),
            id = utils.setId($el);
        expect(id).to.not.be.an('undefined');
        expect(id).to.be.a('string');
        expect(id.indexOf('id')).to.be(0);
      });

      it('can use a custom prefix', function() {
        var $el = $('
'),
            id = utils.setId($el, 'myprefix');
        expect(id.indexOf('myprefix')).to.be(0);
      });

      it('updates the id of an element with no id', function() {
        var $el = $('
'),
            id;
        utils.setId($el);
        id = $el.attr('id');
        expect(id).to.not.be.an('undefined');
        expect(id).to.be.a('string');
        expect(id).to.contain('id');
      });

      it('replaces dots in ids with dashes', function() {
        var $el = $('

'),
            id = utils.setId($el);
        id = $el.attr('id');
        expect(id).to.equal('something-with-dots');
      });
    });

    describe('parseBodyTag', function() {

      it('parses the body tag\'s content from a response', function() {
        var response = '
foo
',
            html = utils.parseBodyTag(response);
        expect(html).to.equal('
foo
');
      });

      it('returns an empty string for responses with an empty body', function() {
        var response = '',
            html = utils.parseBodyTag(response);
        expect(html).to.equal('');
      });

      it('fails for empty responses', function() {
        var response = '',
            fn = function () {utils.parseBodyTag(response);};
        expect(fn).to.throwException(TypeError);
      });

      it('fails for responses without a body tag', function() {
        var response = '
qux
',
            fn = function () {utils.parseBodyTag(response);};
        expect(fn).to.throwException(TypeError);
      });

    });

    describe('bool', function() {

      it('returns true for "true"', function() {
        expect(utils.bool('true')).to.be.equal(true);
        expect(utils.bool(' true ')).to.be.equal(true);
        expect(utils.bool('TRUE')).to.be.equal(true);
        expect(utils.bool('True')).to.be.equal(true);
      });

      it('returns true for true', function() {
        var val = utils.bool(true);
        expect(val).to.be.equal(true);
      });

      it('returns true for true', function() {
        var val = utils.bool(1);
        expect(val).to.be.equal(true);
      });

      it('returns false for strings != "true"', function() {
        expect(utils.bool('1')).to.be.equal(false);
        expect(utils.bool('')).to.be.equal(false);
        expect(utils.bool('false')).to.be.equal(false);
      });

      it('returns false for undefined/null', function() {
        expect(utils.bool(undefined)).to.be.equal(false);
        expect(utils.bool(null)).to.be.equal(false);
      });
    });

    describe('QueryHelper', function() {

      it('getQueryData correctly', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var qd = qh.getQueryData('foobar');
        expect(qd.query).to.equal('{"criteria":[{"i":"SearchableText","o":"plone.app.querystring.operation.string.contains","v":"foobar*"}],"sort_on":"is_folderish","sort_order":"reverse"}');
      });
      it('getQueryData use attributes correctly', function() {
        var qh = new utils.QueryHelper({
          vocabularyUrl: 'http://foobar.com/',
          attributes: ['one', 'two']
        });
        var qd = qh.getQueryData('foobar');
        expect(qd.attributes).to.equal('["one","two"]');
      });
      it('getQueryData set batch', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var qd = qh.getQueryData('foobar', 1);
        expect(qd.batch).to.equal('{"page":1,"size":' + qh.options.batchSize + '}');
      });

      it('selectAjax gets data correctly', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var sa = qh.selectAjax();
        expect(sa.data('foobar').query).to.equal('{"criteria":[{"i":"SearchableText","o":"plone.app.querystring.operation.string.contains","v":"foobar*"}],"sort_on":"is_folderish","sort_order":"reverse"}');
      });
      it('selectAjax formats results correctly', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var sa = qh.selectAjax();
        var data = sa.results({total: 100, results: [1,2,3]}, 1);
        expect(data.results.length).to.equal(3);
        expect(data.more).to.equal(true);
      });

      it('getUrl correct', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        expect(qh.getUrl()).to.equal('http://foobar.com/?query=%7B%22criteria%22%3A%5B%5D%2C%22sort_on%22%3A%22is_folderish%22%2C%22sort_order%22%3A%22reverse%22%7D&attributes=%5B%22UID%22%2C%22Title%22%2C%22Description%22%2C%22getURL%22%2C%22portal_type%22%5D');
      });
      it('getUrl correct and url query params already present', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/?foo=bar'});
        expect(qh.getUrl()).to.equal('http://foobar.com/?foo=bar&query=%7B%22criteria%22%3A%5B%5D%2C%22sort_on%22%3A%22is_folderish%22%2C%22sort_order%22%3A%22reverse%22%7D&attributes=%5B%22UID%22%2C%22Title%22%2C%22Description%22%2C%22getURL%22%2C%22portal_type%22%5D');
      });

      it('browsing adds path criteria', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/?foo=bar'});
        qh.pattern.browsing = true;
        expect(qh.getQueryData('foobar').query).to.contain('plone.app.querystring.operation.string.path');
      });

    });

    describe('Loading', function() {

      it('creates element', function() {
        var loading = new utils.Loading();
        expect($('.' + loading.className).length).to.equal(1);
      });
      it('hidden on creation', function() {
        var loading = new utils.Loading();
        expect(loading.$el.is(':visible')).to.equal(false);
      });
      it('shows loader', function() {
        var loading = new utils.Loading();
        loading.show();
        expect(loading.$el.is(':visible')).to.equal(true);
      });
      it('hide loader', function() {
        var loading = new utils.Loading();
        loading.show();
        loading.hide();
        expect(loading.$el.is(':visible')).to.equal(false);
      });
      it('test custom zIndex', function() {
        var loading = new utils.Loading({
          zIndex: function() { return 99999; }
        });
        loading.show();
        expect(loading.$el[0].style.zIndex + '').to.equal('99999');
      });
      it('works with backdrop', function() {
        var initCalled = false;
        var showCalled = false;
        var fakeBackdrop = {
          init: function() {
            initCalled = true;
          },
          show: function() {
            showCalled = true;
          }
        };
        var loading = new utils.Loading({
          backdrop: fakeBackdrop
        });
        loading.show();
        expect(initCalled).to.equal(true);
        expect(showCalled).to.equal(true);
        expect(fakeBackdrop.closeOnClick).to.equal(true);
        expect(fakeBackdrop.closeOnEsc).to.equal(true);
      });

    });

  });

});
<commit_msg>call show initially so dom is loaded for tests<commit_after>define([
  'expect',
  'jquery',
  'mockup-utils'
], function(expect, $, utils) {
  'use strict';

  window.mocha.setup('bdd');
  $.fx.off = true;

  describe('utils', function () {

    describe('setId', function() {

      it('by default uses "id" as prefix', function() {
        var $el = $('
'),
            id = utils.setId($el);
        expect(id).to.not.be.an('undefined');
        expect(id).to.be.a('string');
        expect(id.indexOf('id')).to.be(0);
      });

      it('can use a custom prefix', function() {
        var $el = $('
'),
            id = utils.setId($el, 'myprefix');
        expect(id.indexOf('myprefix')).to.be(0);
      });

      it('updates the id of an element with no id', function() {
        var $el = $('
'),
            id;
        utils.setId($el);
        id = $el.attr('id');
        expect(id).to.not.be.an('undefined');
        expect(id).to.be.a('string');
        expect(id).to.contain('id');
      });

      it('replaces dots in ids with dashes', function() {
        var $el = $('

'),
            id = utils.setId($el);
        id = $el.attr('id');
        expect(id).to.equal('something-with-dots');
      });
    });

    describe('parseBodyTag', function() {

      it('parses the body tag\'s content from a response', function() {
        var response = '
foo
',
            html = utils.parseBodyTag(response);
        expect(html).to.equal('
foo
');
      });

      it('returns an empty string for responses with an empty body', function() {
        var response = '',
            html = utils.parseBodyTag(response);
        expect(html).to.equal('');
      });

      it('fails for empty responses', function() {
        var response = '',
            fn = function () {utils.parseBodyTag(response);};
        expect(fn).to.throwException(TypeError);
      });

      it('fails for responses without a body tag', function() {
        var response = '
qux
',
            fn = function () {utils.parseBodyTag(response);};
        expect(fn).to.throwException(TypeError);
      });

    });

    describe('bool', function() {

      it('returns true for "true"', function() {
        expect(utils.bool('true')).to.be.equal(true);
        expect(utils.bool(' true ')).to.be.equal(true);
        expect(utils.bool('TRUE')).to.be.equal(true);
        expect(utils.bool('True')).to.be.equal(true);
      });

      it('returns true for true', function() {
        var val = utils.bool(true);
        expect(val).to.be.equal(true);
      });

      it('returns true for true', function() {
        var val = utils.bool(1);
        expect(val).to.be.equal(true);
      });

      it('returns false for strings != "true"', function() {
        expect(utils.bool('1')).to.be.equal(false);
        expect(utils.bool('')).to.be.equal(false);
        expect(utils.bool('false')).to.be.equal(false);
      });

      it('returns false for undefined/null', function() {
        expect(utils.bool(undefined)).to.be.equal(false);
        expect(utils.bool(null)).to.be.equal(false);
      });
    });

    describe('QueryHelper', function() {

      it('getQueryData correctly', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var qd = qh.getQueryData('foobar');
        expect(qd.query).to.equal('{"criteria":[{"i":"SearchableText","o":"plone.app.querystring.operation.string.contains","v":"foobar*"}],"sort_on":"is_folderish","sort_order":"reverse"}');
      });
      it('getQueryData use attributes correctly', function() {
        var qh = new utils.QueryHelper({
          vocabularyUrl: 'http://foobar.com/',
          attributes: ['one', 'two']
        });
        var qd = qh.getQueryData('foobar');
        expect(qd.attributes).to.equal('["one","two"]');
      });
      it('getQueryData set batch', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var qd = qh.getQueryData('foobar', 1);
        expect(qd.batch).to.equal('{"page":1,"size":' + qh.options.batchSize + '}');
      });

      it('selectAjax gets data correctly', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var sa = qh.selectAjax();
        expect(sa.data('foobar').query).to.equal('{"criteria":[{"i":"SearchableText","o":"plone.app.querystring.operation.string.contains","v":"foobar*"}],"sort_on":"is_folderish","sort_order":"reverse"}');
      });
      it('selectAjax formats results correctly', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        var sa = qh.selectAjax();
        var data = sa.results({total: 100, results: [1,2,3]}, 1);
        expect(data.results.length).to.equal(3);
        expect(data.more).to.equal(true);
      });

      it('getUrl correct', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/'});
        expect(qh.getUrl()).to.equal('http://foobar.com/?query=%7B%22criteria%22%3A%5B%5D%2C%22sort_on%22%3A%22is_folderish%22%2C%22sort_order%22%3A%22reverse%22%7D&attributes=%5B%22UID%22%2C%22Title%22%2C%22Description%22%2C%22getURL%22%2C%22portal_type%22%5D');
      });
      it('getUrl correct and url query params already present', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/?foo=bar'});
        expect(qh.getUrl()).to.equal('http://foobar.com/?foo=bar&query=%7B%22criteria%22%3A%5B%5D%2C%22sort_on%22%3A%22is_folderish%22%2C%22sort_order%22%3A%22reverse%22%7D&attributes=%5B%22UID%22%2C%22Title%22%2C%22Description%22%2C%22getURL%22%2C%22portal_type%22%5D');
      });

      it('browsing adds path criteria', function() {
        var qh = new utils.QueryHelper({vocabularyUrl: 'http://foobar.com/?foo=bar'});
        qh.pattern.browsing = true;
        expect(qh.getQueryData('foobar').query).to.contain('plone.app.querystring.operation.string.path');
      });

    });

    describe('Loading', function() {

      it('creates element', function() {
        var loading = new utils.Loading();
        loading.show();
        expect($('.' + loading.className).length).to.equal(1);
      });
      it('hidden on creation', function() {
        var loading = new utils.Loading();
        loading.show();
        loading.hide();
        expect(loading.$el.is(':visible')).to.equal(false);
      });
      it('shows loader', function() {
        var loading = new utils.Loading();
        loading.show();
        expect(loading.$el.is(':visible')).to.equal(true);
      });
      it('hide loader', function() {
        var loading = new utils.Loading();
        loading.show();
        loading.hide();
        expect(loading.$el.is(':visible')).to.equal(false);
      });
      it('test custom zIndex', function() {
        var loading = new utils.Loading({
          zIndex: function() { return 99999; }
        });
        loading.show();
        expect(loading.$el[0].style.zIndex + '').to.equal('99999');
      });
      it('works with backdrop', function() {
        var initCalled = false;
        var showCalled = false;
        var fakeBackdrop = {
          init: function() {
            initCalled = true;
          },
          show: function() {
            showCalled = true;
          }
        };
        var loading = new utils.Loading({
          backdrop: fakeBackdrop
        });
        loading.show();
        expect(initCalled).to.equal(true);
        expect(showCalled).to.equal(true);
        expect(fakeBackdrop.closeOnClick).to.equal(true);
        expect(fakeBackdrop.closeOnEsc).to.equal(true);
      });

    });

  });

});
<|endoftext|>


<commit_before>import axios from 'axios/index'
import includes from 'lodash/includes'

import DIConstants from '../constants'
import { logError } from '../common'

class GithubService {
  AWESOME_LIST_URL = 'https://raw.githubusercontent.com/sindresorhus/awesome/master/readme.md'

  AWESOME_LIST_KEY = '@@awesome-list'

  RATE_LIMIT_THRESHOLD = 0.5

  constructor (ctx) {
    this.log = ctx[DIConstants.LOG]

    /** @type {AccessTokenRepository} */
    this.accessToken = ctx[DIConstants.R_ACCESS_TOKEN]

    /** @type {CacheService} */
    this.cache = ctx[DIConstants.S_CACHE]

    /** @type {ContextMenuService} */
    this.contextMenu = ctx[DIConstants.S_CONTEXT_MENU]

    /** @type {AxiosInstance} */
    this.client = null
  }

  async buildClient () {
    /** @type {string} */
    let token = await this.accessToken.loadAsync()

    if (!this.client || this.accessToken.changed) {
      let headers = {}
      if (token) {
        headers = { Authorization: `Bearer ${token}` }
      }

      this.client = axios.create({ baseURL: 'https://api.github.com', headers })
      this.accessToken.changed = false
    }
  }

  async fetchAwesomeListAsync () {
    /** @type {string} */
    let awesomeList = this.cache.get(this.AWESOME_LIST_KEY)

    if (!awesomeList) {
      let response = await axios.get(this.AWESOME_LIST_URL)

      awesomeList = await response.text()

      this.cache.set(this.AWESOME_LIST_KEY, awesomeList)
    }

    let awesomeListSize = (awesomeList.length / 1024).toFixed(3)
    this.log('📄 fetch awesome list', awesomeListSize, 'KB(s) from cache')

    return awesomeList
  }

  async fetchRateLimitAsync () {
    await this.buildClient()

    let numberFormatter = new Intl.NumberFormat('en-US')
    let percentFormatter = new Intl.NumberFormat('en-US', { style: 'percent' })

    try {
      let response = await this.client.get('/rate_limit')
      let { rate: { remaining, limit } } = response.data

      this.log('🚦 rate limit:', { remaining, limit })

      let title = chrome.i18n.getMessage('menuRateLimit', [
        numberFormatter.format(remaining),
        numberFormatter.format(limit),
        percentFormatter.format(remaining / limit)
      ])
      this.contextMenu.upsert(this.contextMenu.MENU_RATE_LIMIT, { title })

      return { remaining, limit }
    } catch (e) {
      logError(e)
      return { remaining: -1, limit: -1 }
    }
  }

  async fetchMultipleStarCountAsync (tuples) {
    for (let tuple of tuples) {
      let { owner, name } = tuple
      let starCount = await this.fetchStarCountAsync(owner, name)
      tuple.star = starCount
    }
    return tuples
  }

  async fetchStarCountAsync (owner, name) {
    // threshold to prevent the extension to use all rate limit
    let { remaining, limit } = await this.fetchRateLimitAsync()
    if (
      remaining === -1 || limit === -1 ||
      limit === 0 ||
      remaining / limit <= this.RATE_LIMIT_THRESHOLD
    ) {
      return -1
    }

    await this.buildClient()

    let cacheKey = `/repos/${owner}/${name}`
    let repo = this.cache.get(cacheKey)

    if (!repo) {
      try {
        let response = await this.client.get(`/repos/${owner}/${name}`)
        repo = response.data
        this.log('🌍 fetch repository from Github', repo)
        this.cache.set(cacheKey, repo)
      } catch (e) {
        logError(e)
        this.contextMenu.upsert(this.contextMenu.MENU_RATE_LIMIT, {
          title: chrome.i18n.getMessage('menuRateLimit', ['?', '?', 'N/A'])
        })
        return -1
      }
    } else {
      this.log('🗄 fetch repository from cache', repo)
    }

    let { stargazers_count: stargazersCount } = repo
    return parseInt(stargazersCount, 10)
  }

  async isAwesomeListAsync ({ owner, name }) {
    let awesomeList = await this.fetchAwesomeListAsync()
    return includes(awesomeList, `${owner}/${name}`)
  }
}

export default GithubService
<commit_msg>fix: awesome list 偵測<commit_after>import axios from 'axios/index'
import includes from 'lodash/includes'

import DIConstants from '../constants'

class GithubService {
  AWESOME_LIST_URL = 'https://raw.githubusercontent.com/sindresorhus/awesome/master/readme.md'

  AWESOME_LIST_KEY = '@@awesome-list'

  RATE_LIMIT_THRESHOLD = 0.5

  constructor (ctx) {
    this.log = ctx[DIConstants.LOG]

    /** @type {AccessTokenRepository} */
    this.accessToken = ctx[DIConstants.R_ACCESS_TOKEN]

    /** @type {CacheService} */
    this.cache = ctx[DIConstants.S_CACHE]

    /** @type {ContextMenuService} */
    this.contextMenu = ctx[DIConstants.S_CONTEXT_MENU]

    /** @type {AxiosInstance} */
    this.client = null
  }

  async buildClient () {
    /** @type {string} */
    let token = await this.accessToken.loadAsync()

    if (!this.client || this.accessToken.changed) {
      let headers = {}
      if (token) {
        headers = { Authorization: `Bearer ${token}` }
      }

      this.client = axios.create({ baseURL: 'https://api.github.com', headers })
      this.accessToken.changed = false
    }
  }

  async fetchAwesomeListAsync () {
    /** @type {string} */
    let awesomeList = this.cache.get(this.AWESOME_LIST_KEY)

    if (!awesomeList) {
      let response = await axios.get(this.AWESOME_LIST_URL)

      awesomeList = response.data

      this.cache.set(this.AWESOME_LIST_KEY, awesomeList)
    }

    let awesomeListSize = (awesomeList.length / 1024).toFixed(3)
    this.log('📄 fetch awesome list', awesomeListSize, 'KB(s) from cache')

    return awesomeList
  }

  async fetchRateLimitAsync () {
    await this.buildClient()

    let numberFormatter = new Intl.NumberFormat('en-US')
    let percentFormatter = new Intl.NumberFormat('en-US', { style: 'percent' })

    let response = await this.client.get('/rate_limit')
    let { rate: { remaining, limit } } = response.data

    this.log('🚦 rate limit:', { remaining, limit })

    let title = chrome.i18n.getMessage('menuRateLimit', [
      numberFormatter.format(remaining),
      numberFormatter.format(limit),
      percentFormatter.format(remaining / limit)
    ])
    this.contextMenu.upsert(this.contextMenu.MENU_RATE_LIMIT, { title })

    return { remaining, limit }
  }

  async fetchMultipleStarCountAsync (tuples) {
    for (let tuple of tuples) {
      let { owner, name } = tuple
      tuple.star = await this.fetchStarCountAsync(owner, name)
    }
    return tuples
  }

  async fetchStarCountAsync (owner, name) {
    // threshold to prevent the extension to use all rate limit
    let { remaining, limit } = await this.fetchRateLimitAsync()
    if (
      remaining === -1 || limit === -1 ||
      limit === 0 ||
      remaining / limit <= this.RATE_LIMIT_THRESHOLD
    ) {
      throw new Error(
        `rate limit ${remaining}/${limit} is below threshold ${this.RATE_LIMIT_THRESHOLD}`
      )
    }

    await this.buildClient()

    let cacheKey = `/repos/${owner}/${name}`
    let repo = this.cache.get(cacheKey)

    if (!repo) {
      let response = await this.client.get(`/repos/${owner}/${name}`)
      repo = response.data
      this.log('🌍 fetch repository from Github', repo)
      this.cache.set(cacheKey, repo)
    } else {
      this.log('🗄 fetch repository from cache', repo)
    }

    let { stargazers_count: stargazersCount } = repo
    return parseInt(stargazersCount, 10)
  }

  async isAwesomeListAsync ({ owner, name }) {
    let awesomeList = await this.fetchAwesomeListAsync()
    return includes(awesomeList, `${owner}/${name}`)
  }
}

export default GithubService
<|endoftext|>


<commit_before>(function(Ractive, CodeMirror, _, tungsten) {
  'use strict';

  Ractive.DEBUG = false;

  var topViews = [];
  tungsten.View.prototype._initialize = tungsten.View.prototype.initialize;
  tungsten.View.prototype.initialize = function(opts) {
    if (!opts.parentView && !this.tutorialView) {
      topViews.push(this);
    }
    this._initialize(opts);
  };

  var View = tungsten.View.extend({
    initDebug: _.noop,
    tutorialView: true
  });
  var Model = tungsten.Model.extend({
    initDebug: _.noop
  });
  var Collection = tungsten.Collection.extend({
    initDebug: _.noop
  });
  var ComponentWidget = tungsten.ComponentWidget;

  // Code Mirror Extensions and options
  CodeMirror.defineMode('mustache', function(config, parserConfig) {
    var mustacheOverlay = {
      token: function(stream) {
        var ch;
        if (stream.match('{{')) {
          while ((ch = stream.next()) != null) {
            if (ch == '}' && stream.next() == '}') {
              stream.eat('}');
              return 'mustache';
            }
          }
        }
        while (stream.next() != null && !stream.match('{{', false)) {
        }
        return null;
      }
    };
    return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || 'text/html'), mustacheOverlay);
  });

  var codeOptions = {
    lineNumbers: true,
    lineWrapping: true,
    extraKeys: {
      'Ctrl-Alt-Q': function(cm) { cm.foldCode(cm.getCursor()); },
      'Ctrl-Alt-F': function(cm) {
        cm.operation(function() {
          for (var l = cm.firstLine(); l <= cm.lastLine(); ++l) {
            cm.foldCode({
              line: l,
              ch: 0
            }, null, 'fold');
          }
        });
      },
      'Ctrl-Alt-U': function(cm) {
        cm.operation(function() {
          for (var l = cm.firstLine(); l <= cm.lastLine(); ++l) {
            cm.foldCode({
              line: l,
              ch: 0
            }, null, 'unfold');
          }
        });
      }
    },
    foldGutter: true,
    gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
  };

  // Views and Template
  var rawTemplates = {
    app: '
 {{#tutorial}}

 {{#steps}}
{{{index}}}
 {{/steps}}
 <button class="pure-button js-run run" id="run">Run</button>{{#step}}

{{name}}

{{{description_html}}}
 {{/step}}

{{{template}}}

{{{js}}}
 {{/tutorial}}
',
    codeMirror: ''
  };
  var compiledTemplates = tungsten._template.compileTemplates(rawTemplates);

  var CodeMirrorComponent = {
    View: View.extend({
      events: {
        'keyup': 'update',
        'input': 'update'
      },
      postInitialize: function() {
        this.listenTo(this.model, 'change:value', function(model, value) {
          this.codeMirror.setValue(value);
        });
        this.listenTo(this.model, 'change:highlights', function(model, value) {
          var codeMirror = this.codeMirror;
          _.each(value, function(highlight) {
            codeMirror.markText(highlight.start, highlight.end, {
              className: 'styled-background',
              clearOnEnter: true
            });
          });
        });
      },
      update: function() {
        this.model.updateValue(this.codeMirror.getValue());
      },
      postRender: function() {
        var self = this;
        if (!this.codeMirror) {
          setTimeout(function() {
            self.codeMirror = CodeMirror(self.el, self.model.attributes);
          });
        }
      }
    }, {debugName: 'CodeMirrorComponentView'}),
    Model: Model.extend({
      exposedEvents: ['change'],
      updateValue: function(val) {
        this.set('value', val, {silent: true});
        this.trigger('change', this);
      },
      serialize: function(data) {
        return data.value;
      }
    }, {debugName: 'CodeMirrorComponentModel'}),
    template: compiledTemplates.codeMirror,
    constructor: function(data, options) {
      if (data && data.constructor === ComponentWidget) {
        return data;
      }
      var component = new ComponentWidget(
        CodeMirrorComponent.View,
        new CodeMirrorComponent.Model(data),
        CodeMirrorComponent.template,
        options
      );

      return component;
    }
  };

  var StepSelectView = View.extend({
    events: {
      click: function() {
        this.model.trigger('selectStep', this.model);
      }
    }
  });
  var AppView = View.extend({
    events: {
      'click .js-run': 'run',
      'keydown': 'handleKeydown'
    },
    handleKeydown: function(e) {
      // shift + enter
      if (e.shiftKey && e.which === 13) {
        this.run();
        return false;
      }
      // ctrl + s
      if (e.ctrlKey && e.which === 83) {
        this.run();
        return false;
      }
      // meta + s
      if (e.metaKey && e.which === 83) {
        this.run();
        return false;
      }
    },
    run: function() {
      var newLines = /\n/g;
      var boilerplate = 'var rawTemplates = { app_view: \'' + this.model.get('template').doSerialize().replace(newLines, '') + '\' };var compiledTemplates = tungsten._template.compileTemplates(rawTemplates);';
      var evalNoContext = eval.bind(null);
      // Destroy any views that were created in the last run to ensure a fresh runtime
      _.invoke(topViews, 'destroy');
      topViews = [];
      document.getElementById('app').innerHTML = '';
      try {
        evalNoContext(boilerplate + '\n;' + this.model.get('js').doSerialize());
      } catch (e) {
        document.getElementById('app').innerHTML = '
ERROR: ' + e.toString() + '';
      }
    },
    toggleFold: function(cm, fold) {
      cm.operation(function() {
        for (var l = cm.firstLine(); l <= cm.lastLine(); ++l) {
          cm.foldCode({line: l, ch: 0}, null, fold ? 'fold' : unfold);
        }
      });
    },
    postInitialize: function() {
      var self = this;
      var debouncedRun = _.debounce(this.run, 200);
      this.listenTo(this.model, 'change:js change:template', debouncedRun);
      this.listenTo(this.model.get('tutorials'), 'selectTutorial', _.debounce(function(tutorialName) {
        var tutorial = self.model.get('tutorials').where({name: tutorialName})[0];
        self.model.unset('step');
        self.model.unset('tutorial');

        self.model.get('tutorials').each(function(tutorials) {
          tutorials.set('selected', false);
        });
        tutorial.set('selected', true);

        self.model.set('tutorial', tutorial.toJSON());
        self.listenTo(self.model.get('tutorial').get('steps'), 'selectStep', function(s) {
          self.model.get('tutorial').get('steps').each(function(step) {
            step.set('selected', false);
          });
          s.set('selected', true);
          self.model.get('tutorial').set('step', s);
          var appEl = document.getElementById('app');
          if (appEl) {
            appEl.innerHTML = '';
          }
        });
        if (self.model.get('tutorial').get('steps')) {
          // Start at the first step
          self.model.get('tutorial').get('steps').trigger('selectStep', self.model.get('tutorial').get('steps').at(0));
        } else {
          console.log('tutorial has no steps set');
        }

      }, 0));
      // Start with the first tutorial open
      this.model.get('tutorials').trigger('selectTutorial', this.model.get('tutorials').at(0).get('name'));
    },
    childViews: {
      'js-step-select': StepSelectView
    }
  });

  // Models and Collections
  var TutorialModel = Model.extend({
    derived: {
      url_name: {
        deps: ['name'],
        fn: function() {
          return encodeURI(this.get('name'));
        }
      }
    },
    relations: {
      steps: Collection.extend({
        model: Model.extend({
          defaults: {
            selected: false
          }
        })
      })
    }
  });
  var TutorialCollection = Collection.extend({
    model: TutorialModel
  });
  var AppModel = Model.extend({
    defaults: {
      js: _.extend({ mode: 'javascript', value: '' }, codeOptions),
      template: _.extend({ mode: 'mustache', value: '' }, codeOptions)
    },
    relations: {
      js: CodeMirrorComponent.constructor,
      template: CodeMirrorComponent.constructor,
      tutorials: TutorialCollection,
      tutorial: TutorialModel
    },
    postInitialize: function() {
      this.listenTo(this, 'change:tutorial change:tutorial:step', function() {
        this.get('js').set({
          value: this.getDeep('tutorial:step:js'),
          highlights: this.getDeep('tutorial:step:js_highlights')
        });
        this.get('template').set({
          value: this.getDeep('tutorial:step:template'),
          highlights: this.getDeep('tutorial:step:template_highlights')
        });
      });
    }
  });
  var appModel = new AppModel(window.data);

  // Start app
  var app = new AppView({
    el: document.getElementById('appwrapper'),
    template: compiledTemplates.app,
    model: appModel,
    dynamicInitialize: true
  });
  window.app = app;

  if (!tungsten.Backbone.history.started) {
    var Router = tungsten.Backbone.Router.extend({
      routes: {
        '*tutorialName': 'selectTutorial'
      },
      selectTutorial: function(tutorialName) {
        if (tutorialName) {
          appModel.get('tutorials').trigger('selectTutorial', tutorialName);
        }
      }
    });
    new Router();
    tungsten.Backbone.history.start();
  }

})(Ractive, CodeMirror, _, tungsten);
<commit_msg>Ensuring non-null values for CodeMirrorComponent<commit_after>(function(Ractive, CodeMirror, _, tungsten) {
  'use strict';

  Ractive.DEBUG = false;

  var topViews = [];
  tungsten.View.prototype._initialize = tungsten.View.prototype.initialize;
  tungsten.View.prototype.initialize = function(opts) {
    if (!opts.parentView && !this.tutorialView) {
      topViews.push(this);
    }
    this._initialize(opts);
  };

  var View = tungsten.View.extend({
    initDebug: _.noop,
    tutorialView: true
  });
  var Model = tungsten.Model.extend({
    initDebug: _.noop
  });
  var Collection = tungsten.Collection.extend({
    initDebug: _.noop
  });
  var ComponentWidget = tungsten.ComponentWidget;

  // Code Mirror Extensions and options
  CodeMirror.defineMode('mustache', function(config, parserConfig) {
    var mustacheOverlay = {
      token: function(stream) {
        var ch;
        if (stream.match('{{')) {
          while ((ch = stream.next()) != null) {
            if (ch == '}' && stream.next() == '}') {
              stream.eat('}');
              return 'mustache';
            }
          }
        }
        while (stream.next() != null && !stream.match('{{', false)) {
        }
        return null;
      }
    };
    return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || 'text/html'), mustacheOverlay);
  });

  var codeOptions = {
    lineNumbers: true,
    lineWrapping: true,
    extraKeys: {
      'Ctrl-Alt-Q': function(cm) { cm.foldCode(cm.getCursor()); },
      'Ctrl-Alt-F': function(cm) {
        cm.operation(function() {
          for (var l = cm.firstLine(); l <= cm.lastLine(); ++l) {
            cm.foldCode({
              line: l,
              ch: 0
            }, null, 'fold');
          }
        });
      },
      'Ctrl-Alt-U': function(cm) {
        cm.operation(function() {
          for (var l = cm.firstLine(); l <= cm.lastLine(); ++l) {
            cm.foldCode({
              line: l,
              ch: 0
            }, null, 'unfold');
          }
        });
      }
    },
    foldGutter: true,
    gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
  };

  // Views and Template
  var rawTemplates = {
    app: '
 {{#tutorial}}

 {{#steps}}
{{{index}}}
 {{/steps}}
 <button class="pure-button js-run run" id="run">Run</button>{{#step}}

{{name}}

{{{description_html}}}
 {{/step}}

{{{template}}}

{{{js}}}
 {{/tutorial}}
',
    codeMirror: ''
  };
  var compiledTemplates = tungsten._template.compileTemplates(rawTemplates);

  var CodeMirrorComponent = {
    View: View.extend({
      events: {
        'keyup': 'update',
        'input': 'update'
      },
      postInitialize: function() {
        this.listenTo(this.model, 'change:value', function(model, value) {
          this.codeMirror.setValue(value);
        });
        this.listenTo(this.model, 'change:highlights', function(model, value) {
          var codeMirror = this.codeMirror;
          _.each(value, function(highlight) {
            codeMirror.markText(highlight.start, highlight.end, {
              className: 'styled-background',
              clearOnEnter: true
            });
          });
        });
      },
      update: function() {
        this.model.updateValue(this.codeMirror.getValue());
      },
      postRender: function() {
        var self = this;
        if (!this.codeMirror) {
          setTimeout(function() {
            self.codeMirror = CodeMirror(self.el, self.model.attributes);
          });
        }
      }
    }, {debugName: 'CodeMirrorComponentView'}),
    Model: Model.extend({
      exposedEvents: ['change'],
      updateValue: function(val) {
        this.set('value', val, {silent: true});
        this.trigger('change', this);
      },
      serialize: function(data) {
        return data.value;
      }
    }, {debugName: 'CodeMirrorComponentModel'}),
    template: compiledTemplates.codeMirror,
    constructor: function(data, options) {
      if (data && data.constructor === ComponentWidget) {
        return data;
      }
      var component = new ComponentWidget(
        CodeMirrorComponent.View,
        new CodeMirrorComponent.Model(data),
        CodeMirrorComponent.template,
        options
      );

      return component;
    }
  };

  var StepSelectView = View.extend({
    events: {
      click: function() {
        this.model.trigger('selectStep', this.model);
      }
    }
  });
  var AppView = View.extend({
    events: {
      'click .js-run': 'run',
      'keydown': 'handleKeydown'
    },
    handleKeydown: function(e) {
      // shift + enter
      if (e.shiftKey && e.which === 13) {
        this.run();
        return false;
      }
      // ctrl + s
      if (e.ctrlKey && e.which === 83) {
        this.run();
        return false;
      }
      // meta + s
      if (e.metaKey && e.which === 83) {
        this.run();
        return false;
      }
    },
    run: function() {
      var newLines = /\n/g;
      var boilerplate = 'var rawTemplates = { app_view: \'' + this.model.get('template').doSerialize().replace(newLines, '') + '\' };var compiledTemplates = tungsten._template.compileTemplates(rawTemplates);';
      var evalNoContext = eval.bind(null);
      // Destroy any views that were created in the last run to ensure a fresh runtime
      _.invoke(topViews, 'destroy');
      topViews = [];
      document.getElementById('app').innerHTML = '';
      try {
        evalNoContext(boilerplate + '\n;' + this.model.get('js').doSerialize());
      } catch (e) {
        document.getElementById('app').innerHTML = '
ERROR: ' + e.toString() + '';
      }
    },
    toggleFold: function(cm, fold) {
      cm.operation(function() {
        for (var l = cm.firstLine(); l <= cm.lastLine(); ++l) {
          cm.foldCode({line: l, ch: 0}, null, fold ? 'fold' : unfold);
        }
      });
    },
    postInitialize: function() {
      var self = this;
      var debouncedRun = _.debounce(this.run, 200);
      this.listenTo(this.model, 'change:js change:template', debouncedRun);
      this.listenTo(this.model.get('tutorials'), 'selectTutorial', _.debounce(function(tutorialName) {
        var tutorial = self.model.get('tutorials').where({name: tutorialName})[0];
        self.model.unset('step');
        self.model.unset('tutorial');

        self.model.get('tutorials').each(function(tutorials) {
          tutorials.set('selected', false);
        });
        tutorial.set('selected', true);

        self.model.set('tutorial', tutorial.toJSON());
        self.listenTo(self.model.get('tutorial').get('steps'), 'selectStep', function(s) {
          self.model.get('tutorial').get('steps').each(function(step) {
            step.set('selected', false);
          });
          s.set('selected', true);
          self.model.get('tutorial').set('step', s);
          var appEl = document.getElementById('app');
          if (appEl) {
            appEl.innerHTML = '';
          }
        });
        if (self.model.get('tutorial').get('steps')) {
          // Start at the first step
          self.model.get('tutorial').get('steps').trigger('selectStep', self.model.get('tutorial').get('steps').at(0));
        } else {
          console.log('tutorial has no steps set');
        }

      }, 0));
      // Start with the first tutorial open
      this.model.get('tutorials').trigger('selectTutorial', this.model.get('tutorials').at(0).get('name'));
    },
    childViews: {
      'js-step-select': StepSelectView
    }
  });

  // Models and Collections
  var TutorialModel = Model.extend({
    derived: {
      url_name: {
        deps: ['name'],
        fn: function() {
          return encodeURI(this.get('name'));
        }
      }
    },
    relations: {
      steps: Collection.extend({
        model: Model.extend({
          defaults: {
            selected: false
          }
        })
      })
    }
  });
  var TutorialCollection = Collection.extend({
    model: TutorialModel
  });
  var AppModel = Model.extend({
    defaults: {
      js: _.extend({ mode: 'javascript', value: '' }, codeOptions),
      template: _.extend({ mode: 'mustache', value: '' }, codeOptions)
    },
    relations: {
      js: CodeMirrorComponent.constructor,
      template: CodeMirrorComponent.constructor,
      tutorials: TutorialCollection,
      tutorial: TutorialModel
    },
    postInitialize: function() {
      this.listenTo(this, 'change:tutorial change:tutorial:step', function() {
        this.get('js').set({
          value: this.getDeep('tutorial:step:js') || '',
          highlights: this.getDeep('tutorial:step:js_highlights') || []
        });
        this.get('template').set({
          value: this.getDeep('tutorial:step:template') || '',
          highlights: this.getDeep('tutorial:step:template_highlights') || []
        });
      });
    }
  });
  var appModel = new AppModel(window.data);

  // Start app
  var app = new AppView({
    el: document.getElementById('appwrapper'),
    template: compiledTemplates.app,
    model: appModel,
    dynamicInitialize: true
  });
  window.app = app;

  if (!tungsten.Backbone.history.started) {
    var Router = tungsten.Backbone.Router.extend({
      routes: {
        '*tutorialName': 'selectTutorial'
      },
      selectTutorial: function(tutorialName) {
        if (tutorialName) {
          appModel.get('tutorials').trigger('selectTutorial', tutorialName);
        }
      }
    });
    new Router();
    tungsten.Backbone.history.start();
  }

})(Ractive, CodeMirror, _, tungsten);
<|endoftext|>


<commit_before>const settings = require('electron-settings');

const sendToAllWindows = require('../libs/send-to-all-windows');

// scope
const v = '2018.2';

const defaultPreferences = {
  errorMonitoring: true,
  rememberLastPageVisited: false,
  sidebar: true,
  spellChecker: true,
  swipeToNavigate: true,
  theme: 'automatic',
  unreadCountBadge: true,
  jsCodeInjection: null,
  cssCodeInjection: null,
};

const getPreferences = () => Object.assign({}, defaultPreferences, settings.get(`preferences.${v}`, defaultPreferences));

const getPreference = name => settings.get(`preferences.${v}.${name}`, defaultPreferences[name]);

const setPreference = (name, value) => {
  settings.set(`preferences.${v}.${name}`, value);
  sendToAllWindows('set-preference', name, value);
};

const resetPreferences = () => {
  settings.deleteAll();

  const preferences = getPreferences();
  Object.keys(preferences).forEach((name) => {
    sendToAllWindows('set-preference', name, preferences[name]);
  });
};

module.exports = {
  getPreference,
  getPreferences,
  resetPreferences,
  setPreference,
};
<commit_msg>Hide sidebar by default in non-email apps (#224)<commit_after>const settings = require('electron-settings');

const sendToAllWindows = require('../libs/send-to-all-windows');

const appJson = require('../app.json');

// scope
const v = '2018.2';

const defaultPreferences = {
  errorMonitoring: true,
  rememberLastPageVisited: false,
  sidebar: Boolean(appJson.mailtoHandler),
  spellChecker: true,
  swipeToNavigate: true,
  theme: 'automatic',
  unreadCountBadge: true,
  jsCodeInjection: null,
  cssCodeInjection: null,
};

const getPreferences = () => Object.assign({}, defaultPreferences, settings.get(`preferences.${v}`, defaultPreferences));

const getPreference = name => settings.get(`preferences.${v}.${name}`, defaultPreferences[name]);

const setPreference = (name, value) => {
  settings.set(`preferences.${v}.${name}`, value);
  sendToAllWindows('set-preference', name, value);
};

const resetPreferences = () => {
  settings.deleteAll();

  const preferences = getPreferences();
  Object.keys(preferences).forEach((name) => {
    sendToAllWindows('set-preference', name, preferences[name]);
  });
};

module.exports = {
  getPreference,
  getPreferences,
  resetPreferences,
  setPreference,
};
<|endoftext|>


<commit_before>/**
 * @auther Chang Long <changlon@gmail.com>
 * https://github.com/changloong/mooforce
 */

var Klass = (function() {

    var Type = (function() {
        var Type = function(properties, prototype) {
            function type(self) {
                this.self = self;
            }
            Type.implement(type, {
                is: function(self) {
                    return self instanceof prototype;
                }
            });
            Type.implement(type, properties);
            return type;
        };

        Type.implement = function(type, properties) {
            Type.each(properties, function(property, name) {
                this[name] = property;
                if (!this.prototype.hasOwnProperty(name)) {
                    this.prototype[name] = function() {
                        return property.apply(this, Array.prototype.slice.call(arguments).unshift(this.self));
                    };
                }
            }, type);
        };

        Type.chain = function(type, properties) {
            Type.each(properties, function(property, name, type) {
                this[name] = property;
                if (!type.prototype.hasOwnProperty(name)) {
                    type.prototype[name] = function() {
                        this.self = property.apply(this, Array.prototype.slice.call(arguments).unshift(this.self));
                        return this;
                    };
                }
            }, type);
        };

        Type.each = function(self, fn, bind) {
            for (var p in self)
                if (self.hasOwnProperty(p)) {
                    fn.call(bind || self, self[p], p, bind || self);
                }
        };

        return Type;
    })();

    var $fn = (function() {

        var fn = new Type({
        }, Function);

        Type.chain(fn, {
            proxy: function(self, obj) {
                return function() {
                    return self.apply(obj, arguments);
                };
            },
            parent: function(self, parent) {
                return function() {
                    var current = this.parent;
                    this.parent = parent;
                    var result;
                    try {
                        result = self.apply(this, arguments);
                    } finally {
                        this.parent = current;
                    }
                    return result;
                };
            }
        });

        return fn;
    })();

    var $array = (function() {

        var array = new Type({
            each: function(self, fn, bind) {
                for (var i = 0; i < self.length; i++) {
                    fn.call(bind || self, self[i], i, bind || self);
                }
            },
            erase: function(self, item) {
                for (var i = self.length; i--; ) {
                    if (self[i] === item)
                        self.splice(i, 1);
                }
            }
        }, Array);

        if (Array.prototype.hasOwnProperty('indexOf')) {
            Type.chain(array, {
                include: function(self, item) {
                    if (-1 == self.indexOf(item))
                        self.push(item);
                    return self;
                }
            });
            Type.implement(array, {
                contains: function(self, item) {
                    return -1 != self.indexOf(item);
                }
            });
        } else {
            Type.chain(array, {
                include: function(self, item) {
                    for (var i = self.length; i--; ) {
                        if (self[i] == item)
                            return self;
                    }
                    self.push(item);
                    return self;
                }
            });
            Type.implement(array, {
                contains: function(self, item) {
                    for (var i = self.length; i--; ) {
                        if (self[i] == item)
                            return true;
                    }
                    return false;
                }
            });
        }

        return array;
    })();

    var $object = (function() {
        var object = new Type({
            is: function(self) {
                if (!self || self instanceof Array) {
                    return false;
                }
                return 'object' === typeof self;
            },
            each: Type.each,
            merge: function(self, source) {
                if (object.is(self) && object.is(source)) {
                    for (var k in source)
                        if (source.hasOwnProperty(k)) {
                            if (self.hasOwnProperty(k)) {
                                arguments.callee(self[k], source[k]);
                            } else {
                                self[k] = object.clone(source[k]);
                            }
                        }
                }
                return self;
            },
            clone: function(self) {
                if (self) {
                    if (self instanceof Array) {
                        var len = self.length;
                        var o = new Array(len);
                        for (var i = 0; i < len; i++) {
                            o[i] = arguments.callee(self[i]);
                        }
                        return o;
                    } else if (typeof self === 'object') {
                        var o = new Object;
                        for (var i in self)
                            if (self.hasOwnProperty(i)) {
                                o[i] = arguments.callee(self[i]);
                            }
                        return o;
                    }
                }
                return self;
            },
            reset: function(self) {
                if (self)
                    for (var key in self) {
                        var value = self[key];
                        if (value) {
                            if (value instanceof Array) {
                                var len = value.length;
                                var o = new Array(len);
                                for (var i = 0; i < len; i++) {
                                    o[i] = arguments.callee(value[i]);
                                }
                                self[key] = o;
                            } else if (typeof value == 'object') {
                                var F = function() {
                                };
                                F.prototype = value;
                                self[key] = arguments.callee(new F);
                            }
                        }
                    }
                return self;
            }
        }, Object);

        return object;
    })();

    var Class = (function() {
        var classes = [];

        function Class(constructor, properties) {

            if (properties.hasOwnProperty('extends')) {
                this.parent = arguments.callee.find(properties['extends']);
                if (!this.parent) {
                    throw new Error('extends is invalid');
                }
                delete properties['extends'];
            } else {
                this.parent = null;
            }

            this.Constructor = constructor;
            classes.push(this);

            if (properties.hasOwnProperty('initialize')) {
                if ('function' !== typeof properties['initialize']) {
                    throw new Error('initialize method is not function');
                }
                if (this.parent && this.parent.initialize) {
                    this.initialize = $fn.parent(properties['initialize'], this.parent.initialize);
                } else {
                    this.initialize = properties['initialize'];
                }
                delete properties['initialize'];
            } else {
                this.initialize = this.parent ? this.parent.initialize : null;
            }

            this.binds = {};
            this.implements = [Class.Events, Class.Options];
            this.Constructor.prototype = {};

            this.extends(properties);
        }
        ;

        Class.find = function(constructor) {
            var len = classes.length;
            for (var i = 0; i < len; i++) {
                if (classes[i].Constructor === constructor) {
                    return classes[i];
                }
            }
            return null;
        };

        Class.prototype.bind = function(object, parent_prototype) {
            if (this.parent) {
                this.parent.bind(object);
            }
            $object.each(this.binds, function(fn, name) {
                var _fn = null;
                if (object.hasOwnProperty(name)) {
                    _fn = object[name];
                } else if (parent_prototype && parent_prototype.hasOwnProperty(name)) {
                    _fn = parent_prototype[ name ];
                }
                if (_fn && $fn.is(parent_prototype[name])) {
                    object[name] = $fn.proxy($fn.parent(fn, _fn), object);
                } else {
                    object[name] = $fn.proxy(fn, object);
                }
            }, this);
        };

        Class.prototype.extends = function(properties) {

            if (!$object.is(properties)) {
                throw new Error('implements properties must be object');
            }

            if (properties.hasOwnProperty('Binds')) {
                if (!$array.is(properties['Binds'])) {
                    throw new Error('Binds must be array');
                }
                $array.each(properties['Binds'], function(p) {
                    if (properties.hasOwnProperty(p)) {
                        var fn = properties[p];
                        delete properties[p];
                        if ('function' !== typeof fn) {
                            throw new Error('Binds method "' + p + '" is not function');
                        }
                        this.binds[p] = fn;
                    } else {
                        throw new Error('Binds method "' + p + '" not exists');
                    }
                }, this);
                delete properties['Binds'];
            }

            if (properties.hasOwnProperty('implements')) {
                if (properties['implements'] instanceof Array) {
                    $array.each(properties['implements'], function(value) {
                        this.push(value);
                    }, this.implements);
                } else {
                    this.implements.push(properties['implements']);
                }
                delete properties['implements'];
            }

            if (this.parent) {
                $object.each(properties, function(value, name) {
                    if ($fn.is(value) && this.hasOwnProperty(name) && $fn.is(this[name])) {
                        properties[name] = $fn.parent(value, this[name]);
                    } else {
                        properties[name] = $object.clone(value);
                    }
                }, this.parent.Constructor.prototype);
            }

            this.Constructor.prototype = $object.merge(properties, this.parent ? this.parent.Constructor.prototype : {});

        };

        Class.prototype.construct = function(object, args) {
            $object.reset(object);

            this.bind(object, this.parent ? this.parent.Constructor.prototype : null);

            var initialized = [];
            $array.each(this.implements, function(properties) {
                if (properties instanceof Function) {
                    properties = properties.call(object, this.Constructor);
                } else {
                    properties = $object.clone(properties);
                }

                if ( !$object.is(properties) ) {
                    throw new Error('implements "' + String(properties) + '" is not object');
                }

                if (properties.hasOwnProperty('initialized')) {
                    initialized.push(properties['initialized']);
                    delete properties['initialized'];
                }

                if (properties.hasOwnProperty('Binds')) {
                    if (!$array.is(properties['Binds'])) {
                        throw new Error('Binds must be array');
                    }
                    $array.each(properties['Binds'], function(p) {
                        if (properties.hasOwnProperty(p)) {
                            var fn = properties[p];
                            delete properties[p];
                            if ($fn.is(fn)) {
                                this[p] = $fn.proxy(fn, this);
                            } else {
                                throw new Error('Binds method "' + p + '" is not function');
                            }
                        } else {
                            throw new Error('Binds method "' + p + '" not exists');
                        }
                    }, object);
                    delete properties['Binds'];
                }
                $object.merge(object, properties);
            }, this);

            var self = this.initialize ? this.initialize.apply(object, args) : object;

            $array.each(initialized, function(fn) {
                fn.call(this);
            }, object);

            initialized = null;

            return self;
        };

        return Class;
    })();

    Class.Events = function() {
        var events = {};
        return {
            addEvent: function(type, fn) {
                if (!(fn instanceof Function)) {
                    throw new Exception('add event need Function argument!');
                }
                events[type] = $array.include(events[type] || [], fn);
                return this;
            },
            fireEvent: fireEvent = function(type) {
                var args = Array.prototype.slice.call(arguments, 1);
                if (events.hasOwnProperty(type)) {
                    var _events = events[type];
                    for (var i = 0; i < _events.length; i++) {
                        if (false === _events[i].apply(this, args)) {
                            return false;
                        }
                    }
                }
                return true;
            },
            removeEvent: function(type, fn) {
                if (events.hasOwnProperty(type)) {
                    $array.erase(events[type], fn);
                }
                return this;
            },
            addEvents: function(events) {
                for (var type in events)
                    if (events.hasOwnProperty(type)) {
                        this.addEvent(type, events[type]);
                    }
                return this;
            },
            removeEvents: function(type) {
                if (!(type instanceof String)) {
                    for (_type in type)
                        if (type.hasOwnProperty(_type)) {
                            this.removeEvent(_type, type[_type]);
                        }
                    return this;
                }
                if (events.hasOwnProperty(type)) {
                    delete events[type];
                }
                return this;
            }
        };
    };

    Class.Options = (function() {
        function $removeOn(string) {
            return string.replace(/^on([A-Z])/, function(full, first) {
                return first.toLowerCase();
            });
        }
        ;
        function $tryRemoveOn(string) {
            if (/^on([A-Z]\w+)$/.test(string)) {
                return String(RegExp.$1).toLowerCase();
            } else {
                return string;
            }
        }
        ;
        return function(constructor) {
            var options_initialized = true;
            if (constructor.prototype.hasOwnProperty('options')) {
                this.options = $object.clone(constructor.prototype.options);
            } else {
                this.options = {};
            }
            return {
                initialized: function() {
                    var fn = options_initialized;
                    options_initialized = null;
                    if ($fn.is(fn)) {
                        fn.call(this);
                    }
                },
                setOptions: function(options) {
                    if (options) {
                        this.options = $object.merge(options, this.options);
                    }

                    $object.each(this.options, function(value, key) {
                        if (key === 'events') {
                            this.addEvents(value);
                            delete this.options[key];
                        } else {
                            if ($fn.is(value)) {
                                var type = $tryRemoveOn(key);
                                if (key != type) {
                                    this.addEvent(type, value);
                                    delete this.options[key];
                                }
                            }
                        }
                    }, this);

                    var scope_initialized = null;

                    if (this.options.hasOwnProperty('initialized')) {
                        if ($fn.is(this.options['initialized'])) {
                            if (options_initialized) {
                                options_initialized = this.options['initialized'];
                            } else {
                                scope_initialized = this.options['initialized'];
                            }
                            delete this.options['initialized'];
                        }
                    }

                    if (scope_initialized) {
                        scope_initialized.call(this);
                    }
                    return this;
                }
            };
        }
    })();

    var exports = function(properties) {
        var klass = new Class(constructor, properties);
        function constructor() {
            return klass.construct(this, arguments);
        }
        ;
        return constructor;
    };

    exports.extends = function(constructor, properties) {
        var klass = Class.find(constructor);
        if (!klass) {
            throw new Error('extends klass is invalid');
        }
        klass.extends(properties);
    };

    exports.implements = function(constructor, properties) {
        var klass = Class.find(constructor);
        if (!klass) {
            throw new Error('implements klass is invalid');
        }
        klass.implements.push(properties);
    };

    exports.each = function(self, fn, bind) {
        if ($array.is(self)) {
            return $array.each(self, fn, bind);
        } else {
            return $object.each(self, fn, bind);
        }
    }

    return exports;
})();

<commit_msg>fix ie error<commit_after>/**
 * @auther Chang Long <changlon@gmail.com>
 * https://github.com/changloong/mooforce
 */

var Klass = (function() {

    var Type = (function() {
        var Type = function(properties, prototype) {
            function type(self) {
                this.self = self;
            }
            Type.implement(type, {
                is: function(self) {
                    return self instanceof prototype;
                }
            });
            Type.implement(type, properties);
            return type;
        };

        Type.implement = function(type, properties) {
            Type.each(properties, function(property, name) {
                this[name] = property;
                if (!this.prototype.hasOwnProperty(name)) {
                    this.prototype[name] = function() {
                        return property.apply(this, Array.prototype.slice.call(arguments).unshift(this.self));
                    };
                }
            }, type);
        };

        Type.chain = function(type, properties) {
            Type.each(properties, function(property, name, type) {
                this[name] = property;
                if (!type.prototype.hasOwnProperty(name)) {
                    type.prototype[name] = function() {
                        this.self = property.apply(this, Array.prototype.slice.call(arguments).unshift(this.self));
                        return this;
                    };
                }
            }, type);
        };

        Type.each = function(self, fn, bind) {
            for (var p in self)
                if (self.hasOwnProperty(p)) {
                    fn.call(bind || self, self[p], p, bind || self);
                }
        };

        return Type;
    })();

    var $fn = (function() {

        var fn = new Type({
        }, Function);

        Type.chain(fn, {
            proxy: function(self, obj) {
                return function() {
                    return self.apply(obj, arguments);
                };
            },
            parent: function(self, parent) {
                return function() {
                    var current = this.parent;
                    this.parent = parent;
                    var result;
                    try {
                        result = self.apply(this, arguments);
                    } finally {
                        this.parent = current;
                    }
                    return result;
                };
            }
        });

        return fn;
    })();

    var $array = (function() {

        var array = new Type({
            each: function(self, fn, bind) {
                for (var i = 0; i < self.length; i++) {
                    fn.call(bind || self, self[i], i, bind || self);
                }
            },
            erase: function(self, item) {
                for (var i = self.length; i--; ) {
                    if (self[i] === item)
                        self.splice(i, 1);
                }
            }
        }, Array);

        if (Array.prototype.hasOwnProperty('indexOf')) {
            Type.chain(array, {
                include: function(self, item) {
                    if (-1 == self.indexOf(item))
                        self.push(item);
                    return self;
                }
            });
            Type.implement(array, {
                contains: function(self, item) {
                    return -1 != self.indexOf(item);
                }
            });
        } else {
            Type.chain(array, {
                include: function(self, item) {
                    for (var i = self.length; i--; ) {
                        if (self[i] == item)
                            return self;
                    }
                    self.push(item);
                    return self;
                }
            });
            Type.implement(array, {
                contains: function(self, item) {
                    for (var i = self.length; i--; ) {
                        if (self[i] == item)
                            return true;
                    }
                    return false;
                }
            });
        }

        return array;
    })();

    var $object = (function() {
        var object = new Type({
            is: function(self) {
                if (!self || self instanceof Array) {
                    return false;
                }
                return 'object' === typeof self;
            },
            each: Type.each,
            merge: function(self, source) {
                if (object.is(self) && object.is(source)) {
                    for (var k in source)
                        if (source.hasOwnProperty(k)) {
                            if (self.hasOwnProperty(k)) {
                                arguments.callee(self[k], source[k]);
                            } else {
                                self[k] = object.clone(source[k]);
                            }
                        }
                }
                return self;
            },
            clone: function(self) {
                if (self) {
                    if (self instanceof Array) {
                        var len = self.length;
                        var o = new Array(len);
                        for (var i = 0; i < len; i++) {
                            o[i] = arguments.callee(self[i]);
                        }
                        return o;
                    } else if (typeof self === 'object') {
                        var o = new Object;
                        for (var i in self)
                            if (self.hasOwnProperty(i)) {
                                o[i] = arguments.callee(self[i]);
                            }
                        return o;
                    }
                }
                return self;
            },
            reset: function(self) {
                if (self)
                    for (var key in self) {
                        var value = self[key];
                        if (value) {
                            if (value instanceof Array) {
                                var len = value.length;
                                var o = new Array(len);
                                for (var i = 0; i < len; i++) {
                                    o[i] = arguments.callee(value[i]);
                                }
                                self[key] = o;
                            } else if (typeof value == 'object') {
                                var F = function() {
                                };
                                F.prototype = value;
                                self[key] = arguments.callee(new F);
                            }
                        }
                    }
                return self;
            }
        }, Object);

        return object;
    })();

    var Class = (function() {
        var classes = [];

        function Class(constructor, properties) {

            if (properties.hasOwnProperty('extends')) {
                this.parent = arguments.callee.find(properties['extends']);
                if (!this.parent) {
                    throw new Error('extends is invalid');
                }
                delete properties['extends'];
            } else {
                this.parent = null;
            }

            this.Constructor = constructor;
            classes.push(this);

            if (properties.hasOwnProperty('initialize')) {
                if ('function' !== typeof properties['initialize']) {
                    throw new Error('initialize method is not function');
                }
                if (this.parent && this.parent.initialize) {
                    this.initialize = $fn.parent(properties['initialize'], this.parent.initialize);
                } else {
                    this.initialize = properties['initialize'];
                }
                delete properties['initialize'];
            } else {
                this.initialize = this.parent ? this.parent.initialize : null;
            }

            this.binds = {};
            this.implements = [Class.Events, Class.Options];
            this.Constructor.prototype = {};

            this.extend(properties);
        }
        ;

        Class.find = function(constructor) {
            var len = classes.length;
            for (var i = 0; i < len; i++) {
                if (classes[i].Constructor === constructor) {
                    return classes[i];
                }
            }
            return null;
        };

        Class.prototype.bind = function(object, parent_prototype) {
            if (this.parent) {
                this.parent.bind(object);
            }
            $object.each(this.binds, function(fn, name) {
                var _fn = null;
                if (object.hasOwnProperty(name)) {
                    _fn = object[name];
                } else if (parent_prototype && parent_prototype.hasOwnProperty(name)) {
                    _fn = parent_prototype[ name ];
                }
                if (_fn && $fn.is(parent_prototype[name])) {
                    object[name] = $fn.proxy($fn.parent(fn, _fn), object);
                } else {
                    object[name] = $fn.proxy(fn, object);
                }
            }, this);
        };

        Class.prototype.extend = function(properties) {

            if (!$object.is(properties)) {
                throw new Error('implements properties must be object');
            }

            if (properties.hasOwnProperty('Binds')) {
                if (!$array.is(properties['Binds'])) {
                    throw new Error('Binds must be array');
                }
                $array.each(properties['Binds'], function(p) {
                    if (properties.hasOwnProperty(p)) {
                        var fn = properties[p];
                        delete properties[p];
                        if ('function' !== typeof fn) {
                            throw new Error('Binds method "' + p + '" is not function');
                        }
                        this.binds[p] = fn;
                    } else {
                        throw new Error('Binds method "' + p + '" not exists');
                    }
                }, this);
                delete properties['Binds'];
            }

            if (properties.hasOwnProperty('implements')) {
                if (properties['implements'] instanceof Array) {
                    $array.each(properties['implements'], function(value) {
                        this.push(value);
                    }, this.implements);
                } else {
                    this.implements.push(properties['implements']);
                }
                delete properties['implements'];
            }

            if (this.parent) {
                $object.each(properties, function(value, name) {
                    if ($fn.is(value) && this.hasOwnProperty(name) && $fn.is(this[name])) {
                        properties[name] = $fn.parent(value, this[name]);
                    } else {
                        properties[name] = $object.clone(value);
                    }
                }, this.parent.Constructor.prototype);
            }

            this.Constructor.prototype = $object.merge(properties, this.parent ? this.parent.Constructor.prototype : {});

        };

        Class.prototype.Construct = function(object, args) {
            $object.reset(object);

            this.bind(object, this.parent ? this.parent.Constructor.prototype : null);

            var initialized = [];
            $array.each(this.implements, function(properties) {
                if (properties instanceof Function) {
                    properties = properties.call(object, this.Constructor);
                } else {
                    properties = $object.clone(properties);
                }

                if ( !$object.is(properties) ) {
                    throw new Error('implements "' + String(properties) + '" is not object');
                }

                if (properties.hasOwnProperty('initialized')) {
                    initialized.push(properties['initialized']);
                    delete properties['initialized'];
                }

                if (properties.hasOwnProperty('Binds')) {
                    if (!$array.is(properties['Binds'])) {
                        throw new Error('Binds must be array');
                    }
                    $array.each(properties['Binds'], function(p) {
                        if (properties.hasOwnProperty(p)) {
                            var fn = properties[p];
                            delete properties[p];
                            if ($fn.is(fn)) {
                                this[p] = $fn.proxy(fn, this);
                            } else {
                                throw new Error('Binds method "' + p + '" is not function');
                            }
                        } else {
                            throw new Error('Binds method "' + p + '" not exists');
                        }
                    }, object);
                    delete properties['Binds'];
                }
                $object.merge(object, properties);
            }, this);

            var self = this.initialize ? this.initialize.apply(object, args) : object;

            $array.each(initialized, function(fn) {
                fn.call(this);
            }, object);

            initialized = null;

            return self;
        };

        return Class;
    })();

    Class.Events = function() {
        var events = {};
        return {
            addEvent: function(type, fn) {
                if (!(fn instanceof Function)) {
                    throw new Exception('add event need Function argument!');
                }
                events[type] = $array.include(events[type] || [], fn);
                return this;
            },
            fireEvent: fireEvent = function(type) {
                var args = Array.prototype.slice.call(arguments, 1);
                if (events.hasOwnProperty(type)) {
                    var _events = events[type];
                    for (var i = 0; i < _events.length; i++) {
                        if (false === _events[i].apply(this, args)) {
                            return false;
                        }
                    }
                }
                return true;
            },
            removeEvent: function(type, fn) {
                if (events.hasOwnProperty(type)) {
                    $array.erase(events[type], fn);
                }
                return this;
            },
            addEvents: function(events) {
                for (var type in events)
                    if (events.hasOwnProperty(type)) {
                        this.addEvent(type, events[type]);
                    }
                return this;
            },
            removeEvents: function(type) {
                if (!(type instanceof String)) {
                    for (_type in type)
                        if (type.hasOwnProperty(_type)) {
                            this.removeEvent(_type, type[_type]);
                        }
                    return this;
                }
                if (events.hasOwnProperty(type)) {
                    delete events[type];
                }
                return this;
            }
        };
    };

    Class.Options = (function() {
        function $removeOn(string) {
            return string.replace(/^on([A-Z])/, function(full, first) {
                return first.toLowerCase();
            });
        }
        ;
        function $tryRemoveOn(string) {
            if (/^on([A-Z]\w+)$/.test(string)) {
                return String(RegExp.$1).toLowerCase();
            } else {
                return string;
            }
        }
        ;
        return function(constructor) {
            var options_initialized = true;
            if (constructor.prototype.hasOwnProperty('options')) {
                this.options = $object.clone(constructor.prototype.options);
            } else {
                this.options = {};
            }
            return {
                initialized: function() {
                    var fn = options_initialized;
                    options_initialized = null;
                    if ($fn.is(fn)) {
                        fn.call(this);
                    }
                },
                setOptions: function(options) {
                    if (options) {
                        this.options = $object.merge(options, this.options);
                    }

                    $object.each(this.options, function(value, key) {
                        if (key === 'events') {
                            this.addEvents(value);
                            delete this.options[key];
                        } else {
                            if ($fn.is(value)) {
                                var type = $tryRemoveOn(key);
                                if (key != type) {
                                    this.addEvent(type, value);
                                    delete this.options[key];
                                }
                            }
                        }
                    }, this);

                    var scope_initialized = null;

                    if (this.options.hasOwnProperty('initialized')) {
                        if ($fn.is(this.options['initialized'])) {
                            if (options_initialized) {
                                options_initialized = this.options['initialized'];
                            } else {
                                scope_initialized = this.options['initialized'];
                            }
                            delete this.options['initialized'];
                        }
                    }

                    if (scope_initialized) {
                        scope_initialized.call(this);
                    }
                    return this;
                }
            };
        }
    })();

    var exports = function(properties) {
        var klass = new Class(constructor, properties);
        function constructor() {
            return klass.Construct(this, arguments);
        }
        ;
        return constructor;
    };

    exports.extend = function(constructor, properties) {
        var klass = Class.find(constructor);
        if (!klass) {
            throw new Error('extends klass is invalid');
        }
        klass.extend(properties);
    };

    exports.implements = function(constructor, properties) {
        var klass = Class.find(constructor);
        if (!klass) {
            throw new Error('implements klass is invalid');
        }
        klass.implements.push(properties);
    };

    exports.each = function(self, fn, bind) {
        if ($array.is(self)) {
            return $array.each(self, fn, bind);
        } else {
            return $object.each(self, fn, bind);
        }
    }

    return exports;
})();

<|endoftext|>


<commit_before>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You 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.
 */

/*
 * TODO: Expand these tests
 *
 * In order to test the cast client properly we need to have a way to give it
 * custom remotes. Putting them in ~/.cast/remotes.json isn't an appropriate
 * solution, so we should either make that location configurable or (and I this
 * is probably a good idea one way or another) allow per-project remotes. This
 * way we could test the command for adding remotes as well.
 */

var sys = require('sys');
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var exec = require('child_process').exec;
var async = require('extern/async');
var assert = require('assert');

function getServer() {
  return require('services/http')._serverOnly();
}

(function() {
  var completed = false;
  var cbin = path.normalize(path.join(process.cwd(), '..', 'bin', 'cast'));
  var aroot = path.join(process.cwd(), '.tests');
  var croot = path.join(process.cwd(), '.tests/fooserv');
  var tbp = path.join(process.cwd(), 'data/fooserv.tar.gz');

  var copts = {
    cwd: croot
  };

  function cexec(args, callback) {
    args.unshift(cbin);
    exec(args.join(' '), copts, callback);
  }

  async.series([
    async.apply(exec, 'mkdir -p ' + aroot),

    async.apply(exec, 'tar -C ' + aroot + ' -xf ' + tbp),

    function(callback) {
      cexec(['bundles', 'create', 'v1.0'], function(err, stdout, stderr) {
        assert.ifError(err);
        assert.match(stdout, /validation succeeded/);
        assert.match(stdout, /Bundle created/);
        assert.equal(stderr.length, 0);
        callback();
      });
    },
  ],
  function(err) {
    completed = true;
    assert.ifError(err);
  });

  process.on('exit', function() {
    assert.ok(completed, 'Tests completed');
  });
})();
<commit_msg>integration test 'remote add'<commit_after>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You 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.
 */

/*
 * TODO: Expand these tests
 *
 * In order to test the cast client properly we need to have a way to give it
 * custom remotes. Putting them in ~/.cast/remotes.json isn't an appropriate
 * solution, so we should either make that location configurable or (and I this
 * is probably a good idea one way or another) allow per-project remotes. This
 * way we could test the command for adding remotes as well.
 */

var sys = require('sys');
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var exec = require('child_process').exec;
var async = require('extern/async');
var assert = require('assert');
var port = parseInt((Math.random() * (65500 - 2000) + 2000), 10);

function getServer() {
  return require('services/http')._serverOnly();
}

(function() {
  var completed = false;
  var cbin = path.normalize(path.join(process.cwd(), '..', 'bin', 'cast'));
  var aroot = path.join(process.cwd(), '.tests');
  var croot = path.join(process.cwd(), '.tests/fooserv');
  var tbp = path.join(process.cwd(), 'data/fooserv.tar.gz');
  var server = getServer();
  server.listen(port);

  var copts = {
    cwd: croot
  };

  function cexec(args, doChecks, callback) {
    if (doChecks !== false) {
      callback = doChecks;
      doChecks = true;
    }
    args.unshift(cbin);
    exec(args.join(' '), copts, function(err, stdout, stderr) {
      if (doChecks) {
        assert.ifError(err);
        assert.equal(stderr.length, 0);
      }
      callback(err, stdout, stderr);
    });
  }

  async.series([
    async.apply(exec, 'mkdir -p ' + aroot),

    async.apply(exec, 'tar -C ' + aroot + ' -xf ' + tbp),

    // Add a remote
    function(callback) {
      var addr = 'http://localhost:' + port + '/';
      var args = ['remotes', 'add', '-p', '-y', 'test', addr];
      cexec(args, function(err, stdout, stderr) {
        assert.match(stdout, /Remote added/);
        callback();
      });
    },

    // Create a bundle
    function(callback) {
      cexec(['bundles', 'create', 'v1.0'], function(err, stdout, stderr) {
        assert.match(stdout, /validation succeeded/);
        assert.match(stdout, /Bundle created/);
        callback();
      });
    },
  ],
  function(err) {
    server.close();
    completed = true;
    assert.ifError(err);
  });

  process.on('exit', function() {
    assert.ok(completed, 'Tests completed');
  });
})();
<|endoftext|>


<commit_before>'use strict';
angular.module('core').directive('ngSlide', [
	function() {

        return {
            link: function postLink(scope, element, attrs) {
                scope.$parent.templateElements=scope.$parent.templateElements||{};
                scope.$parent.templateElements[attrs.member]={
                    type:attrs.type||'text',
                    label:attrs.label||attrs.member
                };
                var content = scope.$parent.slide || scope.$parent.currentSlide.content;
                if (scope.$parent.slide) {
                    content = scope.$parent.slide.content || content;
                }
                scope.$parent.$watch(function(){
                    if (!content){
                        return;
                    }

                    if (element[0].tagName=="IMG")
                    {
                        element[0].src=content[attrs.member] || 'modules/slideshows/css/img/default.jpg';
                        return;
                    }

                    element[0].innerHTML=content[attrs.member];
                });
			}
		};
	}
]);
<commit_msg>Tried to add some clarification in ng-slide.<commit_after>'use strict';
angular.module('core').directive('ngSlide', [
	function() {

        return {
            link: function postLink(scope, element, attrs) {
                scope.$parent.templateElements=scope.$parent.templateElements||{};
                scope.$parent.templateElements[attrs.member]={
                    type:attrs.type||'text',
                    label:attrs.label||attrs.member
                };

                var slide = scope.$parent.slide || scope.$parent.currentSlide;

                var content = slide.content;

                scope.$parent.$watch(function(){
                    if (!content){
                        return;
                    }

                    if (element[0].tagName=="IMG")
                    {
                        element[0].src=content[attrs.member] || 'modules/slideshows/css/img/default.jpg';
                        return;
                    }

                    element[0].innerHTML=content[attrs.member];
                });
			}
		};
	}
]);
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * A model to hold verification data. Verification data is imported from
 * the URL's query parameters and is cleaned up to remove whitespace on
 * initialization.
 *
 * Subclasses should override the `defaults` and `validation`
 * hashes. The `validation` hash contains the same keys as the `defaults`
 * whose values are validation functions.
 */

define(function (require, exports, module) {
  'use strict';

  var _ = require('underscore');
  var Backbone = require('backbone');

  var proto = Backbone.Model.prototype;

  var VerificationInfo = Backbone.Model.extend({
    initialize: function (options) {
      proto.initialize.call(this, options);

      // clean up any whitespace that was probably added by an MUA.
      _.each(this.defaults, function (value, key) {
        if (this.has(key)) {
          var cleanedValue = this.get(key).replace(/ /g, '');
          if (cleanedValue) {
            this.set(key, cleanedValue);
          } else {
            this.unset(key);
          }
        }
      }, this);
    },

    defaults: {},
    validation: {},

    /**
     * Check if the model is valid.
     *
     * @method isValid
     * @returns {boolean} `false` if a `validationError` is set, or if
     *   `validate` either throws or returns false. `true` otherwise.
     */
    isValid: function () {
      var isValid;

      if (this.isDamaged()) {
        return false;
      }

      try {
        // super's isValid throws if invalid.
        isValid = proto.isValid.call(this);
      } catch (e) {
        isValid = false;
      }

      return isValid;
    },

    /**
     * Validate the data model using the validators defined
     * in the `validation` hash. Called automatically by
     * `isValid`.
     *
     * @method validate
     * @param {Object} attributes
     */
    validate: function (attributes) {
      _.each(this.validation, function (validator, key) {
        if (! validator(attributes[key])) {
          throw new Error('invalid ' + key);
        }
      });
    },

    /**
     * Mark the verification info as expired.
     * @method markExpired
     */
    markExpired: function () {
      this._isExpired = true;
    },

    /**
     * Check if the verification info is expired
     *
     * @method isExpired
     * @returns {boolean} `true` if expired, `false` otw.
     */
    isExpired: function () {
      return !! this._isExpired;
    },

    markUsed: function () {
      this._isUsed = true;
    },

    isUsed: function () {
      return !! this._isUsed;
    },

    /**
     * Mark the verification info as damaged. This will cause `isValid` to
     * return `false`.
     * @method markDamaged
     */
    markDamaged: function () {
      this._isDamaged = true;
    },

    /**
     * Check if the verification info is damaged
     *
     * @method isDamaged
     * @returns {boolean} `true` if damaged, `false` otw.
     */
    isDamaged: function () {
      return !! this._isDamaged;
    }
  });

  module.exports = VerificationInfo;
});

<commit_msg>refactor(jsdocs): displaying new message for already verified sign-in tokens (#4178) r=vladikoff<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * A model to hold verification data. Verification data is imported from
 * the URL's query parameters and is cleaned up to remove whitespace on
 * initialization.
 *
 * Subclasses should override the `defaults` and `validation`
 * hashes. The `validation` hash contains the same keys as the `defaults`
 * whose values are validation functions.
 */

define(function (require, exports, module) {
  'use strict';

  var _ = require('underscore');
  var Backbone = require('backbone');

  var proto = Backbone.Model.prototype;

  var VerificationInfo = Backbone.Model.extend({
    initialize: function (options) {
      proto.initialize.call(this, options);

      // clean up any whitespace that was probably added by an MUA.
      _.each(this.defaults, function (value, key) {
        if (this.has(key)) {
          var cleanedValue = this.get(key).replace(/ /g, '');
          if (cleanedValue) {
            this.set(key, cleanedValue);
          } else {
            this.unset(key);
          }
        }
      }, this);
    },

    defaults: {},
    validation: {},

    /**
     * Check if the model is valid.
     *
     * @method isValid
     * @returns {boolean} `false` if a `validationError` is set, or if
     *   `validate` either throws or returns false. `true` otherwise.
     */
    isValid: function () {
      var isValid;

      if (this.isDamaged()) {
        return false;
      }

      try {
        // super's isValid throws if invalid.
        isValid = proto.isValid.call(this);
      } catch (e) {
        isValid = false;
      }

      return isValid;
    },

    /**
     * Validate the data model using the validators defined
     * in the `validation` hash. Called automatically by
     * `isValid`.
     *
     * @method validate
     * @param {Object} attributes
     */
    validate: function (attributes) {
      _.each(this.validation, function (validator, key) {
        if (! validator(attributes[key])) {
          throw new Error('invalid ' + key);
        }
      });
    },

    /**
     * Mark the verification info as expired.
     * @method markExpired
     */
    markExpired: function () {
      this._isExpired = true;
    },

    /**
     * Check if the verification info is expired
     *
     * @method isExpired
     * @returns {boolean} `true` if expired, `false` otw.
     */
    isExpired: function () {
      return !! this._isExpired;
    },

    /**
     * Mark the verification info as used.
     * @method markUsed
     */
    markUsed: function () {
      this._isUsed = true;
    },

     /**
     * Check if the verification info is used
     *
     * @method isUsed
     * @returns {boolean} `true` if used, `false` otherwise.
     */
    isUsed: function () {
      return !! this._isUsed;
    },

    /**
     * Mark the verification info as damaged. This will cause `isValid` to
     * return `false`.
     * @method markDamaged
     */
    markDamaged: function () {
      this._isDamaged = true;
    },

    /**
     * Check if the verification info is damaged
     *
     * @method isDamaged
     * @returns {boolean} `true` if damaged, `false` otw.
     */
    isDamaged: function () {
      return !! this._isDamaged;
    }
  });

  module.exports = VerificationInfo;
});

<|endoftext|>