First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
331
sites/all/modules/civicrm/bower_components/angular-unsavedChanges/dist/unsavedChanges.js
vendored
Normal file
331
sites/all/modules/civicrm/bower_components/angular-unsavedChanges/dist/unsavedChanges.js
vendored
Normal file
|
@ -0,0 +1,331 @@
|
|||
'use strict';
|
||||
/*jshint globalstrict: true*/
|
||||
/*jshint undef:false */
|
||||
|
||||
// @todo NOTE We should investigate changing default to
|
||||
// $routeChangeStart see https://github.com/angular-ui/ui-router/blob/3898270241d4e32c53e63554034d106363205e0e/src/compat.js#L126
|
||||
|
||||
angular.module('unsavedChanges', ['lazyModel'])
|
||||
|
||||
.provider('unsavedWarningsConfig', function() {
|
||||
|
||||
var _this = this;
|
||||
|
||||
// defaults
|
||||
var logEnabled = false;
|
||||
var useTranslateService = true;
|
||||
var routeEvent = ['$locationChangeStart', '$stateChangeStart'];
|
||||
var navigateMessage = 'You will lose unsaved changes if you leave this page';
|
||||
var reloadMessage = 'You will lose unsaved changes if you reload this page';
|
||||
|
||||
Object.defineProperty(_this, 'navigateMessage', {
|
||||
get: function() {
|
||||
return navigateMessage;
|
||||
},
|
||||
set: function(value) {
|
||||
navigateMessage = value;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(_this, 'reloadMessage', {
|
||||
get: function() {
|
||||
return reloadMessage;
|
||||
},
|
||||
set: function(value) {
|
||||
reloadMessage = value;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(_this, 'useTranslateService', {
|
||||
get: function() {
|
||||
return useTranslateService;
|
||||
},
|
||||
set: function(value) {
|
||||
useTranslateService = !! (value);
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(_this, 'routeEvent', {
|
||||
get: function() {
|
||||
return routeEvent;
|
||||
},
|
||||
set: function(value) {
|
||||
if (typeof value === 'string') value = [value];
|
||||
routeEvent = value;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(_this, 'logEnabled', {
|
||||
get: function() {
|
||||
return logEnabled;
|
||||
},
|
||||
set: function(value) {
|
||||
logEnabled = !! (value);
|
||||
}
|
||||
});
|
||||
|
||||
this.$get = ['$injector',
|
||||
function($injector) {
|
||||
|
||||
function translateIfAble(message) {
|
||||
if ($injector.has('$translate') && useTranslateService) {
|
||||
return $injector.get('$translate')(message);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var publicInterface = {
|
||||
// log function that accepts any number of arguments
|
||||
// @see http://stackoverflow.com/a/7942355/1738217
|
||||
log: function() {
|
||||
if (console.log && logEnabled && arguments.length) {
|
||||
var newarr = [].slice.call(arguments);
|
||||
if (typeof console.log === 'object') {
|
||||
log.apply.call(console.log, console, newarr);
|
||||
} else {
|
||||
console.log.apply(console, newarr);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(publicInterface, 'useTranslateService', {
|
||||
get: function() {
|
||||
return useTranslateService;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(publicInterface, 'reloadMessage', {
|
||||
get: function() {
|
||||
return translateIfAble(reloadMessage) || reloadMessage;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(publicInterface, 'navigateMessage', {
|
||||
get: function() {
|
||||
return translateIfAble(navigateMessage) || navigateMessage;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(publicInterface, 'routeEvent', {
|
||||
get: function() {
|
||||
return routeEvent;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(publicInterface, 'logEnabled', {
|
||||
get: function() {
|
||||
return logEnabled;
|
||||
}
|
||||
});
|
||||
|
||||
return publicInterface;
|
||||
}
|
||||
];
|
||||
})
|
||||
|
||||
.service('unsavedWarningSharedService', ['$rootScope', 'unsavedWarningsConfig', '$injector',
|
||||
function($rootScope, unsavedWarningsConfig, $injector) {
|
||||
|
||||
// Controller scopped variables
|
||||
var _this = this;
|
||||
var allForms = [];
|
||||
var areAllFormsClean = true;
|
||||
var removeFunctions = [angular.noop];
|
||||
|
||||
// @note only exposed for testing purposes.
|
||||
this.allForms = function() {
|
||||
return allForms;
|
||||
};
|
||||
|
||||
// save shorthand reference to messages
|
||||
var messages = {
|
||||
navigate: unsavedWarningsConfig.navigateMessage,
|
||||
reload: unsavedWarningsConfig.reloadMessage
|
||||
};
|
||||
|
||||
// Check all registered forms
|
||||
// if any one is dirty function will return true
|
||||
|
||||
function allFormsClean() {
|
||||
areAllFormsClean = true;
|
||||
angular.forEach(allForms, function(item, idx) {
|
||||
unsavedWarningsConfig.log('Form : ' + item.$name + ' dirty : ' + item.$dirty);
|
||||
if (item.$dirty) {
|
||||
areAllFormsClean = false;
|
||||
}
|
||||
});
|
||||
return areAllFormsClean; // no dirty forms were found
|
||||
}
|
||||
|
||||
// adds form controller to registered forms array
|
||||
// this array will be checked when user navigates away from page
|
||||
this.init = function(form) {
|
||||
if (allForms.length === 0) setup();
|
||||
unsavedWarningsConfig.log("Registering form", form);
|
||||
allForms.push(form);
|
||||
};
|
||||
|
||||
this.removeForm = function(form) {
|
||||
var idx = allForms.indexOf(form);
|
||||
|
||||
// this form is not present array
|
||||
// @todo needs test coverage
|
||||
if (idx === -1) return;
|
||||
|
||||
allForms.splice(idx, 1);
|
||||
unsavedWarningsConfig.log("Removing form from watch list", form);
|
||||
|
||||
if (allForms.length === 0) tearDown();
|
||||
};
|
||||
|
||||
function tearDown() {
|
||||
unsavedWarningsConfig.log('No more forms, tearing down');
|
||||
angular.forEach(removeFunctions, function(fn) {
|
||||
fn();
|
||||
});
|
||||
window.onbeforeunload = null;
|
||||
}
|
||||
|
||||
// Function called when user tries to close the window
|
||||
this.confirmExit = function() {
|
||||
// @todo this could be written a lot cleaner!
|
||||
if (!allFormsClean()) return messages.reload;
|
||||
tearDown();
|
||||
};
|
||||
|
||||
// bind to window close
|
||||
// @todo investigate new method for listening as discovered in previous tests
|
||||
|
||||
function setup() {
|
||||
unsavedWarningsConfig.log('Setting up');
|
||||
|
||||
window.onbeforeunload = _this.confirmExit;
|
||||
|
||||
var eventsToWatchFor = unsavedWarningsConfig.routeEvent;
|
||||
|
||||
angular.forEach(eventsToWatchFor, function(aEvent) {
|
||||
// calling this function later will unbind this, acting as $off()
|
||||
var removeFn = $rootScope.$on(aEvent, function(event, next, current) {
|
||||
unsavedWarningsConfig.log("user is moving with " + aEvent);
|
||||
// @todo this could be written a lot cleaner!
|
||||
if (!allFormsClean()) {
|
||||
unsavedWarningsConfig.log("a form is dirty");
|
||||
if (!confirm(messages.navigate)) {
|
||||
unsavedWarningsConfig.log("user wants to cancel leaving");
|
||||
event.preventDefault(); // user clicks cancel, wants to stay on page
|
||||
} else {
|
||||
unsavedWarningsConfig.log("user doesn't care about loosing stuff");
|
||||
}
|
||||
} else {
|
||||
unsavedWarningsConfig.log("all forms are clean");
|
||||
}
|
||||
|
||||
});
|
||||
removeFunctions.push(removeFn);
|
||||
});
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
.directive('unsavedWarningClear', ['unsavedWarningSharedService',
|
||||
function(unsavedWarningSharedService) {
|
||||
return {
|
||||
scope: true,
|
||||
require: '^form',
|
||||
priority: 3000,
|
||||
link: function(scope, element, attrs, formCtrl) {
|
||||
element.bind('click', function(event) {
|
||||
formCtrl.$setPristine();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.directive('unsavedWarningForm', ['unsavedWarningSharedService',
|
||||
function(unsavedWarningSharedService) {
|
||||
return {
|
||||
require: 'form',
|
||||
link: function(scope, formElement, attrs, formCtrl) {
|
||||
|
||||
// register this form
|
||||
unsavedWarningSharedService.init(formCtrl);
|
||||
|
||||
// bind to form submit, this makes the typical submit button work
|
||||
// in addition to the ability to bind to a seperate button which clears warning
|
||||
formElement.bind('submit', function(event) {
|
||||
if (formCtrl.$valid) {
|
||||
formCtrl.$setPristine();
|
||||
}
|
||||
});
|
||||
|
||||
// @todo check destroy on clear button too?
|
||||
scope.$on('$destroy', function() {
|
||||
unsavedWarningSharedService.removeForm(formCtrl);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
|
||||
|
||||
/**
|
||||
* --------------------------------------------
|
||||
* Lazy model adapted from vitalets
|
||||
* @see https://github.com/vitalets/lazy-model/
|
||||
* --------------------------------------------
|
||||
*
|
||||
*/
|
||||
angular.module('lazyModel', [])
|
||||
|
||||
.directive('lazyModel', ['$parse', '$compile',
|
||||
function($parse, $compile) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
priority: 500,
|
||||
terminal: true,
|
||||
require: '^form',
|
||||
scope: true,
|
||||
compile: function compile(elem, attr) {
|
||||
// getter and setter for original model
|
||||
var ngModelGet = $parse(attr.lazyModel);
|
||||
var ngModelSet = ngModelGet.assign;
|
||||
// set ng-model to buffer in isolate scope
|
||||
elem.attr('ng-model', 'buffer');
|
||||
// remove lazy-model attribute to exclude recursion
|
||||
elem.removeAttr("lazy-model");
|
||||
return {
|
||||
pre: function(scope, elem) {
|
||||
// initialize buffer value as copy of original model
|
||||
scope.buffer = ngModelGet(scope.$parent);
|
||||
// compile element with ng-model directive pointing to buffer value
|
||||
$compile(elem)(scope);
|
||||
},
|
||||
post: function postLink(scope, elem, attr, formCtrl) {
|
||||
// bind form submit to write back final value from buffer
|
||||
var form = elem.parent();
|
||||
while (form[0].tagName !== 'FORM') {
|
||||
form = form.parent();
|
||||
}
|
||||
form.bind('submit', function() {
|
||||
// form valid - save new value
|
||||
if (formCtrl.$valid) {
|
||||
scope.$apply(function() {
|
||||
ngModelSet(scope.$parent, scope.buffer);
|
||||
});
|
||||
}
|
||||
});
|
||||
form.bind('reset', function(e) {
|
||||
e.preventDefault();
|
||||
scope.$apply(function() {
|
||||
scope.buffer = ngModelGet(scope.$parent);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
1
sites/all/modules/civicrm/bower_components/angular-unsavedChanges/dist/unsavedChanges.min.js
vendored
Normal file
1
sites/all/modules/civicrm/bower_components/angular-unsavedChanges/dist/unsavedChanges.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
"use strict";angular.module("unsavedChanges",["lazyModel"]).provider("unsavedWarningsConfig",function(){var f=this;var e=false;var b=true;var d=["$locationChangeStart","$stateChangeStart"];var c="You will lose unsaved changes if you leave this page";var a="You will lose unsaved changes if you reload this page";Object.defineProperty(f,"navigateMessage",{get:function(){return c},set:function(g){c=g}});Object.defineProperty(f,"reloadMessage",{get:function(){return a},set:function(g){a=g}});Object.defineProperty(f,"useTranslateService",{get:function(){return b},set:function(g){b=!!(g)}});Object.defineProperty(f,"routeEvent",{get:function(){return d},set:function(g){if(typeof g==="string"){g=[g]}d=g}});Object.defineProperty(f,"logEnabled",{get:function(){return e},set:function(g){e=!!(g)}});this.$get=["$injector",function(h){function i(j){if(h.has("$translate")&&b){return h.get("$translate")(j)}else{return false}}var g={log:function(){if(console.log&&e&&arguments.length){var j=[].slice.call(arguments);if(typeof console.log==="object"){log.apply.call(console.log,console,j)}else{console.log.apply(console,j)}}}};Object.defineProperty(g,"useTranslateService",{get:function(){return b}});Object.defineProperty(g,"reloadMessage",{get:function(){return i(a)||a}});Object.defineProperty(g,"navigateMessage",{get:function(){return i(c)||c}});Object.defineProperty(g,"routeEvent",{get:function(){return d}});Object.defineProperty(g,"logEnabled",{get:function(){return e}});return g}]}).service("unsavedWarningSharedService",["$rootScope","unsavedWarningsConfig","$injector",function(j,c,k){var i=this;var a=[];var g=true;var d=[angular.noop];this.allForms=function(){return a};var f={navigate:c.navigateMessage,reload:c.reloadMessage};function h(){g=true;angular.forEach(a,function(m,l){c.log("Form : "+m.$name+" dirty : "+m.$dirty);if(m.$dirty){g=false}});return g}this.init=function(l){if(a.length===0){e()}c.log("Registering form",l);a.push(l)};this.removeForm=function(m){var l=a.indexOf(m);if(l===-1){return}a.splice(l,1);c.log("Removing form from watch list",m);if(a.length===0){b()}};function b(){c.log("No more forms, tearing down");angular.forEach(d,function(l){l()});window.onbeforeunload=null}this.confirmExit=function(){if(!h()){return f.reload}b()};function e(){c.log("Setting up");window.onbeforeunload=i.confirmExit;var l=c.routeEvent;angular.forEach(l,function(m){var n=j.$on(m,function(p,o,q){c.log("user is moving with "+m);if(!h()){c.log("a form is dirty");if(!confirm(f.navigate)){c.log("user wants to cancel leaving");p.preventDefault()}else{c.log("user doesn't care about loosing stuff")}}else{c.log("all forms are clean")}});d.push(n)})}}]).directive("unsavedWarningClear",["unsavedWarningSharedService",function(a){return{scope:true,require:"^form",priority:3000,link:function(d,c,b,e){c.bind("click",function(f){e.$setPristine()})}}}]).directive("unsavedWarningForm",["unsavedWarningSharedService",function(a){return{require:"form",link:function(d,c,b,e){a.init(e);c.bind("submit",function(f){if(e.$valid){e.$setPristine()}});d.$on("$destroy",function(){a.removeForm(e)})}}}]);angular.module("lazyModel",[]).directive("lazyModel",["$parse","$compile",function(b,a){return{restrict:"A",priority:500,terminal:true,require:"^form",scope:true,compile:function c(g,e){var f=b(e.lazyModel);var h=f.assign;g.attr("ng-model","buffer");g.removeAttr("lazy-model");return{pre:function(i,j){i.buffer=f(i.$parent);a(j)(i)},post:function d(j,l,i,m){var k=l.parent();while(k[0].tagName!=="FORM"){k=k.parent()}k.bind("submit",function(){if(m.$valid){j.$apply(function(){h(j.$parent,j.buffer)})}});k.bind("reset",function(n){n.preventDefault();j.$apply(function(){j.buffer=f(j.$parent)})})}}}}}]);
|
Loading…
Add table
Add a link
Reference in a new issue