Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

browser-sync

Package Overview
Dependencies
Maintainers
1
Versions
300
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

browser-sync - npm Package Compare versions

Comparing version 0.6.0 to 0.6.1

14

example.js
var browserSync = require("./lib/index");
var bs = browserSync.init("test/fixtures/**/*.css", {
var files = ["test/fixtures/**/*.css", "test/fixtures/**/*.html"];
var bs = browserSync.init(files, {
server: {
baseDir: "test/fixtures"
}
}).on("init", function (api) {
}).on("file:reload", function (file) {
console.log("FILE INJECTED: " + file.assetFileName);
});
//setInterval(function () {
// bs.emit("file:changed", {path: "style.css"});
//}, 5000);
});

@@ -25,4 +25,2 @@ "use strict";

var clients = [];
browserSync.prototype = {

@@ -34,2 +32,12 @@ cwd: cwd,

},
clientEvents: [
"scroll",
"input:text",
"input:select",
"input:radio",
"input:checkbox",
"form:submit",
"form:reset",
"click"
],
/**

@@ -118,3 +126,2 @@ * @param {Array} files

var ioLocal = this.setupSocket(ports);
var callbacks = this.getSocketCallbacks();

@@ -127,3 +134,3 @@ // register internal events

// Handle socket connections
this.handleSocketConnection(callbacks, options, this.handleClientSocketEvent);
this.handleSocketConnection(this.clientEvents, options);

@@ -171,8 +178,2 @@ // Start file watcher

/**
* @returns {*}
*/
getSocketCallbacks: function () {
return _.union(this.ghostModeCallbacks, controlPanel.controlPanelEvents);
},
/**
* Set up the socket.io server

@@ -194,5 +195,4 @@ * @param {Object} ports

* @param {Object} userOptions
* @param {function} handle
*/
handleSocketConnection: function (events, userOptions, handle) {
handleSocketConnection: function (events, userOptions) {

@@ -206,5 +206,5 @@ var _this = this;

if (userOptions.ghostMode) {
for (var i = 0, n = events.length; i < n; i += 1) {
handle(client, events[i], userOptions, _this);
}
events.forEach(function (evt) {
_this.handleClientSocketEvent(client, evt);
});
}

@@ -216,9 +216,3 @@

clients.push(client);
_this.logConnection(ua, userOptions);
client.on("disconnect", function () {
clients.splice(clients.indexOf(client), 1);
});
});

@@ -230,8 +224,6 @@ },

* @param {String} event
* @param {Object} userOptions
* @param {Object} _this
*/
handleClientSocketEvent: function (client, event, userOptions, _this) {
client.on(event.name, function (data) {
event.callback(client, data, _this);
handleClientSocketEvent: function (client, event) {
client.on(event, function (data) {
client.broadcast.emit(event, data);
});

@@ -254,57 +246,2 @@ },

/**
* ghostMode Callbacks (responses to client events)
*/
ghostModeCallbacks: [
{
name: "scroll",
callback: function (client, data) {
client.broadcast.emit("scroll:update", { position: data.pos, ghostId: data.ghostId, url: data.url});
}
},
{
name: "input:type",
callback: function (client, data) {
client.broadcast.emit("input:update", { id: data.id, value: data.value });
}
},
{
name: "input:select",
callback: function (client, data) {
client.broadcast.emit("input:update", { id: data.id, value: data.value });
}
},
{
name: "input:radio",
callback: function (client, data) {
client.broadcast.emit("input:update:radio", { id: data.id, value: data.value });
}
},
{
name: "input:checkbox",
callback: function (client, data) {
client.broadcast.emit("input:update:checkbox", { id: data.id, checked: data.checked });
}
},
{
name: "form:submit",
callback: function (client, data) {
client.broadcast.emit("form:submit", { id: data.id });
}
},
{
name: "form:reset",
callback: function (client, data) {
client.broadcast.emit("form:submit", { id: data.id });
}
},
{
name: "click",
callback: function (client, data) {
client.broadcast.emit("click", data);
}
}
],
/**
* Helper to try to retrieve the correct external IP for host
* Defaults to localhost (0.0.0.0) if no network ip's are accessible.
* @param {Object} options

@@ -350,14 +287,15 @@ * @param {String|Array} [devIp]

var suffix = "";
var validRoots = ["./", "/", "."];
if (!baseDir || baseDir === "./" || baseDir === "/" || baseDir === ".") {
if (!baseDir || _.contains(validRoots, baseDir)) {
return process.cwd();
}
if (baseDir.charAt(0) === "/") {
suffix = baseDir;
} else {
if (baseDir[0] === "/") {
suffix = baseDir;
if (/^.\//.test(baseDir)) {
suffix = baseDir.replace(".", "");
} else {
if (baseDir[0] === "." && baseDir[1] === "/") {
suffix = baseDir.replace(".", "");
} else {
suffix = "/" + baseDir;
}
suffix = "/" + baseDir;
}

@@ -404,3 +342,2 @@ }

* @param {Object} options
* @param _this - context
* @returns {{assetFileName: String}}

@@ -447,2 +384,3 @@ */

var server = options.server || false;
var baseDir = this.getBaseDir(server.baseDir || "./");
var open = false;

@@ -454,3 +392,3 @@ var msg;

if (server) {
msg = messages.initServer(host, ports.server, this.getBaseDir(options.server.baseDir || "./"));
msg = messages.initServer(host, ports.server, baseDir);
open = "server";

@@ -467,3 +405,2 @@ }

if (open) {
// Add test for this!
this.openBrowser(options.url, options);

@@ -470,0 +407,0 @@ }

/*global window*/
/*global document*/
/*global location*/
/*global ___socket___*/

@@ -59,2 +58,3 @@ (function (window, socket) {

notifyElem = this.createNotifyElem(styles || null);
this.notify("Connected to BrowserSync", notifyElem);
}

@@ -119,2 +119,7 @@ },

var yPos = browserSyncActions.getScrollFromHref(window.location.href);
if (yPos) {
window.scrollTo(0, yPos);
}
if (ghostMode.forms) {

@@ -229,3 +234,2 @@

/**
* The actions for the style injector
* @type {{reloadBrowser: Function, swapFile: Function}}

@@ -239,6 +243,36 @@ */

if (confirm) {
location.reload();
window.location.href = this.getPath(window.location.href, ghost.getScrollTop());
}
},
/**
* Retrieve y scroll from href
* @param {String} href
* @returns {String|Boolean}
*/
getScrollFromHref: function (href) {
var match = /bs_page_y=(\d{1,10})/.exec(href);
if (match) {
return match[1];
}
return false;
},
/**
* @param {String} current
* @param {Number} scrollTop
* @returns {String}
*/
getPath: function (current, scrollTop) {
var regex = /(bs_page_y=\d{1,5})/;
var prefix = "?";
if (current.match(regex)) {
return current.replace(regex, function () {
return "bs_page_y=" + scrollTop;
});
}
if (current.match(/\?/)) {
prefix = "&";
}
return current + prefix + "bs_page_y=" + scrollTop;
},
/**
* @param {HTMLElement} elem

@@ -442,2 +476,6 @@ * @param {String} attr

if (socket && socket.emit) {
// send relative path of where the event is sent
data.url = window.location.pathname;
socket.emit(name, data);

@@ -463,56 +501,2 @@ }

/**
* Get a href value from a clicked element
* @param {HTMLElement} elem
* @param {HTMLElement} [thisElem]
* @returns {String}
*/
getHref: function (elem, thisElem) {
var tagName = elem.tagName;
var href;
if (thisElem && thisElem.href) {
href = thisElem.href;
} else {
if (tagName === "A") {
href = elem.href;
} else {
// IE 7/8 find the parent Anchor element
href = this.getParentHref(elem, 5);
}
}
return href;
},
/**
* Walk backwards up the dom until you find the HREF attr of a link.
* @param {HTMLElement} elem
* @param {Number} limit
* @returns {String|Boolean}
*/
getParentHref: function (elem, limit) {
var getHref = function (elem) {
if (elem.parentNode.tagName === "A") {
return elem.parentNode.href;
} else {
return elem.parentNode;
}
};
var looperElem;
var currentElem = elem;
for (var i = 0; i < limit; i += 1) {
looperElem = getHref(currentElem);
if (typeof looperElem === "string") {
return looperElem;
} else {
currentElem = looperElem;
}
}
return false;
},
/**
* @returns {{texts: Array, radios: Array, checkboxes: Array}}

@@ -559,4 +543,2 @@ */

var pos, url;
var scrollTop = {

@@ -566,6 +548,6 @@ raw: ghost.getScrollTop(), // Get px of y axis of scroll

};
var newScroll = new Date().getTime();
var scrollThrottle = 0;
if (scope.options && scope.options.scrollThrottle) {

@@ -585,12 +567,4 @@ scrollThrottle = scope.options.scrollThrottle;

if (scope.options.scrollProportionally) {
pos = scrollTop.proportional;
} else {
pos = scrollTop.raw;
}
url = window.location.host + window.location.pathname;
ghost.emitEvent("scroll", {
pos: scrollTop,
url: url
position: scrollTop
});

@@ -604,10 +578,20 @@ }

* Handle aLL click events by indexing the dom element that was clicked
* @param event
* @param {Event} event
* @param {Object} localScope
*/
click: function (event) {
click: function (event, localScope) {
if (scope.ghostMode.enabled) {
if (!localScope) {
localScope = scope;
}
if (localScope.ghostMode.enabled) {
var elem = event.target || event.srcElement;
var tagName = elem.tagName;
if (elem.type === "checkbox" || elem.type === "radio") {
return;
}
var allElems = document.getElementsByTagName(tagName);

@@ -624,3 +608,3 @@ var index = Array.prototype.indexOf.call(allElems, elem);

} else {
scope.ghostMode.enabled = true;
localScope.ghostMode.enabled = true;
}

@@ -633,3 +617,3 @@ },

}
ghost.emitEvent("input:type", {
ghost.emitEvent("input:text", {
id: target.id,

@@ -651,2 +635,5 @@ value: target.value

checkboxChange: function (event) {
if (!scope.ghostMode.enabled) {
return;
}
var target = event.target || event.srcElement;

@@ -657,3 +644,3 @@ ghost.emitEvent("input:checkbox", { id: target.id, checked: target.checked });

var target = event.target || event.srcElement;
ghost.emitEvent("input:select", { id: target.id, value: target.value });
ghost.emitEvent("input:text", { id: target.id, value: target.value });
},

@@ -669,2 +656,5 @@ formSubmit: function (event) {

},
/**
* Cross-browser event helpers
*/
utils: {

@@ -674,2 +664,14 @@ eventListener: (window.addEventListener) ? "addEventListener" : "attachEvent",

prefix: (window.addEventListener) ? "" : "on"
},
/**
* @returns {string}
*/
getCurrentPath: function () {
return window.location.pathname;
},
/**
* @returns {boolean}
*/
canSync: function (url) {
return url === this.getCurrentPath();
}

@@ -700,2 +702,7 @@ };

// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
var elems = document.getElementsByTagName(data.tagName);

@@ -711,3 +718,3 @@ var elem = elems[data.index];

socket.on("location:update", function (data) {
socket.on("location", function (data) {
if (data.url) {

@@ -718,15 +725,25 @@ window.location = data.url;

socket.on("scroll:update", function (data) {
if (data.url === window.location.host + window.location.pathname) {
scope.ghostMode.enabled = false;
if (scope.options.scrollProportionally) {
var scrollSpace = ghost.getScrollSpace();
window.scrollTo(0, scrollSpace[1] * data.position.proportional); // % of y axis of scroll to px
} else {
window.scrollTo(0, data.position.raw);
}
socket.on("scroll", function (data) {
// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
scope.ghostMode.enabled = false;
if (scope.options.scrollProportionally) {
var scrollSpace = ghost.getScrollSpace();
window.scrollTo(0, scrollSpace[1] * data.position.proportional); // % of y axis of scroll to px
} else {
window.scrollTo(0, data.position.raw);
}
});
socket.on("input:update", function (data) {
socket.on("input:text", function (data) {
// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
scope.ghostMode.enabled = false;

@@ -737,3 +754,9 @@ var elem = ghost.checkCache(scope.ghostMode.cache, data.id);

socket.on("input:update:radio", function (data) {
socket.on("input:radio", function (data) {
// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
scope.ghostMode.enabled = false;

@@ -744,3 +767,10 @@ var elem = ghost.checkCache(scope.ghostMode.cache, data.id);

socket.on("input:update:checkbox", function (data) {
socket.on("input:checkbox", function (data) {
// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
scope.ghostMode.enabled = false;

@@ -752,6 +782,19 @@ var elem = ghost.checkCache(scope.ghostMode.cache, data.id);

socket.on("form:submit", function (data) {
// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
scope.ghostMode.enabled = false;
document.forms[data.id].submit();
});
socket.on("form:reset", function (data) {
// ensure synchronization occurs only between same pages
if (!ghost.canSync(data.url)) {
return;
}
scope.ghostMode.enabled = false;

@@ -758,0 +801,0 @@ document.forms[data.id].reset();

"use strict";
var messages = require("./messages");
var snippetUtils = require("./snippet").utils;
var connect = require("connect");
var http = require("http");
var loadSnippet = require("./loadSnippet");
var fs = require("fs");

@@ -41,5 +41,6 @@ var filePath = require("path");

var baseDir = __dirname + "/control-panel";
var scriptTags = messages.scriptTags(host, ports, options, "controlPanel");
var app = connect()
.use(loadSnippet(host, ports, options, "controlPanel"))
.use(snippetUtils.getSnippetMiddleware(scriptTags))
.use(clientScripts.versioned, modifySnippet)

@@ -46,0 +47,0 @@ .use(connect.static(filePath.resolve(baseDir)));

@@ -5,3 +5,2 @@ "use strict";

var messages = require("./messages");
var write = require("./snippet").write;
var snippetUtils = require("./snippet").utils;

@@ -17,23 +16,20 @@

/**
* @param {String} html
*/
return function (html) {
var string = "";
var host = userServer.host;
var port = userServer.port;
var string = "";
var host = userServer.host;
var port = userServer.port;
var regex;
if (host && port) {
if (host && port) {
string = host;
if (parseInt(port, 10) !== 80) {
string = host + ":" + port;
} else {
string = host;
}
} else {
string = host;
}
regex = new RegExp(string, "g");
return html.replace(regex, function () {
return {
match: new RegExp(string, "g"),
fn: function () {
return proxyUrl;
});
}
};

@@ -52,2 +48,11 @@ },

});
},
/**
* Get the proxy host with optional port
*/
getProxyHost: function (opts) {
if (opts.port && opts.port !== 80) {
return opts.host + ":" + opts.port;
}
return opts.host;
}

@@ -67,4 +72,6 @@ };

var proxyUrl = host + ":" + ports.proxy;
var rewriteLinks = utils.rewriteLinks(proxyOptions, proxyUrl);
var scriptTags = messages.scriptTags(host, ports, options);
var proxy = httpProxy.createProxyServer({});
var snippetMw = snippetUtils.getSnippetMiddleware(scriptTags, rewriteLinks);

@@ -82,3 +89,3 @@ var server = require("http").createServer(function(req, res) {

headers: {
host: proxyOptions.host
host: utils.getProxyHost(proxyOptions)
}

@@ -88,16 +95,9 @@ });

if (snippetUtils.isExcluded(req.url, options.excludedFileTypes)) {
return next();
}
req = snippetUtils.isOldIe(req);
var tags = messages.scriptTags(host, ports, options);
reqCallback(req, res);
snippetMw(req, res, next);
res.write = write(res, tags, null, utils.rewriteLinks(proxyOptions, proxyUrl));
}).listen(ports.proxy);
reqCallback(req, res, next);
});
server.listen(ports.proxy);
//

@@ -104,0 +104,0 @@ // Remove content-length to allow snippets to inserted to any body length

@@ -5,4 +5,4 @@ "use strict";

var http = require("http");
var loadSnippet = require("./loadSnippet");
var proxyModule = require("./proxy");
var messages = require("./messages");
var filePath = require("path");

@@ -35,3 +35,3 @@ var snippetUtils = require("./snippet").utils;

io.sockets.emit("location:update", {
io.sockets.emit("location", {
url: req.url

@@ -49,3 +49,5 @@ });

}
next();
if (typeof next === "function") {
next();
}
};

@@ -100,2 +102,3 @@ },

var navCallback = utils.navigateCallback(io, options);
var scriptTags = messages.scriptTags(host, ports, options);

@@ -110,5 +113,9 @@ if (proxy) {

app = connect()
.use(navCallback)
.use(loadSnippet(host, ports, options))
.use(connect.static(filePath.resolve(baseDir), { index: index }));
.use(function (req, res, next) {
req = snippetUtils.isOldIe(req);
return next();
})
.use(navCallback)
.use(snippetUtils.getSnippetMiddleware(scriptTags))
.use(connect.static(filePath.resolve(baseDir), { index: index }));

@@ -115,0 +122,0 @@ staticServer = http.createServer(app).listen(ports.server);

@@ -5,2 +5,3 @@ "use strict";

var _ = require("lodash");
var lrSnippet = require("resp-modifier");

@@ -15,16 +16,3 @@ /**

var utils = {
bodyPattern: /<body[^>]*>/i,
/**
* Check if HTML body exists
* @param {String} body
* @returns {*}
*/
bodyExists: function (body) {
if (!body) {
return false;
}
return (body.match(this.bodyPattern));
},
/**
* @param {String} url

@@ -46,52 +34,48 @@ * @param {Array} excludeList

}
return false;
}
};
module.exports.utils = utils;
},
/**
* @param {String} snippet
* @returns {Function}
*/
appendSnippet: function (snippet) {
return function (w) {
return w + snippet;
};
},
/**
* @param {String} snippet
* @param {Object} extraRules
* @returns {Function}
*/
getSnippetMiddleware: function (snippet, extraRules) {
/**
* Write function for injecting script tags
* @param {Object} res
* @param {String} tags
* @param {Boolean} rewriteHeaders
* @param {Function} callback - any more actions on the parsed body
* @returns {Function}
*/
module.exports.write = function (res, tags, rewriteHeaders, callback) {
var rules = [{
match: /<body[^>]*>/i,
fn: this.appendSnippet(snippet)
}];
var write = res.write;
return function (string, encoding) {
var body = string instanceof Buffer ? string.toString() : string;
if (utils.bodyExists(body)) {
body = body.replace(utils.bodyPattern, function (w) {
return w + tags;
});
if (extraRules) {
rules.push(extraRules);
}
if (typeof callback === "function") {
body = callback(body);
}
if (string instanceof Buffer) {
string = new Buffer(body);
} else {
string = body;
}
if (rewriteHeaders) {
// Remove content-length to allow snippets to inserted to any body length
if (!this.headerSent) {
if (this._headers.hasOwnProperty("content-length")) {
delete this._headers["content-length"];
return lrSnippet({rules:rules});
},
/**
* @param {Object} req
* @returns {Object}
*/
isOldIe: function (req, excludeList) {
var ua = req.headers["user-agent"];
var match = /MSIE (\d)\.\d/.exec(ua);
if (match) {
if (parseInt(match[1], 10) < 9) {
if (!utils.isExcluded(req.url, excludeList)) {
req.headers["accept"] = "text/html";
}
this._implicitHeader();
}
}
write.call(res, string, encoding);
};
return req;
}
};
module.exports.utils = utils;
{
"name": "browser-sync",
"description": "Live CSS Reload & Browser Syncing",
"version": "0.6.0",
"version": "0.6.1",
"homepage": "https://github.com/shakyshane/browser-sync",

@@ -42,3 +42,4 @@ "author": {

"http-proxy": "~1.0.2",
"cl-strings": "~0.0.5"
"cl-strings": "~0.0.5",
"resp-modifier": "~0.0.2"
},

@@ -45,0 +46,0 @@ "devDependencies": {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc