<commit_before>import { Tracker }     from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';

const helpers = {
  isObject(obj) {
    if (this.isArray(obj) || this.isFunction(obj)) {
      return false;
    }
    return obj === Object(obj);
  },
  isArray(obj) {
    return Array.isArray(obj);
  },
  isFunction(obj) {
    return typeof obj === 'function' || false;
  },
  isEmpty(obj) {
    if (this.isDate(obj)) {
      return false;
    }
    if (this.isObject(obj)) {
      return !Object.keys(obj).length;
    }
    if (this.isArray(obj) || this.isString(obj)) {
      return !obj.length;
    }
    return false;
  },
  has(_obj, path) {
    let obj = _obj;
    if (!this.isObject(obj)) {
      return false;
    }
    if (!this.isArray(path)) {
      return this.isObject(obj) && Object.prototype.hasOwnProperty.call(obj, path);
    }

    const length = path.length;
    for (let i = 0; i < length; i++) {
      if (!Object.prototype.hasOwnProperty.call(obj, path[i])) {
        return false;
      }
      obj = obj[path[i]];
    }
    return !!length;
  }
};

const _helpers = ['String', 'Date'];
for (let i = 0; i < _helpers.length; i++) {
  helpers['is' + _helpers[i]] = function (obj) {
    return Object.prototype.toString.call(obj) === '[object ' + _helpers[i] + ']';
  };
}

export class FlowRouterTitle {
  constructor(router) {
    const self = this;
    this.router = router;
    let hardCodedTitle = document.title || null;
    this.title = new ReactiveVar(hardCodedTitle);
    this.title.set = function(newValue) {
      if (this.curValue !== newValue) {
        if (!hardCodedTitle) {
          hardCodedTitle = document.title;
        }
        setTimeout(() => {
          document.title = newValue;
        }, 0);
        this.curValue = newValue;
      }
    };

    const computations = [];
    this._reactivate = (titleFunc, _context, context, _arguments, cb) => {
      const comp = Tracker.autorun(titleFunc.bind(_context, ..._arguments));
      const compute = () => {
        let result = titleFunc.apply(_context, _arguments);
        if (cb) {
          result = cb(result);
        }

        if (helpers.isString(result)) {
          self.title.set(result);
          if (context && context.context && helpers.isObject(context.context)) {
            context.context.title = result;
          }
        }
      };
      comp.onInvalidate(compute);
      compute();
      computations.push(comp);
    };

    this.titleExitHandler = () => {
      for (let i = computations.length - 1; i >= 0; i--) {
        computations[i].stop();
        computations.splice(i, 1);
      }
    };

    this.titleHandler = (context, redirect, stop, data) => {
      let _title;
      let defaultTitle = null;
      const _context = Object.assign({}, context, { query: context.queryParams });
      const _arguments = [context.params, context.queryParams, data];
      let _groupTitlePrefix = this._getParentPrefix(((this.router._current && this.router._current.route && this.router._current.route.group) ? this.router._current.route.group : void 0), _context, _arguments);

      if (this.router.globals.length) {
        for (let j = 0; j < this.router.globals.length; j++) {
          if (helpers.isObject(this.router.globals[j]) && helpers.has(this.router.globals[j], 'title')) {
            defaultTitle = this.router.globals[j].title;
            break;
          }
        }
      }

      if (context.route && context.route.group && context.route.group.options) {
        let _routeTitle = (context.route.options && context.route.options.title) ? context.route.options.title : void 0;
        let _groupTitle = (context.route.group.options && context.route.group.options.title) ? context.route.group.options.title : void 0;

        const applyRouteTitle = (__routeTitle) => {
          if (helpers.isFunction(__routeTitle)) {
            return __routeTitle.apply(_context, _arguments);
          } else if (helpers.isString(__routeTitle)) {
            return __routeTitle;
          }
          return '';
        };

        const applyGroupTitle = (__groupTitle) => {
          let __title = '';
          const __routeTitle = applyRouteTitle(_routeTitle);
          if (!__routeTitle) {
            __title = _groupTitlePrefix + applyRouteTitle(__groupTitle || defaultTitle || hardCodedTitle);
          } else if (__routeTitle && _groupTitlePrefix) {
            __title = _groupTitlePrefix + __routeTitle;
          } else {
            __title = _groupTitlePrefix + applyRouteTitle(__routeTitle || defaultTitle || hardCodedTitle);
          }
          return __title;
        };

        if (helpers.isFunction(_routeTitle)) {
          this._reactivate(_routeTitle, _context, context, _arguments, applyGroupTitle);
          return;
        }

        if (helpers.isFunction(_groupTitle)) {
          this._reactivate(_groupTitle, _context, context, _arguments, applyGroupTitle);
          return;
        }
        _title = applyGroupTitle(_groupTitle);
      } else {
        _title = (context.route.options && context.route.options.title) ? context.route.options.title : (defaultTitle || hardCodedTitle);
        if (helpers.isFunction(_title)) {
          this._reactivate(_title, _context, context, _arguments);
        }
      }

      if (helpers.isString(_title)) {
        self.title.set(_title);
        if (context && context.context && helpers.isObject(context.context)) {
          context.context.title = _title;
        }
      }
    };

    this.router.triggers.enter([this.titleHandler]);
    this.router.triggers.exit([this.titleExitHandler]);
    const _orig = this.router._notfoundRoute;
    this.router._notfoundRoute = function() {
      const _context = {
        route: {
          options: {}
        }
      };
      _context.route.options.title = (self.router.notFound && self.router.notFound.title) ? self.router.notFound.title : void 0;

      if (!helpers.isEmpty(self.router._current)) {
        self.titleHandler(Object.assign({}, self.router._current, _context));
      } else {
        self.titleHandler(_context);
      }
      _orig.apply(this, arguments);
    };
  }

  set(str) {
    if (helpers.isString(str)) {
      this.title.set(str);
      return true;
    }
    return false;
  }

  _getParentPrefix(group, _context, _arguments, i = 0) {
    let prefix = '';
    i++;
    if (group) {
      if (group.options && group.options.titlePrefix) {
        if ((_context.route.options && _context.route.options.title && i === 1) || i !== 1) {
          let _gt = group.options.titlePrefix;
          if (helpers.isFunction(_gt)) {
            _gt = _gt.apply(_context, _arguments);
          }
          prefix += _gt;
        }
      }

      if (group.parent) {
        prefix = this._getParentPrefix(group.parent, _context, _arguments, i) + prefix;
      }
    }
    return prefix;
  }
}
<commit_msg>possible fix<commit_after>import { Tracker }     from 'meteor/tracker';
import { ReactiveVar } from 'meteor/reactive-var';

const helpers = {
  isObject(obj) {
    if (this.isArray(obj) || this.isFunction(obj)) {
      return false;
    }
    return obj === Object(obj);
  },
  isArray(obj) {
    return Array.isArray(obj);
  },
  isFunction(obj) {
    return typeof obj === 'function' || false;
  },
  isEmpty(obj) {
    if (this.isDate(obj)) {
      return false;
    }
    if (this.isObject(obj)) {
      return !Object.keys(obj).length;
    }
    if (this.isArray(obj) || this.isString(obj)) {
      return !obj.length;
    }
    return false;
  },
  has(_obj, path) {
    let obj = _obj;
    if (!this.isObject(obj)) {
      return false;
    }
    if (!this.isArray(path)) {
      return this.isObject(obj) && Object.prototype.hasOwnProperty.call(obj, path);
    }

    const length = path.length;
    for (let i = 0; i < length; i++) {
      if (!Object.prototype.hasOwnProperty.call(obj, path[i])) {
        return false;
      }
      obj = obj[path[i]];
    }
    return !!length;
  }
};

const _helpers = ['String', 'Date'];
for (let i = 0; i < _helpers.length; i++) {
  helpers['is' + _helpers[i]] = function (obj) {
    return Object.prototype.toString.call(obj) === '[object ' + _helpers[i] + ']';
  };
}

export class FlowRouterTitle {
  constructor(router) {
    const self = this;
    this.router = router;
    let hardCodedTitle = document.title || null;
    this.title = new ReactiveVar(hardCodedTitle);
    this.title.set = function(newValue) {
      if (this.curValue !== newValue) {
        if (!hardCodedTitle) {
          hardCodedTitle = document.title;
        }
        setTimeout(() => {
          document.title = newValue;
        }, 0);
        this.curValue = newValue;
      }
    };

    const computations = [];
    this._reactivate = (titleFunc, _context, context, _arguments, cb) => {
      const compute = () => {
        let result = titleFunc.apply(_context, _arguments);
        if (cb) {
          result = cb(result);
        }

        if (helpers.isString(result)) {
          self.title.set(result);
          if (context && context.context && helpers.isObject(context.context)) {
            context.context.title = result;
          }
        }
      };

      const comp = Tracker.autorun(compute);

      computations.push(comp);
    };

    this.titleExitHandler = () => {
      for (let i = computations.length - 1; i >= 0; i--) {
        computations[i].stop();
        computations.splice(i, 1);
      }
    };

    this.titleHandler = (context, redirect, stop, data) => {
      let _title;
      let defaultTitle = null;
      const _context = Object.assign({}, context, { query: context.queryParams });
      const _arguments = [context.params, context.queryParams, data];
      let _groupTitlePrefix = this._getParentPrefix(((this.router._current && this.router._current.route && this.router._current.route.group) ? this.router._current.route.group : void 0), _context, _arguments);

      if (this.router.globals.length) {
        for (let j = 0; j < this.router.globals.length; j++) {
          if (helpers.isObject(this.router.globals[j]) && helpers.has(this.router.globals[j], 'title')) {
            defaultTitle = this.router.globals[j].title;
            break;
          }
        }
      }

      if (context.route && context.route.group && context.route.group.options) {
        let _routeTitle = (context.route.options && context.route.options.title) ? context.route.options.title : void 0;
        let _groupTitle = (context.route.group.options && context.route.group.options.title) ? context.route.group.options.title : void 0;

        const applyRouteTitle = (__routeTitle) => {
          if (helpers.isFunction(__routeTitle)) {
            return __routeTitle.apply(_context, _arguments);
          } else if (helpers.isString(__routeTitle)) {
            return __routeTitle;
          }
          return '';
        };

        const applyGroupTitle = (__groupTitle) => {
          let __title = '';
          const __routeTitle = applyRouteTitle(_routeTitle);
          if (!__routeTitle) {
            __title = _groupTitlePrefix + applyRouteTitle(__groupTitle || defaultTitle || hardCodedTitle);
          } else if (__routeTitle && _groupTitlePrefix) {
            __title = _groupTitlePrefix + __routeTitle;
          } else {
            __title = _groupTitlePrefix + applyRouteTitle(__routeTitle || defaultTitle || hardCodedTitle);
          }
          return __title;
        };

        if (helpers.isFunction(_routeTitle)) {
          this._reactivate(_routeTitle, _context, context, _arguments, applyGroupTitle);
          return;
        }

        if (helpers.isFunction(_groupTitle)) {
          this._reactivate(_groupTitle, _context, context, _arguments, applyGroupTitle);
          return;
        }
        _title = applyGroupTitle(_groupTitle);
      } else {
        _title = (context.route.options && context.route.options.title) ? context.route.options.title : (defaultTitle || hardCodedTitle);
        if (helpers.isFunction(_title)) {
          this._reactivate(_title, _context, context, _arguments);
        }
      }

      if (helpers.isString(_title)) {
        self.title.set(_title);
        if (context && context.context && helpers.isObject(context.context)) {
          context.context.title = _title;
        }
      }
    };

    this.router.triggers.enter([this.titleHandler]);
    this.router.triggers.exit([this.titleExitHandler]);
    const _orig = this.router._notfoundRoute;
    this.router._notfoundRoute = function() {
      const _context = {
        route: {
          options: {}
        }
      };
      _context.route.options.title = (self.router.notFound && self.router.notFound.title) ? self.router.notFound.title : void 0;

      if (!helpers.isEmpty(self.router._current)) {
        self.titleHandler(Object.assign({}, self.router._current, _context));
      } else {
        self.titleHandler(_context);
      }
      _orig.apply(this, arguments);
    };
  }

  set(str) {
    if (helpers.isString(str)) {
      this.title.set(str);
      return true;
    }
    return false;
  }

  _getParentPrefix(group, _context, _arguments, i = 0) {
    let prefix = '';
    i++;
    if (group) {
      if (group.options && group.options.titlePrefix) {
        if ((_context.route.options && _context.route.options.title && i === 1) || i !== 1) {
          let _gt = group.options.titlePrefix;
          if (helpers.isFunction(_gt)) {
            _gt = _gt.apply(_context, _arguments);
          }
          prefix += _gt;
        }
      }

      if (group.parent) {
        prefix = this._getParentPrefix(group.parent, _context, _arguments, i) + prefix;
      }
    }
    return prefix;
  }
}
<|endoftext|>


<commit_before>/*jslint browser: true, for: true */
/*global dashjs, flowplayer, MediaPlayer, window */

/*!

   MPEG-DASH engine plugin for Flowplayer HTML5

   Copyright (c) 2015-2016, Flowplayer Oy

   Released under the MIT License:
   http://www.opensource.org/licenses/mit-license.php

   Includes hls.js
   Copyright (c) 2015 Dailymotion (http://www.dailymotion.com)
   https://github.com/dailymotion/hls.js/blob/master/LICENSE

   Includes es5.js
   https://github.com/inexorabletash/polyfill/blob/master/es5.js
   for compatibility with legacy browsers

   Requires Flowplayer HTML5 version 6.x
   revision: $GIT_ID$

*/
(function () {
    "use strict";
    var extension = function (dashjs, flowplayer) {
        var engineName = "dash",
            mse = window.MediaSource,
            common = flowplayer.common,
            extend = flowplayer.extend,
            version = flowplayer.version,
            dashconf,

            dashCanPlay = function (sourceType, dashType, dashCodecs) {
                return sourceType.toLowerCase() === "application/dash+xml" &&
                        mse.isTypeSupported(dashType + ';codecs="' + dashCodecs + '"') &&
                        // Android MSE advertises he-aac, but fails
                        (dashCodecs.indexOf("mp4a.40.5") < 0 || navigator.userAgent.indexOf("Android") < 0);
            },

            engineImpl = function dashjsEngine(player, root) {
                var bean = flowplayer.bean,
                    mediaPlayer,
                    videoTag,
                    bc,
                    has_bg,

                    engine = {
                        engineName: engineName,

                        pick: function (sources) {
                            var i,
                                source,
                                dashType,
                                dashCodecs;

                            for (i = 0; i < sources.length; i += 1) {
                                source = sources[i];
                                dashType = source.dashType || dashconf.type;
                                dashCodecs = source.dashCodecs || dashconf.codecs;
                                if (dashCanPlay(source.type, dashType, dashCodecs)) {
                                    if (typeof source.src === 'string') {
                                        source.src = common.createAbsoluteUrl(source.src);
                                    }
                                    return source;
                                }
                            }
                        },

                        load: function (video) {
                            var conf = player.conf,
                                dashUpdatedConf = extend(dashconf, conf.dash, conf.clip.dash),
                                EVENTS = {
                                    ended: "finish",
                                    loadeddata: "ready",
                                    pause: "pause",
                                    play: "resume",
                                    progress: "buffer",
                                    ratechange: "speed",
                                    seeked: "seek",
                                    timeupdate: "progress",
                                    volumechange: "volume"
                                },
                                DASHEVENTS = dashjs.MediaPlayer.events,
                                autoplay = !!video.autoplay || !!conf.autoplay,
                                posterClass = "is-poster",
                                livestartpos = 0;

                            if (!mediaPlayer) {
                                common.removeNode(common.findDirect("video", root)[0]
                                        || common.find(".fp-player > video", root)[0]);
                                // dash.js enforces preload="auto" and
                                // autoplay depending on initialization
                                // so setting the attributes here will have no effect
                                videoTag = common.createElement("video", {
                                    "class": "fp-engine " + engineName + "-engine",
                                    "x-webkit-airplay": "allow"
                                });

                                Object.keys(EVENTS).forEach(function (key) {
                                    var flow = EVENTS[key],
                                        type = key + "." + engineName,
                                        arg;

                                    bean.on(videoTag, type, function (e) {
                                        if (conf.debug && flow.indexOf("progress") < 0) {
                                            console.log(type, "->", flow, e.originalEvent);
                                        }
                                        if (!player.ready && flow.indexOf("ready") < 0) {
                                            return;
                                        }

                                        var ct = 0,
                                            buffer = 0,
                                            buffend = 0,
                                            buffered,
                                            i;

                                        switch (flow) {
                                        case "ready":
                                            arg = extend(player.video, {
                                                duration: videoTag.duration,
                                                seekable: videoTag.seekable.end(null),
                                                width: videoTag.videoWidth,
                                                height: videoTag.videoHeight,
                                                url: player.video.src
                                            });
                                            break;
                                        case "resume":
                                            if (player.poster) {
                                                player.poster = false;
                                                common.removeClass(root, posterClass);
                                            }
                                            break;
                                        case "seek":
                                        case "progress":
                                            ct = videoTag.currentTime;
                                            if (player.video.live && !livestartpos && ct > 0) {
                                                livestartpos = ct;
                                            }
                                            arg = !player.video.live
                                                ? ct
                                                : livestartpos
                                                    ? ct - livestartpos
                                                    : 0;
                                            break;
                                        case "speed":
                                            arg = videoTag.playbackRate;
                                            break;
                                        case "volume":
                                            arg = videoTag.volume;
                                            break;
                                        case "buffer":
                                            try {
                                                ct = videoTag.currentTime;
                                                // cycle through time ranges to obtain buffer
                                                // nearest current time
                                                if (ct) {
                                                    buffered = videoTag.buffered;
                                                    for (i = buffered.length - 1; i > -1; i -= 1) {
                                                        buffend = buffered.end(i);

                                                        if (buffend >= ct) {
                                                            buffer = buffend;
                                                        }
                                                    }
                                                }
                                            } catch (ignore) {}
                                            video.buffer = buffer;
                                            arg = e;
                                            break;
                                        }

                                        player.trigger(flow, [player, arg]);
                                    });
                                });

                                if (conf.poster) {
                                    var posterHack = function () {
                                        setTimeout(function () {
                                            if (!player.poster) {
                                                common.addClass(root, posterClass);
                                                player.poster = true;
                                            }
                                        }, 0);
                                    };

                                    player.one("ready." + engineName, posterHack).on("stop." + engineName, posterHack);
                                }
                                player.on("error." + engineName, function () {
                                    if (mediaPlayer) {
                                        mediaPlayer.reset();
                                        mediaPlayer = 0;
                                    }
                                });

                                mediaPlayer = dashjs.MediaPlayer().create();
                                player.engine[engineName] = mediaPlayer;

                                // new ABR algo
                                mediaPlayer.enableBufferOccupancyABR(!!dashUpdatedConf.bufferOccupancyABR);
                                // caching can cause failures in playlists
                                // for the moment disable entirely
                                mediaPlayer.enableLastBitrateCaching(false);
                                // for seeking in paused state
                                mediaPlayer.setScheduleWhilePaused(true);
                                mediaPlayer.getDebug().setLogToBrowserConsole(!!dashUpdatedConf.debug);

                                Object.keys(DASHEVENTS).forEach(function (key) {
                                    var etype = DASHEVENTS[key],
                                        fpEventType = engineName + etype.charAt(0).toUpperCase() + etype.slice(1),
                                        listeners = dashUpdatedConf.listeners,
                                        expose = listeners && listeners.indexOf(etype) > -1;

                                    mediaPlayer.on(etype, function (e) {
                                        var data = extend({}, e),
                                            src = player.video.src,
                                            fperr,
                                            errobj;

                                        delete data.type;
                                        switch (key) {
                                        case "ERROR":
                                            switch (data.error) {
                                            case "download":
                                                fperr = 4;
                                                break;
                                            case "manifestError":
                                                fperr = 5;
                                                break;
                                            case "mediasource":
                                                switch (e.event) {
                                                case "MEDIA_ERR_DECODE":
                                                    fperr = 3;
                                                    break;
                                                case "MEDIA_ERR_SRC_NOT_SUPPORTED":
                                                    fperr = 5;
                                                    break;
                                                case "MEDIA_ERR_NETWORK":
                                                    fperr = 2;
                                                    break;
                                                case "MEDIA_ERR_ABORTED":
                                                    fperr = 1;
                                                    break;
                                                }
                                                break;
                                            }
                                            if (fperr) {
                                                errobj = {code: fperr};
                                                if (fperr > 2) {
                                                    errobj.video = extend(video, {
                                                        src: src,
                                                        url: data.event.url || src
                                                    });
                                                }
                                                player.trigger('error', [player, errobj]);
                                                return;
                                            }
                                            break;
                                        }

                                        if (expose) {
                                            player.trigger(fpEventType, [player, data]);
                                        }
                                    });
                                });

                                common.prepend(common.find(".fp-player", root)[0], videoTag);
                                mediaPlayer.initialize(videoTag, video.src, autoplay);

                                // at least some Android requires extra load
                                // https://github.com/flowplayer/flowplayer/issues/910
                                if (autoplay && !flowplayer.support.zeropreload) {
                                    videoTag.load();
                                }

                            } else {
                                if ((player.video.src && video.src !== player.video.src) || video.index) {
                                    mediaPlayer.setAutoPlay(true);
                                }
                                mediaPlayer.attachSource(video.src);

                            }

                            // update video object before ready
                            player.video = video;
                        },

                        resume: function () {
                            videoTag.play();
                        },

                        pause: function () {
                            videoTag.pause();
                        },

                        seek: function (time) {
                            videoTag.currentTime = time;
                        },

                        volume: function (level) {
                            if (videoTag) {
                                videoTag.volume = level;
                            }
                        },

                        speed: function (val) {
                            videoTag.playbackRate = val;
                            player.trigger('speed', [player, val]);
                        },

                        unload: function () {
                            if (mediaPlayer) {
                                var listeners = "." + engineName;

                                mediaPlayer.reset();
                                mediaPlayer = 0;
                                player.off(listeners);
                                bean.off(root, listeners);
                                bean.off(videoTag, listeners);
                                common.removeNode(videoTag);
                                videoTag = 0;
                            }
                        }
                    };

                // pre 6.0.4: no boolean api.conf.poster and no poster with autoplay
                if (/^6\.0\.[0-3]$/.test(version) &&
                        !player.conf.splash && !player.conf.poster && !player.conf.autoplay) {
                    bc = common.css(root, 'backgroundColor');
                    // spaces in rgba arg mandatory for recognition
                    has_bg = common.css(root, 'backgroundImage') !== "none" ||
                            (bc && bc !== "rgba(0, 0, 0, 0)" && bc !== "transparent");
                    if (has_bg) {
                        player.conf.poster = true;
                    }
                }

                return engine;
            };

        if (mse && typeof mse.isTypeSupported === "function" && version.indexOf("5.") !== 0) {
            // only load engine if it can be used
            engineImpl.engineName = engineName; // must be exposed
            engineImpl.canPlay = function (type, conf) {
                /*
                  WARNING: MediaSource.isTypeSupported very inconsistent!
                  e.g. Safari ignores codecs entirely, even bogus, like codecs="XYZ"
                  example avc3 main level 3.1 + aac_he: avc3.4d401f; mp4a.40.5
                  example avc1 high level 4.1 + aac_lc: avc1.640029; mp4a.40.2
                  default: avc1 baseline level 3.0 + aac_lc
                */
                // inject dash conf at earliest opportunity
                dashconf = extend({
                    type: "video/mp4",
                    codecs: "avc1.42c01e,mp4a.40.2"
                }, flowplayer.conf[engineName], conf[engineName], conf.clip[engineName]);

                return dashCanPlay(type, dashconf.type, dashconf.codecs);
            };

            // put on top of engine stack
            // so mpegedash is tested before html5
            flowplayer.engines.unshift(engineImpl);

        }

    };
    if (typeof module === 'object' && module.exports) {
        module.exports = extension.bind(undefined, require('dashjs'));
    } else if (window.dashjs && window.flowplayer) {
        extension(window.dashjs, window.flowplayer);
    }
}());
<commit_msg>Disable posterHack on ready for autoplay<commit_after>/*jslint browser: true, for: true */
/*global dashjs, flowplayer, MediaPlayer, window */

/*!

   MPEG-DASH engine plugin for Flowplayer HTML5

   Copyright (c) 2015-2016, Flowplayer Oy

   Released under the MIT License:
   http://www.opensource.org/licenses/mit-license.php

   Includes hls.js
   Copyright (c) 2015 Dailymotion (http://www.dailymotion.com)
   https://github.com/dailymotion/hls.js/blob/master/LICENSE

   Includes es5.js
   https://github.com/inexorabletash/polyfill/blob/master/es5.js
   for compatibility with legacy browsers

   Requires Flowplayer HTML5 version 6.x
   revision: $GIT_ID$

*/
(function () {
    "use strict";
    var extension = function (dashjs, flowplayer) {
        var engineName = "dash",
            mse = window.MediaSource,
            common = flowplayer.common,
            extend = flowplayer.extend,
            version = flowplayer.version,
            dashconf,

            dashCanPlay = function (sourceType, dashType, dashCodecs) {
                return sourceType.toLowerCase() === "application/dash+xml" &&
                        mse.isTypeSupported(dashType + ';codecs="' + dashCodecs + '"') &&
                        // Android MSE advertises he-aac, but fails
                        (dashCodecs.indexOf("mp4a.40.5") < 0 || navigator.userAgent.indexOf("Android") < 0);
            },

            engineImpl = function dashjsEngine(player, root) {
                var bean = flowplayer.bean,
                    mediaPlayer,
                    videoTag,
                    bc,
                    has_bg,

                    engine = {
                        engineName: engineName,

                        pick: function (sources) {
                            var i,
                                source,
                                dashType,
                                dashCodecs;

                            for (i = 0; i < sources.length; i += 1) {
                                source = sources[i];
                                dashType = source.dashType || dashconf.type;
                                dashCodecs = source.dashCodecs || dashconf.codecs;
                                if (dashCanPlay(source.type, dashType, dashCodecs)) {
                                    if (typeof source.src === 'string') {
                                        source.src = common.createAbsoluteUrl(source.src);
                                    }
                                    return source;
                                }
                            }
                        },

                        load: function (video) {
                            var conf = player.conf,
                                dashUpdatedConf = extend(dashconf, conf.dash, conf.clip.dash),
                                EVENTS = {
                                    ended: "finish",
                                    loadeddata: "ready",
                                    pause: "pause",
                                    play: "resume",
                                    progress: "buffer",
                                    ratechange: "speed",
                                    seeked: "seek",
                                    timeupdate: "progress",
                                    volumechange: "volume"
                                },
                                DASHEVENTS = dashjs.MediaPlayer.events,
                                autoplay = !!video.autoplay || !!conf.autoplay,
                                posterClass = "is-poster",
                                livestartpos = 0;

                            if (!mediaPlayer) {
                                common.removeNode(common.findDirect("video", root)[0]
                                        || common.find(".fp-player > video", root)[0]);
                                // dash.js enforces preload="auto" and
                                // autoplay depending on initialization
                                // so setting the attributes here will have no effect
                                videoTag = common.createElement("video", {
                                    "class": "fp-engine " + engineName + "-engine",
                                    "x-webkit-airplay": "allow"
                                });

                                Object.keys(EVENTS).forEach(function (key) {
                                    var flow = EVENTS[key],
                                        type = key + "." + engineName,
                                        arg;

                                    bean.on(videoTag, type, function (e) {
                                        if (conf.debug && flow.indexOf("progress") < 0) {
                                            console.log(type, "->", flow, e.originalEvent);
                                        }
                                        if (!player.ready && flow.indexOf("ready") < 0) {
                                            return;
                                        }

                                        var ct = 0,
                                            buffer = 0,
                                            buffend = 0,
                                            buffered,
                                            i;

                                        switch (flow) {
                                        case "ready":
                                            arg = extend(player.video, {
                                                duration: videoTag.duration,
                                                seekable: videoTag.seekable.end(null),
                                                width: videoTag.videoWidth,
                                                height: videoTag.videoHeight,
                                                url: player.video.src
                                            });
                                            break;
                                        case "resume":
                                            if (player.poster) {
                                                common.removeClass(root, posterClass);
                                                player.poster = false;
                                            }
                                            break;
                                        case "seek":
                                        case "progress":
                                            ct = videoTag.currentTime;
                                            if (player.video.live && !livestartpos && ct > 0) {
                                                livestartpos = ct;
                                            }
                                            arg = !player.video.live
                                                ? ct
                                                : livestartpos
                                                    ? ct - livestartpos
                                                    : 0;
                                            break;
                                        case "speed":
                                            arg = videoTag.playbackRate;
                                            break;
                                        case "volume":
                                            arg = videoTag.volume;
                                            break;
                                        case "buffer":
                                            try {
                                                ct = videoTag.currentTime;
                                                // cycle through time ranges to obtain buffer
                                                // nearest current time
                                                if (ct) {
                                                    buffered = videoTag.buffered;
                                                    for (i = buffered.length - 1; i > -1; i -= 1) {
                                                        buffend = buffered.end(i);

                                                        if (buffend >= ct) {
                                                            buffer = buffend;
                                                        }
                                                    }
                                                }
                                            } catch (ignore) {}
                                            video.buffer = buffer;
                                            arg = e;
                                            break;
                                        }

                                        player.trigger(flow, [player, arg]);
                                    });
                                });

                                if (conf.poster) {
                                    var posterHack = function (e) {
                                        if (e.type === "stop" || !autoplay) {
                                            setTimeout(function () {
                                                if (!player.poster) {
                                                    common.addClass(root, posterClass);
                                                    player.poster = true;
                                                }
                                            }, 0);
                                        }
                                    };

                                    player.one("ready." + engineName, posterHack).on("stop." + engineName, posterHack);
                                }
                                player.on("error." + engineName, function () {
                                    if (mediaPlayer) {
                                        mediaPlayer.reset();
                                        mediaPlayer = 0;
                                    }
                                });

                                mediaPlayer = dashjs.MediaPlayer().create();
                                player.engine[engineName] = mediaPlayer;

                                // new ABR algo
                                mediaPlayer.enableBufferOccupancyABR(!!dashUpdatedConf.bufferOccupancyABR);
                                // caching can cause failures in playlists
                                // for the moment disable entirely
                                mediaPlayer.enableLastBitrateCaching(false);
                                // for seeking in paused state
                                mediaPlayer.setScheduleWhilePaused(true);
                                mediaPlayer.getDebug().setLogToBrowserConsole(!!dashUpdatedConf.debug);

                                Object.keys(DASHEVENTS).forEach(function (key) {
                                    var etype = DASHEVENTS[key],
                                        fpEventType = engineName + etype.charAt(0).toUpperCase() + etype.slice(1),
                                        listeners = dashUpdatedConf.listeners,
                                        expose = listeners && listeners.indexOf(etype) > -1;

                                    mediaPlayer.on(etype, function (e) {
                                        var data = extend({}, e),
                                            src = player.video.src,
                                            fperr,
                                            errobj;

                                        delete data.type;
                                        switch (key) {
                                        case "ERROR":
                                            switch (data.error) {
                                            case "download":
                                                fperr = 4;
                                                break;
                                            case "manifestError":
                                                fperr = 5;
                                                break;
                                            case "mediasource":
                                                switch (e.event) {
                                                case "MEDIA_ERR_DECODE":
                                                    fperr = 3;
                                                    break;
                                                case "MEDIA_ERR_SRC_NOT_SUPPORTED":
                                                    fperr = 5;
                                                    break;
                                                case "MEDIA_ERR_NETWORK":
                                                    fperr = 2;
                                                    break;
                                                case "MEDIA_ERR_ABORTED":
                                                    fperr = 1;
                                                    break;
                                                }
                                                break;
                                            }
                                            if (fperr) {
                                                errobj = {code: fperr};
                                                if (fperr > 2) {
                                                    errobj.video = extend(video, {
                                                        src: src,
                                                        url: data.event.url || src
                                                    });
                                                }
                                                player.trigger('error', [player, errobj]);
                                                return;
                                            }
                                            break;
                                        }

                                        if (expose) {
                                            player.trigger(fpEventType, [player, data]);
                                        }
                                    });
                                });

                                common.prepend(common.find(".fp-player", root)[0], videoTag);
                                mediaPlayer.initialize(videoTag, video.src, autoplay);

                                // at least some Android requires extra load
                                // https://github.com/flowplayer/flowplayer/issues/910
                                if (autoplay && !flowplayer.support.zeropreload) {
                                    videoTag.load();
                                }

                            } else {
                                if ((player.video.src && video.src !== player.video.src) || video.index) {
                                    mediaPlayer.setAutoPlay(true);
                                }
                                mediaPlayer.attachSource(video.src);

                            }

                            // update video object before ready
                            player.video = video;
                        },

                        resume: function () {
                            videoTag.play();
                        },

                        pause: function () {
                            videoTag.pause();
                        },

                        seek: function (time) {
                            videoTag.currentTime = time;
                        },

                        volume: function (level) {
                            if (videoTag) {
                                videoTag.volume = level;
                            }
                        },

                        speed: function (val) {
                            videoTag.playbackRate = val;
                            player.trigger('speed', [player, val]);
                        },

                        unload: function () {
                            if (mediaPlayer) {
                                var listeners = "." + engineName;

                                mediaPlayer.reset();
                                mediaPlayer = 0;
                                player.off(listeners);
                                bean.off(root, listeners);
                                bean.off(videoTag, listeners);
                                common.removeNode(videoTag);
                                videoTag = 0;
                            }
                        }
                    };

                // pre 6.0.4: no boolean api.conf.poster and no poster with autoplay
                if (/^6\.0\.[0-3]$/.test(version) &&
                        !player.conf.splash && !player.conf.poster && !player.conf.autoplay) {
                    bc = common.css(root, 'backgroundColor');
                    // spaces in rgba arg mandatory for recognition
                    has_bg = common.css(root, 'backgroundImage') !== "none" ||
                            (bc && bc !== "rgba(0, 0, 0, 0)" && bc !== "transparent");
                    if (has_bg) {
                        player.conf.poster = true;
                    }
                }

                return engine;
            };

        if (mse && typeof mse.isTypeSupported === "function" && version.indexOf("5.") !== 0) {
            // only load engine if it can be used
            engineImpl.engineName = engineName; // must be exposed
            engineImpl.canPlay = function (type, conf) {
                /*
                  WARNING: MediaSource.isTypeSupported very inconsistent!
                  e.g. Safari ignores codecs entirely, even bogus, like codecs="XYZ"
                  example avc3 main level 3.1 + aac_he: avc3.4d401f; mp4a.40.5
                  example avc1 high level 4.1 + aac_lc: avc1.640029; mp4a.40.2
                  default: avc1 baseline level 3.0 + aac_lc
                */
                // inject dash conf at earliest opportunity
                dashconf = extend({
                    type: "video/mp4",
                    codecs: "avc1.42c01e,mp4a.40.2"
                }, flowplayer.conf[engineName], conf[engineName], conf.clip[engineName]);

                return dashCanPlay(type, dashconf.type, dashconf.codecs);
            };

            // put on top of engine stack
            // so mpegedash is tested before html5
            flowplayer.engines.unshift(engineImpl);

        }

    };
    if (typeof module === 'object' && module.exports) {
        module.exports = extension.bind(undefined, require('dashjs'));
    } else if (window.dashjs && window.flowplayer) {
        extension(window.dashjs, window.flowplayer);
    }
}());
<|endoftext|>


<commit_before>/* eslint-disable no-console */
"use strict";

import { OUTPUT_PATH, DEVSERVER_HOST, DEVSERVER_PORT, DEVSERVER_INDEX_PATH_RELATIVE, HTML_CONFIG_ARTIFACT_FILE, ARTIFACTS_PATH, WEBPACK_STATS_FILENAME } from "../config";
import express from "express";
import compression from "compression";
import * as path from "path";
// imports for react static render
import React from "react";
import { renderToString } from "react-dom/server";
import { match, RouterContext } from "react-router";
import routes from "../src/routes";
import htmlRenderer from "./htmlRenderer";
import fs from "fs";

let htmlConfig = null;
let webpackStats = null;
let app = express();
app.use(compression());

const host = process.env.HOST || DEVSERVER_HOST;
const port = process.env.PORT || DEVSERVER_PORT;

const rootPath = OUTPUT_PATH;

app.use(express.static(rootPath + "/"));

app.get("*", function (req, res) {
    //useStaticFile(req, res);
    useReactRenderer(req, res);
});

app.listen(port, function () {
    console.log(`Server listening on http://${host}:${port}`);
    let open = require("open");
    open(`http://${host}:${port}/`);
});

function useStaticFile(req, res) {
    res.sendFile(rootPath + DEVSERVER_INDEX_PATH_RELATIVE);
}

function useReactRenderer(req, res) {
    match({ routes, location: req.url }, (err, redirect, props) => {
        const appHtml = renderToString(<RouterContext {...props}/>)
        res.send(renderPage(appHtml))
    });

    function renderPage(appHtml) {
        if (htmlConfig === null)
        {
            let configPath = HTML_CONFIG_ARTIFACT_FILE;
            htmlConfig = JSON.parse(fs.readFileSync(configPath));

            let statsPath = path.join(ARTIFACTS_PATH, WEBPACK_STATS_FILENAME);
            webpackStats = JSON.parse(fs.readFileSync(statsPath));

            // remove source maps.
            let webpackJs = [].concat(webpackStats.assetsByChunkName.main).filter(x => x.endsWith(".js"));
            htmlConfig.js = htmlConfig.js.concat(webpackJs);
        }
        let config = Object.assign({}, htmlConfig, { body: appHtml });
        let html = htmlRenderer.render(config);
        return html;
    }
}
<commit_msg>add server side error handling<commit_after>/* eslint-disable no-console */
"use strict";

import { OUTPUT_PATH, DEVSERVER_HOST, DEVSERVER_PORT, DEVSERVER_INDEX_PATH_RELATIVE, HTML_CONFIG_ARTIFACT_FILE, ARTIFACTS_PATH, WEBPACK_STATS_FILENAME } from "../config";
import express from "express";
import compression from "compression";
import * as path from "path";
// imports for react static render
import React from "react";
import { renderToString } from "react-dom/server";
import { match, RouterContext } from "react-router";
import routes from "../src/routes";
import htmlRenderer from "./htmlRenderer";
import fs from "fs";

let htmlConfig = null;
let webpackStats = null;
let app = express();
app.use(compression());

const host = process.env.HOST || DEVSERVER_HOST;
const port = process.env.PORT || DEVSERVER_PORT;

const rootPath = OUTPUT_PATH;

app.use(express.static(rootPath + "/"));

app.get("*", function (req, res) {
    //useStaticFile(req, res);
    useReactRenderer(req, res);
});

app.listen(port, function () {
    console.log(`Server listening on http://${host}:${port}`);
    let open = require("open");
    open(`http://${host}:${port}/`);
});

function useStaticFile(req, res) {
    res.sendFile(rootPath + DEVSERVER_INDEX_PATH_RELATIVE);
}

function useReactRenderer(req, res) {
    match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
        if (error) {
            res.status(500).send(error.message)
        } else if (redirectLocation) {
            res.redirect(302, redirectLocation.pathname + redirectLocation.search)
        } else if (renderProps) {
            // TODO: renderProps.components or renderProps.routes for
            // "not found" component or route respectively, and send 404 as
            // below for catch-all route.
            let appHtml = renderToString(<RouterContext {...renderProps} />);
            res.status(200).send(renderPage(appHtml));
    } else {
            res.status(404).send('Not found')
        }
    });
    match({ routes, location: req.url }, (err, redirect, props) => {
        const appHtml = renderToString(<RouterContext {...props}/>)
        res.send(renderPage(appHtml))
    });

    function renderPage(body) {
        if (htmlConfig === null)
        {
            let configPath = HTML_CONFIG_ARTIFACT_FILE;
            htmlConfig = JSON.parse(fs.readFileSync(configPath));

            let statsPath = path.join(ARTIFACTS_PATH, WEBPACK_STATS_FILENAME);
            webpackStats = JSON.parse(fs.readFileSync(statsPath));

            // remove source maps.
            let webpackJs = [].concat(webpackStats.assetsByChunkName.main).filter(x => x.endsWith(".js"));
            htmlConfig.js = htmlConfig.js.concat(webpackJs);
        }
        let config = Object.assign({}, htmlConfig, { body });
        let html = htmlRenderer.render(config);
        return html;
    }
}
<|endoftext|>


<commit_before><commit_msg>less drawing, animating cards now<commit_after><|endoftext|>


<commit_before>const {readFile, writeFile} = require('fs');
const libui = require('../index.js');

const {
	label,
	window,
	tab,
	menu,
	multilineEntry
} = require('./utils.js');

const onClosing = () => libui.stopLoop();

libui.Ui.onShouldQuit(() => {
	onClosing();
});

const winProps = {
	hasMenubar: true,
	title: 'Node Pad',
	width: 640,
	height: 480,
	onClosing
};

let win;
let editor;
let status;
let currentFileName = '';

function newFile() {
	editor.text = '';
	currentFileName = '';
}

function openFile() {
	const filename = libui.UiDialogs.openFile(win);
	if (filename) {
		readFile(filename, 'utf8', function (err, content) {
			if (err) {
				return libui.UiDialogs.msgBoxError(win, 'Error while reading file', err.stack);
			}
			editor.text = content;
			status.text = `Open ${filename}`;
			currentFileName = filename;
		});
	}
}

function saveFileAs() {
	const filename = libui.UiDialogs.saveFile(win);
	if (filename) {
		writeFile(currentFileName, editor.text, function (err) {
			if (err) {
				return libui.UiDialogs.msgBoxError(win, 'Error while writing file', err.stack);
			}
			currentFileName = filename;
		});
	}
}

function saveFile() {
	if (!currentFileName) {
		return saveFileAs();
	}

	writeFile(currentFileName, editor.text, function (err) {
		if (err) {
			return libui.UiDialogs.msgBoxError(win, 'Error while writing file', err.stack);
		}
	});
}

menu([{
	label: 'File',
	submenu: [
		{
			label: 'New file',
			click: newFile
		}, {
			label: 'Open',
			click: openFile
		}, {
			label: 'Close current tab',
			click: () => {}
		}, {
			label: 'Save',
			click: saveFile
		}, {
			label: 'Save as',
			click: saveFileAs
		}, {
			role: 'quit'
		}
	]
}, {
	label: 'Edit',
	submenu: [
		{
			label: 'Copy'
		}, {
			label: 'Paste'
		}, {
			label: 'Cut'
		}, {
			label: 'Select all'
		}
	]
}, {
	label: 'Help',
	submenu: [
		{
			label: 'Help',
			click: () => {}
		}, {
			role: 'about'
		}
	]
}]);

win = window(winProps,
	tab({stretchy: true},
		editor = multilineEntry({stretchy: true, tabTitle: 'New file'})
	),
	status = label({stretchy: false, text: 'File not changed'})
);

win.show();
libui.startLoop();

<commit_msg>linter<commit_after>const {readFile, writeFile} = require('fs');
const libui = require('../index.js');

const {
	label,
	window,
	tab,
	menu,
	multilineEntry
} = require('./utils.js');

const onClosing = () => libui.stopLoop();

libui.Ui.onShouldQuit(() => {
	onClosing();
});

const winProps = {
	hasMenubar: true,
	title: 'Node Pad',
	width: 640,
	height: 480,
	onClosing
};

let win;
let editor;
let status;
let currentFileName = '';

function newFile() {
	editor.text = '';
	currentFileName = '';
}

function openFile() {
	const filename = libui.UiDialogs.openFile(win);
	if (filename) {
		readFile(filename, 'utf8', function (err, content) {
			if (err) {
				return libui.UiDialogs.msgBoxError(win, 'Error while reading file', err.stack);
			}
			editor.text = content;
			status.text = `Open ${filename}`;
			currentFileName = filename;
		});
	}
}

function saveFileAs() {
	const filename = libui.UiDialogs.saveFile(win);
	if (filename) {
		writeFile(currentFileName, editor.text, function (err) {
			if (err) {
				return libui.UiDialogs.msgBoxError(win, 'Error while writing file', err.stack);
			}
			currentFileName = filename;
		});
	}
}

function saveFile() {
	if (!currentFileName) {
		return saveFileAs();
	}

	writeFile(currentFileName, editor.text, function (err) {
		if (err) {
			return libui.UiDialogs.msgBoxError(win, 'Error while writing file', err.stack);
		}
	});
}

menu([{
	label: 'File',
	submenu: [
		{
			label: 'New file',
			click: newFile
		}, {
			label: 'Open',
			click: openFile
		}, {
			label: 'Close current tab',
			click: () => {}
		}, {
			label: 'Save',
			click: saveFile
		}, {
			label: 'Save as',
			click: saveFileAs
		}, {
			role: 'quit'
		}
	]
}, {
	label: 'Edit',
	submenu: [
		{
			label: 'Copy'
		}, {
			label: 'Paste'
		}, {
			label: 'Cut'
		}, {
			label: 'Select all'
		}
	]
}, {
	label: 'Help',
	submenu: [
		{
			label: 'Help',
			click: () => {}
		}, {
			role: 'about'
		}
	]
}]);

win = window(winProps,
	tab({stretchy: true},
		editor = multilineEntry({stretchy: true, tabTitle: 'New file'})
	),
	status = label({stretchy: false, text: 'File not changed'})
);

win.show();
libui.startLoop();

<|endoftext|>


<commit_before>/* eslint-disable max-len, no-undef */
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Range from '../src/Range';
import createSliderWithTooltip from '../src/createSliderWithTooltip';

const RangeWithTooltip = createSliderWithTooltip(Range);

describe('Range', () => {
  it('should render Range with correct DOM structure', () => {
    const wrapper = render(<Range />);
    expect(renderToJson(wrapper)).toMatchSnapshot();
  });

  it('should render Multi-Range with correct DOM structure', () => {
    const wrapper = render(<Range count={3} />);
    expect(renderToJson(wrapper)).toMatchSnapshot();
  });

  it('should render Range with value correctly', () => {
    const wrapper = mount(<Range value={[0, 50]} />);
    expect(wrapper.state('bounds')[0]).toBe(0);
    expect(wrapper.state('bounds')[1]).toBe(50);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(0).props().style.left).toMatch('0%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(1).props().style.left).toMatch('50%');

    const trackStyle = wrapper.find('.rc-slider-track > .rc-slider-track').at(0).props().style;
    expect(trackStyle.left).toMatch('0%');
    expect(trackStyle.width).toMatch('50%');
    expect(trackStyle.visibility).toMatch('visible');
  });

  it('should render Multi-Range with value correctly', () => {
    const wrapper = mount(<Range count={3} value={[0, 25, 50, 75]} />);
    expect(wrapper.state('bounds')[0]).toBe(0);
    expect(wrapper.state('bounds')[1]).toBe(25);
    expect(wrapper.state('bounds')[2]).toBe(50);
    expect(wrapper.state('bounds')[3]).toBe(75);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(0).props().style.left).toMatch('0%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(1).props().style.left).toMatch('25%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(2).props().style.left).toMatch('50%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(3).props().style.left).toMatch('75%');

    const track1Style = wrapper.find('.rc-slider-track > .rc-slider-track').at(0).props().style;
    expect(track1Style.left).toMatch('0%');
    expect(track1Style.width).toMatch('25%');
    expect(track1Style.visibility).toMatch('visible');

    const track2Style = wrapper.find('.rc-slider-track > .rc-slider-track').at(1).props().style;
    expect(track2Style.left).toMatch('25%');
    expect(track2Style.width).toMatch('25%');
    expect(track2Style.visibility).toMatch('visible');

    const track3Style = wrapper.find('.rc-slider-track > .rc-slider-track').at(2).props().style;
    expect(track3Style.left).toMatch('50%');
    expect(track3Style.width).toMatch('25%');
    expect(track3Style.visibility).toMatch('visible');
  });

  it('should update Range correctly in controllered model', () => {
    class TestParent extends React.Component { // eslint-disable-line
      state = {
        value: [2, 4, 6],
      }
      getSlider() {
        return this.refs.slider;
      }
      render() {
        return <Range ref="slider" value={this.state.value}/>;
      }
    }
    const wrapper = mount(<TestParent/>);

    expect(wrapper.instance().getSlider().state.bounds.length).toBe(3);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').length).toBe(3);
    wrapper.setState({ value: [2, 4] });
    expect(wrapper.instance().getSlider().state.bounds.length).toBe(2);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').length).toBe(2);
  });

  // https://github.com/react-component/slider/pull/256
  it('should handle mutli handle mouseEnter correctly', () => {
    const wrapper = mount(<RangeWithTooltip min={0} max={1000} defaultValue={[50, 55]} />);
    wrapper.find('.rc-slider-handle').at(1).simulate('mouseEnter');
    expect(wrapper.state().visibles[0]).toBe(true);
    wrapper.find('.rc-slider-handle').at(3).simulate('mouseEnter');
    expect(wrapper.state().visibles[1]).toBe(true);
    wrapper.find('.rc-slider-handle').at(1).simulate('mouseLeave');
    expect(wrapper.state().visibles[0]).toBe(false);
    wrapper.find('.rc-slider-handle').at(3).simulate('mouseLeave');
    expect(wrapper.state().visibles[1]).toBe(false);
  });

  it('should keep pushable when not allowCross and setState', () => {
    class CustomizedRange extends React.Component { // eslint-disable-line
      constructor(props) {
        super(props);
        this.state = {
          value: [20, 40],
        };
      }
      getSlider() {
        return this.refs.slider;
      }
      render() {
        return <Range ref="slider" allowCross={false} value={this.state.value} pushable={10} />;
      }
    }
    const wrapper = mount(<CustomizedRange />);
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(20);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [30, 40] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [35, 40] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [30, 30] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
  });

  it('should keep pushable with pushable s defalutValue when not allowCross and setState', () => {
    class CustomizedRange extends React.Component { // eslint-disable-line
      constructor(props) {
        super(props);
        this.state = {
          value: [20, 40],
        };
      }
      getSlider() {
        return this.refs.slider;
      }
      render() {
        return <Range ref="slider" allowCross={false} value={this.state.value} pushable />;
      }
    }
    const wrapper = mount(<CustomizedRange />);
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(20);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [40, 40] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(39);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [39, 38] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(39);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
  });

  describe('focus & blur', () => {
    let container;

    beforeEach(() => {
      container = document.createElement('div');
      document.body.appendChild(container);
    });

    afterEach(() => {
      document.body.removeChild(container);
    });

    const mockRect = (wrapper) => {
      wrapper.instance().sliderRef.getBoundingClientRect = () => ({
        left: 10,
        width: 100,
      });
    };

    it('focus()', () => {
      const handleFocus = jest.fn();
      const wrapper = mount(
        <Range min={0} max={20} onFocus={handleFocus} />,
        { attachTo: container }
      );
      mockRect(wrapper);
      wrapper.instance().focus();
      expect(handleFocus).toBeCalled();
    });

    it('blur', () => {
      const handleBlur = jest.fn();
      const wrapper = mount(
        <Range min={0} max={20} onBlur={handleBlur} />,
        { attachTo: container }
      );
      mockRect(wrapper);
      wrapper.instance().focus();
      wrapper.instance().blur();
      expect(handleBlur).toBeCalled();
    });
  });
});
<commit_msg>update test case<commit_after>/* eslint-disable max-len, no-undef */
import React from 'react';
import { render, mount } from 'enzyme';
import { renderToJson } from 'enzyme-to-json';
import Range from '../src/Range';
import createSliderWithTooltip from '../src/createSliderWithTooltip';

const RangeWithTooltip = createSliderWithTooltip(Range);

describe('Range', () => {
  it('should render Range with correct DOM structure', () => {
    const wrapper = render(<Range />);
    expect(renderToJson(wrapper)).toMatchSnapshot();
  });

  it('should render Multi-Range with correct DOM structure', () => {
    const wrapper = render(<Range count={3} />);
    expect(renderToJson(wrapper)).toMatchSnapshot();
  });

  it('should render Range with value correctly', () => {
    const wrapper = mount(<Range value={[0, 50]} />);
    expect(wrapper.state('bounds')[0]).toBe(0);
    expect(wrapper.state('bounds')[1]).toBe(50);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(0).props().style.left).toMatch('0%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(1).props().style.left).toMatch('50%');

    const trackStyle = wrapper.find('.rc-slider-track > .rc-slider-track').at(0).props().style;
    expect(trackStyle.left).toMatch('0%');
    expect(trackStyle.width).toMatch('50%');
    expect(trackStyle.visibility).toMatch('visible');
  });

  it('should render Multi-Range with value correctly', () => {
    const wrapper = mount(<Range count={3} value={[0, 25, 50, 75]} />);
    expect(wrapper.state('bounds')[0]).toBe(0);
    expect(wrapper.state('bounds')[1]).toBe(25);
    expect(wrapper.state('bounds')[2]).toBe(50);
    expect(wrapper.state('bounds')[3]).toBe(75);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(0).props().style.left).toMatch('0%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(1).props().style.left).toMatch('25%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(2).props().style.left).toMatch('50%');
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').at(3).props().style.left).toMatch('75%');

    const track1Style = wrapper.find('.rc-slider-track > .rc-slider-track').at(0).props().style;
    expect(track1Style.left).toMatch('0%');
    expect(track1Style.width).toMatch('25%');
    expect(track1Style.visibility).toMatch('visible');

    const track2Style = wrapper.find('.rc-slider-track > .rc-slider-track').at(1).props().style;
    expect(track2Style.left).toMatch('25%');
    expect(track2Style.width).toMatch('25%');
    expect(track2Style.visibility).toMatch('visible');

    const track3Style = wrapper.find('.rc-slider-track > .rc-slider-track').at(2).props().style;
    expect(track3Style.left).toMatch('50%');
    expect(track3Style.width).toMatch('25%');
    expect(track3Style.visibility).toMatch('visible');
  });

  it('should update Range correctly in controllered model', () => {
    class TestParent extends React.Component { // eslint-disable-line
      state = {
        value: [2, 4, 6],
      }
      getSlider() {
        return this.refs.slider;
      }
      render() {
        return <Range ref="slider" value={this.state.value}/>;
      }
    }
    const wrapper = mount(<TestParent/>);

    expect(wrapper.instance().getSlider().state.bounds.length).toBe(3);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').length).toBe(3);
    wrapper.setState({ value: [2, 4] });
    expect(wrapper.instance().getSlider().state.bounds.length).toBe(2);
    expect(wrapper.find('.rc-slider-handle > .rc-slider-handle').length).toBe(2);
  });

  // https://github.com/react-component/slider/pull/256
  it('should handle mutli handle mouseEnter correctly', () => {
    const wrapper = mount(<RangeWithTooltip min={0} max={1000} defaultValue={[50, 55]} />);
    wrapper.find('.rc-slider-handle').at(1).simulate('mouseEnter');
    expect(wrapper.state().visibles[0]).toBe(true);
    wrapper.find('.rc-slider-handle').at(3).simulate('mouseEnter');
    expect(wrapper.state().visibles[1]).toBe(true);
    wrapper.find('.rc-slider-handle').at(1).simulate('mouseLeave');
    expect(wrapper.state().visibles[0]).toBe(false);
    wrapper.find('.rc-slider-handle').at(3).simulate('mouseLeave');
    expect(wrapper.state().visibles[1]).toBe(false);
  });

  it('should keep pushable when not allowCross and setState', () => {
    class CustomizedRange extends React.Component { // eslint-disable-line
      constructor(props) {
        super(props);
        this.state = {
          value: [20, 40],
        };
      }
      getSlider() {
        return this.refs.slider;
      }
      render() {
        return <Range ref="slider" allowCross={false} value={this.state.value} pushable={10} />;
      }
    }
    const wrapper = mount(<CustomizedRange />);
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(20);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [30, 40] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [35, 40] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
    wrapper.setState({ value: [30, 30] });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
  });

  it('should keep pushable with pushable s defalutValue when not allowCross and setState', () => {
    class CustomizedRange extends React.Component { // eslint-disable-line
      constructor(props) {
        super(props);
        this.state = {
          value: [20, 40],
        };
        this.onChange = this.onChange.bind(this);
      }
      onChange(value) {
        this.setState({
          value,
        });
      }
      getSlider() {
        return this.refs.slider;
      }
      render() {
        return <Range ref="slider" allowCross={false} value={this.state.value} pushable onChange={this.onChange} />;
      }
    }
    const map = {};
    document.addEventListener = jest.genMockFn().mockImplementation((event, cb) => {
      map[event] = cb;
    });

    const mockRect = (wrapper) => {
      wrapper.instance().getSlider().sliderRef.getBoundingClientRect = () => ({
        left: 10,
        width: 100,
      });
    };

    const container = document.createElement('div');
    document.body.appendChild(container);

    const wrapper = mount(<CustomizedRange />, { attachTo: container });
    mockRect(wrapper);

    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(20);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);

    wrapper.find('.rc-slider').simulate('mouseDown', { button: 0, pageX: 10, pageY: 0 });
    map.mousemove({ type: 'mousemove', pageX: 40, pageY: 0 });
    map.mouseup({ type: 'mouseup', pageX: 40, pageY: 0 });

    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(30);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);

    wrapper.find('.rc-slider').simulate('mouseDown', { button: 0, pageX: 10, pageY: 0 });
    map.mousemove({ type: 'mousemove', pageX: 60, pageY: 0 });
    map.mouseup({ type: 'mouseup', pageX: 60, pageY: 0 });
    expect(wrapper.instance().getSlider().state.bounds[0]).toBe(39);
    expect(wrapper.instance().getSlider().state.bounds[1]).toBe(40);
  });

  describe('focus & blur', () => {
    let container;

    beforeEach(() => {
      container = document.createElement('div');
      document.body.appendChild(container);
    });

    afterEach(() => {
      document.body.removeChild(container);
    });

    const mockRect = (wrapper) => {
      wrapper.instance().sliderRef.getBoundingClientRect = () => ({
        left: 10,
        width: 100,
      });
    };

    it('focus()', () => {
      const handleFocus = jest.fn();
      const wrapper = mount(
        <Range min={0} max={20} onFocus={handleFocus} />,
        { attachTo: container }
      );
      mockRect(wrapper);
      wrapper.instance().focus();
      expect(handleFocus).toBeCalled();
    });

    it('blur', () => {
      const handleBlur = jest.fn();
      const wrapper = mount(
        <Range min={0} max={20} onBlur={handleBlur} />,
        { attachTo: container }
      );
      mockRect(wrapper);
      wrapper.instance().focus();
      wrapper.instance().blur();
      expect(handleBlur).toBeCalled();
    });
  });
});
<|endoftext|>


<commit_before>/*
 * Space Disk Utility
 */

const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

const St = imports.gi.St;
const GObject = imports.gi.GObject;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;

const Main = imports.ui.main;
const Panel = imports.ui.panel;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const MessageTray = imports.ui.messageTray;

const Util = imports.misc.util;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Utils = Me.imports.utils;

const Gettext = imports.gettext.domain('space');
const _ = Gettext.gettext;

/*
 * Initialize application
 */
function init() {
    Utils.initTranslations("space");
}

/*
 * Application window
 */
const SpaceIndicator = new Lang.Class({
    Name: 'SpaceIndicator',
    Extends: PanelMenu.Button,

    _TimeoutUd: null,
    _FirstTimeoutId: null,
    _updateProcess_sourceId: null,
    _updateProcess_stream: null,

    _init: function() {
        this.parent(0.0, "SpaceIndicator");
        Gtk.IconTheme.get_default().append_search_path(Me.dir.get_child('icons').get_path());

        this.updateIcon = new St.Icon({icon_name: "hard-disk",
            style_class: 'system-status-icon'});

        let box = new St.BoxLayout({ vertical: false,
            style_class: 'panel-status-menu-box' });
        this.label = new St.Label({ text: '',
            y_expand: true,
            y_align: Clutter.ActorAlign.CENTER });

        box.add_child(this.updateIcon);
        box.add_child(this.label);
        this.actor.add_child(box);

        // Prepare menu
        this.menuExpander = new PopupMenu.PopupSubMenuMenuItem('');
        this.updatesListMenuLabel = new St.Label();
        this.menuExpander.menu.box.add(this.updatesListMenuLabel);
        this.menuExpander.menu.box.style_class = 'space-list';

        // Configure settings popup
        let settingsMenuItem = new PopupMenu.PopupMenuItem(_('Settings'));

        //Add menu elements
        this.menu.addMenuItem(this.menuExpander);
        this.menu.addMenuItem(settingsMenuItem);

        // Apply action to menu
        settingsMenuItem.connect('activate', Lang.bind(this, this._openSettings));
    },

    _openSettings: function () {
         Util.spawn([ "gnome-shell-extension-prefs", Me.uuid ]);
    },
    destroy: function() {
    },
});

/*
 * Enable/Disable extension
 */
let spacediskindicator;

function enable() {
    spacediskindicator = new SpaceIndicator();
    Main.panel.addToStatusArea("SpaceIndicator", spacediskindicator);
}

function disable() {
    spacediskindicator.destroy();
}
<commit_msg>Change indentation<commit_after>/*
 * Space Disk Utility
 */

const Clutter = imports.gi.Clutter;
const Lang = imports.lang;

const St = imports.gi.St;
const GObject = imports.gi.GObject;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Gio = imports.gi.Gio;

const Main = imports.ui.main;
const Panel = imports.ui.panel;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const MessageTray = imports.ui.messageTray;

const Util = imports.misc.util;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Utils = Me.imports.utils;

const Gettext = imports.gettext.domain('space');
const _ = Gettext.gettext;

/*
 * Initialize application
 */
function init() {
    Utils.initTranslations("space");
}

/*
 * Application window
 */
const SpaceIndicator = new Lang.Class({
  Name: 'SpaceIndicator',
  Extends: PanelMenu.Button,

  _TimeoutUd: null,
  _FirstTimeoutId: null,
  _updateProcess_sourceId: null,
  _updateProcess_stream: null,

  _init: function() {
    this.parent(0.0, "SpaceIndicator");
    Gtk.IconTheme.get_default().append_search_path(Me.dir.get_child('icons').get_path());

    this.updateIcon = new St.Icon({icon_name: "hard-disk", style_class: 'system-status-icon'});

    let box = new St.BoxLayout({ vertical: false, style_class: 'panel-status-menu-box' });
    this.label = new St.Label({ text: '', y_expand: true, y_align: Clutter.ActorAlign.CENTER });

    box.add_child(this.updateIcon);
    box.add_child(this.label);
    this.actor.add_child(box);

    // Prepare menu
    this.menuExpander = new PopupMenu.PopupSubMenuMenuItem('');
    this.updatesListMenuLabel = new St.Label();
    this.menuExpander.menu.box.add(this.updatesListMenuLabel);
    this.menuExpander.menu.box.style_class = 'space-list';

    // Configure settings popup
    let settingsMenuItem = new PopupMenu.PopupMenuItem(_('Settings'));

    //Add menu elements
    this.menu.addMenuItem(this.menuExpander);
    this.menu.addMenuItem(settingsMenuItem);

    // Apply action to menu
    settingsMenuItem.connect('activate', Lang.bind(this, this._openSettings));
  },

  _openSettings: function () {
    Util.spawn([ "gnome-shell-extension-prefs", Me.uuid ]);
  },
  destroy: function() {
  },
});

/*
 * Enable/Disable extension
 */
let spacediskindicator;

function enable() {
  spacediskindicator = new SpaceIndicator();
  Main.panel.addToStatusArea("SpaceIndicator", spacediskindicator);
}

function disable() {
  spacediskindicator.destroy();
}
<|endoftext|>


<commit_before>var vscode = require('vscode');
var renderTableInOutputChannel = require('./view');
var fzCalculator = require('filesize-calculator');

var window = vscode.window;
var workspace = vscode.workspace;

var statusBarItem, oc, info, config, isShowingDetailedInfo;

function updateConfig() {
  var configuration = workspace.getConfiguration('filesize');
  config = {
    useDecimal: configuration.get('useDecimal'),
    use24HourFormat: configuration.get('use24HourFormat'),
    showGzip: configuration.get('showGzip'),
    showGzipInStatusBar: configuration.get('showGzipInStatusBar')
  };
  updateStatusBarItem();
  return config;
}

function showStatusBarItem(newInfo) {
  info = fzCalculator.addPrettySize(newInfo, config);
  if (info && info.prettySize) {
    statusBarItem.text = info.prettySize;
    if (config.showGzipInStatusBar) {
      statusBarItem.text = `Min: ${info.prettySize}`;
      info = fzCalculator.addGzipSize(info, config);
      statusBarItem.text += ` | Gzip: ${info.gzipSize}`
    }
    statusBarItem.show();
  }
}

function hideStatusBarItem() {
  hideDetailedInfo();
  statusBarItem.text = '';
  statusBarItem.hide();
}

// Update simple info in the status bar
function updateStatusBarItem() {
  try {
    var currentEditor = window.activeTextEditor._documentData._document;
    if (currentEditor && currentEditor.uri.scheme === 'file') {
      hideDetailedInfo();
      showStatusBarItem(fzCalculator.loadFileInfoSync(currentEditor.fileName));
    } else {
      if (currentEditor.uri.scheme !== 'output') hideStatusBarItem();
    }
  } catch (e) {
    hideStatusBarItem();
  }
}

// Show detailed filesize info in the OC
function showDetailedInfo() {
  if (info && info.prettySize) {
    info = config.showGzip ? fzCalculator.addGzipSize(info, config) : info;
    info = fzCalculator.addMimeTypeInfo(info);
    info = fzCalculator.addPrettyDateInfo(info, config);
    const table = [];
    if (info.prettySize) table.push({ header: 'Size', content: info.prettySize });
    if (info.gzipSize) table.push({ header: 'Gzipped', content: info.gzipSize });
    if (info.mimeType) table.push({ header: 'Mime type', content: info.mimeType });
    if (info.prettyDateCreated) table.push({ header: 'Created', content: info.prettyDateCreated });
    if (info.prettyDateChanged) table.push({ header: 'Changed', content: info.prettyDateChanged });
    renderTableInOutputChannel(oc, info.absolutePath, table);
  } else {
    oc.clear();
    oc.appendLine('No file information available for this context!');
  }
  oc.show(true);
  isShowingDetailedInfo = true;
}

function hideDetailedInfo() {
  oc.hide();
  isShowingDetailedInfo = false;
}

function toggleDetailedInfo() {
  if (isShowingDetailedInfo) {
    hideDetailedInfo();
  } else {
    showDetailedInfo();
  }
}

// Called when VS Code activates the extension
function activate(context) {
  console.log('filesize is active');

  // Set up statusBarItem
  statusBarItem = window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1);
  statusBarItem.command = 'extension.toggleFilesizeInfo';
  statusBarItem.tooltip = 'Current file size - Click to toggle more info';

  // Global OutputChannel to be used for the extension detailed info
  oc = window.createOutputChannel('filesize');

  // Update handlers
  var onSave = workspace.onDidSaveTextDocument(updateStatusBarItem);
  var onActiveEditorChanged = window.onDidChangeActiveTextEditor(updateStatusBarItem);
  var onChangeConfig = workspace.onDidChangeConfiguration(updateConfig);

  // Show detailed info through custom command
  var command = vscode.commands.registerCommand('extension.toggleFilesizeInfo', toggleDetailedInfo);

  // Register disposables that get disposed when deactivating
  context.subscriptions.push(onSave);
  context.subscriptions.push(onChangeConfig);
  context.subscriptions.push(onActiveEditorChanged);
  context.subscriptions.push(command);

  // Set default config
  updateConfig();
}

// Called when VS Code deactivates the extension
function deactivate() {
  if (oc) {
    oc.clear();
    oc.dispose();
  }
  if (statusBarItem) {
    statusBarItem.hide();
    statusBarItem.dispose();
  }
  oc = null;
  statusBarItem = null;
  config = null;
  info = null;
}

module.exports = {
  activate: activate,
  deactivate: deactivate
};
<commit_msg>Fix issue with 1.54+. Close #28<commit_after>var vscode = require('vscode');
var renderTableInOutputChannel = require('./view');
var fzCalculator = require('filesize-calculator');

var window = vscode.window;
var workspace = vscode.workspace;

var statusBarItem, oc, info, config, isShowingDetailedInfo;

function updateConfig() {
  var configuration = workspace.getConfiguration('filesize');
  config = {
    useDecimal: configuration.get('useDecimal'),
    use24HourFormat: configuration.get('use24HourFormat'),
    showGzip: configuration.get('showGzip'),
    showGzipInStatusBar: configuration.get('showGzipInStatusBar')
  };
  updateStatusBarItem();
  return config;
}

function showStatusBarItem(newInfo) {
  info = fzCalculator.addPrettySize(newInfo, config);
  if (info && info.prettySize) {
    statusBarItem.text = info.prettySize;
    if (config.showGzipInStatusBar) {
      statusBarItem.text = `Min: ${info.prettySize}`;
      info = fzCalculator.addGzipSize(info, config);
      statusBarItem.text += ` | Gzip: ${info.gzipSize}`
    }
    statusBarItem.show();
  }
}

function hideStatusBarItem() {
  hideDetailedInfo();
  statusBarItem.text = '';
  statusBarItem.hide();
}

// Update simple info in the status bar
function updateStatusBarItem() {
  try {
    var currentEditor = window.activeTextEditor.document;
    if (currentEditor && currentEditor.uri.scheme === 'file') {
      hideDetailedInfo();
      showStatusBarItem(fzCalculator.loadFileInfoSync(currentEditor.fileName));
    } else {
      if (currentEditor.uri.scheme !== 'output') hideStatusBarItem();
    }
  } catch (e) {
    hideStatusBarItem();
  }
}

// Show detailed filesize info in the OC
function showDetailedInfo() {
  if (info && info.prettySize) {
    info = config.showGzip ? fzCalculator.addGzipSize(info, config) : info;
    info = fzCalculator.addMimeTypeInfo(info);
    info = fzCalculator.addPrettyDateInfo(info, config);
    const table = [];
    if (info.prettySize) table.push({ header: 'Size', content: info.prettySize });
    if (info.gzipSize) table.push({ header: 'Gzipped', content: info.gzipSize });
    if (info.mimeType) table.push({ header: 'Mime type', content: info.mimeType });
    if (info.prettyDateCreated) table.push({ header: 'Created', content: info.prettyDateCreated });
    if (info.prettyDateChanged) table.push({ header: 'Changed', content: info.prettyDateChanged });
    renderTableInOutputChannel(oc, info.absolutePath, table);
  } else {
    oc.clear();
    oc.appendLine('No file information available for this context!');
  }
  oc.show(true);
  isShowingDetailedInfo = true;
}

function hideDetailedInfo() {
  oc.hide();
  isShowingDetailedInfo = false;
}

function toggleDetailedInfo() {
  if (isShowingDetailedInfo) {
    hideDetailedInfo();
  } else {
    showDetailedInfo();
  }
}

// Called when VS Code activates the extension
function activate(context) {
  console.log('filesize is active');

  // Set up statusBarItem
  statusBarItem = window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1);
  statusBarItem.command = 'extension.toggleFilesizeInfo';
  statusBarItem.tooltip = 'Current file size - Click to toggle more info';

  // Global OutputChannel to be used for the extension detailed info
  oc = window.createOutputChannel('filesize');

  // Update handlers
  var onSave = workspace.onDidSaveTextDocument(updateStatusBarItem);
  var onActiveEditorChanged = window.onDidChangeActiveTextEditor(updateStatusBarItem);
  var onChangeConfig = workspace.onDidChangeConfiguration(updateConfig);

  // Show detailed info through custom command
  var command = vscode.commands.registerCommand('extension.toggleFilesizeInfo', toggleDetailedInfo);

  // Register disposables that get disposed when deactivating
  context.subscriptions.push(onSave);
  context.subscriptions.push(onChangeConfig);
  context.subscriptions.push(onActiveEditorChanged);
  context.subscriptions.push(command);

  // Set default config
  updateConfig();
}

// Called when VS Code deactivates the extension
function deactivate() {
  if (oc) {
    oc.clear();
    oc.dispose();
  }
  if (statusBarItem) {
    statusBarItem.hide();
    statusBarItem.dispose();
  }
  oc = null;
  statusBarItem = null;
  config = null;
  info = null;
}

module.exports = {
  activate: activate,
  deactivate: deactivate
};
<|endoftext|>


<commit_before>var vscode = require('vscode');

var providers = require('./providers');

function activate(context) {
    var disposable = vscode.commands.registerCommand('extension.addpipe', function () {
        var editor = vscode.window.activeTextEditor;
        if (editor != undefined) {
            var position = editor.selection.active;
            var textline = editor.document.getText(new vscode.Range(new vscode.Position(0, 0), position));
            var Regex = /(\/\/.*$)|(\/\/.*\r?\n)|("(""|[^"]*)*")|("[^"]*$)|([^"\/]+)/g;
            while ((ArrStrings = Regex.exec(textline)) != null) {
                var stringmatsh = ArrStrings[5];
            }
            if (stringmatsh != undefined) {
                editor.edit(function (editBuilder) {
                    editBuilder.insert(new vscode.Position(position.line, position.character), '\n|');
                });
            } else {
                editor.edit(function (editBuilder) {
                    editBuilder.insert(new vscode.Position(position.line, position.character), '\n');
                });
            }
        }
    });
    context.subscriptions.push(disposable);

    disposable = vscode.languages.registerDocumentSymbolProvider("bsl", new providers.DocumentSymbolProvider());
    context.subscriptions.push(disposable);

    disposable = vscode.languages.registerDefinitionProvider("bsl", new providers.DefinitionProvider());
    context.subscriptions.push(disposable);

}
exports.activate = activate;
<commit_msg>Рефакторинг<commit_after>var vscode = require('vscode');

var bslProviders = require('./providers');

function activate(context) {
    var disposable = vscode.commands.registerCommand('extension.addpipe', function () {
        var editor = vscode.window.activeTextEditor;
        if (editor != undefined) {
            var position = editor.selection.active;
            var textline = editor.document.getText(new vscode.Range(new vscode.Position(0, 0), position));
            var Regex = /(\/\/.*$)|(\/\/.*\r?\n)|("(""|[^"]*)*")|("[^"]*$)|([^"\/]+)/g;
            var ArrStrings;
            while ((ArrStrings = Regex.exec(textline)) != null) {
                var stringmatsh = ArrStrings[5];
            }
            if (stringmatsh != undefined) {
                editor.edit(function (editBuilder) {
                    editBuilder.insert(new vscode.Position(position.line, position.character), '\n|');
                });
            } else {
                editor.edit(function (editBuilder) {
                    editBuilder.insert(new vscode.Position(position.line, position.character), '\n');
                });
            }
        }
    });
    context.subscriptions.push(disposable);

    disposable = vscode.languages.registerDocumentSymbolProvider("bsl", new bslProviders.DocumentSymbolProvider());
    context.subscriptions.push(disposable);

    disposable = vscode.languages.registerDefinitionProvider("bsl", new bslProviders.DefinitionProvider());
    context.subscriptions.push(disposable);

}

exports.activate = activate;
<|endoftext|>