mirror of
https://github.com/DMOJ/online-judge.git
synced 2024-11-25 16:32:37 +08:00
341 lines
11 KiB
JavaScript
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);
|
|
});
|
|
});
|