/
blackdragon1
/
HORSE
Обзор
Документация
Войти
/
blackdragon1
/
HORSE
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
script.js
507 строк
18 KB
BLACK_DRAGON
create script.js
07 фев 2026, 13:11
Верифицирован
07 фев 2026, 13:11
d5d24a0
Код
Авторство
О чём код?
// Конфигурация браузера Horse const HORSE_CONFIG = { version: "26.001.0", creator: "blackdragon1", creatorUrl: "https://gitverse.ru/blackdragon1", support: ["Беларусь", "Россия"], searchEngines: { google: { name: "Google", url: "https://www.google.com/search?q=", icon: "fab fa-google", color: "#4285f4" }, yandex: { name: "Яндекс", url: "https://yandex.ru/search/?text=", icon: "fab fa-yandex", color: "#ffcc00" } }, bookmarks: { rutube: { name: "RuTube", url: "https://rutube.ru", icon: "fas fa-play-circle" }, youtube: { name: "YouTube", url: "https://www.youtube.com", icon: "fab fa-youtube" }, github: { name: "GitHub", url: "https://github.com", icon: "fab fa-github" }, vk: { name: "ВКонтакте", url: "https://vk.com", icon: "fab fa-vk" }, telegram: { name: "Telegram", url: "https://telegram.org", icon: "fab fa-telegram" }, google: { name: "Google", url: "https://www.google.com", icon: "fab fa-google" }, yandex: { name: "Яндекс", url: "https://yandex.ru", icon: "fab fa-yandex" }, gitverse: { name: "GitVerse", url: "https://gitverse.ru", icon: "fas fa-code-branch" } } }; // Состояние приложения const AppState = { currentSearchEngine: 'google', searchCount: 0, userCity: 'Определение...', userTimezone: 'Europe/Moscow', isVoiceSearchActive: false, theme: 'dark' }; // DOM элементы const DOM = { cityName: document.getElementById('city-name'), time: document.getElementById('time'), date: document.getElementById('date'), currentTime: document.getElementById('current-time'), weekDay: document.getElementById('week-day'), searchCount: document.getElementById('search-count'), searchInput: document.getElementById('search-input'), searchBtn: document.getElementById('search-btn'), voiceSearchBtn: document.getElementById('voice-search-btn'), engineButtons: document.querySelectorAll('.engine-btn'), themeToggle: document.getElementById('theme-toggle'), clearHistory: document.getElementById('clear-history'), aboutBtn: document.getElementById('about-btn'), aboutModal: document.getElementById('about-modal'), closeModal: document.querySelector('.close-modal'), closeAbout: document.getElementById('close-about'), buildInfo: document.getElementById('build-info'), jsEngine: document.getElementById('js-engine'), browserInfo: document.getElementById('browser-info') }; // Инициализация приложения function initApp() { console.log(`🐎 Horse Browser ${HORSE_CONFIG.version} инициализирован`); // Загрузка сохранённых настроек loadSettings(); // Настройка всех модулей setupClock(); setupSearch(); setupEngineSelector(); setupQuickActions(); setupModals(); setupSystemInfo(); // Анимация загрузки document.body.classList.add('fade-in'); // Обновление статистики updateStats(); } // === ЧАСЫ И ГЕОЛОКАЦИЯ === function setupClock() { function updateClock() { const now = new Date(); const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; AppState.userTimezone = timezone; // Определение города if (AppState.userCity === 'Определение...') { AppState.userCity = getCityFromTimezone(timezone); DOM.cityName.textContent = AppState.userCity; } // Время (формат: 14:30:45) const timeStr = now.toLocaleTimeString('ru-RU', { timeZone: timezone, hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' }); // Дата (формат: Понедельник, 15 января 2024) const dateStr = now.toLocaleDateString('ru-RU', { timeZone: timezone, weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); // Только время (14:30) const shortTimeStr = now.toLocaleTimeString('ru-RU', { timeZone: timezone, hour12: false, hour: '2-digit', minute: '2-digit' }); // День недели const weekDayStr = now.toLocaleDateString('ru-RU', { timeZone: timezone, weekday: 'long' }); // Обновление DOM DOM.time.textContent = timeStr; DOM.date.textContent = dateStr; DOM.currentTime.textContent = shortTimeStr; DOM.weekDay.textContent = weekDayStr; } // Первое обновление updateClock(); // Обновление каждую секунду setInterval(updateClock, 1000); } function getCityFromTimezone(timezone) { const cityMap = { 'Europe/Moscow': 'Москва, Россия', 'Europe/Minsk': 'Минск, Беларусь', 'Europe/Kiev': 'Киев, Украина', 'Europe/London': 'Лондон, Великобритания', 'Europe/Berlin': 'Берлин, Германия', 'Europe/Paris': 'Париж, Франция', 'Europe/Warsaw': 'Варшава, Польша', 'America/New_York': 'Нью-Йорк, США', 'America/Los_Angeles': 'Лос-Анджелес, США', 'Asia/Tokyo': 'Токио, Япония', 'Asia/Shanghai': 'Шанхай, Китай', 'Asia/Almaty': 'Алматы, Казахстан' }; return cityMap[timezone] || timezone.split('/').pop().replace('_', ' '); } // === ПОИСК И ПОИСКОВЫЕ СИСТЕМЫ === function setupSearch() { DOM.searchBtn.addEventListener('click', performSearch); DOM.searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { performSearch(); } }); DOM.voiceSearchBtn.addEventListener('click', toggleVoiceSearch); } function performSearch() { const query = DOM.searchInput.value.trim(); if (!query) { DOM.searchInput.focus(); return; } const engine = HORSE_CONFIG.searchEngines[AppState.currentSearchEngine]; const searchUrl = engine.url + encodeURIComponent(query); // Открытие в новой вкладке window.open(searchUrl, '_blank'); // Обновление статистики AppState.searchCount++; DOM.searchCount.textContent = AppState.searchCount; // Сохранение в историю (упрощённо) saveToSearchHistory(query, engine.name); // Очистка поля DOM.searchInput.value = ''; console.log(`🔍 Поиск через ${engine.name}: ${query}`); } function toggleVoiceSearch() { if (!AppState.isVoiceSearchActive) { startVoiceSearch(); } else { stopVoiceSearch(); } } function startVoiceSearch() { if ('webkitSpeechRecognition' in window || 'SpeechRecognition' in window) { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; const recognition = new SpeechRecognition(); recognition.lang = 'ru-RU'; recognition.continuous = false; recognition.interimResults = false; recognition.onstart = () => { AppState.isVoiceSearchActive = true; DOM.voiceSearchBtn.classList.add('listening'); DOM.voiceSearchBtn.title = 'Слушаю... Скажите ваш запрос'; }; recognition.onresult = (event) => { const transcript = event.results[0][0].transcript; DOM.searchInput.value = transcript; performSearch(); }; recognition.onerror = (event) => { console.error('Ошибка распознавания речи:', event.error); alert('Не удалось распознать речь. Проверьте микрофон и разрешения.'); }; recognition.onend = () => { stopVoiceSearch(); }; recognition.start(); } else { alert('Голосовой поиск не поддерживается вашим браузером'); } } function stopVoiceSearch() { AppState.isVoiceSearchActive = false; DOM.voiceSearchBtn.classList.remove('listening'); DOM.voiceSearchBtn.title = 'Голосовой поиск'; } // === ВЫБОР ПОИСКОВОЙ СИСТЕМЫ === function setupEngineSelector() { DOM.engineButtons.forEach(button => { button.addEventListener('click', () => { const engine = button.dataset.engine; // Сброс активной кнопки DOM.engineButtons.forEach(btn => btn.classList.remove('active')); // Активация выбранной button.classList.add('active'); AppState.currentSearchEngine = engine; // Обновление placeholder updateSearchPlaceholder(); // Сохранение в настройки saveSettings(); // Анимация button.style.transform = 'scale(0.95)'; setTimeout(() => { button.style.transform = ''; }, 150); }); }); } function updateSearchPlaceholder() { const engine = HORSE_CONFIG.searchEngines[AppState.currentSearchEngine]; DOM.searchInput.placeholder = `Поиск в ${engine.name}...`; } // === БЫСТРЫЕ ДЕЙСТВИЯ И НАСТРОЙКИ === function setupQuickActions() { // Переключение темы DOM.themeToggle?.addEventListener('click', toggleTheme); // Очистка истории DOM.clearHistory?.addEventListener('click', () => { if (confirm('Очистить всю историю поиска и настройки?')) { localStorage.clear(); AppState.searchCount = 0; DOM.searchCount.textContent = '0'; alert('История очищена!'); } }); // Автофокус на поисковую строку DOM.searchInput.focus(); // Сохранение при закрытии window.addEventListener('beforeunload', saveSettings); } function toggleTheme() { const body = document.body; const currentTheme = body.getAttribute('data-theme') || 'dark'; const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; body.setAttribute('data-theme', newTheme); AppState.theme = newTheme; // Обновление иконки const icon = DOM.themeToggle.querySelector('i'); if (newTheme === 'dark') { icon.className = 'fas fa-moon'; DOM.themeToggle.innerHTML = '<i class="fas fa-moon"></i> Тёмная тема'; } else { icon.className = 'fas fa-sun'; DOM.themeToggle.innerHTML = '<i class="fas fa-sun"></i> Светлая тема'; } saveSettings(); console.log(`🎨 Тема изменена: ${newTheme}`); } // === МОДАЛЬНЫЕ ОКНА === function setupModals() { // Открытие модального окна "О браузере" DOM.aboutBtn?.addEventListener('click', () => { DOM.aboutModal.style.display = 'flex'; document.body.style.overflow = 'hidden'; }); // Закрытие модального окна DOM.closeModal?.addEventListener('click', closeModals); DOM.closeAbout?.addEventListener('click', closeModals); // Закрытие при клике вне окна DOM.aboutModal?.addEventListener('click', (e) => { if (e.target === DOM.aboutModal) { closeModals(); } }); // Закрытие клавишей ESC document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeModals(); } }); } function closeModals() { if (DOM.aboutModal) { DOM.aboutModal.style.display = 'none'; document.body.style.overflow = 'auto'; } } // === СИСТЕМНАЯ ИНФОРМАЦИЯ === function setupSystemInfo() { // Информация о браузере пользователя const userAgent = navigator.userAgent; const browserInfo = detectBrowser(userAgent); if (DOM.browserInfo) { DOM.browserInfo.textContent = `${browserInfo.name} ${browserInfo.version} | ${navigator.platform}`; } // Информация о сборке if (DOM.buildInfo) { const buildDate = new Date().toLocaleDateString('ru-RU', { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' }); DOM.buildInfo.textContent = buildDate; } // Движок JavaScript if (DOM.jsEngine) { DOM.jsEngine.textContent = 'V8 (Chrome/Edge)'; } } function detectBrowser(userAgent) { if (userAgent.includes('Chrome') && !userAgent.includes('Edg')) { return { name: 'Chrome', version: userAgent.match(/Chrome\/(\d+)/)?.[1] || '?' }; } else if (userAgent.includes('Firefox')) { return { name: 'Firefox', version: userAgent.match(/Firefox\/(\d+)/)?.[1] || '?' }; } else if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) { return { name: 'Safari', version: userAgent.match(/Version\/(\d+)/)?.[1] || '?' }; } else if (userAgent.includes('Edg')) { return { name: 'Edge', version: userAgent.match(/Edg\/(\d+)/)?.[1] || '?' }; } else { return { name: 'Браузер', version: 'Неизвестно' }; } } // === СИСТЕМА НАСТРОЕК === function loadSettings() { try { const saved = JSON.parse(localStorage.getItem('horse_browser_settings')); if (saved) { AppState.currentSearchEngine = saved.currentSearchEngine || 'google'; AppState.searchCount = saved.searchCount || 0; AppState.theme = saved.theme || 'dark'; // Применение темы if (AppState.theme === 'light') { document.body.setAttribute('data-theme', 'light'); DOM.themeToggle.innerHTML = '<i class="fas fa-sun"></i> Светлая тема'; } // Применение поисковой системы const button = document.querySelector(`[data-engine="${AppState.currentSearchEngine}"]`); if (button) { DOM.engineButtons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); updateSearchPlaceholder(); } console.log('⚙️ Настройки загружены'); } } catch (e) { console.warn('Не удалось загрузить настройки:', e); } } function saveSettings() { const settings = { currentSearchEngine: AppState.currentSearchEngine, searchCount: AppState.searchCount, theme: AppState.theme, lastSave: new Date().toISOString() }; try { localStorage.setItem('horse_browser_settings', JSON.stringify(settings)); console.log('💾 Настройки сохранены'); } catch (e) { console.error('Ошибка сохранения настроек:', e); } } function saveToSearchHistory(query, engine) { try { const history = JSON.parse(localStorage.getItem('horse_search_history')) || []; history.unshift({ query, engine, timestamp: new Date().toISOString() }); // Ограничение истории 100 записями if (history.length > 100) { history.pop(); } localStorage.setItem('horse_search_history', JSON.stringify(history)); } catch (e) { console.warn('Не удалось сохранить историю поиска:', e); } } // === СТАТИСТИКА === function updateStats() { DOM.searchCount.textContent = AppState.searchCount; } // === ЗАПУСК ПРИЛОЖЕНИЯ === document.addEventListener('DOMContentLoaded', initApp); // Глобальные функции для доступа из консоли window.HorseBrowser = { version: HORSE_CONFIG.version, getConfig: () => HORSE_CONFIG, getState: () => AppState, resetSettings: () => { localStorage.clear(); location.reload(); }, getSearchHistory: () => { return JSON.parse(localStorage.getItem('horse_search_history')) || []; } }; console.log(` ███████╗██╗ ██╗██████╗ ███████╗███████╗ ██╔════╝██║ ██║██╔══██╗██╔════╝██╔════╝ ███████╗███████║██████╔╝█████╗ ███████╗ ╚════██║██╔══██║██╔══██╗██╔══╝ ╚════██║ ███████║██║ ██║██║ ██║███████╗███████║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝ Horse Browser ${HORSE_CONFIG.version} Готов к работе! `);