mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-08-01 23:19:33 +08:00
407 lines
16 KiB
JavaScript
407 lines
16 KiB
JavaScript
(function ($) {
|
|
function applySafeAreaFix() {
|
|
var url = self.location.href;
|
|
|
|
// 修复某些插件导致在 https 下 env(safe-area-inset-bottom) 为 0 的情况
|
|
if ((/(iPhone|iPad|iPod|iOS|Mac|Macintosh)/i.test(navigator.userAgent)) && url.indexOf("openclash") !== -1) {
|
|
var oMeta = document.createElement('meta');
|
|
oMeta.content = 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover';
|
|
oMeta.name = 'viewport';
|
|
document.getElementsByTagName('head')[0].appendChild(oMeta);
|
|
}
|
|
}
|
|
|
|
function setHeaderShadow() {
|
|
if (window.innerWidth <= 992) {
|
|
$("header").css("box-shadow", "0 2px 4px rgb(0 0 0 / 8%)");
|
|
} else {
|
|
$("header").css("box-shadow", "17rem 2px 4px rgb(0 0 0 / 8%)");
|
|
}
|
|
}
|
|
|
|
function syncIndicators() {
|
|
var indicatorRoot = document.getElementById("indicators");
|
|
|
|
if (!indicatorRoot) {
|
|
return;
|
|
}
|
|
|
|
Array.prototype.forEach.call(indicatorRoot.querySelectorAll('[data-indicator]'), function (indicator) {
|
|
var id = indicator.getAttribute('data-indicator');
|
|
var label = (indicator.textContent || '').trim();
|
|
|
|
if (!label) {
|
|
label = indicator.getAttribute('aria-label') || indicator.getAttribute('title') || '';
|
|
}
|
|
|
|
if (id === 'poll-status') {
|
|
indicator.setAttribute('title', label);
|
|
indicator.setAttribute('aria-label', label);
|
|
} else if (id === 'uci-changes') {
|
|
var match = label.match(/(\d+)\s*$/);
|
|
|
|
indicator.setAttribute('title', label);
|
|
indicator.setAttribute('aria-label', label);
|
|
indicator.setAttribute('data-count', match ? match[1] : '');
|
|
}
|
|
});
|
|
}
|
|
|
|
function initIndicators() {
|
|
var indicatorRoot = document.getElementById("indicators");
|
|
|
|
if (!indicatorRoot) {
|
|
return;
|
|
}
|
|
|
|
syncIndicators();
|
|
|
|
new MutationObserver(syncIndicators).observe(indicatorRoot, {
|
|
childList: true,
|
|
subtree: true,
|
|
characterData: true,
|
|
attributes: true,
|
|
attributeFilter: ['data-style']
|
|
});
|
|
}
|
|
|
|
function getOverviewPortColumns(width, cardCount) {
|
|
if (width <= 480) {
|
|
return 1;
|
|
}
|
|
|
|
if (width <= 768) {
|
|
return Math.min(cardCount, 2);
|
|
}
|
|
|
|
return Math.min(cardCount, 8);
|
|
}
|
|
|
|
function syncOverviewPortStatus() {
|
|
var view = document.getElementById('view');
|
|
var portGroups = new Map();
|
|
var mediaPath = (L.env && L.env.media) ? L.env.media : '/luci-static/design';
|
|
var iconMap = {
|
|
'alias': 'ethernet',
|
|
'alias_disabled': 'ethernet_disabled',
|
|
'bridge': 'bridge',
|
|
'bridge_disabled': 'bridge_disabled',
|
|
'ethernet': 'ethernet',
|
|
'ethernet_disabled': 'ethernet_disabled',
|
|
'switch': 'switch',
|
|
'switch_disabled': 'switch_disabled',
|
|
'tunnel': 'tunnel',
|
|
'tunnel_disabled': 'tunnel_disabled',
|
|
'vlan': 'vlan',
|
|
'vlan_disabled': 'vlan_disabled',
|
|
'wifi': 'wifi',
|
|
'wifi_disabled': 'wifi_disabled',
|
|
'signal-none': 'signal-none',
|
|
'signal-0': 'signal-0',
|
|
'signal-0-25': 'signal-0-25',
|
|
'signal-25-50': 'signal-25-50',
|
|
'signal-50-75': 'signal-50-75',
|
|
'signal-75-100': 'signal-75-100',
|
|
'signal-000-000': 'signal-0',
|
|
'signal-000-025': 'signal-0-25',
|
|
'signal-025-050': 'signal-25-50',
|
|
'signal-050-075': 'signal-50-75',
|
|
'signal-075-100': 'signal-75-100',
|
|
'port_up': 'port_up',
|
|
'port_down': 'port_down'
|
|
};
|
|
|
|
if (!view || document.body.getAttribute('data-page') !== 'admin-status-overview') {
|
|
return;
|
|
}
|
|
|
|
Array.prototype.forEach.call(view.querySelectorAll('img[src*="/luci-static/resources/icons/"]'), function (img) {
|
|
var src = img.getAttribute('src') || '';
|
|
var match = src.match(/\/icons\/([^/?#]+)\.(?:png|svg)(?:[?#].*)?$/);
|
|
var key = match ? match[1] : '';
|
|
var mapped = iconMap[key];
|
|
var badge = img.closest('.ifacebadge');
|
|
|
|
if (!mapped || !badge) {
|
|
return;
|
|
}
|
|
|
|
var size = key.indexOf('port_') === 0 ? '18px' :
|
|
key.indexOf('signal-') === 0 ? '16px' : '20px';
|
|
|
|
img.setAttribute('src', mediaPath + '/images/' + mapped + '.png');
|
|
img.style.setProperty('background-image', 'none', 'important');
|
|
img.style.setProperty('visibility', 'visible', 'important');
|
|
img.style.setProperty('opacity', '1', 'important');
|
|
img.style.setProperty('display', 'inline-block', 'important');
|
|
img.style.setProperty('width', size, 'important');
|
|
img.style.setProperty('height', size, 'important');
|
|
img.style.setProperty('min-width', size, 'important');
|
|
img.style.setProperty('padding', '0', 'important');
|
|
img.style.setProperty('margin', '0 .25rem 0 0', 'important');
|
|
img.style.setProperty('vertical-align', 'middle', 'important');
|
|
img.style.setProperty('object-fit', 'contain', 'important');
|
|
});
|
|
|
|
Array.prototype.forEach.call(view.querySelectorAll('.cbi-section > div'), function (grid) {
|
|
var isPortGrid = grid &&
|
|
grid.style &&
|
|
grid.style.display === 'grid' &&
|
|
grid.style.gridTemplateColumns.indexOf('minmax(70px, 1fr)') !== -1 &&
|
|
grid.querySelector('img[src*="/luci-static/resources/icons/port_"]');
|
|
|
|
if (!isPortGrid) {
|
|
return;
|
|
}
|
|
|
|
grid.classList.add('port-status-grid');
|
|
|
|
Array.prototype.forEach.call(grid.querySelectorAll('.ifacebox'), function (card) {
|
|
card.classList.add('port-status-card');
|
|
});
|
|
});
|
|
|
|
Array.prototype.forEach.call(view.querySelectorAll('img[src*="/luci-static/resources/icons/port_"]'), function (img) {
|
|
var card = img.closest('.ifacebox');
|
|
var slot = card ? card.closest('.port-status-slot') : null;
|
|
var parent = card ? (slot ? slot.parentElement : card.parentElement) : null;
|
|
var iconType = (img.getAttribute('src') || '').indexOf('port_down.png') !== -1 ? 'down' : 'up';
|
|
var badge = img.closest('.ifacebadge');
|
|
|
|
if (badge) {
|
|
img.setAttribute('src', mediaPath + '/images/port_' + iconType + '.png');
|
|
}
|
|
|
|
if (!card || !parent) {
|
|
return;
|
|
}
|
|
|
|
img.setAttribute('src', mediaPath + '/images/port_' + iconType + '.png');
|
|
img.style.setProperty('display', 'block', 'important');
|
|
img.style.setProperty('width', '24px', 'important');
|
|
img.style.setProperty('height', '24px', 'important');
|
|
img.style.setProperty('padding', '0', 'important');
|
|
img.style.setProperty('margin', '0.05rem auto', 'important');
|
|
|
|
if (img.nextElementSibling && img.nextElementSibling.tagName === 'BR') {
|
|
img.nextElementSibling.style.setProperty('display', 'none', 'important');
|
|
}
|
|
|
|
if (!portGroups.has(parent)) {
|
|
portGroups.set(parent, []);
|
|
}
|
|
|
|
if (portGroups.get(parent).indexOf(card) === -1) {
|
|
portGroups.get(parent).push(card);
|
|
}
|
|
});
|
|
|
|
portGroups.forEach(function (cards, parent) {
|
|
var width = window.innerWidth || document.documentElement.clientWidth || 1280;
|
|
var columns = getOverviewPortColumns(width, cards.length);
|
|
|
|
cards.forEach(function (card) {
|
|
var body = card.querySelector('.ifacebox-body');
|
|
var slot = card.parentElement;
|
|
|
|
if (!slot || !slot.classList.contains('port-status-slot')) {
|
|
slot = document.createElement('div');
|
|
slot.className = 'port-status-slot';
|
|
parent.insertBefore(slot, card);
|
|
slot.appendChild(card);
|
|
}
|
|
|
|
card.classList.add('port-status-card');
|
|
|
|
slot.style.setProperty('display', 'flex', 'important');
|
|
slot.style.setProperty('justify-content', 'center', 'important');
|
|
slot.style.setProperty('align-items', 'stretch', 'important');
|
|
slot.style.setProperty('min-width', '0', 'important');
|
|
slot.style.setProperty('padding', '0.15rem 0.65rem 0.75rem', 'important');
|
|
|
|
card.style.setProperty('margin', '0', 'important');
|
|
card.style.setProperty('min-width', '76px', 'important');
|
|
card.style.setProperty('max-width', '108px', 'important');
|
|
card.style.setProperty('width', 'fit-content', 'important');
|
|
card.style.setProperty('text-align', 'center', 'important');
|
|
|
|
if (body) {
|
|
body.style.setProperty('text-align', 'center', 'important');
|
|
body.style.setProperty('align-items', 'center', 'important');
|
|
body.style.setProperty('justify-content', 'center', 'important');
|
|
}
|
|
});
|
|
|
|
parent.style.setProperty('display', 'grid', 'important');
|
|
parent.style.setProperty('grid-template-columns', 'repeat(' + columns + ', minmax(0, 1fr))', 'important');
|
|
parent.style.setProperty('align-items', 'stretch', 'important');
|
|
parent.style.setProperty('justify-items', 'stretch', 'important');
|
|
parent.style.setProperty('width', '100%', 'important');
|
|
parent.style.setProperty('max-width', '100%', 'important');
|
|
parent.style.setProperty('padding', '0.2rem 0.6rem 0.35rem', 'important');
|
|
parent.style.setProperty('margin', '0 auto 1rem', 'important');
|
|
parent.style.setProperty('row-gap', '0.2rem', 'important');
|
|
parent.style.setProperty('column-gap', '0', 'important');
|
|
});
|
|
}
|
|
|
|
function initOverviewPortStatus() {
|
|
var view = document.getElementById('view');
|
|
|
|
if (!view || document.body.getAttribute('data-page') !== 'admin-status-overview') {
|
|
return;
|
|
}
|
|
|
|
syncOverviewPortStatus();
|
|
|
|
new MutationObserver(syncOverviewPortStatus).observe(view, {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
|
|
window.addEventListener('resize', syncOverviewPortStatus);
|
|
}
|
|
|
|
function syncNetworkInterfaceIcons() {
|
|
var view = document.getElementById('view');
|
|
var mediaPath = (L.env && L.env.media) ? L.env.media : '/luci-static/design';
|
|
var iconMap = {
|
|
'alias': 'ethernet',
|
|
'alias_disabled': 'ethernet_disabled',
|
|
'bridge': 'bridge',
|
|
'bridge_disabled': 'bridge_disabled',
|
|
'ethernet': 'ethernet',
|
|
'ethernet_disabled': 'ethernet_disabled',
|
|
'switch': 'switch',
|
|
'switch_disabled': 'switch_disabled',
|
|
'tunnel': 'tunnel',
|
|
'tunnel_disabled': 'tunnel_disabled',
|
|
'vlan': 'vlan',
|
|
'vlan_disabled': 'vlan_disabled',
|
|
'wifi': 'wifi',
|
|
'wifi_disabled': 'wifi_disabled'
|
|
};
|
|
|
|
if (!view || document.body.getAttribute('data-page') !== 'admin-network-network') {
|
|
return;
|
|
}
|
|
|
|
Array.prototype.forEach.call(view.querySelectorAll('img[src*="/luci-static/resources/icons/"]'), function (img) {
|
|
var src = img.getAttribute('src') || '';
|
|
var match = src.match(/\/icons\/([^/?#]+)\.(?:png|svg)(?:[?#].*)?$/);
|
|
var key = match ? match[1] : '';
|
|
var mapped = iconMap[key];
|
|
|
|
if (!mapped) {
|
|
return;
|
|
}
|
|
|
|
img.setAttribute('src', mediaPath + '/images/' + mapped + '.png');
|
|
img.classList.add('theme-network-icon');
|
|
img.style.setProperty('background-image', 'none', 'important');
|
|
img.style.setProperty('object-fit', 'contain', 'important');
|
|
});
|
|
}
|
|
|
|
function initNetworkInterfaceIcons() {
|
|
var view = document.getElementById('view');
|
|
|
|
if (!view || document.body.getAttribute('data-page') !== 'admin-network-network') {
|
|
return;
|
|
}
|
|
|
|
syncNetworkInterfaceIcons();
|
|
|
|
new MutationObserver(syncNetworkInterfaceIcons).observe(view, {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
}
|
|
|
|
function syncWirelessIcons() {
|
|
var mediaPath = (L.env && L.env.media) ? L.env.media : '/luci-static/design';
|
|
var iconMap = {
|
|
'wifi': 'wifi_big',
|
|
'wifi_disabled': 'wifi_big_disabled',
|
|
'signal-none': 'signal-none',
|
|
'signal-0': 'signal-0',
|
|
'signal-0-25': 'signal-0-25',
|
|
'signal-25-50': 'signal-25-50',
|
|
'signal-50-75': 'signal-50-75',
|
|
'signal-75-100': 'signal-75-100',
|
|
'signal-000-000': 'signal-0',
|
|
'signal-000-025': 'signal-0-25',
|
|
'signal-025-050': 'signal-25-50',
|
|
'signal-050-075': 'signal-50-75',
|
|
'signal-075-100': 'signal-75-100'
|
|
};
|
|
|
|
if (document.body.getAttribute('data-page') !== 'admin-network-wireless') {
|
|
return;
|
|
}
|
|
|
|
Array.prototype.forEach.call(document.querySelectorAll('img[src*="/luci-static/resources/icons/"]'), function (img) {
|
|
var src = img.getAttribute('src') || '';
|
|
var match = src.match(/\/icons\/([^/?#]+)\.(?:png|svg)(?:[?#].*)?$/);
|
|
var key = match ? match[1] : '';
|
|
var inAssocList = !!img.closest('#wifi_assoclist_table');
|
|
var mapped = iconMap[key];
|
|
var badge = img.closest('.ifacebadge') || img.closest('.center');
|
|
var isDeviceIcon = (key === 'wifi' || key === 'wifi_disabled');
|
|
var size = isDeviceIcon ? '64px' : '18px';
|
|
|
|
if (!mapped || !badge) {
|
|
return;
|
|
}
|
|
|
|
if (inAssocList && isDeviceIcon) {
|
|
mapped = key;
|
|
size = '16px';
|
|
}
|
|
|
|
img.setAttribute('src', mediaPath + '/images/' + mapped + '.png');
|
|
img.classList.add('theme-wireless-icon');
|
|
img.style.setProperty('background-image', 'none', 'important');
|
|
img.style.setProperty('visibility', 'visible', 'important');
|
|
img.style.setProperty('opacity', '1', 'important');
|
|
img.style.setProperty('display', 'inline-block', 'important');
|
|
img.style.setProperty('width', size, 'important');
|
|
img.style.setProperty('height', size, 'important');
|
|
img.style.setProperty('min-width', size, 'important');
|
|
img.style.setProperty('padding', '0', 'important');
|
|
img.style.setProperty('margin', (inAssocList && isDeviceIcon) ? '0 .2rem 0 0' : (isDeviceIcon ? '0 .3rem 0 0' : '0 .25rem 0 0'), 'important');
|
|
img.style.setProperty('vertical-align', 'middle', 'important');
|
|
img.style.setProperty('object-fit', 'contain', 'important');
|
|
});
|
|
}
|
|
|
|
function initWirelessIcons() {
|
|
if (document.body.getAttribute('data-page') !== 'admin-network-wireless') {
|
|
return;
|
|
}
|
|
|
|
syncWirelessIcons();
|
|
|
|
new MutationObserver(syncWirelessIcons).observe(document.body, {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
}
|
|
|
|
function init() {
|
|
applySafeAreaFix();
|
|
initIndicators();
|
|
initOverviewPortStatus();
|
|
initNetworkInterfaceIcons();
|
|
initWirelessIcons();
|
|
setHeaderShadow();
|
|
$(window).on('resize', setHeaderShadow);
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
})(jQuery);
|