⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.50
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-horde
/
kronolith
/
js
/
Edit File: smartmobile.js
/** * mobile.js - Base mobile application logic. * * Copyright 2010-2017 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (GPL). If you * did not receive this file, see http://www.horde.org/licenses/gpl. * * @author Michael J. Rubinsky <mrubinsk@horde.org> * @author Jan Schneider <jan@horde.org> * @category Horde * @license http://www.horde.org/licenses/gpl GPL * @package Kronolith */ var KronolithMobile = { /** * List of calendars we are displaying */ calendars: [], /** * List of calendars that are currently loaded for the current view */ loadedCalendars: [], /** * Event cache */ ecache: {}, cacheStart: null, cacheEnd: null, deferHash: {}, viewRan: false, /** * The currently displayed view */ view: 'day', /** * The currently selected date */ date: null, /** * Temporary fix for pages not firing pagebeforecreate events properly */ haveOverview: false, /** * Load all events between start and end time. * * @param Date firstDay * @param Date lastDay * @param string view The view we are loading for (month, day) */ loadEvents: function(firstDay, lastDay, view) { var dates = [firstDay, lastDay], loading = false; // Clear out the loaded cal cache KronolithMobile.loadedCalendars = []; KronolithMobile.clearView(view); KronolithMobile.viewRan = false; $.each(KronolithMobile.calendars, function(key, cal) { var startDay = dates[0].clone(), endDay = dates[1].clone(), cals = KronolithMobile.ecache[cal[0]], c; if (typeof cals != 'undefined' && typeof cals[cal[1]] != 'undefined') { cals = cals[cal[1]]; c = cals[startDay.dateString()]; while (typeof c != 'undefined' && startDay.isBefore(endDay)) { if (view == 'day') { KronolithMobile.insertEvents([startDay, startDay], view, cal.join('|')); } startDay.addDays(1); c = cals[startDay.dateString()]; } c = cals[endDay.dateString()]; while (typeof c != 'undefined' && !startDay.isAfter(endDay)) { if (view == 'day') { KronolithMobile.insertEvents([endDay, endDay], view, cal.join('|')); } endDay.addDays(-1); c = cals[endDay.dateString()]; } if (startDay.compareTo(endDay) > 0) { KronolithMobile.loadedCalendars.push(cal.join('|')); return; } } var start = startDay.dateString(), end = endDay.dateString(); loading = true; HordeMobile.doAction('listEvents', { 'start': start, 'end': end, 'cal': cal.join('|'), 'view': view, 'sig': start + end + (Math.random() + '').slice(2) }, KronolithMobile.loadEventsCallback ); }); if (!loading && view == 'overview') { KronolithMobile.insertEvents([firstDay, lastDay], view); } }, /** * Sort a collection of events as returned from the ecache */ sortEvents: function(events) { var e = []; // Need a native array to sort. $.each(events, function(id, event) { e.push(event); }); return e.sort(function(a, b) { sortA = a.sort; sortB = b.sort; return (sortA < sortB) ? -1 : (sortA > sortB) ? 1 : 0; }); }, /** * Callback for the loadEvents AJAX request. * * @param object data The ajax response. */ loadEventsCallback: function(data) { var start = KronolithMobile.parseDate(data.sig.substr(0, 8)), end = KronolithMobile.parseDate(data.sig.substr(8, 8)), dates = [start, end], view = data.view; KronolithMobile.storeCache(data.events, data.cal, dates, true); KronolithMobile.loadedCalendars.push(data.cal); KronolithMobile.insertEvents(dates, view, data.cal); }, /** * Inserts events into current view. * For Day view, builds a new listview and attaches to the DOM. * For Month view, hightlights dates with events. */ insertEvents: function(dates, view, cal) { var key = dates[0].dateString() + dates[1].dateString() + view + cal, d = [dates[0].clone(), dates[1].clone()], date, events, list, day; // Make sure all calendars are loaded before rendering the view. // @TODO: Implement LIFO queue as in kronolith.js if (KronolithMobile.loadedCalendars.length != KronolithMobile.calendars.length) { if (KronolithMobile.deferHash[key]) { return; } else { KronolithMobile.deferHash[key] = window.setTimeout(function() { KronolithMobile.insertEvents(d, view, cal); }, 0); return; } } if (KronolithMobile.deferHash[key]) { window.clearTimeout(KronolithMobile.deferHash[key]); KronolithMobile.deferHash[key] = false; } KronolithMobile.running = true; switch (view) { case 'day': if (!KronolithMobile.viewRan) { KronolithMobile.viewRan = true; date = d[0].dateString(); events = KronolithMobile.getCacheForDate(date); events = KronolithMobile.sortEvents(events); list = $('<ul>').attr({'data-role': 'listview'}); $.each(events, function(index, event) { list.append(KronolithMobile.buildDayEvent(event)); }); if (!list.children().length) { list.append($('<li>').text(Kronolith.text.noevents)); } $("#dayview :jqmData(role='content')").append(list).trigger('create'); } break; case 'month': day = d[0].clone(); while (!day.isAfter(d[1])) { date = day.dateString(); events = KronolithMobile.getCacheForDate(date); $.each(events, function(key, event) { $('#kronolithMonth' + date).addClass('kronolithContainsEvents'); }); day.next().day(); } // Select current date. $('#kronolithMonth'+ KronolithMobile.date.dateString()).addClass('kronolith-selected'); KronolithMobile.selectMonthDay(KronolithMobile.date.dateString()); break; case 'overview': day = d[0].clone(), haveEvent = false; list = $('<ul>').attr({'data-role': 'listview'}); while (!day.isAfter(d[1])) { list.append($('<li>').attr({ 'data-role': 'list-divider' }).text(day.toString('ddd') + ' ' + day.toString('d'))); events = KronolithMobile.sortEvents(KronolithMobile.getCacheForDate(day.dateString())) ; $.each(events, function(index, event) { list.append(KronolithMobile.buildDayEvent(event)); haveEvent = true; }); if (!haveEvent) { list.append($('<li>').text(Kronolith.text.noevents)); } haveEvent = false; day.next().day(); } $("#overview :jqmData(role='content')").append(list).trigger('create'); break; } KronolithMobile.running = false; }, /** * Build the dom element for an event to insert into the day view. * * @param object event The event object returned from the ajax request. */ buildDayEvent: function(event) { var id; if ($.isEmptyObject(event)) { return; } var cal = event.calendar, type = cal.split('|')[0], c = cal.split('|')[1], d = $('<div>'), item = $('<li>'), a; // Time var timeWrapper = $('<div>').addClass('kronolithTimeWrapper'); if (event.al) { timeWrapper.append(Kronolith.text.allday).html(); } else { var startTime = Date.parse(event.s).toString(Kronolith.conf.time_format); var endTime = '- ' + Date.parse(event.e).toString(Kronolith.conf.time_format); timeWrapper .append($('<div>').addClass('kronolithStartTime').append(startTime)) .append($('<div>').addClass('kronolithEndTime').append(endTime)); } e = $('<h2>').text(event.t); l = $('<p>').addClass('kronolithDayLocation' + Kronolith.conf.calendars[type][c].fg.substring(1)).text(event.l); d.append(timeWrapper).append(e).append(l); // Add the link to view the event detail. a = $('<a>') .css({ backgroundColor: Kronolith.conf.calendars[type][c].bg }) .attr({ href: '#eventview', 'class': 'kronolith-event kronolith-event-' + Kronolith.conf.calendars[type][c].fg.substring(1) }) .click(function(ev) { $("#eventview :jqmData(role='content') ul").detach(); KronolithMobile.loadEvent(cal, event.id, Date.parse(event.e)); }) .append(d); return item.append(a); }, /** * Retrieve a single event from the server and show it. * * @param string cal The calendar identifier. * @param string id The event identifier. * @param Date d The date the event occurs. */ loadEvent: function(cal, id, d) { HordeMobile.doAction('getEvent', {'cal': cal, 'id': id, 'date': d.toString('yyyyMMdd')}, KronolithMobile.loadEventCallback); }, /** * Callback for loadEvent call. Assume we are in Event view for now, build * the event view structure and attach to DOM. * * @param object data The ajax response. */ loadEventCallback: function(data) { if (!data.event) { // @TODO: Error handling. return; } var event = data.event; var ul = KronolithMobile.buildEventView(event); $("#eventview :jqmData(role='content')").append(ul).trigger('create'); }, /** * Build event view DOM structure and return the top event element. * * @param object e The event structure returned from the ajax call. */ buildEventView: function(e) { var list = $('<ul>') .addClass('kronolithEventDetail') .attr({'data-role': 'listview', 'data-inset': true}); var loc = false; // Title and calendar var title = $('<div>').addClass('kronolithEventDetailTitle').append($('<h2>').text(e.t)); var calendar = $('<p>').addClass('kronolithEventDetailCalendar').text(Kronolith.conf.calendars[e.ty][e.c]['name']); list.append($('<li>').append(title).append(calendar)); // Time var item = $('<div>'); if (e.r) { var recurText = Kronolith.text.recur.desc[e.r.t][(e.r.i > 1) ? 1 : 0], date = Date.parse(e.s); recurText = recurText.replace('#{interval}', e.r.i); switch (e.r.t) { case 2: // WEEKLY recurText = recurText.replace('#{weekday}', Kronolith.text.weekday[e.r.d]); break; case 3: // MONTHLY_DATE recurText = recurText.replace('#{date}', date.toString('d') + '.'); break; case 5: // YEARLY_DATE recurText = recurText.replace('#{date}', date.toString('m')); break; } item.append($('<div>').addClass('kronolithEventDetailRecurring').append(recurText)); item.append($('<div>').addClass('kronolithEventDetailRecurring').text(Kronolith.text.recur[e.r.t])); } if (e.al) { item.append($('<div>').addClass('kronolithEventDetailAllDay').text(Kronolith.text.allday)) .append($('<div>').addClass('kronolithEventDetailDate').text(Date.parse(e.s).toString('D'))); } else { item.append($('<div>') .append($('<div>').addClass('kronolithEventDetailDate').text(Date.parse(e.s).toString('D')) .append($('<div>').addClass('kronolithEventDetailTime').text(Date.parse(e.s).toString(Kronolith.conf.time_format) + ' - ' + Date.parse(e.e).toString(Kronolith.conf.time_format)))) ); } list.append($('<li>').append(item)); // Location if (e.gl) { loc = $('<div>').addClass('kronolithEventDetailLocation') .append($('<a>').attr({'data-style': 'b', 'href': 'http://maps.google.com?q=' + encodeURIComponent(e.gl.lat + ',' + e.gl.lon)}).text(e.l)); } else if (e.l) { loc = $('<div>').addClass('kronolithEventDetailLocation') .append($('<a>').attr({'href': 'http://maps.google.com?q=' + encodeURIComponent(e.l)}).text(e.l)); } if (loc) { list.append($('<li>').append(loc)); } // Description if (e.d) { list.append($('<li>').append($('<div>').addClass('kronolithEventDetailDesc').text(e.d))); } // url if (e.u) { list.append($('<li>').append($('<a>').attr({'rel': 'external', 'href': e.u}).text(e.u))); } return list; }, clearView: function(view) { switch (view) { case 'month': $('#kronolithDayDetail ul').detach(); break; case 'day': $("#dayview :jqmData(role='content') ul").detach(); break; case 'overview': $("#overview :jqmData(role='content') ul").detach(); } }, /** * Advance the day view by one day */ showNextDay: function() { KronolithMobile.moveToDay(KronolithMobile.date.clone().addDays(1)); }, /** * Move the day view back by one day */ showPrevDay: function() { KronolithMobile.moveToDay(KronolithMobile.date.clone().addDays(-1)); }, /** * Move the day view to a specific day * * @param Date date The date to set the day view to. */ moveToDay: function(date) { $('#kronolithDayDate').text(date.toString('ddd') + ' ' + date.toString('d')); KronolithMobile.date = date.clone(); KronolithMobile.loadEvents(KronolithMobile.date, KronolithMobile.date, 'day'); }, /** * Advance the month view ahead one month. */ showPrevMonth: function() { KronolithMobile.moveToMonth(KronolithMobile.date.clone().addMonths(-1)); }, /** * Move the month view back one month */ showNextMonth: function() { KronolithMobile.moveToMonth(KronolithMobile.date.clone().addMonths(1)); }, /** * Move the month view to the month containing the specified date. * * @params Date date The date to move to. */ moveToMonth: function(date) { var dates = KronolithMobile.viewDates(date, 'month'); KronolithMobile.date = date; KronolithMobile.loadEvents(dates[0], dates[1], 'month'); KronolithMobile.buildCal(date); KronolithMobile.insertEvents(dates, 'month'); }, /** * Selects a day in the month view, and displays any events it may contain. * Also sets the dayview to the same date, so navigating back to it is * smooth. * * @param string date A date string in the form of yyyyMMdd. */ selectMonthDay: function(date) { var ul = $('<ul>').attr({ 'data-role': 'listview' }), d = KronolithMobile.parseDate(date), today = new Date(), text; $('#kronolithDayDetail ul').detach(); if (today.dateString() == d.dateString()) { text = Kronolith.text.today; } else if (today.clone().addDays(-1).dateString() == d.dateString()) { text = Kronolith.text.yesterday; } else if (today.clone().addDays(1).dateString() == d.dateString()) { text = Kronolith.text.tomorrow; } else { text = d.toString('ddd') + ' ' + d.toString('d'); } $('#kronolithDayDetailHeader h3').text(text); $('.kronolith-selected').removeClass('kronolith-selected'); $('#kronolithMonth' + date).addClass('kronolith-selected'); if ($('#kronolithMonth' + date).hasClass('kronolithContainsEvents')) { var events = KronolithMobile.getCacheForDate(date); events = KronolithMobile.sortEvents(events); $.each(events, function(k, e) { ul.append(KronolithMobile.buildDayEvent(e)); }); } $('#kronolithDayDetail').append(ul).trigger('create'); KronolithMobile.moveToDay(d); }, /** * Calculates first and last days being displayed. * * @var Date date The date of the view. * @var string view A view name. * * @return array Array with first and last day of the view. */ viewDates: function(date, view) { var start = date.clone(), end = date.clone(); switch (view) { case 'month': start.setDate(1); start.moveToBeginOfWeek(Kronolith.conf.week_start); end.moveToLastDayOfMonth(); end.moveToEndOfWeek(Kronolith.conf.week_start); break; case 'summary': end.add(6).days(); break; } return [start, end]; }, /** * Creates the month view calendar. * * @param Date date The date to show in the calendar. */ buildCal: function(date) { var tbody = $('.kronolith-minical table tbody'); var dates = KronolithMobile.viewDates(date, 'month'), day = dates[0].clone(), today = Date.today(), dateString, td, tr, i; // Remove old calendar rows. tbody.children().remove(); // Update title $('#kronolithMinicalDate').html(date.toString('MMMM yyyy')); for (i = 0; i < 42; i++) { dateString = day.dateString(); // Create calendar row . if (day.getDay() == Kronolith.conf.week_start) { tr = $('<tr>'); tbody.append(tr); } // Insert day cell. td = $('<td>').attr({ id: 'kronolithMonth' + dateString }) .addClass('kronolithMonthDay') .jqmData('date', dateString); if (day.getMonth() != date.getMonth()) { td.addClass('kronolithMinicalEmpty'); } // Highlight today. if (day.dateString() == today.dateString()) { td.addClass('kronolithToday'); } td.html(day.getDate()); tr.append(td); day.next().day(); } }, /** * Parses a date attribute string into a Date object. * * For other strings use Date.parse(). * * @param string date A yyyyMMdd date string. * * @return Date A date object. */ parseDate: function(date) { var d = new Date(date.substr(0, 4), date.substr(4, 2) - 1, date.substr(6, 2)); if (date.length == 12) { d.setHours(date.substr(8, 2)); d.setMinutes(date.substr(10, 2)); } return d; }, storeCache: function(events, calendar, dates, createCache) { events = events || {}; //calendar[0] == type, calendar[1] == calendar name calendar = calendar.split('|'); if (!KronolithMobile.ecache[calendar[0]]) { if (!createCache) { return; } KronolithMobile.ecache[calendar[0]] = {}; } if (!KronolithMobile.ecache[calendar[0]][calendar[1]]) { if (!createCache) { return; } KronolithMobile.ecache[calendar[0]][calendar[1]] = {}; } var calHash = KronolithMobile.ecache[calendar[0]][calendar[1]]; // Create empty cache entries for all dates. if (!!dates) { var day = dates[0].clone(), date; while (!day.isAfter(dates[1])) { date = day.dateString(); if (!calHash[date]) { if (!createCache) { return; } if (!KronolithMobile.cacheStart || KronolithMobile.cacheStart.isAfter(day)) { KronolithMobile.cacheStart = day.clone(); } if (!KronolithMobile.cacheEnd || KronolithMobile.cacheEnd.isBefore(day)) { KronolithMobile.cacheEnd = day.clone(); } calHash[date] = {}; } day.add(1).day(); } } var cal = calendar.join('|'); $.each(events, function(key, date) { // We might not have a cache for this date if the event lasts // longer than the current view if (typeof calHash[key] == 'undefined') { return; } // Store useful information in event objects. $.each(date, function(k, event) { event.calendar = cal; event.start = Date.parse(event.s); event.end = Date.parse(event.e); event.sort = event.start.toString('HHmmss') + (240000 - parseInt(event.end.toString('HHmmss'), 10)).toPaddedString(6); event.id = k; }); // Store events in cache. $.extend(calHash[key], date); }); }, /** * Return all events for a single day from all displayed calendars merged * into a single hash. * * @param string date A yyyymmdd date string. * * @return Hash An event hash which event ids as keys and event objects as * values. */ getCacheForDate: function(date, calendar) { if (calendar) { var cals = calendar.split('|'); return KronolithMobile.ecache[cals[0]][cals[1]][date]; } var events = {}; $.each(KronolithMobile.ecache, function(key, type) { $.each(type, function(id, cal) { if (!Kronolith.conf.calendars[key][id].show) { return; } if (typeof cal[date] != 'undefined') { $.extend(events, cal[date]); } }); }); return events; }, /** * Handle swipe events for the current view. */ handleSwipe: function(map) { switch (KronolithMobile.view) { case 'day': if (map.type == 'swipeleft') { KronolithMobile.showNextDay(); } else { KronolithMobile.showPrevDay(); } break; case 'month': if (map.type == 'swipeleft') { KronolithMobile.showNextMonth(); } else { KronolithMobile.showPrevMonth(); } } }, /** * Event handler for the pagebeforechange event that implements loading of * deep-linked pages. * * @param object e Event object. * @param object data Event data. */ toPage: function(e, data) { switch (data.options.parsedUrl.view) { case 'minical-next': KronolithMobile.showNextMonth(); e.preventDefault(); break; case 'minical-prev': KronolithMobile.showPrevMonth(); e.preventDefault(); break; case 'nextday': KronolithMobile.showNextDay(); e.preventDefault(); break; case 'prevday': KronolithMobile.showPrevDay(); e.preventDefault(); break; } }, /** */ loadPage: function() { switch (HordeMobile.currentPage()) { case 'monthview': KronolithMobile.view = "month"; // (re)build the minical only if we need to if (!$("#kronolithMinicalDate").jqmData("date") || ($("#kronolithMinicalDate").jqmData("date").toString("M") != KronolithMobile.date.toString("M"))) { KronolithMobile.moveToMonth(KronolithMobile.date); } break; case 'overview': KronolithMobile.view = "overview"; if (!KronolithMobile.haveOverview) { KronolithMobile.loadEvents(KronolithMobile.date, KronolithMobile.date.clone().addDays(7), "overview"); KronolithMobile.haveOverview = true; } break; case null: break; case 'dayview': default: KronolithMobile.view = "day"; $("#kronolithDayDate").html(KronolithMobile.date.toString("ddd") + " " + KronolithMobile.date.toString("d")); KronolithMobile.loadEvents(KronolithMobile.date, KronolithMobile.date, "day"); break; } }, onDocumentReady: function() { KronolithMobile.date = new Date(); // Build list of calendars we want. $.each(Kronolith.conf.calendars, function(key, value) { $.each(value, function(cal, info) { if (info.show) { KronolithMobile.calendars.push([key, cal]); } }); }); // Bind click and swipe events $('body').bind('swipeleft', KronolithMobile.handleSwipe) .bind('swiperight', KronolithMobile.handleSwipe); $(document).bind('pageshow', KronolithMobile.loadPage) .bind('pagebeforechange', KronolithMobile.toPage) .on("pageshow", "#eventview", function(event, ui) { KronolithMobile.view = "event"; }); $('#kronolith-minical').on('click', 'td', function(e) { KronolithMobile.selectMonthDay($(e.target).jqmData('date')); }); // Load initial view. KronolithMobile.loadPage(); } }; $(KronolithMobile.onDocumentReady);
Simpan