{"version":3,"sources":["webpack:///datePicker.min.js","webpack:///webpack/bootstrap 9c1ce602f4142b72baa9","webpack:///./src/datePicker.js","webpack:///./src/js/calendar.js","webpack:///./src/js/calendarMonth.js","webpack:///./src/js/calendarMonthBody.js","webpack:///./src/js/calendarYear.js","webpack:///./src/js/calendarYearBody.js","webpack:///./src/js/dateLocaleProvider.js","webpack:///./src/js/datepickerDirective.js","webpack:///./src/js/dateUtil.js","webpack:///./src/datePicker.css?fcce","webpack:///./src/datePicker.css","webpack:///./node_modules/css-loader/lib/css-base.js","webpack:///./node_modules/style-loader/lib/addStyles.js","webpack:///./node_modules/style-loader/lib/urls.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","angular","persianCalendarDirective","template","tElement","tAttr","scope","minDate","maxDate","dateFilter","_currentView","require","controller","PersianCalendarCtrl","controllerAs","bindToController","link","element","attrs","controllers","ngModelCtrl","configureNgModel","$element","$scope","$$mdPersianDateUtil","$mdUtil","$mdConstant","$mdTheming","$$rAF","$attrs","$mdPersianDateLocale","this","dateUtil","keyCode","KEY_CODE","today","createDateAtMidnight","SELECTED_DATE_CLASS","TODAY_CLASS","FOCUSED_DATE_CLASS","id","nextUniqueId","displayDate","selectedDate","firstRenderableDate","lastRenderableDate","isInitialized","width","scrollbarWidth","tabindex","attr","handleKeyElement","boundKeyHandler","bind","handleKeyEvent","parent","hasClass","document","body","on","$on","off","version","major","minor","$onInit","$inject","directive","currentView","dateLocale","self","nextTick","$render","value","$viewValue","$broadcast","setNgModelValue","date","focus","$emit","$setViewValue","setCurrentView","newView","time","isDate","Date","isValidDate","previousFocus","querySelector","classList","remove","cellId","getDateId","cell","getElementById","add","rootElement","getActionFromKeyEvent","event","which","ENTER","RIGHT_ARROW","LEFT_ARROW","DOWN_ARROW","metaKey","UP_ARROW","PAGE_DOWN","PAGE_UP","HOME","END","$apply","ESCAPE","TAB","preventDefault","action","stopPropagation","hideVerticalScrollbar","childCtrl","setWidth","scroller","calendarScroller","scrollMask","style","paddingRight","offsetWidth","clientWidth","namespace","Error","pd","moment","jYear","jMonth","jDate","join","updateVirtualRepeat","virtualRepeatResizeListener","$$phase","TBODY_SINGLE_ROW_HEIGHT","TBODY_HEIGHT","PersianCalendarMonthCtrl","calendarCtrl","initialize","$animate","$q","isMonthTransitionInProgress","cellClickHandler","timestamp","getTimestampFromNode","headerClickHandler","items","length","getMonthDistance","attachScopeListeners","getSelectedMonthIndex","changeSelectedDate","previousSelectedDate","changeDisplayDate","then","selectedDateClass","prevDateCell","setAttribute","dateCell","buildWeekHeader","when","animationPromise","animateDateChange","monthDistance","scrollTop","firstDayOfWeek","shortDays","row","createElement","th","textContent","appendChild","find","append","incrementDays","incrementMonths","getFirstDateOfMonth","getLastDateOfMonth","clampDate","mdPersianCalendarMonthBodyDirective","$compile","$$mdSvgRegistry","ARROW_ICON","mdTabsArrow","offset","PersianCalendarMonthBodyCtrl","monthCtrl","monthBodyCtrl","arrowIcon","cloneNode","$watch","isNumber","generateContent","focusAfterAppend","empty","buildCalendarForMonth","buildDateCell","opt_date","tabIndex","longDateFormatter","getTime","isSameDay","cellText","dates","isDateEnabled","selectionIndicator","addEventListener","isDateWithinRange","isFunction","buildDateRow","rowNumber","weekNumberFormatter","opt_dateInMonth","firstDayOfMonth","firstDayOfTheWeek","getLocaleDay_","numberOfDaysInMonth","getNumberOfDaysInMonth","monthBody","createDocumentFragment","isFinalMonth","blankCellOffset","monthLabelCell","monthLabelCellContent","monthHeaderFormatter","monthFormatter","monthLabelRow","insertBefore","dayOfWeek","iterationDate","toDate","childNodes","whitespaceRow","j","day","PersianCalendarYearCtrl","getYearDistance","getFocusedYearIndex","changeDate","min","max","mdPersianCalendarYearDirective","PersianCalendarYearBodyCtrl","yearCtrl","yearBodyCtrl","incrementYears","buildCalendarForYear","buildMonthCell","year","month","buildBlankCell","firstOfMonth","isSameMonthAndYear","shortMonths","isMonthWithinRange","yearBody","firstRow","labelCell","className","secondRow","config","$provide","PersianDateLocaleProvider","months","days","formatDate","parseDate","msgCalendar","msgOpenCalendar","$get","$locale","$filter","defaultFormatDate","timezone","localeTime","toLocaleTimeString","getHours","indexOf","getFullYear","getMonth","getDate","format","defaultParseDate","dateString","defaultIsDateComplete","trim","test","defaultMonthHeaderFormatter","service","defaultMonthFormatter","defaultWeekNumberFormatter","number","defaultLongDateFormatter","defaultDates","DATETIME_FORMATS","SHORTDAY","map","substring","Array","defaultFirstRenderableDate","defaultLastRendereableDate","isDateComplete","provider","persianDatePickerDirective","$mdAria","inputDirective","tAttrs","hiddenIcons","mdHideIcons","ariaLabelValue","ariaLabel","mdPlaceholder","calendarButton","mdCalendar","triangleButton","addClass","HAS_TRIANGLE_ICON_CLASS","placeholder","isOpen","debounceInterval","PersianDatePickerCtrl","mdDatePickerCtrl","mdInputContainer","parentForm","mdNoAsterisk","parseAttributeBoolean","spacer","after","setHasPlaceholder","input","INPUT_CONTAINER_CLASS","toggleClass","HAS_CALENDAR_ICON_CLASS","label","$observe","expect","isErrorGetter","$invalid","$touched","$submitted","setInvalid","parentSubmittedWatcher","isSubmitted","updateErrorState","$window","documentElement","inputElement","ngInputElement","inputContainer","calendarPane","inputMask","isFocused","isDisabled","setDisabled","disabled","isString","isCalendarOpen","openOnFocus","calendarPaneOpenedFrom","calendarPaneId","nextUid","bodyClickHandler","handleBodyClick","windowEventName","IS_MOBILE_REGEX","navigator","userAgent","vendor","window","opera","windowEventHandler","debounce","closeCalendarPane","windowBlurHandler","handleWindowBlur","ngDateFilter","leftMargin","topMargin","$set","detachCalendarPane","mdIsOpen","shouldBeOpen","openCalendarPane","target","OPEN_CLASS","locale","extend","installPropertyInterceptors","attachChangeListeners","attachInteractionListeners","pre","noop","val","0","$formatters","push","parsedValue","isDefined","parse","isNaN","onExternalChange","$viewChangeListeners","unshift","updateOn","getModelOption","triggerHandler","setModelValue","resizeInputElement","handleInputEvent","keyCodes","altKey","$digest","ngDisabled","$parent","set","clearErrorState","$setValidity","$valid","forEach","field","size","inputString","parsedDate","setDateTimeToMidnight","attachCalendarPane","transform","elementRect","getBoundingClientRect","bodyRect","prop","paneTop","top","paneLeft","left","viewportTop","viewportLeft","scrollLeft","viewportBottom","innerHeight","viewportRight","innerWidth","css","position","height","scale","removeClass","enableScrolling","parentNode","removeChild","inputFocusedOnWindowBlur","disableScrollAround","focusCalendar","evalAttr","reset","$setTouched","removeEventListener","getCalendarCtrl","setFocused","getClosest","activeElement","$eval","setHasValue","factory","startOf","jDaysInMonth","getDateInNextMonth","getDateInPreviousMonth","d1","d2","pd1","pd2","isInNextMonth","startDate","endDate","isInPreviousMonth","getDateMidpoint","getWeekOfMonth","pfirstDayOfMonth","Math","floor","numberOfDays","numberOfMonths","start","end","pstart","pend","endOf","setHours","opt_value","isUndefined","dateAtMidnight","minDateAtMidnight","maxDateAtMidnight","numberOfYears","boundDate","node","hasAttribute","Number","getAttribute","pminDate","pmaxDate","pmonth","pyear","content","options","locals","undefined","cssWithMappingToString","item","useSourceMap","cssMapping","btoa","sourceMapping","toComment","concat","sources","source","sourceRoot","sourceMap","unescape","encodeURIComponent","JSON","stringify","list","toString","mediaQuery","alreadyImportedModules","addStylesToDom","styles","domStyle","stylesInDom","refs","parts","addStyle","listToStyles","newStyles","base","media","part","insertStyleElement","getElement","insertInto","lastStyleElementInsertedAtTop","stylesInsertedAtTop","insertAt","nextSibling","firstChild","removeStyleElement","idx","splice","createStyleElement","type","addAttrs","createLinkElement","rel","el","keys","key","obj","update","result","singleton","styleIndex","singletonCounter","applyToSingletonTag","URL","createObjectURL","revokeObjectURL","Blob","updateLink","href","applyToTag","newObj","index","styleSheet","cssText","replaceText","cssNode","createTextNode","autoFixUrls","convertToAbsoluteUrls","fixUrls","blob","oldSrc","isOldIE","fn","memo","apply","arguments","all","atob","selector","DEBUG","newList","mayRemove","textStore","replacement","filter","Boolean","location","baseUrl","protocol","host","currentDir","pathname","replace","fullMatch","origUrl","unquotedOrigUrl","$1","newUrl"],"mappings":"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","file":"datePicker.min.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(1);\n__webpack_require__(2);\n__webpack_require__(3);\n__webpack_require__(4);\n__webpack_require__(5);\n__webpack_require__(6);\n__webpack_require__(7);\n__webpack_require__(8);\n__webpack_require__(9);\nmodule.exports = __webpack_require__(10);\n\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\n/**\r\n * @ngdoc module\r\n * @name angular-material-persian-datepicker\r\n * @description Module for the Persian datepicker component.\r\n */\r\n\r\nangular.module('angular-material-persian-datepicker', [\r\n 'material.core',\r\n 'material.components.icon',\r\n 'material.components.virtualRepeat'\r\n]);\r\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n /**\r\n * @ngdoc directive\r\n * @name mdPersianCalendar\r\n * @module angular-material-persian-datepicker\r\n *\r\n * @param {Date} ng-model The component's model. Should be a Date object.\r\n * @param {Date=} md-min-date Expression representing the minimum date.\r\n * @param {Date=} md-max-date Expression representing the maximum date.\r\n * @param {(function(Date): boolean)=} md-date-filter Function expecting a date and returning a boolean whether it can be selected or not.\r\n *\r\n * @description\r\n * `` is a component that renders a calendar that can be used to select a date.\r\n * It is a part of the `` pane, however it can also be used on it's own.\r\n *\r\n * @usage\r\n *\r\n * \r\n * \r\n * \r\n */\r\n PersianCalendarCtrl.$inject = [\"$element\", \"$scope\", \"$$mdPersianDateUtil\", \"$mdUtil\", \"$mdConstant\", \"$mdTheming\", \"$$rAF\", \"$attrs\", \"$mdPersianDateLocale\"];\r\n angular.module('angular-material-persian-datepicker')\r\n .directive('mdPersianCalendar', persianCalendarDirective);\r\n\r\n // POST RELEASE\r\n // TODO(jelbourn): Mac Cmd + left / right == Home / End\r\n // TODO(jelbourn): Refactor month element creation to use cloneNode (performance).\r\n // TODO(jelbourn): Define virtual scrolling constants (compactness) users can override.\r\n // TODO(jelbourn): Animated month transition on ng-model change (virtual-repeat)\r\n // TODO(jelbourn): Scroll snapping (virtual repeat)\r\n // TODO(jelbourn): Remove superfluous row from short months (virtual-repeat)\r\n // TODO(jelbourn): Month headers stick to top when scrolling.\r\n // TODO(jelbourn): Previous month opacity is lowered when partially scrolled out of view.\r\n // TODO(jelbourn): Support md-persian-calendar standalone on a page (as a tabstop w/ aria-live\r\n // announcement and key handling).\r\n // Read-only calendar (not just date-picker).\r\n\r\n function persianCalendarDirective() {\r\n return {\r\n template: function(tElement, tAttr) {\r\n // TODO(crisbeto): This is a workaround that allows the calendar to work, without\r\n // a datepicker, until issue #8585 gets resolved. It can safely be removed\r\n // afterwards. This ensures that the virtual repeater scrolls to the proper place on load by\r\n // deferring the execution until the next digest. It's necessary only if the calendar is used\r\n // without a datepicker, otherwise it's already wrapped in an ngIf.\r\n var extraAttrs = tAttr.hasOwnProperty('ngIf') ? '' : 'ng-if=\"calendarCtrl.isInitialized\"';\r\n var template = '' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
';\r\n\r\n return template;\r\n },\r\n scope: {\r\n minDate: '=mdMinDate',\r\n maxDate: '=mdMaxDate',\r\n dateFilter: '=mdDateFilter',\r\n _currentView: '@mdCurrentView'\r\n },\r\n require: ['ngModel', 'mdPersianCalendar'],\r\n controller: PersianCalendarCtrl,\r\n controllerAs: 'calendarCtrl',\r\n bindToController: true,\r\n link: function(scope, element, attrs, controllers) {\r\n var ngModelCtrl = controllers[0];\r\n var mdCalendarCtrl = controllers[1];\r\n mdCalendarCtrl.configureNgModel(ngModelCtrl);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Occasionally the hideVerticalScrollbar method might read an element's\r\n * width as 0, because it hasn't been laid out yet. This value will be used\r\n * as a fallback, in order to prevent scenarios where the element's width\r\n * would otherwise have been set to 0. This value is the \"usual\" width of a\r\n * calendar within a floating calendar pane.\r\n */\r\n var FALLBACK_WIDTH = 340;\r\n\r\n /** Next identifier for calendar instance. */\r\n var nextUniqueId = 0;\r\n\r\n /**\r\n * Controller for the mdPersianCalendar component.\r\n * @ngInject @constructor\r\n */\r\n function PersianCalendarCtrl($element, $scope, $$mdPersianDateUtil, $mdUtil,\r\n $mdConstant, $mdTheming, $$rAF, $attrs, $mdPersianDateLocale) {\r\n\r\n $mdTheming($element);\r\n\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final {!angular.Scope} */\r\n this.$scope = $scope;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final */\r\n this.$mdUtil = $mdUtil;\r\n\r\n /** @final */\r\n this.keyCode = $mdConstant.KEY_CODE;\r\n\r\n /** @final */\r\n this.$$rAF = $$rAF;\r\n\r\n /** @final */\r\n this.$mdPersianDateLocale = $mdPersianDateLocale;\r\n\r\n /** @final {Date} */\r\n this.today = this.dateUtil.createDateAtMidnight();\r\n\r\n /** @type {!angular.NgModelController} */\r\n this.ngModelCtrl = null;\r\n\r\n /** @type {String} Class applied to the selected date cell. */\r\n this.SELECTED_DATE_CLASS = 'md-calendar-selected-date';\r\n\r\n /** @type {String} Class applied to the cell for today. */\r\n this.TODAY_CLASS = 'md-calendar-date-today';\r\n\r\n /** @type {String} Class applied to the focused cell. */\r\n this.FOCUSED_DATE_CLASS = 'md-focus';\r\n\r\n /** @final {number} Unique ID for this calendar instance. */\r\n this.id = nextUniqueId++;\r\n\r\n /**\r\n * The date that is currently focused or showing in the calendar. This will initially be set\r\n * to the ng-model value if set, otherwise to today. It will be updated as the user navigates\r\n * to other months. The cell corresponding to the displayDate does not necesarily always have\r\n * focus in the document (such as for cases when the user is scrolling the calendar).\r\n * @type {Date}\r\n */\r\n this.displayDate = null;\r\n\r\n /**\r\n * The selected date. Keep track of this separately from the ng-model value so that we\r\n * can know, when the ng-model value changes, what the previous value was before it's updated\r\n * in the component's UI.\r\n *\r\n * @type {Date}\r\n */\r\n this.selectedDate = null;\r\n\r\n /**\r\n * The first date that can be rendered by the calendar. The default is taken\r\n * from the mdDateLocale provider and is limited by the mdMinDate.\r\n * @type {Date}\r\n */\r\n this.firstRenderableDate = null;\r\n\r\n /**\r\n * The last date that can be rendered by the calendar. The default comes\r\n * from the mdDateLocale provider and is limited by the maxDate.\r\n * @type {Date}\r\n */\r\n this.lastRenderableDate = null;\r\n\r\n /**\r\n * Used to toggle initialize the root element in the next digest.\r\n * @type {Boolean}\r\n */\r\n this.isInitialized = false;\r\n\r\n /**\r\n * Cache for the width of the element without a scrollbar. Used to hide the scrollbar later on\r\n * and to avoid extra reflows when switching between views.\r\n * @type {Number}\r\n */\r\n this.width = 0;\r\n\r\n /**\r\n * Caches the width of the scrollbar in order to be used when hiding it and to avoid extra reflows.\r\n * @type {Number}\r\n */\r\n this.scrollbarWidth = 0;\r\n\r\n // Unless the user specifies so, the calendar should not be a tab stop.\r\n // This is necessary because ngAria might add a tabindex to anything with an ng-model\r\n // (based on whether or not the user has turned that particular feature on/off).\r\n if (!$attrs.tabindex) {\r\n $element.attr('tabindex', '-1');\r\n }\r\n\r\n var boundKeyHandler = angular.bind(this, this.handleKeyEvent);\r\n\r\n\r\n\r\n // If use the md-persian-calendar directly in the body without datepicker,\r\n // handleKeyEvent will disable other inputs on the page.\r\n // So only apply the handleKeyEvent on the body when the md-persian-calendar inside datepicker,\r\n // otherwise apply on the calendar element only.\r\n\r\n var handleKeyElement;\r\n if ($element.parent().hasClass('md-datepicker-calendar')) {\r\n handleKeyElement = angular.element(document.body);\r\n } else {\r\n handleKeyElement = $element;\r\n }\r\n\r\n // Bind the keydown handler to the body, in order to handle cases where the focused\r\n // element gets removed from the DOM and stops propagating click events.\r\n handleKeyElement.on('keydown', boundKeyHandler);\r\n\r\n $scope.$on('$destroy', function() {\r\n handleKeyElement.off('keydown', boundKeyHandler);\r\n });\r\n\r\n // For AngularJS 1.4 and older, where there are no lifecycle hooks but bindings are pre-assigned,\r\n // manually call the $onInit hook.\r\n if (angular.version.major === 1 && angular.version.minor <= 4) {\r\n this.$onInit();\r\n }\r\n\r\n }\r\n\r\n /**\r\n * AngularJS Lifecycle hook for newer AngularJS versions.\r\n * Bindings are not guaranteed to have been assigned in the controller, but they are in the $onInit hook.\r\n */\r\n PersianCalendarCtrl.prototype.$onInit = function() {\r\n\r\n /**\r\n * The currently visible calendar view. Note the prefix on the scope value,\r\n * which is necessary, because the datepicker seems to reset the real one value if the\r\n * calendar is open, but the value on the datepicker's scope is empty.\r\n * @type {String}\r\n */\r\n this.currentView = this._currentView || 'month';\r\n\r\n var dateLocale = this.$mdPersianDateLocale;\r\n\r\n if (this.minDate && this.minDate > dateLocale.firstRenderableDate) {\r\n this.firstRenderableDate = this.minDate;\r\n } else {\r\n this.firstRenderableDate = dateLocale.firstRenderableDate;\r\n }\r\n\r\n if (this.maxDate && this.maxDate < dateLocale.lastRenderableDate) {\r\n this.lastRenderableDate = this.maxDate;\r\n } else {\r\n this.lastRenderableDate = dateLocale.lastRenderableDate;\r\n }\r\n };\r\n\r\n /**\r\n * Sets up the controller's reference to ngModelController.\r\n * @param {!angular.NgModelController} ngModelCtrl\r\n */\r\n PersianCalendarCtrl.prototype.configureNgModel = function(ngModelCtrl) {\r\n var self = this;\r\n\r\n self.ngModelCtrl = ngModelCtrl;\r\n\r\n self.$mdUtil.nextTick(function() {\r\n self.isInitialized = true;\r\n });\r\n\r\n ngModelCtrl.$render = function() {\r\n var value = this.$viewValue;\r\n\r\n // Notify the child scopes of any changes.\r\n self.$scope.$broadcast('md-calendar-parent-changed', value);\r\n\r\n // Set up the selectedDate if it hasn't been already.\r\n if (!self.selectedDate) {\r\n self.selectedDate = value;\r\n }\r\n\r\n // Also set up the displayDate.\r\n if (!self.displayDate) {\r\n self.displayDate = self.selectedDate || self.today;\r\n }\r\n };\r\n };\r\n\r\n /**\r\n * Sets the ng-model value for the calendar and emits a change event.\r\n * @param {Date} date\r\n */\r\n PersianCalendarCtrl.prototype.setNgModelValue = function(date) {\r\n var value = this.dateUtil.createDateAtMidnight(date);\r\n this.focus(value);\r\n this.$scope.$emit('md-calendar-change', value);\r\n this.ngModelCtrl.$setViewValue(value);\r\n this.ngModelCtrl.$render();\r\n return value;\r\n };\r\n\r\n /**\r\n * Sets the current view that should be visible in the calendar\r\n * @param {string} newView View name to be set.\r\n * @param {number|Date} time Date object or a timestamp for the new display date.\r\n */\r\n PersianCalendarCtrl.prototype.setCurrentView = function(newView, time) {\r\n var self = this;\r\n\r\n self.$mdUtil.nextTick(function() {\r\n self.currentView = newView;\r\n\r\n if (time) {\r\n self.displayDate = angular.isDate(time) ? time : new Date(time);\r\n }\r\n });\r\n };\r\n\r\n /**\r\n * Focus the cell corresponding to the given date.\r\n * @param {Date} date The date to be focused.\r\n */\r\n PersianCalendarCtrl.prototype.focus = function(date) {\r\n if (this.dateUtil.isValidDate(date)) {\r\n var previousFocus = this.$element[0].querySelector('.md-focus');\r\n if (previousFocus) {\r\n previousFocus.classList.remove(this.FOCUSED_DATE_CLASS);\r\n }\r\n\r\n var cellId = this.getDateId(date, this.currentView);\r\n var cell = document.getElementById(cellId);\r\n if (cell) {\r\n cell.classList.add(this.FOCUSED_DATE_CLASS);\r\n cell.focus();\r\n this.displayDate = date;\r\n }\r\n } else {\r\n var rootElement = this.$element[0].querySelector('[ng-switch]');\r\n\r\n if (rootElement) {\r\n rootElement.focus();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Normalizes the key event into an action name. The action will be broadcast\r\n * to the child controllers.\r\n * @param {KeyboardEvent} event\r\n * @returns {String} The action that should be taken, or null if the key\r\n * does not match a calendar shortcut.\r\n */\r\n PersianCalendarCtrl.prototype.getActionFromKeyEvent = function(event) {\r\n var keyCode = this.keyCode;\r\n\r\n switch (event.which) {\r\n case keyCode.ENTER: return 'select';\r\n\r\n case keyCode.RIGHT_ARROW: return 'move-right';\r\n case keyCode.LEFT_ARROW: return 'move-left';\r\n\r\n // TODO(crisbeto): Might want to reconsider using metaKey, because it maps\r\n // to the \"Windows\" key on PC, which opens the start menu or resizes the browser.\r\n case keyCode.DOWN_ARROW: return event.metaKey ? 'move-page-down' : 'move-row-down';\r\n case keyCode.UP_ARROW: return event.metaKey ? 'move-page-up' : 'move-row-up';\r\n\r\n case keyCode.PAGE_DOWN: return 'move-page-down';\r\n case keyCode.PAGE_UP: return 'move-page-up';\r\n\r\n case keyCode.HOME: return 'start';\r\n case keyCode.END: return 'end';\r\n\r\n default: return null;\r\n }\r\n };\r\n\r\n /**\r\n * Handles a key event in the calendar with the appropriate action. The action will either\r\n * be to select the focused date or to navigate to focus a new date.\r\n * @param {KeyboardEvent} event\r\n */\r\n PersianCalendarCtrl.prototype.handleKeyEvent = function(event) {\r\n var self = this;\r\n\r\n this.$scope.$apply(function() {\r\n // Capture escape and emit back up so that a wrapping component\r\n // (such as a date-picker) can decide to close.\r\n if (event.which == self.keyCode.ESCAPE || event.which == self.keyCode.TAB) {\r\n self.$scope.$emit('md-calendar-close');\r\n\r\n if (event.which == self.keyCode.TAB) {\r\n event.preventDefault();\r\n }\r\n\r\n return;\r\n }\r\n\r\n // Broadcast the action that any child controllers should take.\r\n var action = self.getActionFromKeyEvent(event);\r\n if (action) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n self.$scope.$broadcast('md-calendar-parent-action', action);\r\n }\r\n });\r\n };\r\n\r\n /**\r\n * Hides the vertical scrollbar on the calendar scroller of a child controller by\r\n * setting the width on the calendar scroller and the `overflow: hidden` wrapper\r\n * around the scroller, and then setting a padding-right on the scroller equal\r\n * to the width of the browser's scrollbar.\r\n *\r\n * This will cause a reflow.\r\n *\r\n * @param {object} childCtrl The child controller whose scrollbar should be hidden.\r\n */\r\n PersianCalendarCtrl.prototype.hideVerticalScrollbar = function(childCtrl) {\r\n var self = this;\r\n var element = childCtrl.$element[0];\r\n var scrollMask = element.querySelector('.md-calendar-scroll-mask');\r\n\r\n if (self.width > 0) {\r\n setWidth();\r\n } else {\r\n self.$$rAF(function() {\r\n var scroller = childCtrl.calendarScroller;\r\n\r\n self.scrollbarWidth = scroller.offsetWidth - scroller.clientWidth;\r\n self.width = element.querySelector('table').offsetWidth;\r\n setWidth();\r\n });\r\n }\r\n\r\n function setWidth() {\r\n var width = self.width || FALLBACK_WIDTH;\r\n var scrollbarWidth = self.scrollbarWidth;\r\n var scroller = childCtrl.calendarScroller;\r\n\r\n scrollMask.style.width = width + 'px';\r\n scroller.style.width = (width + scrollbarWidth) + 'px';\r\n scroller.style.paddingRight = scrollbarWidth + 'px';\r\n }\r\n };\r\n\r\n /**\r\n * Gets an identifier for a date unique to the calendar instance for internal\r\n * purposes. Not to be displayed.\r\n * @param {Date} date The date for which the id is being generated\r\n * @param {string} namespace Namespace for the id. (month, year etc.)\r\n * @returns {string}\r\n */\r\n PersianCalendarCtrl.prototype.getDateId = function(date, namespace) {\r\n if (!namespace) {\r\n throw new Error('A namespace for the date id has to be specified.');\r\n }\r\n\r\n // return [\r\n // 'md',\r\n // this.id,\r\n // namespace,\r\n // date.getFullYear(),\r\n // date.getMonth(),\r\n // date.getDate()\r\n // ].join('-');\r\n var pd = moment(date);\r\n return [\r\n 'md',\r\n this.id,\r\n namespace,\r\n pd.jYear(),\r\n pd.jMonth(),\r\n pd.jDate()\r\n ].join('-');\r\n };\r\n\r\n /**\r\n * Util to trigger an extra digest on a parent scope, in order to to ensure that\r\n * any child virtual repeaters have updated. This is necessary, because the virtual\r\n * repeater doesn't update the $index the first time around since the content isn't\r\n * in place yet. The case, in which this is an issue, is when the repeater has less\r\n * than a page of content (e.g. a month or year view has a min or max date).\r\n */\r\n PersianCalendarCtrl.prototype.updateVirtualRepeat = function() {\r\n var scope = this.$scope;\r\n var virtualRepeatResizeListener = scope.$on('$md-resize-enable', function() {\r\n if (!scope.$$phase) {\r\n scope.$apply();\r\n }\r\n\r\n virtualRepeatResizeListener();\r\n });\r\n };\r\n})();\r\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n PersianCalendarMonthCtrl.$inject = [\"$element\", \"$scope\", \"$animate\", \"$q\", \"$$mdPersianDateUtil\", \"$mdPersianDateLocale\"];\r\n angular.module('angular-material-persian-datepicker')\r\n .directive('mdPersianCalendarMonth', persianCalendarDirective);\r\n\r\n /**\r\n * Height of one calendar month tbody. This must be made known to the virtual-repeat and is\r\n * subsequently used for scrolling to specific months.\r\n */\r\n var TBODY_HEIGHT = 265;\r\n\r\n /**\r\n * Height of a calendar month with a single row. This is needed to calculate the offset for\r\n * rendering an extra month in virtual-repeat that only contains one row.\r\n */\r\n var TBODY_SINGLE_ROW_HEIGHT = 45;\r\n\r\n /** Private directive that represents a list of months inside the calendar. */\r\n function persianCalendarDirective() {\r\n return {\r\n template:\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n\r\n // The ensures that the will always have the\r\n // proper height, even if it's empty. If it's content is\r\n // compiled, the will be overwritten.\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
',\r\n require: ['^^mdPersianCalendar', 'mdPersianCalendarMonth'],\r\n controller: PersianCalendarMonthCtrl,\r\n controllerAs: 'monthCtrl',\r\n bindToController: true,\r\n link: function(scope, element, attrs, controllers) {\r\n var calendarCtrl = controllers[0];\r\n var monthCtrl = controllers[1];\r\n monthCtrl.initialize(calendarCtrl);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Controller for the calendar month component.\r\n * @ngInject @constructor\r\n */\r\n function PersianCalendarMonthCtrl($element, $scope, $animate, $q,\r\n $$mdPersianDateUtil, $mdPersianDateLocale) {\r\n\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final {!angular.Scope} */\r\n this.$scope = $scope;\r\n\r\n /** @final {!angular.$animate} */\r\n this.$animate = $animate;\r\n\r\n /** @final {!angular.$q} */\r\n this.$q = $q;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final */\r\n this.dateLocale = $mdPersianDateLocale;\r\n\r\n /** @final {HTMLElement} */\r\n this.calendarScroller = $element[0].querySelector('.md-virtual-repeat-scroller');\r\n\r\n /** @type {boolean} */\r\n this.isInitialized = false;\r\n\r\n /** @type {boolean} */\r\n this.isMonthTransitionInProgress = false;\r\n\r\n var self = this;\r\n\r\n /**\r\n * Handles a click event on a date cell.\r\n * Created here so that every cell can use the same function instance.\r\n * @this {HTMLTableCellElement} The cell that was clicked.\r\n */\r\n this.cellClickHandler = function() {\r\n var timestamp = $$mdPersianDateUtil.getTimestampFromNode(this);\r\n self.$scope.$apply(function() {\r\n self.calendarCtrl.setNgModelValue(timestamp);\r\n });\r\n };\r\n\r\n /**\r\n * Handles click events on the month headers. Switches\r\n * the calendar to the year view.\r\n * @this {HTMLTableCellElement} The cell that was clicked.\r\n */\r\n this.headerClickHandler = function() {\r\n self.calendarCtrl.setCurrentView('year', $$mdPersianDateUtil.getTimestampFromNode(this));\r\n };\r\n }\r\n\r\n /*** Initialization ***/\r\n\r\n /**\r\n * Initialize the controller by saving a reference to the calendar and\r\n * setting up the object that will be iterated by the virtual repeater.\r\n */\r\n PersianCalendarMonthCtrl.prototype.initialize = function(calendarCtrl) {\r\n /**\r\n * Dummy array-like object for virtual-repeat to iterate over. The length is the total\r\n * number of months that can be viewed. We add 2 months: one to include the current month\r\n * and one for the last dummy month.\r\n *\r\n * This is shorter than ideal because of a (potential) Firefox bug\r\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1181658.\r\n */\r\n\r\n this.items = {\r\n length: this.dateUtil.getMonthDistance(\r\n calendarCtrl.firstRenderableDate,\r\n calendarCtrl.lastRenderableDate\r\n ) + 2\r\n };\r\n\r\n this.calendarCtrl = calendarCtrl;\r\n this.attachScopeListeners();\r\n calendarCtrl.updateVirtualRepeat();\r\n\r\n // Fire the initial render, since we might have missed it the first time it fired.\r\n calendarCtrl.ngModelCtrl && calendarCtrl.ngModelCtrl.$render();\r\n };\r\n\r\n /**\r\n * Gets the \"index\" of the currently selected date as it would be in the virtual-repeat.\r\n * @returns {number}\r\n */\r\n PersianCalendarMonthCtrl.prototype.getSelectedMonthIndex = function() {\r\n var calendarCtrl = this.calendarCtrl;\r\n\r\n return this.dateUtil.getMonthDistance(\r\n calendarCtrl.firstRenderableDate,\r\n calendarCtrl.displayDate || calendarCtrl.selectedDate || calendarCtrl.today\r\n );\r\n };\r\n\r\n /**\r\n * Change the selected date in the calendar (ngModel value has already been changed).\r\n * @param {Date} date\r\n */\r\n PersianCalendarMonthCtrl.prototype.changeSelectedDate = function(date) {\r\n var self = this;\r\n var calendarCtrl = self.calendarCtrl;\r\n var previousSelectedDate = calendarCtrl.selectedDate;\r\n calendarCtrl.selectedDate = date;\r\n\r\n this.changeDisplayDate(date).then(function() {\r\n var selectedDateClass = calendarCtrl.SELECTED_DATE_CLASS;\r\n var namespace = 'month';\r\n\r\n // Remove the selected class from the previously selected date, if any.\r\n if (previousSelectedDate) {\r\n var prevDateCell = document.getElementById(calendarCtrl.getDateId(previousSelectedDate, namespace));\r\n if (prevDateCell) {\r\n prevDateCell.classList.remove(selectedDateClass);\r\n prevDateCell.setAttribute('aria-selected', 'false');\r\n }\r\n }\r\n\r\n // Apply the select class to the new selected date if it is set.\r\n if (date) {\r\n var dateCell = document.getElementById(calendarCtrl.getDateId(date, namespace));\r\n if (dateCell) {\r\n dateCell.classList.add(selectedDateClass);\r\n dateCell.setAttribute('aria-selected', 'true');\r\n }\r\n }\r\n });\r\n };\r\n\r\n /**\r\n * Change the date that is being shown in the calendar. If the given date is in a different\r\n * month, the displayed month will be transitioned.\r\n * @param {Date} date\r\n */\r\n PersianCalendarMonthCtrl.prototype.changeDisplayDate = function(date) {\r\n // Initialization is deferred until this function is called because we want to reflect\r\n // the starting value of ngModel.\r\n if (!this.isInitialized) {\r\n this.buildWeekHeader();\r\n this.calendarCtrl.hideVerticalScrollbar(this);\r\n this.isInitialized = true;\r\n return this.$q.when();\r\n }\r\n\r\n // If trying to show an invalid date or a transition is in progress, do nothing.\r\n if (!this.dateUtil.isValidDate(date) || this.isMonthTransitionInProgress) {\r\n return this.$q.when();\r\n }\r\n\r\n this.isMonthTransitionInProgress = true;\r\n var animationPromise = this.animateDateChange(date);\r\n\r\n this.calendarCtrl.displayDate = date;\r\n\r\n var self = this;\r\n animationPromise.then(function() {\r\n self.isMonthTransitionInProgress = false;\r\n });\r\n\r\n return animationPromise;\r\n };\r\n\r\n /**\r\n * Animates the transition from the calendar's current month to the given month.\r\n * @param {Date} date\r\n * @returns {angular.$q.Promise} The animation promise.\r\n */\r\n PersianCalendarMonthCtrl.prototype.animateDateChange = function(date) {\r\n if (this.dateUtil.isValidDate(date)) {\r\n var monthDistance = this.dateUtil.getMonthDistance(this.calendarCtrl.firstRenderableDate, date);\r\n this.calendarScroller.scrollTop = monthDistance * TBODY_HEIGHT;\r\n }\r\n\r\n return this.$q.when();\r\n };\r\n\r\n /**\r\n * Builds and appends a day-of-the-week header to the calendar.\r\n * This should only need to be called once during initialization.\r\n */\r\n PersianCalendarMonthCtrl.prototype.buildWeekHeader = function() {\r\n var firstDayOfWeek = this.dateLocale.firstDayOfWeek;\r\n var shortDays = this.dateLocale.shortDays;\r\n\r\n var row = document.createElement('tr');\r\n for (var i = 0; i < 7; i++) {\r\n var th = document.createElement('th');\r\n th.textContent = shortDays[(i + firstDayOfWeek) % 7];\r\n row.appendChild(th);\r\n }\r\n\r\n this.$element.find('thead').append(row);\r\n };\r\n\r\n /**\r\n * Attaches listeners for the scope events that are broadcast by the calendar.\r\n */\r\n PersianCalendarMonthCtrl.prototype.attachScopeListeners = function() {\r\n var self = this;\r\n\r\n self.$scope.$on('md-calendar-parent-changed', function(event, value) {\r\n self.changeSelectedDate(value);\r\n });\r\n\r\n self.$scope.$on('md-calendar-parent-action', angular.bind(this, this.handleKeyEvent));\r\n };\r\n\r\n /**\r\n * Handles the month-specific keyboard interactions.\r\n * @param {Object} event Scope event object passed by the calendar.\r\n * @param {String} action Action, corresponding to the key that was pressed.\r\n */\r\n PersianCalendarMonthCtrl.prototype.handleKeyEvent = function(event, action) {\r\n var calendarCtrl = this.calendarCtrl;\r\n var displayDate = calendarCtrl.displayDate;\r\n\r\n if (action === 'select') {\r\n calendarCtrl.setNgModelValue(displayDate);\r\n } else {\r\n var date = null;\r\n var dateUtil = this.dateUtil;\r\n\r\n switch (action) {\r\n case 'move-right': date = dateUtil.incrementDays(displayDate, 1); break;\r\n case 'move-left': date = dateUtil.incrementDays(displayDate, -1); break;\r\n\r\n case 'move-page-down': date = dateUtil.incrementMonths(displayDate, 1); break;\r\n case 'move-page-up': date = dateUtil.incrementMonths(displayDate, -1); break;\r\n\r\n case 'move-row-down': date = dateUtil.incrementDays(displayDate, 7); break;\r\n case 'move-row-up': date = dateUtil.incrementDays(displayDate, -7); break;\r\n\r\n case 'start': date = dateUtil.getFirstDateOfMonth(displayDate); break;\r\n case 'end': date = dateUtil.getLastDateOfMonth(displayDate); break;\r\n }\r\n\r\n if (date) {\r\n date = this.dateUtil.clampDate(date, calendarCtrl.minDate, calendarCtrl.maxDate);\r\n\r\n this.changeDisplayDate(date).then(function() {\r\n calendarCtrl.focus(date);\r\n });\r\n }\r\n }\r\n };\r\n})();\r\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n mdPersianCalendarMonthBodyDirective.$inject = [\"$compile\", \"$$mdSvgRegistry\"];\r\n PersianCalendarMonthBodyCtrl.$inject = [\"$element\", \"$$mdPersianDateUtil\", \"$mdPersianDateLocale\"];\r\n angular.module('angular-material-persian-datepicker')\r\n .directive('mdPersianCalendarMonthBody', mdPersianCalendarMonthBodyDirective);\r\n\r\n /**\r\n * Private directive consumed by md-persian-calendar-month. Having this directive lets the calender use\r\n * md-virtual-repeat and also cleanly separates the month DOM construction functions from\r\n * the rest of the calendar controller logic.\r\n * @ngInject\r\n */\r\n function mdPersianCalendarMonthBodyDirective($compile, $$mdSvgRegistry) {\r\n var ARROW_ICON = $compile('')({})[0];\r\n\r\n return {\r\n require: ['^^mdPersianCalendar', '^^mdPersianCalendarMonth', 'mdPersianCalendarMonthBody'],\r\n scope: { offset: '=mdMonthOffset' },\r\n controller: PersianCalendarMonthBodyCtrl,\r\n controllerAs: 'mdMonthBodyCtrl',\r\n bindToController: true,\r\n link: function(scope, element, attrs, controllers) {\r\n var calendarCtrl = controllers[0];\r\n var monthCtrl = controllers[1];\r\n var monthBodyCtrl = controllers[2];\r\n\r\n monthBodyCtrl.calendarCtrl = calendarCtrl;\r\n monthBodyCtrl.monthCtrl = monthCtrl;\r\n monthBodyCtrl.arrowIcon = ARROW_ICON.cloneNode(true);\r\n\r\n // The virtual-repeat re-uses the same DOM elements, so there are only a limited number\r\n // of repeated items that are linked, and then those elements have their bindings updated.\r\n // Since the months are not generated by bindings, we simply regenerate the entire thing\r\n // when the binding (offset) changes.\r\n scope.$watch(function() { return monthBodyCtrl.offset; }, function(offset) {\r\n if (angular.isNumber(offset)) {\r\n monthBodyCtrl.generateContent();\r\n }\r\n });\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Controller for a single calendar month.\r\n * @ngInject @constructor\r\n */\r\n function PersianCalendarMonthBodyCtrl($element, $$mdPersianDateUtil, $mdPersianDateLocale) {\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final */\r\n this.dateLocale = $mdPersianDateLocale;\r\n\r\n /** @type {Object} Reference to the month view. */\r\n this.monthCtrl = null;\r\n\r\n /** @type {Object} Reference to the calendar. */\r\n this.calendarCtrl = null;\r\n\r\n /**\r\n * Number of months from the start of the month \"items\" that the currently rendered month\r\n * occurs. Set via angular data binding.\r\n * @type {number}\r\n */\r\n this.offset = null;\r\n\r\n /**\r\n * Date cell to focus after appending the month to the document.\r\n * @type {HTMLElement}\r\n */\r\n this.focusAfterAppend = null;\r\n }\r\n\r\n /** Generate and append the content for this month to the directive element. */\r\n PersianCalendarMonthBodyCtrl.prototype.generateContent = function() {\r\n var date = this.dateUtil.incrementMonths(this.calendarCtrl.firstRenderableDate, this.offset);\r\n\r\n this.$element\r\n .empty()\r\n .append(this.buildCalendarForMonth(date));\r\n\r\n if (this.focusAfterAppend) {\r\n this.focusAfterAppend.classList.add(this.calendarCtrl.FOCUSED_DATE_CLASS);\r\n this.focusAfterAppend.focus();\r\n this.focusAfterAppend = null;\r\n }\r\n };\r\n\r\n /**\r\n * Creates a single cell to contain a date in the calendar with all appropriate\r\n * attributes and classes added. If a date is given, the cell content will be set\r\n * based on the date.\r\n * @param {Date=} opt_date\r\n * @returns {HTMLElement}\r\n */\r\n PersianCalendarMonthBodyCtrl.prototype.buildDateCell = function(opt_date) {\r\n var monthCtrl = this.monthCtrl;\r\n var calendarCtrl = this.calendarCtrl;\r\n\r\n // TODO(jelbourn): cloneNode is likely a faster way of doing this.\r\n var cell = document.createElement('td');\r\n cell.tabIndex = -1;\r\n cell.classList.add('md-calendar-date');\r\n cell.setAttribute('role', 'gridcell');\r\n\r\n if (opt_date) {\r\n cell.setAttribute('tabindex', '-1');\r\n cell.setAttribute('aria-label', this.dateLocale.longDateFormatter(opt_date));\r\n cell.id = calendarCtrl.getDateId(opt_date, 'month');\r\n\r\n // Use `data-timestamp` attribute because IE10 does not support the `dataset` property.\r\n cell.setAttribute('data-timestamp', opt_date.getTime());\r\n\r\n // TODO(jelourn): Doing these comparisons for class addition during generation might be slow.\r\n // It may be better to finish the construction and then query the node and add the class.\r\n if (this.dateUtil.isSameDay(opt_date, calendarCtrl.today)) {\r\n cell.classList.add(calendarCtrl.TODAY_CLASS);\r\n }\r\n\r\n if (this.dateUtil.isValidDate(calendarCtrl.selectedDate) &&\r\n this.dateUtil.isSameDay(opt_date, calendarCtrl.selectedDate)) {\r\n cell.classList.add(calendarCtrl.SELECTED_DATE_CLASS);\r\n cell.setAttribute('aria-selected', 'true');\r\n }\r\n\r\n var cellText = this.dateLocale.dates[moment(opt_date).jDate()];\r\n\r\n if (this.isDateEnabled(opt_date)) {\r\n // Add a indicator for select, hover, and focus states.\r\n var selectionIndicator = document.createElement('span');\r\n selectionIndicator.classList.add('md-calendar-date-selection-indicator');\r\n selectionIndicator.textContent = cellText;\r\n cell.appendChild(selectionIndicator);\r\n cell.addEventListener('click', monthCtrl.cellClickHandler);\r\n\r\n if (calendarCtrl.displayDate && this.dateUtil.isSameDay(opt_date, calendarCtrl.displayDate)) {\r\n this.focusAfterAppend = cell;\r\n }\r\n } else {\r\n cell.classList.add('md-calendar-date-disabled');\r\n cell.textContent = cellText;\r\n }\r\n }\r\n\r\n return cell;\r\n };\r\n\r\n /**\r\n * Check whether date is in range and enabled\r\n * @param {Date=} opt_date\r\n * @return {boolean} Whether the date is enabled.\r\n */\r\n PersianCalendarMonthBodyCtrl.prototype.isDateEnabled = function(opt_date) {\r\n return this.dateUtil.isDateWithinRange(opt_date,\r\n this.calendarCtrl.minDate, this.calendarCtrl.maxDate) &&\r\n (!angular.isFunction(this.calendarCtrl.dateFilter)\r\n || this.calendarCtrl.dateFilter(opt_date));\r\n };\r\n\r\n /**\r\n * Builds a `tr` element for the calendar grid.\r\n * @param rowNumber The week number within the month.\r\n * @returns {HTMLElement}\r\n */\r\n PersianCalendarMonthBodyCtrl.prototype.buildDateRow = function(rowNumber) {\r\n var row = document.createElement('tr');\r\n row.setAttribute('role', 'row');\r\n\r\n // Because of an NVDA bug (with Firefox), the row needs an aria-label in order\r\n // to prevent the entire row being read aloud when the user moves between rows.\r\n // See http://community.nvda-project.org/ticket/4643.\r\n row.setAttribute('aria-label', this.dateLocale.weekNumberFormatter(rowNumber));\r\n\r\n return row;\r\n };\r\n\r\n /**\r\n * Builds the content for the given date's month.\r\n * @param {Date=} opt_dateInMonth\r\n * @returns {DocumentFragment} A document fragment containing the elements.\r\n */\r\n PersianCalendarMonthBodyCtrl.prototype.buildCalendarForMonth = function(opt_dateInMonth) {\r\n var date = this.dateUtil.isValidDate(opt_dateInMonth) ? opt_dateInMonth : new Date();\r\n\r\n var firstDayOfMonth = this.dateUtil.getFirstDateOfMonth(date);\r\n var firstDayOfTheWeek = this.getLocaleDay_(firstDayOfMonth);\r\n var numberOfDaysInMonth = this.dateUtil.getNumberOfDaysInMonth(date);\r\n\r\n // Store rows for the month in a document fragment so that we can append them all at once.\r\n var monthBody = document.createDocumentFragment();\r\n\r\n var rowNumber = 1;\r\n var row = this.buildDateRow(rowNumber);\r\n monthBody.appendChild(row);\r\n\r\n // If this is the final month in the list of items, only the first week should render,\r\n // so we should return immediately after the first row is complete and has been\r\n // attached to the body.\r\n var isFinalMonth = this.offset === this.monthCtrl.items.length - 1;\r\n\r\n // Add a label for the month. If the month starts on a Sun/Mon/Tues, the month label\r\n // goes on a row above the first of the month. Otherwise, the month label takes up the first\r\n // two cells of the first row.\r\n var blankCellOffset = 0;\r\n var monthLabelCell = document.createElement('td');\r\n var monthLabelCellContent = document.createElement('span');\r\n\r\n monthLabelCellContent.textContent = this.dateLocale.monthHeaderFormatter(date);\r\n monthLabelCell.appendChild(monthLabelCellContent);\r\n monthLabelCell.classList.add('md-calendar-month-label');\r\n // If the entire month is after the max date, render the label as a disabled state.\r\n if (this.calendarCtrl.maxDate && firstDayOfMonth > this.calendarCtrl.maxDate) {\r\n monthLabelCell.classList.add('md-calendar-month-label-disabled');\r\n } else {\r\n monthLabelCell.addEventListener('click', this.monthCtrl.headerClickHandler);\r\n monthLabelCell.setAttribute('data-timestamp', firstDayOfMonth.getTime());\r\n monthLabelCell.setAttribute('aria-label', this.dateLocale.monthFormatter(date));\r\n monthLabelCell.appendChild(this.arrowIcon.cloneNode(true));\r\n }\r\n\r\n if (firstDayOfTheWeek <= 2) {\r\n monthLabelCell.setAttribute('colspan', '7');\r\n\r\n var monthLabelRow = this.buildDateRow();\r\n monthLabelRow.appendChild(monthLabelCell);\r\n monthBody.insertBefore(monthLabelRow, row);\r\n\r\n if (isFinalMonth) {\r\n return monthBody;\r\n }\r\n } else {\r\n blankCellOffset = 3;\r\n monthLabelCell.setAttribute('colspan', '3');\r\n row.appendChild(monthLabelCell);\r\n }\r\n\r\n // Add a blank cell for each day of the week that occurs before the first of the month.\r\n // For example, if the first day of the month is a Tuesday, add blank cells for Sun and Mon.\r\n // The blankCellOffset is needed in cases where the first N cells are used by the month label.\r\n for (var i = blankCellOffset; i < firstDayOfTheWeek; i++) {\r\n row.appendChild(this.buildDateCell());\r\n }\r\n\r\n // Add a cell for each day of the month, keeping track of the day of the week so that\r\n // we know when to start a new row.\r\n var dayOfWeek = firstDayOfTheWeek;\r\n var iterationDate = firstDayOfMonth;\r\n for (var d = 1; d <= numberOfDaysInMonth; d++) {\r\n // If we've reached the end of the week, start a new row.\r\n if (dayOfWeek === 7) {\r\n // We've finished the first row, so we're done if this is the final month.\r\n if (isFinalMonth) {\r\n return monthBody;\r\n }\r\n dayOfWeek = 0;\r\n rowNumber++;\r\n row = this.buildDateRow(rowNumber);\r\n monthBody.appendChild(row);\r\n }\r\n\r\n var cell = this.buildDateCell(iterationDate);\r\n row.appendChild(cell);\r\n\r\n iterationDate = moment(iterationDate).add(1, 'day').toDate();\r\n dayOfWeek++;\r\n }\r\n\r\n // Ensure that the last row of the month has 7 cells.\r\n while (row.childNodes.length < 7) {\r\n row.appendChild(this.buildDateCell());\r\n }\r\n\r\n // Ensure that all months have 6 rows. This is necessary for now because the virtual-repeat\r\n // requires that all items have exactly the same height.\r\n while (monthBody.childNodes.length < 6) {\r\n var whitespaceRow = this.buildDateRow();\r\n for (var j = 0; j < 7; j++) {\r\n whitespaceRow.appendChild(this.buildDateCell());\r\n }\r\n monthBody.appendChild(whitespaceRow);\r\n }\r\n\r\n return monthBody;\r\n };\r\n\r\n /**\r\n * Gets the day-of-the-week index for a date for the current locale.\r\n * @private\r\n * @param {Date} date\r\n * @returns {number} The column index of the date in the calendar.\r\n */\r\n PersianCalendarMonthBodyCtrl.prototype.getLocaleDay_ = function(date) {\r\n return (moment(date).day() + (7 - this.dateLocale.firstDayOfWeek)) % 7;\r\n };\r\n})();\r\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n PersianCalendarYearCtrl.$inject = [\"$element\", \"$scope\", \"$animate\", \"$q\", \"$$mdPersianDateUtil\"];\r\n angular.module('angular-material-persian-datepicker')\r\n .directive('mdPersianCalendarYear', persianCalendarDirective);\r\n\r\n /**\r\n * Height of one calendar year tbody. This must be made known to the virtual-repeat and is\r\n * subsequently used for scrolling to specific years.\r\n */\r\n var TBODY_HEIGHT = 88;\r\n\r\n /** Private component, representing a list of years in the calendar. */\r\n function persianCalendarDirective() {\r\n return {\r\n template:\r\n '
' +\r\n '' +\r\n '' +\r\n '' +\r\n // The ensures that the will have the proper\r\n // height, even though it may be empty.\r\n '' +\r\n '' +\r\n '
' +\r\n '
' +\r\n '
',\r\n require: ['^^mdPersianCalendar', 'mdPersianCalendarYear'],\r\n controller: PersianCalendarYearCtrl,\r\n controllerAs: 'yearCtrl',\r\n bindToController: true,\r\n link: function(scope, element, attrs, controllers) {\r\n var calendarCtrl = controllers[0];\r\n var yearCtrl = controllers[1];\r\n yearCtrl.initialize(calendarCtrl);\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Controller for the mdPersianCalendar component.\r\n * @ngInject @constructor\r\n */\r\n function PersianCalendarYearCtrl($element, $scope, $animate, $q, $$mdPersianDateUtil) {\r\n\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final {!angular.Scope} */\r\n this.$scope = $scope;\r\n\r\n /** @final {!angular.$animate} */\r\n this.$animate = $animate;\r\n\r\n /** @final {!angular.$q} */\r\n this.$q = $q;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final {HTMLElement} */\r\n this.calendarScroller = $element[0].querySelector('.md-virtual-repeat-scroller');\r\n\r\n /** @type {boolean} */\r\n this.isInitialized = false;\r\n\r\n /** @type {boolean} */\r\n this.isMonthTransitionInProgress = false;\r\n\r\n var self = this;\r\n\r\n /**\r\n * Handles a click event on a date cell.\r\n * Created here so that every cell can use the same function instance.\r\n * @this {HTMLTableCellElement} The cell that was clicked.\r\n */\r\n this.cellClickHandler = function() {\r\n self.calendarCtrl.setCurrentView('month', $$mdPersianDateUtil.getTimestampFromNode(this));\r\n };\r\n }\r\n\r\n /**\r\n * Initialize the controller by saving a reference to the calendar and\r\n * setting up the object that will be iterated by the virtual repeater.\r\n */\r\n PersianCalendarYearCtrl.prototype.initialize = function(calendarCtrl) {\r\n /**\r\n * Dummy array-like object for virtual-repeat to iterate over. The length is the total\r\n * number of years that can be viewed. We add 1 extra in order to include the current year.\r\n */\r\n this.items = {\r\n length: this.dateUtil.getYearDistance(\r\n calendarCtrl.firstRenderableDate,\r\n calendarCtrl.lastRenderableDate\r\n ) + 1\r\n };\r\n\r\n this.calendarCtrl = calendarCtrl;\r\n this.attachScopeListeners();\r\n calendarCtrl.updateVirtualRepeat();\r\n\r\n // Fire the initial render, since we might have missed it the first time it fired.\r\n calendarCtrl.ngModelCtrl && calendarCtrl.ngModelCtrl.$render();\r\n };\r\n\r\n /**\r\n * Gets the \"index\" of the currently selected date as it would be in the virtual-repeat.\r\n * @returns {number}\r\n */\r\n PersianCalendarYearCtrl.prototype.getFocusedYearIndex = function() {\r\n var calendarCtrl = this.calendarCtrl;\r\n\r\n return this.dateUtil.getYearDistance(\r\n calendarCtrl.firstRenderableDate,\r\n calendarCtrl.displayDate || calendarCtrl.selectedDate || calendarCtrl.today\r\n );\r\n };\r\n\r\n /**\r\n * Change the date that is highlighted in the calendar.\r\n * @param {Date} date\r\n */\r\n PersianCalendarYearCtrl.prototype.changeDate = function(date) {\r\n // Initialization is deferred until this function is called because we want to reflect\r\n // the starting value of ngModel.\r\n if (!this.isInitialized) {\r\n this.calendarCtrl.hideVerticalScrollbar(this);\r\n this.isInitialized = true;\r\n return this.$q.when();\r\n } else if (this.dateUtil.isValidDate(date) && !this.isMonthTransitionInProgress) {\r\n var self = this;\r\n var animationPromise = this.animateDateChange(date);\r\n\r\n self.isMonthTransitionInProgress = true;\r\n self.calendarCtrl.displayDate = date;\r\n\r\n return animationPromise.then(function() {\r\n self.isMonthTransitionInProgress = false;\r\n });\r\n }\r\n };\r\n\r\n /**\r\n * Animates the transition from the calendar's current month to the given month.\r\n * @param {Date} date\r\n * @returns {angular.$q.Promise} The animation promise.\r\n */\r\n PersianCalendarYearCtrl.prototype.animateDateChange = function(date) {\r\n if (this.dateUtil.isValidDate(date)) {\r\n var monthDistance = this.dateUtil.getYearDistance(this.calendarCtrl.firstRenderableDate, date);\r\n this.calendarScroller.scrollTop = monthDistance * TBODY_HEIGHT;\r\n }\r\n\r\n return this.$q.when();\r\n };\r\n\r\n /**\r\n * Handles the year-view-specific keyboard interactions.\r\n * @param {Object} event Scope event object passed by the calendar.\r\n * @param {String} action Action, corresponding to the key that was pressed.\r\n */\r\n PersianCalendarYearCtrl.prototype.handleKeyEvent = function(event, action) {\r\n var calendarCtrl = this.calendarCtrl;\r\n var displayDate = calendarCtrl.displayDate;\r\n\r\n if (action === 'select') {\r\n this.changeDate(displayDate).then(function() {\r\n calendarCtrl.setCurrentView('month', displayDate);\r\n calendarCtrl.focus(displayDate);\r\n });\r\n } else {\r\n var date = null;\r\n var dateUtil = this.dateUtil;\r\n\r\n switch (action) {\r\n case 'move-right': date = dateUtil.incrementMonths(displayDate, 1); break;\r\n case 'move-left': date = dateUtil.incrementMonths(displayDate, -1); break;\r\n\r\n case 'move-row-down': date = dateUtil.incrementMonths(displayDate, 6); break;\r\n case 'move-row-up': date = dateUtil.incrementMonths(displayDate, -6); break;\r\n }\r\n\r\n if (date) {\r\n var min = calendarCtrl.minDate ? dateUtil.getFirstDateOfMonth(calendarCtrl.minDate) : null;\r\n var max = calendarCtrl.maxDate ? dateUtil.getFirstDateOfMonth(calendarCtrl.maxDate) : null;\r\n date = dateUtil.getFirstDateOfMonth(this.dateUtil.clampDate(date, min, max));\r\n\r\n this.changeDate(date).then(function() {\r\n calendarCtrl.focus(date);\r\n });\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Attaches listeners for the scope events that are broadcast by the calendar.\r\n */\r\n PersianCalendarYearCtrl.prototype.attachScopeListeners = function() {\r\n var self = this;\r\n\r\n self.$scope.$on('md-calendar-parent-changed', function(event, value) {\r\n self.changeDate(value);\r\n });\r\n\r\n self.$scope.$on('md-calendar-parent-action', angular.bind(self, self.handleKeyEvent));\r\n };\r\n})();\r\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n PersianCalendarYearBodyCtrl.$inject = [\"$element\", \"$$mdPersianDateUtil\", \"$mdPersianDateLocale\"];\r\n angular.module('angular-material-persian-datepicker')\r\n .directive('mdPersianCalendarYearBody', mdPersianCalendarYearDirective);\r\n\r\n /**\r\n * Private component, consumed by the md-persian-calendar-year, which separates the DOM construction logic\r\n * and allows for the year view to use md-virtual-repeat.\r\n */\r\n function mdPersianCalendarYearDirective() {\r\n return {\r\n require: ['^^mdPersianCalendar', '^^mdPersianCalendarYear', 'mdPersianCalendarYearBody'],\r\n scope: { offset: '=mdYearOffset' },\r\n controller: PersianCalendarYearBodyCtrl,\r\n controllerAs: 'mdYearBodyCtrl',\r\n bindToController: true,\r\n link: function(scope, element, attrs, controllers) {\r\n var calendarCtrl = controllers[0];\r\n var yearCtrl = controllers[1];\r\n var yearBodyCtrl = controllers[2];\r\n\r\n yearBodyCtrl.calendarCtrl = calendarCtrl;\r\n yearBodyCtrl.yearCtrl = yearCtrl;\r\n\r\n scope.$watch(function() { return yearBodyCtrl.offset; }, function(offset) {\r\n if (angular.isNumber(offset)) {\r\n yearBodyCtrl.generateContent();\r\n }\r\n });\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Controller for a single year.\r\n * @ngInject @constructor\r\n */\r\n function PersianCalendarYearBodyCtrl($element, $$mdPersianDateUtil, $mdPersianDateLocale) {\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final */\r\n this.dateLocale = $mdPersianDateLocale;\r\n\r\n /** @type {Object} Reference to the calendar. */\r\n this.calendarCtrl = null;\r\n\r\n /** @type {Object} Reference to the year view. */\r\n this.yearCtrl = null;\r\n\r\n /**\r\n * Number of months from the start of the month \"items\" that the currently rendered month\r\n * occurs. Set via angular data binding.\r\n * @type {number}\r\n */\r\n this.offset = null;\r\n\r\n /**\r\n * Date cell to focus after appending the month to the document.\r\n * @type {HTMLElement}\r\n */\r\n this.focusAfterAppend = null;\r\n }\r\n\r\n /** Generate and append the content for this year to the directive element. */\r\n PersianCalendarYearBodyCtrl.prototype.generateContent = function() {\r\n var date = this.dateUtil.incrementYears(this.calendarCtrl.firstRenderableDate, this.offset);\r\n\r\n this.$element\r\n .empty()\r\n .append(this.buildCalendarForYear(date));\r\n\r\n if (this.focusAfterAppend) {\r\n this.focusAfterAppend.classList.add(this.calendarCtrl.FOCUSED_DATE_CLASS);\r\n this.focusAfterAppend.focus();\r\n this.focusAfterAppend = null;\r\n }\r\n };\r\n\r\n /**\r\n * Creates a single cell to contain a year in the calendar.\r\n * @param {number} opt_year Four-digit year.\r\n * @param {number} opt_month Zero-indexed month.\r\n * @returns {HTMLElement}\r\n */\r\n PersianCalendarYearBodyCtrl.prototype.buildMonthCell = function(year, month) {\r\n var calendarCtrl = this.calendarCtrl;\r\n var yearCtrl = this.yearCtrl;\r\n var cell = this.buildBlankCell();\r\n\r\n // Represent this month/year as a date.\r\n var firstOfMonth = moment([year, (month+1), 1].join('/'), 'jYYYY/jM/jD').toDate();\r\n cell.setAttribute('aria-label', this.dateLocale.monthFormatter(firstOfMonth));\r\n cell.id = calendarCtrl.getDateId(firstOfMonth, 'year');\r\n\r\n // Use `data-timestamp` attribute because IE10 does not support the `dataset` property.\r\n cell.setAttribute('data-timestamp', firstOfMonth.getTime());\r\n\r\n if (this.dateUtil.isSameMonthAndYear(firstOfMonth, calendarCtrl.today)) {\r\n cell.classList.add(calendarCtrl.TODAY_CLASS);\r\n }\r\n\r\n if (this.dateUtil.isValidDate(calendarCtrl.selectedDate) &&\r\n this.dateUtil.isSameMonthAndYear(firstOfMonth, calendarCtrl.selectedDate)) {\r\n cell.classList.add(calendarCtrl.SELECTED_DATE_CLASS);\r\n cell.setAttribute('aria-selected', 'true');\r\n }\r\n\r\n var cellText = this.dateLocale.shortMonths[month];\r\n\r\n if (this.dateUtil.isMonthWithinRange(firstOfMonth,\r\n calendarCtrl.minDate, calendarCtrl.maxDate)) {\r\n var selectionIndicator = document.createElement('span');\r\n selectionIndicator.classList.add('md-calendar-date-selection-indicator');\r\n selectionIndicator.textContent = cellText;\r\n cell.appendChild(selectionIndicator);\r\n cell.addEventListener('click', yearCtrl.cellClickHandler);\r\n\r\n if (calendarCtrl.displayDate && this.dateUtil.isSameMonthAndYear(firstOfMonth, calendarCtrl.displayDate)) {\r\n this.focusAfterAppend = cell;\r\n }\r\n } else {\r\n cell.classList.add('md-calendar-date-disabled');\r\n cell.textContent = cellText;\r\n }\r\n\r\n return cell;\r\n };\r\n\r\n /**\r\n * Builds a blank cell.\r\n * @return {HTMLTableCellElement}\r\n */\r\n PersianCalendarYearBodyCtrl.prototype.buildBlankCell = function() {\r\n var cell = document.createElement('td');\r\n cell.tabIndex = -1;\r\n cell.classList.add('md-calendar-date');\r\n cell.setAttribute('role', 'gridcell');\r\n\r\n cell.setAttribute('tabindex', '-1');\r\n return cell;\r\n };\r\n\r\n /**\r\n * Builds the content for the given year.\r\n * @param {Date} date Date for which the content should be built.\r\n * @returns {DocumentFragment} A document fragment containing the months within the year.\r\n */\r\n PersianCalendarYearBodyCtrl.prototype.buildCalendarForYear = function(date) {\r\n // Store rows for the month in a document fragment so that we can append them all at once.\r\n var year = moment(date).jYear();\r\n var yearBody = document.createDocumentFragment();\r\n\r\n var monthCell, i;\r\n // First row contains label and Jan-Jun.\r\n var firstRow = document.createElement('tr');\r\n var labelCell = document.createElement('td');\r\n labelCell.className = 'md-calendar-month-label';\r\n labelCell.textContent = year;\r\n firstRow.appendChild(labelCell);\r\n\r\n for (i = 0; i < 6; i++) {\r\n firstRow.appendChild(this.buildMonthCell(year, i));\r\n }\r\n yearBody.appendChild(firstRow);\r\n\r\n // Second row contains a blank cell and Jul-Dec.\r\n var secondRow = document.createElement('tr');\r\n secondRow.appendChild(this.buildBlankCell());\r\n for (i = 6; i < 12; i++) {\r\n secondRow.appendChild(this.buildMonthCell(year, i));\r\n }\r\n yearBody.appendChild(secondRow);\r\n\r\n return yearBody;\r\n };\r\n})();\r\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n /**\r\n * @ngdoc service\r\n * @name $mdPersianDateLocaleProvider\r\n * @module angular-material-persian-datepicker\r\n *\r\n * @description\r\n * The `$mdPersianDateLocaleProvider` is the provider that creates the `$mdPersianDateLocale` service.\r\n * This provider that allows the user to specify messages, formatters, and parsers for date\r\n * internationalization. The `$mdPersianDateLocale` service itself is consumed by AngularJS Material\r\n * components that deal with dates.\r\n *\r\n * @property {(Array)=} months Array of month names (in order).\r\n * @property {(Array)=} shortMonths Array of abbreviated month names.\r\n * @property {(Array)=} days Array of the days of the week (in order).\r\n * @property {(Array)=} shortDays Array of abbreviated days of the week.\r\n * @property {(Array)=} dates Array of dates of the month. Only necessary for locales\r\n * using a numeral system other than [1, 2, 3...].\r\n * @property {(Array)=} firstDayOfWeek The first day of the week. Sunday = 0, Monday = 1,\r\n * etc.\r\n * @property {(function(string): Date)=} parseDate Function to parse a date object from a string.\r\n * @property {(function(Date, string): string)=} formatDate Function to format a date object to a\r\n * string. The datepicker directive also provides the time zone, if it was specified.\r\n * @property {(function(Date): string)=} monthHeaderFormatter Function that returns the label for\r\n * a month given a date.\r\n * @property {(function(Date): string)=} monthFormatter Function that returns the full name of a month\r\n * for a given date.\r\n * @property {(function(number): string)=} weekNumberFormatter Function that returns a label for\r\n * a week given the week number.\r\n * @property {(string)=} msgCalendar Translation of the label \"Calendar\" for the current locale.\r\n * @property {(string)=} msgOpenCalendar Translation of the button label \"Open calendar\" for the\r\n * current locale.\r\n * @property {Date=} firstRenderableDate The date from which the datepicker calendar will begin\r\n * rendering. Note that this will be ignored if a minimum date is set. Defaults to January 1st 1880.\r\n * @property {Date=} lastRenderableDate The last date that will be rendered by the datepicker\r\n * calendar. Note that this will be ignored if a maximum date is set. Defaults to January 1st 2130.\r\n *\r\n * @usage\r\n * \r\n * myAppModule.config(function($mdPersianDateLocaleProvider) {\r\n *\r\n * // Example of a French localization.\r\n * $mdPersianDateLocaleProvider.months = ['janvier', 'février', 'mars', ...];\r\n * $mdPersianDateLocaleProvider.shortMonths = ['janv', 'févr', 'mars', ...];\r\n * $mdPersianDateLocaleProvider.days = ['dimanche', 'lundi', 'mardi', ...];\r\n * $mdPersianDateLocaleProvider.shortDays = ['Di', 'Lu', 'Ma', ...];\r\n *\r\n * // Can change week display to start on Monday.\r\n * $mdPersianDateLocaleProvider.firstDayOfWeek = 1;\r\n *\r\n * // Optional.\r\n * $mdPersianDateLocaleProvider.dates = [1, 2, 3, 4, 5, 6, ...];\r\n *\r\n * // Example uses moment.js to parse and format dates.\r\n * $mdPersianDateLocaleProvider.parseDate = function(dateString) {\r\n * var m = moment(dateString, 'L', true);\r\n * return m.isValid() ? m.toDate() : new Date(NaN);\r\n * };\r\n *\r\n * $mdPersianDateLocaleProvider.formatDate = function(date) {\r\n * var m = moment(date);\r\n * return m.isValid() ? m.format('L') : '';\r\n * };\r\n *\r\n * $mdPersianDateLocaleProvider.monthHeaderFormatter = function(date) {\r\n * return myShortMonths[date.getMonth()] + ' ' + date.getFullYear();\r\n * };\r\n *\r\n * // In addition to date display, date components also need localized messages\r\n * // for aria-labels for screen-reader users.\r\n *\r\n * $mdPersianDateLocaleProvider.weekNumberFormatter = function(weekNumber) {\r\n * return 'Semaine ' + weekNumber;\r\n * };\r\n *\r\n * $mdPersianDateLocaleProvider.msgCalendar = 'Calendrier';\r\n * $mdPersianDateLocaleProvider.msgOpenCalendar = 'Ouvrir le calendrier';\r\n *\r\n * // You can also set when your calendar begins and ends.\r\n * $mdPersianDateLocaleProvider.firstRenderableDate = new Date(1776, 6, 4);\r\n * $mdPersianDateLocaleProvider.lastRenderableDate = new Date(2012, 11, 21);\r\n * });\r\n * \r\n *\r\n */\r\n angular.module('angular-material-persian-datepicker').config([\"$provide\", function($provide) {\r\n // TODO(jelbourn): Assert provided values are correctly formatted. Need assertions.\r\n\r\n /** @constructor */\r\n function PersianDateLocaleProvider() {\r\n /** Array of full month names. E.g., ['January', 'Febuary', ...] */\r\n this.months = null;\r\n\r\n /** Array of abbreviated month names. E.g., ['Jan', 'Feb', ...] */\r\n this.shortMonths = null;\r\n\r\n /** Array of full day of the week names. E.g., ['Monday', 'Tuesday', ...] */\r\n this.days = null;\r\n\r\n /** Array of abbreviated dat of the week names. E.g., ['M', 'T', ...] */\r\n this.shortDays = null;\r\n\r\n /** Array of dates of a month (1 - 31). Characters might be different in some locales. */\r\n this.dates = null;\r\n\r\n /** Index of the first day of the week. 0 = Sunday, 1 = Monday, etc. */\r\n this.firstDayOfWeek = 6;\r\n\r\n /**\r\n * Function that converts the date portion of a Date to a string.\r\n * @type {(function(Date): string)}\r\n */\r\n this.formatDate = null;\r\n\r\n /**\r\n * Function that converts a date string to a Date object (the date portion)\r\n * @type {function(string): Date}\r\n */\r\n this.parseDate = null;\r\n\r\n /**\r\n * Function that formats a Date into a month header string.\r\n * @type {function(Date): string}\r\n */\r\n this.monthHeaderFormatter = null;\r\n\r\n /**\r\n * Function that formats a week number into a label for the week.\r\n * @type {function(number): string}\r\n */\r\n this.weekNumberFormatter = null;\r\n\r\n /**\r\n * Function that formats a date into a long aria-label that is read\r\n * when the focused date changes.\r\n * @type {function(Date): string}\r\n */\r\n this.longDateFormatter = null;\r\n\r\n /**\r\n * ARIA label for the calendar \"dialog\" used in the datepicker.\r\n * @type {string}\r\n */\r\n this.msgCalendar = '';\r\n\r\n /**\r\n * ARIA label for the datepicker's \"Open calendar\" buttons.\r\n * @type {string}\r\n */\r\n this.msgOpenCalendar = '';\r\n }\r\n\r\n /**\r\n * Factory function that returns an instance of the dateLocale service.\r\n * @ngInject\r\n * @param $locale\r\n * @returns {DateLocale}\r\n */\r\n PersianDateLocaleProvider.prototype.$get = function($locale, $filter) {\r\n /**\r\n * Default date-to-string formatting function.\r\n * @param {!Date} date\r\n * @param {string=} timezone\r\n * @returns {string}\r\n */\r\n function defaultFormatDate(date, timezone) {\r\n if (!date) {\r\n return '';\r\n }\r\n\r\n // All of the dates created through ng-material *should* be set to midnight.\r\n // If we encounter a date where the localeTime shows at 11pm instead of midnight,\r\n // we have run into an issue with DST where we need to increment the hour by one:\r\n // var d = new Date(1992, 9, 8, 0, 0, 0);\r\n // d.toLocaleString(); // == \"10/7/1992, 11:00:00 PM\"\r\n var localeTime = date.toLocaleTimeString();\r\n var formatDate = date;\r\n if (date.getHours() === 0 &&\r\n (localeTime.indexOf('11:') !== -1 || localeTime.indexOf('23:') !== -1)) {\r\n formatDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 1, 0, 0);\r\n }\r\n\r\n return moment(date).format('jYYYY/jMM/jDD'); // $filter('date')(formatDate, 'M/d/yyyy', timezone);\r\n }\r\n\r\n /**\r\n * Default string-to-date parsing function.\r\n * @param {string} dateString\r\n * @returns {!Date}\r\n */\r\n function defaultParseDate(dateString) {\r\n return moment(dateString, 'jYYYY/jM/jD').toDate();\r\n }\r\n\r\n /**\r\n * Default function to determine whether a string makes sense to be\r\n * parsed to a Date object.\r\n *\r\n * This is very permissive and is just a basic sanity check to ensure that\r\n * things like single integers aren't able to be parsed into dates.\r\n * @param {string} dateString\r\n * @returns {boolean}\r\n */\r\n function defaultIsDateComplete(dateString) {\r\n dateString = dateString.trim();\r\n\r\n // Looks for three chunks of content (either numbers or text) separated\r\n // by delimiters.\r\n var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ \\.,]+|[\\/\\-])){2}([a-zA-Z]{3,}|[0-9]{1,4})$/;\r\n return re.test(dateString);\r\n }\r\n\r\n /**\r\n * Default date-to-string formatter to get a month header.\r\n * @param {!Date} date\r\n * @returns {string}\r\n */\r\n function defaultMonthHeaderFormatter(date) {\r\n var pd = moment(date);\r\n return service.shortMonths[pd.jMonth()] + ' ' + pd.jYear();\r\n }\r\n\r\n /**\r\n * Default formatter for a month.\r\n * @param {!Date} date\r\n * @returns {string}\r\n */\r\n function defaultMonthFormatter(date) {\r\n var pd = moment(date);\r\n return service.months[pd.jMonth()] + ' ' + pd.jYear();\r\n }\r\n\r\n /**\r\n * Default week number formatter.\r\n * @param number\r\n * @returns {string}\r\n */\r\n function defaultWeekNumberFormatter(number) {\r\n return 'هفته ' + number;\r\n }\r\n\r\n /**\r\n * Default formatter for date cell aria-labels.\r\n * @param {!Date} date\r\n * @returns {string}\r\n */\r\n function defaultLongDateFormatter(date) {\r\n // Example: 'Thursday June 18 2015'\r\n var pd = moment(date);\r\n return [\r\n service.days[pd.day()],\r\n service.dates[pd.jDate()],\r\n service.months[pd.jMonth()],\r\n pd.jYear()\r\n ].join(' ');\r\n }\r\n\r\n // The default \"short\" day strings are the first character of each day,\r\n // e.g., \"Monday\" => \"M\".\r\n var defaultShortDays = $locale.DATETIME_FORMATS.SHORTDAY.map(function(day) {\r\n return day.substring(0, 1);\r\n });\r\n\r\n // The default dates are simply the numbers 1 through 31.\r\n var defaultDates = Array(32);\r\n for (var i = 1; i <= 31; i++) {\r\n defaultDates[i] = i;\r\n }\r\n\r\n // Default ARIA messages are in English (US).\r\n var defaultMsgCalendar = 'تقویم';\r\n var defaultMsgOpenCalendar = 'گشودن تقویم';\r\n\r\n // Default start/end dates that are rendered in the calendar.\r\n var defaultFirstRenderableDate = new Date(1880, 0, 1);\r\n var defaultLastRendereableDate = new Date(defaultFirstRenderableDate.getFullYear() + 250, 0, 1);\r\n\r\n var service = {\r\n months: this.months || //$locale.DATETIME_FORMATS.MONTH,\r\n [\r\n \"فروردین\",\r\n \"اردیبهشت\",\r\n \"خرداد\",\r\n \"تیر\",\r\n \"مرداد\",\r\n \"شهریور\",\r\n \"مهر\",\r\n \"آبان\",\r\n \"آذر\",\r\n \"دی\",\r\n \"بهمن\",\r\n \"اسفند\"\r\n ],\r\n shortMonths: this.shortMonths || //$locale.DATETIME_FORMATS.SHORTMONTH,\r\n [\r\n \"فروردین\",\r\n \"اردیبهشت\",\r\n \"خرداد\",\r\n \"تیر\",\r\n \"مرداد\",\r\n \"شهریور\",\r\n \"مهر\",\r\n \"آبان\",\r\n \"آذر\",\r\n \"دی\",\r\n \"بهمن\",\r\n \"اسفند\"\r\n ],\r\n days: this.days || //$locale.DATETIME_FORMATS.DAY,\r\n [\r\n \"یکشنبه\",\r\n \"دوشنبه\",\r\n \"سه‌شنبه\",\r\n \"چهارشنبه\",\r\n \"پنجشنبه\",\r\n \"جمعه\",\r\n \"شنبه\"\r\n ],\r\n shortDays: this.shortDays || //defaultShortDays,\r\n [\r\n \"ی\",\r\n \"د\",\r\n \"س\",\r\n \"چ\",\r\n \"پ\",\r\n \"ج\",\r\n \"ش\"\r\n ],\r\n dates: this.dates || defaultDates,\r\n firstDayOfWeek: this.firstDayOfWeek || 6,\r\n formatDate: this.formatDate || defaultFormatDate,\r\n parseDate: this.parseDate || defaultParseDate,\r\n isDateComplete: this.isDateComplete || defaultIsDateComplete,\r\n monthHeaderFormatter: this.monthHeaderFormatter || defaultMonthHeaderFormatter,\r\n monthFormatter: this.monthFormatter || defaultMonthFormatter,\r\n weekNumberFormatter: this.weekNumberFormatter || defaultWeekNumberFormatter,\r\n longDateFormatter: this.longDateFormatter || defaultLongDateFormatter,\r\n msgCalendar: this.msgCalendar || defaultMsgCalendar,\r\n msgOpenCalendar: this.msgOpenCalendar || defaultMsgOpenCalendar,\r\n firstRenderableDate: this.firstRenderableDate || defaultFirstRenderableDate,\r\n lastRenderableDate: this.lastRenderableDate || defaultLastRendereableDate\r\n };\r\n\r\n return service;\r\n };\r\n PersianDateLocaleProvider.prototype.$get.$inject = [\"$locale\", \"$filter\"];\r\n\r\n $provide.provider('$mdPersianDateLocale', new PersianDateLocaleProvider());\r\n }]);\r\n})();\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\n(function() {\r\n 'use strict';\r\n\r\n // POST RELEASE\r\n // TODO(jelbourn): Demo that uses moment.js\r\n // TODO(jelbourn): make sure this plays well with validation and ngMessages.\r\n // TODO(jelbourn): calendar pane doesn't open up outside of visible viewport.\r\n // TODO(jelbourn): forward more attributes to the internal input (required, autofocus, etc.)\r\n // TODO(jelbourn): something better for mobile (calendar panel takes up entire screen?)\r\n // TODO(jelbourn): input behavior (masking? auto-complete?)\r\n\r\n\r\n PersianDatePickerCtrl.$inject = [\"$scope\", \"$element\", \"$attrs\", \"$window\", \"$mdConstant\", \"$mdTheming\", \"$mdUtil\", \"$mdPersianDateLocale\", \"$$mdPersianDateUtil\", \"$$rAF\", \"$filter\"];\r\n persianDatePickerDirective.$inject = [\"$$mdSvgRegistry\", \"$mdUtil\", \"$mdAria\", \"inputDirective\"];\r\n angular.module('angular-material-persian-datepicker')\r\n .directive('mdPersianDatepicker', persianDatePickerDirective);\r\n\r\n /**\r\n * @ngdoc directive\r\n * @name mdPersianDatepicker\r\n * @module angular-material-persian-datepicker\r\n *\r\n * @param {Date} ng-model The component's model. Expects either a JavaScript Date object or a value that can be parsed into one (e.g. a ISO 8601 string).\r\n * @param {Object=} ng-model-options Allows tuning of the way in which `ng-model` is being updated. Also allows\r\n * for a timezone to be specified. Read more at the ngModelOptions docs.\r\n * @param {expression=} ng-change Expression evaluated when the model value changes.\r\n * @param {expression=} ng-focus Expression evaluated when the input is focused or the calendar is opened.\r\n * @param {expression=} ng-blur Expression evaluated when focus is removed from the input or the calendar is closed.\r\n * @param {boolean=} ng-disabled Whether the datepicker is disabled.\r\n * @param {boolean=} ng-required Whether a value is required for the datepicker.\r\n * @param {Date=} md-min-date Expression representing a min date (inclusive).\r\n * @param {Date=} md-max-date Expression representing a max date (inclusive).\r\n * @param {(function(Date): boolean)=} md-date-filter Function expecting a date and returning a boolean whether it can be selected or not.\r\n * @param {String=} md-placeholder The date input placeholder value.\r\n * @param {String=} md-open-on-focus When present, the calendar will be opened when the input is focused.\r\n * @param {Boolean=} md-is-open Expression that can be used to open the datepicker's calendar on-demand.\r\n * @param {String=} md-current-view Default open view of the calendar pane. Can be either \"month\" or \"year\".\r\n * @param {String=} md-hide-icons Determines which datepicker icons should be hidden. Note that this may cause the\r\n * datepicker to not align properly with other components. **Use at your own risk.** Possible values are:\r\n * * `\"all\"` - Hides all icons.\r\n * * `\"calendar\"` - Only hides the calendar icon.\r\n * * `\"triangle\"` - Only hides the triangle icon.\r\n * @param {Object=} md-date-locale Allows for the values from the `$mdPersianDateLocaleProvider` to be\r\n * ovewritten on a per-element basis (e.g. `msgOpenCalendar` can be overwritten with\r\n * `md-date-locale=\"{ msgOpenCalendar: 'Open a special calendar' }\"`).\r\n *\r\n * @description\r\n * `` is a component used to select a single date.\r\n * For information on how to configure internationalization for the date picker,\r\n * see `$mdPersianDateLocaleProvider`.\r\n *\r\n * This component supports [ngMessages](https://docs.angularjs.org/api/ngMessages/directive/ngMessages).\r\n * Supported attributes are:\r\n * * `required`: whether a required date is not set.\r\n * * `mindate`: whether the selected date is before the minimum allowed date.\r\n * * `maxdate`: whether the selected date is after the maximum allowed date.\r\n * * `debounceInterval`: ms to delay input processing (since last debounce reset); default value 500ms\r\n *\r\n * @usage\r\n * \r\n * \r\n * \r\n *\r\n */\r\n\r\n function persianDatePickerDirective($$mdSvgRegistry, $mdUtil, $mdAria, inputDirective) {\r\n return {\r\n template: function(tElement, tAttrs) {\r\n // Buttons are not in the tab order because users can open the calendar via keyboard\r\n // interaction on the text input, and multiple tab stops for one component (picker)\r\n // may be confusing.\r\n var hiddenIcons = tAttrs.mdHideIcons;\r\n var ariaLabelValue = tAttrs.ariaLabel || tAttrs.mdPlaceholder;\r\n\r\n var calendarButton = (hiddenIcons === 'all' || hiddenIcons === 'calendar') ? '' :\r\n '' +\r\n '' +\r\n '';\r\n\r\n var triangleButton = '';\r\n\r\n if (hiddenIcons !== 'all' && hiddenIcons !== 'triangle') {\r\n triangleButton = '' +\r\n '' +\r\n '
' +\r\n '
';\r\n\r\n tElement.addClass(HAS_TRIANGLE_ICON_CLASS);\r\n }\r\n\r\n return calendarButton +\r\n '
' +\r\n ' ' +\r\n triangleButton +\r\n '
' +\r\n\r\n // This pane will be detached from here and re-attached to the document body.\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
';\r\n },\r\n require: ['ngModel', 'mdPersianDatepicker', '?^mdInputContainer', '?^form'],\r\n scope: {\r\n minDate: '=mdMinDate',\r\n maxDate: '=mdMaxDate',\r\n placeholder: '@mdPlaceholder',\r\n currentView: '@mdCurrentView',\r\n dateFilter: '=mdDateFilter',\r\n isOpen: '=?mdIsOpen',\r\n debounceInterval: '=mdDebounceInterval',\r\n dateLocale: '=mdDateLocale'\r\n },\r\n controller: PersianDatePickerCtrl,\r\n controllerAs: 'ctrl',\r\n bindToController: true,\r\n link: function(scope, element, attr, controllers) {\r\n var ngModelCtrl = controllers[0];\r\n var mdDatePickerCtrl = controllers[1];\r\n var mdInputContainer = controllers[2];\r\n var parentForm = controllers[3];\r\n var mdNoAsterisk = $mdUtil.parseAttributeBoolean(attr.mdNoAsterisk);\r\n\r\n mdDatePickerCtrl.configureNgModel(ngModelCtrl, mdInputContainer, inputDirective);\r\n\r\n if (mdInputContainer) {\r\n // We need to move the spacer after the datepicker itself,\r\n // because md-input-container adds it after the\r\n // md-datepicker-input by default. The spacer gets wrapped in a\r\n // div, because it floats and gets aligned next to the datepicker.\r\n // There are easier ways of working around this with CSS (making the\r\n // datepicker 100% wide, change the `display` etc.), however they\r\n // break the alignment with any other form controls.\r\n var spacer = element[0].querySelector('.md-errors-spacer');\r\n\r\n if (spacer) {\r\n element.after(angular.element('
').append(spacer));\r\n }\r\n\r\n mdInputContainer.setHasPlaceholder(attr.mdPlaceholder);\r\n mdInputContainer.input = element;\r\n mdInputContainer.element\r\n .addClass(INPUT_CONTAINER_CLASS)\r\n .toggleClass(HAS_CALENDAR_ICON_CLASS, attr.mdHideIcons !== 'calendar' && attr.mdHideIcons !== 'all');\r\n\r\n if (!mdInputContainer.label) {\r\n $mdAria.expect(element, 'aria-label', attr.mdPlaceholder);\r\n } else if(!mdNoAsterisk) {\r\n attr.$observe('required', function(value) {\r\n mdInputContainer.label.toggleClass('md-required', !!value);\r\n });\r\n }\r\n\r\n scope.$watch(mdInputContainer.isErrorGetter || function() {\r\n return ngModelCtrl.$invalid && (ngModelCtrl.$touched || (parentForm && parentForm.$submitted));\r\n }, mdInputContainer.setInvalid);\r\n } else if (parentForm) {\r\n // If invalid, highlights the input when the parent form is submitted.\r\n var parentSubmittedWatcher = scope.$watch(function() {\r\n return parentForm.$submitted;\r\n }, function(isSubmitted) {\r\n if (isSubmitted) {\r\n mdDatePickerCtrl.updateErrorState();\r\n parentSubmittedWatcher();\r\n }\r\n });\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** Additional offset for the input's `size` attribute, which is updated based on its content. */\r\n var EXTRA_INPUT_SIZE = 3;\r\n\r\n /** Class applied to the container if the date is invalid. */\r\n var INVALID_CLASS = 'md-datepicker-invalid';\r\n\r\n /** Class applied to the datepicker when it's open. */\r\n var OPEN_CLASS = 'md-datepicker-open';\r\n\r\n /** Class applied to the md-input-container, if a datepicker is placed inside it */\r\n var INPUT_CONTAINER_CLASS = '_md-datepicker-floating-label';\r\n\r\n /** Class to be applied when the calendar icon is enabled. */\r\n var HAS_CALENDAR_ICON_CLASS = '_md-datepicker-has-calendar-icon';\r\n\r\n /** Class to be applied when the triangle icon is enabled. */\r\n var HAS_TRIANGLE_ICON_CLASS = '_md-datepicker-has-triangle-icon';\r\n\r\n /** Default time in ms to debounce input event by. */\r\n var DEFAULT_DEBOUNCE_INTERVAL = 500;\r\n\r\n /**\r\n * Height of the calendar pane used to check if the pane is going outside the boundary of\r\n * the viewport. See calendar.scss for how $md-calendar-height is computed; an extra 20px is\r\n * also added to space the pane away from the exact edge of the screen.\r\n *\r\n * This is computed statically now, but can be changed to be measured if the circumstances\r\n * of calendar sizing are changed.\r\n */\r\n var CALENDAR_PANE_HEIGHT = 368;\r\n\r\n /**\r\n * Width of the calendar pane used to check if the pane is going outside the boundary of\r\n * the viewport. See calendar.scss for how $md-calendar-width is computed; an extra 20px is\r\n * also added to space the pane away from the exact edge of the screen.\r\n *\r\n * This is computed statically now, but can be changed to be measured if the circumstances\r\n * of calendar sizing are changed.\r\n */\r\n var CALENDAR_PANE_WIDTH = 360;\r\n\r\n /** Used for checking whether the current user agent is on iOS or Android. */\r\n var IS_MOBILE_REGEX = /ipad|iphone|ipod|android/i;\r\n\r\n /**\r\n * Controller for md-datepicker.\r\n *\r\n * @ngInject @constructor\r\n */\r\n function PersianDatePickerCtrl($scope, $element, $attrs, $window, $mdConstant,\r\n $mdTheming, $mdUtil, $mdPersianDateLocale, $$mdPersianDateUtil, $$rAF, $filter) {\r\n\r\n /** @final */\r\n this.$window = $window;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final */\r\n this.$mdConstant = $mdConstant;\r\n\r\n /* @final */\r\n this.$mdUtil = $mdUtil;\r\n\r\n /** @final */\r\n this.$$rAF = $$rAF;\r\n\r\n /** @final */\r\n this.$mdPersianDateLocale = $mdPersianDateLocale;\r\n\r\n /**\r\n * The root document element. This is used for attaching a top-level click handler to\r\n * close the calendar panel when a click outside said panel occurs. We use `documentElement`\r\n * instead of body because, when scrolling is disabled, some browsers consider the body element\r\n * to be completely off the screen and propagate events directly to the html element.\r\n * @type {!angular.JQLite}\r\n */\r\n this.documentElement = angular.element(document.documentElement);\r\n\r\n /** @type {!angular.NgModelController} */\r\n this.ngModelCtrl = null;\r\n\r\n /** @type {HTMLInputElement} */\r\n this.inputElement = $element[0].querySelector('input');\r\n\r\n /** @final {!angular.JQLite} */\r\n this.ngInputElement = angular.element(this.inputElement);\r\n\r\n /** @type {HTMLElement} */\r\n this.inputContainer = $element[0].querySelector('.md-datepicker-input-container');\r\n\r\n /** @type {HTMLElement} Floating calendar pane. */\r\n this.calendarPane = $element[0].querySelector('.md-datepicker-calendar-pane');\r\n\r\n /** @type {HTMLElement} Calendar icon button. */\r\n this.calendarButton = $element[0].querySelector('.md-datepicker-button');\r\n\r\n /**\r\n * Element covering everything but the input in the top of the floating calendar pane.\r\n * @type {!angular.JQLite}\r\n */\r\n this.inputMask = angular.element($element[0].querySelector('.md-datepicker-input-mask-opaque'));\r\n\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final {!angular.Attributes} */\r\n this.$attrs = $attrs;\r\n\r\n /** @final {!angular.Scope} */\r\n this.$scope = $scope;\r\n\r\n /** @type {Date} */\r\n this.date = null;\r\n\r\n /** @type {boolean} */\r\n this.isFocused = false;\r\n\r\n /** @type {boolean} */\r\n this.isDisabled;\r\n this.setDisabled($element[0].disabled || angular.isString($attrs.disabled));\r\n\r\n /** @type {boolean} Whether the date-picker's calendar pane is open. */\r\n this.isCalendarOpen = false;\r\n\r\n /** @type {boolean} Whether the calendar should open when the input is focused. */\r\n this.openOnFocus = $attrs.hasOwnProperty('mdOpenOnFocus');\r\n\r\n /** @final */\r\n this.mdInputContainer = null;\r\n\r\n /**\r\n * Element from which the calendar pane was opened. Keep track of this so that we can return\r\n * focus to it when the pane is closed.\r\n * @type {HTMLElement}\r\n */\r\n this.calendarPaneOpenedFrom = null;\r\n\r\n /** @type {String} Unique id for the calendar pane. */\r\n this.calendarPaneId = 'md-date-pane-' + $mdUtil.nextUid();\r\n\r\n /** Pre-bound click handler is saved so that the event listener can be removed. */\r\n this.bodyClickHandler = angular.bind(this, this.handleBodyClick);\r\n\r\n /**\r\n * Name of the event that will trigger a close. Necessary to sniff the browser, because\r\n * the resize event doesn't make sense on mobile and can have a negative impact since it\r\n * triggers whenever the browser zooms in on a focused input.\r\n */\r\n this.windowEventName = IS_MOBILE_REGEX.test(\r\n navigator.userAgent || navigator.vendor || window.opera\r\n ) ? 'orientationchange' : 'resize';\r\n\r\n /** Pre-bound close handler so that the event listener can be removed. */\r\n this.windowEventHandler = $mdUtil.debounce(angular.bind(this, this.closeCalendarPane), 100);\r\n\r\n /** Pre-bound handler for the window blur event. Allows for it to be removed later. */\r\n this.windowBlurHandler = angular.bind(this, this.handleWindowBlur);\r\n\r\n /** The built-in AngularJS date filter. */\r\n this.ngDateFilter = $filter('date');\r\n\r\n /** @type {Number} Extra margin for the left side of the floating calendar pane. */\r\n this.leftMargin = 20;\r\n\r\n /** @type {Number} Extra margin for the top of the floating calendar. Gets determined on the first open. */\r\n this.topMargin = null;\r\n\r\n // Unless the user specifies so, the datepicker should not be a tab stop.\r\n // This is necessary because ngAria might add a tabindex to anything with an ng-model\r\n // (based on whether or not the user has turned that particular feature on/off).\r\n if ($attrs.tabindex) {\r\n this.ngInputElement.attr('tabindex', $attrs.tabindex);\r\n $attrs.$set('tabindex', null);\r\n } else {\r\n $attrs.$set('tabindex', '-1');\r\n }\r\n\r\n $attrs.$set('aria-owns', this.calendarPaneId);\r\n\r\n $mdTheming($element);\r\n $mdTheming(angular.element(this.calendarPane));\r\n\r\n var self = this;\r\n\r\n $scope.$on('$destroy', function() {\r\n self.detachCalendarPane();\r\n });\r\n\r\n if ($attrs.mdIsOpen) {\r\n $scope.$watch('ctrl.isOpen', function(shouldBeOpen) {\r\n if (shouldBeOpen) {\r\n self.openCalendarPane({\r\n target: self.inputElement\r\n });\r\n } else {\r\n self.closeCalendarPane();\r\n }\r\n });\r\n }\r\n\r\n // For AngularJS 1.4 and older, where there are no lifecycle hooks but bindings are pre-assigned,\r\n // manually call the $onInit hook.\r\n if (angular.version.major === 1 && angular.version.minor <= 4) {\r\n this.$onInit();\r\n }\r\n\r\n }\r\n\r\n /**\r\n * AngularJS Lifecycle hook for newer AngularJS versions.\r\n * Bindings are not guaranteed to have been assigned in the controller, but they are in the $onInit hook.\r\n */\r\n PersianDatePickerCtrl.prototype.$onInit = function() {\r\n\r\n /**\r\n * Holds locale-specific formatters, parsers, labels etc. Allows\r\n * the user to override specific ones from the $mdPersianDateLocale provider.\r\n * @type {!Object}\r\n */\r\n this.locale = this.dateLocale ? angular.extend({}, this.$mdPersianDateLocale, this.dateLocale) : this.$mdPersianDateLocale;\r\n\r\n this.installPropertyInterceptors();\r\n this.attachChangeListeners();\r\n this.attachInteractionListeners();\r\n };\r\n\r\n /**\r\n * Sets up the controller's reference to ngModelController and\r\n * applies AngularJS's `input[type=\"date\"]` directive.\r\n * @param {!angular.NgModelController} ngModelCtrl Instance of the ngModel controller.\r\n * @param {Object} mdInputContainer Instance of the mdInputContainer controller.\r\n * @param {Object} inputDirective Config for AngularJS's `input` directive.\r\n */\r\n PersianDatePickerCtrl.prototype.configureNgModel = function(ngModelCtrl, mdInputContainer, inputDirective) {\r\n this.ngModelCtrl = ngModelCtrl;\r\n this.mdInputContainer = mdInputContainer;\r\n\r\n // The input needs to be [type=\"date\"] in order to be picked up by AngularJS.\r\n this.$attrs.$set('type', 'date');\r\n\r\n // Invoke the `input` directive link function, adding a stub for the element.\r\n // This allows us to re-use AngularJS's logic for setting the timezone via ng-model-options.\r\n // It works by calling the link function directly which then adds the proper `$parsers` and\r\n // `$formatters` to the ngModel controller.\r\n inputDirective[0].link.pre(this.$scope, {\r\n on: angular.noop,\r\n val: angular.noop,\r\n 0: {}\r\n }, this.$attrs, [ngModelCtrl]);\r\n\r\n var self = this;\r\n\r\n // Responds to external changes to the model value.\r\n self.ngModelCtrl.$formatters.push(function(value) {\r\n var parsedValue = angular.isDefined(value) ? Date.parse(value) : null;\r\n\r\n // `parsedValue` is the time since epoch if valid or `NaN` if invalid.\r\n if (!isNaN(parsedValue) && angular.isNumber(parsedValue)) {\r\n value = new Date(parsedValue);\r\n }\r\n\r\n if (value && !(value instanceof Date)) {\r\n throw Error(\r\n 'The ng-model for md-datepicker must be a Date instance or a value ' +\r\n 'that can be parsed into a date. Currently the model is of type: ' + typeof value\r\n );\r\n }\r\n\r\n self.onExternalChange(value);\r\n\r\n return value;\r\n });\r\n\r\n // Responds to external error state changes (e.g. ng-required based on another input).\r\n ngModelCtrl.$viewChangeListeners.unshift(angular.bind(this, this.updateErrorState));\r\n\r\n // Forwards any events from the input to the root element. This is necessary to get `updateOn`\r\n // working for events that don't bubble (e.g. 'blur') since AngularJS binds the handlers to\r\n // the ``.\r\n var updateOn = self.$mdUtil.getModelOption(ngModelCtrl, 'updateOn');\r\n\r\n if (updateOn) {\r\n this.ngInputElement.on(\r\n updateOn,\r\n angular.bind(this.$element, this.$element.triggerHandler, updateOn)\r\n );\r\n }\r\n };\r\n\r\n /**\r\n * Attach event listeners for both the text input and the md-persian-calendar.\r\n * Events are used instead of ng-model so that updates don't infinitely update the other\r\n * on a change. This should also be more performant than using a $watch.\r\n */\r\n PersianDatePickerCtrl.prototype.attachChangeListeners = function() {\r\n var self = this;\r\n\r\n self.$scope.$on('md-calendar-change', function(event, date) {\r\n self.setModelValue(date);\r\n self.onExternalChange(date);\r\n self.closeCalendarPane();\r\n });\r\n\r\n self.ngInputElement.on('input', angular.bind(self, self.resizeInputElement));\r\n\r\n var debounceInterval = angular.isDefined(this.debounceInterval) ?\r\n this.debounceInterval : DEFAULT_DEBOUNCE_INTERVAL;\r\n self.ngInputElement.on('input', self.$mdUtil.debounce(self.handleInputEvent,\r\n debounceInterval, self));\r\n };\r\n\r\n /** Attach event listeners for user interaction. */\r\n PersianDatePickerCtrl.prototype.attachInteractionListeners = function() {\r\n var self = this;\r\n var $scope = this.$scope;\r\n var keyCodes = this.$mdConstant.KEY_CODE;\r\n\r\n // Add event listener through angular so that we can triggerHandler in unit tests.\r\n self.ngInputElement.on('keydown', function(event) {\r\n if (event.altKey && event.keyCode == keyCodes.DOWN_ARROW) {\r\n self.openCalendarPane(event);\r\n $scope.$digest();\r\n }\r\n });\r\n\r\n if (self.openOnFocus) {\r\n self.ngInputElement.on('focus', angular.bind(self, self.openCalendarPane));\r\n angular.element(self.$window).on('blur', self.windowBlurHandler);\r\n\r\n $scope.$on('$destroy', function() {\r\n angular.element(self.$window).off('blur', self.windowBlurHandler);\r\n });\r\n }\r\n\r\n $scope.$on('md-calendar-close', function() {\r\n self.closeCalendarPane();\r\n });\r\n };\r\n\r\n /**\r\n * Capture properties set to the date-picker and imperitively handle internal changes.\r\n * This is done to avoid setting up additional $watches.\r\n */\r\n PersianDatePickerCtrl.prototype.installPropertyInterceptors = function() {\r\n var self = this;\r\n\r\n if (this.$attrs.ngDisabled) {\r\n // The expression is to be evaluated against the directive element's scope and not\r\n // the directive's isolate scope.\r\n var scope = this.$scope.$parent;\r\n\r\n if (scope) {\r\n scope.$watch(this.$attrs.ngDisabled, function(isDisabled) {\r\n self.setDisabled(isDisabled);\r\n });\r\n }\r\n }\r\n\r\n Object.defineProperty(this, 'placeholder', {\r\n get: function() { return self.inputElement.placeholder; },\r\n set: function(value) { self.inputElement.placeholder = value || ''; }\r\n });\r\n };\r\n\r\n /**\r\n * Sets whether the date-picker is disabled.\r\n * @param {boolean} isDisabled\r\n */\r\n PersianDatePickerCtrl.prototype.setDisabled = function(isDisabled) {\r\n this.isDisabled = isDisabled;\r\n this.inputElement.disabled = isDisabled;\r\n\r\n if (this.calendarButton) {\r\n this.calendarButton.disabled = isDisabled;\r\n }\r\n };\r\n\r\n /**\r\n * Sets the custom ngModel.$error flags to be consumed by ngMessages. Flags are:\r\n * - mindate: whether the selected date is before the minimum date.\r\n * - maxdate: whether the selected flag is after the maximum date.\r\n * - filtered: whether the selected date is allowed by the custom filtering function.\r\n * - valid: whether the entered text input is a valid date\r\n *\r\n * The 'required' flag is handled automatically by ngModel.\r\n *\r\n * @param {Date=} opt_date Date to check. If not given, defaults to the datepicker's model value.\r\n */\r\n PersianDatePickerCtrl.prototype.updateErrorState = function(opt_date) {\r\n var date = opt_date || this.date;\r\n\r\n // Clear any existing errors to get rid of anything that's no longer relevant.\r\n this.clearErrorState();\r\n\r\n if (this.dateUtil.isValidDate(date)) {\r\n // Force all dates to midnight in order to ignore the time portion.\r\n date = this.dateUtil.createDateAtMidnight(date);\r\n\r\n if (this.dateUtil.isValidDate(this.minDate)) {\r\n var minDate = this.dateUtil.createDateAtMidnight(this.minDate);\r\n this.ngModelCtrl.$setValidity('mindate', date >= minDate);\r\n }\r\n\r\n if (this.dateUtil.isValidDate(this.maxDate)) {\r\n var maxDate = this.dateUtil.createDateAtMidnight(this.maxDate);\r\n this.ngModelCtrl.$setValidity('maxdate', date <= maxDate);\r\n }\r\n\r\n if (angular.isFunction(this.dateFilter)) {\r\n this.ngModelCtrl.$setValidity('filtered', this.dateFilter(date));\r\n }\r\n } else {\r\n // The date is seen as \"not a valid date\" if there is *something* set\r\n // (i.e.., not null or undefined), but that something isn't a valid date.\r\n this.ngModelCtrl.$setValidity('valid', date == null);\r\n }\r\n\r\n angular.element(this.inputContainer).toggleClass(INVALID_CLASS, !this.ngModelCtrl.$valid);\r\n };\r\n\r\n /** Clears any error flags set by `updateErrorState`. */\r\n PersianDatePickerCtrl.prototype.clearErrorState = function() {\r\n this.inputContainer.classList.remove(INVALID_CLASS);\r\n ['mindate', 'maxdate', 'filtered', 'valid'].forEach(function(field) {\r\n this.ngModelCtrl.$setValidity(field, true);\r\n }, this);\r\n };\r\n\r\n /** Resizes the input element based on the size of its content. */\r\n PersianDatePickerCtrl.prototype.resizeInputElement = function() {\r\n this.inputElement.size = this.inputElement.value.length + EXTRA_INPUT_SIZE;\r\n };\r\n\r\n /**\r\n * Sets the model value if the user input is a valid date.\r\n * Adds an invalid class to the input element if not.\r\n */\r\n PersianDatePickerCtrl.prototype.handleInputEvent = function() {\r\n var inputString = this.inputElement.value;\r\n var parsedDate = inputString ? this.locale.parseDate(inputString) : null;\r\n this.dateUtil.setDateTimeToMidnight(parsedDate);\r\n\r\n // An input string is valid if it is either empty (representing no date)\r\n // or if it parses to a valid date that the user is allowed to select.\r\n var isValidInput = inputString == '' || (\r\n this.dateUtil.isValidDate(parsedDate) &&\r\n this.locale.isDateComplete(inputString) &&\r\n this.isDateEnabled(parsedDate)\r\n );\r\n\r\n // The datepicker's model is only updated when there is a valid input.\r\n if (isValidInput) {\r\n this.setModelValue(parsedDate);\r\n this.date = parsedDate;\r\n }\r\n\r\n this.updateErrorState(parsedDate);\r\n };\r\n\r\n /**\r\n * Check whether date is in range and enabled\r\n * @param {Date=} opt_date\r\n * @return {boolean} Whether the date is enabled.\r\n */\r\n PersianDatePickerCtrl.prototype.isDateEnabled = function(opt_date) {\r\n return this.dateUtil.isDateWithinRange(opt_date, this.minDate, this.maxDate) &&\r\n (!angular.isFunction(this.dateFilter) || this.dateFilter(opt_date));\r\n };\r\n\r\n /** Position and attach the floating calendar to the document. */\r\n PersianDatePickerCtrl.prototype.attachCalendarPane = function() {\r\n var calendarPane = this.calendarPane;\r\n var body = document.body;\r\n\r\n calendarPane.style.transform = '';\r\n this.$element.addClass(OPEN_CLASS);\r\n this.mdInputContainer && this.mdInputContainer.element.addClass(OPEN_CLASS);\r\n angular.element(body).addClass('md-datepicker-is-showing');\r\n\r\n var elementRect = this.inputContainer.getBoundingClientRect();\r\n var bodyRect = body.getBoundingClientRect();\r\n\r\n if (!this.topMargin || this.topMargin < 0) {\r\n this.topMargin = (this.inputMask.parent().prop('clientHeight') - this.ngInputElement.prop('clientHeight')) / 2;\r\n }\r\n\r\n // Check to see if the calendar pane would go off the screen. If so, adjust position\r\n // accordingly to keep it within the viewport.\r\n var paneTop = elementRect.top - bodyRect.top - this.topMargin;\r\n var paneLeft = elementRect.left - bodyRect.left - this.leftMargin;\r\n\r\n // If ng-material has disabled body scrolling (for example, if a dialog is open),\r\n // then it's possible that the already-scrolled body has a negative top/left. In this case,\r\n // we want to treat the \"real\" top as (0 - bodyRect.top). In a normal scrolling situation,\r\n // though, the top of the viewport should just be the body's scroll position.\r\n var viewportTop = (bodyRect.top < 0 && document.body.scrollTop == 0) ?\r\n -bodyRect.top :\r\n document.body.scrollTop;\r\n\r\n var viewportLeft = (bodyRect.left < 0 && document.body.scrollLeft == 0) ?\r\n -bodyRect.left :\r\n document.body.scrollLeft;\r\n\r\n var viewportBottom = viewportTop + this.$window.innerHeight;\r\n var viewportRight = viewportLeft + this.$window.innerWidth;\r\n\r\n // Creates an overlay with a hole the same size as element. We remove a pixel or two\r\n // on each end to make it overlap slightly. The overlay's background is added in\r\n // the theme in the form of a box-shadow with a huge spread.\r\n this.inputMask.css({\r\n position: 'absolute',\r\n left: this.leftMargin + 'px',\r\n top: this.topMargin + 'px',\r\n width: (elementRect.width - 1) + 'px',\r\n height: (elementRect.height - 2) + 'px'\r\n });\r\n\r\n // If the right edge of the pane would be off the screen and shifting it left by the\r\n // difference would not go past the left edge of the screen. If the calendar pane is too\r\n // big to fit on the screen at all, move it to the left of the screen and scale the entire\r\n // element down to fit.\r\n if (paneLeft + CALENDAR_PANE_WIDTH > viewportRight) {\r\n if (viewportRight - CALENDAR_PANE_WIDTH > 0) {\r\n paneLeft = viewportRight - CALENDAR_PANE_WIDTH;\r\n } else {\r\n paneLeft = viewportLeft;\r\n var scale = this.$window.innerWidth / CALENDAR_PANE_WIDTH;\r\n calendarPane.style.transform = 'scale(' + scale + ')';\r\n }\r\n\r\n calendarPane.classList.add('md-datepicker-pos-adjusted');\r\n }\r\n\r\n // If the bottom edge of the pane would be off the screen and shifting it up by the\r\n // difference would not go past the top edge of the screen.\r\n if (paneTop + CALENDAR_PANE_HEIGHT > viewportBottom &&\r\n viewportBottom - CALENDAR_PANE_HEIGHT > viewportTop) {\r\n paneTop = viewportBottom - CALENDAR_PANE_HEIGHT;\r\n calendarPane.classList.add('md-datepicker-pos-adjusted');\r\n }\r\n\r\n calendarPane.style.left = paneLeft + 'px';\r\n calendarPane.style.top = paneTop + 'px';\r\n document.body.appendChild(calendarPane);\r\n\r\n // Add CSS class after one frame to trigger open animation.\r\n this.$$rAF(function() {\r\n calendarPane.classList.add('md-pane-open');\r\n });\r\n };\r\n\r\n /** Detach the floating calendar pane from the document. */\r\n PersianDatePickerCtrl.prototype.detachCalendarPane = function() {\r\n this.$element.removeClass(OPEN_CLASS);\r\n this.mdInputContainer && this.mdInputContainer.element.removeClass(OPEN_CLASS);\r\n angular.element(document.body).removeClass('md-datepicker-is-showing');\r\n this.calendarPane.classList.remove('md-pane-open');\r\n this.calendarPane.classList.remove('md-datepicker-pos-adjusted');\r\n\r\n if (this.isCalendarOpen) {\r\n this.$mdUtil.enableScrolling();\r\n }\r\n\r\n if (this.calendarPane.parentNode) {\r\n // Use native DOM removal because we do not want any of the\r\n // angular state of this element to be disposed.\r\n this.calendarPane.parentNode.removeChild(this.calendarPane);\r\n }\r\n };\r\n\r\n /**\r\n * Open the floating calendar pane.\r\n * @param {Event} event\r\n */\r\n PersianDatePickerCtrl.prototype.openCalendarPane = function(event) {\r\n if (!this.isCalendarOpen && !this.isDisabled && !this.inputFocusedOnWindowBlur) {\r\n this.isCalendarOpen = this.isOpen = true;\r\n this.calendarPaneOpenedFrom = event.target;\r\n\r\n // Because the calendar pane is attached directly to the body, it is possible that the\r\n // rest of the component (input, etc) is in a different scrolling container, such as\r\n // an md-content. This means that, if the container is scrolled, the pane would remain\r\n // stationary. To remedy this, we disable scrolling while the calendar pane is open, which\r\n // also matches the native behavior for things like ` ' +\r\n triangleButton +\r\n '
' +\r\n\r\n // This pane will be detached from here and re-attached to the document body.\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '' +\r\n '' +\r\n '
' +\r\n '
';\r\n },\r\n require: ['ngModel', 'mdPersianDatepicker', '?^mdInputContainer', '?^form'],\r\n scope: {\r\n minDate: '=mdMinDate',\r\n maxDate: '=mdMaxDate',\r\n placeholder: '@mdPlaceholder',\r\n currentView: '@mdCurrentView',\r\n dateFilter: '=mdDateFilter',\r\n isOpen: '=?mdIsOpen',\r\n debounceInterval: '=mdDebounceInterval',\r\n dateLocale: '=mdDateLocale'\r\n },\r\n controller: PersianDatePickerCtrl,\r\n controllerAs: 'ctrl',\r\n bindToController: true,\r\n link: function(scope, element, attr, controllers) {\r\n var ngModelCtrl = controllers[0];\r\n var mdDatePickerCtrl = controllers[1];\r\n var mdInputContainer = controllers[2];\r\n var parentForm = controllers[3];\r\n var mdNoAsterisk = $mdUtil.parseAttributeBoolean(attr.mdNoAsterisk);\r\n\r\n mdDatePickerCtrl.configureNgModel(ngModelCtrl, mdInputContainer, inputDirective);\r\n\r\n if (mdInputContainer) {\r\n // We need to move the spacer after the datepicker itself,\r\n // because md-input-container adds it after the\r\n // md-datepicker-input by default. The spacer gets wrapped in a\r\n // div, because it floats and gets aligned next to the datepicker.\r\n // There are easier ways of working around this with CSS (making the\r\n // datepicker 100% wide, change the `display` etc.), however they\r\n // break the alignment with any other form controls.\r\n var spacer = element[0].querySelector('.md-errors-spacer');\r\n\r\n if (spacer) {\r\n element.after(angular.element('
').append(spacer));\r\n }\r\n\r\n mdInputContainer.setHasPlaceholder(attr.mdPlaceholder);\r\n mdInputContainer.input = element;\r\n mdInputContainer.element\r\n .addClass(INPUT_CONTAINER_CLASS)\r\n .toggleClass(HAS_CALENDAR_ICON_CLASS, attr.mdHideIcons !== 'calendar' && attr.mdHideIcons !== 'all');\r\n\r\n if (!mdInputContainer.label) {\r\n $mdAria.expect(element, 'aria-label', attr.mdPlaceholder);\r\n } else if(!mdNoAsterisk) {\r\n attr.$observe('required', function(value) {\r\n mdInputContainer.label.toggleClass('md-required', !!value);\r\n });\r\n }\r\n\r\n scope.$watch(mdInputContainer.isErrorGetter || function() {\r\n return ngModelCtrl.$invalid && (ngModelCtrl.$touched || (parentForm && parentForm.$submitted));\r\n }, mdInputContainer.setInvalid);\r\n } else if (parentForm) {\r\n // If invalid, highlights the input when the parent form is submitted.\r\n var parentSubmittedWatcher = scope.$watch(function() {\r\n return parentForm.$submitted;\r\n }, function(isSubmitted) {\r\n if (isSubmitted) {\r\n mdDatePickerCtrl.updateErrorState();\r\n parentSubmittedWatcher();\r\n }\r\n });\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** Additional offset for the input's `size` attribute, which is updated based on its content. */\r\n var EXTRA_INPUT_SIZE = 3;\r\n\r\n /** Class applied to the container if the date is invalid. */\r\n var INVALID_CLASS = 'md-datepicker-invalid';\r\n\r\n /** Class applied to the datepicker when it's open. */\r\n var OPEN_CLASS = 'md-datepicker-open';\r\n\r\n /** Class applied to the md-input-container, if a datepicker is placed inside it */\r\n var INPUT_CONTAINER_CLASS = '_md-datepicker-floating-label';\r\n\r\n /** Class to be applied when the calendar icon is enabled. */\r\n var HAS_CALENDAR_ICON_CLASS = '_md-datepicker-has-calendar-icon';\r\n\r\n /** Class to be applied when the triangle icon is enabled. */\r\n var HAS_TRIANGLE_ICON_CLASS = '_md-datepicker-has-triangle-icon';\r\n\r\n /** Default time in ms to debounce input event by. */\r\n var DEFAULT_DEBOUNCE_INTERVAL = 500;\r\n\r\n /**\r\n * Height of the calendar pane used to check if the pane is going outside the boundary of\r\n * the viewport. See calendar.scss for how $md-calendar-height is computed; an extra 20px is\r\n * also added to space the pane away from the exact edge of the screen.\r\n *\r\n * This is computed statically now, but can be changed to be measured if the circumstances\r\n * of calendar sizing are changed.\r\n */\r\n var CALENDAR_PANE_HEIGHT = 368;\r\n\r\n /**\r\n * Width of the calendar pane used to check if the pane is going outside the boundary of\r\n * the viewport. See calendar.scss for how $md-calendar-width is computed; an extra 20px is\r\n * also added to space the pane away from the exact edge of the screen.\r\n *\r\n * This is computed statically now, but can be changed to be measured if the circumstances\r\n * of calendar sizing are changed.\r\n */\r\n var CALENDAR_PANE_WIDTH = 360;\r\n\r\n /** Used for checking whether the current user agent is on iOS or Android. */\r\n var IS_MOBILE_REGEX = /ipad|iphone|ipod|android/i;\r\n\r\n /**\r\n * Controller for md-datepicker.\r\n *\r\n * @ngInject @constructor\r\n */\r\n function PersianDatePickerCtrl($scope, $element, $attrs, $window, $mdConstant,\r\n $mdTheming, $mdUtil, $mdPersianDateLocale, $$mdPersianDateUtil, $$rAF, $filter) {\r\n\r\n /** @final */\r\n this.$window = $window;\r\n\r\n /** @final */\r\n this.dateUtil = $$mdPersianDateUtil;\r\n\r\n /** @final */\r\n this.$mdConstant = $mdConstant;\r\n\r\n /* @final */\r\n this.$mdUtil = $mdUtil;\r\n\r\n /** @final */\r\n this.$$rAF = $$rAF;\r\n\r\n /** @final */\r\n this.$mdPersianDateLocale = $mdPersianDateLocale;\r\n\r\n /**\r\n * The root document element. This is used for attaching a top-level click handler to\r\n * close the calendar panel when a click outside said panel occurs. We use `documentElement`\r\n * instead of body because, when scrolling is disabled, some browsers consider the body element\r\n * to be completely off the screen and propagate events directly to the html element.\r\n * @type {!angular.JQLite}\r\n */\r\n this.documentElement = angular.element(document.documentElement);\r\n\r\n /** @type {!angular.NgModelController} */\r\n this.ngModelCtrl = null;\r\n\r\n /** @type {HTMLInputElement} */\r\n this.inputElement = $element[0].querySelector('input');\r\n\r\n /** @final {!angular.JQLite} */\r\n this.ngInputElement = angular.element(this.inputElement);\r\n\r\n /** @type {HTMLElement} */\r\n this.inputContainer = $element[0].querySelector('.md-datepicker-input-container');\r\n\r\n /** @type {HTMLElement} Floating calendar pane. */\r\n this.calendarPane = $element[0].querySelector('.md-datepicker-calendar-pane');\r\n\r\n /** @type {HTMLElement} Calendar icon button. */\r\n this.calendarButton = $element[0].querySelector('.md-datepicker-button');\r\n\r\n /**\r\n * Element covering everything but the input in the top of the floating calendar pane.\r\n * @type {!angular.JQLite}\r\n */\r\n this.inputMask = angular.element($element[0].querySelector('.md-datepicker-input-mask-opaque'));\r\n\r\n /** @final {!angular.JQLite} */\r\n this.$element = $element;\r\n\r\n /** @final {!angular.Attributes} */\r\n this.$attrs = $attrs;\r\n\r\n /** @final {!angular.Scope} */\r\n this.$scope = $scope;\r\n\r\n /** @type {Date} */\r\n this.date = null;\r\n\r\n /** @type {boolean} */\r\n this.isFocused = false;\r\n\r\n /** @type {boolean} */\r\n this.isDisabled;\r\n this.setDisabled($element[0].disabled || angular.isString($attrs.disabled));\r\n\r\n /** @type {boolean} Whether the date-picker's calendar pane is open. */\r\n this.isCalendarOpen = false;\r\n\r\n /** @type {boolean} Whether the calendar should open when the input is focused. */\r\n this.openOnFocus = $attrs.hasOwnProperty('mdOpenOnFocus');\r\n\r\n /** @final */\r\n this.mdInputContainer = null;\r\n\r\n /**\r\n * Element from which the calendar pane was opened. Keep track of this so that we can return\r\n * focus to it when the pane is closed.\r\n * @type {HTMLElement}\r\n */\r\n this.calendarPaneOpenedFrom = null;\r\n\r\n /** @type {String} Unique id for the calendar pane. */\r\n this.calendarPaneId = 'md-date-pane-' + $mdUtil.nextUid();\r\n\r\n /** Pre-bound click handler is saved so that the event listener can be removed. */\r\n this.bodyClickHandler = angular.bind(this, this.handleBodyClick);\r\n\r\n /**\r\n * Name of the event that will trigger a close. Necessary to sniff the browser, because\r\n * the resize event doesn't make sense on mobile and can have a negative impact since it\r\n * triggers whenever the browser zooms in on a focused input.\r\n */\r\n this.windowEventName = IS_MOBILE_REGEX.test(\r\n navigator.userAgent || navigator.vendor || window.opera\r\n ) ? 'orientationchange' : 'resize';\r\n\r\n /** Pre-bound close handler so that the event listener can be removed. */\r\n this.windowEventHandler = $mdUtil.debounce(angular.bind(this, this.closeCalendarPane), 100);\r\n\r\n /** Pre-bound handler for the window blur event. Allows for it to be removed later. */\r\n this.windowBlurHandler = angular.bind(this, this.handleWindowBlur);\r\n\r\n /** The built-in AngularJS date filter. */\r\n this.ngDateFilter = $filter('date');\r\n\r\n /** @type {Number} Extra margin for the left side of the floating calendar pane. */\r\n this.leftMargin = 20;\r\n\r\n /** @type {Number} Extra margin for the top of the floating calendar. Gets determined on the first open. */\r\n this.topMargin = null;\r\n\r\n // Unless the user specifies so, the datepicker should not be a tab stop.\r\n // This is necessary because ngAria might add a tabindex to anything with an ng-model\r\n // (based on whether or not the user has turned that particular feature on/off).\r\n if ($attrs.tabindex) {\r\n this.ngInputElement.attr('tabindex', $attrs.tabindex);\r\n $attrs.$set('tabindex', null);\r\n } else {\r\n $attrs.$set('tabindex', '-1');\r\n }\r\n\r\n $attrs.$set('aria-owns', this.calendarPaneId);\r\n\r\n $mdTheming($element);\r\n $mdTheming(angular.element(this.calendarPane));\r\n\r\n var self = this;\r\n\r\n $scope.$on('$destroy', function() {\r\n self.detachCalendarPane();\r\n });\r\n\r\n if ($attrs.mdIsOpen) {\r\n $scope.$watch('ctrl.isOpen', function(shouldBeOpen) {\r\n if (shouldBeOpen) {\r\n self.openCalendarPane({\r\n target: self.inputElement\r\n });\r\n } else {\r\n self.closeCalendarPane();\r\n }\r\n });\r\n }\r\n\r\n // For AngularJS 1.4 and older, where there are no lifecycle hooks but bindings are pre-assigned,\r\n // manually call the $onInit hook.\r\n if (angular.version.major === 1 && angular.version.minor <= 4) {\r\n this.$onInit();\r\n }\r\n\r\n }\r\n\r\n /**\r\n * AngularJS Lifecycle hook for newer AngularJS versions.\r\n * Bindings are not guaranteed to have been assigned in the controller, but they are in the $onInit hook.\r\n */\r\n PersianDatePickerCtrl.prototype.$onInit = function() {\r\n\r\n /**\r\n * Holds locale-specific formatters, parsers, labels etc. Allows\r\n * the user to override specific ones from the $mdPersianDateLocale provider.\r\n * @type {!Object}\r\n */\r\n this.locale = this.dateLocale ? angular.extend({}, this.$mdPersianDateLocale, this.dateLocale) : this.$mdPersianDateLocale;\r\n\r\n this.installPropertyInterceptors();\r\n this.attachChangeListeners();\r\n this.attachInteractionListeners();\r\n };\r\n\r\n /**\r\n * Sets up the controller's reference to ngModelController and\r\n * applies AngularJS's `input[type=\"date\"]` directive.\r\n * @param {!angular.NgModelController} ngModelCtrl Instance of the ngModel controller.\r\n * @param {Object} mdInputContainer Instance of the mdInputContainer controller.\r\n * @param {Object} inputDirective Config for AngularJS's `input` directive.\r\n */\r\n PersianDatePickerCtrl.prototype.configureNgModel = function(ngModelCtrl, mdInputContainer, inputDirective) {\r\n this.ngModelCtrl = ngModelCtrl;\r\n this.mdInputContainer = mdInputContainer;\r\n\r\n // The input needs to be [type=\"date\"] in order to be picked up by AngularJS.\r\n this.$attrs.$set('type', 'date');\r\n\r\n // Invoke the `input` directive link function, adding a stub for the element.\r\n // This allows us to re-use AngularJS's logic for setting the timezone via ng-model-options.\r\n // It works by calling the link function directly which then adds the proper `$parsers` and\r\n // `$formatters` to the ngModel controller.\r\n inputDirective[0].link.pre(this.$scope, {\r\n on: angular.noop,\r\n val: angular.noop,\r\n 0: {}\r\n }, this.$attrs, [ngModelCtrl]);\r\n\r\n var self = this;\r\n\r\n // Responds to external changes to the model value.\r\n self.ngModelCtrl.$formatters.push(function(value) {\r\n var parsedValue = angular.isDefined(value) ? Date.parse(value) : null;\r\n\r\n // `parsedValue` is the time since epoch if valid or `NaN` if invalid.\r\n if (!isNaN(parsedValue) && angular.isNumber(parsedValue)) {\r\n value = new Date(parsedValue);\r\n }\r\n\r\n if (value && !(value instanceof Date)) {\r\n throw Error(\r\n 'The ng-model for md-datepicker must be a Date instance or a value ' +\r\n 'that can be parsed into a date. Currently the model is of type: ' + typeof value\r\n );\r\n }\r\n\r\n self.onExternalChange(value);\r\n\r\n return value;\r\n });\r\n\r\n // Responds to external error state changes (e.g. ng-required based on another input).\r\n ngModelCtrl.$viewChangeListeners.unshift(angular.bind(this, this.updateErrorState));\r\n\r\n // Forwards any events from the input to the root element. This is necessary to get `updateOn`\r\n // working for events that don't bubble (e.g. 'blur') since AngularJS binds the handlers to\r\n // the ``.\r\n var updateOn = self.$mdUtil.getModelOption(ngModelCtrl, 'updateOn');\r\n\r\n if (updateOn) {\r\n this.ngInputElement.on(\r\n updateOn,\r\n angular.bind(this.$element, this.$element.triggerHandler, updateOn)\r\n );\r\n }\r\n };\r\n\r\n /**\r\n * Attach event listeners for both the text input and the md-persian-calendar.\r\n * Events are used instead of ng-model so that updates don't infinitely update the other\r\n * on a change. This should also be more performant than using a $watch.\r\n */\r\n PersianDatePickerCtrl.prototype.attachChangeListeners = function() {\r\n var self = this;\r\n\r\n self.$scope.$on('md-calendar-change', function(event, date) {\r\n self.setModelValue(date);\r\n self.onExternalChange(date);\r\n self.closeCalendarPane();\r\n });\r\n\r\n self.ngInputElement.on('input', angular.bind(self, self.resizeInputElement));\r\n\r\n var debounceInterval = angular.isDefined(this.debounceInterval) ?\r\n this.debounceInterval : DEFAULT_DEBOUNCE_INTERVAL;\r\n self.ngInputElement.on('input', self.$mdUtil.debounce(self.handleInputEvent,\r\n debounceInterval, self));\r\n };\r\n\r\n /** Attach event listeners for user interaction. */\r\n PersianDatePickerCtrl.prototype.attachInteractionListeners = function() {\r\n var self = this;\r\n var $scope = this.$scope;\r\n var keyCodes = this.$mdConstant.KEY_CODE;\r\n\r\n // Add event listener through angular so that we can triggerHandler in unit tests.\r\n self.ngInputElement.on('keydown', function(event) {\r\n if (event.altKey && event.keyCode == keyCodes.DOWN_ARROW) {\r\n self.openCalendarPane(event);\r\n $scope.$digest();\r\n }\r\n });\r\n\r\n if (self.openOnFocus) {\r\n self.ngInputElement.on('focus', angular.bind(self, self.openCalendarPane));\r\n angular.element(self.$window).on('blur', self.windowBlurHandler);\r\n\r\n $scope.$on('$destroy', function() {\r\n angular.element(self.$window).off('blur', self.windowBlurHandler);\r\n });\r\n }\r\n\r\n $scope.$on('md-calendar-close', function() {\r\n self.closeCalendarPane();\r\n });\r\n };\r\n\r\n /**\r\n * Capture properties set to the date-picker and imperitively handle internal changes.\r\n * This is done to avoid setting up additional $watches.\r\n */\r\n PersianDatePickerCtrl.prototype.installPropertyInterceptors = function() {\r\n var self = this;\r\n\r\n if (this.$attrs.ngDisabled) {\r\n // The expression is to be evaluated against the directive element's scope and not\r\n // the directive's isolate scope.\r\n var scope = this.$scope.$parent;\r\n\r\n if (scope) {\r\n scope.$watch(this.$attrs.ngDisabled, function(isDisabled) {\r\n self.setDisabled(isDisabled);\r\n });\r\n }\r\n }\r\n\r\n Object.defineProperty(this, 'placeholder', {\r\n get: function() { return self.inputElement.placeholder; },\r\n set: function(value) { self.inputElement.placeholder = value || ''; }\r\n });\r\n };\r\n\r\n /**\r\n * Sets whether the date-picker is disabled.\r\n * @param {boolean} isDisabled\r\n */\r\n PersianDatePickerCtrl.prototype.setDisabled = function(isDisabled) {\r\n this.isDisabled = isDisabled;\r\n this.inputElement.disabled = isDisabled;\r\n\r\n if (this.calendarButton) {\r\n this.calendarButton.disabled = isDisabled;\r\n }\r\n };\r\n\r\n /**\r\n * Sets the custom ngModel.$error flags to be consumed by ngMessages. Flags are:\r\n * - mindate: whether the selected date is before the minimum date.\r\n * - maxdate: whether the selected flag is after the maximum date.\r\n * - filtered: whether the selected date is allowed by the custom filtering function.\r\n * - valid: whether the entered text input is a valid date\r\n *\r\n * The 'required' flag is handled automatically by ngModel.\r\n *\r\n * @param {Date=} opt_date Date to check. If not given, defaults to the datepicker's model value.\r\n */\r\n PersianDatePickerCtrl.prototype.updateErrorState = function(opt_date) {\r\n var date = opt_date || this.date;\r\n\r\n // Clear any existing errors to get rid of anything that's no longer relevant.\r\n this.clearErrorState();\r\n\r\n if (this.dateUtil.isValidDate(date)) {\r\n // Force all dates to midnight in order to ignore the time portion.\r\n date = this.dateUtil.createDateAtMidnight(date);\r\n\r\n if (this.dateUtil.isValidDate(this.minDate)) {\r\n var minDate = this.dateUtil.createDateAtMidnight(this.minDate);\r\n this.ngModelCtrl.$setValidity('mindate', date >= minDate);\r\n }\r\n\r\n if (this.dateUtil.isValidDate(this.maxDate)) {\r\n var maxDate = this.dateUtil.createDateAtMidnight(this.maxDate);\r\n this.ngModelCtrl.$setValidity('maxdate', date <= maxDate);\r\n }\r\n\r\n if (angular.isFunction(this.dateFilter)) {\r\n this.ngModelCtrl.$setValidity('filtered', this.dateFilter(date));\r\n }\r\n } else {\r\n // The date is seen as \"not a valid date\" if there is *something* set\r\n // (i.e.., not null or undefined), but that something isn't a valid date.\r\n this.ngModelCtrl.$setValidity('valid', date == null);\r\n }\r\n\r\n angular.element(this.inputContainer).toggleClass(INVALID_CLASS, !this.ngModelCtrl.$valid);\r\n };\r\n\r\n /** Clears any error flags set by `updateErrorState`. */\r\n PersianDatePickerCtrl.prototype.clearErrorState = function() {\r\n this.inputContainer.classList.remove(INVALID_CLASS);\r\n ['mindate', 'maxdate', 'filtered', 'valid'].forEach(function(field) {\r\n this.ngModelCtrl.$setValidity(field, true);\r\n }, this);\r\n };\r\n\r\n /** Resizes the input element based on the size of its content. */\r\n PersianDatePickerCtrl.prototype.resizeInputElement = function() {\r\n this.inputElement.size = this.inputElement.value.length + EXTRA_INPUT_SIZE;\r\n };\r\n\r\n /**\r\n * Sets the model value if the user input is a valid date.\r\n * Adds an invalid class to the input element if not.\r\n */\r\n PersianDatePickerCtrl.prototype.handleInputEvent = function() {\r\n var inputString = this.inputElement.value;\r\n var parsedDate = inputString ? this.locale.parseDate(inputString) : null;\r\n this.dateUtil.setDateTimeToMidnight(parsedDate);\r\n\r\n // An input string is valid if it is either empty (representing no date)\r\n // or if it parses to a valid date that the user is allowed to select.\r\n var isValidInput = inputString == '' || (\r\n this.dateUtil.isValidDate(parsedDate) &&\r\n this.locale.isDateComplete(inputString) &&\r\n this.isDateEnabled(parsedDate)\r\n );\r\n\r\n // The datepicker's model is only updated when there is a valid input.\r\n if (isValidInput) {\r\n this.setModelValue(parsedDate);\r\n this.date = parsedDate;\r\n }\r\n\r\n this.updateErrorState(parsedDate);\r\n };\r\n\r\n /**\r\n * Check whether date is in range and enabled\r\n * @param {Date=} opt_date\r\n * @return {boolean} Whether the date is enabled.\r\n */\r\n PersianDatePickerCtrl.prototype.isDateEnabled = function(opt_date) {\r\n return this.dateUtil.isDateWithinRange(opt_date, this.minDate, this.maxDate) &&\r\n (!angular.isFunction(this.dateFilter) || this.dateFilter(opt_date));\r\n };\r\n\r\n /** Position and attach the floating calendar to the document. */\r\n PersianDatePickerCtrl.prototype.attachCalendarPane = function() {\r\n var calendarPane = this.calendarPane;\r\n var body = document.body;\r\n\r\n calendarPane.style.transform = '';\r\n this.$element.addClass(OPEN_CLASS);\r\n this.mdInputContainer && this.mdInputContainer.element.addClass(OPEN_CLASS);\r\n angular.element(body).addClass('md-datepicker-is-showing');\r\n\r\n var elementRect = this.inputContainer.getBoundingClientRect();\r\n var bodyRect = body.getBoundingClientRect();\r\n\r\n if (!this.topMargin || this.topMargin < 0) {\r\n this.topMargin = (this.inputMask.parent().prop('clientHeight') - this.ngInputElement.prop('clientHeight')) / 2;\r\n }\r\n\r\n // Check to see if the calendar pane would go off the screen. If so, adjust position\r\n // accordingly to keep it within the viewport.\r\n var paneTop = elementRect.top - bodyRect.top - this.topMargin;\r\n var paneLeft = elementRect.left - bodyRect.left - this.leftMargin;\r\n\r\n // If ng-material has disabled body scrolling (for example, if a dialog is open),\r\n // then it's possible that the already-scrolled body has a negative top/left. In this case,\r\n // we want to treat the \"real\" top as (0 - bodyRect.top). In a normal scrolling situation,\r\n // though, the top of the viewport should just be the body's scroll position.\r\n var viewportTop = (bodyRect.top < 0 && document.body.scrollTop == 0) ?\r\n -bodyRect.top :\r\n document.body.scrollTop;\r\n\r\n var viewportLeft = (bodyRect.left < 0 && document.body.scrollLeft == 0) ?\r\n -bodyRect.left :\r\n document.body.scrollLeft;\r\n\r\n var viewportBottom = viewportTop + this.$window.innerHeight;\r\n var viewportRight = viewportLeft + this.$window.innerWidth;\r\n\r\n // Creates an overlay with a hole the same size as element. We remove a pixel or two\r\n // on each end to make it overlap slightly. The overlay's background is added in\r\n // the theme in the form of a box-shadow with a huge spread.\r\n this.inputMask.css({\r\n position: 'absolute',\r\n left: this.leftMargin + 'px',\r\n top: this.topMargin + 'px',\r\n width: (elementRect.width - 1) + 'px',\r\n height: (elementRect.height - 2) + 'px'\r\n });\r\n\r\n // If the right edge of the pane would be off the screen and shifting it left by the\r\n // difference would not go past the left edge of the screen. If the calendar pane is too\r\n // big to fit on the screen at all, move it to the left of the screen and scale the entire\r\n // element down to fit.\r\n if (paneLeft + CALENDAR_PANE_WIDTH > viewportRight) {\r\n if (viewportRight - CALENDAR_PANE_WIDTH > 0) {\r\n paneLeft = viewportRight - CALENDAR_PANE_WIDTH;\r\n } else {\r\n paneLeft = viewportLeft;\r\n var scale = this.$window.innerWidth / CALENDAR_PANE_WIDTH;\r\n calendarPane.style.transform = 'scale(' + scale + ')';\r\n }\r\n\r\n calendarPane.classList.add('md-datepicker-pos-adjusted');\r\n }\r\n\r\n // If the bottom edge of the pane would be off the screen and shifting it up by the\r\n // difference would not go past the top edge of the screen.\r\n if (paneTop + CALENDAR_PANE_HEIGHT > viewportBottom &&\r\n viewportBottom - CALENDAR_PANE_HEIGHT > viewportTop) {\r\n paneTop = viewportBottom - CALENDAR_PANE_HEIGHT;\r\n calendarPane.classList.add('md-datepicker-pos-adjusted');\r\n }\r\n\r\n calendarPane.style.left = paneLeft + 'px';\r\n calendarPane.style.top = paneTop + 'px';\r\n document.body.appendChild(calendarPane);\r\n\r\n // Add CSS class after one frame to trigger open animation.\r\n this.$$rAF(function() {\r\n calendarPane.classList.add('md-pane-open');\r\n });\r\n };\r\n\r\n /** Detach the floating calendar pane from the document. */\r\n PersianDatePickerCtrl.prototype.detachCalendarPane = function() {\r\n this.$element.removeClass(OPEN_CLASS);\r\n this.mdInputContainer && this.mdInputContainer.element.removeClass(OPEN_CLASS);\r\n angular.element(document.body).removeClass('md-datepicker-is-showing');\r\n this.calendarPane.classList.remove('md-pane-open');\r\n this.calendarPane.classList.remove('md-datepicker-pos-adjusted');\r\n\r\n if (this.isCalendarOpen) {\r\n this.$mdUtil.enableScrolling();\r\n }\r\n\r\n if (this.calendarPane.parentNode) {\r\n // Use native DOM removal because we do not want any of the\r\n // angular state of this element to be disposed.\r\n this.calendarPane.parentNode.removeChild(this.calendarPane);\r\n }\r\n };\r\n\r\n /**\r\n * Open the floating calendar pane.\r\n * @param {Event} event\r\n */\r\n PersianDatePickerCtrl.prototype.openCalendarPane = function(event) {\r\n if (!this.isCalendarOpen && !this.isDisabled && !this.inputFocusedOnWindowBlur) {\r\n this.isCalendarOpen = this.isOpen = true;\r\n this.calendarPaneOpenedFrom = event.target;\r\n\r\n // Because the calendar pane is attached directly to the body, it is possible that the\r\n // rest of the component (input, etc) is in a different scrolling container, such as\r\n // an md-content. This means that, if the container is scrolled, the pane would remain\r\n // stationary. To remedy this, we disable scrolling while the calendar pane is open, which\r\n // also matches the native behavior for things like `