online-judge/resources/common.js
2023-01-23 00:22:20 -05:00

341 lines
11 KiB
JavaScript

if (!String.prototype.startsWith) {
String.prototype.startsWith = function (searchString, position) {
return this.substr(position || 0, searchString.length) === searchString;
};
}
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (searchString, position) {
var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.lastIndexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
// http://stackoverflow.com/a/1060034/1090657
$(function () {
var hidden = 'hidden';
// Standards:
if (hidden in document)
document.addEventListener('visibilitychange', onchange);
else if ((hidden = 'mozHidden') in document)
document.addEventListener('mozvisibilitychange', onchange);
else if ((hidden = 'webkitHidden') in document)
document.addEventListener('webkitvisibilitychange', onchange);
else if ((hidden = 'msHidden') in document)
document.addEventListener('msvisibilitychange', onchange);
// IE 9 and lower:
else if ('onfocusin' in document)
document.onfocusin = document.onfocusout = onchange;
// All others:
else
window.onpageshow = window.onpagehide
= window.onfocus = window.onblur = onchange;
function onchange(evt) {
var v = 'window-visible', h = 'window-hidden', evtMap = {
focus: v, focusin: v, pageshow: v, blur: h, focusout: h, pagehide: h
};
evt = evt || window.event;
if (evt.type in evtMap)
document.body.className = evtMap[evt.type];
else
document.body.className = this[hidden] ? 'window-hidden' : 'window-visible';
if ('$' in window)
$(window).trigger('dmoj:' + document.body.className);
}
// set the initial state (but only if browser supports the Page Visibility API)
if (document[hidden] !== undefined)
onchange({type: document[hidden] ? 'blur' : 'focus'});
});
function register_toggle(link) {
link.click(function () {
var toggled = link.next('.toggled');
if (toggled.is(':visible')) {
toggled.hide(400);
link.removeClass('open');
link.addClass('closed');
} else {
toggled.show(400);
link.addClass('open');
link.removeClass('closed');
}
});
}
$(function register_all_toggles() {
$('.toggle').each(function () {
register_toggle($(this));
});
});
function featureTest(property, value, noPrefixes) {
var prop = property + ':',
el = document.createElement('test'),
mStyle = el.style;
if (!noPrefixes) {
mStyle.cssText = prop + ['-webkit-', '-moz-', '-ms-', '-o-', ''].join(value + ';' + prop) + value + ';';
} else {
mStyle.cssText = prop + value;
}
return !!mStyle[property];
}
window.fix_div = function (div, height) {
var div_offset = div.offset().top - $('html').offset().top;
var is_moving;
var moving = function () {
div.css('position', 'absolute').css('top', div_offset);
is_moving = true;
};
var fix = function () {
div.css('position', 'fixed').css('top', height);
is_moving = false;
};
($(window).scrollTop() - div_offset > -height) ? fix() : moving();
$(window).scroll(function () {
if (($(window).scrollTop() - div_offset > -height) == is_moving)
is_moving ? fix() : moving();
});
};
$(function () {
if (typeof window.orientation !== 'undefined') {
$(window).resize(function () {
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
$('#viewport').attr('content', width > 480 ? 'initial-scale=1' : 'width=480');
});
}
var $nav_list = $('#nav-list');
$('#navicon').click(function (event) {
event.stopPropagation();
$nav_list.toggleClass('show-list');
if ($nav_list.is(':hidden'))
$(this).blur().removeClass('hover');
else {
$(this).addClass('hover');
}
}).hover(function () {
$(this).addClass('hover');
}, function () {
$(this).removeClass('hover');
});
$nav_list.find('li a .nav-expand').click(function (event) {
event.preventDefault();
$(this).parent().siblings('ul').toggleClass('show-list');
});
$nav_list.find('li a').each(function () {
if (!$(this).siblings('ul').length)
return;
$(this).on('contextmenu', function (event) {
event.preventDefault();
}).on('taphold', function () {
$(this).siblings('ul').css('display', 'block');
});
});
$nav_list.click(function (event) {
event.stopPropagation();
});
$('html').click(function () {
$nav_list.removeClass('show-list');
});
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!(/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type)) && !this.crossDomain)
xhr.setRequestHeader('X-CSRFToken', $.cookie('csrftoken'));
}
});
});
if (!Date.now) {
Date.now = function () {
return new Date().getTime();
};
}
function count_down(label) {
var initial = parseInt(label.attr('data-secs'));
var start = Date.now();
function format(num) {
var s = "0" + num;
return s.substr(s.length - 2);
}
var timer = setInterval(function () {
var time = Math.round(initial - (Date.now() - start) / 1000);
if (time <= 0) {
clearInterval(timer);
setTimeout(function() {
window.location.reload();
}, 2000);
}
var d = Math.floor(time / 86400);
var h = Math.floor(time % 86400 / 3600);
var m = Math.floor(time % 3600 / 60);
var s = time % 60;
if (d > 0)
label.text(npgettext('time format with day', '%d day %h:%m:%s', '%d days %h:%m:%s', d)
.replace('%d', d).replace('%h', format(h)).replace('%m', format(m)).replace('%s', format(s)));
else
label.text(pgettext('time format without day', '%h:%m:%s')
.replace('%h', format(h)).replace('%m', format(m)).replace('%s', format(s)));
}, 1000);
}
function set_date_locale(language_code) {
if (typeof Intl !== 'undefined' && !!Intl.RelativeTimeFormat && !!Math.trunc) {
var rtf = new Intl.RelativeTimeFormat(language_code);
window.format_ms = function (amount) {
amount = Math.trunc(amount / 1000); // seconds
if (Math.abs(amount) < 120) return rtf.format(amount, 'second');
amount = Math.trunc(amount / 60); // minutes
if (Math.abs(amount) < 180) return rtf.format(amount, 'minute');
amount = Math.trunc(amount / 60); // hours
if (Math.abs(amount) < 48) return rtf.format(amount, 'hour');
amount = Math.trunc(amount / 24); // days
if (Math.abs(amount) < 100) return rtf.format(amount, 'day');
return ''; // beyond 100 days, use absolute time
};
} else {
window.format_ms = function () {
return '';
};
}
}
function register_time(elems) {
elems.each(function () {
var outdated = false;
var $this = $(this);
var time = Date.parse($this.attr('data-iso'));
var rel_format = $this.attr('data-format');
var abs = $this.text();
function update() {
if ($('body').hasClass('window-hidden'))
return outdated = true;
outdated = false;
var msg = window.format_ms(time - Date.now());
if (!msg) {
$this.text(abs);
return;
}
$this.text(rel_format.replace('{time}', msg));
setTimeout(update, 10000);
}
$(window).on('dmoj:window-visible', function () {
if (outdated)
update();
});
update();
});
}
$(function () {
register_time($('.time-with-rel'));
$('form').submit(function (evt) {
// Prevent multiple submissions of forms, see #565, #1776
$("button[type=submit], input[type=submit]").prop('disabled', true);
});
});
window.notification_template = {
icon: '/logo.png'
};
window.notification_timeout = 5000;
window.notify = function (type, title, data, timeout) {
if (localStorage[type + '_notification'] != 'true') return;
var template = window[type + '_notification_template'] || window.notification_template;
var data = (typeof data !== 'undefined' ? $.extend({}, template, data) : template);
var object = new Notification(title, data);
if (typeof timeout === 'undefined')
timeout = window.notification_timeout;
if (timeout)
setTimeout(function () {
object.close();
}, timeout);
return object;
};
window.register_notify = function (type, options) {
if (typeof options === 'undefined')
options = {};
function status_change() {
if ('change' in options)
options.change(localStorage[key] == 'true');
}
var key = type + '_notification';
if ('Notification' in window) {
if (!(key in localStorage) || Notification.permission !== 'granted')
localStorage[key] = 'false';
if ('$checkbox' in options) {
options.$checkbox.change(function () {
var status = $(this).is(':checked');
if (status) {
if (Notification.permission === 'granted') {
localStorage[key] = 'true';
notify(type, 'Notification enabled!');
status_change();
} else
Notification.requestPermission(function (permission) {
if (permission === 'granted') {
localStorage[key] = 'true';
notify(type, 'Notification enabled!');
} else localStorage[key] = 'false';
status_change();
});
} else {
localStorage[key] = 'false';
status_change();
}
}).prop('checked', localStorage[key] == 'true');
}
$(window).on('storage', function (e) {
e = e.originalEvent;
if (e.key === key) {
if ('$checkbox' in options)
options.$checkbox.prop('checked', e.newValue == 'true');
status_change();
}
});
} else {
if ('$checkbox' in options) options.$checkbox.hide();
localStorage[key] = 'false';
}
status_change();
};
$(function () {
// Close dismissable boxes
$("a.close").click(function () {
var $closer = $(this);
$closer.parent().fadeOut(200);
});
});