<
  • Главная
Статьи

Як створити свій власний браузер для Windows 10 на HTML і JavaScript

  1. створюємо браузер
  2. інтерфейс користувача
  3. Додаткова функціональність
  4. Використання WebView
  5. Розробка браузера
  6. Управління кнопками назад і вперед
  7. Управління кнопками поновлення і зупинки
  8. Управління адресним рядком
  9. відображення favicon
  10. Підтримка комбінацій клавіш
  11. Зовнішній вигляд браузера
  12. Брендування заголовка
  13. Інші можливості
  14. Вихідний код
  15. Створіть свій додаток для Windows 10

Вам знадобиться

Для розробки під Windows вам знадобитися наступне ПО:

Пробна версія Windows 10 Пробна версія Windows 10

Спробуйте нову версію ОС.

Visual Studio Visual Studio

Visual Studio - це інтегроване середовище розробки з широкими можливостями для створення приголомшливих додатків для Windows, Android і iOS, а також сучасних веб-додатків і хмарних служб.

Microsoft Microsoft .NET Framework 4.6

Пакет многоплатформенного націлювання .NET Framework 4.6 дозволяє розробникам створювати додатки для .NET Framework 4.6, використовуючи Visual Studio або сторонні IDE.

Дата публікації: 30.10.2015

За останні кілька місяців ми внесли безліч поліпшень в движок рендеринга Microsoft Edge (EdgeHTML), роблячи особливий акцент на сумісності з сучасними браузерами і відповідно новим і прийдешнім стандартам. Крім того, що EdgeHTML лежить в основі браузера Microsoft Edge, він також доступний для додатків на Universal Windows Platform (UWP) через елемент управління WebView . Сьогодні ми хочемо розповісти, як можна використовувати WebView для створення свого браузера в Windows 10.
Використовуючи стандартні веб-технології, включаючи JavaScript, HTML і CSS, ми створили просте UWP-додаток, що містить усередині WebView і реалізує базову функціональність: навігацію і роботу з обраним. Подібні прийоми можуть бути використані в будь-якому UWP-додатку для прозорої інтеграції веб-контенту.
За останні кілька місяців ми внесли   безліч поліпшень   в   движок рендеринга Microsoft Edge   (EdgeHTML), роблячи особливий акцент на сумісності з сучасними браузерами і відповідно новим і прийдешнім стандартам
В основі нашого прикладу лежить потужний елемент управління WebView. Крім комплексного набору API, даний елемент також дозволяє подолати деякі обмеження , Властиві iframe, наприклад, відстеження фреймів (коли певний сайт змінює свою поведінку в разі виконання всередині iframe) і складність визначення завантаження документа. На додаток x-ms-webview , - так WebView задається в HTML, - дає доступ до функціональності, не доступної в iframe, зокрема, полегшений доступ до локального контенту і можливості робити знімки вмісту. Коли ви використовуєте елемент управління WebView, ви отримуєте той же самий движок, що і в Microsoft Edge.

створюємо браузер

Як було написано вище, браузер базується на елементі управління WebView для HTML, а для створення і пожвавлення призначеного для користувача інтерфейсу в основному використовується JavaScript. Проект створений в Visual Studio 2015 і являє собою універсальне Windows-додаток на JavaScript.
Крім JavaScript, ми також використовували трохи HTML і CSS, а також деяку кількість рядків коду на C ++ для підтримки комбінацій клавіш, але це не потрібно в простому випадку.
Також ми користуємося новими можливостями нового ECMAScript 2015 (ES2015), підтримуваними в Chakra, JavaScript-движку, що працює в Microsoft Edge і елементі управління WebView. ES2015 дозволив нам скоротити кількість генерованого і шаблонного коду, тим самим істотно спростивши реалізацію ідеї. Ми використовували такі можливості ES2015 при створенні програми: Array.from () , Array.prototype.find () , arrow functions , method properties , const , for-of , let , Map , Object.assign () , Promises , property shorthands , Proxies , spread operator , String.prototype.includes () , String.prototype.startsWith () , Symbols , template strings і Unicode code point escapes .

інтерфейс користувача

Інтерфейс включає наступні десять компонентів:

  • Заголовок
  • кнопка назад
  • кнопка вперед
  • кнопка поновлення
  • Favicon
  • Адресний рядок
  • Кнопка «поширюють в Твіттері»
  • Кнопка і меню вибраного
  • Кнопка і меню налаштувань
  • Елемент управління WebView


Заголовок   кнопка назад   кнопка вперед   кнопка поновлення   Favicon   Адресний рядок   Кнопка «поширюють в Твіттері»   Кнопка і меню вибраного   Кнопка і меню налаштувань   Елемент управління WebView

Додаткова функціональність

Ми також реалізували кілька додаткових можливостей, щоб зробити роботу з браузером ще більш приємною:

  • Сполучення клавіш: натискання F11 переводить в повноекранний режим, ESC виходить з повноекранного режиму, Ctrl + L виділяє адресний рядок,
  • CSS transitions для анімації меню,
  • Управління кешем,
  • Управління обраним,
  • Аналіз вводяться адрес - наприклад, "bing.com" переводить на http (s): //bing.com, а "seahawks" шукає в Bing,
  • Автоматична зміна виділення адресного рядка при фокусі,
  • Чуйний дизайн.

Використання WebView

<Div class = "navbar"> <! - ... -> </ div> <x-ms-webview id = "WebView"> </ x-ms-webview>

Введений для JavaScript-додатків в Windows 8.1 елемент управління WebView, іноді також згадується по імені тега x-ms-webview , Дозволяє хостити веб-контент всередині вашого Windows-програми. Він доступний як для HTML, так і для XAML .Для початку роботи досить розмістити відповідний елемент в коді сторінки.
Введений   для JavaScript-додатків в Windows 8

Розробка браузера

Ми будемо використовувати 15 різних API x-ms-webview. Всі крім двох з них керують навігацією між сторінками з деякому сенсі. Давайте подивимося, як можна використовувати дані інтерфейси для створення різних елементів UI.

Управління кнопками назад і вперед

Коли ви натискаєте кнопку назад, браузер повертає попередню сторінку з історії браузера, якщо вона доступна. Аналогічно, коли ви натискаєте кнопку вперед, браузер повертає наступну сторінку з історії, якщо вона також доступна. Для реалізації подібної логіки ми використовуємо методи goBack () і goForward () , Відповідно. Дані функції автоматично здійснять навігацію на коректну сторінку з стека навігації.
Після переходу на деяку сторінку, ми також оновлюємо поточний стан кнопок, щоб запобігти «можливість» навігації, коли ми досягаємо одного з кінців стека навігації. Іншими словами, ми відключаємо кнопки навігації вперед або назад, перевіряючи властивості canGoBack або canGoForward на рівність false.

// Update the navigation state this.updateNavState = () => {this.backButton.disabled =! This.webview.canGoBack; this.forwardButton.disabled =! this.webview.canGoForward; }; // Listen for the back button to navigate backwards this.backButton.addEventListener ( "click", () => this.webview.goBack ()); // Listen for the forward button to navigate forwards this.forwardButton.addEventListener ( "click", () => this.webview.goForward ());

Управління кнопками поновлення і зупинки

Кнопки поновлення і зупинки злегка відрізняються від інших компонент панелі навігації тим, що вони використовують один і той же місце в UI. Коли сторінка завантажується, натискання на кнопку зупинить завантаження, сховає «кільце прогресу» і відобразить іконку поновлення. І навпаки, коли сторінка завантажена, натискання на кнопку запустить оновлення сторінки і (в іншій частині коду) відобразить іконку зупинки. Ми використовуємо методи refresh () або stop () в залежності від поточних умов.

// Listen for the stop / refresh button to stop navigation / refresh the page this.stopButton.addEventListener ( "click", () => {if (this.loading) {this.webview.stop (); this.showProgressRing ( false); this.showRefresh ();} else {this.webview.refresh ();}});

Управління адресним рядком

В цілому, реалізація адресного рядка може бути дуже простий. Коли адреса URL введений в текстове поле, натискання Enter викличе метод navigate () , Використовуючи вміст input-елемента адресного рядка в якості параметра.
Однак сучасні браузери пішли сильно далі й запроваджують додаткову функціональність для зручності користувачів. Це додає деяку складність в реалізації - і тут все залежить від сценаріїв, які ви хочете підтримати.

const RE_VALIDATE_URL = /^[-:.&#+()[\]$'*;@~!,?%=\/\w]+$/; // Attempt a function function attempt (func) {try {return func (); } Catch (e) {return e; }} // Navigate to the specified absolute URL function navigate (webview, url, silent) {let resp = attempt (() => webview.navigate (url)); // ...} // Navigate to the specified location this.navigateTo = loc => {// ... // Check if the input value contains illegal characters let isUrl = RE_VALIDATE_URL.test (loc); if (isUrl && navigate (this.webview, loc, true)) {return; } // ... Fallback logic (eg prepending http (s) to the URL, querying Bing.com, etc.)}; // Listen for the Enter key in the address bar to navigate to the specified URL this.urlInput.addEventListener ( "keypress", e => {if (e.keyCode === 13) {this.navigateTo (urlInput.value) ;}});

Ось приклад сценарію, який ми спробували реалізувати. Припустимо, в адресний рядок введено значення "microsoft.com". Адреса не є повним. Якщо таке значення передати в метод navigate (), він завершиться невдачею. Наш браузер повинен знати, що URL не повний, і вміти визначити, який коректний протокол підставити: http або https. Більш того, можливо, що введене значення і не передбачалося адресою. Наприклад, ми могли ввести в адресний рядок значення "seahawks", сподіваючись, що, як і в багатьох браузерах, рядок також працює як поле пошуку. Браузер повинен зрозуміти, що значення не є адресою, і спробувати «знайти» його в пошуковій системі.

відображення favicon

запит favicon - нетривіальне завдання, так як існує кілька способів, як ікона може бути задана. Найпростіший спосіб - це перевірити корінь веб-сайту на наявність файлу «favicon.ico». Однак деякі сайти можуть бути на піддомені і тому мати відмінну іконку. Наприклад, іконка на "microsoft.com" відрізняється від іконки на "windows.microsoft.com". Щоб виключити двозначність, можна використовувати інший спосіб - перевірити розмітку сторінки на наявність link-тека всередині документа з rel-атрибутом, рівним "icon" або "shortcut icon".
Ми використовуємо метод invokeScriptAsync () , Щоб вставити всередину елемента управління WebView скрипт, який поверне рядок в разі успіху. Наш скрипт шукає всередині сторінки все елементи з link-теком, перевіряє, якщо rel-атрибут містить слово "icon", і в разі збігу повертає значення "href" -атрібута назад в додаток.

// Check if a file exists at the specified URL function fileExists (url) {return new Promise (resolve => Windows.Web.Http.HttpClient () .getAsync (new URI (url), Windows.Web.Http.HttpCompletionOption. responseHeadersRead) .done (e => resolve (e.isSuccessStatusCode), () => resolve (false))); } // Show the favicon if available this.getFavicon = loc => {let host = new URI (loc) .host; // Exit for cached ico location // ... let protocol = loc.split ( ":") [0]; // Hide favicon when the host can not be resolved or the protocol is not http (s) // ... loc = `$ {protocol}: // $ {host} / favicon.ico`; // Check if there is a favicon in the root directory fileExists (loc) .then (exists => {if (exists) {console.log ( `Favicon found: $ {loc}`); this.favicon.src = loc ; return;} // Asynchronously check for a favicon in the web page markup console.log ( "Favicon not found in root. Checking the markup ..."); let script = "Object (Array.from (document.getElementsByTagName ( 'link')). find (link => link.rel.includes ( 'icon'))). href "; let asyncOp = this.webview.invokeScriptAsync (" eval ", script); asyncOp.oncomplete = e => {loc = e.target.result || ""; if (loc) {console.log ( `Found favicon in markup: $ {loc}`); this.favicon.src = loc;} else {this.hideFavicon ( );}}; asyncOp.onerror = e => {console.error ( `Unable to find favicon in markup: $ {e.message}`);}; asyncOp.start ();}); };

Як згадано вище, ми використовуємо в нашому коді можливості з новою специфікації ES2015. Ви могли помітити використання стрілочної нотації в багатьох прикладах вище, а також ряд інших можливостей. Вставляється скрипт - це відмінний приклад поліпшення коду, що досягається за рахунок підтримки ES2015.

// Before (ES <6): "(function () {var n = document.getElementsByTagName ( 'link'); for (var i = 0; i <n.length; i ++) {if (n [i]. rel.indexOf ( 'icon')> -1) {return n [i] .href;}}}) (); " // After (ES6): "Object (Array.from (document.getElementsByTagName ( 'link')). Find (link => link.rel.includes ( 'icon'))). Href"

Підтримка комбінацій клавіш

На відміну від можливостей, які ми реалізували вище, підтримка комбінацій клавіш зажадає від нас невеликого шматка коду на C ++ або C #, обернутого у вигляді Windows Runtime (WinRT) компонента.
На відміну від можливостей, які ми реалізували вище, підтримка комбінацій клавіш зажадає від нас невеликого шматка коду на C ++ або C #, обернутого у вигляді Windows Runtime (WinRT) компонента
Щоб визначити натискання гарячих клавіш для виконання тих чи інших дій, наприклад, щоб при натисканні комбінації Ctrl + L виділяти адресний рядок або по F11 перемикатися в повноекранний режим, нам потрібно вставити ще один скрипт в WebView. Для цього ми використовуємо метод invokeScriptAsync () , Який ми вже згадували вище. Однак, нам потрібно якось повідомляти назад в шар додатки, коли ті чи інші клавіші натискати.
За допомогою методу addWebAllowedObject () , Ми можемо виставити для інжектіруемого коду метод, через який можна буде передавати натискаються клавіші в шар додатки на JavaScript. Також важливо розуміти, що в Windows 10, елемент управління WebView виконується в окремому потоці. Нам потрібно створити диспетчер, який буде передавати події в потік UI, щоб шар додатки міг їх обробляти.

KeyHandler :: KeyHandler () {// Must run on App UI thread m_dispatcher = Windows :: UI :: Core :: CoreWindow :: GetForCurrentThread () -> Dispatcher; } Void KeyHandler :: setKeyCombination (int keyPress) {m_dispatcher-> RunAsync (CoreDispatcherPriority :: Normal, ref new DispatchedHandler ([this, keyPress] {NotifyAppEvent (keyPress);})); } // Create the C ++ Windows Runtime Component let winRTObject = new NativeListener.KeyHandler (); // Listen for an app notification from the WinRT object winRTObject.onnotifyappevent = e => this.handleShortcuts (e.target); // Expose the native WinRT object on the page's global object this.webview.addWebAllowedObject ( "NotifyApp", winRTObject); // ... // Inject fullscreen mode hot key listener into the WebView with every page load this.webview.addEventListener ( "MSWebViewDOMContentLoaded", () => {let asyncOp = this.webview.invokeScriptAsync ( "eval", `addEventListener ( "keydown", e => {let k = e.keyCode; if (k === $ {this.KEYS.ESC} || k === $ {this.KEYS.F11} || (e.ctrlKey && k === $ {this.KEYS.L})) {NotifyApp.setKeyCombination (k);}}); `); asyncOp.onerror = e => console.error (` Unable to listen for fullscreen hot keys: $ {e.message} `); asyncOp.start ();});

Зовнішній вигляд браузера


Тепер, коли ми розібралися з ключовими API WebView, давайте трохи покращимо зовнішній вигляд нашого браузера.

Брендування заголовка


використовуючи API Windows Runtime , Ми можемо поміняти властивість ApplicationView.TitleBar , Щоб налаштувати колірну палітру все компонентів заголовка програми. У нашому браузері при завантаженні програми ми міняємо кольору так, щоб вони відповідали панелі навігації. Ми також оновлюємо кольору при відкритті меню, щоб відповідати фону меню. Кожен колір потрібно задавати як об'єкт з RGBA властивостями. Для зручності ми створили допоміжну функцію, яка генерує потрібний формат з шістнадцятковій строкової записи.

//// browser.js // Use a proxy to workaround a WinRT issue with Object.assign this.titleBar = new Proxy (Windows.UI.ViewManagement.ApplicationView.getForCurrentView (). TitleBar, { "get": (target, key) => target [key], "set": (target, key, value) => (target [key] = value, true)}); //// title-bar.js // Set your default colors const BRAND = hexStrToRGBA ( "# 3B3B3B"); const GRAY = hexStrToRGBA ( "# 666"); const WHITE = hexStrToRGBA ( "# FFF"); // Set the default title bar colors this.setDefaultAppBarColors = () => {Object.assign (this.titleBar, { "foregroundColor": BRAND, "backgroundColor": BRAND, "buttonForegroundColor": WHITE, "buttonBackgroundColor": BRAND, "buttonHoverForegroundColor": WHITE, "buttonHoverBackgroundColor": GRAY, "buttonPressedForegroundColor": BRAND, "buttonPressedBackgroundColor": WHITE, "inactiveForegroundColor": BRAND, "inactiveBackgroundColor": BRAND, "buttonInactiveForegroundColor": GRAY, "buttonInactiveBackgroundColor": BRAND, "buttonInactiveHoverForegroundColor ": WHITE," buttonInactiveHoverBackgroundColor ": BRAND," buttonPressedForegroundColor ": BRAND," buttonPressedBackgroundColor ": BRAND}); };

Інші можливості

Індикація прогресу, а також меню налаштувань і обраного використовують CSS transitions для анімації. З меню налаштувань тимчасові веб-дані можна очистити, використовуючи метод clearTemporaryWebDataAsync () . А в меню вибраного відображається список зберігається в JSON-файлі в кореневій папці переміщуваного сховища даних додатка .

Вихідний код

Повний приклад коду доступний в нашому репозитарії на GitHub. Ви можете також спробувати демонстраційний браузер, встановивши відповідну програму з Windows Store, або розгорнувши додаток з проекту для Visual Studio.
Повний приклад коду   доступний в нашому репозитарії на GitHub

Створіть свій додаток для Windows 10

За допомогою WebView ми змогли створити простий браузер, використовуючи веб-стандарти, буквально за день. Цікаво, що ви зможете створити для Windows 10?

Автор статті: Костянтин Кичинський

Цікаво, що ви зможете створити для Windows 10?


Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью