前端代码
This commit is contained in:
201
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.client.js
generated
vendored
Normal file
201
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.client.js
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
(function (angular) {
|
||||
|
||||
const SECTION_NAME = "network-throttle";
|
||||
|
||||
angular
|
||||
.module("BrowserSync")
|
||||
.controller("NetworkThrottleController", [
|
||||
"options",
|
||||
"pagesConfig",
|
||||
"Socket",
|
||||
"$scope",
|
||||
NetworkThrottleController
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param options
|
||||
* @param pagesConfig
|
||||
* @param Socket
|
||||
* @param $scope
|
||||
*/
|
||||
function NetworkThrottleController (options, pagesConfig, Socket, $scope) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.section = pagesConfig[SECTION_NAME];
|
||||
ctrl.options = options.bs;
|
||||
ctrl.uiOptions = options.ui;
|
||||
ctrl.clientFiles = options.ui.clientFiles || {};
|
||||
ctrl.section = pagesConfig[SECTION_NAME];
|
||||
|
||||
ctrl.throttle = ctrl.uiOptions[SECTION_NAME];
|
||||
ctrl.selected = ctrl.throttle.targets[0].id;
|
||||
ctrl.servers = ctrl.throttle.servers;
|
||||
ctrl.port = "";
|
||||
ctrl.portEntry = "auto";
|
||||
ctrl.serverCount = Object.keys(ctrl.servers).length;
|
||||
ctrl.blurs = [];
|
||||
|
||||
ctrl.state = {
|
||||
success: false,
|
||||
waiting: false,
|
||||
classname: "ready"
|
||||
};
|
||||
|
||||
ctrl.createServer = function (selected, event) {
|
||||
|
||||
if (ctrl.blurs.indexOf(event.target) === -1) {
|
||||
ctrl.blurs.push(event.target);
|
||||
}
|
||||
|
||||
var item = getByProp(ctrl.throttle.targets, "id", ctrl.selected);
|
||||
|
||||
|
||||
if (ctrl.portEntry === "auto") {
|
||||
return send("");
|
||||
}
|
||||
|
||||
if (!ctrl.port || !ctrl.port.length) {
|
||||
setError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctrl.port.match(/\d{4,5}/)) {
|
||||
setError();
|
||||
return;
|
||||
}
|
||||
|
||||
var port = parseInt(ctrl.port, 10);
|
||||
|
||||
if (port < 1024 || port > 65535) {
|
||||
setError();
|
||||
return;
|
||||
}
|
||||
|
||||
send(ctrl.port);
|
||||
|
||||
function setError() {
|
||||
ctrl.state.waiting = false;
|
||||
ctrl.state.portError = true;
|
||||
}
|
||||
|
||||
function send (port) {
|
||||
|
||||
ctrl.state.classname = "waiting";
|
||||
ctrl.state.waiting = true;
|
||||
|
||||
Socket.uiEvent({
|
||||
namespace: SECTION_NAME,
|
||||
event: "server:create",
|
||||
data: {
|
||||
speed: item,
|
||||
port: port
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ctrl.destroyServer = function (item, port) {
|
||||
Socket.uiEvent({
|
||||
namespace: SECTION_NAME,
|
||||
event: "server:destroy",
|
||||
data: {
|
||||
speed: item,
|
||||
port: port
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ctrl.toggleSpeed = function (item) {
|
||||
if (!item.active) {
|
||||
item.urls = [];
|
||||
}
|
||||
};
|
||||
|
||||
ctrl.update = function (data) {
|
||||
|
||||
ctrl.servers = data.servers;
|
||||
ctrl.serverCount = Object.keys(ctrl.servers).length;
|
||||
|
||||
if (data.event === "server:create") {
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
$scope.$digest();
|
||||
};
|
||||
|
||||
function updateButtonState() {
|
||||
|
||||
ctrl.state.success = true;
|
||||
ctrl.state.classname = "success";
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
ctrl.blurs.forEach(function (elem) {
|
||||
elem.blur();
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
ctrl.state.success = false;
|
||||
ctrl.state.waiting = false;
|
||||
ctrl.state.classname = "ready";
|
||||
|
||||
$scope.$digest();
|
||||
|
||||
}, 500);
|
||||
|
||||
}, 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param collection
|
||||
* @param prop
|
||||
* @returns {*}
|
||||
*/
|
||||
function getByProp (collection, prop, name) {
|
||||
var match = collection.filter(function (item) {
|
||||
return item[prop] === name;
|
||||
});
|
||||
if (match.length) {
|
||||
return match[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Socket.on("ui:network-throttle:update", ctrl.update);
|
||||
$scope.$on("$destroy", function () {
|
||||
Socket.off("ui:network-throttle:update", ctrl.update);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the snippet when in snippet mode
|
||||
*/
|
||||
angular
|
||||
.module("BrowserSync")
|
||||
.directive("throttle", function () {
|
||||
return {
|
||||
restrict: "E",
|
||||
replace: true,
|
||||
scope: {
|
||||
"target": "=",
|
||||
"options": "="
|
||||
},
|
||||
templateUrl: "network-throttle.directive.html",
|
||||
controller: ["$scope", "Socket", throttleDirectiveControlller],
|
||||
controllerAs: "ctrl"
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* @param $scope
|
||||
*/
|
||||
function throttleDirectiveControlller ($scope) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.throttle = $scope.options[SECTION_NAME];
|
||||
|
||||
}
|
||||
|
||||
})(angular);
|
12
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.directive.html
generated
vendored
Normal file
12
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.directive.html
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
<section bs-panel-content>
|
||||
<div ng-if="target.active">
|
||||
<p ng-if="!target.urls.length">
|
||||
Creating a throttled server, please wait...
|
||||
</p>
|
||||
<div ng-if="target.urls.length">
|
||||
<ul bs-list>
|
||||
<li ng-repeat="url in target.urls"><a href="{{url}}">{{url}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
93
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.html
generated
vendored
Normal file
93
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.html
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
<article>
|
||||
<div bs-panel="controls outline">
|
||||
<h1 bs-heading>
|
||||
<icon icon="{{ctrl.section.icon}}"></icon>
|
||||
{{ctrl.section.title}}
|
||||
</h1>
|
||||
</div>
|
||||
<div bs-panel="no-border" ng-if="ctrl.options.mode === 'snippet'">
|
||||
<div bs-panel-content="basic">
|
||||
<p class="lede">Sorry, Network Throttling is only available in Server or Proxy mode.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div bs-panel="no-border" ng-if="ctrl.options.mode !== 'snippet'">
|
||||
<div bs-panel-content="basic">
|
||||
<div bs-inputs bs-grid="wide-3 desk-2">
|
||||
<div bs-grid-item>
|
||||
<p bs-label-heading>Speed</p>
|
||||
<div bs-input="inline" ng-repeat="(key, item) in ctrl.throttle.targets | orderObjectBy:'order'">
|
||||
<input
|
||||
type="radio"
|
||||
id="speed-{{item.id}}"
|
||||
checked name="speed"
|
||||
ng-model="ctrl.selected"
|
||||
value="{{item.id}}">
|
||||
|
||||
<label for="speed-{{item.id}}" bs-input-label="light">{{item.title}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div bs-grid-item>
|
||||
<p bs-label-heading>Port</p>
|
||||
<div bs-input="text">
|
||||
<div bs-input="inline">
|
||||
<input type="radio" name="port-select" id="port-auto" checked value="auto"
|
||||
ng-model="ctrl.portEntry">
|
||||
<label for="port-auto" bs-input-label="light">Auto Detection</label>
|
||||
</div>
|
||||
<div bs-input="inline">
|
||||
<input type="radio" id="port-manual" name="port-select" value="manual" ng-model="ctrl.portEntry">
|
||||
<label for="port-manual" bs-input-label="light">User specified <span ng-if="ctrl.state.portError">(between
|
||||
1024 & 65535)</span></label>
|
||||
</div>
|
||||
<input id="server-port"
|
||||
type="text"
|
||||
value=""
|
||||
placeholder="Eg: 1024"
|
||||
ng-model="ctrl.port"
|
||||
ng-focus="ctrl.portEntry = 'manual'"
|
||||
custom-validation>
|
||||
|
||||
</div>
|
||||
<br/>
|
||||
<div ng-class="[ctrl.state.classname]" bs-state-wrapper>
|
||||
<button
|
||||
id="create-server"
|
||||
bs-button="size-small subtle-alt icon-left"
|
||||
ng-click="ctrl.createServer(ctrl.selected, $event)"
|
||||
ng-disabled="ctrl.state.waiting"
|
||||
>
|
||||
<icon icon="circle-plus"></icon>
|
||||
Create Server
|
||||
</button>
|
||||
<div bs-state-icons>
|
||||
<icon icon="circle-ok" bs-state="success inline"></icon>
|
||||
<icon icon="circle-minus" bs-state="waiting inline" bs-anim="spin"></icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div bs-grid-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div bs-panel-content="basic">
|
||||
<h3 ng-if="ctrl.serverCount">Your Servers:</h3>
|
||||
<h3 ng-if="!ctrl.serverCount">Your Servers will appear here...</h3>
|
||||
</div>
|
||||
|
||||
<ul bs-list="bordered inline-controls" bs-offset="basic" id="throttle-server-list">
|
||||
<li ng-repeat="(key, item) in ctrl.servers track by key">
|
||||
<p bs-width="5">{{$index + 1}}.</p>
|
||||
<p bs-width="10"><b>{{item.speed.id | uppercase}}</b></p>
|
||||
<p><a href="{{item.urls[0]}}">{{item.urls[0]}}</a></p>
|
||||
<p><a href="{{item.urls[1]}}">{{item.urls[1]}}</a></p>
|
||||
<div bs-button-group>
|
||||
<button href="#" bs-button="subtle-alt icon" ng-click="ctrl.destroyServer(item, key)">
|
||||
<svg bs-svg-icon><use xlink:href="#svg-bin"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</article>
|
160
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.js
generated
vendored
Normal file
160
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.js
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
var Immutable = require("immutable");
|
||||
|
||||
module.exports.init = function (ui) {
|
||||
|
||||
var optPath = ["network-throttle"];
|
||||
var serverOptPath = optPath.concat(["servers"]);
|
||||
var listenHost = ui.options.get("listen");
|
||||
ui.servers = {};
|
||||
|
||||
ui.setOptionIn(optPath, Immutable.fromJS({
|
||||
name: "network-throttle",
|
||||
title: "Network Throttle",
|
||||
active: false,
|
||||
targets: require("./targets")
|
||||
}));
|
||||
|
||||
ui.setOptionIn(serverOptPath, Immutable.Map({}));
|
||||
|
||||
/**
|
||||
* @param input
|
||||
* @returns {number}
|
||||
*/
|
||||
function getPortArg(input) {
|
||||
input = input.trim();
|
||||
if (input.length && input.match(/\d{3,5}/)) {
|
||||
input = parseInt(input, 10);
|
||||
} else {
|
||||
input = ui.bs.options.get("port") + 1;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTargetUrl() {
|
||||
return require("url").parse(ui.bs.options.getIn(["urls", "local"]));
|
||||
}
|
||||
|
||||
var methods = {
|
||||
/**
|
||||
* @param data
|
||||
*/
|
||||
"server:create": function (data) {
|
||||
|
||||
data.port = getPortArg(data.port);
|
||||
data.cb = data.cb || function () { /* noop */};
|
||||
|
||||
/**
|
||||
* @param opts
|
||||
*/
|
||||
function saveThrottleInfo (opts) {
|
||||
|
||||
var urls = getUrls(ui.bs.options.set("port", opts.port).toJS());
|
||||
|
||||
ui.setOptionIn(serverOptPath.concat([opts.port]), Immutable.fromJS({
|
||||
urls: urls,
|
||||
speed: opts.speed
|
||||
}));
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
ui.socket.emit("ui:network-throttle:update", {
|
||||
servers: ui.getOptionIn(serverOptPath).toJS(),
|
||||
event: "server:create"
|
||||
});
|
||||
|
||||
ui.servers[opts.port] = opts.server;
|
||||
|
||||
data.cb(null, opts);
|
||||
|
||||
}, 300);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param err
|
||||
* @param port
|
||||
*/
|
||||
function createThrottle (err, port) {
|
||||
|
||||
var target = getTargetUrl();
|
||||
|
||||
var args = {
|
||||
port: port,
|
||||
target: target,
|
||||
speed: data.speed
|
||||
};
|
||||
|
||||
if (ui.bs.getOption("scheme") === "https") {
|
||||
var httpsOpts = require("browser-sync/lib/server/utils").getHttpsOptions(ui.bs.options);
|
||||
args.key = httpsOpts.key;
|
||||
args.cert = httpsOpts.cert;
|
||||
}
|
||||
|
||||
args.server = require("./throttle-server")(args, listenHost);
|
||||
require('server-destroy')(args.server);
|
||||
args.server.listen(port, listenHost);
|
||||
|
||||
saveThrottleInfo(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try for a free port
|
||||
*/
|
||||
ui.bs.utils.portscanner.findAPortNotInUse(data.port, data.port + 100, (listenHost || "127.0.0.1"), function (err, port) {
|
||||
if (err) {
|
||||
return createThrottle(err);
|
||||
} else {
|
||||
createThrottle(null, port);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @param data
|
||||
*/
|
||||
"server:destroy": function (data) {
|
||||
if (ui.servers[data.port]) {
|
||||
ui.servers[data.port].destroy();
|
||||
ui.setMany(function (item) {
|
||||
item.deleteIn(serverOptPath.concat([parseInt(data.port, 10)]));
|
||||
});
|
||||
delete ui.servers[data.port];
|
||||
}
|
||||
ui.socket.emit("ui:network-throttle:update", {
|
||||
servers: ui.getOptionIn(serverOptPath).toJS(),
|
||||
event: "server:destroy"
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @param event
|
||||
*/
|
||||
event: function (event) {
|
||||
methods[event.event](event.data);
|
||||
}
|
||||
};
|
||||
|
||||
return methods;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get local + external urls with a different port
|
||||
* @param opts
|
||||
* @returns {List<T>|List<any>}
|
||||
*/
|
||||
function getUrls (opts) {
|
||||
|
||||
var list = [];
|
||||
|
||||
var bsLocal = require("url").parse(opts.urls.local);
|
||||
|
||||
list.push([bsLocal.protocol + "//", bsLocal.hostname, ":", opts.port].join(""));
|
||||
|
||||
if (opts.urls.external) {
|
||||
var external = require("url").parse(opts.urls.external);
|
||||
list.push([bsLocal.protocol + "//", external.hostname, ":", opts.port].join(""));
|
||||
}
|
||||
|
||||
return Immutable.List(list);
|
||||
}
|
53
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.plugin.js
generated
vendored
Normal file
53
node_modules/browser-sync-ui/lib/plugins/network-throttle/network-throttle.plugin.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
var networkThrottle = require("./network-throttle");
|
||||
|
||||
const PLUGIN_NAME = "Network Throttle";
|
||||
|
||||
/**
|
||||
* @type {{plugin: Function, plugin:name: string, markup: string}}
|
||||
*/
|
||||
module.exports = {
|
||||
/**
|
||||
* Plugin init
|
||||
*/
|
||||
"plugin": function (ui, bs) {
|
||||
ui.throttle = networkThrottle.init(ui, bs);
|
||||
ui.listen("network-throttle", ui.throttle);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hooks
|
||||
*/
|
||||
"hooks": {
|
||||
"markup": fileContent("/network-throttle.html"),
|
||||
"client:js": [fileContent("/network-throttle.client.js")],
|
||||
"templates": [],
|
||||
"page": {
|
||||
path: "/network-throttle",
|
||||
title: PLUGIN_NAME,
|
||||
template: "network-throttle.html",
|
||||
controller: "NetworkThrottleController",
|
||||
order: 5,
|
||||
icon: "time"
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Plugin name
|
||||
*/
|
||||
"plugin:name": PLUGIN_NAME
|
||||
};
|
||||
|
||||
/**
|
||||
* @param filepath
|
||||
* @returns {*}
|
||||
*/
|
||||
function getPath (filepath) {
|
||||
return require("path").join(__dirname, filepath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filepath
|
||||
* @returns {*}
|
||||
*/
|
||||
function fileContent (filepath) {
|
||||
return require("fs").readFileSync(getPath(filepath));
|
||||
}
|
57
node_modules/browser-sync-ui/lib/plugins/network-throttle/targets.js
generated
vendored
Normal file
57
node_modules/browser-sync-ui/lib/plugins/network-throttle/targets.js
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
module.exports = [
|
||||
{
|
||||
active: false,
|
||||
title: "DSL (2Mbs, 5ms RTT)",
|
||||
id: "dsl",
|
||||
speed: 200,
|
||||
latency: 5,
|
||||
urls: [],
|
||||
order: 1
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
title: "4G (4Mbs, 20ms RTT)",
|
||||
id: "4g",
|
||||
speed: 400,
|
||||
latency: 10,
|
||||
urls: [],
|
||||
order: 2
|
||||
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
title: "3G (750kbs, 100ms RTT)",
|
||||
id: "3g",
|
||||
speed: 75,
|
||||
latency: 50,
|
||||
urls: [],
|
||||
order: 3
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
id: "good-2g",
|
||||
title: "Good 2G (450kbs, 150ms RTT)",
|
||||
speed: 45,
|
||||
latency: 75,
|
||||
urls: [],
|
||||
order: 4
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
id: "2g",
|
||||
title: "Regular 2G (250kbs, 300ms RTT)",
|
||||
speed: 25,
|
||||
latency: 150,
|
||||
urls: [],
|
||||
order: 5
|
||||
},
|
||||
{
|
||||
active: false,
|
||||
id: "gprs",
|
||||
title: "GPRS (50kbs, 500ms RTT)",
|
||||
speed: 5,
|
||||
latency: 250,
|
||||
urls: [],
|
||||
order: 6
|
||||
}
|
||||
];
|
70
node_modules/browser-sync-ui/lib/plugins/network-throttle/throttle-server.js
generated
vendored
Normal file
70
node_modules/browser-sync-ui/lib/plugins/network-throttle/throttle-server.js
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
var ThrottleGroup = require("stream-throttle").ThrottleGroup;
|
||||
|
||||
module.exports = throttle;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function throttle (opts, listenHost) {
|
||||
|
||||
var options = {
|
||||
local_host: listenHost,
|
||||
remote_host: listenHost,
|
||||
upstream: 10*1024,
|
||||
downstream: opts.speed.speed * 1024,
|
||||
keepalive: false
|
||||
};
|
||||
|
||||
var serverOpts = {
|
||||
allowHalfOpen: true,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
var module = "net";
|
||||
var method = "createConnection";
|
||||
|
||||
if (opts.key) {
|
||||
module = "tls";
|
||||
method = "connect";
|
||||
serverOpts.key = opts.key;
|
||||
serverOpts.cert = opts.cert;
|
||||
}
|
||||
|
||||
return require(module).createServer(serverOpts, function (local) {
|
||||
|
||||
var remote = require(module)[method]({
|
||||
host: opts.target.hostname,
|
||||
port: opts.target.port,
|
||||
allowHalfOpen: true,
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
|
||||
var upThrottle = new ThrottleGroup({ rate: options.upstream });
|
||||
var downThrottle = new ThrottleGroup({ rate: options.downstream });
|
||||
|
||||
var localThrottle = upThrottle.throttle();
|
||||
var remoteThrottle = downThrottle.throttle();
|
||||
|
||||
setTimeout(function () {
|
||||
local
|
||||
.pipe(localThrottle)
|
||||
.pipe(remote);
|
||||
}, opts.speed.latency);
|
||||
|
||||
setTimeout(function () {
|
||||
remote
|
||||
.pipe(remoteThrottle)
|
||||
.pipe(local);
|
||||
}, opts.speed.latency);
|
||||
|
||||
local.on("error", function() {
|
||||
remote.destroy();
|
||||
local.destroy();
|
||||
});
|
||||
|
||||
remote.on("error", function() {
|
||||
local.destroy();
|
||||
remote.destroy();
|
||||
});
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user