├── MyTaskListApp ├── Views │ ├── _ViewStart.cshtml │ ├── Home │ │ ├── About.cshtml │ │ ├── Contact.cshtml │ │ ├── Index.cshtml │ │ └── Create.cshtml │ ├── Account │ │ ├── ExternalLoginFailure.cshtml │ │ ├── ForgotPasswordConfirmation.cshtml │ │ ├── ConfirmEmail.cshtml │ │ ├── ResetPasswordConfirmation.cshtml │ │ ├── SendCode.cshtml │ │ ├── ForgotPassword.cshtml │ │ ├── _ExternalLoginsListPartial.cshtml │ │ ├── VerifyCode.cshtml │ │ ├── ExternalLoginConfirmation.cshtml │ │ ├── Register.cshtml │ │ ├── ResetPassword.cshtml │ │ └── Login.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── Lockout.cshtml │ │ ├── _LoginPartial.cshtml │ │ └── _Layout.cshtml │ ├── Manage │ │ ├── AddPhoneNumber.cshtml │ │ ├── VerifyPhoneNumber.cshtml │ │ ├── SetPassword.cshtml │ │ ├── ChangePassword.cshtml │ │ ├── ManageLogins.cshtml │ │ └── Index.cshtml │ └── Web.config ├── Global.asax ├── favicon.ico ├── Scripts │ ├── src │ │ ├── utils │ │ │ ├── isBrowser.js │ │ │ ├── isNumeric.js │ │ │ ├── getWindow.js │ │ │ ├── isModifierEnabled.js │ │ │ ├── isOffsetContainer.js │ │ │ ├── getRoot.js │ │ │ ├── getParentNode.js │ │ │ ├── getClientRect.js │ │ │ ├── getOppositePlacement.js │ │ │ ├── isFunction.js │ │ │ ├── getReferenceNode.js │ │ │ ├── getOppositeVariation.js │ │ │ ├── find.js │ │ │ ├── getStyleComputedProperty.js │ │ │ ├── isIE.js │ │ │ ├── findIndex.js │ │ │ ├── setAttributes.js │ │ │ ├── getBordersSize.js │ │ │ ├── getOuterSizes.js │ │ │ ├── getScroll.js │ │ │ ├── removeEventListeners.js │ │ │ ├── getSupportedPropertyName.js │ │ │ ├── setStyles.js │ │ │ ├── isFixed.js │ │ │ ├── clockwise.js │ │ │ ├── getFixedPositionOffsetParent.js │ │ │ ├── getWindowSizes.js │ │ │ ├── includeScroll.js │ │ │ ├── getOffsetRect.js │ │ │ ├── getViewportOffsetRectRelativeToArtbitraryNode.js │ │ │ ├── getScrollParent.js │ │ │ ├── getReferenceOffsets.js │ │ │ ├── isModifierRequired.js │ │ │ ├── debounce.js │ │ │ ├── setupEventListeners.js │ │ │ ├── getOffsetParent.js │ │ │ ├── runModifiers.js │ │ │ ├── getPopperOffsets.js │ │ │ ├── findCommonOffsetParent.js │ │ │ ├── getRoundedOffsets.js │ │ │ ├── computeAutoPlacement.js │ │ │ ├── getBoundingClientRect.js │ │ │ ├── getOffsetRectRelativeToArbitraryNode.js │ │ │ ├── getBoundaries.js │ │ │ └── index.js │ │ ├── methods │ │ │ ├── enableEventListeners.js │ │ │ ├── disableEventListeners.js │ │ │ ├── destroy.js │ │ │ ├── placements.js │ │ │ ├── defaults.js │ │ │ └── update.js │ │ ├── modifiers │ │ │ ├── keepTogether.js │ │ │ ├── inner.js │ │ │ ├── shift.js │ │ │ ├── hide.js │ │ │ ├── applyStyle.js │ │ │ ├── preventOverflow.js │ │ │ ├── arrow.js │ │ │ ├── computeStyle.js │ │ │ └── flip.js │ │ └── index.js │ ├── _references.js │ ├── index.js.flow │ ├── umd │ │ └── popper.js.flow │ ├── respond.min.js │ ├── respond.matchmedia.addListener.min.js │ ├── index.d.ts │ └── jquery.validate.unobtrusive.min.js ├── Core │ └── Compression │ │ ├── Snappy │ │ └── lib │ │ │ └── win │ │ │ ├── snappy32.dll │ │ │ └── snappy64.dll │ │ └── Zstandard │ │ └── lib │ │ └── win │ │ └── libzstd.dll ├── Service References │ └── Application Insights │ │ └── ConnectedService.json ├── App_Start │ ├── FilterConfig.cs │ ├── RouteConfig.cs │ ├── BundleConfig.cs │ ├── Startup.Auth.cs │ └── IdentityConfig.cs ├── Startup.cs ├── Content │ ├── Site.css │ ├── bootstrap-reboot.min.css │ └── bootstrap-reboot.css ├── Global.asax.cs ├── Models │ ├── TaskModel.cs │ ├── IdentityModels.cs │ ├── ManageViewModels.cs │ └── AccountViewModels.cs ├── Web.Debug.config ├── Web.Release.config ├── Properties │ └── AssemblyInfo.cs ├── Controllers │ └── HomeController.cs ├── DAL │ └── Dal.cs ├── packages.config └── Project_Readme.html ├── MyTaskListApp.sln ├── LICENSE ├── README.md └── .gitignore /MyTaskListApp/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /MyTaskListApp/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MyTaskListApp.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /MyTaskListApp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-cosmos-db-mongodb-dotnet-getting-started/HEAD/MyTaskListApp/favicon.ico -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isBrowser.js: -------------------------------------------------------------------------------- 1 | export default typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; 2 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |

@ViewBag.Title.

5 |

@ViewBag.Message

6 | 7 |

Use this area to provide additional information.

8 | -------------------------------------------------------------------------------- /MyTaskListApp/Core/Compression/Snappy/lib/win/snappy32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-cosmos-db-mongodb-dotnet-getting-started/HEAD/MyTaskListApp/Core/Compression/Snappy/lib/win/snappy32.dll -------------------------------------------------------------------------------- /MyTaskListApp/Core/Compression/Snappy/lib/win/snappy64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-cosmos-db-mongodb-dotnet-getting-started/HEAD/MyTaskListApp/Core/Compression/Snappy/lib/win/snappy64.dll -------------------------------------------------------------------------------- /MyTaskListApp/Core/Compression/Zstandard/lib/win/libzstd.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure-Samples/azure-cosmos-db-mongodb-dotnet-getting-started/HEAD/MyTaskListApp/Core/Compression/Zstandard/lib/win/libzstd.dll -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ExternalLoginFailure.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Login Failure"; 3 | } 4 | 5 |
6 |

@ViewBag.Title.

7 |

Unsuccessful login with service.

8 |
9 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Error"; 5 | } 6 | 7 |

Error.

8 |

An error occurred while processing your request.

9 | 10 | -------------------------------------------------------------------------------- /MyTaskListApp/Service References/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "7.0.20622.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=613413" 6 | } 7 | } -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isNumeric.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tells if a given input is a number 3 | * @method 4 | * @memberof Popper.Utils 5 | * @param {*} input to check 6 | * @return {Boolean} 7 | */ 8 | export default function isNumeric(n) { 9 | return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 10 | } 11 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Shared/Lockout.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Locked Out"; 5 | } 6 | 7 |
8 |

Locked out.

9 |

This account has been locked out, please try again later.

10 |
11 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ForgotPasswordConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Forgot Password Confirmation"; 3 | } 4 | 5 |
6 |

@ViewBag.Title.

7 |
8 |
9 |

10 | Please check your email to reset your password. 11 |

12 |
13 | 14 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getWindow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the window associated with the element 3 | * @argument {Element} element 4 | * @returns {Window} 5 | */ 6 | export default function getWindow(element) { 7 | const ownerDocument = element.ownerDocument; 8 | return ownerDocument ? ownerDocument.defaultView : window; 9 | } 10 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/_references.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | /// 8 | -------------------------------------------------------------------------------- /MyTaskListApp/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace MyTaskListApp 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MyTaskListApp/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Owin; 2 | using Owin; 3 | 4 | [assembly: OwinStartupAttribute(typeof(MyTaskListApp.Startup))] 5 | namespace MyTaskListApp 6 | { 7 | public partial class Startup 8 | { 9 | public void Configuration(IAppBuilder app) 10 | { 11 | ConfigureAuth(app); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ConfirmEmail.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Confirm Email"; 3 | } 4 | 5 |

@ViewBag.Title.

6 |
7 |

8 | Thank you for confirming your email. Please @Html.ActionLink("Click here to Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" }) 9 |

10 |
11 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isModifierEnabled.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper used to know if the given modifier is enabled. 3 | * @method 4 | * @memberof Popper.Utils 5 | * @returns {Boolean} 6 | */ 7 | export default function isModifierEnabled(modifiers, modifierName) { 8 | return modifiers.some( 9 | ({ name, enabled }) => enabled && name === modifierName 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isOffsetContainer.js: -------------------------------------------------------------------------------- 1 | import getOffsetParent from './getOffsetParent'; 2 | 3 | export default function isOffsetContainer(element) { 4 | const { nodeName } = element; 5 | if (nodeName === 'BODY') { 6 | return false; 7 | } 8 | return ( 9 | nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getRoot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Finds the root node (document, shadowDOM root) of the given element 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Element} node 6 | * @returns {Element} root node 7 | */ 8 | export default function getRoot(node) { 9 | if (node.parentNode !== null) { 10 | return getRoot(node.parentNode); 11 | } 12 | 13 | return node; 14 | } 15 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getParentNode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the parentNode or the host of the element 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Element} element 6 | * @returns {Element} parent 7 | */ 8 | export default function getParentNode(element) { 9 | if (element.nodeName === 'HTML') { 10 | return element; 11 | } 12 | return element.parentNode || element.host; 13 | } 14 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ResetPasswordConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Reset password confirmation"; 3 | } 4 | 5 |
6 |

@ViewBag.Title.

7 |
8 |
9 |

10 | Your password has been reset. Please @Html.ActionLink("click here to log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" }) 11 |

12 |
13 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getClientRect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Given element offsets, generate an output similar to getBoundingClientRect 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Object} offsets 6 | * @returns {Object} ClientRect like output 7 | */ 8 | export default function getClientRect(offsets) { 9 | return { 10 | ...offsets, 11 | right: offsets.left + offsets.width, 12 | bottom: offsets.top + offsets.height, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getOppositePlacement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the opposite placement of the given one 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {String} placement 6 | * @returns {String} flipped placement 7 | */ 8 | export default function getOppositePlacement(placement) { 9 | const hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; 10 | return placement.replace(/left|right|bottom|top/g, matched => hash[matched]); 11 | } 12 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isFunction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Check if the given variable is a function 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Any} functionToCheck - variable to check 6 | * @returns {Boolean} answer to: is a function? 7 | */ 8 | export default function isFunction(functionToCheck) { 9 | const getType = {}; 10 | return ( 11 | functionToCheck && 12 | getType.toString.call(functionToCheck) === '[object Function]' 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getReferenceNode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the reference node of the reference object, or the reference object itself. 3 | * @method 4 | * @memberof Popper.Utils 5 | * @param {Element|Object} reference - the reference element (the popper will be relative to this) 6 | * @returns {Element} parent 7 | */ 8 | export default function getReferenceNode(reference) { 9 | return reference && reference.referenceNode ? reference.referenceNode : reference; 10 | } 11 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getOppositeVariation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the opposite placement variation of the given one 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {String} placement variation 6 | * @returns {String} flipped placement variation 7 | */ 8 | export default function getOppositeVariation(variation) { 9 | if (variation === 'end') { 10 | return 'start'; 11 | } else if (variation === 'start') { 12 | return 'end'; 13 | } 14 | return variation; 15 | } 16 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/find.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Mimics the `find` method of Array 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Array} arr 6 | * @argument prop 7 | * @argument value 8 | * @returns index or -1 9 | */ 10 | export default function find(arr, check) { 11 | // use native find if supported 12 | if (Array.prototype.find) { 13 | return arr.find(check); 14 | } 15 | 16 | // use `filter` to obtain the same behavior of `find` 17 | return arr.filter(check)[0]; 18 | } 19 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Contact"; 3 | } 4 |

@ViewBag.Title.

5 |

@ViewBag.Message

6 | 7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P: 11 | 425.555.0100 12 |
13 | 14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com 17 |
-------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/methods/enableEventListeners.js: -------------------------------------------------------------------------------- 1 | import setupEventListeners from '../utils/setupEventListeners'; 2 | 3 | /** 4 | * It will add resize/scroll events and start recalculating 5 | * position of the popper element when they are triggered. 6 | * @method 7 | * @memberof Popper 8 | */ 9 | export default function enableEventListeners() { 10 | if (!this.state.eventsEnabled) { 11 | this.state = setupEventListeners( 12 | this.reference, 13 | this.options, 14 | this.state, 15 | this.scheduleUpdate 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getStyleComputedProperty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get CSS computed property of the given element 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Eement} element 6 | * @argument {String} property 7 | */ 8 | export default function getStyleComputedProperty(element, property) { 9 | if (element.nodeType !== 1) { 10 | return []; 11 | } 12 | // NOTE: 1 DOM access here 13 | const window = element.ownerDocument.defaultView; 14 | const css = window.getComputedStyle(element, null); 15 | return property ? css[property] : css; 16 | } 17 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/methods/disableEventListeners.js: -------------------------------------------------------------------------------- 1 | import removeEventListeners from '../utils/removeEventListeners'; 2 | 3 | /** 4 | * It will remove resize/scroll events and won't recalculate popper position 5 | * when they are triggered. It also won't trigger `onUpdate` callback anymore, 6 | * unless you call `update` method manually. 7 | * @method 8 | * @memberof Popper 9 | */ 10 | export default function disableEventListeners() { 11 | if (this.state.eventsEnabled) { 12 | cancelAnimationFrame(this.scheduleUpdate); 13 | this.state = removeEventListeners(this.reference, this.state); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isIE.js: -------------------------------------------------------------------------------- 1 | import isBrowser from './isBrowser'; 2 | 3 | const isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); 4 | const isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); 5 | 6 | /** 7 | * Determines if the browser is Internet Explorer 8 | * @method 9 | * @memberof Popper.Utils 10 | * @param {Number} version to check 11 | * @returns {Boolean} isIE 12 | */ 13 | export default function isIE(version) { 14 | if (version === 11) { 15 | return isIE11; 16 | } 17 | if (version === 10) { 18 | return isIE10; 19 | } 20 | return isIE11 || isIE10; 21 | } 22 | -------------------------------------------------------------------------------- /MyTaskListApp/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Override the default bootstrap behavior where horizontal description lists 13 | will truncate terms that are too long to fit in the left column 14 | */ 15 | .dl-horizontal dt { 16 | white-space: normal; 17 | } 18 | 19 | /* Set width on the form input elements since they're 100% wide by default */ 20 | input, 21 | select, 22 | textarea { 23 | max-width: 280px; 24 | } 25 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/findIndex.js: -------------------------------------------------------------------------------- 1 | import find from './find'; 2 | 3 | /** 4 | * Return the index of the matching object 5 | * @method 6 | * @memberof Popper.Utils 7 | * @argument {Array} arr 8 | * @argument prop 9 | * @argument value 10 | * @returns index or -1 11 | */ 12 | export default function findIndex(arr, prop, value) { 13 | // use native findIndex if supported 14 | if (Array.prototype.findIndex) { 15 | return arr.findIndex(cur => cur[prop] === value); 16 | } 17 | 18 | // use `find` + `indexOf` if `findIndex` isn't supported 19 | const match = find(arr, obj => obj[prop] === value); 20 | return arr.indexOf(match); 21 | } 22 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/setAttributes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Set the attributes to the given popper 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Element} element - Element to apply the attributes to 6 | * @argument {Object} styles 7 | * Object with a list of properties and values which will be applied to the element 8 | */ 9 | export default function setAttributes(element, attributes) { 10 | Object.keys(attributes).forEach(function(prop) { 11 | const value = attributes[prop]; 12 | if (value !== false) { 13 | element.setAttribute(prop, attributes[prop]); 14 | } else { 15 | element.removeAttribute(prop); 16 | } 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /MyTaskListApp/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Optimization; 7 | using System.Web.Routing; 8 | 9 | namespace MyTaskListApp 10 | { 11 | public class MvcApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | AreaRegistration.RegisterAllAreas(); 16 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | BundleConfig.RegisterBundles(BundleTable.Bundles); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getBordersSize.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper to detect borders of a given element 3 | * @method 4 | * @memberof Popper.Utils 5 | * @param {CSSStyleDeclaration} styles 6 | * Result of `getStyleComputedProperty` on the given element 7 | * @param {String} axis - `x` or `y` 8 | * @return {number} borders - The borders size of the given axis 9 | */ 10 | 11 | export default function getBordersSize(styles, axis) { 12 | const sideA = axis === 'x' ? 'Left' : 'Top'; 13 | const sideB = sideA === 'Left' ? 'Right' : 'Bottom'; 14 | 15 | return ( 16 | parseFloat(styles[`border${sideA}Width`]) + 17 | parseFloat(styles[`border${sideB}Width`]) 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /MyTaskListApp/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace MyTaskListApp 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getOuterSizes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the outer sizes of the given element (offset size + margins) 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Element} element 6 | * @returns {Object} object containing width and height properties 7 | */ 8 | export default function getOuterSizes(element) { 9 | const window = element.ownerDocument.defaultView; 10 | const styles = window.getComputedStyle(element); 11 | const x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); 12 | const y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); 13 | const result = { 14 | width: element.offsetWidth + y, 15 | height: element.offsetHeight + x, 16 | }; 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getScroll.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gets the scroll value of the given element in the given side (top and left) 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {Element} element 6 | * @argument {String} side `top` or `left` 7 | * @returns {number} amount of scrolled pixels 8 | */ 9 | export default function getScroll(element, side = 'top') { 10 | const upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; 11 | const nodeName = element.nodeName; 12 | 13 | if (nodeName === 'BODY' || nodeName === 'HTML') { 14 | const html = element.ownerDocument.documentElement; 15 | const scrollingElement = element.ownerDocument.scrollingElement || html; 16 | return scrollingElement[upperSide]; 17 | } 18 | 19 | return element[upperSide]; 20 | } 21 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/removeEventListeners.js: -------------------------------------------------------------------------------- 1 | import getWindow from './getWindow'; 2 | 3 | /** 4 | * Remove event listeners used to update the popper position 5 | * @method 6 | * @memberof Popper.Utils 7 | * @private 8 | */ 9 | export default function removeEventListeners(reference, state) { 10 | // Remove resize event listener on window 11 | getWindow(reference).removeEventListener('resize', state.updateBound); 12 | 13 | // Remove scroll event listener on scroll parents 14 | state.scrollParents.forEach(target => { 15 | target.removeEventListener('scroll', state.updateBound); 16 | }); 17 | 18 | // Reset state 19 | state.updateBound = null; 20 | state.scrollParents = []; 21 | state.scrollElement = null; 22 | state.eventsEnabled = false; 23 | return state; 24 | } 25 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getSupportedPropertyName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the prefixed supported property name 3 | * @method 4 | * @memberof Popper.Utils 5 | * @argument {String} property (camelCase) 6 | * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 7 | */ 8 | export default function getSupportedPropertyName(property) { 9 | const prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 10 | const upperProp = property.charAt(0).toUpperCase() + property.slice(1); 11 | 12 | for (let i = 0; i < prefixes.length; i++) { 13 | const prefix = prefixes[i]; 14 | const toCheck = prefix ? `${prefix}${upperProp}` : property; 15 | if (typeof document.body.style[toCheck] !== 'undefined') { 16 | return toCheck; 17 | } 18 | } 19 | return null; 20 | } 21 | -------------------------------------------------------------------------------- /MyTaskListApp/Models/TaskModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using MongoDB.Bson.Serialization.Attributes; 6 | using MongoDB.Bson.Serialization.IdGenerators; 7 | using MongoDB.Bson; 8 | 9 | namespace MyTaskListApp.Models 10 | { 11 | public class MyTask 12 | { 13 | [BsonId(IdGenerator = typeof(CombGuidGenerator))] 14 | public Guid Id { get; set; } 15 | 16 | [BsonElement("Name")] 17 | public string Name { get; set; } 18 | 19 | [BsonElement("Category")] 20 | public string Category { get; set; } 21 | 22 | [BsonElement("Date")] 23 | public DateTime Date { get; set; } 24 | 25 | [BsonElement("CreatedDate")] 26 | public DateTime CreatedDate { get; set; } 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/setStyles.js: -------------------------------------------------------------------------------- 1 | import isNumeric from './isNumeric'; 2 | 3 | /** 4 | * Set the style to the given popper 5 | * @method 6 | * @memberof Popper.Utils 7 | * @argument {Element} element - Element to apply the style to 8 | * @argument {Object} styles 9 | * Object with a list of properties and values which will be applied to the element 10 | */ 11 | export default function setStyles(element, styles) { 12 | Object.keys(styles).forEach(prop => { 13 | let unit = ''; 14 | // add unit if the value is numeric and is one of the following 15 | if ( 16 | ['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== 17 | -1 && 18 | isNumeric(styles[prop]) 19 | ) { 20 | unit = 'px'; 21 | } 22 | element.style[prop] = styles[prop] + unit; 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isFixed.js: -------------------------------------------------------------------------------- 1 | import getStyleComputedProperty from './getStyleComputedProperty'; 2 | import getParentNode from './getParentNode'; 3 | 4 | /** 5 | * Check if the given element is fixed or is inside a fixed parent 6 | * @method 7 | * @memberof Popper.Utils 8 | * @argument {Element} element 9 | * @argument {Element} customContainer 10 | * @returns {Boolean} answer to "isFixed?" 11 | */ 12 | export default function isFixed(element) { 13 | const nodeName = element.nodeName; 14 | if (nodeName === 'BODY' || nodeName === 'HTML') { 15 | return false; 16 | } 17 | if (getStyleComputedProperty(element, 'position') === 'fixed') { 18 | return true; 19 | } 20 | const parentNode = getParentNode(element); 21 | if (!parentNode) { 22 | return false; 23 | } 24 | return isFixed(parentNode); 25 | } 26 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/SendCode.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.SendCodeViewModel 2 | @{ 3 | ViewBag.Title = "Send"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("SendCode", "Account", new { ReturnUrl = Model.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { 9 | @Html.AntiForgeryToken() 10 | @Html.Hidden("rememberMe", @Model.RememberMe) 11 |

Send verification code

12 |
13 |
14 |
15 | Select Two-Factor Authentication Provider: 16 | @Html.DropDownListFor(model => model.SelectedProvider, Model.Providers) 17 | 18 |
19 |
20 | } 21 | 22 | @section Scripts { 23 | @Scripts.Render("~/bundles/jqueryval") 24 | } 25 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/clockwise.js: -------------------------------------------------------------------------------- 1 | import placements from '../methods/placements'; 2 | 3 | // Get rid of `auto` `auto-start` and `auto-end` 4 | const validPlacements = placements.slice(3); 5 | 6 | /** 7 | * Given an initial placement, returns all the subsequent placements 8 | * clockwise (or counter-clockwise). 9 | * 10 | * @method 11 | * @memberof Popper.Utils 12 | * @argument {String} placement - A valid placement (it accepts variations) 13 | * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 14 | * @returns {Array} placements including their variations 15 | */ 16 | export default function clockwise(placement, counter = false) { 17 | const index = validPlacements.indexOf(placement); 18 | const arr = validPlacements 19 | .slice(index + 1) 20 | .concat(validPlacements.slice(0, index)); 21 | return counter ? arr.reverse() : arr; 22 | } 23 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getFixedPositionOffsetParent.js: -------------------------------------------------------------------------------- 1 | import getStyleComputedProperty from './getStyleComputedProperty'; 2 | import isIE from './isIE'; 3 | /** 4 | * Finds the first parent of an element that has a transformed property defined 5 | * @method 6 | * @memberof Popper.Utils 7 | * @argument {Element} element 8 | * @returns {Element} first transformed parent or documentElement 9 | */ 10 | 11 | export default function getFixedPositionOffsetParent(element) { 12 | // This check is needed to avoid errors in case one of the elements isn't defined for any reason 13 | if (!element || !element.parentElement || isIE()) { 14 | return document.documentElement; 15 | } 16 | let el = element.parentElement; 17 | while (el && getStyleComputedProperty(el, 'transform') === 'none') { 18 | el = el.parentElement; 19 | } 20 | return el || document.documentElement; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getWindowSizes.js: -------------------------------------------------------------------------------- 1 | import isIE from './isIE'; 2 | 3 | function getSize(axis, body, html, computedStyle) { 4 | return Math.max( 5 | body[`offset${axis}`], 6 | body[`scroll${axis}`], 7 | html[`client${axis}`], 8 | html[`offset${axis}`], 9 | html[`scroll${axis}`], 10 | isIE(10) 11 | ? (parseInt(html[`offset${axis}`]) + 12 | parseInt(computedStyle[`margin${axis === 'Height' ? 'Top' : 'Left'}`]) + 13 | parseInt(computedStyle[`margin${axis === 'Height' ? 'Bottom' : 'Right'}`])) 14 | : 0 15 | ); 16 | } 17 | 18 | export default function getWindowSizes(document) { 19 | const body = document.body; 20 | const html = document.documentElement; 21 | const computedStyle = isIE(10) && getComputedStyle(html); 22 | 23 | return { 24 | height: getSize('Height', body, html, computedStyle), 25 | width: getSize('Width', body, html, computedStyle), 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model IEnumerable 2 | 3 | @{ 4 | ViewBag.Title = "My Task List"; 5 | } 6 | 7 |

My Task List

8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | @foreach (var item in Model) 18 | { 19 | 20 | 23 | 26 | 29 | 30 | 31 | } 32 | 33 |
TaskCategoryDate
21 | @Html.DisplayFor(modelItem => item.Name) 22 | 24 | @Html.DisplayFor(modelItem => item.Category) 25 | 27 | @Html.DisplayFor(modelItem => item.Date) 28 |
34 |
@Html.Partial("Create", new MyTaskListApp.Models.MyTask())
35 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/includeScroll.js: -------------------------------------------------------------------------------- 1 | import getScroll from './getScroll'; 2 | 3 | /* 4 | * Sum or subtract the element scroll values (left and top) from a given rect object 5 | * @method 6 | * @memberof Popper.Utils 7 | * @param {Object} rect - Rect object you want to change 8 | * @param {HTMLElement} element - The element from the function reads the scroll values 9 | * @param {Boolean} subtract - set to true if you want to subtract the scroll values 10 | * @return {Object} rect - The modifier rect object 11 | */ 12 | export default function includeScroll(rect, element, subtract = false) { 13 | const scrollTop = getScroll(element, 'top'); 14 | const scrollLeft = getScroll(element, 'left'); 15 | const modifier = subtract ? -1 : 1; 16 | rect.top += scrollTop * modifier; 17 | rect.bottom += scrollTop * modifier; 18 | rect.left += scrollLeft * modifier; 19 | rect.right += scrollLeft * modifier; 20 | return rect; 21 | } 22 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getOffsetRect.js: -------------------------------------------------------------------------------- 1 | import getWindowSizes from './getWindowSizes'; 2 | import getClientRect from './getClientRect'; 3 | 4 | /** 5 | * Get the position of the given element, relative to its offset parent 6 | * @method 7 | * @memberof Popper.Utils 8 | * @param {Element} element 9 | * @return {Object} position - Coordinates of the element and its `scrollTop` 10 | */ 11 | export default function getOffsetRect(element) { 12 | let elementRect; 13 | if (element.nodeName === 'HTML') { 14 | const { width, height } = getWindowSizes(element.ownerDocument); 15 | elementRect = { 16 | width, 17 | height, 18 | left: 0, 19 | top: 0, 20 | }; 21 | } else { 22 | elementRect = { 23 | width: element.offsetWidth, 24 | height: element.offsetHeight, 25 | left: element.offsetLeft, 26 | top: element.offsetTop, 27 | }; 28 | } 29 | 30 | // position 31 | return getClientRect(elementRect); 32 | } 33 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNet.Identity 2 | @if (Request.IsAuthenticated) 3 | { 4 | using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) 5 | { 6 | @Html.AntiForgeryToken() 7 | 8 | 14 | } 15 | } 16 | else 17 | { 18 | 22 | } 23 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Manage/AddPhoneNumber.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.AddPhoneNumberViewModel 2 | @{ 3 | ViewBag.Title = "Phone Number"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("AddPhoneNumber", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

Add a phone number

12 |
13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
15 | @Html.LabelFor(m => m.Number, new { @class = "col-md-2 control-label" }) 16 |
17 | @Html.TextBoxFor(m => m.Number, new { @class = "form-control" }) 18 |
19 |
20 |
21 |
22 | 23 |
24 |
25 | } 26 | 27 | @section Scripts { 28 | @Scripts.Render("~/bundles/jqueryval") 29 | } 30 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/keepTogether.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function 3 | * @memberof Modifiers 4 | * @argument {Object} data - The data object generated by update method 5 | * @argument {Object} options - Modifiers configuration and options 6 | * @returns {Object} The data object, properly modified 7 | */ 8 | export default function keepTogether(data) { 9 | const { popper, reference } = data.offsets; 10 | const placement = data.placement.split('-')[0]; 11 | const floor = Math.floor; 12 | const isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 13 | const side = isVertical ? 'right' : 'bottom'; 14 | const opSide = isVertical ? 'left' : 'top'; 15 | const measurement = isVertical ? 'width' : 'height'; 16 | 17 | if (popper[side] < floor(reference[opSide])) { 18 | data.offsets.popper[opSide] = 19 | floor(reference[opSide]) - popper[measurement]; 20 | } 21 | if (popper[opSide] > floor(reference[side])) { 22 | data.offsets.popper[opSide] = floor(reference[side]); 23 | } 24 | 25 | return data; 26 | } 27 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ForgotPassword.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.ForgotPasswordViewModel 2 | @{ 3 | ViewBag.Title = "Forgot your password?"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("ForgotPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

Enter your email.

12 |
13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
15 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 16 |
17 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 18 |
19 |
20 |
21 |
22 | 23 |
24 |
25 | } 26 | 27 | @section Scripts { 28 | @Scripts.Render("~/bundles/jqueryval") 29 | } 30 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getViewportOffsetRectRelativeToArtbitraryNode.js: -------------------------------------------------------------------------------- 1 | import getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode'; 2 | import getScroll from './getScroll'; 3 | import getClientRect from './getClientRect'; 4 | 5 | export default function getViewportOffsetRectRelativeToArtbitraryNode(element, excludeScroll = false) { 6 | const html = element.ownerDocument.documentElement; 7 | const relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 8 | const width = Math.max(html.clientWidth, window.innerWidth || 0); 9 | const height = Math.max(html.clientHeight, window.innerHeight || 0); 10 | 11 | const scrollTop = !excludeScroll ? getScroll(html) : 0; 12 | const scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 13 | 14 | const offset = { 15 | top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 16 | left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 17 | width, 18 | height, 19 | }; 20 | 21 | return getClientRect(offset); 22 | } 23 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/inner.js: -------------------------------------------------------------------------------- 1 | import getClientRect from '../utils/getClientRect'; 2 | import getOppositePlacement from '../utils/getOppositePlacement'; 3 | 4 | /** 5 | * @function 6 | * @memberof Modifiers 7 | * @argument {Object} data - The data object generated by `update` method 8 | * @argument {Object} options - Modifiers configuration and options 9 | * @returns {Object} The data object, properly modified 10 | */ 11 | export default function inner(data) { 12 | const placement = data.placement; 13 | const basePlacement = placement.split('-')[0]; 14 | const { popper, reference } = data.offsets; 15 | const isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 16 | 17 | const subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 18 | 19 | popper[isHoriz ? 'left' : 'top'] = 20 | reference[basePlacement] - 21 | (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 22 | 23 | data.placement = getOppositePlacement(placement); 24 | data.offsets.popper = getClientRect(popper); 25 | 26 | return data; 27 | } 28 | -------------------------------------------------------------------------------- /MyTaskListApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyTaskListApp", "MyTaskListApp\MyTaskListApp.csproj", "{8A8EDD4C-DD3E-4786-B328-0D263C3CD3A6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8A8EDD4C-DD3E-4786-B328-0D263C3CD3A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8A8EDD4C-DD3E-4786-B328-0D263C3CD3A6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8A8EDD4C-DD3E-4786-B328-0D263C3CD3A6}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8A8EDD4C-DD3E-4786-B328-0D263C3CD3A6}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getScrollParent.js: -------------------------------------------------------------------------------- 1 | import getStyleComputedProperty from './getStyleComputedProperty'; 2 | import getParentNode from './getParentNode'; 3 | 4 | /** 5 | * Returns the scrolling parent of the given element 6 | * @method 7 | * @memberof Popper.Utils 8 | * @argument {Element} element 9 | * @returns {Element} scroll parent 10 | */ 11 | export default function getScrollParent(element) { 12 | // Return body, `getScroll` will take care to get the correct `scrollTop` from it 13 | if (!element) { 14 | return document.body 15 | } 16 | 17 | switch (element.nodeName) { 18 | case 'HTML': 19 | case 'BODY': 20 | return element.ownerDocument.body 21 | case '#document': 22 | return element.body 23 | } 24 | 25 | // Firefox want us to check `-x` and `-y` variations as well 26 | const { overflow, overflowX, overflowY } = getStyleComputedProperty(element); 27 | if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { 28 | return element; 29 | } 30 | 31 | return getScrollParent(getParentNode(element)); 32 | } 33 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getReferenceOffsets.js: -------------------------------------------------------------------------------- 1 | import findCommonOffsetParent from './findCommonOffsetParent'; 2 | import getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode'; 3 | import getFixedPositionOffsetParent from './getFixedPositionOffsetParent'; 4 | import getReferenceNode from './getReferenceNode'; 5 | 6 | /** 7 | * Get offsets to the reference element 8 | * @method 9 | * @memberof Popper.Utils 10 | * @param {Object} state 11 | * @param {Element} popper - the popper element 12 | * @param {Element} reference - the reference element (the popper will be relative to this) 13 | * @param {Element} fixedPosition - is in fixed position mode 14 | * @returns {Object} An object containing the offsets which will be applied to the popper 15 | */ 16 | export default function getReferenceOffsets(state, popper, reference, fixedPosition = null) { 17 | const commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); 18 | return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 19 | } 20 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Manage/VerifyPhoneNumber.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.VerifyPhoneNumberViewModel 2 | @{ 3 | ViewBag.Title = "Verify Phone Number"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("VerifyPhoneNumber", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 | @Html.Hidden("phoneNumber", @Model.PhoneNumber) 12 |

Enter verification code

13 |
@ViewBag.Status
14 |
15 | @Html.ValidationSummary("", new { @class = "text-danger" }) 16 |
17 | @Html.LabelFor(m => m.Code, new { @class = "col-md-2 control-label" }) 18 |
19 | @Html.TextBoxFor(m => m.Code, new { @class = "form-control" }) 20 |
21 |
22 |
23 |
24 | 25 |
26 |
27 | } 28 | 29 | @section Scripts { 30 | @Scripts.Render("~/bundles/jqueryval") 31 | } 32 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/methods/destroy.js: -------------------------------------------------------------------------------- 1 | import isModifierEnabled from '../utils/isModifierEnabled'; 2 | import getSupportedPropertyName from '../utils/getSupportedPropertyName'; 3 | 4 | /** 5 | * Destroys the popper. 6 | * @method 7 | * @memberof Popper 8 | */ 9 | export default function destroy() { 10 | this.state.isDestroyed = true; 11 | 12 | // touch DOM only if `applyStyle` modifier is enabled 13 | if (isModifierEnabled(this.modifiers, 'applyStyle')) { 14 | this.popper.removeAttribute('x-placement'); 15 | this.popper.style.position = ''; 16 | this.popper.style.top = ''; 17 | this.popper.style.left = ''; 18 | this.popper.style.right = ''; 19 | this.popper.style.bottom = ''; 20 | this.popper.style.willChange = ''; 21 | this.popper.style[getSupportedPropertyName('transform')] = ''; 22 | } 23 | 24 | this.disableEventListeners(); 25 | 26 | // remove the popper if user explicitly asked for the deletion on destroy 27 | // do not use `remove` because IE11 doesn't support it 28 | if (this.options.removeOnDestroy) { 29 | this.popper.parentNode.removeChild(this.popper); 30 | } 31 | return this; 32 | } 33 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/shift.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function 3 | * @memberof Modifiers 4 | * @argument {Object} data - The data object generated by `update` method 5 | * @argument {Object} options - Modifiers configuration and options 6 | * @returns {Object} The data object, properly modified 7 | */ 8 | export default function shift(data) { 9 | const placement = data.placement; 10 | const basePlacement = placement.split('-')[0]; 11 | const shiftvariation = placement.split('-')[1]; 12 | 13 | // if shift shiftvariation is specified, run the modifier 14 | if (shiftvariation) { 15 | const { reference, popper } = data.offsets; 16 | const isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 17 | const side = isVertical ? 'left' : 'top'; 18 | const measurement = isVertical ? 'width' : 'height'; 19 | 20 | const shiftOffsets = { 21 | start: { [side]: reference[side] }, 22 | end: { 23 | [side]: reference[side] + reference[measurement] - popper[measurement], 24 | }, 25 | }; 26 | 27 | data.offsets.popper = { ...popper, ...shiftOffsets[shiftvariation] }; 28 | } 29 | 30 | return data; 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/isModifierRequired.js: -------------------------------------------------------------------------------- 1 | import find from './find'; 2 | 3 | /** 4 | * Helper used to know if the given modifier depends from another one.
5 | * It checks if the needed modifier is listed and enabled. 6 | * @method 7 | * @memberof Popper.Utils 8 | * @param {Array} modifiers - list of modifiers 9 | * @param {String} requestingName - name of requesting modifier 10 | * @param {String} requestedName - name of requested modifier 11 | * @returns {Boolean} 12 | */ 13 | export default function isModifierRequired( 14 | modifiers, 15 | requestingName, 16 | requestedName 17 | ) { 18 | const requesting = find(modifiers, ({ name }) => name === requestingName); 19 | 20 | const isRequired = 21 | !!requesting && 22 | modifiers.some(modifier => { 23 | return ( 24 | modifier.name === requestedName && 25 | modifier.enabled && 26 | modifier.order < requesting.order 27 | ); 28 | }); 29 | 30 | if (!isRequired) { 31 | const requesting = `\`${requestingName}\``; 32 | const requested = `\`${requestedName}\``; 33 | console.warn( 34 | `${requested} modifier is required by ${requesting} modifier in order to work, be sure to include it before ${requesting}!` 35 | ); 36 | } 37 | return isRequired; 38 | } 39 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/_ExternalLoginsListPartial.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.ExternalLoginListViewModel 2 | @using Microsoft.Owin.Security 3 | 4 |

Use another service to log in.

5 |
6 | @{ 7 | var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes(); 8 | if (loginProviders.Count() == 0) { 9 |
10 |

11 | There are no external authentication services configured. See this article 12 | for details on setting up this ASP.NET application to support logging in via external services. 13 |

14 |
15 | } 16 | else { 17 | using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = Model.ReturnUrl })) { 18 | @Html.AntiForgeryToken() 19 |
20 |

21 | @foreach (AuthenticationDescription p in loginProviders) { 22 | 23 | } 24 |

25 |
26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/methods/placements.js: -------------------------------------------------------------------------------- 1 | /** 2 | * List of accepted placements to use as values of the `placement` option.
3 | * Valid placements are: 4 | * - `auto` 5 | * - `top` 6 | * - `right` 7 | * - `bottom` 8 | * - `left` 9 | * 10 | * Each placement can have a variation from this list: 11 | * - `-start` 12 | * - `-end` 13 | * 14 | * Variations are interpreted easily if you think of them as the left to right 15 | * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 16 | * is right.
17 | * Vertically (`left` and `right`), `start` is top and `end` is bottom. 18 | * 19 | * Some valid examples are: 20 | * - `top-end` (on top of reference, right aligned) 21 | * - `right-start` (on right of reference, top aligned) 22 | * - `bottom` (on bottom, centered) 23 | * - `auto-end` (on the side with more space available, alignment depends by placement) 24 | * 25 | * @static 26 | * @type {Array} 27 | * @enum {String} 28 | * @readonly 29 | * @method placements 30 | * @memberof Popper 31 | */ 32 | export default [ 33 | 'auto-start', 34 | 'auto', 35 | 'auto-end', 36 | 'top-start', 37 | 'top', 38 | 'top-end', 39 | 'right-start', 40 | 'right', 41 | 'right-end', 42 | 'bottom-end', 43 | 'bottom', 44 | 'bottom-start', 45 | 'left-end', 46 | 'left', 47 | 'left-start', 48 | ]; 49 | -------------------------------------------------------------------------------- /MyTaskListApp/Models/IdentityModels.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using System.Security.Claims; 3 | using System.Threading.Tasks; 4 | using Microsoft.AspNet.Identity; 5 | using Microsoft.AspNet.Identity.EntityFramework; 6 | 7 | namespace MyTaskListApp.Models 8 | { 9 | // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. 10 | public class ApplicationUser : IdentityUser 11 | { 12 | public async Task GenerateUserIdentityAsync(UserManager manager) 13 | { 14 | // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 15 | var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 16 | // Add custom user claims here 17 | return userIdentity; 18 | } 19 | } 20 | 21 | public class ApplicationDbContext : IdentityDbContext 22 | { 23 | public ApplicationDbContext() 24 | : base("DefaultConnection", throwIfV1Schema: false) 25 | { 26 | } 27 | 28 | public static ApplicationDbContext Create() 29 | { 30 | return new ApplicationDbContext(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /MyTaskListApp/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /MyTaskListApp/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace MyTaskListApp 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js", 24 | "~/Scripts/respond.js")); 25 | 26 | bundles.Add(new StyleBundle("~/Content/css").Include( 27 | "~/Content/bootstrap.css", 28 | "~/Content/site.css")); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/debounce.js: -------------------------------------------------------------------------------- 1 | import isBrowser from './isBrowser'; 2 | 3 | const timeoutDuration = (function(){ 4 | const longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 5 | for (let i = 0; i < longerTimeoutBrowsers.length; i += 1) { 6 | if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { 7 | return 1; 8 | } 9 | } 10 | return 0; 11 | }()); 12 | 13 | export function microtaskDebounce(fn) { 14 | let called = false 15 | return () => { 16 | if (called) { 17 | return 18 | } 19 | called = true 20 | window.Promise.resolve().then(() => { 21 | called = false 22 | fn() 23 | }) 24 | } 25 | } 26 | 27 | export function taskDebounce(fn) { 28 | let scheduled = false; 29 | return () => { 30 | if (!scheduled) { 31 | scheduled = true; 32 | setTimeout(() => { 33 | scheduled = false; 34 | fn(); 35 | }, timeoutDuration); 36 | } 37 | }; 38 | } 39 | 40 | const supportsMicroTasks = isBrowser && window.Promise 41 | 42 | 43 | /** 44 | * Create a debounced version of a method, that's asynchronously deferred 45 | * but called in the minimum time possible. 46 | * 47 | * @method 48 | * @memberof Popper.Utils 49 | * @argument {Function} fn 50 | * @returns {Function} 51 | */ 52 | export default (supportsMicroTasks 53 | ? microtaskDebounce 54 | : taskDebounce); 55 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/hide.js: -------------------------------------------------------------------------------- 1 | import isModifierRequired from '../utils/isModifierRequired'; 2 | import find from '../utils/find'; 3 | 4 | /** 5 | * @function 6 | * @memberof Modifiers 7 | * @argument {Object} data - The data object generated by update method 8 | * @argument {Object} options - Modifiers configuration and options 9 | * @returns {Object} The data object, properly modified 10 | */ 11 | export default function hide(data) { 12 | if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 13 | return data; 14 | } 15 | 16 | const refRect = data.offsets.reference; 17 | const bound = find( 18 | data.instance.modifiers, 19 | modifier => modifier.name === 'preventOverflow' 20 | ).boundaries; 21 | 22 | if ( 23 | refRect.bottom < bound.top || 24 | refRect.left > bound.right || 25 | refRect.top > bound.bottom || 26 | refRect.right < bound.left 27 | ) { 28 | // Avoid unnecessary DOM access if visibility hasn't changed 29 | if (data.hide === true) { 30 | return data; 31 | } 32 | 33 | data.hide = true; 34 | data.attributes['x-out-of-boundaries'] = ''; 35 | } else { 36 | // Avoid unnecessary DOM access if visibility hasn't changed 37 | if (data.hide === false) { 38 | return data; 39 | } 40 | 41 | data.hide = false; 42 | data.attributes['x-out-of-boundaries'] = false; 43 | } 44 | 45 | return data; 46 | } 47 | -------------------------------------------------------------------------------- /MyTaskListApp/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/VerifyCode.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.VerifyCodeViewModel 2 | @{ 3 | ViewBag.Title = "Verify"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("VerifyCode", "Account", new { ReturnUrl = Model.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { 9 | @Html.AntiForgeryToken() 10 | @Html.Hidden("provider", @Model.Provider) 11 | @Html.Hidden("rememberMe", @Model.RememberMe) 12 |

Enter verification code

13 |
14 | @Html.ValidationSummary("", new { @class = "text-danger" }) 15 |
16 | @Html.LabelFor(m => m.Code, new { @class = "col-md-2 control-label" }) 17 |
18 | @Html.TextBoxFor(m => m.Code, new { @class = "form-control" }) 19 |
20 |
21 |
22 |
23 |
24 | @Html.CheckBoxFor(m => m.RememberBrowser) 25 | @Html.LabelFor(m => m.RememberBrowser) 26 |
27 |
28 |
29 |
30 |
31 | 32 |
33 |
34 | } 35 | 36 | @section Scripts { 37 | @Scripts.Render("~/bundles/jqueryval") 38 | } 39 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/setupEventListeners.js: -------------------------------------------------------------------------------- 1 | import getScrollParent from './getScrollParent'; 2 | import getWindow from './getWindow'; 3 | 4 | function attachToScrollParents(scrollParent, event, callback, scrollParents) { 5 | const isBody = scrollParent.nodeName === 'BODY'; 6 | const target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 7 | target.addEventListener(event, callback, { passive: true }); 8 | 9 | if (!isBody) { 10 | attachToScrollParents( 11 | getScrollParent(target.parentNode), 12 | event, 13 | callback, 14 | scrollParents 15 | ); 16 | } 17 | scrollParents.push(target); 18 | } 19 | 20 | /** 21 | * Setup needed event listeners used to update the popper position 22 | * @method 23 | * @memberof Popper.Utils 24 | * @private 25 | */ 26 | export default function setupEventListeners( 27 | reference, 28 | options, 29 | state, 30 | updateBound 31 | ) { 32 | // Resize event listener on window 33 | state.updateBound = updateBound; 34 | getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); 35 | 36 | // Scroll event listener on scroll parents 37 | const scrollElement = getScrollParent(reference); 38 | attachToScrollParents( 39 | scrollElement, 40 | 'scroll', 41 | state.updateBound, 42 | state.scrollParents 43 | ); 44 | state.scrollElement = scrollElement; 45 | state.eventsEnabled = true; 46 | 47 | return state; 48 | } 49 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getOffsetParent.js: -------------------------------------------------------------------------------- 1 | import getStyleComputedProperty from './getStyleComputedProperty'; 2 | import isIE from './isIE'; 3 | /** 4 | * Returns the offset parent of the given element 5 | * @method 6 | * @memberof Popper.Utils 7 | * @argument {Element} element 8 | * @returns {Element} offset parent 9 | */ 10 | export default function getOffsetParent(element) { 11 | if (!element) { 12 | return document.documentElement; 13 | } 14 | 15 | const noOffsetParent = isIE(10) ? document.body : null; 16 | 17 | // NOTE: 1 DOM access here 18 | let offsetParent = element.offsetParent || null; 19 | // Skip hidden elements which don't have an offsetParent 20 | while (offsetParent === noOffsetParent && element.nextElementSibling) { 21 | offsetParent = (element = element.nextElementSibling).offsetParent; 22 | } 23 | 24 | const nodeName = offsetParent && offsetParent.nodeName; 25 | 26 | if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { 27 | return element ? element.ownerDocument.documentElement : document.documentElement; 28 | } 29 | 30 | // .offsetParent will return the closest TH, TD or TABLE in case 31 | // no offsetParent is present, I hate this job... 32 | if ( 33 | ['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && 34 | getStyleComputedProperty(offsetParent, 'position') === 'static' 35 | ) { 36 | return getOffsetParent(offsetParent); 37 | } 38 | 39 | return offsetParent; 40 | } 41 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Manage/SetPassword.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.SetPasswordViewModel 2 | @{ 3 | ViewBag.Title = "Create Password"; 4 | } 5 | 6 |

@ViewBag.Title.

7 |

8 | You do not have a local username/password for this site. Add a local 9 | account so you can log in without an external login. 10 |

11 | 12 | @using (Html.BeginForm("SetPassword", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 13 | { 14 | @Html.AntiForgeryToken() 15 | 16 |

Create Local Login

17 |
18 | @Html.ValidationSummary("", new { @class = "text-danger" }) 19 |
20 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 21 |
22 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 23 |
24 |
25 |
26 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 27 |
28 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 29 |
30 |
31 |
32 |
33 | 34 |
35 |
36 | } 37 | @section Scripts { 38 | @Scripts.Render("~/bundles/jqueryval") 39 | } -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ExternalLoginConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.ExternalLoginConfirmationViewModel 2 | @{ 3 | ViewBag.Title = "Register"; 4 | } 5 |

@ViewBag.Title.

6 |

Associate your @ViewBag.LoginProvider account.

7 | 8 | @using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 | 12 |

Association Form

13 |
14 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 15 |

16 | You've successfully authenticated with @ViewBag.LoginProvider. 17 | Please enter a user name for this site below and click the Register button to finish 18 | logging in. 19 |

20 |
21 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 22 |
23 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 24 | @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) 25 |
26 |
27 |
28 |
29 | 30 |
31 |
32 | } 33 | 34 | @section Scripts { 35 | @Scripts.Render("~/bundles/jqueryval") 36 | } 37 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/runModifiers.js: -------------------------------------------------------------------------------- 1 | import isFunction from './isFunction'; 2 | import findIndex from './findIndex'; 3 | import getClientRect from '../utils/getClientRect'; 4 | 5 | /** 6 | * Loop trough the list of modifiers and run them in order, 7 | * each of them will then edit the data object. 8 | * @method 9 | * @memberof Popper.Utils 10 | * @param {dataObject} data 11 | * @param {Array} modifiers 12 | * @param {String} ends - Optional modifier name used as stopper 13 | * @returns {dataObject} 14 | */ 15 | export default function runModifiers(modifiers, data, ends) { 16 | const modifiersToRun = ends === undefined 17 | ? modifiers 18 | : modifiers.slice(0, findIndex(modifiers, 'name', ends)); 19 | 20 | modifiersToRun.forEach(modifier => { 21 | if (modifier['function']) { // eslint-disable-line dot-notation 22 | console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 23 | } 24 | const fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 25 | if (modifier.enabled && isFunction(fn)) { 26 | // Add properties to offsets to make them a complete clientRect object 27 | // we do this before each modifier to make sure the previous one doesn't 28 | // mess with these values 29 | data.offsets.popper = getClientRect(data.offsets.popper); 30 | data.offsets.reference = getClientRect(data.offsets.reference); 31 | 32 | data = fn(data, modifier); 33 | } 34 | }); 35 | 36 | return data; 37 | } 38 | -------------------------------------------------------------------------------- /MyTaskListApp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MyTaskListApp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MyTaskListApp")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f070c0f9-64c4-4b10-8f4f-744b2080a218")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Home/Create.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.MyTask 2 | 3 | 4 | 5 | 6 | 7 | @using (Html.BeginForm("Create", "Home")) 8 | { 9 | @Html.ValidationSummary(true) 10 |
11 | New Task 12 | 13 |
14 | @Html.LabelFor(model => model.Name) 15 |
16 |
17 | @Html.EditorFor(model => model.Name) 18 | @Html.ValidationMessageFor(model => model.Name) 19 |
20 | 21 |
22 | @Html.LabelFor(model => model.Category) 23 |
24 |
25 | @Html.EditorFor(model => model.Category) 26 | @Html.ValidationMessageFor(model => model.Category) 27 |
28 | 29 |
30 | @Html.LabelFor(model => model.Date) 31 |
32 |
33 | @Html.EditorFor(model => model.Date) 34 | @Html.ValidationMessageFor(model => model.Date) 35 |
36 | 37 |

38 | 39 |

40 |
41 | } -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.RegisterViewModel 2 | @{ 3 | ViewBag.Title = "Register"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

Create a new account.

12 |
13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
15 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 16 |
17 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 18 |
19 |
20 |
21 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 22 |
23 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 24 |
25 |
26 |
27 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 28 |
29 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 30 |
31 |
32 |
33 |
34 | 35 |
36 |
37 | } 38 | 39 | @section Scripts { 40 | @Scripts.Render("~/bundles/jqueryval") 41 | } 42 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Manage/ChangePassword.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.ChangePasswordViewModel 2 | @{ 3 | ViewBag.Title = "Change Password"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("ChangePassword", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

Change Password Form

12 |
13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
15 | @Html.LabelFor(m => m.OldPassword, new { @class = "col-md-2 control-label" }) 16 |
17 | @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" }) 18 |
19 |
20 |
21 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 22 |
23 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 24 |
25 |
26 |
27 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 28 |
29 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 30 |
31 |
32 |
33 |
34 | 35 |
36 |
37 | } 38 | @section Scripts { 39 | @Scripts.Render("~/bundles/jqueryval") 40 | } -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/ResetPassword.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.ResetPasswordViewModel 2 | @{ 3 | ViewBag.Title = "Reset password"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 | @using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

Reset your password.

12 |
13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 | @Html.HiddenFor(model => model.Code) 15 |
16 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 17 |
18 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 19 |
20 |
21 |
22 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 23 |
24 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 25 |
26 |
27 |
28 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 29 |
30 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 31 |
32 |
33 |
34 |
35 | 36 |
37 |
38 | } 39 | 40 | @section Scripts { 41 | @Scripts.Render("~/bundles/jqueryval") 42 | } 43 | -------------------------------------------------------------------------------- /MyTaskListApp/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using MyTaskListApp.Models; 7 | using System.Configuration; 8 | 9 | namespace MyTaskListApp.Controllers 10 | { 11 | public class HomeController : Controller, IDisposable 12 | { 13 | private Dal dal = new Dal(); 14 | private bool disposed = false; 15 | // 16 | // GET: /MyTask/ 17 | 18 | public ActionResult Index() 19 | { 20 | return View(dal.GetAllTasks()); 21 | } 22 | 23 | // 24 | // GET: /MyTask/Create 25 | 26 | public ActionResult Create() 27 | { 28 | return View(); 29 | } 30 | 31 | // 32 | // POST: /MyTask/Create 33 | 34 | [HttpPost] 35 | public ActionResult Create(MyTask task) 36 | { 37 | try 38 | { 39 | dal.CreateTask(task); 40 | return RedirectToAction("Index"); 41 | } 42 | catch 43 | { 44 | return View(); 45 | } 46 | } 47 | 48 | public ActionResult About() 49 | { 50 | return View(); 51 | } 52 | 53 | # region IDisposable 54 | 55 | new protected void Dispose() 56 | { 57 | this.Dispose(true); 58 | GC.SuppressFinalize(this); 59 | } 60 | 61 | new protected virtual void Dispose(bool disposing) 62 | { 63 | if (!this.disposed) 64 | { 65 | if (disposing) 66 | { 67 | this.dal.Dispose(); 68 | } 69 | } 70 | 71 | this.disposed = true; 72 | } 73 | 74 | # endregion 75 | 76 | } 77 | } -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getPopperOffsets.js: -------------------------------------------------------------------------------- 1 | import getOuterSizes from './getOuterSizes'; 2 | import getOppositePlacement from './getOppositePlacement'; 3 | 4 | /** 5 | * Get offsets to the popper 6 | * @method 7 | * @memberof Popper.Utils 8 | * @param {Object} position - CSS position the Popper will get applied 9 | * @param {HTMLElement} popper - the popper element 10 | * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 11 | * @param {String} placement - one of the valid placement options 12 | * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 13 | */ 14 | export default function getPopperOffsets(popper, referenceOffsets, placement) { 15 | placement = placement.split('-')[0]; 16 | 17 | // Get popper node sizes 18 | const popperRect = getOuterSizes(popper); 19 | 20 | // Add position, width and height to our offsets object 21 | const popperOffsets = { 22 | width: popperRect.width, 23 | height: popperRect.height, 24 | }; 25 | 26 | // depending by the popper placement we have to compute its offsets slightly differently 27 | const isHoriz = ['right', 'left'].indexOf(placement) !== -1; 28 | const mainSide = isHoriz ? 'top' : 'left'; 29 | const secondarySide = isHoriz ? 'left' : 'top'; 30 | const measurement = isHoriz ? 'height' : 'width'; 31 | const secondaryMeasurement = !isHoriz ? 'height' : 'width'; 32 | 33 | popperOffsets[mainSide] = 34 | referenceOffsets[mainSide] + 35 | referenceOffsets[measurement] / 2 - 36 | popperRect[measurement] / 2; 37 | if (placement === secondarySide) { 38 | popperOffsets[secondarySide] = 39 | referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 40 | } else { 41 | popperOffsets[secondarySide] = 42 | referenceOffsets[getOppositePlacement(secondarySide)]; 43 | } 44 | 45 | return popperOffsets; 46 | } 47 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/findCommonOffsetParent.js: -------------------------------------------------------------------------------- 1 | import isOffsetContainer from './isOffsetContainer'; 2 | import getRoot from './getRoot'; 3 | import getOffsetParent from './getOffsetParent'; 4 | 5 | /** 6 | * Finds the offset parent common to the two provided nodes 7 | * @method 8 | * @memberof Popper.Utils 9 | * @argument {Element} element1 10 | * @argument {Element} element2 11 | * @returns {Element} common offset parent 12 | */ 13 | export default function findCommonOffsetParent(element1, element2) { 14 | // This check is needed to avoid errors in case one of the elements isn't defined for any reason 15 | if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 16 | return document.documentElement; 17 | } 18 | 19 | // Here we make sure to give as "start" the element that comes first in the DOM 20 | const order = 21 | element1.compareDocumentPosition(element2) & 22 | Node.DOCUMENT_POSITION_FOLLOWING; 23 | const start = order ? element1 : element2; 24 | const end = order ? element2 : element1; 25 | 26 | // Get common ancestor container 27 | const range = document.createRange(); 28 | range.setStart(start, 0); 29 | range.setEnd(end, 0); 30 | const { commonAncestorContainer } = range; 31 | 32 | // Both nodes are inside #document 33 | if ( 34 | (element1 !== commonAncestorContainer && 35 | element2 !== commonAncestorContainer) || 36 | start.contains(end) 37 | ) { 38 | if (isOffsetContainer(commonAncestorContainer)) { 39 | return commonAncestorContainer; 40 | } 41 | 42 | return getOffsetParent(commonAncestorContainer); 43 | } 44 | 45 | // one of the nodes is inside shadowDOM, find which one 46 | const element1root = getRoot(element1); 47 | if (element1root.host) { 48 | return findCommonOffsetParent(element1root.host, element2); 49 | } else { 50 | return findCommonOffsetParent(element1, getRoot(element2).host); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getRoundedOffsets.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function 3 | * @memberof Popper.Utils 4 | * @argument {Object} data - The data object generated by `update` method 5 | * @argument {Boolean} shouldRound - If the offsets should be rounded at all 6 | * @returns {Object} The popper's position offsets rounded 7 | * 8 | * The tale of pixel-perfect positioning. It's still not 100% perfect, but as 9 | * good as it can be within reason. 10 | * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 11 | * 12 | * Low DPI screens cause a popper to be blurry if not using full pixels (Safari 13 | * as well on High DPI screens). 14 | * 15 | * Firefox prefers no rounding for positioning and does not have blurriness on 16 | * high DPI screens. 17 | * 18 | * Only horizontal placement and left/right values need to be considered. 19 | */ 20 | export default function getRoundedOffsets(data, shouldRound) { 21 | const { popper, reference } = data.offsets; 22 | const { round, floor } = Math; 23 | const noRound = v => v; 24 | 25 | const referenceWidth = round(reference.width); 26 | const popperWidth = round(popper.width); 27 | 28 | const isVertical = ['left', 'right'].indexOf(data.placement) !== -1; 29 | const isVariation = data.placement.indexOf('-') !== -1; 30 | const sameWidthParity = referenceWidth % 2 === popperWidth % 2; 31 | const bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; 32 | 33 | const horizontalToInteger = !shouldRound 34 | ? noRound 35 | : isVertical || isVariation || sameWidthParity 36 | ? round 37 | : floor; 38 | const verticalToInteger = !shouldRound ? noRound : round; 39 | 40 | return { 41 | left: horizontalToInteger( 42 | bothOddWidth && !isVariation && shouldRound 43 | ? popper.left - 1 44 | : popper.left 45 | ), 46 | top: verticalToInteger(popper.top), 47 | bottom: verticalToInteger(popper.bottom), 48 | right: horizontalToInteger(popper.right), 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/computeAutoPlacement.js: -------------------------------------------------------------------------------- 1 | import getBoundaries from '../utils/getBoundaries'; 2 | 3 | function getArea({ width, height }) { 4 | return width * height; 5 | } 6 | 7 | /** 8 | * Utility used to transform the `auto` placement to the placement with more 9 | * available space. 10 | * @method 11 | * @memberof Popper.Utils 12 | * @argument {Object} data - The data object generated by update method 13 | * @argument {Object} options - Modifiers configuration and options 14 | * @returns {Object} The data object, properly modified 15 | */ 16 | export default function computeAutoPlacement( 17 | placement, 18 | refRect, 19 | popper, 20 | reference, 21 | boundariesElement, 22 | padding = 0 23 | ) { 24 | if (placement.indexOf('auto') === -1) { 25 | return placement; 26 | } 27 | 28 | const boundaries = getBoundaries( 29 | popper, 30 | reference, 31 | padding, 32 | boundariesElement 33 | ); 34 | 35 | const rects = { 36 | top: { 37 | width: boundaries.width, 38 | height: refRect.top - boundaries.top, 39 | }, 40 | right: { 41 | width: boundaries.right - refRect.right, 42 | height: boundaries.height, 43 | }, 44 | bottom: { 45 | width: boundaries.width, 46 | height: boundaries.bottom - refRect.bottom, 47 | }, 48 | left: { 49 | width: refRect.left - boundaries.left, 50 | height: boundaries.height, 51 | }, 52 | }; 53 | 54 | const sortedAreas = Object.keys(rects) 55 | .map(key => ({ 56 | key, 57 | ...rects[key], 58 | area: getArea(rects[key]), 59 | })) 60 | .sort((a, b) => b.area - a.area); 61 | 62 | const filteredAreas = sortedAreas.filter( 63 | ({ width, height }) => 64 | width >= popper.clientWidth && height >= popper.clientHeight 65 | ); 66 | 67 | const computedPlacement = filteredAreas.length > 0 68 | ? filteredAreas[0].key 69 | : sortedAreas[0].key; 70 | 71 | const variation = placement.split('-')[1]; 72 | 73 | return computedPlacement + (variation ? `-${variation}` : ''); 74 | } 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | languages: 3 | - csharp 4 | page_type: sample 5 | products: 6 | - dotnet 7 | - azure 8 | - azure-cosmos-db 9 | description: "How to use the Azure Cosmos DB for MongoDB API to store and access data from a .NET application." 10 | --- 11 | 12 | # Developing a .NET app using Azure Cosmos DB for MongoDB API 13 | Azure Cosmos DB is a fully managed globally distributed, multi-model database service, transparently replicating your data across any number of Azure regions. You can elastically scale throughput and storage, and take advantage of fast, single-digit-millisecond data access using the API of your choice backed by 99.999 SLA. This sample shows you how to use the Azure Cosmos DB for MongoDB API to store and access data from a .NET application. 14 | 15 | ## Running this sample 16 | 17 | * Before you can run this sample, you must have the following prerequisites: 18 | 19 | * An active Azure account. If you don't have one, you can sign up for a [free account](https://azure.microsoft.com/free/). Alternatively, you can use the [Azure Cosmos DB Emulator](https://azure.microsoft.com/documentation/articles/documentdb-nosql-local-emulator) for this tutorial. 20 | * Visual Studio 2017 (download and use the free [Visual Studio 2017 Community Edition](https://www.visualstudio.com/downloads/)) 21 | 22 | * Then, clone this repository using `git clone git@github.com:azure-samples/azure-cosmosdb-for-mongodb-api-dotnet-getting-started.git`. 23 | 24 | * Next, substitute the `username`, `host`, and `password` in *DAL / Dal.cs* with your Cosmos DB account's values. 25 | 26 | * Install the *MongoDB.Driver* library from Visual Studio's Nuget Manager. 27 | 28 | * Click *CTRL + F5* to run your application. 29 | 30 | ## About the code 31 | The code included in this sample is intended to get you quickly started with a .NET application that connects to Azure Cosmos DB for MongoDB API. 32 | 33 | ## More information 34 | 35 | - [Azure Cosmos DB](https://docs.microsoft.com/azure/cosmos-db/introduction) 36 | - [Azure Cosmos DB for MongoDB API](https://docs.microsoft.com/en-us/azure/cosmos-db/mongodb-introduction) 37 | - [MongoDB .NET driver documentation](http://mongodb.github.io/mongo-csharp-driver/) 38 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/methods/defaults.js: -------------------------------------------------------------------------------- 1 | import modifiers from '../modifiers/index'; 2 | 3 | /** 4 | * Default options provided to Popper.js constructor.
5 | * These can be overridden using the `options` argument of Popper.js.
6 | * To override an option, simply pass an object with the same 7 | * structure of the `options` object, as the 3rd argument. For example: 8 | * ``` 9 | * new Popper(ref, pop, { 10 | * modifiers: { 11 | * preventOverflow: { enabled: false } 12 | * } 13 | * }) 14 | * ``` 15 | * @type {Object} 16 | * @static 17 | * @memberof Popper 18 | */ 19 | export default { 20 | /** 21 | * Popper's placement. 22 | * @prop {Popper.placements} placement='bottom' 23 | */ 24 | placement: 'bottom', 25 | 26 | /** 27 | * Set this to true if you want popper to position it self in 'fixed' mode 28 | * @prop {Boolean} positionFixed=false 29 | */ 30 | positionFixed: false, 31 | 32 | /** 33 | * Whether events (resize, scroll) are initially enabled. 34 | * @prop {Boolean} eventsEnabled=true 35 | */ 36 | eventsEnabled: true, 37 | 38 | /** 39 | * Set to true if you want to automatically remove the popper when 40 | * you call the `destroy` method. 41 | * @prop {Boolean} removeOnDestroy=false 42 | */ 43 | removeOnDestroy: false, 44 | 45 | /** 46 | * Callback called when the popper is created.
47 | * By default, it is set to no-op.
48 | * Access Popper.js instance with `data.instance`. 49 | * @prop {onCreate} 50 | */ 51 | onCreate: () => {}, 52 | 53 | /** 54 | * Callback called when the popper is updated. This callback is not called 55 | * on the initialization/creation of the popper, but only on subsequent 56 | * updates.
57 | * By default, it is set to no-op.
58 | * Access Popper.js instance with `data.instance`. 59 | * @prop {onUpdate} 60 | */ 61 | onUpdate: () => {}, 62 | 63 | /** 64 | * List of modifiers used to modify the offsets before they are applied to the popper. 65 | * They provide most of the functionalities of Popper.js. 66 | * @prop {modifiers} 67 | */ 68 | modifiers, 69 | }; 70 | 71 | /** 72 | * @callback onCreate 73 | * @param {dataObject} data 74 | */ 75 | 76 | /** 77 | * @callback onUpdate 78 | * @param {dataObject} data 79 | */ 80 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getBoundingClientRect.js: -------------------------------------------------------------------------------- 1 | import getStyleComputedProperty from './getStyleComputedProperty'; 2 | import getBordersSize from './getBordersSize'; 3 | import getWindowSizes from './getWindowSizes'; 4 | import getScroll from './getScroll'; 5 | import getClientRect from './getClientRect'; 6 | import isIE from './isIE'; 7 | 8 | /** 9 | * Get bounding client rect of given element 10 | * @method 11 | * @memberof Popper.Utils 12 | * @param {HTMLElement} element 13 | * @return {Object} client rect 14 | */ 15 | export default function getBoundingClientRect(element) { 16 | let rect = {}; 17 | 18 | // IE10 10 FIX: Please, don't ask, the element isn't 19 | // considered in DOM in some circumstances... 20 | // This isn't reproducible in IE10 compatibility mode of IE11 21 | try { 22 | if (isIE(10)) { 23 | rect = element.getBoundingClientRect(); 24 | const scrollTop = getScroll(element, 'top'); 25 | const scrollLeft = getScroll(element, 'left'); 26 | rect.top += scrollTop; 27 | rect.left += scrollLeft; 28 | rect.bottom += scrollTop; 29 | rect.right += scrollLeft; 30 | } 31 | else { 32 | rect = element.getBoundingClientRect(); 33 | } 34 | } 35 | catch(e){} 36 | 37 | const result = { 38 | left: rect.left, 39 | top: rect.top, 40 | width: rect.right - rect.left, 41 | height: rect.bottom - rect.top, 42 | }; 43 | 44 | // subtract scrollbar size from sizes 45 | const sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; 46 | const width = 47 | sizes.width || element.clientWidth || result.width; 48 | const height = 49 | sizes.height || element.clientHeight || result.height; 50 | 51 | let horizScrollbar = element.offsetWidth - width; 52 | let vertScrollbar = element.offsetHeight - height; 53 | 54 | // if an hypothetical scrollbar is detected, we must be sure it's not a `border` 55 | // we make this check conditional for performance reasons 56 | if (horizScrollbar || vertScrollbar) { 57 | const styles = getStyleComputedProperty(element); 58 | horizScrollbar -= getBordersSize(styles, 'x'); 59 | vertScrollbar -= getBordersSize(styles, 'y'); 60 | 61 | result.width -= horizScrollbar; 62 | result.height -= vertScrollbar; 63 | } 64 | 65 | return getClientRect(result); 66 | } 67 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/methods/update.js: -------------------------------------------------------------------------------- 1 | import computeAutoPlacement from '../utils/computeAutoPlacement'; 2 | import getReferenceOffsets from '../utils/getReferenceOffsets'; 3 | import getPopperOffsets from '../utils/getPopperOffsets'; 4 | import runModifiers from '../utils/runModifiers'; 5 | 6 | /** 7 | * Updates the position of the popper, computing the new offsets and applying 8 | * the new style.
9 | * Prefer `scheduleUpdate` over `update` because of performance reasons. 10 | * @method 11 | * @memberof Popper 12 | */ 13 | export default function update() { 14 | // if popper is destroyed, don't perform any further update 15 | if (this.state.isDestroyed) { 16 | return; 17 | } 18 | 19 | let data = { 20 | instance: this, 21 | styles: {}, 22 | arrowStyles: {}, 23 | attributes: {}, 24 | flipped: false, 25 | offsets: {}, 26 | }; 27 | 28 | // compute reference element offsets 29 | data.offsets.reference = getReferenceOffsets( 30 | this.state, 31 | this.popper, 32 | this.reference, 33 | this.options.positionFixed 34 | ); 35 | 36 | // compute auto placement, store placement inside the data object, 37 | // modifiers will be able to edit `placement` if needed 38 | // and refer to originalPlacement to know the original value 39 | data.placement = computeAutoPlacement( 40 | this.options.placement, 41 | data.offsets.reference, 42 | this.popper, 43 | this.reference, 44 | this.options.modifiers.flip.boundariesElement, 45 | this.options.modifiers.flip.padding 46 | ); 47 | 48 | // store the computed placement inside `originalPlacement` 49 | data.originalPlacement = data.placement; 50 | 51 | data.positionFixed = this.options.positionFixed; 52 | 53 | // compute the popper offsets 54 | data.offsets.popper = getPopperOffsets( 55 | this.popper, 56 | data.offsets.reference, 57 | data.placement 58 | ); 59 | 60 | data.offsets.popper.position = this.options.positionFixed 61 | ? 'fixed' 62 | : 'absolute'; 63 | 64 | // run the modifiers 65 | data = runModifiers(this.modifiers, data); 66 | 67 | // the first `update` will call `onCreate` callback 68 | // the other ones will call `onUpdate` callback 69 | if (!this.state.isCreated) { 70 | this.state.isCreated = true; 71 | this.options.onCreate(data); 72 | } else { 73 | this.options.onUpdate(data); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getOffsetRectRelativeToArbitraryNode.js: -------------------------------------------------------------------------------- 1 | import getStyleComputedProperty from './getStyleComputedProperty'; 2 | import includeScroll from './includeScroll'; 3 | import getScrollParent from './getScrollParent'; 4 | import getBoundingClientRect from './getBoundingClientRect'; 5 | import runIsIE from './isIE'; 6 | import getClientRect from './getClientRect'; 7 | 8 | export default function getOffsetRectRelativeToArbitraryNode(children, parent, fixedPosition = false) { 9 | const isIE10 = runIsIE(10); 10 | const isHTML = parent.nodeName === 'HTML'; 11 | const childrenRect = getBoundingClientRect(children); 12 | const parentRect = getBoundingClientRect(parent); 13 | const scrollParent = getScrollParent(children); 14 | 15 | const styles = getStyleComputedProperty(parent); 16 | const borderTopWidth = parseFloat(styles.borderTopWidth); 17 | const borderLeftWidth = parseFloat(styles.borderLeftWidth); 18 | 19 | // In cases where the parent is fixed, we must ignore negative scroll in offset calc 20 | if(fixedPosition && isHTML) { 21 | parentRect.top = Math.max(parentRect.top, 0); 22 | parentRect.left = Math.max(parentRect.left, 0); 23 | } 24 | let offsets = getClientRect({ 25 | top: childrenRect.top - parentRect.top - borderTopWidth, 26 | left: childrenRect.left - parentRect.left - borderLeftWidth, 27 | width: childrenRect.width, 28 | height: childrenRect.height, 29 | }); 30 | offsets.marginTop = 0; 31 | offsets.marginLeft = 0; 32 | 33 | // Subtract margins of documentElement in case it's being used as parent 34 | // we do this only on HTML because it's the only element that behaves 35 | // differently when margins are applied to it. The margins are included in 36 | // the box of the documentElement, in the other cases not. 37 | if (!isIE10 && isHTML) { 38 | const marginTop = parseFloat(styles.marginTop); 39 | const marginLeft = parseFloat(styles.marginLeft); 40 | 41 | offsets.top -= borderTopWidth - marginTop; 42 | offsets.bottom -= borderTopWidth - marginTop; 43 | offsets.left -= borderLeftWidth - marginLeft; 44 | offsets.right -= borderLeftWidth - marginLeft; 45 | 46 | // Attach marginTop and marginLeft because in some circumstances we may need them 47 | offsets.marginTop = marginTop; 48 | offsets.marginLeft = marginLeft; 49 | } 50 | 51 | if ( 52 | isIE10 && !fixedPosition 53 | ? parent.contains(scrollParent) 54 | : parent === scrollParent && scrollParent.nodeName !== 'BODY' 55 | ) { 56 | offsets = includeScroll(offsets, parent); 57 | } 58 | 59 | return offsets; 60 | } 61 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 20 | 21 | 22 | 42 |
43 | @RenderBody() 44 |
45 |
46 |

© @DateTime.Now.Year - My ASP.NET Application

47 |
48 |
49 | 50 | @Scripts.Render("~/bundles/jquery") 51 | @Scripts.Render("~/bundles/bootstrap") 52 | @RenderSection("scripts", required: false) 53 | 54 | 55 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Account/Login.cshtml: -------------------------------------------------------------------------------- 1 | @using MyTaskListApp.Models 2 | @model LoginViewModel 3 | @{ 4 | ViewBag.Title = "Log in"; 5 | } 6 | 7 |

@ViewBag.Title.

8 |
9 |
10 |
11 | @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 12 | { 13 | @Html.AntiForgeryToken() 14 |

Use a local account to log in.

15 |
16 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 17 |
18 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 19 |
20 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 21 | @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) 22 |
23 |
24 |
25 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 26 |
27 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 28 | @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) 29 |
30 |
31 |
32 |
33 |
34 | @Html.CheckBoxFor(m => m.RememberMe) 35 | @Html.LabelFor(m => m.RememberMe) 36 |
37 |
38 |
39 |
40 |
41 | 42 |
43 |
44 |

45 | @Html.ActionLink("Register as a new user", "Register") 46 |

47 | @* Enable this once you have account confirmation enabled for password reset functionality 48 |

49 | @Html.ActionLink("Forgot your password?", "ForgotPassword") 50 |

*@ 51 | } 52 |
53 |
54 |
55 |
56 | @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) 57 |
58 |
59 |
60 | 61 | @section Scripts { 62 | @Scripts.Render("~/bundles/jqueryval") 63 | } -------------------------------------------------------------------------------- /MyTaskListApp/Models/ManageViewModels.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | using Microsoft.AspNet.Identity; 4 | using Microsoft.Owin.Security; 5 | 6 | namespace MyTaskListApp.Models 7 | { 8 | public class IndexViewModel 9 | { 10 | public bool HasPassword { get; set; } 11 | public IList Logins { get; set; } 12 | public string PhoneNumber { get; set; } 13 | public bool TwoFactor { get; set; } 14 | public bool BrowserRemembered { get; set; } 15 | } 16 | 17 | public class ManageLoginsViewModel 18 | { 19 | public IList CurrentLogins { get; set; } 20 | public IList OtherLogins { get; set; } 21 | } 22 | 23 | public class FactorViewModel 24 | { 25 | public string Purpose { get; set; } 26 | } 27 | 28 | public class SetPasswordViewModel 29 | { 30 | [Required] 31 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 32 | [DataType(DataType.Password)] 33 | [Display(Name = "New password")] 34 | public string NewPassword { get; set; } 35 | 36 | [DataType(DataType.Password)] 37 | [Display(Name = "Confirm new password")] 38 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 39 | public string ConfirmPassword { get; set; } 40 | } 41 | 42 | public class ChangePasswordViewModel 43 | { 44 | [Required] 45 | [DataType(DataType.Password)] 46 | [Display(Name = "Current password")] 47 | public string OldPassword { get; set; } 48 | 49 | [Required] 50 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 51 | [DataType(DataType.Password)] 52 | [Display(Name = "New password")] 53 | public string NewPassword { get; set; } 54 | 55 | [DataType(DataType.Password)] 56 | [Display(Name = "Confirm new password")] 57 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 58 | public string ConfirmPassword { get; set; } 59 | } 60 | 61 | public class AddPhoneNumberViewModel 62 | { 63 | [Required] 64 | [Phone] 65 | [Display(Name = "Phone Number")] 66 | public string Number { get; set; } 67 | } 68 | 69 | public class VerifyPhoneNumberViewModel 70 | { 71 | [Required] 72 | [Display(Name = "Code")] 73 | public string Code { get; set; } 74 | 75 | [Required] 76 | [Phone] 77 | [Display(Name = "Phone Number")] 78 | public string PhoneNumber { get; set; } 79 | } 80 | 81 | public class ConfigureTwoFactorViewModel 82 | { 83 | public string SelectedProvider { get; set; } 84 | public ICollection Providers { get; set; } 85 | } 86 | } -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/applyStyle.js: -------------------------------------------------------------------------------- 1 | import setStyles from '../utils/setStyles'; 2 | import setAttributes from '../utils/setAttributes'; 3 | import getReferenceOffsets from '../utils/getReferenceOffsets'; 4 | import computeAutoPlacement from '../utils/computeAutoPlacement'; 5 | 6 | /** 7 | * @function 8 | * @memberof Modifiers 9 | * @argument {Object} data - The data object generated by `update` method 10 | * @argument {Object} data.styles - List of style properties - values to apply to popper element 11 | * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 12 | * @argument {Object} options - Modifiers configuration and options 13 | * @returns {Object} The same data object 14 | */ 15 | export default function applyStyle(data) { 16 | // any property present in `data.styles` will be applied to the popper, 17 | // in this way we can make the 3rd party modifiers add custom styles to it 18 | // Be aware, modifiers could override the properties defined in the previous 19 | // lines of this modifier! 20 | setStyles(data.instance.popper, data.styles); 21 | 22 | // any property present in `data.attributes` will be applied to the popper, 23 | // they will be set as HTML attributes of the element 24 | setAttributes(data.instance.popper, data.attributes); 25 | 26 | // if arrowElement is defined and arrowStyles has some properties 27 | if (data.arrowElement && Object.keys(data.arrowStyles).length) { 28 | setStyles(data.arrowElement, data.arrowStyles); 29 | } 30 | 31 | return data; 32 | } 33 | 34 | /** 35 | * Set the x-placement attribute before everything else because it could be used 36 | * to add margins to the popper margins needs to be calculated to get the 37 | * correct popper offsets. 38 | * @method 39 | * @memberof Popper.modifiers 40 | * @param {HTMLElement} reference - The reference element used to position the popper 41 | * @param {HTMLElement} popper - The HTML element used as popper 42 | * @param {Object} options - Popper.js options 43 | */ 44 | export function applyStyleOnLoad( 45 | reference, 46 | popper, 47 | options, 48 | modifierOptions, 49 | state 50 | ) { 51 | // compute reference element offsets 52 | const referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); 53 | 54 | // compute auto placement, store placement inside the data object, 55 | // modifiers will be able to edit `placement` if needed 56 | // and refer to originalPlacement to know the original value 57 | const placement = computeAutoPlacement( 58 | options.placement, 59 | referenceOffsets, 60 | popper, 61 | reference, 62 | options.modifiers.flip.boundariesElement, 63 | options.modifiers.flip.padding 64 | ); 65 | 66 | popper.setAttribute('x-placement', placement); 67 | 68 | // Apply `position` to popper before anything else because 69 | // without the position applied we can't guarantee correct computations 70 | setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); 71 | 72 | return options; 73 | } 74 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Manage/ManageLogins.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.ManageLoginsViewModel 2 | @using Microsoft.Owin.Security 3 | @{ 4 | ViewBag.Title = "Manage your external logins"; 5 | } 6 | 7 |

@ViewBag.Title.

8 | 9 |

@ViewBag.StatusMessage

10 | @{ 11 | var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes(); 12 | if (loginProviders.Count() == 0) { 13 |
14 |

15 | There are no external authentication services configured. See this article 16 | for details on setting up this ASP.NET application to support logging in via external services. 17 |

18 |
19 | } 20 | else 21 | { 22 | if (Model.CurrentLogins.Count > 0) 23 | { 24 |

Registered Logins

25 | 26 | 27 | @foreach (var account in Model.CurrentLogins) 28 | { 29 | 30 | 31 | 49 | 50 | } 51 | 52 |
@account.LoginProvider 32 | @if (ViewBag.ShowRemoveButton) 33 | { 34 | using (Html.BeginForm("RemoveLogin", "Manage")) 35 | { 36 | @Html.AntiForgeryToken() 37 |
38 | @Html.Hidden("loginProvider", account.LoginProvider) 39 | @Html.Hidden("providerKey", account.ProviderKey) 40 | 41 |
42 | } 43 | } 44 | else 45 | { 46 | @:   47 | } 48 |
53 | } 54 | if (Model.OtherLogins.Count > 0) 55 | { 56 | using (Html.BeginForm("LinkLogin", "Manage")) 57 | { 58 | @Html.AntiForgeryToken() 59 |
60 |

61 | @foreach (AuthenticationDescription p in Model.OtherLogins) 62 | { 63 | 64 | } 65 |

66 |
67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/preventOverflow.js: -------------------------------------------------------------------------------- 1 | import getOffsetParent from '../utils/getOffsetParent'; 2 | import getBoundaries from '../utils/getBoundaries'; 3 | import getSupportedPropertyName from '../utils/getSupportedPropertyName'; 4 | 5 | /** 6 | * @function 7 | * @memberof Modifiers 8 | * @argument {Object} data - The data object generated by `update` method 9 | * @argument {Object} options - Modifiers configuration and options 10 | * @returns {Object} The data object, properly modified 11 | */ 12 | export default function preventOverflow(data, options) { 13 | let boundariesElement = 14 | options.boundariesElement || getOffsetParent(data.instance.popper); 15 | 16 | // If offsetParent is the reference element, we really want to 17 | // go one step up and use the next offsetParent as reference to 18 | // avoid to make this modifier completely useless and look like broken 19 | if (data.instance.reference === boundariesElement) { 20 | boundariesElement = getOffsetParent(boundariesElement); 21 | } 22 | 23 | // NOTE: DOM access here 24 | // resets the popper's position so that the document size can be calculated excluding 25 | // the size of the popper element itself 26 | const transformProp = getSupportedPropertyName('transform'); 27 | const popperStyles = data.instance.popper.style; // assignment to help minification 28 | const { top, left, [transformProp]: transform } = popperStyles; 29 | popperStyles.top = ''; 30 | popperStyles.left = ''; 31 | popperStyles[transformProp] = ''; 32 | 33 | const boundaries = getBoundaries( 34 | data.instance.popper, 35 | data.instance.reference, 36 | options.padding, 37 | boundariesElement, 38 | data.positionFixed 39 | ); 40 | 41 | // NOTE: DOM access here 42 | // restores the original style properties after the offsets have been computed 43 | popperStyles.top = top; 44 | popperStyles.left = left; 45 | popperStyles[transformProp] = transform; 46 | 47 | options.boundaries = boundaries; 48 | 49 | const order = options.priority; 50 | let popper = data.offsets.popper; 51 | 52 | const check = { 53 | primary(placement) { 54 | let value = popper[placement]; 55 | if ( 56 | popper[placement] < boundaries[placement] && 57 | !options.escapeWithReference 58 | ) { 59 | value = Math.max(popper[placement], boundaries[placement]); 60 | } 61 | return { [placement]: value }; 62 | }, 63 | secondary(placement) { 64 | const mainSide = placement === 'right' ? 'left' : 'top'; 65 | let value = popper[mainSide]; 66 | if ( 67 | popper[placement] > boundaries[placement] && 68 | !options.escapeWithReference 69 | ) { 70 | value = Math.min( 71 | popper[mainSide], 72 | boundaries[placement] - 73 | (placement === 'right' ? popper.width : popper.height) 74 | ); 75 | } 76 | return { [mainSide]: value }; 77 | }, 78 | }; 79 | 80 | order.forEach(placement => { 81 | const side = 82 | ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 83 | popper = { ...popper, ...check[side](placement) }; 84 | }); 85 | 86 | data.offsets.popper = popper; 87 | 88 | return data; 89 | } 90 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/getBoundaries.js: -------------------------------------------------------------------------------- 1 | import getScrollParent from './getScrollParent'; 2 | import getParentNode from './getParentNode'; 3 | import getReferenceNode from './getReferenceNode'; 4 | import findCommonOffsetParent from './findCommonOffsetParent'; 5 | import getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode'; 6 | import getViewportOffsetRectRelativeToArtbitraryNode from './getViewportOffsetRectRelativeToArtbitraryNode'; 7 | import getWindowSizes from './getWindowSizes'; 8 | import isFixed from './isFixed'; 9 | import getFixedPositionOffsetParent from './getFixedPositionOffsetParent'; 10 | 11 | /** 12 | * Computed the boundaries limits and return them 13 | * @method 14 | * @memberof Popper.Utils 15 | * @param {HTMLElement} popper 16 | * @param {HTMLElement} reference 17 | * @param {number} padding 18 | * @param {HTMLElement} boundariesElement - Element used to define the boundaries 19 | * @param {Boolean} fixedPosition - Is in fixed position mode 20 | * @returns {Object} Coordinates of the boundaries 21 | */ 22 | export default function getBoundaries( 23 | popper, 24 | reference, 25 | padding, 26 | boundariesElement, 27 | fixedPosition = false 28 | ) { 29 | // NOTE: 1 DOM access here 30 | 31 | let boundaries = { top: 0, left: 0 }; 32 | const offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); 33 | 34 | // Handle viewport case 35 | if (boundariesElement === 'viewport' ) { 36 | boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 37 | } 38 | 39 | else { 40 | // Handle other cases based on DOM element used as boundaries 41 | let boundariesNode; 42 | if (boundariesElement === 'scrollParent') { 43 | boundariesNode = getScrollParent(getParentNode(reference)); 44 | if (boundariesNode.nodeName === 'BODY') { 45 | boundariesNode = popper.ownerDocument.documentElement; 46 | } 47 | } else if (boundariesElement === 'window') { 48 | boundariesNode = popper.ownerDocument.documentElement; 49 | } else { 50 | boundariesNode = boundariesElement; 51 | } 52 | 53 | const offsets = getOffsetRectRelativeToArbitraryNode( 54 | boundariesNode, 55 | offsetParent, 56 | fixedPosition 57 | ); 58 | 59 | // In case of HTML, we need a different computation 60 | if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 61 | const { height, width } = getWindowSizes(popper.ownerDocument); 62 | boundaries.top += offsets.top - offsets.marginTop; 63 | boundaries.bottom = height + offsets.top; 64 | boundaries.left += offsets.left - offsets.marginLeft; 65 | boundaries.right = width + offsets.left; 66 | } else { 67 | // for all the other DOM elements, this one is good 68 | boundaries = offsets; 69 | } 70 | } 71 | 72 | // Add paddings 73 | padding = padding || 0; 74 | const isPaddingNumber = typeof padding === 'number'; 75 | boundaries.left += isPaddingNumber ? padding : padding.left || 0; 76 | boundaries.top += isPaddingNumber ? padding : padding.top || 0; 77 | boundaries.right -= isPaddingNumber ? padding : padding.right || 0; 78 | boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; 79 | 80 | return boundaries; 81 | } 82 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/utils/index.js: -------------------------------------------------------------------------------- 1 | import computeAutoPlacement from './computeAutoPlacement'; 2 | import debounce from './debounce'; 3 | import findIndex from './findIndex'; 4 | import getBordersSize from './getBordersSize'; 5 | import getBoundaries from './getBoundaries'; 6 | import getBoundingClientRect from './getBoundingClientRect'; 7 | import getClientRect from './getClientRect'; 8 | import getOffsetParent from './getOffsetParent'; 9 | import getOffsetRect from './getOffsetRect'; 10 | import getOffsetRectRelativeToArbitraryNode from './getOffsetRectRelativeToArbitraryNode'; 11 | import getOuterSizes from './getOuterSizes'; 12 | import getParentNode from './getParentNode'; 13 | import getPopperOffsets from './getPopperOffsets'; 14 | import getReferenceOffsets from './getReferenceOffsets'; 15 | import getScroll from './getScroll'; 16 | import getScrollParent from './getScrollParent'; 17 | import getStyleComputedProperty from './getStyleComputedProperty'; 18 | import getSupportedPropertyName from './getSupportedPropertyName'; 19 | import getWindowSizes from './getWindowSizes'; 20 | import isFixed from './isFixed'; 21 | import isFunction from './isFunction'; 22 | import isModifierEnabled from './isModifierEnabled'; 23 | import isModifierRequired from './isModifierRequired'; 24 | import isNumeric from './isNumeric'; 25 | import removeEventListeners from './removeEventListeners'; 26 | import runModifiers from './runModifiers'; 27 | import setAttributes from './setAttributes'; 28 | import setStyles from './setStyles'; 29 | import setupEventListeners from './setupEventListeners'; 30 | 31 | /** @namespace Popper.Utils */ 32 | export { 33 | computeAutoPlacement, 34 | debounce, 35 | findIndex, 36 | getBordersSize, 37 | getBoundaries, 38 | getBoundingClientRect, 39 | getClientRect, 40 | getOffsetParent, 41 | getOffsetRect, 42 | getOffsetRectRelativeToArbitraryNode, 43 | getOuterSizes, 44 | getParentNode, 45 | getPopperOffsets, 46 | getReferenceOffsets, 47 | getScroll, 48 | getScrollParent, 49 | getStyleComputedProperty, 50 | getSupportedPropertyName, 51 | getWindowSizes, 52 | isFixed, 53 | isFunction, 54 | isModifierEnabled, 55 | isModifierRequired, 56 | isNumeric, 57 | removeEventListeners, 58 | runModifiers, 59 | setAttributes, 60 | setStyles, 61 | setupEventListeners, 62 | }; 63 | 64 | // This is here just for backward compatibility with versions lower than v1.10.3 65 | // you should import the utilities using named exports, if you want them all use: 66 | // ``` 67 | // import * as PopperUtils from 'popper-utils'; 68 | // ``` 69 | // The default export will be removed in the next major version. 70 | export default { 71 | computeAutoPlacement, 72 | debounce, 73 | findIndex, 74 | getBordersSize, 75 | getBoundaries, 76 | getBoundingClientRect, 77 | getClientRect, 78 | getOffsetParent, 79 | getOffsetRect, 80 | getOffsetRectRelativeToArbitraryNode, 81 | getOuterSizes, 82 | getParentNode, 83 | getPopperOffsets, 84 | getReferenceOffsets, 85 | getScroll, 86 | getScrollParent, 87 | getStyleComputedProperty, 88 | getSupportedPropertyName, 89 | getWindowSizes, 90 | isFixed, 91 | isFunction, 92 | isModifierEnabled, 93 | isModifierRequired, 94 | isNumeric, 95 | removeEventListeners, 96 | runModifiers, 97 | setAttributes, 98 | setStyles, 99 | setupEventListeners, 100 | }; 101 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/arrow.js: -------------------------------------------------------------------------------- 1 | import getClientRect from '../utils/getClientRect'; 2 | import getOuterSizes from '../utils/getOuterSizes'; 3 | import isModifierRequired from '../utils/isModifierRequired'; 4 | import getStyleComputedProperty from '../utils/getStyleComputedProperty'; 5 | 6 | /** 7 | * @function 8 | * @memberof Modifiers 9 | * @argument {Object} data - The data object generated by update method 10 | * @argument {Object} options - Modifiers configuration and options 11 | * @returns {Object} The data object, properly modified 12 | */ 13 | export default function arrow(data, options) { 14 | // arrow depends on keepTogether in order to work 15 | if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 16 | return data; 17 | } 18 | 19 | let arrowElement = options.element; 20 | 21 | // if arrowElement is a string, suppose it's a CSS selector 22 | if (typeof arrowElement === 'string') { 23 | arrowElement = data.instance.popper.querySelector(arrowElement); 24 | 25 | // if arrowElement is not found, don't run the modifier 26 | if (!arrowElement) { 27 | return data; 28 | } 29 | } else { 30 | // if the arrowElement isn't a query selector we must check that the 31 | // provided DOM node is child of its popper node 32 | if (!data.instance.popper.contains(arrowElement)) { 33 | console.warn( 34 | 'WARNING: `arrow.element` must be child of its popper element!' 35 | ); 36 | return data; 37 | } 38 | } 39 | 40 | const placement = data.placement.split('-')[0]; 41 | const { popper, reference } = data.offsets; 42 | const isVertical = ['left', 'right'].indexOf(placement) !== -1; 43 | 44 | const len = isVertical ? 'height' : 'width'; 45 | const sideCapitalized = isVertical ? 'Top' : 'Left'; 46 | const side = sideCapitalized.toLowerCase(); 47 | const altSide = isVertical ? 'left' : 'top'; 48 | const opSide = isVertical ? 'bottom' : 'right'; 49 | const arrowElementSize = getOuterSizes(arrowElement)[len]; 50 | 51 | // 52 | // extends keepTogether behavior making sure the popper and its 53 | // reference have enough pixels in conjunction 54 | // 55 | 56 | // top/left side 57 | if (reference[opSide] - arrowElementSize < popper[side]) { 58 | data.offsets.popper[side] -= 59 | popper[side] - (reference[opSide] - arrowElementSize); 60 | } 61 | // bottom/right side 62 | if (reference[side] + arrowElementSize > popper[opSide]) { 63 | data.offsets.popper[side] += 64 | reference[side] + arrowElementSize - popper[opSide]; 65 | } 66 | data.offsets.popper = getClientRect(data.offsets.popper); 67 | 68 | // compute center of the popper 69 | const center = reference[side] + reference[len] / 2 - arrowElementSize / 2; 70 | 71 | // Compute the sideValue using the updated popper offsets 72 | // take popper margin in account because we don't have this info available 73 | const css = getStyleComputedProperty(data.instance.popper); 74 | const popperMarginSide = parseFloat(css[`margin${sideCapitalized}`]); 75 | const popperBorderSide = parseFloat(css[`border${sideCapitalized}Width`]); 76 | let sideValue = 77 | center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; 78 | 79 | // prevent arrowElement from being placed not contiguously to its popper 80 | sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 81 | 82 | data.arrowElement = arrowElement; 83 | data.offsets.arrow = { 84 | [side]: Math.round(sideValue), 85 | [altSide]: '', // make sure to unset any eventual altSide value from the DOM node 86 | }; 87 | 88 | return data; 89 | } 90 | -------------------------------------------------------------------------------- /MyTaskListApp/Views/Manage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model MyTaskListApp.Models.IndexViewModel 2 | @{ 3 | ViewBag.Title = "Manage"; 4 | } 5 | 6 |

@ViewBag.Title.

7 | 8 |

@ViewBag.StatusMessage

9 |
10 |

Change your account settings

11 |
12 |
13 |
Password:
14 |
15 | [ 16 | @if (Model.HasPassword) 17 | { 18 | @Html.ActionLink("Change your password", "ChangePassword") 19 | } 20 | else 21 | { 22 | @Html.ActionLink("Create", "SetPassword") 23 | } 24 | ] 25 |
26 |
External Logins:
27 |
28 | @Model.Logins.Count [ 29 | @Html.ActionLink("Manage", "ManageLogins") ] 30 |
31 | @* 32 | Phone Numbers can used as a second factor of verification in a two-factor authentication system. 33 | 34 | See this article 35 | for details on setting up this ASP.NET application to support two-factor authentication using SMS. 36 | 37 | Uncomment the following block after you have set up two-factor authentication 38 | *@ 39 | @* 40 |
Phone Number:
41 |
42 | @(Model.PhoneNumber ?? "None") 43 | @if (Model.PhoneNumber != null) 44 | { 45 |
46 | [  @Html.ActionLink("Change", "AddPhoneNumber")  ] 47 | using (Html.BeginForm("RemovePhoneNumber", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 48 | { 49 | @Html.AntiForgeryToken() 50 | [] 51 | } 52 | } 53 | else 54 | { 55 | [  @Html.ActionLink("Add", "AddPhoneNumber") 56 | } 57 |
58 | *@ 59 |
Two-Factor Authentication:
60 |
61 |

62 | There are no two-factor authentication providers configured. See this article 63 | for details on setting up this ASP.NET application to support two-factor authentication. 64 |

65 | @*@if (Model.TwoFactor) 66 | { 67 | using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 68 | { 69 | @Html.AntiForgeryToken() 70 | Enabled 71 | 72 | 73 | } 74 | } 75 | else 76 | { 77 | using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 78 | { 79 | @Html.AntiForgeryToken() 80 | Disabled 81 | 82 | 83 | } 84 | }*@ 85 |
86 |
87 |
88 | -------------------------------------------------------------------------------- /MyTaskListApp/Models/AccountViewModels.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace MyTaskListApp.Models 5 | { 6 | public class ExternalLoginConfirmationViewModel 7 | { 8 | [Required] 9 | [Display(Name = "Email")] 10 | public string Email { get; set; } 11 | } 12 | 13 | public class ExternalLoginListViewModel 14 | { 15 | public string ReturnUrl { get; set; } 16 | } 17 | 18 | public class SendCodeViewModel 19 | { 20 | public string SelectedProvider { get; set; } 21 | public ICollection Providers { get; set; } 22 | public string ReturnUrl { get; set; } 23 | public bool RememberMe { get; set; } 24 | } 25 | 26 | public class VerifyCodeViewModel 27 | { 28 | [Required] 29 | public string Provider { get; set; } 30 | 31 | [Required] 32 | [Display(Name = "Code")] 33 | public string Code { get; set; } 34 | public string ReturnUrl { get; set; } 35 | 36 | [Display(Name = "Remember this browser?")] 37 | public bool RememberBrowser { get; set; } 38 | 39 | public bool RememberMe { get; set; } 40 | } 41 | 42 | public class ForgotViewModel 43 | { 44 | [Required] 45 | [Display(Name = "Email")] 46 | public string Email { get; set; } 47 | } 48 | 49 | public class LoginViewModel 50 | { 51 | [Required] 52 | [Display(Name = "Email")] 53 | [EmailAddress] 54 | public string Email { get; set; } 55 | 56 | [Required] 57 | [DataType(DataType.Password)] 58 | [Display(Name = "Password")] 59 | public string Password { get; set; } 60 | 61 | [Display(Name = "Remember me?")] 62 | public bool RememberMe { get; set; } 63 | } 64 | 65 | public class RegisterViewModel 66 | { 67 | [Required] 68 | [EmailAddress] 69 | [Display(Name = "Email")] 70 | public string Email { get; set; } 71 | 72 | [Required] 73 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 74 | [DataType(DataType.Password)] 75 | [Display(Name = "Password")] 76 | public string Password { get; set; } 77 | 78 | [DataType(DataType.Password)] 79 | [Display(Name = "Confirm password")] 80 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 81 | public string ConfirmPassword { get; set; } 82 | } 83 | 84 | public class ResetPasswordViewModel 85 | { 86 | [Required] 87 | [EmailAddress] 88 | [Display(Name = "Email")] 89 | public string Email { get; set; } 90 | 91 | [Required] 92 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 93 | [DataType(DataType.Password)] 94 | [Display(Name = "Password")] 95 | public string Password { get; set; } 96 | 97 | [DataType(DataType.Password)] 98 | [Display(Name = "Confirm password")] 99 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 100 | public string ConfirmPassword { get; set; } 101 | 102 | public string Code { get; set; } 103 | } 104 | 105 | public class ForgotPasswordViewModel 106 | { 107 | [Required] 108 | [EmailAddress] 109 | [Display(Name = "Email")] 110 | public string Email { get; set; } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /MyTaskListApp/App_Start/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNet.Identity; 3 | using Microsoft.AspNet.Identity.Owin; 4 | using Microsoft.Owin; 5 | using Microsoft.Owin.Security.Cookies; 6 | using Microsoft.Owin.Security.Google; 7 | using Owin; 8 | using MyTaskListApp.Models; 9 | 10 | namespace MyTaskListApp 11 | { 12 | public partial class Startup 13 | { 14 | // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 15 | public void ConfigureAuth(IAppBuilder app) 16 | { 17 | // Configure the db context, user manager and signin manager to use a single instance per request 18 | app.CreatePerOwinContext(ApplicationDbContext.Create); 19 | app.CreatePerOwinContext(ApplicationUserManager.Create); 20 | app.CreatePerOwinContext(ApplicationSignInManager.Create); 21 | 22 | // Enable the application to use a cookie to store information for the signed in user 23 | // and to use a cookie to temporarily store information about a user logging in with a third party login provider 24 | // Configure the sign in cookie 25 | app.UseCookieAuthentication(new CookieAuthenticationOptions 26 | { 27 | AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 28 | LoginPath = new PathString("/Account/Login"), 29 | Provider = new CookieAuthenticationProvider 30 | { 31 | // Enables the application to validate the security stamp when the user logs in. 32 | // This is a security feature which is used when you change a password or add an external login to your account. 33 | OnValidateIdentity = SecurityStampValidator.OnValidateIdentity( 34 | validateInterval: TimeSpan.FromMinutes(30), 35 | regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 36 | } 37 | }); 38 | app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 39 | 40 | // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process. 41 | app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); 42 | 43 | // Enables the application to remember the second login verification factor such as phone or email. 44 | // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from. 45 | // This is similar to the RememberMe option when you log in. 46 | app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); 47 | 48 | // Uncomment the following lines to enable logging in with third party login providers 49 | //app.UseMicrosoftAccountAuthentication( 50 | // clientId: "", 51 | // clientSecret: ""); 52 | 53 | //app.UseTwitterAuthentication( 54 | // consumerKey: "", 55 | // consumerSecret: ""); 56 | 57 | //app.UseFacebookAuthentication( 58 | // appId: "", 59 | // appSecret: ""); 60 | 61 | //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() 62 | //{ 63 | // ClientId = "", 64 | // ClientSecret = "" 65 | //}); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /MyTaskListApp/Content/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2020 The Bootstrap Authors 4 | * Copyright 2011-2020 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/index.js.flow: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export type Position = 'top' | 'right' | 'bottom' | 'left'; 4 | 5 | export type Placement = 6 | | 'auto-start' 7 | | 'auto' 8 | | 'auto-end' 9 | | 'top-start' 10 | | 'top' 11 | | 'top-end' 12 | | 'right-start' 13 | | 'right' 14 | | 'right-end' 15 | | 'bottom-end' 16 | | 'bottom' 17 | | 'bottom-start' 18 | | 'left-end' 19 | | 'left' 20 | | 'left-start'; 21 | 22 | export type Offset = { 23 | top: number, 24 | left: number, 25 | width: number, 26 | height: number, 27 | position: Position, 28 | }; 29 | 30 | export type Boundary = 'scrollParent' | 'viewport' | 'window'; 31 | 32 | export type Behavior = 'flip' | 'clockwise' | 'counterclockwise'; 33 | 34 | export type Data = { 35 | instance: Popper, 36 | placement: Placement, 37 | originalPlacement: Placement, 38 | flipped: boolean, 39 | hide: boolean, 40 | arrowElement: Element, 41 | styles: CSSStyleDeclaration, 42 | arrowStyles: CSSStyleDeclaration, 43 | boundaries: Object, 44 | offsets: { 45 | popper: Offset, 46 | reference: Offset, 47 | arrow: { 48 | top: number, 49 | left: number, 50 | }, 51 | }, 52 | }; 53 | 54 | export type ModifierFn = (data: Data, options: Object) => Data; 55 | 56 | export type Padding = { 57 | top?: number, 58 | bottom?: number, 59 | left?: number, 60 | right?: number, 61 | }; 62 | 63 | export type BaseModifier = { 64 | order?: number, 65 | enabled?: boolean, 66 | fn?: ModifierFn, 67 | }; 68 | 69 | export type Modifiers = { 70 | shift?: BaseModifier, 71 | offset?: BaseModifier & { 72 | offset?: number | string, 73 | }, 74 | preventOverflow?: BaseModifier & { 75 | priority?: Position[], 76 | padding?: number | Padding, 77 | boundariesElement?: Boundary | Element, 78 | escapeWithReference?: boolean, 79 | }, 80 | keepTogether?: BaseModifier, 81 | arrow?: BaseModifier & { 82 | element?: string | Element | null, 83 | }, 84 | flip?: BaseModifier & { 85 | behavior?: Behavior | Position[], 86 | padding?: number | Padding, 87 | boundariesElement?: Boundary | Element, 88 | flipVariations?: boolean, 89 | flipVariationsByContent?: boolean, 90 | }, 91 | inner?: BaseModifier, 92 | hide?: BaseModifier, 93 | applyStyle?: BaseModifier & { 94 | onLoad?: Function, 95 | gpuAcceleration?: boolean, 96 | }, 97 | computeStyle?: BaseModifier & { 98 | gpuAcceleration?: boolean, 99 | x?: 'bottom' | 'top', 100 | y?: 'left' | 'right', 101 | }, 102 | 103 | [name: string]: (BaseModifier & { [string]: * }) | null, 104 | }; 105 | 106 | export type Options = { 107 | placement?: Placement, 108 | positionFixed?: boolean, 109 | eventsEnabled?: boolean, 110 | modifiers?: Modifiers, 111 | removeOnDestroy?: boolean, 112 | 113 | onCreate?: (data: Data) => void, 114 | 115 | onUpdate?: (data: Data) => void, 116 | }; 117 | 118 | export type ReferenceObject = { 119 | +clientHeight: number, 120 | +clientWidth: number, 121 | +referenceNode?: Node, 122 | 123 | getBoundingClientRect(): 124 | | ClientRect 125 | | { 126 | width: number, 127 | height: number, 128 | top: number, 129 | right: number, 130 | bottom: number, 131 | left: number, 132 | }, 133 | }; 134 | 135 | export type Instance = { 136 | destroy: () => void, 137 | scheduleUpdate: () => void, 138 | update: () => void, 139 | enableEventListeners: () => void, 140 | disableEventListeners: () => void, 141 | }; 142 | 143 | declare class Popper { 144 | static placements: Placement; 145 | 146 | popper: Element; 147 | reference: Element | ReferenceObject; 148 | 149 | constructor( 150 | reference: Element | ReferenceObject, 151 | popper: Element, 152 | options?: Options 153 | ): Instance; 154 | } 155 | 156 | declare export default typeof Popper; 157 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/umd/popper.js.flow: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | export type Position = 'top' | 'right' | 'bottom' | 'left'; 4 | 5 | export type Placement = 6 | | 'auto-start' 7 | | 'auto' 8 | | 'auto-end' 9 | | 'top-start' 10 | | 'top' 11 | | 'top-end' 12 | | 'right-start' 13 | | 'right' 14 | | 'right-end' 15 | | 'bottom-end' 16 | | 'bottom' 17 | | 'bottom-start' 18 | | 'left-end' 19 | | 'left' 20 | | 'left-start'; 21 | 22 | export type Offset = { 23 | top: number, 24 | left: number, 25 | width: number, 26 | height: number, 27 | position: Position, 28 | }; 29 | 30 | export type Boundary = 'scrollParent' | 'viewport' | 'window'; 31 | 32 | export type Behavior = 'flip' | 'clockwise' | 'counterclockwise'; 33 | 34 | export type Data = { 35 | instance: Popper, 36 | placement: Placement, 37 | originalPlacement: Placement, 38 | flipped: boolean, 39 | hide: boolean, 40 | arrowElement: Element, 41 | styles: CSSStyleDeclaration, 42 | arrowStyles: CSSStyleDeclaration, 43 | boundaries: Object, 44 | offsets: { 45 | popper: Offset, 46 | reference: Offset, 47 | arrow: { 48 | top: number, 49 | left: number, 50 | }, 51 | }, 52 | }; 53 | 54 | export type ModifierFn = (data: Data, options: Object) => Data; 55 | 56 | export type Padding = { 57 | top?: number, 58 | bottom?: number, 59 | left?: number, 60 | right?: number, 61 | }; 62 | 63 | export type BaseModifier = { 64 | order?: number, 65 | enabled?: boolean, 66 | fn?: ModifierFn, 67 | }; 68 | 69 | export type Modifiers = { 70 | shift?: BaseModifier, 71 | offset?: BaseModifier & { 72 | offset?: number | string, 73 | }, 74 | preventOverflow?: BaseModifier & { 75 | priority?: Position[], 76 | padding?: number | Padding, 77 | boundariesElement?: Boundary | Element, 78 | escapeWithReference?: boolean, 79 | }, 80 | keepTogether?: BaseModifier, 81 | arrow?: BaseModifier & { 82 | element?: string | Element | null, 83 | }, 84 | flip?: BaseModifier & { 85 | behavior?: Behavior | Position[], 86 | padding?: number | Padding, 87 | boundariesElement?: Boundary | Element, 88 | flipVariations?: boolean, 89 | flipVariationsByContent?: boolean, 90 | }, 91 | inner?: BaseModifier, 92 | hide?: BaseModifier, 93 | applyStyle?: BaseModifier & { 94 | onLoad?: Function, 95 | gpuAcceleration?: boolean, 96 | }, 97 | computeStyle?: BaseModifier & { 98 | gpuAcceleration?: boolean, 99 | x?: 'bottom' | 'top', 100 | y?: 'left' | 'right', 101 | }, 102 | 103 | [name: string]: (BaseModifier & { [string]: * }) | null, 104 | }; 105 | 106 | export type Options = { 107 | placement?: Placement, 108 | positionFixed?: boolean, 109 | eventsEnabled?: boolean, 110 | modifiers?: Modifiers, 111 | removeOnDestroy?: boolean, 112 | 113 | onCreate?: (data: Data) => void, 114 | 115 | onUpdate?: (data: Data) => void, 116 | }; 117 | 118 | export type ReferenceObject = { 119 | +clientHeight: number, 120 | +clientWidth: number, 121 | +referenceNode?: Node, 122 | 123 | getBoundingClientRect(): 124 | | ClientRect 125 | | { 126 | width: number, 127 | height: number, 128 | top: number, 129 | right: number, 130 | bottom: number, 131 | left: number, 132 | }, 133 | }; 134 | 135 | export type Instance = { 136 | destroy: () => void, 137 | scheduleUpdate: () => void, 138 | update: () => void, 139 | enableEventListeners: () => void, 140 | disableEventListeners: () => void, 141 | }; 142 | 143 | declare class Popper { 144 | static placements: Placement; 145 | 146 | popper: Element; 147 | reference: Element | ReferenceObject; 148 | 149 | constructor( 150 | reference: Element | ReferenceObject, 151 | popper: Element, 152 | options?: Options 153 | ): Instance; 154 | } 155 | 156 | declare export default typeof Popper; 157 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl 2 | * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT 3 | * */ 4 | 5 | !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b modifier.name === 'applyStyle' 25 | ).gpuAcceleration; 26 | if (legacyGpuAccelerationOption !== undefined) { 27 | console.warn( 28 | 'WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!' 29 | ); 30 | } 31 | const gpuAcceleration = 32 | legacyGpuAccelerationOption !== undefined 33 | ? legacyGpuAccelerationOption 34 | : options.gpuAcceleration; 35 | 36 | const offsetParent = getOffsetParent(data.instance.popper); 37 | const offsetParentRect = getBoundingClientRect(offsetParent); 38 | 39 | // Styles 40 | const styles = { 41 | position: popper.position, 42 | }; 43 | 44 | const offsets = getRoundedOffsets( 45 | data, 46 | window.devicePixelRatio < 2 || !isFirefox 47 | ); 48 | 49 | const sideA = x === 'bottom' ? 'top' : 'bottom'; 50 | const sideB = y === 'right' ? 'left' : 'right'; 51 | 52 | // if gpuAcceleration is set to `true` and transform is supported, 53 | // we use `translate3d` to apply the position to the popper we 54 | // automatically use the supported prefixed version if needed 55 | const prefixedProperty = getSupportedPropertyName('transform'); 56 | 57 | // now, let's make a step back and look at this code closely (wtf?) 58 | // If the content of the popper grows once it's been positioned, it 59 | // may happen that the popper gets misplaced because of the new content 60 | // overflowing its reference element 61 | // To avoid this problem, we provide two options (x and y), which allow 62 | // the consumer to define the offset origin. 63 | // If we position a popper on top of a reference element, we can set 64 | // `x` to `top` to make the popper grow towards its top instead of 65 | // its bottom. 66 | let left, top; 67 | if (sideA === 'bottom') { 68 | // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) 69 | // and not the bottom of the html element 70 | if (offsetParent.nodeName === 'HTML') { 71 | top = -offsetParent.clientHeight + offsets.bottom; 72 | } else { 73 | top = -offsetParentRect.height + offsets.bottom; 74 | } 75 | } else { 76 | top = offsets.top; 77 | } 78 | if (sideB === 'right') { 79 | if (offsetParent.nodeName === 'HTML') { 80 | left = -offsetParent.clientWidth + offsets.right; 81 | } else { 82 | left = -offsetParentRect.width + offsets.right; 83 | } 84 | } else { 85 | left = offsets.left; 86 | } 87 | if (gpuAcceleration && prefixedProperty) { 88 | styles[prefixedProperty] = `translate3d(${left}px, ${top}px, 0)`; 89 | styles[sideA] = 0; 90 | styles[sideB] = 0; 91 | styles.willChange = 'transform'; 92 | } else { 93 | // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 94 | const invertTop = sideA === 'bottom' ? -1 : 1; 95 | const invertLeft = sideB === 'right' ? -1 : 1; 96 | styles[sideA] = top * invertTop; 97 | styles[sideB] = left * invertLeft; 98 | styles.willChange = `${sideA}, ${sideB}`; 99 | } 100 | 101 | // Attributes 102 | const attributes = { 103 | 'x-placement': data.placement, 104 | }; 105 | 106 | // Update `data` attributes, styles and arrowStyles 107 | data.attributes = { ...attributes, ...data.attributes }; 108 | data.styles = { ...styles, ...data.styles }; 109 | data.arrowStyles = { ...data.offsets.arrow, ...data.arrowStyles }; 110 | 111 | return data; 112 | } 113 | -------------------------------------------------------------------------------- /MyTaskListApp/DAL/Dal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using MyTaskListApp.Models; 6 | using MongoDB.Driver; 7 | using MongoDB.Bson; 8 | using System.Configuration; 9 | using System.Security.Authentication; 10 | 11 | namespace MyTaskListApp 12 | { 13 | public class Dal : IDisposable 14 | { 15 | //private MongoServer mongoServer = null; 16 | private bool disposed = false; 17 | 18 | // To do: update the connection string with the DNS name 19 | // or IP address of your server. 20 | //For example, "mongodb://testlinux.cloudapp.net 21 | private string userName = "FILLME"; 22 | private string host = "FILLME"; 23 | private string password = "FILLME"; 24 | 25 | // This sample uses a database named "Tasks" and a 26 | //collection named "TasksList". The database and collection 27 | //will be automatically created if they don't already exist. 28 | private string dbName = "Tasks"; 29 | private string collectionName = "TasksList"; 30 | 31 | // Default constructor. 32 | public Dal() 33 | { 34 | } 35 | 36 | // Gets all Task items from the MongoDB server. 37 | public List GetAllTasks() 38 | { 39 | try 40 | { 41 | var collection = GetTasksCollection(); 42 | return collection.Find(new BsonDocument()).ToList(); 43 | } 44 | catch (MongoConnectionException) 45 | { 46 | return new List(); 47 | } 48 | } 49 | 50 | // Creates a Task and inserts it into the collection in MongoDB. 51 | public void CreateTask(MyTask task) 52 | { 53 | var collection = GetTasksCollectionForEdit(); 54 | try 55 | { 56 | collection.InsertOne(task); 57 | } 58 | catch (MongoCommandException ex) 59 | { 60 | string msg = ex.Message; 61 | } 62 | } 63 | 64 | private IMongoCollection GetTasksCollection() 65 | { 66 | MongoClientSettings settings = new MongoClientSettings(); 67 | settings.Server = new MongoServerAddress(host, 10255); 68 | settings.UseSsl = true; 69 | settings.SslSettings = new SslSettings(); 70 | settings.SslSettings.EnabledSslProtocols = SslProtocols.Tls12; 71 | settings.RetryWrites = false; 72 | 73 | MongoIdentity identity = new MongoInternalIdentity(dbName, userName); 74 | MongoIdentityEvidence evidence = new PasswordEvidence(password); 75 | 76 | settings.Credential = new MongoCredential("SCRAM-SHA-1", identity, evidence); 77 | 78 | MongoClient client = new MongoClient(settings); 79 | var database = client.GetDatabase(dbName); 80 | var todoTaskCollection = database.GetCollection(collectionName); 81 | return todoTaskCollection; 82 | } 83 | 84 | private IMongoCollection GetTasksCollectionForEdit() 85 | { 86 | MongoClientSettings settings = new MongoClientSettings(); 87 | settings.Server = new MongoServerAddress(host, 10255); 88 | settings.UseSsl = true; 89 | settings.SslSettings = new SslSettings(); 90 | settings.SslSettings.EnabledSslProtocols = SslProtocols.Tls12; 91 | settings.RetryWrites = false; 92 | 93 | MongoIdentity identity = new MongoInternalIdentity(dbName, userName); 94 | MongoIdentityEvidence evidence = new PasswordEvidence(password); 95 | 96 | settings.Credential = new MongoCredential("SCRAM-SHA-1", identity, evidence); 97 | 98 | MongoClient client = new MongoClient(settings); 99 | var database = client.GetDatabase(dbName); 100 | var todoTaskCollection = database.GetCollection(collectionName); 101 | return todoTaskCollection; 102 | } 103 | 104 | # region IDisposable 105 | 106 | public void Dispose() 107 | { 108 | this.Dispose(true); 109 | GC.SuppressFinalize(this); 110 | } 111 | 112 | protected virtual void Dispose(bool disposing) 113 | { 114 | if (!this.disposed) 115 | { 116 | if (disposing) 117 | { 118 | } 119 | } 120 | 121 | this.disposed = true; 122 | } 123 | 124 | # endregion 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /MyTaskListApp/App_Start/IdentityConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Identity.EntityFramework; 10 | using Microsoft.AspNet.Identity.Owin; 11 | using Microsoft.Owin; 12 | using Microsoft.Owin.Security; 13 | using MyTaskListApp.Models; 14 | 15 | namespace MyTaskListApp 16 | { 17 | public class EmailService : IIdentityMessageService 18 | { 19 | public Task SendAsync(IdentityMessage message) 20 | { 21 | // Plug in your email service here to send an email. 22 | return Task.FromResult(0); 23 | } 24 | } 25 | 26 | public class SmsService : IIdentityMessageService 27 | { 28 | public Task SendAsync(IdentityMessage message) 29 | { 30 | // Plug in your SMS service here to send a text message. 31 | return Task.FromResult(0); 32 | } 33 | } 34 | 35 | // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. 36 | public class ApplicationUserManager : UserManager 37 | { 38 | public ApplicationUserManager(IUserStore store) 39 | : base(store) 40 | { 41 | } 42 | 43 | public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context) 44 | { 45 | var manager = new ApplicationUserManager(new UserStore(context.Get())); 46 | // Configure validation logic for usernames 47 | manager.UserValidator = new UserValidator(manager) 48 | { 49 | AllowOnlyAlphanumericUserNames = false, 50 | RequireUniqueEmail = true 51 | }; 52 | 53 | // Configure validation logic for passwords 54 | manager.PasswordValidator = new PasswordValidator 55 | { 56 | RequiredLength = 6, 57 | RequireNonLetterOrDigit = true, 58 | RequireDigit = true, 59 | RequireLowercase = true, 60 | RequireUppercase = true, 61 | }; 62 | 63 | // Configure user lockout defaults 64 | manager.UserLockoutEnabledByDefault = true; 65 | manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); 66 | manager.MaxFailedAccessAttemptsBeforeLockout = 5; 67 | 68 | // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user 69 | // You can write your own provider and plug it in here. 70 | manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider 71 | { 72 | MessageFormat = "Your security code is {0}" 73 | }); 74 | manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider 75 | { 76 | Subject = "Security Code", 77 | BodyFormat = "Your security code is {0}" 78 | }); 79 | manager.EmailService = new EmailService(); 80 | manager.SmsService = new SmsService(); 81 | var dataProtectionProvider = options.DataProtectionProvider; 82 | if (dataProtectionProvider != null) 83 | { 84 | manager.UserTokenProvider = 85 | new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); 86 | } 87 | return manager; 88 | } 89 | } 90 | 91 | // Configure the application sign-in manager which is used in this application. 92 | public class ApplicationSignInManager : SignInManager 93 | { 94 | public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 95 | : base(userManager, authenticationManager) 96 | { 97 | } 98 | 99 | public override Task CreateUserIdentityAsync(ApplicationUser user) 100 | { 101 | return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); 102 | } 103 | 104 | public static ApplicationSignInManager Create(IdentityFactoryOptions options, IOwinContext context) 105 | { 106 | return new ApplicationSignInManager(context.GetUserManager(), context.Authentication); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /MyTaskListApp/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/respond.matchmedia.addListener.min.js: -------------------------------------------------------------------------------- 1 | /*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl 2 | * Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT 3 | * */ 4 | 5 | !function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='­',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";if(a.matchMedia&&a.matchMedia("all").addListener)return!1;var b=a.matchMedia,c=b("only all").matches,d=!1,e=0,f=[],g=function(){a.clearTimeout(e),e=a.setTimeout(function(){for(var c=0,d=f.length;d>c;c++){var e=f[c].mql,g=f[c].listeners||[],h=b(e.media).matches;if(h!==e.matches){e.matches=h;for(var i=0,j=g.length;j>i;i++)g[i].call(a,e)}}},30)};a.matchMedia=function(e){var h=b(e),i=[],j=0;return h.addListener=function(b){c&&(d||(d=!0,a.addEventListener("resize",g,!0)),0===j&&(j=f.push({mql:h,listeners:i})),i.push(b))},h.removeListener=function(a){for(var b=0,c=i.length;c>b;b++)i[b]===a&&i.splice(b,1)},h}}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b, ggray , rhysd , joscha , seckardt , marcfallows 6 | */ 7 | 8 | /** 9 | * This kind of namespace declaration is not necessary, but is kept here for backwards-compatibility with 10 | * popper.js 1.x. It can be removed in 2.x so that the default export is simply the Popper class 11 | * and all the types / interfaces are top-level named exports. 12 | */ 13 | declare namespace Popper { 14 | export type Position = 'top' | 'right' | 'bottom' | 'left'; 15 | 16 | export type Placement = 'auto-start' 17 | | 'auto' 18 | | 'auto-end' 19 | | 'top-start' 20 | | 'top' 21 | | 'top-end' 22 | | 'right-start' 23 | | 'right' 24 | | 'right-end' 25 | | 'bottom-end' 26 | | 'bottom' 27 | | 'bottom-start' 28 | | 'left-end' 29 | | 'left' 30 | | 'left-start'; 31 | 32 | export type Boundary = 'scrollParent' | 'viewport' | 'window'; 33 | 34 | export type Behavior = 'flip' | 'clockwise' | 'counterclockwise'; 35 | 36 | export type ModifierFn = (data: Data, options: Object) => Data; 37 | 38 | export interface Attributes { 39 | 'x-out-of-boundaries': '' | false; 40 | 'x-placement': Placement; 41 | } 42 | 43 | export interface Padding { 44 | top?: number, 45 | bottom?: number, 46 | left?: number, 47 | right?: number, 48 | } 49 | 50 | export interface BaseModifier { 51 | order?: number; 52 | enabled?: boolean; 53 | fn?: ModifierFn; 54 | } 55 | 56 | export interface Modifiers { 57 | shift?: BaseModifier; 58 | offset?: BaseModifier & { 59 | offset?: number | string, 60 | }; 61 | preventOverflow?: BaseModifier & { 62 | priority?: Position[], 63 | padding?: number | Padding, 64 | boundariesElement?: Boundary | Element, 65 | escapeWithReference?: boolean 66 | }; 67 | keepTogether?: BaseModifier; 68 | arrow?: BaseModifier & { 69 | element?: string | Element, 70 | }; 71 | flip?: BaseModifier & { 72 | behavior?: Behavior | Position[], 73 | padding?: number | Padding, 74 | boundariesElement?: Boundary | Element, 75 | flipVariations?: boolean, 76 | flipVariationsByContent?: boolean, 77 | }; 78 | inner?: BaseModifier; 79 | hide?: BaseModifier; 80 | applyStyle?: BaseModifier & { 81 | onLoad?: Function, 82 | gpuAcceleration?: boolean, 83 | }; 84 | computeStyle?: BaseModifier & { 85 | gpuAcceleration?: boolean; 86 | x?: 'bottom' | 'top', 87 | y?: 'left' | 'right' 88 | }; 89 | 90 | [name: string]: (BaseModifier & Record) | undefined; 91 | } 92 | 93 | export interface Offset { 94 | top: number; 95 | left: number; 96 | width: number; 97 | height: number; 98 | } 99 | 100 | export interface Data { 101 | instance: Popper; 102 | placement: Placement; 103 | originalPlacement: Placement; 104 | flipped: boolean; 105 | hide: boolean; 106 | arrowElement: Element; 107 | styles: CSSStyleDeclaration; 108 | arrowStyles: CSSStyleDeclaration; 109 | attributes: Attributes; 110 | boundaries: Object; 111 | offsets: { 112 | popper: Offset, 113 | reference: Offset, 114 | arrow: { 115 | top: number, 116 | left: number, 117 | }, 118 | }; 119 | } 120 | 121 | export interface PopperOptions { 122 | placement?: Placement; 123 | positionFixed?: boolean; 124 | eventsEnabled?: boolean; 125 | modifiers?: Modifiers; 126 | removeOnDestroy?: boolean; 127 | 128 | onCreate?(data: Data): void; 129 | 130 | onUpdate?(data: Data): void; 131 | } 132 | 133 | export interface ReferenceObject { 134 | clientHeight: number; 135 | clientWidth: number; 136 | referenceNode?: Node; 137 | 138 | getBoundingClientRect(): ClientRect; 139 | } 140 | } 141 | 142 | // Re-export types in the Popper namespace so that they can be accessed as top-level named exports. 143 | // These re-exports should be removed in 2.x when the "declare namespace Popper" syntax is removed. 144 | export type Padding = Popper.Padding; 145 | export type Position = Popper.Position; 146 | export type Placement = Popper.Placement; 147 | export type Boundary = Popper.Boundary; 148 | export type Behavior = Popper.Behavior; 149 | export type ModifierFn = Popper.ModifierFn; 150 | export type BaseModifier = Popper.BaseModifier; 151 | export type Modifiers = Popper.Modifiers; 152 | export type Offset = Popper.Offset; 153 | export type Data = Popper.Data; 154 | export type PopperOptions = Popper.PopperOptions; 155 | export type ReferenceObject = Popper.ReferenceObject; 156 | 157 | declare class Popper { 158 | static modifiers: (BaseModifier & { name: string })[]; 159 | static placements: Placement[]; 160 | static Defaults: PopperOptions; 161 | 162 | options: PopperOptions; 163 | popper: Element; 164 | reference: Element | ReferenceObject; 165 | 166 | constructor(reference: Element | ReferenceObject, popper: Element, options?: PopperOptions); 167 | 168 | destroy(): void; 169 | 170 | update(): void; 171 | 172 | scheduleUpdate(): void; 173 | 174 | enableEventListeners(): void; 175 | 176 | disableEventListeners(): void; 177 | } 178 | 179 | export default Popper; 180 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | // Unobtrusive validation support library for jQuery and jQuery Validate 2 | // Copyright (c) .NET Foundation. All rights reserved. 3 | // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 4 | // @version v3.2.11 5 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive}); -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/modifiers/flip.js: -------------------------------------------------------------------------------- 1 | import getOppositePlacement from '../utils/getOppositePlacement'; 2 | import getOppositeVariation from '../utils/getOppositeVariation'; 3 | import getPopperOffsets from '../utils/getPopperOffsets'; 4 | import runModifiers from '../utils/runModifiers'; 5 | import getBoundaries from '../utils/getBoundaries'; 6 | import isModifierEnabled from '../utils/isModifierEnabled'; 7 | import clockwise from '../utils/clockwise'; 8 | 9 | const BEHAVIORS = { 10 | FLIP: 'flip', 11 | CLOCKWISE: 'clockwise', 12 | COUNTERCLOCKWISE: 'counterclockwise', 13 | }; 14 | 15 | /** 16 | * @function 17 | * @memberof Modifiers 18 | * @argument {Object} data - The data object generated by update method 19 | * @argument {Object} options - Modifiers configuration and options 20 | * @returns {Object} The data object, properly modified 21 | */ 22 | export default function flip(data, options) { 23 | // if `inner` modifier is enabled, we can't use the `flip` modifier 24 | if (isModifierEnabled(data.instance.modifiers, 'inner')) { 25 | return data; 26 | } 27 | 28 | if (data.flipped && data.placement === data.originalPlacement) { 29 | // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 30 | return data; 31 | } 32 | 33 | const boundaries = getBoundaries( 34 | data.instance.popper, 35 | data.instance.reference, 36 | options.padding, 37 | options.boundariesElement, 38 | data.positionFixed 39 | ); 40 | 41 | let placement = data.placement.split('-')[0]; 42 | let placementOpposite = getOppositePlacement(placement); 43 | let variation = data.placement.split('-')[1] || ''; 44 | 45 | let flipOrder = []; 46 | 47 | switch (options.behavior) { 48 | case BEHAVIORS.FLIP: 49 | flipOrder = [placement, placementOpposite]; 50 | break; 51 | case BEHAVIORS.CLOCKWISE: 52 | flipOrder = clockwise(placement); 53 | break; 54 | case BEHAVIORS.COUNTERCLOCKWISE: 55 | flipOrder = clockwise(placement, true); 56 | break; 57 | default: 58 | flipOrder = options.behavior; 59 | } 60 | 61 | flipOrder.forEach((step, index) => { 62 | if (placement !== step || flipOrder.length === index + 1) { 63 | return data; 64 | } 65 | 66 | placement = data.placement.split('-')[0]; 67 | placementOpposite = getOppositePlacement(placement); 68 | 69 | const popperOffsets = data.offsets.popper; 70 | const refOffsets = data.offsets.reference; 71 | 72 | // using floor because the reference offsets may contain decimals we are not going to consider here 73 | const floor = Math.floor; 74 | const overlapsRef = 75 | (placement === 'left' && 76 | floor(popperOffsets.right) > floor(refOffsets.left)) || 77 | (placement === 'right' && 78 | floor(popperOffsets.left) < floor(refOffsets.right)) || 79 | (placement === 'top' && 80 | floor(popperOffsets.bottom) > floor(refOffsets.top)) || 81 | (placement === 'bottom' && 82 | floor(popperOffsets.top) < floor(refOffsets.bottom)); 83 | 84 | const overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 85 | const overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 86 | const overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 87 | const overflowsBottom = 88 | floor(popperOffsets.bottom) > floor(boundaries.bottom); 89 | 90 | const overflowsBoundaries = 91 | (placement === 'left' && overflowsLeft) || 92 | (placement === 'right' && overflowsRight) || 93 | (placement === 'top' && overflowsTop) || 94 | (placement === 'bottom' && overflowsBottom); 95 | 96 | // flip the variation if required 97 | const isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 98 | 99 | // flips variation if reference element overflows boundaries 100 | const flippedVariationByRef = 101 | !!options.flipVariations && 102 | ((isVertical && variation === 'start' && overflowsLeft) || 103 | (isVertical && variation === 'end' && overflowsRight) || 104 | (!isVertical && variation === 'start' && overflowsTop) || 105 | (!isVertical && variation === 'end' && overflowsBottom)); 106 | 107 | // flips variation if popper content overflows boundaries 108 | const flippedVariationByContent = 109 | !!options.flipVariationsByContent && 110 | ((isVertical && variation === 'start' && overflowsRight) || 111 | (isVertical && variation === 'end' && overflowsLeft) || 112 | (!isVertical && variation === 'start' && overflowsBottom) || 113 | (!isVertical && variation === 'end' && overflowsTop)); 114 | 115 | const flippedVariation = flippedVariationByRef || flippedVariationByContent; 116 | 117 | if (overlapsRef || overflowsBoundaries || flippedVariation) { 118 | // this boolean to detect any flip loop 119 | data.flipped = true; 120 | 121 | if (overlapsRef || overflowsBoundaries) { 122 | placement = flipOrder[index + 1]; 123 | } 124 | 125 | if (flippedVariation) { 126 | variation = getOppositeVariation(variation); 127 | } 128 | 129 | data.placement = placement + (variation ? '-' + variation : ''); 130 | 131 | // this object contains `position`, we want to preserve it along with 132 | // any additional property we may add in the future 133 | data.offsets.popper = { 134 | ...data.offsets.popper, 135 | ...getPopperOffsets( 136 | data.instance.popper, 137 | data.offsets.reference, 138 | data.placement 139 | ), 140 | }; 141 | 142 | data = runModifiers(data.instance.modifiers, data, 'flip'); 143 | } 144 | }); 145 | return data; 146 | } 147 | -------------------------------------------------------------------------------- /MyTaskListApp/Project_Readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Your ASP.NET application 6 | 95 | 96 | 97 | 98 | 102 | 103 |
    104 |
    105 |

    This application consists of:

    106 |
      107 |
    • Sample pages showing basic nav between Home, About, and Contact
    • 108 |
    • Theming using Bootstrap
    • 109 |
    • Authentication, if selected, shows how to register and sign in
    • 110 |
    • ASP.NET features managed using NuGet
    • 111 |
    112 |
    113 | 114 | 131 | 132 |
    133 |

    Deploy

    134 | 139 |
    140 | 141 |
    142 |

    Get help

    143 | 147 |
    148 |
    149 | 150 | 151 | -------------------------------------------------------------------------------- /MyTaskListApp/Scripts/src/index.js: -------------------------------------------------------------------------------- 1 | // Utils 2 | import debounce from './utils/debounce'; 3 | import isFunction from './utils/isFunction'; 4 | 5 | // Methods 6 | import update from './methods/update'; 7 | import destroy from './methods/destroy'; 8 | import enableEventListeners from './methods/enableEventListeners'; 9 | import disableEventListeners from './methods/disableEventListeners'; 10 | import Defaults from './methods/defaults'; 11 | import placements from './methods/placements'; 12 | 13 | export default class Popper { 14 | /** 15 | * Creates a new Popper.js instance. 16 | * @class Popper 17 | * @param {Element|referenceObject} reference - The reference element used to position the popper 18 | * @param {Element} popper - The HTML / XML element used as the popper 19 | * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 20 | * @return {Object} instance - The generated Popper.js instance 21 | */ 22 | constructor(reference, popper, options = {}) { 23 | // make update() debounced, so that it only runs at most once-per-tick 24 | this.update = debounce(this.update.bind(this)); 25 | 26 | // with {} we create a new object with the options inside it 27 | this.options = { ...Popper.Defaults, ...options }; 28 | 29 | // init state 30 | this.state = { 31 | isDestroyed: false, 32 | isCreated: false, 33 | scrollParents: [], 34 | }; 35 | 36 | // get reference and popper elements (allow jQuery wrappers) 37 | this.reference = reference && reference.jquery ? reference[0] : reference; 38 | this.popper = popper && popper.jquery ? popper[0] : popper; 39 | 40 | // Deep merge modifiers options 41 | this.options.modifiers = {}; 42 | Object.keys({ 43 | ...Popper.Defaults.modifiers, 44 | ...options.modifiers, 45 | }).forEach(name => { 46 | this.options.modifiers[name] = { 47 | // If it's a built-in modifier, use it as base 48 | ...(Popper.Defaults.modifiers[name] || {}), 49 | // If there are custom options, override and merge with default ones 50 | ...(options.modifiers ? options.modifiers[name] : {}), 51 | }; 52 | }); 53 | 54 | // Refactoring modifiers' list (Object => Array) 55 | this.modifiers = Object.keys(this.options.modifiers) 56 | .map(name => ({ 57 | name, 58 | ...this.options.modifiers[name], 59 | })) 60 | // sort the modifiers by order 61 | .sort((a, b) => a.order - b.order); 62 | 63 | // modifiers have the ability to execute arbitrary code when Popper.js get inited 64 | // such code is executed in the same order of its modifier 65 | // they could add new properties to their options configuration 66 | // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 67 | this.modifiers.forEach(modifierOptions => { 68 | if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 69 | modifierOptions.onLoad( 70 | this.reference, 71 | this.popper, 72 | this.options, 73 | modifierOptions, 74 | this.state 75 | ); 76 | } 77 | }); 78 | 79 | // fire the first update to position the popper in the right place 80 | this.update(); 81 | 82 | const eventsEnabled = this.options.eventsEnabled; 83 | if (eventsEnabled) { 84 | // setup event listeners, they will take care of update the position in specific situations 85 | this.enableEventListeners(); 86 | } 87 | 88 | this.state.eventsEnabled = eventsEnabled; 89 | } 90 | 91 | // We can't use class properties because they don't get listed in the 92 | // class prototype and break stuff like Sinon stubs 93 | update() { 94 | return update.call(this); 95 | } 96 | destroy() { 97 | return destroy.call(this); 98 | } 99 | enableEventListeners() { 100 | return enableEventListeners.call(this); 101 | } 102 | disableEventListeners() { 103 | return disableEventListeners.call(this); 104 | } 105 | 106 | /** 107 | * Schedules an update. It will run on the next UI update available. 108 | * @method scheduleUpdate 109 | * @memberof Popper 110 | */ 111 | scheduleUpdate = () => requestAnimationFrame(this.update); 112 | 113 | /** 114 | * Collection of utilities useful when writing custom modifiers. 115 | * Starting from version 1.7, this method is available only if you 116 | * include `popper-utils.js` before `popper.js`. 117 | * 118 | * **DEPRECATION**: This way to access PopperUtils is deprecated 119 | * and will be removed in v2! Use the PopperUtils module directly instead. 120 | * Due to the high instability of the methods contained in Utils, we can't 121 | * guarantee them to follow semver. Use them at your own risk! 122 | * @static 123 | * @private 124 | * @type {Object} 125 | * @deprecated since version 1.8 126 | * @member Utils 127 | * @memberof Popper 128 | */ 129 | static Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 130 | 131 | static placements = placements; 132 | 133 | static Defaults = Defaults; 134 | } 135 | 136 | /** 137 | * The `referenceObject` is an object that provides an interface compatible with Popper.js 138 | * and lets you use it as replacement of a real DOM node.
    139 | * You can use this method to position a popper relatively to a set of coordinates 140 | * in case you don't have a DOM node to use as reference. 141 | * 142 | * ``` 143 | * new Popper(referenceObject, popperNode); 144 | * ``` 145 | * 146 | * NB: This feature isn't supported in Internet Explorer 10. 147 | * @name referenceObject 148 | * @property {Function} data.getBoundingClientRect 149 | * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 150 | * @property {number} data.clientWidth 151 | * An ES6 getter that will return the width of the virtual reference element. 152 | * @property {number} data.clientHeight 153 | * An ES6 getter that will return the height of the virtual reference element. 154 | */ 155 | -------------------------------------------------------------------------------- /MyTaskListApp/Content/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.5.3 (https://getbootstrap.com/) 3 | * Copyright 2011-2020 The Bootstrap Authors 4 | * Copyright 2011-2020 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */ 8 | *, 9 | *::before, 10 | *::after { 11 | box-sizing: border-box; 12 | } 13 | 14 | html { 15 | font-family: sans-serif; 16 | line-height: 1.15; 17 | -webkit-text-size-adjust: 100%; 18 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 19 | } 20 | 21 | article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { 22 | display: block; 23 | } 24 | 25 | body { 26 | margin: 0; 27 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 28 | font-size: 1rem; 29 | font-weight: 400; 30 | line-height: 1.5; 31 | color: #212529; 32 | text-align: left; 33 | background-color: #fff; 34 | } 35 | 36 | [tabindex="-1"]:focus:not(:focus-visible) { 37 | outline: 0 !important; 38 | } 39 | 40 | hr { 41 | box-sizing: content-box; 42 | height: 0; 43 | overflow: visible; 44 | } 45 | 46 | h1, h2, h3, h4, h5, h6 { 47 | margin-top: 0; 48 | margin-bottom: 0.5rem; 49 | } 50 | 51 | p { 52 | margin-top: 0; 53 | margin-bottom: 1rem; 54 | } 55 | 56 | abbr[title], 57 | abbr[data-original-title] { 58 | text-decoration: underline; 59 | -webkit-text-decoration: underline dotted; 60 | text-decoration: underline dotted; 61 | cursor: help; 62 | border-bottom: 0; 63 | -webkit-text-decoration-skip-ink: none; 64 | text-decoration-skip-ink: none; 65 | } 66 | 67 | address { 68 | margin-bottom: 1rem; 69 | font-style: normal; 70 | line-height: inherit; 71 | } 72 | 73 | ol, 74 | ul, 75 | dl { 76 | margin-top: 0; 77 | margin-bottom: 1rem; 78 | } 79 | 80 | ol ol, 81 | ul ul, 82 | ol ul, 83 | ul ol { 84 | margin-bottom: 0; 85 | } 86 | 87 | dt { 88 | font-weight: 700; 89 | } 90 | 91 | dd { 92 | margin-bottom: .5rem; 93 | margin-left: 0; 94 | } 95 | 96 | blockquote { 97 | margin: 0 0 1rem; 98 | } 99 | 100 | b, 101 | strong { 102 | font-weight: bolder; 103 | } 104 | 105 | small { 106 | font-size: 80%; 107 | } 108 | 109 | sub, 110 | sup { 111 | position: relative; 112 | font-size: 75%; 113 | line-height: 0; 114 | vertical-align: baseline; 115 | } 116 | 117 | sub { 118 | bottom: -.25em; 119 | } 120 | 121 | sup { 122 | top: -.5em; 123 | } 124 | 125 | a { 126 | color: #007bff; 127 | text-decoration: none; 128 | background-color: transparent; 129 | } 130 | 131 | a:hover { 132 | color: #0056b3; 133 | text-decoration: underline; 134 | } 135 | 136 | a:not([href]):not([class]) { 137 | color: inherit; 138 | text-decoration: none; 139 | } 140 | 141 | a:not([href]):not([class]):hover { 142 | color: inherit; 143 | text-decoration: none; 144 | } 145 | 146 | pre, 147 | code, 148 | kbd, 149 | samp { 150 | font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 151 | font-size: 1em; 152 | } 153 | 154 | pre { 155 | margin-top: 0; 156 | margin-bottom: 1rem; 157 | overflow: auto; 158 | -ms-overflow-style: scrollbar; 159 | } 160 | 161 | figure { 162 | margin: 0 0 1rem; 163 | } 164 | 165 | img { 166 | vertical-align: middle; 167 | border-style: none; 168 | } 169 | 170 | svg { 171 | overflow: hidden; 172 | vertical-align: middle; 173 | } 174 | 175 | table { 176 | border-collapse: collapse; 177 | } 178 | 179 | caption { 180 | padding-top: 0.75rem; 181 | padding-bottom: 0.75rem; 182 | color: #6c757d; 183 | text-align: left; 184 | caption-side: bottom; 185 | } 186 | 187 | th { 188 | text-align: inherit; 189 | text-align: -webkit-match-parent; 190 | } 191 | 192 | label { 193 | display: inline-block; 194 | margin-bottom: 0.5rem; 195 | } 196 | 197 | button { 198 | border-radius: 0; 199 | } 200 | 201 | button:focus { 202 | outline: 1px dotted; 203 | outline: 5px auto -webkit-focus-ring-color; 204 | } 205 | 206 | input, 207 | button, 208 | select, 209 | optgroup, 210 | textarea { 211 | margin: 0; 212 | font-family: inherit; 213 | font-size: inherit; 214 | line-height: inherit; 215 | } 216 | 217 | button, 218 | input { 219 | overflow: visible; 220 | } 221 | 222 | button, 223 | select { 224 | text-transform: none; 225 | } 226 | 227 | [role="button"] { 228 | cursor: pointer; 229 | } 230 | 231 | select { 232 | word-wrap: normal; 233 | } 234 | 235 | button, 236 | [type="button"], 237 | [type="reset"], 238 | [type="submit"] { 239 | -webkit-appearance: button; 240 | } 241 | 242 | button:not(:disabled), 243 | [type="button"]:not(:disabled), 244 | [type="reset"]:not(:disabled), 245 | [type="submit"]:not(:disabled) { 246 | cursor: pointer; 247 | } 248 | 249 | button::-moz-focus-inner, 250 | [type="button"]::-moz-focus-inner, 251 | [type="reset"]::-moz-focus-inner, 252 | [type="submit"]::-moz-focus-inner { 253 | padding: 0; 254 | border-style: none; 255 | } 256 | 257 | input[type="radio"], 258 | input[type="checkbox"] { 259 | box-sizing: border-box; 260 | padding: 0; 261 | } 262 | 263 | textarea { 264 | overflow: auto; 265 | resize: vertical; 266 | } 267 | 268 | fieldset { 269 | min-width: 0; 270 | padding: 0; 271 | margin: 0; 272 | border: 0; 273 | } 274 | 275 | legend { 276 | display: block; 277 | width: 100%; 278 | max-width: 100%; 279 | padding: 0; 280 | margin-bottom: .5rem; 281 | font-size: 1.5rem; 282 | line-height: inherit; 283 | color: inherit; 284 | white-space: normal; 285 | } 286 | 287 | progress { 288 | vertical-align: baseline; 289 | } 290 | 291 | [type="number"]::-webkit-inner-spin-button, 292 | [type="number"]::-webkit-outer-spin-button { 293 | height: auto; 294 | } 295 | 296 | [type="search"] { 297 | outline-offset: -2px; 298 | -webkit-appearance: none; 299 | } 300 | 301 | [type="search"]::-webkit-search-decoration { 302 | -webkit-appearance: none; 303 | } 304 | 305 | ::-webkit-file-upload-button { 306 | font: inherit; 307 | -webkit-appearance: button; 308 | } 309 | 310 | output { 311 | display: inline-block; 312 | } 313 | 314 | summary { 315 | display: list-item; 316 | cursor: pointer; 317 | } 318 | 319 | template { 320 | display: none; 321 | } 322 | 323 | [hidden] { 324 | display: none !important; 325 | } 326 | /*# sourceMappingURL=bootstrap-reboot.css.map */ --------------------------------------------------------------------------------