<commit_before>const test = require('ava')
const { equal } = require('..')

test('equal', assert => {
  assert.truthy(equal({ type: 'ReturnStatement' }, { type: 'ReturnStatement' }))
})
<commit_msg>Add specs for the equal method<commit_after>const test = require('ava')
const { equal } = require('..')

const object = {
  key1: 1,
  key2: '2',
  keyNull: null,
  deep: {
    key3: 3
  },
  veryDeep: {
    value: {
      key4: 4
    }
  },
  many: [1, '2']
}

const email = {
  from: 'tester@example.com',
  to: ['myfriend@example.com', 'boss@example.com'],
  subject: 'My Email',
  body: 'Hello,\nI will be on vacation for the rest of the year.\n\nThanks!'
}

test('equal: returns true for two exact nodes', assert => {
  assert.truthy(equal({ type: 'ReturnStatement' }, { type: 'ReturnStatement' }))
})

test('equal: checks simple keys', assert => {
  assert.truthy(equal(object, { key1: 1 }))
  assert.truthy(equal(object, { keyNull: null }))
  assert.falsy(equal(object, { key1: 0 }, true))
  assert.falsy(equal(object, { keyNull: 1 }))
})

test('equal: checks dot-notation keys', assert => {
  assert.truthy(equal(object, { 'deep.key3': 3 }))
  assert.falsy(equal(object, { 'deep.key3': 4 }))
})

test('equal: checks multiple keys', assert => {
  assert.truthy(equal(object, { key1: 1, key2: '2' }))
  assert.falsy(equal(object, { key1: 1, key2: '3' }))
})

test('equal: checks mixed simple and nested keys', assert => {
  assert.truthy(equal(object, { 'deep.key3': 3, key1: 1 }))
  assert.falsy(equal(object, { 'deep.key3': 2, key1: 1 }))
})

test('equal: recurses through object searches', assert => {
  assert.truthy(equal(object, { deep: { key3: 3 } }))
  assert.falsy(equal(object, { deep: { key3: 4 } }))
})

test('equal: handles mixed object and dot-notation', assert => {
  assert.truthy(equal(object, { 'deep.key3': 3, deep: { key3: 3 } }))
  assert.falsy(equal(object, { 'deep.key3': 4, deep: { key3: 3 } }))
  assert.falsy(equal(object, { 'deep.key3': 3, deep: { key3: 4 } }))
})

test('equal: handles the kitchen sink', assert => {
  assert.truthy(equal(object, {
    key1: 1,
    key2: '2',
    keyNull: null,
    deep: { key3: 3 },
    'deep.key3': 3,
    veryDeep: {
      'value.key4': 4,
      value: { key4: 4 }
    },
    'veryDeep.value.key4': 4
  }))
})

test('equal: uses regexes', assert => {
  assert.truthy(equal(object, { key2: /2/ }))
  assert.falsy(equal(object, { key2: /3/ }))
})

test('equal: handles arrays as values', assert => {
  assert.truthy(equal(object, { many: 1 }))
  assert.truthy(equal(object, { many: '2' }))
  assert.falsy(equal(object, { many: 3 }))
})

test('equal: handles arrays as criterias', assert => {
  assert.truthy(equal(object, { many: [1, '2'] }))
  assert.falsy(equal(object, { many: ['1', 2] }))
})

test('equal: compares strings', assert => {
  assert.truthy(equal(email, { from: 'tester@example.com' }))
  assert.falsy(equal(email, { from: 'other@example.com' }))
})

test('equal: checks if a string is inside of an array', assert => {
  assert.truthy(equal(email, { to: 'myfriend@example.com' }))
  assert.truthy(equal(email, { to: 'boss@example.com' }))
  assert.falsy(equal(email, { to: 'other@example.com' }))
})

test('equal: checks arrays', assert => {
  assert.truthy(equal(email, { to: ['myfriend@example.com', 'boss@example.com'] }))
  assert.falsy(equal(email, { to: ['myfriend@example.com', 'you@example.com'] }))
})
<|endoftext|>


<commit_before>import Cube from './Cube';
import CubeStyle from './Cube.less';

/** Parent Render Class */
export default class Render {
  constructor(element) {
    this.grid = 10;
    this.rows = this.grid;
    this.cols = this.grid;
    this.z = this.grid;
    this.time = 0;
    this.angle = 45;
    this.rotation = 65;
    this.cubes = [];
    this.element = element;
    this.perspective = this.createPerspective();
    this.renderLoop = this.renderLoop.bind(this);
    this.generateField = this.generateField.bind(this);
    this.changeAngle = this.changeAngle.bind(this);
    document.addEventListener('keydown', this.changeAngle, false);
    this.generateField();
    this.renderLoop();
  }

  createPerspective() {
    const perspective = document.createElement('div');
    perspective.className = 'container';
    perspective.id = 'container';
    this.element.appendChild(perspective);
    return perspective;
  }

  generateField() {
    // Generate Cube Field //
    let counter = 0;
    const size = parseInt(CubeStyle.size, 10);
    for (let r = 0; r < this.z; r++) {
      for (let y = 0; y < this.rows; y++) {
        for (let x = 0; x < this.cols; x++) {
          const cube = new Cube(counter, (x * size), (y * size), (r * size), this.perspective, 100);
          this.cubes.push(cube);
          counter ++;
        }
      }
    }
  }
  changeAngle(e) {
    console.log(e.keyCode);
    if (e.keyCode === 38) {
      this.rotation += 10;
    }
    if (e.keyCode === 40) {
      this.rotation -= 10;
    }
    if (e.keyCode === 37) {
      this.angle += 10;
    }
    if (e.keyCode === 39) {
      this.angle -= 10;
    }
    document.getElementById('container').setAttribute('style',
      `transform: rotateX(${this.rotation}deg) rotateZ(${this.angle}deg)`);
  }
  renderLoop() {
    // Loop though Simplex Noise //
    let counter = 0;
    const size = parseInt(CubeStyle.size, 10) / 2;
    for (let r = 0; r < this.z; r++) {
      this.time += 1;
      for (let y = 0; y < this.rows; y++) {
        for (let x = 0; x < this.cols; x++) {
          const cube = this.cubes[counter];
          cube.updateCube((x * size), (y * size), (r * size) + this.time);
          counter ++;
        }
      }
    }
    window.requestAnimationFrame(this.renderLoop);
  }
}
<commit_msg>adding rotation with arrow keys<commit_after>import Cube from './Cube';
import CubeStyle from './Cube.less';

/** Parent Render Class */
export default class Render {
  constructor(element) {
    this.grid = 10;
    this.rows = this.grid;
    this.cols = this.grid;
    this.z = this.grid;
    this.time = 0;
    this.angle = 45;
    this.rotation = 65;
    this.cubes = [];
    this.element = element;
    this.perspective = this.createPerspective();
    this.renderLoop = this.renderLoop.bind(this);
    this.generateField = this.generateField.bind(this);
    this.changeAngle = this.changeAngle.bind(this);
    document.addEventListener('keydown', this.changeAngle, false);
    this.generateField();
    this.renderLoop();
  }

  createPerspective() {
    const perspective = document.createElement('div');
    perspective.className = 'container';
    perspective.id = 'container';
    this.element.appendChild(perspective);
    return perspective;
  }

  generateField() {
    // Generate Cube Field //
    let counter = 0;
    const size = parseInt(CubeStyle.size, 10);
    for (let r = 0; r < this.z; r++) {
      for (let y = 0; y < this.rows; y++) {
        for (let x = 0; x < this.cols; x++) {
          const cube = new Cube(counter, (x * size), (y * size), (r * size), this.perspective, 100);
          this.cubes.push(cube);
          counter ++;
        }
      }
    }
  }
  changeAngle(e) {
    if (e.keyCode === 38) {
      this.rotation += 10;
    }
    if (e.keyCode === 40) {
      this.rotation -= 10;
    }
    if (e.keyCode === 37) {
      this.angle += 10;
    }
    if (e.keyCode === 39) {
      this.angle -= 10;
    }
    document.getElementById('container').setAttribute('style',
      `transform: rotateX(${this.rotation}deg) rotateZ(${this.angle}deg)`);
  }
  renderLoop() {
    // Loop though Simplex Noise //
    let counter = 0;
    const size = parseInt(CubeStyle.size, 10) / 2;
    for (let r = 0; r < this.z; r++) {
      this.time += 1;
      for (let y = 0; y < this.rows; y++) {
        for (let x = 0; x < this.cols; x++) {
          const cube = this.cubes[counter];
          cube.updateCube((x * size), (y * size), (r * size) + this.time);
          counter ++;
        }
      }
    }
    window.requestAnimationFrame(this.renderLoop);
  }
}
<|endoftext|>


<commit_before>
var assert = require('assert')
  , ref = require('ref')
  , ffi = require('../')
  , errno = ffi.errno
  , charPtr = ref.refType(ref.types.char)

describe('errno()', function () {

  afterEach(gc)

  it('should be a function', function () {
    assert.equal('function', typeof errno)
  })

  it('should set the errno with out-of-range "strtoul" value', function () {
    var lib = process.platform == 'win32' ? 'msvcrt' : 'libc'
    var strtoul = new ffi.Library(lib, {
      'strtoul': [ 'ulong', [ 'string', charPtr, 'int' ] ]
    }).strtoul
    var before = errno()
    strtoul('1234567890123456789012345678901234567890', null, 0)
    assert.notEqual(before, errno())
    assert.equal(34, errno()) // errno == ERANGE
  })

})
<commit_msg>test: use "string" instead of "char *"<commit_after>
var assert = require('assert')
  , ref = require('ref')
  , ffi = require('../')
  , errno = ffi.errno

describe('errno()', function () {

  afterEach(gc)

  it('should be a function', function () {
    assert.equal('function', typeof errno)
  })

  it('should set the errno with out-of-range "strtoul" value', function () {
    var lib = process.platform == 'win32' ? 'msvcrt' : 'libc'
    var strtoul = new ffi.Library(lib, {
      'strtoul': [ 'ulong', [ 'string', 'string', 'int' ] ]
    }).strtoul
    var before = errno()
    strtoul('1234567890123456789012345678901234567890', null, 0)
    assert.notEqual(before, errno())
    assert.equal(34, errno()) // errno == ERANGE
  })

})
<|endoftext|>


<commit_before>/**
 * Copyright 2015 Longtail Ad Solutions Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 **/

(function () {

    angular
        .module('jwShowcase.core')
        .decorator('$httpBackend', $httpBackendDecorator)
        .service('api', apiService);

    /**
     * @ngdoc service
     * @name jwShowcase.core.api
     *
     * @requires $http
     * @requires $q
     * @requires jwShowcase.config
     */
    apiService.$inject = ['$http', '$q', 'config', 'utils'];
    function apiService ($http, $q, config, utils) {

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} feedId Id of the feed
         * @description
         * Get feed from jw platform
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which will be resolved when the request is completed.
         */
        this.getFeed = function (feedId) {

            // reject when feedId is empty or no string
            if (!angular.isString(feedId) || feedId === '') {
                return $q.reject(new Error('feedId is not given or not a string'));
            }

            return getFeed(config.contentService + '/feed.json?feed_id=' + feedId);
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getSearchFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} searchPlaylist Search playlist
         * @param {string} phrase Search phrase
         * @description
         * Get search feed from jw platform with given search phrase
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getSearchFeed = function (searchPlaylist, phrase) {

            // reject when searchPlaylist is missing
            if (!searchPlaylist) {
                return $q.reject(new Error('searchPlaylist is missing'));
            }

            // reject when feedId is empty or no string
            if (!angular.isString(phrase) || phrase === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            phrase = encodeURIComponent(phrase);

            return getFeed(config.contentService + '/feed.json?feed_id=' + searchPlaylist + '&search=' + phrase);
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getRecommendationsFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} recommendationsPlaylist Recommendations playlist
         * @param {string} mediaId Id of item to get related items
         * @description
         * Get recommendations feed from jw platform with given mediaId
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getRecommendationsFeed = function (recommendationsPlaylist, mediaId) {

            // reject when recommendationsPlaylist is missing
            if (!recommendationsPlaylist) {
                return $q.reject(new Error('recommendationsPlaylist is missing'));
            }

            // reject when mediaId is empty or no string
            if (!angular.isString(mediaId) || mediaId === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            return getFeed(config.contentService + '/feed.json?feed_id=' + recommendationsPlaylist +
                '&related_media_id=' + mediaId);
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getPlayer
         * @methodOf jwShowcase.core.api
         *
         * @param {string} playerId Id of the player
         * @description
         * Get JW Player library from jw platform by including the library in the DOM
         *
         * @resolves
         * @returns {Promise} Promise which be resolved when the library is loaded.
         */
        this.getPlayer = function (playerId) {

            var defer  = $q.defer(),
                script = document.createElement('script');

            script.type = 'text/javascript';

            script.onload = function () {
                defer.resolve();
            };

            script.onerror = function () {
                defer.reject(new Error('Player with id `' + playerId + '` could not been loaded'));
            };

            script.src = config.contentService + '/libraries/' + playerId + '.js';
            document.head.appendChild(script);

            return defer.promise;
        };

        /**
         * Get feed from the given URL.
         *
         * @param {string} url
         * @returns {Promise}
         */
        function getFeed (url) {

            return $http.get(url)
                .then(getFeedCompleted, getFeedFailed);

            function getFeedCompleted (response) {

                var feed = response.data;

                // the search feed can return an empty playlist, so we can show "No results for ..."
                if (feed && 'SEARCH' === feed.kind) {
                    feed.playlist = feed.playlist || [];
                }

                if (!feed || !angular.isArray(feed.playlist)) {
                    return getFeedFailed(response);
                }

                feed.playlist = feed.playlist
                    .map(function (item, index) {

                        if (!item.feedId) {
                            item.feedid = feed.feedid;
                        }

                        item.$key  = index + item.mediaid;
                        item.$slug = utils.slugify(item.title);

                        return item;
                    })
                    .map(fixItemUrls);

                return feed;
            }

            function getFeedFailed (response) {

                var message = 'Failed to get feed from `' + url + '`';

                if (404 === response.status) {
                    message = 'Feed with url `' + url + '` does not exist';
                }

                return $q.reject(new Error(message));
            }
        }

        /**
         * Fix urls in item and sources
         *
         * @param {jwShowcase.core.item} [item]
         * @returns {jwShowcase.core.item}
         */
        function fixItemUrls (item) {

            if (!angular.isObject(item)) {
                return item;
            }

            item.image = fixUrl(item.image);

            if (angular.isArray(item.sources)) {
                item.sources = item.sources.map(function (source) {
                    source.file = fixUrl(source.file);
                    return source;
                });
            }

            if (angular.isArray(item.tracks)) {
                item.tracks = item.tracks.map(function (track) {
                    track.file = fixUrl(track.file);
                    return track;
                });
            }

            return item;
        }

        /**
         * Fix url by replacing '//' with 'https://'
         *
         * @param {string} [url]
         * @returns {*}
         */
        function fixUrl (url) {

            if (angular.isString(url) && 0 === url.indexOf('//')) {
                return 'https://' + url.substr(2);
            }

            return url;
        }
    }

    /**
     * @name jwShowcase.core.feed
     * @type Object
     * @property {string}                   description    Feed description
     * @property {string}                   feedid         Feed id
     * @property {string}                   kind           Feed kind
     * @property {jwShowcase.core.item[]}   playlist       Feed playlist
     * @property {string}                   title          Feed title
     */

    /**
     * @name jwShowcase.core.item
     * @type Object
     * @property {string[]}             custom          Custom parameters
     * @property {string}               description     Video description
     * @property {string}               image           Video poster image
     * @property {string}               link            Link
     * @property {string}               mediaid         Video id
     * @property {string}               feedid          Feed id (set by apiService)
     * @property {string}               $feedid         Original feedid
     * @property {string}               $slug           Title slugified
     * @property {number}               pubdate         Publication date timestamp
     * @property {Object[]}             sources         Video sources
     * @property {string}               tags            Tags
     * @property {string}               title           Video title
     * @property {Object[]}             tracks          Tracks
     * @property {number}               [lastWatched]   Last watched timestamp
     * @property {number}               [progress]      Watch progress percentage
     */

    /**
     * $httpBackendDecorator
     *
     * This decorator will add crossdomain request support for IE9 using XDomainRequest.
     */
    $httpBackendDecorator.$inject = ['$delegate', '$browser'];
    function $httpBackendDecorator ($delegate, $browser) {

        if (!window.XDomainRequest) {
            return $delegate;
        }

        return function (method, url, post, callback, headers, timeout) {

            var location = window.location,
                hostname = location.hostname + (location.port ? ':' + location.port : '');

            url = url.replace('./', 'http://' + hostname + $browser.baseHref());

            if (!/^https?:\/\/([^\?\/]+)/.test(url) || RegExp.$1 === hostname) {
                return $delegate.apply(this, arguments);
            }

            method = method.toUpperCase();
            method = method !== 'GET' ? 'POST' : 'GET';

            //force same protocol
            url = url.replace(/^https?:/, location.protocol);

            doXdrRequest(url, method, timeout, callback);
        };

        /**
         * Do actual XDR request
         *
         * @param {string} url
         * @param {string} method
         * @param {number} timeout
         * @param {function} callback
         */
        function doXdrRequest (url, method, timeout, callback) {

            var xdr        = new window.XDomainRequest();
            xdr.timeout    = timeout || 15000;
            xdr.onprogress = angular.noop;

            xdr.ontimeout = xdr.onerror = function () {
                callback(-1, null, null, '');
            };

            xdr.onload = function () {
                callback(200, xdr.responseText, '', 'OK');
            };

            xdr.open(method, url);
            xdr.send();
        }
    }

}());
<commit_msg>Update to new content service endpoints<commit_after>/**
 * Copyright 2015 Longtail Ad Solutions Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 **/

(function () {

    angular
        .module('jwShowcase.core')
        .decorator('$httpBackend', $httpBackendDecorator)
        .service('api', apiService);

    /**
     * @ngdoc service
     * @name jwShowcase.core.api
     *
     * @requires $http
     * @requires $q
     * @requires jwShowcase.config
     */
    apiService.$inject = ['$http', '$q', 'config', 'utils'];
    function apiService ($http, $q, config, utils) {

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} feedId Id of the feed
         * @description
         * Get feed from jw platform
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which will be resolved when the request is completed.
         */
        this.getFeed = function (feedId) {

            // reject when feedId is empty or no string
            if (!angular.isString(feedId) || feedId === '') {
                return $q.reject(new Error('feedId is not given or not a string'));
            }

            return getFeed(config.contentService + '/v2/playlists/' + feedId);
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getSearchFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} searchPlaylist Search playlist
         * @param {string} phrase Search phrase
         * @description
         * Get search feed from jw platform with given search phrase
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getSearchFeed = function (searchPlaylist, phrase) {

            // reject when searchPlaylist is missing
            if (!searchPlaylist) {
                return $q.reject(new Error('searchPlaylist is missing'));
            }

            // reject when feedId is empty or no string
            if (!angular.isString(phrase) || phrase === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            phrase = encodeURIComponent(phrase);

            return getFeed(config.contentService + '/v2/playlists/' + searchPlaylist + '?search=' + phrase);
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getRecommendationsFeed
         * @methodOf jwShowcase.core.api
         *
         * @param {string} recommendationsPlaylist Recommendations playlist
         * @param {string} mediaId Id of item to get related items
         * @description
         * Get recommendations feed from jw platform with given mediaId
         *
         * @resolves {jwShowcase.core.feed}
         * @returns {Promise} Promise which be resolved when the request is completed.
         */
        this.getRecommendationsFeed = function (recommendationsPlaylist, mediaId) {

            // reject when recommendationsPlaylist is missing
            if (!recommendationsPlaylist) {
                return $q.reject(new Error('recommendationsPlaylist is missing'));
            }

            // reject when mediaId is empty or no string
            if (!angular.isString(mediaId) || mediaId === '') {
                return $q.reject(new Error('search phrase is not given or not a string'));
            }

            return getFeed(config.contentService + '/v2/playlists/' + recommendationsPlaylist +
                '?related_media_id=' + mediaId);
        };

        /**
         * @ngdoc method
         * @name jwShowcase.core.api#getPlayer
         * @methodOf jwShowcase.core.api
         *
         * @param {string} playerId Id of the player
         * @description
         * Get JW Player library from jw platform by including the library in the DOM
         *
         * @resolves
         * @returns {Promise} Promise which be resolved when the library is loaded.
         */
        this.getPlayer = function (playerId) {

            var defer  = $q.defer(),
                script = document.createElement('script');

            script.type = 'text/javascript';

            script.onload = function () {
                defer.resolve();
            };

            script.onerror = function () {
                defer.reject(new Error('Player with id `' + playerId + '` could not been loaded'));
            };

            script.src = config.contentService + '/libraries/' + playerId + '.js';
            document.head.appendChild(script);

            return defer.promise;
        };

        /**
         * Get feed from the given URL.
         *
         * @param {string} url
         * @returns {Promise}
         */
        function getFeed (url) {

            return $http.get(url)
                .then(getFeedCompleted, getFeedFailed);

            function getFeedCompleted (response) {

                var feed = response.data;

                // the search feed can return an empty playlist, so we can show "No results for ..."
                if (feed && 'SEARCH' === feed.kind) {
                    feed.playlist = feed.playlist || [];
                }

                if (!feed || !angular.isArray(feed.playlist)) {
                    return getFeedFailed(response);
                }

                feed.playlist = feed.playlist
                    .map(function (item, index) {

                        if (!item.feedId) {
                            item.feedid = feed.feedid;
                        }

                        item.$key  = index + item.mediaid;
                        item.$slug = utils.slugify(item.title);

                        return item;
                    })
                    .map(fixItemUrls);

                return feed;
            }

            function getFeedFailed (response) {

                var message = 'Failed to get feed from `' + url + '`';

                if (404 === response.status) {
                    message = 'Feed with url `' + url + '` does not exist';
                }

                return $q.reject(new Error(message));
            }
        }

        /**
         * Fix urls in item and sources
         *
         * @param {jwShowcase.core.item} [item]
         * @returns {jwShowcase.core.item}
         */
        function fixItemUrls (item) {

            if (!angular.isObject(item)) {
                return item;
            }

            item.image = fixUrl(item.image);

            if (angular.isArray(item.sources)) {
                item.sources = item.sources.map(function (source) {
                    source.file = fixUrl(source.file);
                    return source;
                });
            }

            if (angular.isArray(item.tracks)) {
                item.tracks = item.tracks.map(function (track) {
                    track.file = fixUrl(track.file);
                    return track;
                });
            }

            return item;
        }

        /**
         * Fix url by replacing '//' with 'https://'
         *
         * @param {string} [url]
         * @returns {*}
         */
        function fixUrl (url) {

            if (angular.isString(url) && 0 === url.indexOf('//')) {
                return 'https://' + url.substr(2);
            }

            return url;
        }
    }

    /**
     * @name jwShowcase.core.feed
     * @type Object
     * @property {string}                   description    Feed description
     * @property {string}                   feedid         Feed id
     * @property {string}                   kind           Feed kind
     * @property {jwShowcase.core.item[]}   playlist       Feed playlist
     * @property {string}                   title          Feed title
     */

    /**
     * @name jwShowcase.core.item
     * @type Object
     * @property {string[]}             custom          Custom parameters
     * @property {string}               description     Video description
     * @property {string}               image           Video poster image
     * @property {string}               link            Link
     * @property {string}               mediaid         Video id
     * @property {string}               feedid          Feed id (set by apiService)
     * @property {string}               $feedid         Original feedid
     * @property {string}               $slug           Title slugified
     * @property {number}               pubdate         Publication date timestamp
     * @property {Object[]}             sources         Video sources
     * @property {string}               tags            Tags
     * @property {string}               title           Video title
     * @property {Object[]}             tracks          Tracks
     * @property {number}               [lastWatched]   Last watched timestamp
     * @property {number}               [progress]      Watch progress percentage
     */

    /**
     * $httpBackendDecorator
     *
     * This decorator will add crossdomain request support for IE9 using XDomainRequest.
     */
    $httpBackendDecorator.$inject = ['$delegate', '$browser'];
    function $httpBackendDecorator ($delegate, $browser) {

        if (!window.XDomainRequest) {
            return $delegate;
        }

        return function (method, url, post, callback, headers, timeout) {

            var location = window.location,
                hostname = location.hostname + (location.port ? ':' + location.port : '');

            url = url.replace('./', 'http://' + hostname + $browser.baseHref());

            if (!/^https?:\/\/([^\?\/]+)/.test(url) || RegExp.$1 === hostname) {
                return $delegate.apply(this, arguments);
            }

            method = method.toUpperCase();
            method = method !== 'GET' ? 'POST' : 'GET';

            //force same protocol
            url = url.replace(/^https?:/, location.protocol);

            doXdrRequest(url, method, timeout, callback);
        };

        /**
         * Do actual XDR request
         *
         * @param {string} url
         * @param {string} method
         * @param {number} timeout
         * @param {function} callback
         */
        function doXdrRequest (url, method, timeout, callback) {

            var xdr        = new window.XDomainRequest();
            xdr.timeout    = timeout || 15000;
            xdr.onprogress = angular.noop;

            xdr.ontimeout = xdr.onerror = function () {
                callback(-1, null, null, '');
            };

            xdr.onload = function () {
                callback(200, xdr.responseText, '', 'OK');
            };

            xdr.open(method, url);
            xdr.send();
        }
    }

}());
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Phoenix Scholars Co. (http://dpq.co.ir)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
'use strict';

angular.module('pluf')

/**
 * @memberof pluf
 * @ngdoc service
 * @name $pluf
 * @description ابزارهای پایه‌ای
 */
.service('$pluf',
		function(PaginatorPage, $q, $http, $httpParamSerializerJQLike) {

			/**
			 *
			 * @memberof $pluf
			 * @param {Object}
			 *            params
			 * @param {PObjectCache}
			 *            cache
			 * @return {function}
			 */
			this.createFind = function(params, _cache) {
				return function(paginatorParameter) {
					if (paginatorParameter) {
						params.params = paginatorParameter.getParameter();
					}
					return $http(params)//
					.then(function(res) {
						var page = new PaginatorPage(res.data);
						var items = [];
						for (var i = 0; i < page.counts; i++) {
							var item = page.items[i];
							items.push(_cache.restor(item.id, item));
						}
						page.items = items;
						return page;
					});
				};
			};

			/**
			 *
			 * @memberof $pluf
			 * @param {Object}
			 *            params
			 * @param {PObjectCache}
			 *            cache
			 * @return {function}
			 */
			this.createGet = function(params, _cache) {
				var urlTemplate = params.url;
				return function(id) {
					if (_cache.contains(id)) {
						var deferred = $q.defer();
						deferred.resolve(_cache.get(id));
						return deferred.promise;
					}
					params.url = urlTemplate.replace('{id}', id);
					return $http(params)//
					.then(function(res) {
						return _cache.restor(res.data.id, res.data);
					});
				};
			};

			/**
			 *
			 */
			this.createUpdate = function(params) {
				params.headers = {
					'Content-Type' : 'application/x-www-form-urlencoded'
				};
				return function(objectData) {
					var scope = this;
					params.data = $httpParamSerializerJQLike(objectData);
					return $http(params)//
					.then(function(res) {
						scope.setData(res.data);
						return scope;
					});
				};
			};

			/**
			 *
			 */
			this.createDelete = function(params) {
				return function() {
					var scope = this;
					return $http(params)//
					.then(function(res) {
						scope.setData(res.data);
						return scope;
					});
				};
			};

			/**
			 *
			 * @memberof $pluf
			 * @param {Object}
			 *            params
			 * @param {PObjectCache}
			 *            cache
			 * @return {function}
			 */
			this.createNew = function(params, _cache) {
				params.headers = {
					'Content-Type' : 'application/x-www-form-urlencoded'
				};
				return function(objectData) {
					params.data = $httpParamSerializerJQLike(objectData);
					return $http(params)//
					.then(function(res) {
						return _cache.restor(res.data.id, res.data);
					});
				};
			};
		});<commit_msg>یه متد برای وراثت پیشنهاد شده.<commit_after>/*
 * Copyright (c) 2015 Phoenix Scholars Co. (http://dpq.co.ir)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
'use strict';

angular.module('pluf')

/**
 * @memberof pluf
 * @ngdoc service
 * @name $pluf
 * @description ابزارهای پایه‌ای
 */
.service('$pluf',
	function(PaginatorPage, $q, $http, $httpParamSerializerJQLike) {

	    /**
	     *
	     * @memberof $pluf
	     * @param {Object}
	     *                params
	     * @param {PObjectCache}
	     *                cache
	     * @return {function}
	     */
	    this.createFind = function(params, _cache) {
		return function(paginatorParameter) {
		    if (paginatorParameter) {
			params.params = paginatorParameter.getParameter();
		    }
		    return $http(params)//
		    .then(function(res) {
			var page = new PaginatorPage(res.data);
			var items = [];
			for (var i = 0; i < page.counts; i++) {
			    var item = page.items[i];
			    items.push(_cache.restor(item.id, item));
			}
			page.items = items;
			return page;
		    });
		};
	    };

	    /**
	     *
	     * @memberof $pluf
	     * @param {Object}
	     *                params
	     * @param {PObjectCache}
	     *                cache
	     * @return {function}
	     */
	    this.createGet = function(params, _cache) {
		var urlTemplate = params.url;
		return function(id) {
		    if (_cache.contains(id)) {
			var deferred = $q.defer();
			deferred.resolve(_cache.get(id));
			return deferred.promise;
		    }
		    params.url = urlTemplate.replace('{id}', id);
		    return $http(params)//
		    .then(function(res) {
			return _cache.restor(res.data.id, res.data);
		    });
		};
	    };

	    /**
	     *
	     */
	    this.createUpdate = function(params) {
		params.headers = {
		    'Content-Type' : 'application/x-www-form-urlencoded'
		};
		return function(objectData) {
		    var scope = this;
		    params.data = $httpParamSerializerJQLike(objectData);
		    return $http(params)//
		    .then(function(res) {
			scope.setData(res.data);
			return scope;
		    });
		};
	    };

	    /**
	     *
	     */
	    this.createDelete = function(params) {
		return function() {
		    var scope = this;
		    return $http(params)//
		    .then(function(res) {
			scope.setData(res.data);
			return scope;
		    });
		};
	    };

	    /**
	     *
	     * @memberof $pluf
	     * @param {Object}
	     *                params
	     * @param {PObjectCache}
	     *                cache
	     * @return {function}
	     */
	    this.createNew = function(params, _cache) {
		params.headers = {
		    'Content-Type' : 'application/x-www-form-urlencoded'
		};
		return function(objectData) {
		    params.data = $httpParamSerializerJQLike(objectData);
		    return $http(params)//
		    .then(function(res) {
			return _cache.restor(res.data.id, res.data);
		    });
		};
	    };

//	    this.inherit = function(object) {
//		function F() {
//		    // Empty object
//		}
//		F.prototype = object.prototype;
//		return new F;
//	    };

	});<|endoftext|>


<commit_before>import React from 'react';
import { stringToSecs, secsToString } from '../utils/parseTime'

class Task extends React.Component {

	constructor(props) {
		super(props);
		this.state={
			title: ''
		}
	}
	updateTime(event) {
		this.setState({time: event.target.value});
	}

	updateTitle(event) {
		this.setState({title: event.target.value});
	}

	saveTask() {
		let title = this.state.title.trim();
		let secs = stringToSecs(this.state.time);
		this.props.onSave(title, secs);
		this.setState({
			title,
			time: secsToString(secs)
		})
	}

	randomInitTime() {
		return secsToString(parseInt(Math.random()*6000));
	}
	render() {
		return (

				<input
					type="text"
					placeholder="Title"
					value={this.state.title}
					onChange={this.updateTitle.bind(this)}
					onBlur={this.saveTask.bind(this)}
				/>
				<input
					type="text"
					placeholder={this.randomInitTime()}
					value={this.state.time}
					onChange={this.updateTime.bind(this)}
					onBlur={this.saveTask.bind(this)}
				/>
				<button onClick={(e) => {
					e.preventDefault();
					this.props.onRemove();
				}}
			>
				X
			</button>

		)
	}
}

export default Task;
<commit_msg>Focus on input field after adding task<commit_after>import React from 'react';
import { stringToSecs, secsToString } from '../utils/parseTime'

class Task extends React.Component {

	titleInput;

	constructor(props) {
		super(props);
		this.state={
			title: ''
		}
	}

	componentDidMount() {
		this.titleInput.focus();
	}

	updateTime(event) {
		this.setState({time: event.target.value});
	}

	updateTitle(event) {
		this.setState({title: event.target.value});
	}

	saveTask() {
		let title = this.state.title.trim();
		let secs = stringToSecs(this.state.time);
		this.props.onSave(title, secs);
		this.setState({
			title,
			time: secsToString(secs)
		})
	}

	randomInitTime() {
		return secsToString(parseInt(Math.random()*6000));
	}
	render() {
		return (

				<input
					type="text"
					placeholder="Title"
					value={this.state.title}
					onChange={this.updateTitle.bind(this)}
					onBlur={this.saveTask.bind(this)}
					ref={(input) => {this.titleInput = input;}}
				/>
				<input
					type="text"
					placeholder={this.randomInitTime()}
					value={this.state.time}
					onChange={this.updateTime.bind(this)}
					onBlur={this.saveTask.bind(this)}
				/>
				<button onClick={(e) => {
					e.preventDefault();
					this.props.onRemove();
				}}
			>
				X
			</button>

		)
	}
}

export default Task;
<|endoftext|>


<commit_before>
import Immutable from 'immutable'
import Base64 from '../serializers/base-64'
import Debug from 'debug'
import React from 'react'
import ReactDOM from 'react-dom'
import TYPES from '../constants/types'
import IS_DEV from '../constants/is-dev'
import Leaf from './leaf'
import Void from './void'
import scrollTo from '../utils/scroll-to'
import warn from '../utils/warn'

/**
 * Debug.
 *
 * @type {Function}
 */

const debug = Debug('slate:node')

/**
 * Node.
 *
 * @type {Component}
 */

class Node extends React.Component {

  /**
   * Property types.
   *
   * @type {Object}
   */

  static propTypes = {
    editor: React.PropTypes.object.isRequired,
    node: React.PropTypes.object.isRequired,
    parent: React.PropTypes.object.isRequired,
    schema: React.PropTypes.object.isRequired,
    state: React.PropTypes.object.isRequired
  }

  /**
   * Constructor.
   *
   * @param {Object} props
   */

  constructor(props) {
    super(props)
    const { node, schema } = props
    this.state = {}
    this.state.Component = node.kind == 'text' ? null : node.getComponent(schema)
  }

  /**
   * Debug.
   *
   * @param {String} message
   * @param {Mixed} ...args
   */

  debug = (message, ...args) => {
    const { node } = this.props
    const { key, kind, type } = node
    let id = kind == 'text' ? `${key} (${kind})` : `${key} (${type})`
    debug(message, `${id}`, ...args)
  }

  /**
   * On receiving new props, update the `Component` renderer.
   *
   * @param {Object} props
   */

  componentWillReceiveProps = (props) => {
    if (props.node.kind == 'text') return
    if (props.node == this.props.node) return
    const Component = props.node.getComponent(props.schema)
    this.setState({ Component })
  }

  /**
   * Should the node update?
   *
   * @param {Object} nextProps
   * @param {Object} state
   * @return {Boolean}
   */

  shouldComponentUpdate = (nextProps) => {
    const { Component } = this.state

    // If the node is rendered with a `Component` that has enabled suppression
    // of update checking, always return true so that it can deal with update
    // checking itself.
    if (Component && Component.suppressShouldComponentUpdate) {
      return true
    }

    // If the node has changed, update.
    if (nextProps.node != this.props.node) {
      if (!IS_DEV || !Immutable.is(nextProps.node, this.props.node)) {
        return true
      } else {
        warn('A new immutable Node instance was encountered with an identical structure to the previous instance. This is usually a mistake and can impact performance. Make sure to preserve immutable references when nothing has changed. The node in question was:', nextProps.node)
      }
    }

    const nextHasEdgeIn = nextProps.state.selection.hasEdgeIn(nextProps.node)

    // If the selection is focused and is inside the node, we need to update so
    // that the selection will be set by one of the <Leaf> components.
    if (
      nextProps.state.isFocused &&
      nextHasEdgeIn
    ) {
      return true
    }

    const hasEdgeIn = this.props.state.selection.hasEdgeIn(nextProps.node)
    // If the selection is blurred but was previously focused (or vice versa) inside the node,
    // we need to update to ensure the selection gets updated by re-rendering.
    if (
      this.props.state.isFocused != nextProps.state.isFocused &&
      (
          hasEdgeIn || nextHasEdgeIn
      )
    ) {
      return true
    }

    // For block and inline nodes, which can have custom renderers, we need to
    // include another check for whether the previous selection had an edge in
    // the node, to allow for intuitive selection-based rendering.
    if (
      this.props.node.kind != 'text' &&
      hasEdgeIn != nextHasEdgeIn
    ) {
      return true
    }

    // For text nodes, which can have custom decorations, we need to check to
    // see if the block has changed, which has caused the decorations to change.
    if (nextProps.node.kind == 'text' && nextProps.schema.hasDecorators) {
      const { node, schema, state } = nextProps

      const { document } = state
      const decorators = document.getDescendantDecorators(node.key, schema)
      const ranges = node.getRanges(decorators)

      const prevNode = this.props.node
      const prevSchema = this.props.schema
      const prevDocument = this.props.state.document
      const prevDecorators = prevDocument.getDescendantDecorators(prevNode.key, prevSchema)
      const prevRanges = prevNode.getRanges(prevDecorators)

      if (!ranges.equals(prevRanges)) {
        return true
      }
    }

    // Otherwise, don't update.
    return false
  }

  /**
   * On mount, update the scroll position.
   */

  componentDidMount = () => {
    this.updateScroll()
  }

  /**
   * After update, update the scroll position if the node's content changed.
   *
   * @param {Object} prevProps
   * @param {Object} prevState
   */

  componentDidUpdate = (prevProps, prevState) => {
    if (this.props.node != prevProps.node) this.updateScroll()
  }

  /**
   * Update the scroll position after a change as occured if this is a leaf
   * block and it has the selection's ending edge. This ensures that scrolling
   * matches native `contenteditable` behavior even for cases where the edit is
   * not applied natively, like when enter is pressed.
   */

  updateScroll = () => {
    const { node, state } = this.props
    const { selection } = state

    // If this isn't a block, or it's a wrapping block, abort.
    if (node.kind != 'block') return
    if (node.nodes.first().kind == 'block') return

    // If the selection is blurred, or this block doesn't contain it, abort.
    if (selection.isBlurred) return
    if (!selection.hasEndIn(node)) return

    const el = ReactDOM.findDOMNode(this)
    scrollTo(el)

    this.debug('updateScroll', el)
  }

  /**
   * On drag start, add a serialized representation of the node to the data.
   *
   * @param {Event} e
   */

  onDragStart = (e) => {
    const { node } = this.props
    const encoded = Base64.serializeNode(node)
    const data = e.nativeEvent.dataTransfer
    data.setData(TYPES.NODE, encoded)

    this.debug('onDragStart', e)
  }

  /**
   * Render.
   *
   * @return {Element}
   */

  render = () => {
    this.debug('render')

    const { node } = this.props
    return node.kind == 'text'
      ? this.renderText()
      : this.renderElement()
  }

  /**
   * Render a `child` node.
   *
   * @param {Node} child
   * @return {Element}
   */

  renderNode = (child) => {
    return (
      <Node
        key={child.key}
        node={child}
        parent={this.props.node}
        editor={this.props.editor}
        schema={this.props.schema}
        state={this.props.state}
      />
    )
  }

  /**
   * Render an element `node`.
   *
   * @return {Element}
   */

  renderElement = () => {
    const { editor, node, parent, state } = this.props
    const { Component } = this.state
    const children = node.nodes
      .map(child => this.renderNode(child))
      .toArray()

    // Attributes that the developer must to mix into the element in their
    // custom node renderer component.
    const attributes = {
      'data-key': node.key,
      'onDragStart': this.onDragStart
    }

    // If it's a block node with inline children, add the proper `dir` attribute
    // for text direction.
    if (node.kind == 'block' && node.nodes.first().kind != 'block') {
      const direction = node.getTextDirection()
      if (direction == 'rtl') attributes.dir = 'rtl'
    }

    const element = (
      <Component
        attributes={attributes}
        key={node.key}
        editor={editor}
        parent={parent}
        node={node}
        state={state}
      >
        {children}
      </Component>
    )

    return node.isVoid
      ? <Void {...this.props}>{element}</Void>
      : element
  }

  /**
   * Render a text node.
   *
   * @return {Element}
   */

  renderText = () => {
    const { node, schema, state } = this.props
    const { document } = state
    const decorators = schema.hasDecorators ? document.getDescendantDecorators(node.key, schema) : []
    const ranges = node.getRanges(decorators)
    let offset = 0

    const leaves = ranges.map((range, i) => {
      const leaf = this.renderLeaf(ranges, range, i, offset)
      offset += range.text.length
      return leaf
    })

    return (

        {leaves}

    )
  }

  /**
   * Render a single leaf node given a `range` and `offset`.
   *
   * @param {List<Range>} ranges
   * @param {Range} range
   * @param {Number} index
   * @param {Number} offset
   * @return {Element} leaf
   */

  renderLeaf = (ranges, range, index, offset) => {
    const { node, parent, schema, state } = this.props
    const text = range.text
    const marks = range.marks

    return (
      <Leaf
        key={`${node.key}-${index}`}
        index={index}
        marks={marks}
        node={node}
        parent={parent}
        ranges={ranges}
        schema={schema}
        state={state}
        text={text}
      />
    )
  }

}

/**
 * Export.
 *
 * @type {Component}
 */

export default Node
<commit_msg>remove Immutable.is check in node shouldComponentUpdate<commit_after>
import Immutable from 'immutable'
import Base64 from '../serializers/base-64'
import Debug from 'debug'
import React from 'react'
import ReactDOM from 'react-dom'
import TYPES from '../constants/types'
import IS_DEV from '../constants/is-dev'
import Leaf from './leaf'
import Void from './void'
import scrollTo from '../utils/scroll-to'
import warn from '../utils/warn'

/**
 * Debug.
 *
 * @type {Function}
 */

const debug = Debug('slate:node')

/**
 * Node.
 *
 * @type {Component}
 */

class Node extends React.Component {

  /**
   * Property types.
   *
   * @type {Object}
   */

  static propTypes = {
    editor: React.PropTypes.object.isRequired,
    node: React.PropTypes.object.isRequired,
    parent: React.PropTypes.object.isRequired,
    schema: React.PropTypes.object.isRequired,
    state: React.PropTypes.object.isRequired
  }

  /**
   * Constructor.
   *
   * @param {Object} props
   */

  constructor(props) {
    super(props)
    const { node, schema } = props
    this.state = {}
    this.state.Component = node.kind == 'text' ? null : node.getComponent(schema)
  }

  /**
   * Debug.
   *
   * @param {String} message
   * @param {Mixed} ...args
   */

  debug = (message, ...args) => {
    const { node } = this.props
    const { key, kind, type } = node
    let id = kind == 'text' ? `${key} (${kind})` : `${key} (${type})`
    debug(message, `${id}`, ...args)
  }

  /**
   * On receiving new props, update the `Component` renderer.
   *
   * @param {Object} props
   */

  componentWillReceiveProps = (props) => {
    if (props.node.kind == 'text') return
    if (props.node == this.props.node) return
    const Component = props.node.getComponent(props.schema)
    this.setState({ Component })
  }

  /**
   * Should the node update?
   *
   * @param {Object} nextProps
   * @param {Object} state
   * @return {Boolean}
   */

  shouldComponentUpdate = (nextProps) => {
    const { Component } = this.state

    // If the node is rendered with a `Component` that has enabled suppression
    // of update checking, always return true so that it can deal with update
    // checking itself.
    if (Component && Component.suppressShouldComponentUpdate) {
      return true
    }

    // If the node has changed, update. PERF: There are certain cases where the
    // node instance will have changed, but it's properties will be exactly the
    // same (copy-paste, delete backwards, etc.) in which case this will not
    // catch a potentially avoidable re-render. But those cases should be much
    // rarer than trying to deeply evaluate any changes in all nodes.
    if (nextProps.node != this.props.node) {
      return true
    }

    const nextHasEdgeIn = nextProps.state.selection.hasEdgeIn(nextProps.node)

    // If the selection is focused and is inside the node, we need to update so
    // that the selection will be set by one of the <Leaf> components.
    if (
      nextProps.state.isFocused &&
      nextHasEdgeIn
    ) {
      return true
    }

    const hasEdgeIn = this.props.state.selection.hasEdgeIn(nextProps.node)
    // If the selection is blurred but was previously focused (or vice versa) inside the node,
    // we need to update to ensure the selection gets updated by re-rendering.
    if (
      this.props.state.isFocused != nextProps.state.isFocused &&
      (
          hasEdgeIn || nextHasEdgeIn
      )
    ) {
      return true
    }

    // For block and inline nodes, which can have custom renderers, we need to
    // include another check for whether the previous selection had an edge in
    // the node, to allow for intuitive selection-based rendering.
    if (
      this.props.node.kind != 'text' &&
      hasEdgeIn != nextHasEdgeIn
    ) {
      return true
    }

    // For text nodes, which can have custom decorations, we need to check to
    // see if the block has changed, which has caused the decorations to change.
    if (nextProps.node.kind == 'text' && nextProps.schema.hasDecorators) {
      const { node, schema, state } = nextProps

      const { document } = state
      const decorators = document.getDescendantDecorators(node.key, schema)
      const ranges = node.getRanges(decorators)

      const prevNode = this.props.node
      const prevSchema = this.props.schema
      const prevDocument = this.props.state.document
      const prevDecorators = prevDocument.getDescendantDecorators(prevNode.key, prevSchema)
      const prevRanges = prevNode.getRanges(prevDecorators)

      if (!ranges.equals(prevRanges)) {
        return true
      }
    }

    // Otherwise, don't update.
    return false
  }

  /**
   * On mount, update the scroll position.
   */

  componentDidMount = () => {
    this.updateScroll()
  }

  /**
   * After update, update the scroll position if the node's content changed.
   *
   * @param {Object} prevProps
   * @param {Object} prevState
   */

  componentDidUpdate = (prevProps, prevState) => {
    if (this.props.node != prevProps.node) this.updateScroll()
  }

  /**
   * Update the scroll position after a change as occured if this is a leaf
   * block and it has the selection's ending edge. This ensures that scrolling
   * matches native `contenteditable` behavior even for cases where the edit is
   * not applied natively, like when enter is pressed.
   */

  updateScroll = () => {
    const { node, state } = this.props
    const { selection } = state

    // If this isn't a block, or it's a wrapping block, abort.
    if (node.kind != 'block') return
    if (node.nodes.first().kind == 'block') return

    // If the selection is blurred, or this block doesn't contain it, abort.
    if (selection.isBlurred) return
    if (!selection.hasEndIn(node)) return

    const el = ReactDOM.findDOMNode(this)
    scrollTo(el)

    this.debug('updateScroll', el)
  }

  /**
   * On drag start, add a serialized representation of the node to the data.
   *
   * @param {Event} e
   */

  onDragStart = (e) => {
    const { node } = this.props
    const encoded = Base64.serializeNode(node)
    const data = e.nativeEvent.dataTransfer
    data.setData(TYPES.NODE, encoded)

    this.debug('onDragStart', e)
  }

  /**
   * Render.
   *
   * @return {Element}
   */

  render = () => {
    this.debug('render')

    const { node } = this.props
    return node.kind == 'text'
      ? this.renderText()
      : this.renderElement()
  }

  /**
   * Render a `child` node.
   *
   * @param {Node} child
   * @return {Element}
   */

  renderNode = (child) => {
    return (
      <Node
        key={child.key}
        node={child}
        parent={this.props.node}
        editor={this.props.editor}
        schema={this.props.schema}
        state={this.props.state}
      />
    )
  }

  /**
   * Render an element `node`.
   *
   * @return {Element}
   */

  renderElement = () => {
    const { editor, node, parent, state } = this.props
    const { Component } = this.state
    const children = node.nodes
      .map(child => this.renderNode(child))
      .toArray()

    // Attributes that the developer must to mix into the element in their
    // custom node renderer component.
    const attributes = {
      'data-key': node.key,
      'onDragStart': this.onDragStart
    }

    // If it's a block node with inline children, add the proper `dir` attribute
    // for text direction.
    if (node.kind == 'block' && node.nodes.first().kind != 'block') {
      const direction = node.getTextDirection()
      if (direction == 'rtl') attributes.dir = 'rtl'
    }

    const element = (
      <Component
        attributes={attributes}
        key={node.key}
        editor={editor}
        parent={parent}
        node={node}
        state={state}
      >
        {children}
      </Component>
    )

    return node.isVoid
      ? <Void {...this.props}>{element}</Void>
      : element
  }

  /**
   * Render a text node.
   *
   * @return {Element}
   */

  renderText = () => {
    const { node, schema, state } = this.props
    const { document } = state
    const decorators = schema.hasDecorators ? document.getDescendantDecorators(node.key, schema) : []
    const ranges = node.getRanges(decorators)
    let offset = 0

    const leaves = ranges.map((range, i) => {
      const leaf = this.renderLeaf(ranges, range, i, offset)
      offset += range.text.length
      return leaf
    })

    return (

        {leaves}

    )
  }

  /**
   * Render a single leaf node given a `range` and `offset`.
   *
   * @param {List<Range>} ranges
   * @param {Range} range
   * @param {Number} index
   * @param {Number} offset
   * @return {Element} leaf
   */

  renderLeaf = (ranges, range, index, offset) => {
    const { node, parent, schema, state } = this.props
    const text = range.text
    const marks = range.marks

    return (
      <Leaf
        key={`${node.key}-${index}`}
        index={index}
        marks={marks}
        node={node}
        parent={parent}
        ranges={ranges}
        schema={schema}
        state={state}
        text={text}
      />
    )
  }

}

/**
 * Export.
 *
 * @type {Component}
 */

export default Node
<|endoftext|>


<commit_before>import axios from 'axios';

import * as types from '../mutation-types';
import URLS from '../../urls';

const state = {};

const getters = {};

const mutations = {};

const actions = {};

export default {
  state,
  getters,
  actions,
  mutations
}<commit_msg>Offerings getter<commit_after>import axios from 'axios';
import _ from 'lodash';

import * as types from '../mutation-types';
import URLS from '../../urls';

const state = {
  event: {},
  offerings: []
};

const getters = {
  offerings(state) {
    return {
      eventId: event,
      offerings: offerings
    };
  }
};

const mutations = {
  [types.GET_OFFERINGS] (state, event) {
    state.offerings = _.map(event.offerings, 'details');
    state.event = event.id;
  }
};

const actions = {
  getOfferings({ commit }, eventId) {
    return new Promise((resolve, reject) => {
      axios.get(URLS.EVENTS_URL + '?id=' + eventId)
        .then((response) => {
          console.log('Received event', response.data[0]);
          commit(types.GET_OFFERINGS, response.data[0]);
          resolve();
        })
        .catch(() => {
          console.log('Failed to get event offerings');
          reject();
        });
    });
  }
};

export default {
  state,
  getters,
  actions,
  mutations
}<|endoftext|>


<commit_before>/*global Scroller*/
require('list-view/list_view_mixin');
require('list-view/list_view_helper');

var max = Math.max;
function updateScrollerDimensions(){
  this.scroller.setDimensions(this.get('width'), this.get('height'), this.get('width'), this.get('totalHeight'));
}

/**
  VirtualListView

  @class VirtualListView
  @namespace Ember
*/
Ember.VirtualListView = Ember.ContainerView.extend(Ember.ListViewMixin, {
  css: {
    position: 'relative',
    overflow: 'hidden'
  },
  init: function(){
    this._super();
    this.setupScroller();
  },
  applyTransform: Ember.ListViewHelper.applyTransform,
  setupScroller: function(){
    var _this = this;
    this.scroller = new Scroller(function(left, top, zoom) {
      if (_this.listContainerElement) {
        _this.applyTransform(_this.listContainerElement, {x: 0, y: -top});
        _this._scrollContentTo(max(0, top));
      }
    }, {
      scrollingX: false
    });
    updateScrollerDimensions.call(this);
    this.scroller.setDimensions(this.get('width'), this.get('height'), this.get('width'), this.get('totalHeight'));
  },
  scrollerDimensionsNeedToChange: Ember.observer(function() {
    Ember.run.once(this, updateScrollerDimensions);
  }, 'width', 'height', 'elementWidth'),
  didInsertElement: function() {
    var self, listContainerElement, el;

    self = this;
    this.listContainerElement = el = this.$('> .ember-list-container')[0];

    self._touchStart = function(e) { self.touchStart(e); };
    self._touchMove =  function(e) { self.touchMove(e);  };
    self._touchEnd =   function(e) { self.touchEnd(e);   };
    self._mouseDown =  function(e) { self.mouseDown(e);  };
    self._mouseMove =  function(e) { self.mouseMove(e);  };
    self._mouseUp =    function(e) { self.mouseUp(e);    };
    self._mouseWheel = function(e) { self.mouseWheel(e); };

    el.addEventListener('touchstart', this._touchStart);
    el.addEventListener('touchmove',  this._touchMove);
    el.addEventListener('touchend',   this._touchEnd);
    el.addEventListener('mousedown',  this._mouseDown);
    el.addEventListener('mousemove',  this._mouseMove);
    el.addEventListener('mouseup',    this._mouseUp);
    el.addEventListener('mousewheel', this._mouseWheel);
  },

  willDestroyElement: function() {
    var el = this.listContainerElement;
    el.removeEventListener('touchstart', this._touchStart);
    el.removeEventListener('touchmove',  this._touchMove);
    el.removeEventListener('touchend',   this._touchEnd);
    el.removeEventListener('mousedown',  this._mouseDown);
    el.removeEventListener('mousemove',  this._mouseMove);
    el.removeEventListener('mouseup',    this._mouseUp);
    el.removeEventListener('mousewheel', this._mouseWheel);
  },
  mouseWheel: function(e){
    var inverted = e.webkitDirectionInvertedFromDevice,
        delta = e.wheelDeltaY * (inverted ? 0.5 : -0.5),
        candidatePosition = this.scroller.__scrollTop + delta;
    if ((candidatePosition >= 0) && (candidatePosition <= this.scroller.__maxScrollTop)) {
      //TODO: this.showScrollbar()
      this.scroller.scrollBy(0, delta, true);
    }
    return false;
  },

  beginScroll: function(touches, timeStamp) {
    this.scroller.doTouchStart(touches, timeStamp);
  },
  continueScroll: function(touches, timeStamp) {
    this.scroller.doTouchMove(touches, timeStamp);
  },
  endScroll: function(timeStamp) {
    this.scroller.doTouchEnd(timeStamp);
  },

  touchStart: function(e){
    this.beginScroll(e.touches, e.timeStamp);
    return false;
  },
  touchMove: function(e){
    this.continueScroll(e.touches, e.timeStamp);
    return false;
  },
  touchEnd: function(e){
    this.endScroll(e.timeStamp);
    return false;
  },
  mouseDown: function(e){
    this.beginScroll([e], e.timeStamp);
    return false;
  },
  mouseMove: function(e){
    this.continueScroll([e], e.timeStamp);
    return false;
  },
  mouseUp: function(e){
    this.endScroll(e.timeStamp);
    return false;
  },
  scrollTo: function(y, animate) {
    if (animate === undefined) {
      animate = true;
    }
    this.scroller.scrollTo(0, y, animate, 1);
  }
});
<commit_msg>Android sometimes sends touchstart and touchmove with events that have no touches property<commit_after>/*global Scroller*/
require('list-view/list_view_mixin');
require('list-view/list_view_helper');

var max = Math.max;
function updateScrollerDimensions(){
  this.scroller.setDimensions(this.get('width'), this.get('height'), this.get('width'), this.get('totalHeight'));
}

/**
  VirtualListView

  @class VirtualListView
  @namespace Ember
*/
Ember.VirtualListView = Ember.ContainerView.extend(Ember.ListViewMixin, {
  css: {
    position: 'relative',
    overflow: 'hidden'
  },
  init: function(){
    this._super();
    this.setupScroller();
  },
  applyTransform: Ember.ListViewHelper.applyTransform,
  setupScroller: function(){
    var _this = this;
    this.scroller = new Scroller(function(left, top, zoom) {
      if (_this.listContainerElement) {
        _this.applyTransform(_this.listContainerElement, {x: 0, y: -top});
        _this._scrollContentTo(max(0, top));
      }
    }, {
      scrollingX: false
    });
    updateScrollerDimensions.call(this);
    this.scroller.setDimensions(this.get('width'), this.get('height'), this.get('width'), this.get('totalHeight'));
  },
  scrollerDimensionsNeedToChange: Ember.observer(function() {
    Ember.run.once(this, updateScrollerDimensions);
  }, 'width', 'height', 'elementWidth'),
  didInsertElement: function() {
    var self, listContainerElement, el;

    self = this;
    this.listContainerElement = el = this.$('> .ember-list-container')[0];

    self._touchStart = function(e) { self.touchStart(e); };
    self._touchMove =  function(e) { self.touchMove(e);  };
    self._touchEnd =   function(e) { self.touchEnd(e);   };
    self._mouseDown =  function(e) { self.mouseDown(e);  };
    self._mouseMove =  function(e) { self.mouseMove(e);  };
    self._mouseUp =    function(e) { self.mouseUp(e);    };
    self._mouseWheel = function(e) { self.mouseWheel(e); };

    el.addEventListener('touchstart', this._touchStart);
    el.addEventListener('touchmove',  this._touchMove);
    el.addEventListener('touchend',   this._touchEnd);
    el.addEventListener('mousedown',  this._mouseDown);
    el.addEventListener('mousemove',  this._mouseMove);
    el.addEventListener('mouseup',    this._mouseUp);
    el.addEventListener('mousewheel', this._mouseWheel);
  },

  willDestroyElement: function() {
    var el = this.listContainerElement;
    el.removeEventListener('touchstart', this._touchStart);
    el.removeEventListener('touchmove',  this._touchMove);
    el.removeEventListener('touchend',   this._touchEnd);
    el.removeEventListener('mousedown',  this._mouseDown);
    el.removeEventListener('mousemove',  this._mouseMove);
    el.removeEventListener('mouseup',    this._mouseUp);
    el.removeEventListener('mousewheel', this._mouseWheel);
  },
  mouseWheel: function(e){
    var inverted = e.webkitDirectionInvertedFromDevice,
        delta = e.wheelDeltaY * (inverted ? 0.5 : -0.5),
        candidatePosition = this.scroller.__scrollTop + delta;
    if ((candidatePosition >= 0) && (candidatePosition <= this.scroller.__maxScrollTop)) {
      //TODO: this.showScrollbar()
      this.scroller.scrollBy(0, delta, true);
    }
    return false;
  },

  beginScroll: function(touches, timeStamp) {
    this.scroller.doTouchStart(touches, timeStamp);
  },
  continueScroll: function(touches, timeStamp) {
    this.scroller.doTouchMove(touches, timeStamp);
  },
  endScroll: function(timeStamp) {
    this.scroller.doTouchEnd(timeStamp);
  },

  touchStart: function(e){
    if (e.touches) {
      this.beginScroll(e.touches, e.timeStamp);
    }
    return false;
  },
  touchMove: function(e){
    if (e.touches) {
      this.continueScroll(e.touches, e.timeStamp);
    }
    return false;
  },
  touchEnd: function(e){
    this.endScroll(e.timeStamp);
    return false;
  },
  mouseDown: function(e){
    this.beginScroll([e], e.timeStamp);
    return false;
  },
  mouseMove: function(e){
    this.continueScroll([e], e.timeStamp);
    return false;
  },
  mouseUp: function(e){
    this.endScroll(e.timeStamp);
    return false;
  },
  scrollTo: function(y, animate) {
    if (animate === undefined) {
      animate = true;
    }
    this.scroller.scrollTo(0, y, animate, 1);
  }
});
<|endoftext|>


<commit_before>frappe.pages['dashboard'].on_page_load = function(wrapper) {

	let page = frappe.ui.make_app_page({
		parent: wrapper,
		title: __("Dashboard"),
		single_column: true
	})

	frappe.dashboard = new Dashboard(wrapper)
	$(wrapper).bind('show', function() {
		frappe.dashboard.show()
	})

}

class Dashboard {
	constructor(wrapper) {
		this.wrapper = $(wrapper)
		$(`

`).appendTo(this.wrapper.find(".page-content").empty())
		this.container = this.wrapper.find(".dashboard-graph")
		this.page = wrapper.page
	}

	show() {
		this.route = frappe.get_route()
		const current_dashboard_name = this.route.slice(-1)[0]

		if(this.dashboard_name !== current_dashboard_name) {
			this.dashboard_name = current_dashboard_name
			this.page.set_title(this.dashboard_name)
			this.refresh()
		}
	}

	refresh() {
		this.get_dashboard_doc().then((doc) => {
			this.dashboard_doc = doc
			this.charts = this.dashboard_doc.charts

			this.charts.map((chart) => {
				this.fetch_and_render_chart(chart);
			})
		})
	}

	fetch_and_render_chart(chart) {
		this.fetch_chart(chart).then((data) => this.render_chart(chart, data))
	}

	get_dashboard_doc() {
		return frappe.model.with_doc('Dashboard', this.dashboard_name)
	}

	fetch_chart(chart) {
		return frappe.xcall(
			"frappe.core.page.dashboard.dashboard.get_data",
			{
				dashboard_name: chart.method_path,
				filters: JSON.parse(chart.filters_json),
			}
		)
	}

	render_chart(chart, data) {
		chart.filter_fields = JSON.parse(chart.filter_fields || '[]')
		chart.filters_json = JSON.parse(chart.filters_json || '{}')

		const column_width_map = {
			"Half": "6",
			"Full": "12",
		};
		let columns = column_width_map[chart.width];
		let actions = [
			{
				label: __("More"),
				action: "more",
				handler() {
					const d = new frappe.ui.Dialog({
						title: __('Set Filters'),
						fields: chart.filter_fields
					})
					d.set_values(chart.filters_json)
					d.show();
				}
			}
		]

		let chart_action = $(`

			 <button class="btn btn-default btn-xs"></button>

				${actions.map(action => `<li><a data-action="${action.action}">${action.label}</a></li>`).join('')}

		`);

		chart_action.find("a[data-action]").each((i, o) => {
			const action = o.dataset.action
			$(o).click(actions.find(a => a.action === action))
		})

		let chart_container = $(`

`);
		chart_action.prependTo(chart_container)
		chart_container.appendTo(this.container);

		const chart_type_map = {
			"Line": "line",
			"Bar": "bar",
		};
		let chart_args = {
			title: chart.chart_name,
			data: {
				datasets: data.datasets,
				labels: data.labels,
			},
			type: chart_type_map[chart.type],
			colors: [chart.color || "light-blue"],
		};
		new Chart(chart_container.find(".chart-wrapper")[0], chart_args);
	}
}<commit_msg>refactor(dashboard): Rename More to Set Filters<commit_after>frappe.pages['dashboard'].on_page_load = function(wrapper) {

	let page = frappe.ui.make_app_page({
		parent: wrapper,
		title: __("Dashboard"),
		single_column: true
	})

	frappe.dashboard = new Dashboard(wrapper)
	$(wrapper).bind('show', function() {
		frappe.dashboard.show()
	})

}

class Dashboard {
	constructor(wrapper) {
		this.wrapper = $(wrapper)
		$(`

`).appendTo(this.wrapper.find(".page-content").empty())
		this.container = this.wrapper.find(".dashboard-graph")
		this.page = wrapper.page
	}

	show() {
		this.route = frappe.get_route()
		const current_dashboard_name = this.route.slice(-1)[0]

		if(this.dashboard_name !== current_dashboard_name) {
			this.dashboard_name = current_dashboard_name
			this.page.set_title(this.dashboard_name)
			this.refresh()
		}
	}

	refresh() {
		this.get_dashboard_doc().then((doc) => {
			this.dashboard_doc = doc
			this.charts = this.dashboard_doc.charts

			this.charts.map((chart) => {
				this.fetch_and_render_chart(chart);
			})
		})
	}

	fetch_and_render_chart(chart) {
		this.fetch_chart(chart).then((data) => this.render_chart(chart, data))
	}

	get_dashboard_doc() {
		return frappe.model.with_doc('Dashboard', this.dashboard_name)
	}

	fetch_chart(chart) {
		return frappe.xcall(
			"frappe.core.page.dashboard.dashboard.get_data",
			{
				dashboard_name: chart.method_path,
				filters: JSON.parse(chart.filters_json),
			}
		)
	}

	render_chart(chart, data) {
		chart.filter_fields = JSON.parse(chart.filter_fields || '[]')
		chart.filters_json = JSON.parse(chart.filters_json || '{}')

		const column_width_map = {
			"Half": "6",
			"Full": "12",
		};
		let columns = column_width_map[chart.width];
		let actions = [
			{
				label: __("Set Filters"),
				action: "set-filters",
				handler() {
					const d = new frappe.ui.Dialog({
						title: __('Set Filters'),
						fields: chart.filter_fields
					})
					d.set_values(chart.filters_json)
					d.show();
				}
			}
		]

		let chart_action = $(`

			 <button class="btn btn-default btn-xs"></button>

				${actions.map(action => `<li><a data-action="${action.action}">${action.label}</a></li>`).join('')}

		`);

		chart_action.find("a[data-action]").each((i, o) => {
			const action = o.dataset.action
			$(o).click(actions.find(a => a.action === action))
		})

		let chart_container = $(`

`);
		chart_action.prependTo(chart_container)
		chart_container.appendTo(this.container);

		const chart_type_map = {
			"Line": "line",
			"Bar": "bar",
		};
		let chart_args = {
			title: chart.chart_name,
			data: {
				datasets: data.datasets,
				labels: data.labels,
			},
			type: chart_type_map[chart.type],
			colors: [chart.color || "light-blue"],
		};
		new Chart(chart_container.find(".chart-wrapper")[0], chart_args);
	}
}<|endoftext|>


<commit_before>/***
 This will reset the preferences that have been removed completely from the ghacks user.js.

 Last updated: 21-April-2020

 For instructions see:
 https://github.com/ghacksuserjs/ghacks-user.js/wiki/3.1-Resetting-Inactive-Prefs-[Scripts]
***/

(function() {
  let ops = [
    /* removed in ghacks user.js v52-57 */
    /* 52-alpha */
    'browser.search.reset.enabled',
    'browser.search.reset.whitelist',
    /* 54-alpha */
    'browser.migrate.automigrate.enabled',
    'services.sync.enabled',
    'webextensions.storage.sync.enabled',
    'webextensions.storage.sync.serverURL',
    /* 55-alpha */
    'dom.keyboardevent.dispatch_during_composition', // default is false anyway
    'dom.vr.oculus.enabled', // covered by dom.vr.enabled
    'dom.vr.openvr.enabled', // ditto
    'dom.vr.osvr.enabled', // ditto
    'extensions.pocket.api', // covered by extensions.pocket.enabled
    'extensions.pocket.oAuthConsumerKey', // ditto
    'extensions.pocket.site', // ditto
    /* 56-alpha: none */
    /* 57-alpha */
    'geo.wifi.xhr.timeout', // covered by geo.enabled
    'browser.search.geoip.timeout', // ditto
    'media.webspeech.recognition.enable', // default is false anyway
    'gfx.layerscope.enabled', // default is false anyway
    /* 58-alpha */
    //  excluding these e10 settings
       // 'browser.tabs.remote.autostart',
       // 'browser.tabs.remote.autostart.2',
       // 'browser.tabs.remote.force-enable',
       // 'browser.tabs.remote.separateFileUriProcess',
       // 'extensions.e10sBlocksEnabling',
       // 'extensions.webextensions.remote',
       // 'dom.ipc.processCount',
       // 'dom.ipc.shims.enabledWarnings',
       // 'dom.ipc.processCount.extension',
       // 'dom.ipc.processCount.file',
       // 'security.sandbox.content.level',
       // 'dom.ipc.plugins.sandbox-level.default',
       // 'dom.ipc.plugins.sandbox-level.flash',
       // 'security.sandbox.logging.enabled',
    'dom.presentation.controller.enabled',
    'dom.presentation.discoverable',
    'dom.presentation.discovery.enabled',
    'dom.presentation.enabled',
    'dom.presentation.receiver.enabled',
    'dom.presentation.session_transport.data_channel.enable',
    /* 59-alpha */
    'browser.stopReloadAnimation.enabled',
    'browser.tabs.insertRelatedAfterCurrent',
    'browser.tabs.loadDivertedInBackground',
    'browser.tabs.loadInBackground',
    'browser.tabs.selectOwnerOnClose',
    'browser.urlbar.clickSelectsAll',
    'browser.urlbar.doubleClickSelectsAll',
    'media.flac.enabled',
    'media.mediasource.enabled',
    'media.mediasource.mp4.enabled',
    'media.mediasource.webm.audio.enabled',
    'media.mediasource.webm.enabled',
    'media.mp4.enabled',
    'media.ogg.enabled',
    'media.ogg.flac.enabled',
    'media.opus.enabled',
    'media.raw.enabled',
    'media.wave.enabled',
    'media.webm.enabled',
    'media.wmf.amd.vp9.enabled',
    'media.wmf.enabled',
    'media.wmf.vp9.enabled',
    'ui.submenuDelay',
    /* 60-beta - these were all at default anyway */
    'device.storage.enabled',
    'general.useragent.compatMode.firefox',
    'network.dns.blockDotOnion',
    'network.stricttransportsecurity.preloadlist',
    'security.block_script_with_wrong_mime',
    'security.fileuri.strict_origin_policy',
    'security.sri.enable',
    /* 61-beta */
    'browser.laterrun.enabled',
    'browser.offline-apps.notify',
    'browser.rights.3.shown',
    'browser.slowStartup.maxSamples',
    'browser.slowStartup.notificationDisabled',
    'browser.slowStartup.samples',
    'browser.storageManager.enabled',
    'dom.allow_scripts_to_close_windows',
    'dom.disable_window_flip',
    'network.http.fast-fallback-to-IPv4',
    'offline-apps.quota.warn',
    'services.blocklist.signing.enforced',
    /* 62-beta */
    'browser.urlbar.autoFill.typed',
    'security.tls.version.fallback-limit',
    /* 63-beta */
    'extensions.webextensions.keepStorageOnUninstall',
    'extensions.webextensions.keepUuidOnUninstall',
    'privacy.trackingprotection.ui.enabled',
    /* 64-beta */
    'browser.eme.ui.enabled',
    'browser.sessionstore.max_windows_undo',
    'network.auth.subresource-img-cross-origin-http-auth-allow',
    'media.peerconnection.ice.tcp',
    'media.peerconnection.identity.enabled',
    'media.peerconnection.identity.timeout',
    'media.peerconnection.turn.disable',
    'media.peerconnection.use_document_iceservers',
    'media.peerconnection.video.enabled',
    'media.navigator.video.enabled',
    /* 65-beta */
    'browser.contentblocking.enabled',
    'browser.urlbar.maxHistoricalSearchSuggestions',
    /* 67-beta */
    'app.update.service.enabled',
    'app.update.silent',
    'app.update.staging.enabled',
    'browser.cache.disk.capacity',
    'browser.cache.disk.smart_size.enabled',
    'browser.cache.disk.smart_size.first_run',
    'browser.cache.offline.insecure.enable',
    'browser.safebrowsing.downloads.remote.url',
    'browser.safebrowsing.provider.google.reportMalwareMistakeURL',
    'browser.safebrowsing.provider.google.reportPhishMistakeURL',
    'browser.safebrowsing.provider.google.reportURL',
    'browser.safebrowsing.provider.google4.dataSharing.enabled',
    'browser.safebrowsing.provider.google4.dataSharingURL',
    'browser.safebrowsing.provider.google4.reportMalwareMistakeURL',
    'browser.safebrowsing.provider.google4.reportPhishMistakeURL',
    'browser.safebrowsing.provider.google4.reportURL',
    'browser.safebrowsing.reportPhishURL',
    'browser.sessionhistory.max_total_viewers',
    'browser.urlbar.filter.javascript',
    'canvas.capturestream.enabled',
    'dom.imagecapture.enabled',
    'dom.popup_maximum',
    'gfx.offscreencanvas.enabled',
    'javascript.options.shared_memory',
    'media.gmp-gmpopenh264.autoupdate',
    'media.gmp-gmpopenh264.enabled',
    'media.gmp-manager.updateEnabled',
    'media.gmp-manager.url',
    'media.gmp-manager.url.override',
    'media.gmp.trial-create.enabled',
    'media.gmp-widevinecdm.autoupdate',
    'network.cookie.leave-secure-alone',
    'network.cookie.same-site.enabled',
    'network.dnsCacheEntries',
    'network.dnsCacheExpiration',
    'network.proxy.autoconfig_url.include_path',
    'pdfjs.enableWebGL',
    'plugin.default.state',
    'plugin.defaultXpi.state',
    'plugin.scan.plid.all',
    'security.data_uri.block_toplevel_data_uri_navigations',
    'security.insecure_field_warning.contextual.enabled',
    'security.insecure_password.ui.enabled',
    'signon.autofillForms.http',
    'signon.storeWhenAutocompleteOff',
    'xpinstall.whitelist.required',
    /* 67-beta: Blocklist, SB & TP cleanup: these were all inactive */
    'browser.safebrowsing.downloads.remote.block_dangerous',
    'browser.safebrowsing.downloads.remote.block_dangerous_host',
    'browser.safebrowsing.blockedURIs.enabled',
    'browser.safebrowsing.provider.google.gethashURL',
    'browser.safebrowsing.provider.google.updateURL',
    'browser.safebrowsing.provider.google4.gethashURL',
    'browser.safebrowsing.provider.google4.updateURL',
    'browser.safebrowsing.provider.mozilla.gethashURL',
    'browser.safebrowsing.provider.mozilla.updateURL',
    'browser.urlbar.userMadeSearchSuggestionsChoice',
    'privacy.trackingprotection.annotate_channels',
    'privacy.trackingprotection.enabled',
    'privacy.trackingprotection.lower_network_priority',
    'privacy.trackingprotection.pbmode.enabled',
    'services.blocklist.addons.collection',
    'services.blocklist.gfx.collection',
    'services.blocklist.onecrl.collection',
    'services.blocklist.plugins.collection',
    'services.blocklist.update_enabled',
    'urlclassifier.trackingTable',
    /* 68-beta */
    'dom.forms.datetime',
    'font.blacklist.underline_offset',
    'font.name.monospace.x-unicode',
    'font.name.monospace.x-western',
    'font.name.sans-serif.x-unicode',
    'font.name.sans-serif.x-western',
    'font.name.serif.x-unicode',
    'font.name.serif.x-western',
    'layout.css.font-loading-api.enabled',
    'toolkit.telemetry.cachedClientID',
    /* 69-beta */
    'plugin.sessionPermissionNow.intervalInMinutes',
    /* 70-beta */
    'browser.cache.disk_cache_ssl',
    'browser.sessionhistory.max_entries',
    'dom.push.connection.enabled',
    'dom.push.serverURL',
    'extensions.getAddons.discovery.api_url',
    'extensions.htmlaboutaddons.discover.enabled',
    'extensions.webservice.discoverURL',
    'intl.locale.requested',
    'intl.regional_prefs.use_os_locales',
    'privacy.usercontext.about_newtab_segregation.enabled',
    'security.insecure_connection_icon.pbmode.enabled',
    'security.insecure_connection_text.pbmode.enabled',
    'webgl.dxgl.enabled',
    /* 71-beta */
    'media.block-autoplay-until-in-foreground',
    'middlemouse.paste',
    /* 75-beta */
    'browser.search.geoip.url',
    'browser.search.region',
    /* reset parrot: check your open about:config after running the script */
    '_user.js.parrot'
  ]

  if("undefined" === typeof(Services)) {
    alert("about:config needs to be the active tab!");
    return;
  }

  let c = 0;
  for (let i = 0, len = ops.length; i < len; i++) {
    if (Services.prefs.prefHasUserValue(ops[i])) {
      Services.prefs.clearUserPref(ops[i]);
      if (!Services.prefs.prefHasUserValue(ops[i])) {
        console.log("reset", ops[i]);
        c++;
      } else { console.log("failed to reset", ops[i]); }
    }
  }

  focus();

  let d = (c==1) ? " pref" : " prefs";
  if (c > 0) {
    alert("successfully reset " + c + d + "\n\nfor details check the Browser Console (Ctrl+Shift+J)");
  } else { alert("nothing to reset"); }

})();
<commit_msg>browser.urlbar.usepreloadedtopurls.enabled<commit_after>/***
 This will reset the preferences that have been removed completely from the ghacks user.js.

 Last updated: 28-July-2020

 For instructions see:
 https://github.com/ghacksuserjs/ghacks-user.js/wiki/3.1-Resetting-Inactive-Prefs-[Scripts]
***/

(function() {
  let ops = [
    /* removed in ghacks user.js v52-57 */
    /* 52-alpha */
    'browser.search.reset.enabled',
    'browser.search.reset.whitelist',
    /* 54-alpha */
    'browser.migrate.automigrate.enabled',
    'services.sync.enabled',
    'webextensions.storage.sync.enabled',
    'webextensions.storage.sync.serverURL',
    /* 55-alpha */
    'dom.keyboardevent.dispatch_during_composition', // default is false anyway
    'dom.vr.oculus.enabled', // covered by dom.vr.enabled
    'dom.vr.openvr.enabled', // ditto
    'dom.vr.osvr.enabled', // ditto
    'extensions.pocket.api', // covered by extensions.pocket.enabled
    'extensions.pocket.oAuthConsumerKey', // ditto
    'extensions.pocket.site', // ditto
    /* 56-alpha: none */
    /* 57-alpha */
    'geo.wifi.xhr.timeout', // covered by geo.enabled
    'browser.search.geoip.timeout', // ditto
    'media.webspeech.recognition.enable', // default is false anyway
    'gfx.layerscope.enabled', // default is false anyway
    /* 58-alpha */
    //  excluding these e10 settings
       // 'browser.tabs.remote.autostart',
       // 'browser.tabs.remote.autostart.2',
       // 'browser.tabs.remote.force-enable',
       // 'browser.tabs.remote.separateFileUriProcess',
       // 'extensions.e10sBlocksEnabling',
       // 'extensions.webextensions.remote',
       // 'dom.ipc.processCount',
       // 'dom.ipc.shims.enabledWarnings',
       // 'dom.ipc.processCount.extension',
       // 'dom.ipc.processCount.file',
       // 'security.sandbox.content.level',
       // 'dom.ipc.plugins.sandbox-level.default',
       // 'dom.ipc.plugins.sandbox-level.flash',
       // 'security.sandbox.logging.enabled',
    'dom.presentation.controller.enabled',
    'dom.presentation.discoverable',
    'dom.presentation.discovery.enabled',
    'dom.presentation.enabled',
    'dom.presentation.receiver.enabled',
    'dom.presentation.session_transport.data_channel.enable',
    /* 59-alpha */
    'browser.stopReloadAnimation.enabled',
    'browser.tabs.insertRelatedAfterCurrent',
    'browser.tabs.loadDivertedInBackground',
    'browser.tabs.loadInBackground',
    'browser.tabs.selectOwnerOnClose',
    'browser.urlbar.clickSelectsAll',
    'browser.urlbar.doubleClickSelectsAll',
    'media.flac.enabled',
    'media.mediasource.enabled',
    'media.mediasource.mp4.enabled',
    'media.mediasource.webm.audio.enabled',
    'media.mediasource.webm.enabled',
    'media.mp4.enabled',
    'media.ogg.enabled',
    'media.ogg.flac.enabled',
    'media.opus.enabled',
    'media.raw.enabled',
    'media.wave.enabled',
    'media.webm.enabled',
    'media.wmf.amd.vp9.enabled',
    'media.wmf.enabled',
    'media.wmf.vp9.enabled',
    'ui.submenuDelay',
    /* 60-beta - these were all at default anyway */
    'device.storage.enabled',
    'general.useragent.compatMode.firefox',
    'network.dns.blockDotOnion',
    'network.stricttransportsecurity.preloadlist',
    'security.block_script_with_wrong_mime',
    'security.fileuri.strict_origin_policy',
    'security.sri.enable',
    /* 61-beta */
    'browser.laterrun.enabled',
    'browser.offline-apps.notify',
    'browser.rights.3.shown',
    'browser.slowStartup.maxSamples',
    'browser.slowStartup.notificationDisabled',
    'browser.slowStartup.samples',
    'browser.storageManager.enabled',
    'dom.allow_scripts_to_close_windows',
    'dom.disable_window_flip',
    'network.http.fast-fallback-to-IPv4',
    'offline-apps.quota.warn',
    'services.blocklist.signing.enforced',
    /* 62-beta */
    'browser.urlbar.autoFill.typed',
    'security.tls.version.fallback-limit',
    /* 63-beta */
    'extensions.webextensions.keepStorageOnUninstall',
    'extensions.webextensions.keepUuidOnUninstall',
    'privacy.trackingprotection.ui.enabled',
    /* 64-beta */
    'browser.eme.ui.enabled',
    'browser.sessionstore.max_windows_undo',
    'network.auth.subresource-img-cross-origin-http-auth-allow',
    'media.peerconnection.ice.tcp',
    'media.peerconnection.identity.enabled',
    'media.peerconnection.identity.timeout',
    'media.peerconnection.turn.disable',
    'media.peerconnection.use_document_iceservers',
    'media.peerconnection.video.enabled',
    'media.navigator.video.enabled',
    /* 65-beta */
    'browser.contentblocking.enabled',
    'browser.urlbar.maxHistoricalSearchSuggestions',
    /* 67-beta */
    'app.update.service.enabled',
    'app.update.silent',
    'app.update.staging.enabled',
    'browser.cache.disk.capacity',
    'browser.cache.disk.smart_size.enabled',
    'browser.cache.disk.smart_size.first_run',
    'browser.cache.offline.insecure.enable',
    'browser.safebrowsing.downloads.remote.url',
    'browser.safebrowsing.provider.google.reportMalwareMistakeURL',
    'browser.safebrowsing.provider.google.reportPhishMistakeURL',
    'browser.safebrowsing.provider.google.reportURL',
    'browser.safebrowsing.provider.google4.dataSharing.enabled',
    'browser.safebrowsing.provider.google4.dataSharingURL',
    'browser.safebrowsing.provider.google4.reportMalwareMistakeURL',
    'browser.safebrowsing.provider.google4.reportPhishMistakeURL',
    'browser.safebrowsing.provider.google4.reportURL',
    'browser.safebrowsing.reportPhishURL',
    'browser.sessionhistory.max_total_viewers',
    'browser.urlbar.filter.javascript',
    'canvas.capturestream.enabled',
    'dom.imagecapture.enabled',
    'dom.popup_maximum',
    'gfx.offscreencanvas.enabled',
    'javascript.options.shared_memory',
    'media.gmp-gmpopenh264.autoupdate',
    'media.gmp-gmpopenh264.enabled',
    'media.gmp-manager.updateEnabled',
    'media.gmp-manager.url',
    'media.gmp-manager.url.override',
    'media.gmp.trial-create.enabled',
    'media.gmp-widevinecdm.autoupdate',
    'network.cookie.leave-secure-alone',
    'network.cookie.same-site.enabled',
    'network.dnsCacheEntries',
    'network.dnsCacheExpiration',
    'network.proxy.autoconfig_url.include_path',
    'pdfjs.enableWebGL',
    'plugin.default.state',
    'plugin.defaultXpi.state',
    'plugin.scan.plid.all',
    'security.data_uri.block_toplevel_data_uri_navigations',
    'security.insecure_field_warning.contextual.enabled',
    'security.insecure_password.ui.enabled',
    'signon.autofillForms.http',
    'signon.storeWhenAutocompleteOff',
    'xpinstall.whitelist.required',
    /* 67-beta: Blocklist, SB & TP cleanup: these were all inactive */
    'browser.safebrowsing.downloads.remote.block_dangerous',
    'browser.safebrowsing.downloads.remote.block_dangerous_host',
    'browser.safebrowsing.blockedURIs.enabled',
    'browser.safebrowsing.provider.google.gethashURL',
    'browser.safebrowsing.provider.google.updateURL',
    'browser.safebrowsing.provider.google4.gethashURL',
    'browser.safebrowsing.provider.google4.updateURL',
    'browser.safebrowsing.provider.mozilla.gethashURL',
    'browser.safebrowsing.provider.mozilla.updateURL',
    'browser.urlbar.userMadeSearchSuggestionsChoice',
    'privacy.trackingprotection.annotate_channels',
    'privacy.trackingprotection.enabled',
    'privacy.trackingprotection.lower_network_priority',
    'privacy.trackingprotection.pbmode.enabled',
    'services.blocklist.addons.collection',
    'services.blocklist.gfx.collection',
    'services.blocklist.onecrl.collection',
    'services.blocklist.plugins.collection',
    'services.blocklist.update_enabled',
    'urlclassifier.trackingTable',
    /* 68-beta */
    'dom.forms.datetime',
    'font.blacklist.underline_offset',
    'font.name.monospace.x-unicode',
    'font.name.monospace.x-western',
    'font.name.sans-serif.x-unicode',
    'font.name.sans-serif.x-western',
    'font.name.serif.x-unicode',
    'font.name.serif.x-western',
    'layout.css.font-loading-api.enabled',
    'toolkit.telemetry.cachedClientID',
    /* 69-beta */
    'plugin.sessionPermissionNow.intervalInMinutes',
    /* 70-beta */
    'browser.cache.disk_cache_ssl',
    'browser.sessionhistory.max_entries',
    'dom.push.connection.enabled',
    'dom.push.serverURL',
    'extensions.getAddons.discovery.api_url',
    'extensions.htmlaboutaddons.discover.enabled',
    'extensions.webservice.discoverURL',
    'intl.locale.requested',
    'intl.regional_prefs.use_os_locales',
    'privacy.usercontext.about_newtab_segregation.enabled',
    'security.insecure_connection_icon.pbmode.enabled',
    'security.insecure_connection_text.pbmode.enabled',
    'webgl.dxgl.enabled',
    /* 71-beta */
    'media.block-autoplay-until-in-foreground',
    'middlemouse.paste',
    /* 75-beta */
    'browser.search.geoip.url',
    'browser.search.region',
    /* 79-beta */
    'browser.urlbar.usepreloadedtopurls.enabled',
    /* reset parrot: check your open about:config after running the script */
    '_user.js.parrot'
  ]

  if("undefined" === typeof(Services)) {
    alert("about:config needs to be the active tab!");
    return;
  }

  let c = 0;
  for (let i = 0, len = ops.length; i < len; i++) {
    if (Services.prefs.prefHasUserValue(ops[i])) {
      Services.prefs.clearUserPref(ops[i]);
      if (!Services.prefs.prefHasUserValue(ops[i])) {
        console.log("reset", ops[i]);
        c++;
      } else { console.log("failed to reset", ops[i]); }
    }
  }

  focus();

  let d = (c==1) ? " pref" : " prefs";
  if (c > 0) {
    alert("successfully reset " + c + d + "\n\nfor details check the Browser Console (Ctrl+Shift+J)");
  } else { alert("nothing to reset"); }

})();
<|endoftext|>


<commit_before>// create table view data object
var data = [
	{title:'Tatoba', hasChild:true, combo:'tatoba'},
	{title:'Gatakiriba', hasChild:true, combo:'gatakiriba'},
	{title:'Latorartar', hasChild:true, combo:'latorartar'},
	{title:'Sagohzo', hasChild:true, combo:'sagohzo'},
	{title:'Shauta', hasChild:true, combo:'shauta'},
	{title:'Tajadol', hasChild:true, combo:'tajadol'},
	{title:'Putotyra', hasChild:true, combo:'putotyra'},
];

// create table view
var tableview = Titanium.UI.createTableView({
	data:data
});

// create table view event listener
tableview.addEventListener('click', function(e)
{
	var win = Titanium.UI.createWindow({
		url:'../windows/combo_change.js',
		title:e.rowData.title,
        combo:e.rowData.combo,
        barColor:'black',
	});
	Titanium.UI.currentTab.open(win,{animated:true});
});

// add table view to the window
Titanium.UI.currentWindow.add(tableview);
<commit_msg>コンボデータにシンボルカラー設定を追加した。<commit_after>// create table view data object
var data = [
	{title:'Tatoba', hasChild:true, combo:'tatoba', color:{1:'red', 2:'yellow', 3:'green'}},
	{title:'Gatakiriba', hasChild:true, combo:'gatakiriba', color:{1:'green', 2:'green', 3:'green'}},
	{title:'Latorartar', hasChild:true, combo:'latorartar', color:{1:'yellow', 2:'yellow', 3:'yellow'}},
	{title:'Sagohzo', hasChild:true, combo:'sagohzo', color:{1:'silver', 2:'silver', 3:'silver'}},
	{title:'Shauta', hasChild:true, combo:'shauta', color:{1:'blue', 2:'blue', 3:'blue'}},
	{title:'Tajadol', hasChild:true, combo:'tajadol', color:{1:'red', 2:'red', 3:'red'}},
	{title:'Putotyra', hasChild:true, combo:'putotyra', color:{1:'purple', 2:'purple', 3:'purple'}},
];

// create table view
var tableview = Titanium.UI.createTableView({
	data:data
});

// create table view event listener
tableview.addEventListener('click', function(e)
{
	var win = Titanium.UI.createWindow({
		url:'../windows/combo_change.js',
		title:e.rowData.title,
        combo:e.rowData.combo,
        color:e.rowData.color,
        barColor:'black',
	});
	Titanium.UI.currentTab.open(win,{animated:true});
});

// add table view to the window
Titanium.UI.currentWindow.add(tableview);
<|endoftext|>