You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

304 lines
8.8 KiB

(function (angular) {
var OPT_PATH = ["shakyshane", "rewrite-rules"];
var NS = OPT_PATH.join(":");
var PLUGIN_NAME = "Rewrite Rules";
var errorTypes = {
DuplicateEntry: 'DuplicateEntry'
};
angular
.module("BrowserSync")
.directive("rewriteRules", function () {
return {
restrict: "E",
replace: true,
scope: {
"options": "=",
"pluginOpts": "=",
"uiOptions": "="
},
templateUrl: "rewrite-rules/rewrite.directive.html",
controller: ["$scope", "Socket", "Store", "Clients", rewriteRulesDirective],
controllerAs: "ctrl"
};
});
angular
.module("BrowserSync")
.directive("stateButton", function () {
return {
restrict: "E",
replace: true,
scope: {
"fn": "&",
"state": "=",
"on": "@",
"off": "@"
},
templateUrl: "rewrite-rules/rewrite.state-button.html"
};
});
/**
* Rewrite Rules Directive
* @param $scope
* @param Socket
* @param Store
* @param Clients
*/
function rewriteRulesDirective($scope, Socket, Store, Clients) {
var ctrl = this;
ctrl.errors = [];
ctrl.exports = [];
ctrl.addError = function (incoming) {
var dupes = ctrl.errors.filter(function (error) {
return error.type === incoming.type;
});
if (dupes.length) return;
ctrl.errors.push(incoming);
};
$scope.$watch(function () {
return ctrl.inputs.match.value
}, function (value) {
if (ctrl.state.editing) return;
var dupes = ctrl.rules.filter(function (rule) {
return rule.matchInput === value;
});
if (dupes.length) {
ctrl.showErrors = true;
ctrl.addError({type: errorTypes.DuplicateEntry, message: 'Duplicate Entry'});
} else {
ctrl.errors = [];
}
});
ctrl.plugin = $scope.options.userPlugins.filter(function (item) {
return item.name === PLUGIN_NAME;
})[0];
ctrl.plugin.opts = $scope.uiOptions[OPT_PATH[0]][OPT_PATH[1]];
ctrl.rules = ctrl.plugin.opts.rules;
var config = ctrl.plugin.opts.config;
var store = Store.create(NS);
ctrl.exportRules = function () {
if (ctrl.exports.length) {
return ctrl.exports = [];
}
ctrl.exports = ctrl.rules
.filter(function (rule) {
return rule.matchType === 'string' && rule.replaceType === 'string'
})
.map(function (rule) {
return {
match: rule.matchInput,
replace: rule.replaceInput
}
});
};
ctrl.nextUpdate = [];
ctrl.state = {
classname: "ready",
adding: false,
editing: false
};
ctrl.inputs = {
match: {
type: 'string',
value: '',
flags: ''
},
replace: {
type: 'string',
value: ''
}
};
ctrl.showInputs = function () {
ctrl.resetForm();
if (!ctrl.state.adding) {
ctrl.state.adding = true;
ctrl.buttonText = "Cancel";
} else {
ctrl.state.adding = false;
ctrl.buttonText = "Add new";
}
};
ctrl.isMatchType = function (type) {
return ctrl.inputs.match.type === type;
};
ctrl.isReplaceType = function (type) {
return ctrl.inputs.replace.type === type;
};
ctrl.setMatchType = function (type) {
ctrl.inputs.match.type = type;
};
ctrl.setReplaceType = function (type) {
ctrl.inputs.replace.type = type;
};
ctrl.setReplaceType = function (type) {
ctrl.inputs.replace.type = type;
};
ctrl.toggleState = function (rule) {
rule.active = !rule.active;
};
ctrl.resetForm = function () {
ctrl.buttonText = "Add new";
ctrl.showErrors = false;
ctrl.errors = [];
ctrl.inputs.match.value = "";
ctrl.inputs.match.flags = "";
ctrl.inputs.replace.value = "";
ctrl.state.editing = false;
};
ctrl.editRule = function (rule) {
ctrl.state.editing = true;
ctrl.state.currentRule = rule;
ctrl.buttonText = 'Cancel';
ctrl.inputs.match.value = rule.matchInput;
ctrl.inputs.match.type = rule.matchType;
if (ctrl.inputs.match.type === 'regex') {
ctrl.inputs.match.flags = rule.matchFlags;
}
ctrl.inputs.replace.value = rule.replaceInput;
ctrl.inputs.replace.type = rule.replaceType;
ctrl.state.adding = true;
};
ctrl.saveRule = function (after) {
if (after === 'reload') {
ctrl.nextUpdate.push(function () {
Clients.reloadAll();
});
}
var match = ctrl.inputs.match;
var replace = ctrl.inputs.replace;
var obj = {};
if (ctrl.state.editing) {
obj.id = ctrl.state.currentRule.id;
}
if (!$scope.rewriteForm.$valid) {
ctrl.showErrors = true;
return;
}
if (ctrl.errors.length) return;
obj.match = match;
obj.replace = replace;
Socket.uiEvent({
namespace: NS,
event: 'addRule',
data: obj
});
ctrl.state.classname = 'waiting';
setTimeout(function () {
ctrl.state.classname = 'success';
$scope.$digest();
setTimeout(function () {
ctrl.state.classname = 'ready';
ctrl.state.adding = false;
ctrl.resetForm();
$scope.$digest();
}, 300);
}, 300);
};
var prev = store.get('previous');
if (prev) {
console.log('Previous items exist');
if (prev[Socket.sessionId]) {
//prev = prev[Socket.sessionId];
//console.log('Previous items exist for CURRENT session');
//var uniq = prev.filter(function (item) {
// var matches = ctrl.rules.filter(function (rule) {
// return item.id !== rule.id;
// });
// return !matches.length;
//});
//if (uniq.length) {
// ctrl.previousRules = prev;
//}
} else {
//console.log('Previous items exist for PREVIOUS session');
prev = prev[Object.keys(prev)[0]];
if (prev.length && ctrl.rules.length) {
//console.log('BOTH');
//console.log('uniq');
} else {
ctrl.previousRules = prev;
}
}
}
ctrl.updateOptions = function (data) {
ctrl.plugin.opts = data.opts;
ctrl.rules = data.rules;
$scope.$digest();
};
ctrl.restorePreviousRules = function () {
Socket.uiEvent({
namespace: NS,
event: 'replaceRules',
data: ctrl.previousRules
});
ctrl.previousRules = false;
};
ctrl.updateRules = function (data) {
ctrl.rules = data.rules;
if (ctrl.nextUpdate.length) {
ctrl.nextUpdate.forEach(function (fn) {
fn(data);
var obj = {};
obj[Socket.sessionId] = ctrl.rules;
store.set('previous', obj);
});
}
ctrl.nextUpdate = [];
$scope.$digest();
};
Socket.on(config.EVENT_UPDATE, ctrl.updateRules);
Socket.on("options:update", ctrl.updateOptions);
$scope.$on("$destory", function () {
Socket.off(config.EVENT_UPDATE, ctrl.updateRules);
Socket.off("options:update", ctrl.updateOptions);
});
}
})(angular);