X-Git-Url: https://git.ladys.computer/Gitweb/blobdiff_plain/e301db1d49799c3f6cce05ac75438cd76254de83cb4675c7b45e9019abcb6306..5f9145e76025077e55316b834b3276fca8deec9c3241ded66ab032d72002e6d9:/static/js/adjust-timezone.js diff --git a/static/js/adjust-timezone.js b/static/js/adjust-timezone.js index 5b80fa6..d2a8f1c 100644 --- a/static/js/adjust-timezone.js +++ b/static/js/adjust-timezone.js @@ -7,34 +7,51 @@ */ /** - * Get common timezone and adjust dates to use this common timezone. + * Get common timezone, add UI for changing timezones, and adjust + * dates to use requested common timezone. * * This function is called during onload event (added to window.onload). * * @param {String} tzDefault: default timezone, if there is no cookie - * @param {String} tzCookieName: name of cookie to store timezone + * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone + * @param {String} tzCookieInfo.name: name of cookie to store timezone * @param {String} tzClassName: denotes elements with date to be adjusted */ -function onloadTZSetup(tzDefault, tzCookieName, tzClassName) { - var tzCookie = getCookie(tzCookieName); - var tz = tzCookie ? tzCookie : tzDefault; +function onloadTZSetup(tzDefault, tzCookieInfo, tzClassName) { + var tzCookieTZ = getCookie(tzCookieInfo.name, tzCookieInfo); + var tz = tzDefault; + + if (tzCookieTZ) { + // set timezone to value saved in a cookie + tz = tzCookieTZ; + // refresh cookie, so its expiration counts from last use of gitweb + setCookie(tzCookieInfo.name, tzCookieTZ, tzCookieInfo); + } + + // add UI for changing timezone + addChangeTZ(tz, tzCookieInfo, tzClassName); // server-side of gitweb produces datetime in UTC, // so if tz is 'utc' there is no need for changes - if (tz !== 'utc') { - fixDatetimeTZ(tz, tzClassName); - } + var nochange = tz === 'utc'; + + // adjust dates to use specified common timezone + fixDatetimeTZ(tz, tzClassName, nochange); } +/* ...................................................................... */ +/* Changing dates to use requested timezone */ + /** * Replace RFC-2822 dates contained in SPAN elements with tzClassName * CSS class with equivalent dates in given timezone. * * @param {String} tz: numeric timezone in '(-|+)HHMM' format, or 'utc', or 'local' * @param {String} tzClassName: specifies elements to be changed + * @param {Boolean} nochange: markup for timezone change, but don't change it */ -function fixDatetimeTZ(tz, tzClassName) { +function fixDatetimeTZ(tz, tzClassName, nochange) { // sanity check, method should be ensured by common-lib.js if (!document.getElementsByClassName) { return; @@ -48,13 +65,266 @@ function fixDatetimeTZ(tz, tzClassName) { for (var i = 0, len = classesFound.length; i < len; i++) { var curElement = classesFound[i]; - // we use *.firstChild.data (W3C DOM) instead of *.innerHTML - // as the latter doesn't always work everywhere in every browser - var epoch = parseRFC2822Date(curElement.firstChild.data); - var adjusted = formatDateRFC2882(epoch, tz); + curElement.title = 'Click to change timezone'; + if (!nochange) { + // we use *.firstChild.data (W3C DOM) instead of *.innerHTML + // as the latter doesn't always work everywhere in every browser + var epoch = parseRFC2822Date(curElement.firstChild.data); + var adjusted = formatDateRFC2882(epoch, tz); + + curElement.firstChild.data = adjusted; + } + } +} + + +/* ...................................................................... */ +/* Adding triggers, generating timezone menu, displaying and hiding */ + +/** + * Adds triggers for UI to change common timezone used for dates in + * gitweb output: it marks up and/or creates item to click to invoke + * timezone change UI, creates timezone UI fragment to be attached, + * and installs appropriate onclick trigger (via event delegation). + * + * @param {String} tzSelected: pre-selected timezone, + * 'utc' or 'local' or '(-|+)HHMM' + * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone + * @param {String} tzClassName: specifies elements to install trigger + */ +function addChangeTZ(tzSelected, tzCookieInfo, tzClassName) { + // make link to timezone UI discoverable + addCssRule('.'+tzClassName + ':hover', + 'text-decoration: underline; cursor: help;'); + + // create form for selecting timezone (to be saved in a cookie) + var tzSelectFragment = document.createDocumentFragment(); + tzSelectFragment = createChangeTZForm(tzSelectFragment, + tzSelected, tzCookieInfo, tzClassName); + + // event delegation handler for timezone selection UI (clicking on entry) + // see http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/ + // assumes that there is no existing document.onclick handler + document.onclick = function onclickHandler(event) { + //IE doesn't pass in the event object + event = event || window.event; + + //IE uses srcElement as the target + var target = event.target || event.srcElement; + + switch (target.className) { + case tzClassName: + // don't display timezone menu if it is already displayed + if (tzSelectFragment.childNodes.length > 0) { + displayChangeTZForm(target, tzSelectFragment); + } + break; + } // end switch + }; +} + +/** + * Create DocumentFragment with UI for changing common timezone in + * which dates are shown in. + * + * @param {DocumentFragment} documentFragment: where attach UI + * @param {String} tzSelected: default (pre-selected) timezone + * @param {Object} tzCookieInfo: object literal with info about cookie to store timezone + * @returns {DocumentFragment} + */ +function createChangeTZForm(documentFragment, tzSelected, tzCookieInfo, tzClassName) { + var div = document.createElement("div"); + div.className = 'popup'; + + /* '
' */ + var closeButton = document.createElement('div'); + closeButton.className = 'close-button'; + closeButton.title = '(click on this box to close)'; + closeButton.appendChild(document.createTextNode('X')); + closeButton.onclick = closeTZFormHandler(documentFragment, tzClassName); + div.appendChild(closeButton); + + /* 'Select timezone: