browser-sync
Version:
Live CSS Reload & Browser Syncing
2,152 lines (1,839 loc) • 249 kB
JavaScript
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 33);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
var g;
// This works in non-strict mode
g = (function() {
return this;
})();
try {
// This works if eval is allowed (see CSP)
g = g || Function("return this")() || (1,eval)("this");
} catch(e) {
// This works if the window reference is available
if(typeof window === "object")
g = window;
}
// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}
module.exports = g;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process) {/**
* This is the web browser implementation of `debug()`.
*
* Expose `debug()` as the module.
*/
exports = module.exports = __webpack_require__(37);
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;
exports.storage = 'undefined' != typeof chrome
&& 'undefined' != typeof chrome.storage
? chrome.storage.local
: localstorage();
/**
* Colors.
*/
exports.colors = [
'lightseagreen',
'forestgreen',
'goldenrod',
'dodgerblue',
'darkorchid',
'crimson'
];
/**
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
* and the Firebug extension (any Firefox version) are known
* to support "%c" CSS customizations.
*
* TODO: add a `localStorage` variable to explicitly enable/disable colors
*/
function useColors() {
// NB: In an Electron preload script, document will be defined but not fully
// initialized. Since we know we're in Chrome, we'll just detect this case
// explicitly
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
return true;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
// is firebug? http://stackoverflow.com/a/398120/376773
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
// is firefox >= v31?
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
// double check webkit in userAgent just in case we are in a worker
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
}
/**
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
*/
exports.formatters.j = function(v) {
try {
return JSON.stringify(v);
} catch (err) {
return '[UnexpectedJSONParseError]: ' + err.message;
}
};
/**
* Colorize log arguments if enabled.
*
* @api public
*/
function formatArgs(args) {
var useColors = this.useColors;
args[0] = (useColors ? '%c' : '')
+ this.namespace
+ (useColors ? ' %c' : ' ')
+ args[0]
+ (useColors ? '%c ' : ' ')
+ '+' + exports.humanize(this.diff);
if (!useColors) return;
var c = 'color: ' + this.color;
args.splice(1, 0, c, 'color: inherit')
// the final "%c" is somewhat tricky, because there could be other
// arguments passed either before or after the %c, so we need to
// figure out the correct index to insert the CSS into
var index = 0;
var lastC = 0;
args[0].replace(/%[a-zA-Z%]/g, function(match) {
if ('%%' === match) return;
index++;
if ('%c' === match) {
// we only are interested in the *last* %c
// (the user may have provided their own)
lastC = index;
}
});
args.splice(lastC, 0, c);
}
/**
* Invokes `console.log()` when available.
* No-op when `console.log` is not a "function".
*
* @api public
*/
function log() {
// this hackery is required for IE8/9, where
// the `console.log` function doesn't have 'apply'
return 'object' === typeof console
&& console.log
&& Function.prototype.apply.call(console.log, console, arguments);
}
/**
* Save `namespaces`.
*
* @param {String} namespaces
* @api private
*/
function save(namespaces) {
try {
if (null == namespaces) {
exports.storage.removeItem('debug');
} else {
exports.storage.debug = namespaces;
}
} catch(e) {}
}
/**
* Load `namespaces`.
*
* @return {String} returns the previously persisted debug modes
* @api private
*/
function load() {
var r;
try {
r = exports.storage.debug;
} catch(e) {}
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
if (!r && typeof process !== 'undefined' && 'env' in process) {
r = process.env.DEBUG;
}
return r;
}
/**
* Enable namespaces listed in `localStorage.debug` initially.
*/
exports.enable(load());
/**
* Localstorage attempts to return the localstorage.
*
* This is necessary because safari throws
* when a user disables cookies/localstorage
* and you attempt to access it.
*
* @return {LocalStorage}
* @api private
*/
function localstorage() {
try {
return window.localStorage;
} catch (e) {}
}
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15)))
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Expose `Emitter`.
*/
if (true) {
module.exports = Emitter;
}
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter(obj) {
if (obj) return mixin(obj);
};
/**
* Mixin the emitter properties.
*
* @param {Object} obj
* @return {Object}
* @api private
*/
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
}
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on =
Emitter.prototype.addEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
function on() {
this.off(event, on);
fn.apply(this, arguments);
}
on.fn = fn;
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off =
Emitter.prototype.removeListener =
Emitter.prototype.removeAllListeners =
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks['$' + event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks['$' + event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1);
break;
}
}
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks['$' + event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
/**
* Return array of callbacks for `event`.
*
* @param {String} event
* @return {Array}
* @api public
*/
Emitter.prototype.listeners = function(event){
this._callbacks = this._callbacks || {};
return this._callbacks['$' + event] || [];
};
/**
* Check if this emitter has `event` handlers.
*
* @param {String} event
* @return {Boolean}
* @api public
*/
Emitter.prototype.hasListeners = function(event){
return !! this.listeners(event).length;
};
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/**
* Module dependencies.
*/
var keys = __webpack_require__(46);
var hasBinary = __webpack_require__(16);
var sliceBuffer = __webpack_require__(47);
var after = __webpack_require__(48);
var utf8 = __webpack_require__(49);
var base64encoder;
if (global && global.ArrayBuffer) {
base64encoder = __webpack_require__(51);
}
/**
* Check if we are running an android browser. That requires us to use
* ArrayBuffer with polling transports...
*
* http://ghinda.net/jpeg-blob-ajax-android/
*/
var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent);
/**
* Check if we are running in PhantomJS.
* Uploading a Blob with PhantomJS does not work correctly, as reported here:
* https://github.com/ariya/phantomjs/issues/11395
* @type boolean
*/
var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent);
/**
* When true, avoids using Blobs to encode payloads.
* @type boolean
*/
var dontSendBlobs = isAndroid || isPhantomJS;
/**
* Current protocol version.
*/
exports.protocol = 3;
/**
* Packet types.
*/
var packets = exports.packets = {
open: 0 // non-ws
, close: 1 // non-ws
, ping: 2
, pong: 3
, message: 4
, upgrade: 5
, noop: 6
};
var packetslist = keys(packets);
/**
* Premade error packet.
*/
var err = { type: 'error', data: 'parser error' };
/**
* Create a blob api even for blob builder when vendor prefixes exist
*/
var Blob = __webpack_require__(52);
/**
* Encodes a packet.
*
* <packet type id> [ <data> ]
*
* Example:
*
* 5hello world
* 3
* 4
*
* Binary is encoded in an identical principle
*
* @api private
*/
exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
if (typeof supportsBinary === 'function') {
callback = supportsBinary;
supportsBinary = false;
}
if (typeof utf8encode === 'function') {
callback = utf8encode;
utf8encode = null;
}
var data = (packet.data === undefined)
? undefined
: packet.data.buffer || packet.data;
if (global.ArrayBuffer && data instanceof ArrayBuffer) {
return encodeArrayBuffer(packet, supportsBinary, callback);
} else if (Blob && data instanceof global.Blob) {
return encodeBlob(packet, supportsBinary, callback);
}
// might be an object with { base64: true, data: dataAsBase64String }
if (data && data.base64) {
return encodeBase64Object(packet, callback);
}
// Sending data as a utf-8 string
var encoded = packets[packet.type];
// data fragment is optional
if (undefined !== packet.data) {
encoded += utf8encode ? utf8.encode(String(packet.data), { strict: false }) : String(packet.data);
}
return callback('' + encoded);
};
function encodeBase64Object(packet, callback) {
// packet data is an object { base64: true, data: dataAsBase64String }
var message = 'b' + exports.packets[packet.type] + packet.data.data;
return callback(message);
}
/**
* Encode packet helpers for binary types
*/
function encodeArrayBuffer(packet, supportsBinary, callback) {
if (!supportsBinary) {
return exports.encodeBase64Packet(packet, callback);
}
var data = packet.data;
var contentArray = new Uint8Array(data);
var resultBuffer = new Uint8Array(1 + data.byteLength);
resultBuffer[0] = packets[packet.type];
for (var i = 0; i < contentArray.length; i++) {
resultBuffer[i+1] = contentArray[i];
}
return callback(resultBuffer.buffer);
}
function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
if (!supportsBinary) {
return exports.encodeBase64Packet(packet, callback);
}
var fr = new FileReader();
fr.onload = function() {
packet.data = fr.result;
exports.encodePacket(packet, supportsBinary, true, callback);
};
return fr.readAsArrayBuffer(packet.data);
}
function encodeBlob(packet, supportsBinary, callback) {
if (!supportsBinary) {
return exports.encodeBase64Packet(packet, callback);
}
if (dontSendBlobs) {
return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
}
var length = new Uint8Array(1);
length[0] = packets[packet.type];
var blob = new Blob([length.buffer, packet.data]);
return callback(blob);
}
/**
* Encodes a packet with binary data in a base64 string
*
* @param {Object} packet, has `type` and `data`
* @return {String} base64 encoded message
*/
exports.encodeBase64Packet = function(packet, callback) {
var message = 'b' + exports.packets[packet.type];
if (Blob && packet.data instanceof global.Blob) {
var fr = new FileReader();
fr.onload = function() {
var b64 = fr.result.split(',')[1];
callback(message + b64);
};
return fr.readAsDataURL(packet.data);
}
var b64data;
try {
b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
} catch (e) {
// iPhone Safari doesn't let you apply with typed arrays
var typed = new Uint8Array(packet.data);
var basic = new Array(typed.length);
for (var i = 0; i < typed.length; i++) {
basic[i] = typed[i];
}
b64data = String.fromCharCode.apply(null, basic);
}
message += global.btoa(b64data);
return callback(message);
};
/**
* Decodes a packet. Changes format to Blob if requested.
*
* @return {Object} with `type` and `data` (if any)
* @api private
*/
exports.decodePacket = function (data, binaryType, utf8decode) {
if (data === undefined) {
return err;
}
// String data
if (typeof data === 'string') {
if (data.charAt(0) === 'b') {
return exports.decodeBase64Packet(data.substr(1), binaryType);
}
if (utf8decode) {
data = tryDecode(data);
if (data === false) {
return err;
}
}
var type = data.charAt(0);
if (Number(type) != type || !packetslist[type]) {
return err;
}
if (data.length > 1) {
return { type: packetslist[type], data: data.substring(1) };
} else {
return { type: packetslist[type] };
}
}
var asArray = new Uint8Array(data);
var type = asArray[0];
var rest = sliceBuffer(data, 1);
if (Blob && binaryType === 'blob') {
rest = new Blob([rest]);
}
return { type: packetslist[type], data: rest };
};
function tryDecode(data) {
try {
data = utf8.decode(data, { strict: false });
} catch (e) {
return false;
}
return data;
}
/**
* Decodes a packet encoded in a base64 string
*
* @param {String} base64 encoded message
* @return {Object} with `type` and `data` (if any)
*/
exports.decodeBase64Packet = function(msg, binaryType) {
var type = packetslist[msg.charAt(0)];
if (!base64encoder) {
return { type: type, data: { base64: true, data: msg.substr(1) } };
}
var data = base64encoder.decode(msg.substr(1));
if (binaryType === 'blob' && Blob) {
data = new Blob([data]);
}
return { type: type, data: data };
};
/**
* Encodes multiple messages (payload).
*
* <length>:data
*
* Example:
*
* 11:hello world2:hi
*
* If any contents are binary, they will be encoded as base64 strings. Base64
* encoded strings are marked with a b before the length specifier
*
* @param {Array} packets
* @api private
*/
exports.encodePayload = function (packets, supportsBinary, callback) {
if (typeof supportsBinary === 'function') {
callback = supportsBinary;
supportsBinary = null;
}
var isBinary = hasBinary(packets);
if (supportsBinary && isBinary) {
if (Blob && !dontSendBlobs) {
return exports.encodePayloadAsBlob(packets, callback);
}
return exports.encodePayloadAsArrayBuffer(packets, callback);
}
if (!packets.length) {
return callback('0:');
}
function setLengthHeader(message) {
return message.length + ':' + message;
}
function encodeOne(packet, doneCallback) {
exports.encodePacket(packet, !isBinary ? false : supportsBinary, false, function(message) {
doneCallback(null, setLengthHeader(message));
});
}
map(packets, encodeOne, function(err, results) {
return callback(results.join(''));
});
};
/**
* Async array map using after
*/
function map(ary, each, done) {
var result = new Array(ary.length);
var next = after(ary.length, done);
var eachWithIndex = function(i, el, cb) {
each(el, function(error, msg) {
result[i] = msg;
cb(error, result);
});
};
for (var i = 0; i < ary.length; i++) {
eachWithIndex(i, ary[i], next);
}
}
/*
* Decodes data when a payload is maybe expected. Possible binary contents are
* decoded from their base64 representation
*
* @param {String} data, callback method
* @api public
*/
exports.decodePayload = function (data, binaryType, callback) {
if (typeof data !== 'string') {
return exports.decodePayloadAsBinary(data, binaryType, callback);
}
if (typeof binaryType === 'function') {
callback = binaryType;
binaryType = null;
}
var packet;
if (data === '') {
// parser error - ignoring payload
return callback(err, 0, 1);
}
var length = '', n, msg;
for (var i = 0, l = data.length; i < l; i++) {
var chr = data.charAt(i);
if (chr !== ':') {
length += chr;
continue;
}
if (length === '' || (length != (n = Number(length)))) {
// parser error - ignoring payload
return callback(err, 0, 1);
}
msg = data.substr(i + 1, n);
if (length != msg.length) {
// parser error - ignoring payload
return callback(err, 0, 1);
}
if (msg.length) {
packet = exports.decodePacket(msg, binaryType, false);
if (err.type === packet.type && err.data === packet.data) {
// parser error in individual packet - ignoring payload
return callback(err, 0, 1);
}
var ret = callback(packet, i + n, l);
if (false === ret) return;
}
// advance cursor
i += n;
length = '';
}
if (length !== '') {
// parser error - ignoring payload
return callback(err, 0, 1);
}
};
/**
* Encodes multiple messages (payload) as binary.
*
* <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
* 255><data>
*
* Example:
* 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
*
* @param {Array} packets
* @return {ArrayBuffer} encoded payload
* @api private
*/
exports.encodePayloadAsArrayBuffer = function(packets, callback) {
if (!packets.length) {
return callback(new ArrayBuffer(0));
}
function encodeOne(packet, doneCallback) {
exports.encodePacket(packet, true, true, function(data) {
return doneCallback(null, data);
});
}
map(packets, encodeOne, function(err, encodedPackets) {
var totalLength = encodedPackets.reduce(function(acc, p) {
var len;
if (typeof p === 'string'){
len = p.length;
} else {
len = p.byteLength;
}
return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
}, 0);
var resultArray = new Uint8Array(totalLength);
var bufferIndex = 0;
encodedPackets.forEach(function(p) {
var isString = typeof p === 'string';
var ab = p;
if (isString) {
var view = new Uint8Array(p.length);
for (var i = 0; i < p.length; i++) {
view[i] = p.charCodeAt(i);
}
ab = view.buffer;
}
if (isString) { // not true binary
resultArray[bufferIndex++] = 0;
} else { // true binary
resultArray[bufferIndex++] = 1;
}
var lenStr = ab.byteLength.toString();
for (var i = 0; i < lenStr.length; i++) {
resultArray[bufferIndex++] = parseInt(lenStr[i]);
}
resultArray[bufferIndex++] = 255;
var view = new Uint8Array(ab);
for (var i = 0; i < view.length; i++) {
resultArray[bufferIndex++] = view[i];
}
});
return callback(resultArray.buffer);
});
};
/**
* Encode as Blob
*/
exports.encodePayloadAsBlob = function(packets, callback) {
function encodeOne(packet, doneCallback) {
exports.encodePacket(packet, true, true, function(encoded) {
var binaryIdentifier = new Uint8Array(1);
binaryIdentifier[0] = 1;
if (typeof encoded === 'string') {
var view = new Uint8Array(encoded.length);
for (var i = 0; i < encoded.length; i++) {
view[i] = encoded.charCodeAt(i);
}
encoded = view.buffer;
binaryIdentifier[0] = 0;
}
var len = (encoded instanceof ArrayBuffer)
? encoded.byteLength
: encoded.size;
var lenStr = len.toString();
var lengthAry = new Uint8Array(lenStr.length + 1);
for (var i = 0; i < lenStr.length; i++) {
lengthAry[i] = parseInt(lenStr[i]);
}
lengthAry[lenStr.length] = 255;
if (Blob) {
var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
doneCallback(null, blob);
}
});
}
map(packets, encodeOne, function(err, results) {
return callback(new Blob(results));
});
};
/*
* Decodes data when a payload is maybe expected. Strings are decoded by
* interpreting each byte as a key code for entries marked to start with 0. See
* description of encodePayloadAsBinary
*
* @param {ArrayBuffer} data, callback method
* @api public
*/
exports.decodePayloadAsBinary = function (data, binaryType, callback) {
if (typeof binaryType === 'function') {
callback = binaryType;
binaryType = null;
}
var bufferTail = data;
var buffers = [];
while (bufferTail.byteLength > 0) {
var tailArray = new Uint8Array(bufferTail);
var isString = tailArray[0] === 0;
var msgLength = '';
for (var i = 1; ; i++) {
if (tailArray[i] === 255) break;
// 310 = char length of Number.MAX_VALUE
if (msgLength.length > 310) {
return callback(err, 0, 1);
}
msgLength += tailArray[i];
}
bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
msgLength = parseInt(msgLength);
var msg = sliceBuffer(bufferTail, 0, msgLength);
if (isString) {
try {
msg = String.fromCharCode.apply(null, new Uint8Array(msg));
} catch (e) {
// iPhone Safari doesn't let you apply to typed arrays
var typed = new Uint8Array(msg);
msg = '';
for (var i = 0; i < typed.length; i++) {
msg += String.fromCharCode(typed[i]);
}
}
}
buffers.push(msg);
bufferTail = sliceBuffer(bufferTail, msgLength);
}
var total = buffers.length;
buffers.forEach(function(buffer, i) {
callback(exports.decodePacket(buffer, binaryType, true), i, total);
});
};
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var utils = exports;
/**
* @returns {window}
*/
utils.getWindow = function () {
return window;
};
/**
* @returns {HTMLDocument}
*/
utils.getDocument = function () {
return document;
};
/**
* @returns {HTMLElement}
*/
utils.getBody = function () {
return document.getElementsByTagName("body")[0];
};
/**
* Get the current x/y position crossbow
* @returns {{x: *, y: *}}
*/
utils.getBrowserScrollPosition = function () {
var $window = exports.getWindow();
var $document = exports.getDocument();
var scrollX;
var scrollY;
var dElement = $document.documentElement;
var dBody = $document.body;
if ($window.pageYOffset !== undefined) {
scrollX = $window.pageXOffset;
scrollY = $window.pageYOffset;
}
else {
scrollX = dElement.scrollLeft || dBody.scrollLeft || 0;
scrollY = dElement.scrollTop || dBody.scrollTop || 0;
}
return {
x: scrollX,
y: scrollY
};
};
/**
* @returns {{x: number, y: number}}
*/
utils.getScrollSpace = function () {
var $document = exports.getDocument();
var dElement = $document.documentElement;
var dBody = $document.body;
return {
x: dBody.scrollHeight - dElement.clientWidth,
y: dBody.scrollHeight - dElement.clientHeight
};
};
/**
* Saves scroll position into cookies
*/
utils.saveScrollPosition = function () {
var pos = utils.getBrowserScrollPosition();
pos = [pos.x, pos.y];
utils.getDocument.cookie = "bs_scroll_pos=" + pos.join(",");
};
/**
* Restores scroll position from cookies
*/
utils.restoreScrollPosition = function () {
var pos = utils
.getDocument()
.cookie.replace(/(?:(?:^|.*;\s*)bs_scroll_pos\s*\=\s*([^;]*).*$)|^.*$/, "$1")
.split(",");
utils.getWindow().scrollTo(pos[0], pos[1]);
};
/**
* @param tagName
* @param elem
* @returns {*|number}
*/
utils.getElementIndex = function (tagName, elem) {
var allElems = utils.getDocument().getElementsByTagName(tagName);
return Array.prototype.indexOf.call(allElems, elem);
};
/**
* Force Change event on radio & checkboxes (IE)
*/
utils.forceChange = function (elem) {
elem.blur();
elem.focus();
};
/**
* @param elem
* @returns {{tagName: (elem.tagName|*), index: *}}
*/
utils.getElementData = function (elem) {
var tagName = elem.tagName;
var index = utils.getElementIndex(tagName, elem);
return {
tagName: tagName,
index: index
};
};
/**
* @param {string} tagName
* @param {number} index
*/
utils.getSingleElement = function (tagName, index) {
var elems = utils.getDocument().getElementsByTagName(tagName);
return elems[index];
};
/**
* Get the body element
*/
utils.getBody = function () {
return utils.getDocument().getElementsByTagName("body")[0];
};
/**
* @param {{x: number, y: number}} pos
*/
utils.setScroll = function (pos) {
utils.getWindow().scrollTo(pos.x, pos.y);
};
/**
* Hard reload
*/
utils.reloadBrowser = function () {
utils.getWindow().location.reload(true);
};
/**
* Foreach polyfill
* @param coll
* @param fn
*/
utils.forEach = function (coll, fn) {
for (var i = 0, n = coll.length; i < n; i += 1) {
fn(coll[i], i, coll);
}
};
/**
* Are we dealing with old IE?
* @returns {boolean}
*/
utils.isOldIe = function () {
return typeof utils.getWindow().attachEvent !== "undefined";
};
/**
* Split the URL information
* @returns {object}
*/
utils.getLocation = function (url) {
var location = utils.getDocument().createElement("a");
location.href = url;
if (location.host === "") {
location.href = location.href;
}
return location;
};
/***/ }),
/* 5 */
/***/ (function(module, exports) {
/**
* Compiles a querystring
* Returns string representation of the object
*
* @param {Object}
* @api private
*/
exports.encode = function (obj) {
var str = '';
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
if (str.length) str += '&';
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
}
}
return str;
};
/**
* Parses a simple querystring into an object
*
* @param {String} qs
* @api private
*/
exports.decode = function(qs){
var qry = {};
var pairs = qs.split('&');
for (var i = 0, l = pairs.length; i < l; i++) {
var pair = pairs[i].split('=');
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return qry;
};
/***/ }),
/* 6 */
/***/ (function(module, exports) {
module.exports = function(a, b){
var fn = function(){};
fn.prototype = b.prototype;
a.prototype = new fn;
a.prototype.constructor = a;
};
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
exports.events = {};
/**
* @param name
* @param data
*/
exports.emit = function (name, data) {
var event = exports.events[name];
var listeners;
if (event && event.listeners) {
listeners = event.listeners;
for (var i = 0, n = listeners.length; i < n; i += 1) {
listeners[i](data);
}
}
};
/**
* @param name
* @param func
*/
exports.on = function (name, func) {
var events = exports.events;
if (!events[name]) {
events[name] = {
listeners: [func]
};
}
else {
events[name].listeners.push(func);
}
};
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Module dependencies.
*/
var debug = __webpack_require__(1)('socket.io-parser');
var Emitter = __webpack_require__(2);
var hasBin = __webpack_require__(16);
var binary = __webpack_require__(40);
var isBuf = __webpack_require__(17);
/**
* Protocol version.
*
* @api public
*/
exports.protocol = 4;
/**
* Packet types.
*
* @api public
*/
exports.types = [
'CONNECT',
'DISCONNECT',
'EVENT',
'ACK',
'ERROR',
'BINARY_EVENT',
'BINARY_ACK'
];
/**
* Packet type `connect`.
*
* @api public
*/
exports.CONNECT = 0;
/**
* Packet type `disconnect`.
*
* @api public
*/
exports.DISCONNECT = 1;
/**
* Packet type `event`.
*
* @api public
*/
exports.EVENT = 2;
/**
* Packet type `ack`.
*
* @api public
*/
exports.ACK = 3;
/**
* Packet type `error`.
*
* @api public
*/
exports.ERROR = 4;
/**
* Packet type 'binary event'
*
* @api public
*/
exports.BINARY_EVENT = 5;
/**
* Packet type `binary ack`. For acks with binary arguments.
*
* @api public
*/
exports.BINARY_ACK = 6;
/**
* Encoder constructor.
*
* @api public
*/
exports.Encoder = Encoder;
/**
* Decoder constructor.
*
* @api public
*/
exports.Decoder = Decoder;
/**
* A socket.io Encoder instance
*
* @api public
*/
function Encoder() {}
/**
* Encode a packet as a single string if non-binary, or as a
* buffer sequence, depending on packet type.
*
* @param {Object} obj - packet object
* @param {Function} callback - function to handle encodings (likely engine.write)
* @return Calls callback with Array of encodings
* @api public
*/
Encoder.prototype.encode = function(obj, callback){
if ((obj.type === exports.EVENT || obj.type === exports.ACK) && hasBin(obj.data)) {
obj.type = obj.type === exports.EVENT ? exports.BINARY_EVENT : exports.BINARY_ACK;
}
debug('encoding packet %j', obj);
if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) {
encodeAsBinary(obj, callback);
}
else {
var encoding = encodeAsString(obj);
callback([encoding]);
}
};
/**
* Encode packet as string.
*
* @param {Object} packet
* @return {String} encoded
* @api private
*/
function encodeAsString(obj) {
// first is type
var str = '' + obj.type;
// attachments if we have them
if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) {
str += obj.attachments + '-';
}
// if we have a namespace other than `/`
// we append it followed by a comma `,`
if (obj.nsp && '/' !== obj.nsp) {
str += obj.nsp + ',';
}
// immediately followed by the id
if (null != obj.id) {
str += obj.id;
}
// json data
if (null != obj.data) {
str += JSON.stringify(obj.data);
}
debug('encoded %j as %s', obj, str);
return str;
}
/**
* Encode packet as 'buffer sequence' by removing blobs, and
* deconstructing packet into object with placeholders and
* a list of buffers.
*
* @param {Object} packet
* @return {Buffer} encoded
* @api private
*/
function encodeAsBinary(obj, callback) {
function writeEncoding(bloblessData) {
var deconstruction = binary.deconstructPacket(bloblessData);
var pack = encodeAsString(deconstruction.packet);
var buffers = deconstruction.buffers;
buffers.unshift(pack); // add packet info to beginning of data list
callback(buffers); // write all the buffers
}
binary.removeBlobs(obj, writeEncoding);
}
/**
* A socket.io Decoder instance
*
* @return {Object} decoder
* @api public
*/
function Decoder() {
this.reconstructor = null;
}
/**
* Mix in `Emitter` with Decoder.
*/
Emitter(Decoder.prototype);
/**
* Decodes an ecoded packet string into packet JSON.
*
* @param {String} obj - encoded packet
* @return {Object} packet
* @api public
*/
Decoder.prototype.add = function(obj) {
var packet;
if (typeof obj === 'string') {
packet = decodeString(obj);
if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { // binary packet's json
this.reconstructor = new BinaryReconstructor(packet);
// no attachments, labeled binary but no binary data to follow
if (this.reconstructor.reconPack.attachments === 0) {
this.emit('decoded', packet);
}
} else { // non-binary full packet
this.emit('decoded', packet);
}
}
else if (isBuf(obj) || obj.base64) { // raw binary data
if (!this.reconstructor) {
throw new Error('got binary data when not reconstructing a packet');
} else {
packet = this.reconstructor.takeBinaryData(obj);
if (packet) { // received final buffer
this.reconstructor = null;
this.emit('decoded', packet);
}
}
}
else {
throw new Error('Unknown type: ' + obj);
}
};
/**
* Decode a packet String (JSON data)
*
* @param {String} str
* @return {Object} packet
* @api private
*/
function decodeString(str) {
var i = 0;
// look up type
var p = {
type: Number(str.charAt(0))
};
if (null == exports.types[p.type]) return error();
// look up attachments if type binary
if (exports.BINARY_EVENT === p.type || exports.BINARY_ACK === p.type) {
var buf = '';
while (str.charAt(++i) !== '-') {
buf += str.charAt(i);
if (i == str.length) break;
}
if (buf != Number(buf) || str.charAt(i) !== '-') {
throw new Error('Illegal attachments');
}
p.attachments = Number(buf);
}
// look up namespace (if any)
if ('/' === str.charAt(i + 1)) {
p.nsp = '';
while (++i) {
var c = str.charAt(i);
if (',' === c) break;
p.nsp += c;
if (i === str.length) break;
}
} else {
p.nsp = '/';
}
// look up id
var next = str.charAt(i + 1);
if ('' !== next && Number(next) == next) {
p.id = '';
while (++i) {
var c = str.charAt(i);
if (null == c || Number(c) != c) {
--i;
break;
}
p.id += str.charAt(i);
if (i === str.length) break;
}
p.id = Number(p.id);
}
// look up json data
if (str.charAt(++i)) {
p = tryParse(p, str.substr(i));
}
debug('decoded %s as %j', str, p);
return p;
}
function tryParse(p, str) {
try {
p.data = JSON.parse(str);
} catch(e){
return error();
}
return p;
}
/**
* Deallocates a parser's resources
*
* @api public
*/
Decoder.prototype.destroy = function() {
if (this.reconstructor) {
this.reconstructor.finishedReconstruction();
}
};
/**
* A manager of a binary event's 'buffer sequence'. Should
* be constructed whenever a packet of type BINARY_EVENT is
* decoded.
*
* @param {Object} packet
* @return {BinaryReconstructor} initialized reconstructor
* @api private
*/
function BinaryReconstructor(packet) {
this.reconPack = packet;
this.buffers = [];
}
/**
* Method to be called when binary data received from connection
* after a BINARY_EVENT packet.
*
* @param {Buffer | ArrayBuffer} binData - the raw binary data received
* @return {null | Object} returns null if more binary data is expected or
* a reconstructed packet object if all buffers have been received.
* @api private
*/
BinaryReconstructor.prototype.takeBinaryData = function(binData) {
this.buffers.push(binData);
if (this.buffers.length === this.reconPack.attachments) { // done with buffer list
var packet = binary.reconstructPacket(this.reconPack, this.buffers);
this.finishedReconstruction();
return packet;
}
return null;
};
/**
* Cleans up binary packet reconstruction variables.
*
* @api private
*/
BinaryReconstructor.prototype.finishedReconstruction = function() {
this.reconPack = null;
this.buffers = [];
};
function error() {
return {
type: exports.ERROR,
data: 'parser error'
};
}
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {// browser shim for xmlhttprequest module
var hasCORS = __webpack_require__(44);
module.exports = function (opts) {
var xdomain = opts.xdomain;
// scheme must be same when usign XDomainRequest
// http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
var xscheme = opts.xscheme;
// XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
// https://github.com/Automattic/engine.io-client/pull/217
var enablesXDR = opts.enablesXDR;
// XMLHttpRequest can be disabled on IE
try {
if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) {
return new XMLHttpRequest();
}
} catch (e) { }
// Use XDomainRequest for IE8 if enablesXDR is true
// because loading bar keeps flashing when using jsonp-polling
// https://github.com/yujiosaka/socke.io-ie8-loading-example
try {
if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) {
return new XDomainRequest();
}
} catch (e) { }
if (!xdomain) {
try {
return new global[['Active'].concat('Object').join('X')]('Microsoft.XMLHTTP');
} catch (e) { }
}
};
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Module dependencies.
*/
var parser = __webpack_require__(3);
var Emitter = __webpack_require__(2);
/**
* Module exports.
*/
module.exports = Transport;
/**
* Transport abstract constructor.
*
* @param {Object} options.
* @api private
*/
function Transport (opts) {
this.path = opts.path;
this.hostname = opts.hostname;
this.port = opts.port;
this.secure = opts.secure;
this.query = opts.query;
this.timestampParam = opts.timestampParam;
this.timestampRequests = opts.timestampRequests;
this.readyState = '';
this.agent = opts.agent || false;
this.socket = opts.socket;
this.enablesXDR = opts.enablesXDR;
// SSL options for Node.js client
this.pfx = opts.pfx;
this.key = opts.key;
this.passphrase = opts.passphrase;
this.cert = opts.cert;
this.ca = opts.ca;
this.ciphers = opts.ciphers;
this.rejectUnauthorized = opts.rejectUnauthorized;
this.forceNode = opts.forceNode;
// other options for Node.js client
this.extraHeaders = opts.extraHeaders;
this.localAddress = opts.localAddress;
}
/**
* Mix in `Emitter`.
*/
Emitter(Transport.prototype);
/**
* Emits an error.
*
* @param {String} str
* @return {Transport} for chaining
* @api public
*/
Transport.prototype.onError = function (msg, desc) {
var err = new Error(msg);
err.type = 'TransportError';
err.description = desc;
this.emit('error', err);
return this;
};
/**
* Opens the transport.
*
* @api public
*/
Transport.prototype.open = function () {
if ('closed' === this.readyState || '' === this.readyState) {
this.readyState = 'opening';
this.doOpen();
}
return this;
};
/**
* Closes the transport.
*
* @api private
*/
Transport.prototype.close = function () {
if ('opening' === this.readyState || 'open' === this.readyState) {
this.doClose();
this.onClose();
}
return this;
};
/**
* Sends multiple packets.
*
* @param {Array} packets
* @api private
*/
Transport.prototype.send = function (packets) {
if ('open' === this.readyState) {
this.write(packets);
} else {
throw new Error('Transport not open');
}
};
/**
* Called upon open
*
* @api private
*/
Transport.prototype.onOpen = function () {
this.readyState = 'open';
this.writable = true;
this.emit('open');
};
/**
* Called with data.
*
* @param {String} data
* @api private
*/
Transport.prototype.onData = function (data) {
var packet = parser.decodePacket(data, this.socket.binaryType);
this.onPacket(packet);
};
/**
* Called with a decoded packet.
*/
Transport.prototype.onPacket = function (packet) {
this.emit('packet', packet);
};
/**
* Called upon close.
*
* @api private
*/
Transport.prototype.onClose = function () {
this.readyState = 'closed';
this.emit('close');
};
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* This is the plugin for syncing scroll between devices
* @type {string}
*/
var WINDOW_EVENT_NAME = "scroll";
var ELEMENT_EVENT_NAME = "scroll:element";
var OPT_PATH = "ghostMode.scroll";
var utils;
exports.canEmitEvents = true;
/**
* @param {BrowserSync} bs
* @param eventManager
*/
exports.init = function (bs, eventManager) {
utils = bs.utils;
var opts = bs.options;
/**
* Window Scroll events
*/
eventManager.addEvent(window, WINDOW_EVENT_NAME, exports.browserEvent(bs));
bs.socket.on(WINDOW_EVENT_NAME, exports.socketEvent(bs));
/**
* element Scroll Events
*/
var cache = {};
addElementScrollEvents("scrollElements", false);
addElementScrollEvents("scrollElementMapping", true);
bs.socket.on(ELEMENT_EVENT_NAME, exports.socketEventForElement(bs, cache));
function addElementScrollEvents(key, map) {
if (!opts[key] ||
!opts[key].length ||
!("querySelectorAll" in document)) {
return;
}
utils.forEach(opts[key], function (selector) {
var elems = document.querySelectorAll(selector) || [];
utils.forEach(elems, function (elem) {
var data = utils.getElementData(elem);
data.cacheSelector = data.tagName + ":" + data.index;
data.map = map;
cache[data.cacheSelector] = elem;
eventManager.addEvent(elem, WINDOW_EVENT_NAME, exports.browserEventForElement(bs, elem, data));
});
});
}
};
/**
* @param {BrowserSync} bs
*/
exports.socketEvent = function (bs) {
return function (data) {
if (!bs.canSync(data, OPT_PATH)) {
return false;
}
var scrollSpace = utils.getScrollSpace();
exports.canEmitEvents = false;
if (bs.options && bs.options.scrollProportionally) {
return window.scrollTo(0, scrollSpace.y * data.position.proportional); // % of y axis of scroll to px
}
else {
return window.scrollTo(0, data.position.raw.y);
}
};
};
/**
* @param bs
*/
exports.socketEventForElement = function (bs, cache) {
return function (data) {
if (!bs.canSync(data, OPT_PATH)) {
return false;
}
exports.canEmitEvents = false;
function scrollOne(selector, pos) {
if (cache[selector]) {
cache[selector].scrollTop = pos;
}
}
if (data.map) {
return Object.keys(cache).forEach(function (key) {
scrollOne(key, data.position);
});
}
scrollOne(data.elem.cacheSelector, data.position);
};
};
/**
* @param bs
*/
exports.browserEventForElement = function (bs, elem, data) {
return function () {
var canSync = exports.canEmitEvents;
if (canSync) {
bs.socket.emit(ELEMENT_EVENT_NAME, {
position: elem.scrollTop,
elem: data,
map: data.map
});
}
exports.canEmitEvents = true;
};
};
exports.browserEvent = function (bs) {
return function () {
var canSync = exports.canEmitEvents;
if (canSync) {
bs.socket.emit(WINDOW_EVENT_NAME, {
position: exports.getScrollPosition()
});
}
exports.canEmitEvents = true;
};
};
/**
* @returns {{raw: number, proportional: number}}
*/
exports.getScrollPosition = function () {
var pos = utils.getBrowserScrollPosition();
return {
raw: pos,
proportional: exports.getScrollTopPercentage(pos) // Get % of y axis of scroll
};
};
/**
* @param {{x: number, y: number}} scrollSpace
* @param scrollPosition
* @returns {{x: number, y: number}}
*/
exports.getScrollPercentage = function (scrollSpace, scrollPosition) {
var x = scrollPosition.x / scrollSpace.x;
var y = scrollPosition.y / scrollSpace.y;
return {
x: x || 0,
y: y
};
};
/**
* Get just the percentage of Y axis of scroll
* @returns {number}
*/
exports.getScrollTopPercentage = function (pos) {
var scrollSpace = utils.getScrollSpace();
var percentage = exports.getScrollPercentage(scrollSpace, pos);
return percentage.y;
};
/***/ }),
/* 12 */
/***/ (function(module, exports) {
exports._ElementCache = function () {
var cache = {}, guidCounter = 1, expando = "data" + new Date().getTime();
this.getData = function (elem) {
var guid = elem[expando];
if (!guid) {
guid = elem[expando] = guidCounter++;
cache[guid] = {};
}
return cache[guid];
};
this.removeData = function (elem) {
var guid = elem[expando];
if (!guid)
return;
delete cache[guid];
try {
delete elem[expando];
}
catch (e) {
if (elem.removeAttribute) {
elem.removeAttribute(expando);
}
}
};
};
/**
* Fix an event
* @param event
* @returns {*}
*/
exports._fixEvent = function (event) {
function returnTrue() {
return true;
}
function returnFalse() {
return false;
}
if (!event || !event.stopPropagation) {
var old = event || window.event;
// Clone the old object so that we can modify the values
event = {};
for (var prop in old) {
event[prop] = old[prop];
}
// The event occurred on this element
if (!event.target) {
event.target = event.srcElement || document;
}
// Handle which other element the event is related to
event.relatedTarget =
event.fromElement === event.target
? event.toElement
: event.fromElement;
// Stop the default browser action
event.preventDefault = function () {
event.returnValue = false;
event.isDefaultPrevented = returnTrue;
};