diff --git a/src/static/i18n/strings_zh-CN.properties b/src/static/i18n/strings_zh-CN.properties index 1cce1fa..9263f41 100644 --- a/src/static/i18n/strings_zh-CN.properties +++ b/src/static/i18n/strings_zh-CN.properties @@ -138,3 +138,16 @@ ccn-i18n-tokenItem-ua=UA: ccn-i18n-tokenItem-ip=IP: ccn-i18n-tokenItem-expireOn=过期时间: ccn-i18n-tokenItem-isMe=这是你当前使用的登录凭据 + +ccn-i18n-datetime-loopStopRuleText-infinity=永远循环。 +ccn-i18n-datetime-loopStopRuleText-datetime=到{0}停止循环。 +ccn-i18n-datetime-loopStopRuleText-times=循环{0}次。 +ccn-i18n-datetime-loopRuleText-modeStrict=严格模式。 +ccn-i18n-datetime-loopRuleText-modeRough=宽松模式。 +ccn-i18n-datetime-loopRuleText-year=每{0}年于{1}循环一次。 +ccn-i18n-datetime-loopRuleText-monthA=每{0}月的第{1}日循环一次。 +ccn-i18n-datetime-loopRuleText-monthB=每{0}月的倒数第{1}日循环一次。 +ccn-i18n-datetime-loopRuleText-monthC=每{0}月的第{1}个星期{2}循环一次。 +ccn-i18n-datetime-loopRuleText-monthD=每{0}月的倒数第{1}个星期{2}循环一次。 +ccn-i18n-datetime-loopRuleText-week=每{0}周的{1}循环一次。 +ccn-i18n-datetime-loopRuleText-day=每{0}天循环一次。 diff --git a/src/static/js/datetime.js b/src/static/js/datetime.js index f4cf14f..877d890 100644 --- a/src/static/js/datetime.js +++ b/src/static/js/datetime.js @@ -261,8 +261,76 @@ function ccn_datetime_ResolveLoopRules4Event(loopRules, loopDateTimeStart, loopD return realResult; } -function ccn_datetime_ResolveLoopRules4Text(loopRules) { - return ""; +function ccn_datetime_ResolveLoopRules4Text(strl, startDateTime, timezoneOffset) { + if (strl == '') return ""; + + var sp = strl.split('-'); + if (sp.length != 2) return ""; + var loopRules = undefined; + var loopStopRules = undefined; + var datetimeInstance = new Date((startDateTime + timezoneOffset) * 60000) + + if (ccn_datetime_precompiledLoopRules.year.test(sp[0])) { + if (RegExp.$1 == 'S') + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeStrict'); + else + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeRough'); + loopRules += $.i18n.prop('ccn-i18n-datetime-loopRuleText-year') + .format(parseInt(RegExp.$2), datetimeInstance.toLocaleDateString(undefined, {timeZone: "UTC"})); + } else if (ccn_datetime_precompiledLoopRules.month.test(sp[0])) { + if (RegExp.$1 == 'S') + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeStrict'); + else + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeRough'); + + var dayInMonth = ccn_datetime_GetDayInMonth( + datetimeInstance.getUTCFullYear(), + datetimeInstance.getUTCMonth() + 1, + datetimeInstance.getUTCDate()); + switch(loopMethod) { + case 'A': + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthA') + format(parseInt(RegExp.$3), dayInMonth[0]); + break; + case 'B': + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthB') + format(parseInt(RegExp.$3), dayInMonth[1]); + break; + case 'C': + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthC') + format(parseInt(RegExp.$3), dayInMonth[2], dayInMonth[3]); + break; + case 'D': + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthD') + format(parseInt(RegExp.$3), dayInMonth[4], dayInMonth[5]); + break; + } + } else if (ccn_datetime_precompiledLoopRules.week.test(sp[0])) { + var weekOfDayCache = []; + for (var i = 0; i < 7; i++) { + if (RegExp.$1[i] == 'T') + weekOfDayCache.push(ccn_i18n_UniversalGetDayOfWeek(i)); + } + + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-week') + .format(parseInt(RegExp.$2), weekOfDayCache.join(', ')); + } else if (ccn_datetime_precompiledLoopRules.day.test(sp[0])) { + loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-day') + .format(parseInt(RegExp.$1)); + } else return ""; + + + if (ccn_datetime_precompiledLoopStopRules.infinity.test(sp[1])) { + loopStopRules = $.i18n.prop('ccn-i18n-datetime-loopStopRuleText-infinity'); + } else if (ccn_datetime_precompiledLoopStopRules.datetime.test(sp[1])) { + loopStopRules = $.i18n.prop('ccn-i18n-datetime-loopStopRuleText-datetime') + .format(new Date(parseInt(RegExp.$1)).toLocaleDateString()); + } else if (ccn_datetime_precompiledLoopStopRules.times.test(sp[1])) { + loopStopRules = $.i18n.prop('ccn-i18n-datetime-loopStopRuleText-times') + .format(parseInt(RegExp.$1)); + } else return ""; + + return (loopRules + loopStopRules); } function ccn_datetime_LeapYearCountEx(endYear, includeThis, baseYear, includeBase) { diff --git a/src/static/js/i18n.js b/src/static/js/i18n.js index 578ad25..3cc1bfa 100644 --- a/src/static/js/i18n.js +++ b/src/static/js/i18n.js @@ -82,3 +82,8 @@ function ccn_i18n_UniversalGetMonth(month) { return $.i18n.prop('ccn-i18n-universal-month-' + (month + 1)); } +// note: day of week is zero based +function ccn_i18n_UniversalGetDayOfWeek(dayOfWeek) { + return $.i18n.prop('ccn-i18n-universal-week-' + (dayOfWeek + 1)); +} + diff --git a/src/static/js/page/calendar.js b/src/static/js/page/calendar.js index 74a290d..448b394 100644 --- a/src/static/js/page/calendar.js +++ b/src/static/js/page/calendar.js @@ -157,7 +157,7 @@ function ccn_calendar_calendar_Analyse() { color: deserializedDescription.color, isVisible: true, isLocked: typeof(ccn_calendar_owned_displayCache[item[0]]) != 'undefined', - loopText: " ", // todo: finish this + loopText: ccn_datetime_ResolveLoopRules4Text(item[8], item[5], item[7]), timezoneWarning: mytimezone != item[7], start: eventDateTime.toLocaleTimeString(), end: undefined // filled in follwing code diff --git a/src/static/tmpl/scheduleItem.tmpl b/src/static/tmpl/scheduleItem.tmpl index 7509603..26fdb5d 100644 --- a/src/static/tmpl/scheduleItem.tmpl +++ b/src/static/tmpl/scheduleItem.tmpl @@ -15,6 +15,9 @@
{{>title}}
{{>description}}
{{>start}}-{{>end}}
+ {{if loopText != ""}} +{{>loopText}}
+ {{/if}} \ No newline at end of file