      1 (function ($, rf) {
      2
      3     rf.calendarUtils = rf.calendarUtils || {};
      4
      5     var getDefaultMonthNames = function(shortNames) {
      6         return (shortNames
      7             ? ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
      8             : ['January','February','March','April','May','June','July','August','September','October','November','December']);
      9     };
     10
     11     $.extend(rf.calendarUtils, {
     12             // TODO: rewrite this function or use the same function if exists
     13             /*clonePosition: function (elements, source)
     14              {
     15              if (!elements.length) elements = [elements];
     16              var offset = Position.cumulativeOffset(source);
     17              offset = {left:offset[0], top:offset[1]};
     18              var offsetTemp;
     19              if (source.style.position!='absolute')
     20              {
     21              offsetTemp = Position.realOffset(source);
     22              offset.left -= offsetTemp.left;
     23              offset.top -= offsetTemp.top;
     24              offsetTemp = Richfaces.Calendar.getWindowScrollOffset();
     25              offset.left += offsetTemp.left;
     26              offset.top += offsetTemp.top;
     27              }
     28
     29              for (var i=0;i<elements.length;i++)
     30              {
     31              offsetTemp = Richfaces.Calendar.getParentOffset(elements[i]);
     32              elements[i].style.left = (offset.left - offsetTemp.left) + 'px';
     33              elements[i].style.top = (offset.top - offsetTemp.top) + 'px';
     34              }
     35              return offset;
     36              }*/
     37
     38             //TODO: not used
     39             /*Object.extend(Event, {
     40              findElementByAttr : function(event, tagName, attribute, value, flag) {
     41              var element = Event.findElement(event, tagName);
     42              while (!element[attribute] || (flag ? element[attribute].indexOf(value)!=0 : element[attribute]!=value) )
     43              {
     44              element = element.parentNode;
     45              }
     46              return element;
     47              }
     48              });
     49
     50              Object.extend(Element, {
     51              replaceClassName : function (element, whichClassName, toClassName) {
     52              if (!(element = $(element))) return;
     53              var e = Element.classNames(element);
     54              e.remove(whichClassName);
     55              e.add(toClassName);
     56              return element;
     57              }
     58              });*/
     59
     60             // TODO: move joinArray to richfaces utils
     61             joinArray: function(array, begin, end, separator) {
     62                 var value = '';
     63                 if (array.length != 0) value = begin + array.pop() + end;
     64                 while (array.length)
     65                     value = begin + array.pop() + end + separator + value;
     66                 return value;
     67             },
     68
     69             getMonthByLabel: function (monthLabel, monthNames) {
     70                 var toLowerMonthLabel = monthLabel.toLowerCase();
     71                 var i = 0;
     72                 while (i < monthNames.length) {
     73                     if (monthNames[i].toLowerCase() == toLowerMonthLabel) {
     74                         return i;
     75                     }
     76
     77                     i++;
     78                 }
     79             },
     80
     81             createDate: function (yy, mm, dd, h, m, s) {
     82                 h = h || 0;
     83                 m = m || 0;
     84                 s = s || 0;
     85                 var date = new Date(yy, mm, dd, h, m, s);
     86                 if (date.getDate() != dd) {
     87                     date = new Date(yy, mm);
     88                     date.setHours(h);
     89                     date.setMinutes(m);
     90                     date.setSeconds(s);
     91                     date.setUTCDate(dd);
     92                 }
     93                 return date;
     94             },
     95
     96             /* Year:
     97              *	y,yy - 00-99
     98              *	yyy+ - 1999
     99              * Month:
    100              *	M - 1-12
    101              *	MM - 01-12
    102              *	MMM - short (Jul)
    103              *	MMMM+ - long (July)
    104              * Date:
    105              *	d - 1-31
    106              *	dd+ - 01-31 */
    107             parseDate: function(dateString, pattern, monthNames, monthNamesShort) {
    108                 var re = /([.*+?^<>=!:${}()\[\]\/\\])/g;
    109                 var monthNamesStr
    110                 var monthNamesShortStr;
    111                 if (!monthNames) {
    112                     monthNames = getDefaultMonthNames();
    113                     monthNamesStr = monthNames.join('|');
    114                 } else {
    115                     monthNamesStr = monthNames.join('|').replace(re, '\\$1');
    116                 }
    117
    118                 if (!monthNamesShort) {
    119                     monthNamesShort = getDefaultMonthNames(true);
    120                     monthNamesShortStr = monthNamesShort.join('|');
    121                 } else {
    122                     monthNamesShortStr = monthNamesShort.join('|').replace(re, '\\$1');
    123                 }
    124
    125                 var counter = 1;
    126                 var y,m,d;
    127                 var a,h,min,s;
    128                 var shortLabel = false;
    129
    130                 pattern = pattern.replace(/([.*+?^<>=!:${}()|\[\]\/\\])/g, '\\$1');
    131                 pattern = pattern.replace(/(y+|M+|d+|a|H{1,2}|h{1,2}|m{2}|s{2})/g,
    132                     function($1) {
    133                         switch ($1) {
    134                             case 'y'  :
    135                             case 'yy' :
    136                                 y = counter;
    137                                 counter++;
    138                                 return '(\\d{2})';
    139                             case 'MM' :
    140                                 m = counter;
    141                                 counter++;
    142                                 return '(\\d{2})';
    143                             case 'M'  :
    144                                 m = counter;
    145                                 counter++;
    146                                 return '(\\d{1,2})';
    147                             case 'd'  :
    148                                 d = counter;
    149                                 counter++;
    150                                 return '(\\d{1,2})';
    151                             case 'MMM':
    152                                 m = counter;
    153                                 counter++;
    154                                 shortLabel = true;
    155                                 return '(' + monthNamesShortStr + ')';
    156                             case 'a'  :
    157                                 a = counter;
    158                                 counter++;
    159                                 return '(AM|am|PM|pm)?';
    160                             case 'HH' :
    161                             case 'hh' :
    162                                 h = counter;
    163                                 counter++;
    164                                 return '(\\d{2})?';
    165                             case 'H'  :
    166                             case 'h'  :
    167                                 h = counter;
    168                                 counter++;
    169                                 return '(\\d{1,2})?';
    170                             case 'mm' :
    171                                 min = counter;
    172                                 counter++;
    173                                 return '(\\d{2})?';
    174                             case 'ss' :
    175                                 s = counter;
    176                                 counter++;
    177                                 return '(\\d{2})?';
    178
    179                         }
    180                         // y+,M+,d+
    181                         var ch = $1.charAt(0);
    182                         if (ch == 'y') {
    183                             y = counter;
    184                             counter++;
    185                             return '(\\d{3,4})'
    186                         }
    187                         ;
    188                         if (ch == 'M') {
    189                             m = counter;
    190                             counter++;
    191                             return '(' + monthNamesStr + ')'
    192                         }
    193                         ;
    194                         if (ch == 'd') {
    195                             d = counter;
    196                             counter++;
    197                             return '(\\d{2})'
    198                         }
    199                         ;
    200                     }
    201                 );
    202
    203                 var re = new RegExp(pattern, 'i');
    204                 var match = dateString.match(re);
    205                 if (match != null && y != undefined && m != undefined) {
    206                     // set default century start
    207                     var correctYear = false;
    208                     var defaultCenturyStart = new Date();
    209                     defaultCenturyStart.setFullYear(defaultCenturyStart.getFullYear() - 80);
    210
    211                     var yy = parseInt(match[y], 10);
    212                     if (isNaN(yy)) return null;
    213                     else if (yy < 100) {
    214                         // calculate full year if year has only two digits
    215                         var defaultCenturyStartYear = defaultCenturyStart.getFullYear();
    216                         var ambiguousTwoDigitYear = defaultCenturyStartYear % 100;
    217                         correctYear = yy == ambiguousTwoDigitYear;
    218                         yy += Math.floor(defaultCenturyStartYear / 100) * 100 + (yy < ambiguousTwoDigitYear ? 100 : 0);
    219                     }
    220
    221                     var mm = parseInt(match[m], 10);
    222                     if (isNaN(mm)) mm = this.getMonthByLabel(match[m], shortLabel ? monthNamesShort : monthNames); else if (--mm < 0 || mm > 11) return null;
    223                     var addDay = correctYear ? 1 : 0;
    224                     var dd;
    225                     if (d != undefined) {
    226                         dd = parseInt(match[d], 10);
    227                     } else {
    228                         dd = 1; // default to the first of the month when the date is not selected
    229                     }
    230                     if (isNaN(dd) || dd < 1 || dd > this.daysInMonth(yy, mm) + addDay) return null;
    231
    232                     var date;
    233
    234                     // time parsing
    235                     if (min != undefined && h != undefined) {
    236                         var hh,mmin,aa;
    237                         mmin = parseInt(match[min], 10);
    238                         if (isNaN(mmin) || mmin < 0 || mmin > 59) return null;
    239                         hh = parseInt(match[h], 10);
    240                         if (isNaN(hh)) return null;
    241                         if (a != undefined) {
    242                             aa = match[a];
    243                             if (!aa) return null;
    244                             aa = aa.toLowerCase();
    245                             if ((aa != 'am' && aa != 'pm') || hh < 1 || hh > 12) return null;
    246                             if (aa == 'pm') {
    247                                 if (hh != 12) hh += 12;
    248                             } else if (hh == 12) hh = 0;
    249                         }
    250                         else if (hh < 0 || hh > 23) return null;
    251
    252                         date = this.createDate(yy, mm, dd, hh, mmin);
    253                         if (s != undefined) {
    254                             sec = parseInt(match[s], 10);
    255                             if (isNaN(sec) || sec < 0 || sec > 59) return null;
    256                             date.setSeconds(sec);
    257                         }
    258                     } else {
    259                         date = this.createDate(yy, mm, dd);
    260                     }
    261
    262                     if (correctYear) {
    263                         if (date.getTime() < defaultCenturyStart.getTime()) {
    264                             date.setFullYear(yy + 100);
    265                         }
    266                         if (date.getMonth() != mm) return null;
    267                     }
    268
    269                     return date;
    270                 }
    271                 return null;
    272             },
    273
    274             formatDate: function(date, pattern, monthNames, monthNamesShort) {
    275                 if (!monthNames) monthNames = getDefaultMonthNames();
    276                 if (!monthNamesShort) monthNamesShort = getDefaultMonthNames(true);
    277                 var mm,dd,hh,min,sec;
    278                 var result = pattern.replace(/(\\\\|\\[yMdaHhms])|(y+|M+|d+|a|H{1,2}|h{1,2}|m{2}|s{2})/g,
    279                     function($1, $2, $3) {
    280                         if ($2) return $2.charAt(1);
    281                         switch ($3) {
    282                             case 'y':
    283                             case 'yy':
    284                                 return date.getYear().toString().slice(-2);
    285                             case 'M':
    286                                 return (date.getMonth() + 1);
    287                             case 'MM':
    288                                 return ((mm = date.getMonth() + 1) < 10 ? '0' + mm : mm);
    289                             case 'MMM':
    290                                 return monthNamesShort[date.getMonth()];
    291                             case 'd':
    292                                 return date.getDate();
    293                             case 'a'  :
    294                                 return (date.getHours() < 12 ? 'AM' : 'PM');
    295                             case 'HH' :
    296                                 return ((hh = date.getHours()) < 10 ? '0' + hh : hh);
    297                             case 'H'  :
    298                                 return date.getHours();
    299                             case 'hh' :
    300                                 return ((hh = date.getHours()) == 0 ? '12' : (hh < 10 ? '0' + hh : (hh > 21 ? hh - 12 : (hh > 12) ? '0' + (hh - 12) : hh)));
    301                             case 'h'  :
    302                                 return ((hh = date.getHours()) == 0 ? '12' : (hh > 12 ? hh - 12 : hh));
    303                             case 'mm' :
    304                                 return ((min = date.getMinutes()) < 10 ? '0' + min : min);
    305                             case 'ss' :
    306                                 return ((sec = date.getSeconds()) < 10 ? '0' + sec : sec);
    307                         }
    308                         // y+,M+,d+
    309                         var ch = $3.charAt(0);
    310                         if (ch == 'y') return date.getFullYear();
    311                         if (ch == 'M') return monthNames[date.getMonth()];
    312                         if (ch == 'd') return ((dd = date.getDate()) < 10 ? '0' + dd : dd);
    313                     }
    314                 );
    315                 return result;
    316             },
    317
    318             isLeapYear: function(year) {
    319                 return new Date(year, 1, 29).getDate() == 29;
    320             },
    321
    322             daysInMonth: function(year, month) {
    323                 return 32 - new Date(year, month, 32).getDate();
    324             },
    325
    326             daysInMonthByDate: function(date) {
    327                 return 32 - new Date(date.getFullYear(), date.getMonth(), 32).getDate();
    328             },
    329
    330             getDay: function(date, firstWeekDay) {
    331                 var value = date.getDay() - firstWeekDay;
    332                 if (value < 0) value = 7 + value;
    333                 return value;
    334             },
    335
    336             getFirstWeek: function(year, mdifw, fdow) {
    337                 var date = new Date(year, 0, 1);
    338                 var firstday = this.getDay(date, fdow);
    339
    340                 var weeknumber = (7 - firstday < mdifw) ? 0 : 1;
    341
    342                 return {date:date, firstDay:firstday, weekNumber:weeknumber, mdifw:mdifw, fdow:fdow};
    343             },
    344
    345             getLastWeekOfPrevYear: function(o) {
    346                 var year = o.date.getFullYear() - 1;
    347                 var days = (this.isLeapYear(year) ? 366 : 365);
    348                 var obj = this.getFirstWeek(year, o.mdifw, o.fdow);
    349                 days = (days - 7 + o.firstDay);
    350                 var weeks = Math.ceil(days / 7);
    351
    352                 return  weeks + obj.weekNumber;
    353             },
    354
    355             weekNumber: function(year, month, mdifw, fdow) {
    356
    357                 var o = this.getFirstWeek(year, mdifw, fdow);
    358
    359                 if (month == 0) {
    360                     if (o.weekNumber == 1) return 1;
    361                     return this.getLastWeekOfPrevYear(o);
    362                 }
    363                 var oneweek = 604800000;
    364                 var d = new Date(year, month, 1);
    365                 d.setDate(1 + o.firstDay + (this.getDay(d, fdow) == 0 ? 1 : 0));
    366
    367                 weeknumber = o.weekNumber + Math.floor((d.getTime() - o.date.getTime()) / oneweek);
    368
    369                 return weeknumber;
    370             }
    371
    372         });
    373
    374     rf.calendarTemplates = rf.calendarTemplates || {};
    375
    376     $.extend(rf.calendarTemplates, (function () {
    377
    378         var VARIABLE_NAME_PATTERN = /^\s*[_,A-Z,a-z][\w,_\.]*\s*$/;
    379
    380         var getObjectValue = function (str, object) {
    381             var a = str.split(".");
    382             var value = object[a[0]];
    383             var c = 1;
    384             while (value && c < a.length) value = value[a[c++]];
    385             return (value ? value : "");
    386         };
    387
    388         return  {
    389             evalMacro: function(template, object) {
    390                 var _value_ = "";
    391                 // variable evaluation
    392                 if (VARIABLE_NAME_PATTERN.test(template)) {
    393                     if (template.indexOf('.') == -1) {
    394                         _value_ = object[template];
    395                         if (!_value_)    _value_ = window[template];
    396                     }
    397                     // object's variable evaluation
    398                     else {
    399                         _value_ = getObjectValue(template, object);
    400                         if (!_value_) _value_ = getObjectValue(template, window);
    401                     }
    402                     if (_value_ && typeof _value_ == 'function') _value_ = _value_(object);
    403                     if (!_value_) _value_ = "";
    404                 }
    405                 //js string evaluation
    406                 else {
    407                     try {
    408                         if (object.eval) {
    409                             _value_ = object.eval(template);
    410                         }
    411                         else with (object) {
    412                             _value_ = eval(template);
    413                         }
    414
    415                         if (typeof _value_ == 'function') {
    416                             _value_ = _value_(object);
    417                         }
    418                     } catch (e) {
    419                         LOG.warn("Exception: " + e.Message + "\n[" + template + "]");
    420                     }
    421                 }
    422                 return _value_;
    423             }
    424         };
    425     })());
    426
    427 })(RichFaces.jQuery, RichFaces);